diff --git a/COPYING.LGPL b/COPYING.LGPL index 00b4fedfe7e..6178d5217c8 100644 --- a/COPYING.LGPL +++ b/COPYING.LGPL @@ -1,3 +1,9 @@ +NOTE: Only certain parts of the Residual project are under the GNU LGPL. +The majority of the files are under the GNU GPL. See the headers of the +individual files to find out the exact license. + + + GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 diff --git a/Makefile b/Makefile index 9a2bb69dd4d..b5b3ae685bf 100644 --- a/Makefile +++ b/Makefile @@ -26,7 +26,7 @@ ifeq "$(HAVE_GCC)" "1" CXXFLAGS+= -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder # Enable even more warnings... CXXFLAGS+= -Wpointer-arith -Wcast-qual - CXXFLAGS+= -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings + CXXFLAGS+= -Wshadow -Wnon-virtual-dtor -Wwrite-strings # Currently we disable this gcc flag, since it will also warn in cases, # where using GCC_PRINTF (means: __attribute__((format(printf, x, y)))) @@ -48,9 +48,12 @@ ifeq "$(HAVE_CLANG)" "1" CXXFLAGS+= -Wno-conversion -Wno-shorten-64-to-32 -Wno-sign-compare -Wno-four-char-constants endif -# Warn if global constructors are used. Only available in GCC with LLVM backend -# (and maybe clang?), hence off by default. -#CXXFLAGS+= -Wglobal-constructors +ifeq "$(HAVE_ICC)" "1" + # Disable some warnings: + # 161: unrecognized #pragma + # 1899: multicharacter character literal (potential portability problem) + CXXFLAGS+= -diag-disable 161,1899 +endif ####################################################################### # Default commands - put the necessary replacements in config.mk # @@ -69,7 +72,7 @@ ZIP ?= zip -q # Misc stuff - you should never have to edit this # ####################################################################### -EXECUTABLE := residual$(EXEEXT) +EXECUTABLE := $(EXEPRE)residual$(EXEEXT) include $(srcdir)/Makefile.common diff --git a/Makefile.common b/Makefile.common index 9c3808e1f01..e1938fd46af 100644 --- a/Makefile.common +++ b/Makefile.common @@ -16,22 +16,22 @@ all: $(EXECUTABLE) plugins ###################################################################### PLUGINS := -MODULES := base $(MODULES) +MODULES := devtools base $(MODULES) -include $(srcdir)/engines/engines.mk # After the game specific modules follow the shared modules MODULES += \ gui \ - sound \ backends \ engines \ graphics \ + audio \ common \ po ifdef USE_MT32EMU -MODULES += sound/softsynth/mt32 +MODULES += audio/softsynth/mt32 endif ###################################################################### @@ -54,6 +54,10 @@ DEPFILES = # the build date in gScummVMBuildDate is correct. base/version.o: $(filter-out base/libbase.a,$(OBJS)) +ifdef USE_ELF_LOADER +backends/plugins/elf/version.o: $(filter-out base/libbase.a,$(filter-out backends/libbackends.a,$(OBJS))) +endif + # Replace regular output with quiet messages ifneq ($(findstring $(MAKEFLAGS),s),s) ifneq ($(VERBOSE_BUILD),1) @@ -158,34 +162,36 @@ VER_EXTRA = $(shell echo $(VERSION) | cut -d. -f 3 | cut -c2-) ###################################################################### -# Get Subversion's working copy information +# Get git's working copy information ###################################################################### -ifneq ($(shell svn info $(srcdir) 1>/dev/null 2>&1 || echo "error"),error) -SVNROOT := $(srcdir) -ifeq ($(origin VER_SVNREV), undefined) +ifneq ($(shell cd $(srcdir); git rev-parse --verify HEAD 1>/dev/null 2>&1 || echo "error"),error) +GITROOT := $(srcdir) +ifeq ($(origin VER_REV), undefined) +# Are there uncommitted changes? (describe --dirty is only available since 1.6.6) +VER_DIRTY := $(shell cd $(srcdir); git update-index --refresh --unmerged 1>/dev/null 2>&1; git diff-index --quiet HEAD || echo "-dirty") # Get the working copy base revision -VER_SVNREV := $(shell LANG=C svn info $(SVNROOT) | grep "^Revision" | cut -d ' ' -f 2) +VER_REV := $(shell cd $(srcdir); git describe --match desc/\* | cut -d '-' -f 2-)$(VER_DIRTY) endif else -SVNROOT := https://resisual.svn.sourceforge.net/svnroot/residual/residual/trunk/ +GITROOT := git://github.com/residual/residual.git endif # Define the Subversion revision if available, either autodetected or # specified by the user, but only for base/version.cpp. -ifneq ($(origin VER_SVNREV), undefined) -CXXFLAGS+= -DRESIDUAL_SVN_REVISION=\"$(VER_SVNREV)\" +ifneq ($(origin VER_REV), undefined) +base/version.o: CXXFLAGS:=$(CXXFLAGS) -DRESIDUAL_REVISION=\"$(VER_REV)\" endif ###################################################################### # Distribution settings ###################################################################### -ifeq ($(VER_EXTRA),svn) -ifeq ($(origin VER_SVNREV), undefined) +ifeq ($(VER_EXTRA),git) +ifeq ($(origin VER_REV), undefined) DISTVERSION = $(shell date '+%Y-%m-%d') else -DISTVERSION = svn$(VER_SVNREV) +DISTVERSION = git$(VER_REV) endif else DISTVERSION = $(VERSION) @@ -195,14 +201,15 @@ DISTNAME := residual-$(DISTVERSION) DISTDIR := dist VERFILE := $(DISTDIR)/$(DISTNAME)/base/internal_version.h +# TODO git via $(GITROOT) $(VERFILE): $(srcdir)/base/internal_version.h @$(RM_REC) $(DISTDIR) @$(MKDIR) $(DISTDIR) svn export $(SVNROOT) $(DISTDIR)/$(DISTNAME) -ifneq ($(origin VER_SVNREV), undefined) +ifneq ($(origin VER_REV), undefined) @# Use the current SVN revision as a default for the snapshot sources @svn cat $(SVNROOT)/base/internal_version.h | sed -e \ - "s/^#define RESIDUAL_SVN_REVISION$$/#define RESIDUAL_SVN_REVISION \"$(VER_SVNREV)\"/g" \ + "s/^#define RESIDUAL_REVISION$$/#define RESIDUAL_REVISION \"$(VER_REV)\"/g" \ > $(VERFILE) endif diff --git a/sound/audiostream.cpp b/audio/audiostream.cpp similarity index 97% rename from sound/audiostream.cpp rename to audio/audiostream.cpp index 3e1a3d04b02..d1b273bf3fe 100644 --- a/sound/audiostream.cpp +++ b/audio/audiostream.cpp @@ -29,12 +29,12 @@ #include "common/queue.h" #include "common/util.h" -#include "sound/audiostream.h" -#include "sound/decoders/flac.h" -#include "sound/mixer.h" -#include "sound/decoders/mp3.h" -#include "sound/decoders/raw.h" -#include "sound/decoders/vorbis.h" +#include "audio/audiostream.h" +#include "audio/decoders/flac.h" +#include "audio/mixer.h" +#include "audio/decoders/mp3.h" +#include "audio/decoders/raw.h" +#include "audio/decoders/vorbis.h" namespace Audio { @@ -228,8 +228,8 @@ int SubLoopingAudioStream::readBuffer(int16 *buffer, const int numSamples) { SubSeekableAudioStream::SubSeekableAudioStream(SeekableAudioStream *parent, const Timestamp start, const Timestamp end, DisposeAfterUse::Flag disposeAfterUse) : _parent(parent), _disposeAfterUse(disposeAfterUse), _start(convertTimeToStreamPos(start, getRate(), isStereo())), - _pos(0, getRate() * (isStereo() ? 2 : 1)), - _length(convertTimeToStreamPos(end - start, getRate(), isStereo())) { + _pos(0, getRate() * (isStereo() ? 2 : 1)), + _length(convertTimeToStreamPos(end, getRate(), isStereo()) - _start) { assert(_length.totalNumberOfFrames() % (isStereo() ? 2 : 1) == 0); _parent->seek(_start); @@ -393,7 +393,7 @@ Timestamp convertTimeToStreamPos(const Timestamp &where, int rate, bool isStereo // // An example is when converting the timestamp 500ms to a 11025 Hz based // stream. It would have an internal frame counter of 5512.5. Now when - // doing calculations at frame precision, this might lead to unexpected + // doing calculations at frame precision, this might lead to unexpected // results: The frame difference between a timestamp 1000ms and the above // mentioned timestamp (both with 11025 as framerate) would be 5512, // instead of 5513, which is what a frame-precision based code would expect. diff --git a/sound/audiostream.h b/audio/audiostream.h similarity index 97% rename from sound/audiostream.h rename to audio/audiostream.h index af92d263c4a..2d549c599f9 100644 --- a/sound/audiostream.h +++ b/audio/audiostream.h @@ -30,7 +30,7 @@ #include "common/sys.h" #include "common/types.h" -#include "sound/timestamp.h" +#include "audio/timestamp.h" namespace Audio { @@ -276,11 +276,6 @@ private: * The same caveats apply to SubSeekableAudioStream as do to SeekableAudioStream. * * Manipulating the parent stream directly /will/ mess up a substream. - * - * IMPORTANT: - * Note for engine authors. This object is currently under inspection. In case - * we need to revise the looping API we might drop this. So if you really need - * something like this object, please drop a mail to LordHoto. */ class SubSeekableAudioStream : public SeekableAudioStream { public: diff --git a/sound/decoders/flac.cpp b/audio/decoders/flac.cpp similarity index 98% rename from sound/decoders/flac.cpp rename to audio/decoders/flac.cpp index 5eeb8a2c3cc..cefbf3a7ede 100644 --- a/sound/decoders/flac.cpp +++ b/audio/decoders/flac.cpp @@ -23,7 +23,10 @@ * */ -#include "sound/decoders/flac.h" +// Disable symbol overrides for FILE as that is used in FLAC headers +#define FORBIDDEN_SYMBOL_EXCEPTION_FILE + +#include "audio/decoders/flac.h" #ifdef USE_FLAC @@ -31,8 +34,7 @@ #include "common/stream.h" #include "common/util.h" -#include "sound/audiostream.h" -#include "sound/audiocd.h" +#include "audio/audiostream.h" #define FLAC__NO_DLL // that MS-magic gave me headaches - just link the library you like #include @@ -140,7 +142,7 @@ public: bool seek(const Timestamp &where); Timestamp getLength() const { return _length; } - bool isStreamDecoderReady() const { return getStreamDecoderState() == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC ; } + bool isStreamDecoderReady() const { return getStreamDecoderState() == FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC; } protected: uint getChannels() const { return MIN(_streaminfo.channels, MAX_OUTPUT_CHANNELS); } @@ -303,7 +305,7 @@ int FLACStream::readBuffer(int16 *buffer, const int numSamples) { const uint numChannels = getChannels(); if (numChannels == 0) { - warning("FLACStream: Stream not sucessfully initialised, cant playback"); + warning("FLACStream: Stream not successfully initialised, cant playback"); return -1; // streaminfo wasnt read! } @@ -553,7 +555,7 @@ void FLACStream::convertBuffersGeneric(SampleType* bufDestination, const FLAC__i for (; numSamples > 0; numSamples -= numChannels) { for (uint i = 0; i < numChannels; ++i) - *bufDestination++ = static_cast(*(inChannels[i]++) >> kPower) ; + *bufDestination++ = static_cast(*(inChannels[i]++) >> kPower); } } else { for (; numSamples > 0; numSamples -= numChannels) { diff --git a/sound/decoders/flac.h b/audio/decoders/flac.h similarity index 98% rename from sound/decoders/flac.h rename to audio/decoders/flac.h index 354775d4ff1..c6e0e637dfb 100644 --- a/sound/decoders/flac.h +++ b/audio/decoders/flac.h @@ -27,10 +27,12 @@ * @file * Sound decoder used in engines: * - agos + * - draci * - kyra * - m4 * - queen * - saga + * - sci * - scumm * - sword1 * - sword2 diff --git a/sound/decoders/mp3.cpp b/audio/decoders/mp3.cpp similarity index 99% rename from sound/decoders/mp3.cpp rename to audio/decoders/mp3.cpp index 0eac2e8ef60..45166701b23 100644 --- a/sound/decoders/mp3.cpp +++ b/audio/decoders/mp3.cpp @@ -23,7 +23,7 @@ * */ -#include "sound/decoders/mp3.h" +#include "audio/decoders/mp3.h" #ifdef USE_MAD @@ -31,8 +31,7 @@ #include "common/stream.h" #include "common/util.h" -#include "sound/audiocd.h" -#include "sound/audiostream.h" +#include "audio/audiostream.h" #include diff --git a/sound/decoders/mp3.h b/audio/decoders/mp3.h similarity index 98% rename from sound/decoders/mp3.h rename to audio/decoders/mp3.h index 335f43c0cf1..8e9e0c18a2b 100644 --- a/sound/decoders/mp3.h +++ b/audio/decoders/mp3.h @@ -27,10 +27,13 @@ * @file * Sound decoder used in engines: * - agos + * - draci * - kyra * - m4 + * - mohawk * - queen * - saga + * - sci * - scumm * - sword1 * - sword2 diff --git a/sound/decoders/raw.cpp b/audio/decoders/raw.cpp similarity index 98% rename from sound/decoders/raw.cpp rename to audio/decoders/raw.cpp index 4356c08faf0..43d20e8ac51 100644 --- a/sound/decoders/raw.cpp +++ b/audio/decoders/raw.cpp @@ -24,11 +24,11 @@ */ #include "common/endian.h" -#include "common/stream.h" +#include "common/memstream.h" -#include "sound/audiostream.h" -#include "sound/mixer.h" -#include "sound/decoders/raw.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" +#include "audio/decoders/raw.h" namespace Audio { diff --git a/sound/decoders/raw.h b/audio/decoders/raw.h similarity index 100% rename from sound/decoders/raw.h rename to audio/decoders/raw.h diff --git a/sound/decoders/vorbis.cpp b/audio/decoders/vorbis.cpp similarity index 96% rename from sound/decoders/vorbis.cpp rename to audio/decoders/vorbis.cpp index 7e883f3eda6..0225d151827 100644 --- a/sound/decoders/vorbis.cpp +++ b/audio/decoders/vorbis.cpp @@ -23,7 +23,12 @@ * */ -#include "sound/decoders/vorbis.h" +// Disable symbol overrides for FILE and fseek as those are used in the +// Vorbis headers. +#define FORBIDDEN_SYMBOL_EXCEPTION_FILE +#define FORBIDDEN_SYMBOL_EXCEPTION_fseek + +#include "audio/decoders/vorbis.h" #ifdef USE_VORBIS @@ -31,8 +36,7 @@ #include "common/stream.h" #include "common/util.h" -#include "sound/audiostream.h" -#include "sound/audiocd.h" +#include "audio/audiostream.h" #ifdef USE_TREMOR #if defined(__GP32__) // custom libtremor locations diff --git a/sound/decoders/vorbis.h b/audio/decoders/vorbis.h similarity index 98% rename from sound/decoders/vorbis.h rename to audio/decoders/vorbis.h index 16c2de00b3c..d764042685d 100644 --- a/sound/decoders/vorbis.h +++ b/audio/decoders/vorbis.h @@ -27,10 +27,12 @@ * @file * Sound decoder used in engines: * - agos + * - draci * - kyra * - m4 * - queen * - saga + * - sci * - scumm * - sword1 * - sword2 diff --git a/sound/fmopl.cpp b/audio/fmopl.cpp similarity index 97% rename from sound/fmopl.cpp rename to audio/fmopl.cpp index 25c8900e1db..bf6d75d217e 100644 --- a/sound/fmopl.cpp +++ b/audio/fmopl.cpp @@ -22,10 +22,10 @@ * $Id$ */ -#include "sound/fmopl.h" +#include "audio/fmopl.h" -#include "sound/softsynth/opl/dosbox.h" -#include "sound/softsynth/opl/mame.h" +#include "audio/softsynth/opl/dosbox.h" +#include "audio/softsynth/opl/mame.h" #include "common/config-manager.h" #include "common/translation.h" diff --git a/sound/fmopl.h b/audio/fmopl.h similarity index 100% rename from sound/fmopl.h rename to audio/fmopl.h diff --git a/sound/mididrv.cpp b/audio/mididrv.cpp similarity index 88% rename from sound/mididrv.cpp rename to audio/mididrv.cpp index f3e45957ef6..cf6d1c012d7 100644 --- a/sound/mididrv.cpp +++ b/audio/mididrv.cpp @@ -28,8 +28,8 @@ #include "common/str.h" #include "common/system.h" #include "common/util.h" -#include "sound/mididrv.h" -#include "sound/musicplugin.h" +#include "audio/mididrv.h" +#include "audio/musicplugin.h" #include "common/translation.h" const byte MidiDriver::_mt32ToGm[128] = { @@ -162,7 +162,7 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { case MT_AMIGA: if (flags & MDT_AMIGA) return hdl; - break; + break; case MT_APPLEIIGS: if (flags & MDT_APPLEIIGS) @@ -209,35 +209,40 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { hdl = getDeviceHandle("auto"); const MusicType type = getMusicType(hdl); - if (type != MT_AUTO && type != MT_INVALID) { - if (flags & MDT_PREFER_MT32) - // If we have a preferred MT32 device we disable the gm/mt32 mapping (more about this in mididrv.h) - _forceTypeMT32 = true; - return hdl; - } + // If have a "Don't use GM/MT-32" setting we skip this part and jump + // to AdLib, PC Speaker etc. detection right away. + if (type != MT_NULL) { + if (type != MT_AUTO && type != MT_INVALID) { + if (flags & MDT_PREFER_MT32) + // If we have a preferred MT32 device we disable the gm/mt32 mapping (more about this in mididrv.h) + _forceTypeMT32 = true; - // If we have no specific device selected (neither in the scummvm nor in the game domain) - // and no preferred MT32 or GM device selected we arrive here. - // If MT32 is preferred we try for the first available device with music type 'MT_MT32' (usually the mt32 emulator) - if (flags & MDT_PREFER_MT32) { + return hdl; + } + + // If we have no specific device selected (neither in the scummvm nor in the game domain) + // and no preferred MT32 or GM device selected we arrive here. + // If MT32 is preferred we try for the first available device with music type 'MT_MT32' (usually the mt32 emulator) + if (flags & MDT_PREFER_MT32) { + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getMusicType() == MT_MT32) + return d->getHandle(); + } + } + } + + // Now we default to the first available device with music type 'MT_GM' for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { MusicDevices i = (**m)->getDevices(); for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { - if (d->getMusicType() == MT_MT32) + if (d->getMusicType() == MT_GM || d->getMusicType() == MT_GS) return d->getHandle(); } } } - - // Now we default to the first available device with music type 'MT_GM' - for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { - MusicDevices i = (**m)->getDevices(); - for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { - if (d->getMusicType() == MT_GM || d->getMusicType() == MT_GS) - return d->getHandle(); - } - } } MusicType tp = MT_AUTO; @@ -247,10 +252,10 @@ MidiDriver::DeviceHandle MidiDriver::detectDevice(int flags) { tp = MT_PC98; else if (flags & MDT_ADLIB) tp = MT_ADLIB; - else if (flags & MDT_PCSPK) - tp = MT_PCSPK; else if (flags & MDT_PCJR) tp = MT_PCJR; + else if (flags & MDT_PCSPK) + tp = MT_PCSPK; else if (flags & MDT_C64) tp = MT_C64; else if (flags & MDT_AMIGA) diff --git a/sound/mididrv.h b/audio/mididrv.h similarity index 90% rename from sound/mididrv.h rename to audio/mididrv.h index d7f809ec105..78178c019ac 100644 --- a/sound/mididrv.h +++ b/audio/mididrv.h @@ -37,15 +37,6 @@ namespace Audio { } namespace Common { class String; } -/** - * Music Driver Types, used to uniquely identify each music driver. - * - * The pseudo drivers are listed first, then all native drivers, - * then all other MIDI drivers, and finally the non-MIDI drivers. - * - * @todo Rename MidiDriverType to MusicDriverType - */ - /** * Music types that music drivers can implement and engines can rely on. */ @@ -71,16 +62,21 @@ enum MusicType { * A set of flags to be passed to detectDevice() which can be used to * specify what kind of music driver is preferred / accepted. * - * The flags (except for MDT_PREFER_MT32 and MDT_PREFER_GM) indicate whether a given driver - * type is acceptable. E.g. the TOWNS music driver could be returned by - * detectDevice if and only if MDT_TOWNS is specified. + * The flags (except for MDT_PREFER_MT32 and MDT_PREFER_GM) indicate whether a + * given driver type is acceptable. E.g. the TOWNS music driver could be + * returned by detectDevice if and only if MDT_TOWNS is specified. + * + * MDT_PREFER_MT32 and MDT_PREFER_GM indicate the MIDI device type to use when + * no device is selected in the music options, or when the MIDI device selected + * does not match the requirements of a game engine. With these flags, more + * priority is given to an MT-32 device, or a GM device respectively. * * @todo Rename MidiDriverFlags to MusicDriverFlags */ enum MidiDriverFlags { MDT_NONE = 0, - MDT_PCSPK = 1 << 0, // PC Speaker: Maps to MD_PCSPK and MD_PCJR - MDT_CMS = 1 << 1, // Creative Music System / Gameblaster: Maps to MD_CMS + MDT_PCSPK = 1 << 0, // PC Speaker: Maps to MT_PCSPK and MT_PCJR + MDT_CMS = 1 << 1, // Creative Music System / Gameblaster: Maps to MT_CMS MDT_PCJR = 1 << 2, // Tandy/PC Junior driver MDT_ADLIB = 1 << 3, // AdLib: Maps to MT_ADLIB MDT_C64 = 1 << 4, @@ -94,19 +90,53 @@ enum MidiDriverFlags { }; /** - * Abstract description of a MIDI driver. Used by the config file and command - * line parsing code, and also to be able to give the user a list of available - * drivers. - * - * @todo Rename MidiDriverType to MusicDriverType + * TODO: Document this, give it a better name. */ +class MidiDriver_BASE { +public: + virtual ~MidiDriver_BASE() { } + + /** + * Output a packed midi command to the midi stream. + * The 'lowest' byte (i.e. b & 0xFF) is the status + * code, then come (if used) the first and second + * opcode. + */ + virtual void send(uint32 b) = 0; + + /** + * Output a midi command to the midi stream. Convenience wrapper + * around the usual 'packed' send method. + * + * Do NOT use this for sysEx transmission; instead, use the sysEx() + * method below. + */ + void send(byte status, byte firstOp, byte secondOp) { + send(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16)); + } + + /** + * Transmit a sysEx to the midi device. + * + * The given msg MUST NOT contain the usual SysEx frame, i.e. + * do NOT include the leading 0xF0 and the trailing 0xF7. + * + * Furthermore, the maximal supported length of a SysEx + * is 264 bytes. Passing longer buffers can lead to + * undefined behavior (most likely, a crash). + */ + virtual void sysEx(const byte *msg, uint16 length) { } + + // TODO: Document this. + virtual void metaEvent(byte type, byte *data, uint16 length) { } +}; /** * Abstract MIDI Driver Class * * @todo Rename MidiDriver to MusicDriver */ -class MidiDriver { +class MidiDriver : public MidiDriver_BASE { public: /** * The device handle. @@ -130,7 +160,7 @@ public: /** Returns device handle based on the present devices and the flags parameter. */ static DeviceHandle detectDevice(int flags); - + /** Find the music driver matching the given driver name/description. */ static DeviceHandle getDeviceHandle(const Common::String &identifier); @@ -177,28 +207,14 @@ public: */ virtual int open() = 0; + /** + * Check whether the midi driver has already been opened. + */ + virtual bool isOpen() const = 0; + /** Close the midi driver. */ virtual void close() = 0; - /** - * Output a packed midi command to the midi stream. - * The 'lowest' byte (i.e. b & 0xFF) is the status - * code, then come (if used) the first and second - * opcode. - */ - virtual void send(uint32 b) = 0; - - /** - * Output a midi command to the midi stream. Convenience wrapper - * around the usual 'packed' send method. - * - * Do NOT use this for sysEx transmission; instead, use the sysEx() - * method below. - */ - void send(byte status, byte firstOp, byte secondOp) { - send(status | ((uint32)firstOp << 8) | ((uint32)secondOp << 16)); - } - /** Get or set a property. */ virtual uint32 property(int prop, uint32 param) { return 0; } @@ -225,22 +241,8 @@ public: */ void sendGMReset(); - /** - * Transmit a sysEx to the midi device. - * - * The given msg MUST NOT contain the usual SysEx frame, i.e. - * do NOT include the leading 0xF0 and the trailing 0xF7. - * - * Furthermore, the maximal supported length of a SysEx - * is 264 bytes. Passing longer buffers can lead to - * undefined behavior (most likely, a crash). - */ - virtual void sysEx(const byte *msg, uint16 length) { } - virtual void sysEx_customInstrument(byte channel, uint32 type, const byte *instr) { } - virtual void metaEvent(byte type, byte *data, uint16 length) { } - // Timing functions - MidiDriver now operates timers virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) = 0; diff --git a/sound/midiparser.cpp b/audio/midiparser.cpp similarity index 92% rename from sound/midiparser.cpp rename to audio/midiparser.cpp index d54a85e7331..c6520d34b01 100644 --- a/sound/midiparser.cpp +++ b/audio/midiparser.cpp @@ -23,8 +23,8 @@ * */ -#include "sound/midiparser.h" -#include "sound/mididrv.h" +#include "audio/midiparser.h" +#include "audio/mididrv.h" #include "common/util.h" ////////////////////////////////////////////////// @@ -43,6 +43,7 @@ _psec_per_tick(5208), // 500000 / 96 _autoLoop(false), _smartJump(false), _centerPitchWheelOnUnload(false), +_sendSustainOffOnNotesOff(false), _num_tracks(0), _active_track(255), _abort_parse(0) { @@ -64,6 +65,9 @@ void MidiParser::property(int prop, int value) { case mpCenterPitchWheelOnUnload: _centerPitchWheelOnUnload = (value != 0); break; + case mpSendSustainOffOnNotesOff: + _sendSustainOffOnNotesOff = (value != 0); + break; } } @@ -281,6 +285,8 @@ void MidiParser::allNotesOff() { for (i = 0; i < 16; ++i) { sendToDriver(0xB0 | i, 0x7b, 0); // All notes off + if (_sendSustainOffOnNotesOff) + sendToDriver(0xB0 | i, 0x40, 0); // Also send a sustain off event (bug #3116608) } memset(_active_notes, 0, sizeof(_active_notes)); @@ -344,7 +350,7 @@ void MidiParser::hangAllActiveNotes() { if (_next_event.command() == 0x8) { if (temp_active[_next_event.basic.param1] & (1 << _next_event.channel())) { hangingNote(_next_event.channel(), _next_event.basic.param1, (advance_tick - _position._last_event_tick) * _psec_per_tick, false); - temp_active[_next_event.basic.param1] &= ~ (1 << _next_event.channel()); + temp_active[_next_event.basic.param1] &= ~(1 << _next_event.channel()); } } else if (_next_event.event == 0xFF && _next_event.ext.type == 0x2F) { // warning("MidiParser::hangAllActiveNotes(): Hit End of Track with active notes left"); @@ -361,7 +367,7 @@ void MidiParser::hangAllActiveNotes() { } } -bool MidiParser::jumpToTick(uint32 tick, bool fireEvents, bool stopNotes) { +bool MidiParser::jumpToTick(uint32 tick, bool fireEvents, bool stopNotes, bool dontSendNoteOn) { if (_active_track >= _num_tracks) return false; @@ -402,8 +408,17 @@ bool MidiParser::jumpToTick(uint32 tick, bool fireEvents, bool stopNotes) { _driver->sysEx(info.ext.data, (uint16)info.length-1); else _driver->sysEx(info.ext.data, (uint16)info.length); - } else - sendToDriver(info.event, info.basic.param1, info.basic.param2); + } else { + // The note on sending code is used by the SCUMM engine. Other engine using this code + // (such as SCI) have issues with this, as all the notes sent can be heard when a song + // is fast-forwarded. Thus, if the engine requests it, don't send note on events. + if (info.command() == 0x9 && dontSendNoteOn) { + // Don't send note on; doing so creates a "warble" with some instruments on the MT-32. + // Refer to patch #3117577 + } else { + sendToDriver(info.event, info.basic.param1, info.basic.param2); + } + } } parseNextEvent(_next_event); diff --git a/sound/midiparser.h b/audio/midiparser.h similarity index 96% rename from sound/midiparser.h rename to audio/midiparser.h index 687ed1da055..99b5bece227 100644 --- a/sound/midiparser.h +++ b/audio/midiparser.h @@ -32,7 +32,7 @@ #include "common/endian.h" class MidiParser; -class MidiDriver; +class MidiDriver_BASE; @@ -273,7 +273,7 @@ protected: ///< Used for "Smart Jump" and MIDI formats that do not include explicit Note Off events. byte _hanging_notes_count; ///< Count of hanging notes, used to optimize expiration. - MidiDriver *_driver; ///< The device to which all events will be transmitted. + MidiDriver_BASE *_driver; ///< The device to which all events will be transmitted. uint32 _timer_rate; ///< The time in microseconds between onTimer() calls. Obtained from the MidiDriver. uint32 _ppqn; ///< Pulses Per Quarter Note. (We refer to "pulses" as "ticks".) uint32 _tempo; ///< Microseconds per quarter note. @@ -281,7 +281,7 @@ protected: bool _autoLoop; ///< For lightweight clients that don't provide their own flow control. bool _smartJump; ///< Support smart expiration of hanging notes when jumping bool _centerPitchWheelOnUnload; ///< Center the pitch wheels when unloading a song - + bool _sendSustainOffOnNotesOff; ///< Send a sustain off on a notes off event, stopping hanging notes byte *_tracks[120]; ///< Multi-track MIDI formats are supported, up to 120 tracks. byte _num_tracks; ///< Count of total tracks for multi-track MIDI formats. 1 for single-track formats. byte _active_track; ///< Keeps track of the currently active track, in multi-track formats. @@ -361,7 +361,13 @@ public: * Center the pitch wheels when unloading music in preparation * for the next piece of music. */ - mpCenterPitchWheelOnUnload = 4 + mpCenterPitchWheelOnUnload = 4, + + /** + * Sends a sustain off event when a notes off event is triggered. + * Stops hanging notes. + */ + mpSendSustainOffOnNotesOff = 5 }; public: @@ -374,7 +380,7 @@ public: virtual void unloadMusic(); virtual void property(int prop, int value); - void setMidiDriver(MidiDriver *driver) { _driver = driver; } + void setMidiDriver(MidiDriver_BASE *driver) { _driver = driver; } void setTimerRate(uint32 rate) { _timer_rate = rate; } void setTempo(uint32 tempo); void onTimer(); @@ -383,7 +389,7 @@ public: void stopPlaying(); bool setTrack(int track); - bool jumpToTick(uint32 tick, bool fireEvents = false, bool stopNotes = true); + bool jumpToTick(uint32 tick, bool fireEvents = false, bool stopNotes = true, bool dontSendNoteOn = false); uint32 getPPQN() { return _ppqn; } virtual uint32 getTick() { return _position._play_tick; } diff --git a/sound/mixer.cpp b/audio/mixer.cpp similarity index 95% rename from sound/mixer.cpp rename to audio/mixer.cpp index f6f7c0361e3..6305eab3623 100644 --- a/sound/mixer.cpp +++ b/audio/mixer.cpp @@ -26,10 +26,10 @@ #include "common/util.h" #include "common/system.h" -#include "sound/mixer_intern.h" -#include "sound/rate.h" -#include "sound/audiostream.h" -#include "sound/timestamp.h" +#include "audio/mixer_intern.h" +#include "audio/rate.h" +#include "audio/audiostream.h" +#include "audio/timestamp.h" namespace Audio { @@ -54,8 +54,9 @@ public: * @param len number of sample *pairs*. So a value of * 10 means that the buffer contains twice 10 sample, each * 16 bits, for a total of 40 bytes. + * @return number of sample pairs processed (which can still be silence!) */ - void mix(int16 *data, uint len); + int mix(int16 *data, uint len); /** * Queries whether the channel is still playing or not. @@ -257,7 +258,7 @@ void MixerImpl::playStream( insertChannel(handle, chan); } -void MixerImpl::mixCallback(byte *samples, uint len) { +int MixerImpl::mixCallback(byte *samples, uint len) { assert(samples); Common::StackLock lock(_mutex); @@ -272,14 +273,21 @@ void MixerImpl::mixCallback(byte *samples, uint len) { memset(buf, 0, 2 * len * sizeof(int16)); // mix all channels + int res = 0, tmp; for (int i = 0; i != NUM_CHANNELS; i++) if (_channels[i]) { if (_channels[i]->isFinished()) { delete _channels[i]; _channels[i] = 0; - } else if (!_channels[i]->isPaused()) - _channels[i]->mix(buf, len); + } else if (!_channels[i]->isPaused()) { + tmp = _channels[i]->mix(buf, len); + + if (tmp > res) + res = tmp; + } } + + return res; } void MixerImpl::stopAll() { @@ -538,19 +546,23 @@ Timestamp Channel::getElapsedTime() { return ts; } -void Channel::mix(int16 *data, uint len) { +int Channel::mix(int16 *data, uint len) { assert(_stream); + int res = 0; + if (_stream->endOfData()) { // TODO: call drain method } else { assert(_converter); - _samplesConsumed = _samplesDecoded; _mixerTimeStamp = g_system->getMillis(); _pauseTime = 0; - _samplesDecoded += _converter->flow(*_stream, data, len, _volL, _volR); + res = _converter->flow(*_stream, data, len, _volL, _volR); + _samplesDecoded += res; } + + return res; } } // End of namespace Audio diff --git a/sound/mixer.h b/audio/mixer.h similarity index 98% rename from sound/mixer.h rename to audio/mixer.h index 8c940e0880f..54cd092526a 100644 --- a/sound/mixer.h +++ b/audio/mixer.h @@ -28,8 +28,9 @@ #include "common/types.h" #include "common/mutex.h" +#include "common/noncopyable.h" -#include "sound/timestamp.h" +#include "audio/timestamp.h" class OSystem; @@ -37,8 +38,6 @@ class OSystem; namespace Audio { class AudioStream; -class RewindableAudioStream; -class SeekableAudioStream; class Channel; class Mixer; class MixerImpl; @@ -61,7 +60,7 @@ public: * The main audio mixer handles mixing of an arbitrary number of * audio streams (in the form of AudioStream instances). */ -class Mixer { +class Mixer : Common::NonCopyable { public: enum SoundType { kPlainSoundType = 0, diff --git a/sound/mixer_intern.h b/audio/mixer_intern.h similarity index 96% rename from sound/mixer_intern.h rename to audio/mixer_intern.h index e004bad5f79..d903dde10b5 100644 --- a/sound/mixer_intern.h +++ b/audio/mixer_intern.h @@ -28,7 +28,7 @@ #include "common/sys.h" #include "common/mutex.h" -#include "sound/mixer.h" +#include "audio/mixer.h" namespace Audio { @@ -118,8 +118,10 @@ public: * The mixer callback function, to be called at regular intervals by * the backend (e.g. from an audio mixing thread). All the actual mixing * work is done from here. + * + * @return number of sample pairs processed (which can still be silence!) */ - void mixCallback(byte *samples, uint len); + int mixCallback(byte *samples, uint len); /** * Set the internal 'is ready' flag of the mixer. diff --git a/sound/module.mk b/audio/module.mk similarity index 95% rename from sound/module.mk rename to audio/module.mk index e604e3d9ce3..e54a68a0dbe 100644 --- a/sound/module.mk +++ b/audio/module.mk @@ -1,7 +1,6 @@ -MODULE := sound +MODULE := audio MODULE_OBJS := \ - audiocd.o \ audiostream.o \ fmopl.o \ mididrv.o \ diff --git a/sound/mpu401.cpp b/audio/mpu401.cpp similarity index 95% rename from sound/mpu401.cpp rename to audio/mpu401.cpp index 0fefca87c66..15fc6b4760f 100644 --- a/sound/mpu401.cpp +++ b/audio/mpu401.cpp @@ -22,7 +22,7 @@ * $Id$ */ -#include "sound/mpu401.h" +#include "audio/mpu401.h" #include "common/system.h" #include "common/timer.h" #include "common/util.h" // for ARRAYSIZE @@ -101,12 +101,18 @@ MidiDriver_MPU401::MidiDriver_MPU401() : } } +MidiDriver_MPU401::~MidiDriver_MPU401() { +} + void MidiDriver_MPU401::close() { - if (_timer_proc) + if (_timer_proc) { g_system->getTimerManager()->removeTimerProc(_timer_proc); - _timer_proc = 0; - for (int i = 0; i < 16; ++i) - send(0x7B << 8 | 0xB0 | i); + _timer_proc = 0; + } + if (isOpen()) { + for (int i = 0; i < 16; ++i) + send(0x7B << 8 | 0xB0 | i); + } } uint32 MidiDriver_MPU401::property(int prop, uint32 param) { diff --git a/sound/mpu401.h b/audio/mpu401.h similarity index 69% rename from sound/mpu401.h rename to audio/mpu401.h index 68f4637432b..5af0f2b7137 100644 --- a/sound/mpu401.h +++ b/audio/mpu401.h @@ -26,7 +26,7 @@ #ifndef SOUND_MPU401_H #define SOUND_MPU401_H -#include "sound/mididrv.h" +#include "audio/mididrv.h" //////////////////////////////////////// // @@ -46,22 +46,22 @@ private: public: MidiDriver *device(); byte getNumber() { return _channel; } - void release() { _allocated = false; } + virtual void release() { _allocated = false; } - void send(uint32 b); + virtual void send(uint32 b); // Regular messages - void noteOff(byte note); - void noteOn(byte note, byte velocity); - void programChange(byte program); - void pitchBend(int16 bend); + virtual void noteOff(byte note); + virtual void noteOn(byte note, byte velocity); + virtual void programChange(byte program); + virtual void pitchBend(int16 bend); // Control Change messages - void controlChange(byte control, byte value); - void pitchBendFactor(byte value); + virtual void controlChange(byte control, byte value); + virtual void pitchBendFactor(byte value); // SysEx messages - void sysEx_customInstrument(uint32 type, const byte *instr); + virtual void sysEx_customInstrument(uint32 type, const byte *instr); // Only to be called by the owner void init(MidiDriver *owner, byte channel); @@ -78,14 +78,15 @@ private: public: MidiDriver_MPU401(); + virtual ~MidiDriver_MPU401(); virtual void close(); - void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc); - uint32 getBaseTempo(void) { return 10000; } - uint32 property(int prop, uint32 param); + virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc); + virtual uint32 getBaseTempo(void) { return 10000; } + virtual uint32 property(int prop, uint32 param); - MidiChannel *allocateChannel(); - MidiChannel *getPercussionChannel() { return &_midi_channels[9]; } + virtual MidiChannel *allocateChannel(); + virtual MidiChannel *getPercussionChannel() { return &_midi_channels[9]; } }; diff --git a/sound/musicplugin.cpp b/audio/musicplugin.cpp similarity index 98% rename from sound/musicplugin.cpp rename to audio/musicplugin.cpp index 56360b011c2..3f78033a556 100644 --- a/sound/musicplugin.cpp +++ b/audio/musicplugin.cpp @@ -23,7 +23,7 @@ * */ -#include "sound/musicplugin.h" +#include "audio/musicplugin.h" #include "common/hash-str.h" #include "common/translation.h" diff --git a/sound/musicplugin.h b/audio/musicplugin.h similarity index 99% rename from sound/musicplugin.h rename to audio/musicplugin.h index 6b4bdaea9bc..a266cab365d 100644 --- a/sound/musicplugin.h +++ b/audio/musicplugin.h @@ -26,7 +26,7 @@ #define SOUND_MUSICPLUGIN_H #include "base/plugins.h" -#include "sound/mididrv.h" +#include "audio/mididrv.h" #include "common/list.h" class MusicPluginObject; diff --git a/sound/null.cpp b/audio/null.cpp similarity index 98% rename from sound/null.cpp rename to audio/null.cpp index cc615fd8cbb..b08f295b8b2 100644 --- a/sound/null.cpp +++ b/audio/null.cpp @@ -22,7 +22,7 @@ * $Id$ */ -#include "sound/null.h" +#include "audio/null.h" Common::Error NullMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { *mididriver = new MidiDriver_NULL(); diff --git a/sound/null.h b/audio/null.h similarity index 94% rename from sound/null.h rename to audio/null.h index cc806a4c770..41bacb99a01 100644 --- a/sound/null.h +++ b/audio/null.h @@ -25,14 +25,15 @@ #ifndef SOUND_NULL_H #define SOUND_NULL_H -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include "common/translation.h" /* NULL driver */ class MidiDriver_NULL : public MidiDriver_MPU401 { public: int open() { return 0; } + bool isOpen() const { return true; } void send(uint32 b) { } }; diff --git a/sound/rate.cpp b/audio/rate.cpp similarity index 99% rename from sound/rate.cpp rename to audio/rate.cpp index 799979089c5..0e03a3d70c2 100644 --- a/sound/rate.cpp +++ b/audio/rate.cpp @@ -31,9 +31,9 @@ * improvements over the original code were made. */ -#include "sound/audiostream.h" -#include "sound/rate.h" -#include "sound/mixer.h" +#include "audio/audiostream.h" +#include "audio/rate.h" +#include "audio/mixer.h" #include "common/frac.h" #include "common/util.h" diff --git a/sound/rate.h b/audio/rate.h similarity index 100% rename from sound/rate.h rename to audio/rate.h diff --git a/sound/rate_arm.cpp b/audio/rate_arm.cpp similarity index 68% rename from sound/rate_arm.cpp rename to audio/rate_arm.cpp index 2724e2bcf89..d56db37ce42 100644 --- a/sound/rate_arm.cpp +++ b/audio/rate_arm.cpp @@ -44,9 +44,9 @@ * other improvments over the original code were made. */ -#include "sound/audiostream.h" -#include "sound/rate.h" -#include "sound/mixer.h" +#include "audio/audiostream.h" +#include "audio/rate.h" +#include "audio/mixer.h" #include "common/util.h" //#define DEBUG_RATECONV @@ -60,7 +60,7 @@ namespace Audio { * ARM routine we call doesn't respect those definitions. */ #define FRAC_BITS 16 -#define FRAC_ONE (1< int SimpleRateConverter::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) { #ifdef DEBUG_RATECONV -fprintf(stderr, "Simple st=%d rev=%d\n", stereo, reverseStereo); -fflush(stderr); + debug("Simple st=%d rev=%d", stereo, reverseStereo); #endif st_sample_t *ostart = obuf; if (!stereo) { obuf = ARM_SimpleRate_M(input, - &SimpleRate_readFudge, - &sr, - obuf, osamp, vol_l, vol_r); + &SimpleRate_readFudge, + &sr, + obuf, osamp, vol_l, vol_r); } else if (reverseStereo) { obuf = ARM_SimpleRate_R(input, - &SimpleRate_readFudge, - &sr, - obuf, osamp, vol_l, vol_r); + &SimpleRate_readFudge, + &sr, + obuf, osamp, vol_l, vol_r); } else { obuf = ARM_SimpleRate_S(input, - &SimpleRate_readFudge, - &sr, - obuf, osamp, vol_l, vol_r); + &SimpleRate_readFudge, + &sr, + obuf, osamp, vol_l, vol_r); } - return (obuf-ostart)/2; + + return (obuf - ostart) / 2; } /** @@ -242,31 +240,31 @@ extern "C" { } extern "C" st_sample_t *ARM_LinearRate_M( - AudioStream &input, - int (*fn)(Audio::AudioStream&,int16*,int), - LinearRateDetails *lr, - st_sample_t *obuf, - st_size_t osamp, - st_volume_t vol_l, - st_volume_t vol_r); + AudioStream &input, + int (*fn)(Audio::AudioStream&,int16*,int), + LinearRateDetails *lr, + st_sample_t *obuf, + st_size_t osamp, + st_volume_t vol_l, + st_volume_t vol_r); extern "C" st_sample_t *ARM_LinearRate_S( - AudioStream &input, - int (*fn)(Audio::AudioStream&,int16*,int), - LinearRateDetails *lr, - st_sample_t *obuf, - st_size_t osamp, - st_volume_t vol_l, - st_volume_t vol_r); + AudioStream &input, + int (*fn)(Audio::AudioStream&,int16*,int), + LinearRateDetails *lr, + st_sample_t *obuf, + st_size_t osamp, + st_volume_t vol_l, + st_volume_t vol_r); extern "C" st_sample_t *ARM_LinearRate_R( - AudioStream &input, - int (*fn)(Audio::AudioStream&,int16*,int), - LinearRateDetails *lr, - st_sample_t *obuf, - st_size_t osamp, - st_volume_t vol_l, - st_volume_t vol_r); + AudioStream &input, + int (*fn)(Audio::AudioStream&,int16*,int), + LinearRateDetails *lr, + st_sample_t *obuf, + st_size_t osamp, + st_volume_t vol_l, + st_volume_t vol_r); template class LinearRateConverter : public RateConverter { @@ -318,28 +316,33 @@ template int LinearRateConverter::flow(AudioStream &input, st_sample_t *obuf, st_size_t osamp, st_volume_t vol_l, st_volume_t vol_r) { #ifdef DEBUG_RATECONV -fprintf(stderr, "Linear st=%d rev=%d\n", stereo, reverseStereo); -fflush(stderr); + debug("Linear st=%d rev=%d", stereo, reverseStereo); #endif st_sample_t *ostart = obuf; + if (vol_l > 0xff) + vol_l = 0xff; + + if (vol_r > 0xff) + vol_r = 0xff; + if (!stereo) { obuf = ARM_LinearRate_M(input, - &SimpleRate_readFudge, - &lr, - obuf, osamp, vol_l, vol_r); + &SimpleRate_readFudge, + &lr, + obuf, osamp, vol_l, vol_r); } else if (reverseStereo) { obuf = ARM_LinearRate_R(input, - &SimpleRate_readFudge, - &lr, - obuf, osamp, vol_l, vol_r); + &SimpleRate_readFudge, + &lr, + obuf, osamp, vol_l, vol_r); } else { obuf = ARM_LinearRate_S(input, - &SimpleRate_readFudge, - &lr, - obuf, osamp, vol_l, vol_r); + &SimpleRate_readFudge, + &lr, + obuf, osamp, vol_l, vol_r); } - return (obuf-ostart)/2; + return (obuf - ostart) / 2; } @@ -358,31 +361,32 @@ extern "C" { } extern "C" st_sample_t *ARM_CopyRate_M( - st_size_t len, - st_sample_t *obuf, - st_volume_t vol_l, - st_volume_t vol_r, - st_sample_t *_buffer); + st_size_t len, + st_sample_t *obuf, + st_volume_t vol_l, + st_volume_t vol_r, + st_sample_t *_buffer); extern "C" st_sample_t *ARM_CopyRate_S( - st_size_t len, - st_sample_t *obuf, - st_volume_t vol_l, - st_volume_t vol_r, - st_sample_t *_buffer); + st_size_t len, + st_sample_t *obuf, + st_volume_t vol_l, + st_volume_t vol_r, + st_sample_t *_buffer); extern "C" st_sample_t *ARM_CopyRate_R( - st_size_t len, - st_sample_t *obuf, - st_volume_t vol_l, - st_volume_t vol_r, - st_sample_t *_buffer); + st_size_t len, + st_sample_t *obuf, + st_volume_t vol_l, + st_volume_t vol_r, + st_sample_t *_buffer); template class CopyRateConverter : public RateConverter { st_sample_t *_buffer; st_size_t _bufferSize; + public: CopyRateConverter() : _buffer(0), _bufferSize(0) {} ~CopyRateConverter() { @@ -393,11 +397,10 @@ public: assert(input.isStereo() == stereo); #ifdef DEBUG_RATECONV -fprintf(stderr, "Copy st=%d rev=%d\n", stereo, reverseStereo); -fflush(stderr); + debug("Copy st=%d rev=%d", stereo, reverseStereo); #endif st_size_t len; - st_sample_t *ostart = obuf; + st_sample_t *ostart = obuf; if (stereo) osamp *= 2; @@ -422,8 +425,9 @@ fflush(stderr); else obuf = ARM_CopyRate_M(len, obuf, vol_l, vol_r, _buffer); - return (obuf-ostart)/2; + return (obuf - ostart) / 2; } + virtual int drain(st_sample_t *obuf, st_size_t osamp, st_volume_t vol) { return (ST_SUCCESS); } @@ -467,3 +471,5 @@ RateConverter *makeRateConverter(st_rate_t inrate, st_rate_t outrate, bool stere } } // End of namespace Audio + + diff --git a/sound/rate_arm_asm.s b/audio/rate_arm_asm.s similarity index 100% rename from sound/rate_arm_asm.s rename to audio/rate_arm_asm.s diff --git a/sound/softsynth/adlib.cpp b/audio/softsynth/adlib.cpp similarity index 99% rename from sound/softsynth/adlib.cpp rename to audio/softsynth/adlib.cpp index b14951d9463..b4e816621bc 100644 --- a/sound/softsynth/adlib.cpp +++ b/audio/softsynth/adlib.cpp @@ -1,3 +1,4 @@ + /* Residual - A 3D game interpreter * * Residual is the legal property of its developers, whose names @@ -22,11 +23,11 @@ * $Id$ */ -#include "sound/softsynth/emumidi.h" +#include "audio/softsynth/emumidi.h" #include "common/debug.h" #include "common/util.h" -#include "sound/fmopl.h" -#include "sound/musicplugin.h" +#include "audio/fmopl.h" +#include "audio/musicplugin.h" #include "common/translation.h" #ifdef DEBUG_ADLIB @@ -118,7 +119,7 @@ public: byte getNumber() { return _channel; } void release() { _allocated = false; } - void send (uint32 b); + void send(uint32 b); // Regular messages void noteOff(byte note); diff --git a/sound/softsynth/appleiigs.cpp b/audio/softsynth/appleiigs.cpp similarity index 98% rename from sound/softsynth/appleiigs.cpp rename to audio/softsynth/appleiigs.cpp index b69c59478e9..d419ceeb73a 100644 --- a/sound/softsynth/appleiigs.cpp +++ b/audio/softsynth/appleiigs.cpp @@ -23,7 +23,7 @@ * */ -#include "sound/null.h" +#include "audio/null.h" // Plugin interface // (This can only create a null driver since apple II gs support seeems not to be implemented diff --git a/sound/softsynth/cms.cpp b/audio/softsynth/cms.cpp similarity index 71% rename from sound/softsynth/cms.cpp rename to audio/softsynth/cms.cpp index 1e60471d85e..e763af38d7f 100644 --- a/sound/softsynth/cms.cpp +++ b/audio/softsynth/cms.cpp @@ -22,8 +22,8 @@ * $Id$ */ -#include "sound/softsynth/cms.h" -#include "sound/null.h" +#include "audio/softsynth/cms.h" +#include "audio/null.h" #include "common/textconsole.h" #include "common/translation.h" @@ -86,35 +86,39 @@ static const int amplitude_lookup[16] = { void CMSEmulator::portWrite(int port, int val) { switch (port) { - case 0x220: - portWriteIntern(0, 1, val); - break; + case 0x220: + portWriteIntern(0, 1, val); + break; - case 0x221: - _saa1099[0].selected_reg = val & 0x1f; - if (_saa1099[0].selected_reg == 0x18 || _saa1099[0].selected_reg == 0x19) { - /* clock the envelope channels */ - if (_saa1099[0].env_clock[0]) envelope(0, 0); - if (_saa1099[0].env_clock[1]) envelope(0, 1); - } - break; + case 0x221: + _saa1099[0].selected_reg = val & 0x1f; + if (_saa1099[0].selected_reg == 0x18 || _saa1099[0].selected_reg == 0x19) { + /* clock the envelope channels */ + if (_saa1099[0].env_clock[0]) + envelope(0, 0); + if (_saa1099[0].env_clock[1]) + envelope(0, 1); + } + break; - case 0x222: - portWriteIntern(1, 1, val); - break; + case 0x222: + portWriteIntern(1, 1, val); + break; - case 0x223: - _saa1099[1].selected_reg = val & 0x1f; - if (_saa1099[1].selected_reg == 0x18 || _saa1099[1].selected_reg == 0x19) { - /* clock the envelope channels */ - if (_saa1099[1].env_clock[0]) envelope(1, 0); - if (_saa1099[1].env_clock[1]) envelope(1, 1); - } - break; + case 0x223: + _saa1099[1].selected_reg = val & 0x1f; + if (_saa1099[1].selected_reg == 0x18 || _saa1099[1].selected_reg == 0x19) { + /* clock the envelope channels */ + if (_saa1099[1].env_clock[0]) + envelope(1, 0); + if (_saa1099[1].env_clock[1]) + envelope(1, 1); + } + break; - default: - warning("CMSEmulator got port: 0x%X", port); - break; + default: + warning("CMSEmulator got port: 0x%X", port); + break; } } @@ -177,10 +181,10 @@ void CMSEmulator::update(int chip, int16 *buffer, int length) { for (ch = 0; ch < 2; ch++) { switch (saa->noise_params[ch]) { - case 0: saa->noise[ch].freq = 31250.0 * 2; break; - case 1: saa->noise[ch].freq = 15625.0 * 2; break; - case 2: saa->noise[ch].freq = 7812.5 * 2; break; - case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break; + case 0: saa->noise[ch].freq = 31250.0 * 2; break; + case 1: saa->noise[ch].freq = 15625.0 * 2; break; + case 2: saa->noise[ch].freq = 7812.5 * 2; break; + case 3: saa->noise[ch].freq = saa->channels[ch * 3].freq; break; } } @@ -254,95 +258,95 @@ void CMSEmulator::portWriteIntern(int chip, int offset, int data) { int ch; switch (reg) { - /* channel i amplitude */ - case 0x00: - case 0x01: - case 0x02: - case 0x03: - case 0x04: - case 0x05: - ch = reg & 7; - saa->channels[ch].amplitude[LEFT] = amplitude_lookup[data & 0x0f]; - saa->channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f]; - break; + /* channel i amplitude */ + case 0x00: + case 0x01: + case 0x02: + case 0x03: + case 0x04: + case 0x05: + ch = reg & 7; + saa->channels[ch].amplitude[LEFT] = amplitude_lookup[data & 0x0f]; + saa->channels[ch].amplitude[RIGHT] = amplitude_lookup[(data >> 4) & 0x0f]; + break; - /* channel i frequency */ - case 0x08: - case 0x09: - case 0x0a: - case 0x0b: - case 0x0c: - case 0x0d: - ch = reg & 7; - saa->channels[ch].frequency = data & 0xff; - break; + /* channel i frequency */ + case 0x08: + case 0x09: + case 0x0a: + case 0x0b: + case 0x0c: + case 0x0d: + ch = reg & 7; + saa->channels[ch].frequency = data & 0xff; + break; - /* channel i octave */ - case 0x10: - case 0x11: - case 0x12: - ch = (reg - 0x10) << 1; - saa->channels[ch + 0].octave = data & 0x07; - saa->channels[ch + 1].octave = (data >> 4) & 0x07; - break; + /* channel i octave */ + case 0x10: + case 0x11: + case 0x12: + ch = (reg - 0x10) << 1; + saa->channels[ch + 0].octave = data & 0x07; + saa->channels[ch + 1].octave = (data >> 4) & 0x07; + break; - /* channel i frequency enable */ - case 0x14: - saa->channels[0].freq_enable = data & 0x01; - saa->channels[1].freq_enable = data & 0x02; - saa->channels[2].freq_enable = data & 0x04; - saa->channels[3].freq_enable = data & 0x08; - saa->channels[4].freq_enable = data & 0x10; - saa->channels[5].freq_enable = data & 0x20; - break; + /* channel i frequency enable */ + case 0x14: + saa->channels[0].freq_enable = data & 0x01; + saa->channels[1].freq_enable = data & 0x02; + saa->channels[2].freq_enable = data & 0x04; + saa->channels[3].freq_enable = data & 0x08; + saa->channels[4].freq_enable = data & 0x10; + saa->channels[5].freq_enable = data & 0x20; + break; - /* channel i noise enable */ - case 0x15: - saa->channels[0].noise_enable = data & 0x01; - saa->channels[1].noise_enable = data & 0x02; - saa->channels[2].noise_enable = data & 0x04; - saa->channels[3].noise_enable = data & 0x08; - saa->channels[4].noise_enable = data & 0x10; - saa->channels[5].noise_enable = data & 0x20; - break; + /* channel i noise enable */ + case 0x15: + saa->channels[0].noise_enable = data & 0x01; + saa->channels[1].noise_enable = data & 0x02; + saa->channels[2].noise_enable = data & 0x04; + saa->channels[3].noise_enable = data & 0x08; + saa->channels[4].noise_enable = data & 0x10; + saa->channels[5].noise_enable = data & 0x20; + break; - /* noise generators parameters */ - case 0x16: - saa->noise_params[0] = data & 0x03; - saa->noise_params[1] = (data >> 4) & 0x03; - break; + /* noise generators parameters */ + case 0x16: + saa->noise_params[0] = data & 0x03; + saa->noise_params[1] = (data >> 4) & 0x03; + break; - /* envelope generators parameters */ - case 0x18: - case 0x19: - ch = reg - 0x18; - saa->env_reverse_right[ch] = data & 0x01; - saa->env_mode[ch] = (data >> 1) & 0x07; - saa->env_bits[ch] = data & 0x10; - saa->env_clock[ch] = data & 0x20; - saa->env_enable[ch] = data & 0x80; - /* reset the envelope */ - saa->env_step[ch] = 0; - break; + /* envelope generators parameters */ + case 0x18: + case 0x19: + ch = reg - 0x18; + saa->env_reverse_right[ch] = data & 0x01; + saa->env_mode[ch] = (data >> 1) & 0x07; + saa->env_bits[ch] = data & 0x10; + saa->env_clock[ch] = data & 0x20; + saa->env_enable[ch] = data & 0x80; + /* reset the envelope */ + saa->env_step[ch] = 0; + break; - /* channels enable & reset generators */ - case 0x1c: - saa->all_ch_enable = data & 0x01; - saa->sync_state = data & 0x02; - if (data & 0x02) { - int i; - /* Synch & Reset generators */ - for (i = 0; i < 6; i++) { - saa->channels[i].level = 0; - saa->channels[i].counter = 0.0; - } + /* channels enable & reset generators */ + case 0x1c: + saa->all_ch_enable = data & 0x01; + saa->sync_state = data & 0x02; + if (data & 0x02) { + int i; + /* Synch & Reset generators */ + for (i = 0; i < 6; i++) { + saa->channels[i].level = 0; + saa->channels[i].counter = 0.0; } - break; + } + break; - default: - // The CMS allows all registers to be written, so we just output some debug - // message here - debug(5, "CMS Unkown write to reg %x with %x",reg, data); + default: + // The CMS allows all registers to be written, so we just output some debug + // message here + debug(5, "CMS Unknown write to reg %x with %x",reg, data); } } diff --git a/sound/softsynth/cms.h b/audio/softsynth/cms.h similarity index 100% rename from sound/softsynth/cms.h rename to audio/softsynth/cms.h diff --git a/sound/softsynth/emumidi.h b/audio/softsynth/emumidi.h similarity index 79% rename from sound/softsynth/emumidi.h rename to audio/softsynth/emumidi.h index d5b9d902d40..e21cce2d08b 100644 --- a/sound/softsynth/emumidi.h +++ b/audio/softsynth/emumidi.h @@ -25,9 +25,9 @@ #ifndef SOUND_SOFTSYNTH_EMUMIDI_H #define SOUND_SOFTSYNTH_EMUMIDI_H -#include "sound/audiostream.h" -#include "sound/mididrv.h" -#include "sound/mixer.h" +#include "audio/audiostream.h" +#include "audio/mididrv.h" +#include "audio/mixer.h" #define FIXP_SHIFT 16 @@ -45,25 +45,24 @@ private: int _samplesPerTick; protected: + int _baseFreq; + virtual void generateSamples(int16 *buf, int len) = 0; virtual void onTimer() {} - int _baseFreq; - public: - MidiDriver_Emulated(Audio::Mixer *mixer) : _mixer(mixer) { - _isOpen = false; - - _timerProc = 0; - _timerParam = 0; - - _nextTick = 0; - _samplesPerTick = 0; - - _baseFreq = 250; + MidiDriver_Emulated(Audio::Mixer *mixer) : + _mixer(mixer), + _isOpen(false), + _timerProc(0), + _timerParam(0), + _nextTick(0), + _samplesPerTick(0), + _baseFreq(250) { } - int open() { + // MidiDriver API + virtual int open() { _isOpen = true; int d = getRate() / _baseFreq; @@ -73,19 +72,23 @@ public: // but less prone to arithmetic overflow. _samplesPerTick = (d << FIXP_SHIFT) + (r << FIXP_SHIFT) / _baseFreq; + return 0; } - void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) { + bool isOpen() const { return _isOpen; } + + virtual void setTimerCallback(void *timer_param, Common::TimerManager::TimerProc timer_proc) { _timerProc = timer_proc; _timerParam = timer_param; } - uint32 getBaseTempo() { return 1000000 / _baseFreq; } - + virtual uint32 getBaseTempo() { + return 1000000 / _baseFreq; + } // AudioStream API - int readBuffer(int16 *data, const int numSamples) { + virtual int readBuffer(int16 *data, const int numSamples) { const int stereoFactor = isStereo() ? 2 : 1; int len = numSamples / stereoFactor; int step; @@ -101,16 +104,22 @@ public: if (!(_nextTick >> FIXP_SHIFT)) { if (_timerProc) (*_timerProc)(_timerParam); + onTimer(); + _nextTick += _samplesPerTick; } + data += step * stereoFactor; len -= step; } while (len); return numSamples; } - bool endOfData() const { return false; } + + virtual bool endOfData() const { + return false; + } }; #endif diff --git a/sound/softsynth/fluidsynth.cpp b/audio/softsynth/fluidsynth.cpp similarity index 95% rename from sound/softsynth/fluidsynth.cpp rename to audio/softsynth/fluidsynth.cpp index 809aebc1ba8..889ad431e5b 100644 --- a/sound/softsynth/fluidsynth.cpp +++ b/audio/softsynth/fluidsynth.cpp @@ -27,9 +27,9 @@ #ifdef USE_FLUIDSYNTH #include "common/config-manager.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" -#include "sound/softsynth/emumidi.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" +#include "audio/softsynth/emumidi.h" #include @@ -40,7 +40,6 @@ private: fluid_synth_t *_synth; int _soundFont; int _outputRate; - Audio::SoundHandle _handle; protected: // Because GCC complains about casting from const to non-const... @@ -144,7 +143,7 @@ int MidiDriver_FluidSynth::open() { MidiDriver_Emulated::open(); // The MT-32 emulator uses kSFXSoundType here. I don't know why. - _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); return 0; } @@ -153,7 +152,7 @@ void MidiDriver_FluidSynth::close() { return; _isOpen = false; - _mixer->stopHandle(_handle); + _mixer->stopHandle(_mixerSoundHandle); if (_soundFont != -1) fluid_synth_sfunload(_synth, _soundFont, 1); diff --git a/sound/softsynth/mt32.cpp b/audio/softsynth/mt32.cpp similarity index 96% rename from sound/softsynth/mt32.cpp rename to audio/softsynth/mt32.cpp index 86e9e642fcf..dc8270cd54c 100644 --- a/sound/softsynth/mt32.cpp +++ b/audio/softsynth/mt32.cpp @@ -26,11 +26,11 @@ #ifdef USE_MT32EMU -#include "sound/softsynth/mt32/mt32emu.h" +#include "audio/softsynth/mt32/mt32emu.h" -#include "sound/softsynth/emumidi.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/softsynth/emumidi.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include "common/config-manager.h" #include "common/debug.h" @@ -51,7 +51,6 @@ class MidiChannel_MT32 : public MidiChannel_MPU401 { class MidiDriver_MT32 : public MidiDriver_Emulated { private: - Audio::SoundHandle _handle; MidiChannel_MT32 _midiChannels[16]; uint16 _channelMask; MT32Emu::Synth *_synth; @@ -149,7 +148,7 @@ static void drawProgress(float progress) { Common::Rect r(x, y, x + w, y + h); uint32 col; - + if (screenFormat.bytesPerPixel > 1) col = screenFormat.RGBToColor(0, 171, 0); else @@ -230,8 +229,7 @@ static void MT32_PrintDebug(void *userData, const char *fmt, va_list list) { static int MT32_Report(void *userData, MT32Emu::ReportType type, const void *reportData) { switch (type) { case MT32Emu::ReportType_lcdMessage: - // FIXME implament in Residual -// g_system->displayMessageOnOSD((const char *)reportData); + g_system->displayMessageOnOSD((const char *)reportData); break; case MT32Emu::ReportType_errorControlROM: error("Failed to load MT32_CONTROL.ROM"); @@ -317,9 +315,9 @@ int MidiDriver_MT32::open() { if (screenFormat.bytesPerPixel == 1) { const byte dummy_palette[] = { - 0, 0, 0, 0, // background - 0, 171, 0, 0, // border, font - 171, 0, 0, 0 // fill + 0, 0, 0, // background + 0, 171, 0, // border, font + 171, 0, 0 // fill }; // TODO implement in Residual @@ -340,7 +338,7 @@ int MidiDriver_MT32::open() { g_system->updateScreen();*/ - _mixer->playStream(Audio::Mixer::kSFXSoundType, &_handle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); + _mixer->playStream(Audio::Mixer::kSFXSoundType, &_mixerSoundHandle, this, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::NO, true); return 0; } @@ -382,7 +380,7 @@ void MidiDriver_MT32::close() { // Detach the player callback handler setTimerCallback(NULL, NULL); // Detach the mixer callback handler - _mixer->stopHandle(_handle); + _mixer->stopHandle(_mixerSoundHandle); _synth->close(); delete _synth; diff --git a/sound/softsynth/mt32/freeverb.cpp b/audio/softsynth/mt32/freeverb.cpp similarity index 99% rename from sound/softsynth/mt32/freeverb.cpp rename to audio/softsynth/mt32/freeverb.cpp index 7118f6a1777..797de4ff08d 100644 --- a/sound/softsynth/mt32/freeverb.cpp +++ b/audio/softsynth/mt32/freeverb.cpp @@ -29,7 +29,7 @@ // http://www.dreampoint.co.uk // This code is public domain -#include "sound/softsynth/mt32/freeverb.h" +#include "audio/softsynth/mt32/freeverb.h" comb::comb() { filterstore = 0; @@ -125,12 +125,12 @@ revmodel::revmodel() { allpassR[2].setfeedback(0.5f); allpassL[3].setfeedback(0.5f); allpassR[3].setfeedback(0.5f); + setmode(initialmode); setwet(initialwet); setroomsize(initialroom); setdry(initialdry); setdamp(initialdamp); setwidth(initialwidth); - setmode(initialmode); // Buffer will be full of rubbish - so we MUST mute them mute(); diff --git a/sound/softsynth/mt32/freeverb.h b/audio/softsynth/mt32/freeverb.h similarity index 100% rename from sound/softsynth/mt32/freeverb.h rename to audio/softsynth/mt32/freeverb.h diff --git a/sound/softsynth/mt32/i386.cpp b/audio/softsynth/mt32/i386.cpp similarity index 100% rename from sound/softsynth/mt32/i386.cpp rename to audio/softsynth/mt32/i386.cpp diff --git a/sound/softsynth/mt32/i386.h b/audio/softsynth/mt32/i386.h similarity index 100% rename from sound/softsynth/mt32/i386.h rename to audio/softsynth/mt32/i386.h diff --git a/sound/softsynth/mt32/module.mk b/audio/softsynth/mt32/module.mk similarity index 84% rename from sound/softsynth/mt32/module.mk rename to audio/softsynth/mt32/module.mk index 4d5d899ac31..a8329bc98cf 100644 --- a/sound/softsynth/mt32/module.mk +++ b/audio/softsynth/mt32/module.mk @@ -1,4 +1,4 @@ -MODULE := sound/softsynth/mt32 +MODULE := audio/softsynth/mt32 MODULE_OBJS := \ mt32_file.o \ diff --git a/audio/softsynth/mt32/mt32_file.cpp b/audio/softsynth/mt32/mt32_file.cpp new file mode 100644 index 00000000000..cdf9fa13f6a --- /dev/null +++ b/audio/softsynth/mt32/mt32_file.cpp @@ -0,0 +1,70 @@ +/* Copyright (c) 2003-2005 Various contributors + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + + +#include "mt32emu.h" + +namespace MT32Emu { + +bool File::readBit16u(Bit16u *in) { + Bit8u b[2]; + if (read(&b[0], 2) != 2) + return false; + *in = ((b[0] << 8) | b[1]); + return true; +} + +bool File::readBit32u(Bit32u *in) { + Bit8u b[4]; + if (read(&b[0], 4) != 4) + return false; + *in = ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]); + return true; +} + +bool File::writeBit16u(Bit16u out) { + if (!writeBit8u((Bit8u)((out & 0xFF00) >> 8))) { + return false; + } + if (!writeBit8u((Bit8u)(out & 0x00FF))) { + return false; + } + return true; +} + +bool File::writeBit32u(Bit32u out) { + if (!writeBit8u((Bit8u)((out & 0xFF000000) >> 24))) { + return false; + } + if (!writeBit8u((Bit8u)((out & 0x00FF0000) >> 16))) { + return false; + } + if (!writeBit8u((Bit8u)((out & 0x0000FF00) >> 8))) { + return false; + } + if (!writeBit8u((Bit8u)(out & 0x000000FF))) { + return false; + } + return true; +} + +} // End of namespace MT32Emu + diff --git a/sound/softsynth/mt32/mt32_file.h b/audio/softsynth/mt32/mt32_file.h similarity index 85% rename from sound/softsynth/mt32/mt32_file.h rename to audio/softsynth/mt32/mt32_file.h index 27c8ccbe468..177936a014e 100644 --- a/sound/softsynth/mt32/mt32_file.h +++ b/audio/softsynth/mt32/mt32_file.h @@ -22,7 +22,7 @@ #ifndef MT32EMU_FILE_H #define MT32EMU_FILE_H -#include +#include "common/sys.h" namespace MT32Emu { @@ -47,19 +47,6 @@ public: virtual bool isEOF() = 0; }; -class ANSIFile: public File { -private: - FILE *fp; -public: - bool open(const char *filename, OpenMode mode); - void close(); - size_t read(void *in, size_t size); - bool readBit8u(Bit8u *in); - size_t write(const void *out, size_t size); - bool writeBit8u(Bit8u out); - bool isEOF(); -}; - -} +} // End of namespace MT32Emu #endif diff --git a/sound/softsynth/mt32/mt32emu.h b/audio/softsynth/mt32/mt32emu.h similarity index 100% rename from sound/softsynth/mt32/mt32emu.h rename to audio/softsynth/mt32/mt32emu.h diff --git a/sound/softsynth/mt32/part.cpp b/audio/softsynth/mt32/part.cpp similarity index 99% rename from sound/softsynth/mt32/part.cpp rename to audio/softsynth/mt32/part.cpp index b3d71bccca2..eb087f7ea03 100644 --- a/sound/softsynth/mt32/part.cpp +++ b/audio/softsynth/mt32/part.cpp @@ -283,6 +283,7 @@ void Part::cacheTimbre(PatchCache cache[4], const TimbreParam *timbre) { backupCacheToPartials(cache); int partialCount = 0; for (int t = 0; t < 4; t++) { + cache[t].PCMPartial = false; if (((timbre->common.pmute >> t) & 0x1) == 1) { cache[t].playPartial = true; partialCount++; diff --git a/sound/softsynth/mt32/part.h b/audio/softsynth/mt32/part.h similarity index 100% rename from sound/softsynth/mt32/part.h rename to audio/softsynth/mt32/part.h diff --git a/sound/softsynth/mt32/partial.cpp b/audio/softsynth/mt32/partial.cpp similarity index 98% rename from sound/softsynth/mt32/partial.cpp rename to audio/softsynth/mt32/partial.cpp index f016084d8cb..5ba9ef6145b 100644 --- a/sound/softsynth/mt32/partial.cpp +++ b/audio/softsynth/mt32/partial.cpp @@ -118,7 +118,7 @@ void Partial::initKeyFollow(int key) { #endif #if MT32EMU_ACCURATENOTES == 1 noteVal = newPitch; - synth->printDebug("key=%d, pitch=%f, pitchKeyfollow=%f, pitchShift=%f, newPitch=%f", key, patchCache->pitch, patchCache->pitchKeyfollow, patchCache->pitchShift, newPitch); + synth->printDebug("key=%d, pitch=%f, pitchKeyfollow=%f, pitchShift=%f, newPitch=%f", key, (double)patchCache->pitch, (double)patchCache->pitchKeyfollow, (double)patchCache->pitchShift, (double)newPitch); #else float newPitchInt; float newPitchFract = modff(newPitch, &newPitchInt); @@ -128,7 +128,7 @@ void Partial::initKeyFollow(int key) { } noteVal = (int)newPitchInt; fineShift = (int)(powf(2.0f, newPitchFract / 12.0f) * 4096.0f); - synth->printDebug("key=%d, pitch=%f, pitchKeyfollow=%f, pitchShift=%f, newPitch=%f, noteVal=%d, fineShift=%d", key, patchCache->pitch, patchCache->pitchKeyfollow, patchCache->pitchShift, newPitch, noteVal, fineShift); + synth->printDebug("key=%d, pitch=%f, pitchKeyfollow=%f, pitchShift=%f, newPitch=%f, noteVal=%d, fineShift=%d", key, (double)patchCache->pitch, (double)patchCache->pitchKeyfollow, (double)patchCache->pitchShift, (double)newPitch, noteVal, fineShift); #endif // FIXME:KG: Raise/lower by octaves until in the supported range. while (noteVal > HIGHEST_NOTE) // FIXME:KG: see tables.cpp: >108? @@ -451,7 +451,7 @@ void Partial::setBend(float factor) { // FIXME:KG: Bend should be influenced by pitch key-follow too, according to docs. float bendSemitones = factor * patchCache->benderRange; // -24 .. 24 float mult = powf(2.0f, bendSemitones / 12.0f); - synth->printDebug("setBend(): factor=%f, benderRange=%f, semitones=%f, mult=%f\n", factor, patchCache->benderRange, bendSemitones, mult); + synth->printDebug("setBend(): factor=%f, benderRange=%f, semitones=%f, mult=%f\n", (double)factor, (double)patchCache->benderRange, (double)bendSemitones, (double)mult); bendShift = (int)(mult * 4096.0f); } diff --git a/sound/softsynth/mt32/partial.h b/audio/softsynth/mt32/partial.h similarity index 100% rename from sound/softsynth/mt32/partial.h rename to audio/softsynth/mt32/partial.h diff --git a/sound/softsynth/mt32/partialManager.cpp b/audio/softsynth/mt32/partialManager.cpp similarity index 100% rename from sound/softsynth/mt32/partialManager.cpp rename to audio/softsynth/mt32/partialManager.cpp diff --git a/sound/softsynth/mt32/partialManager.h b/audio/softsynth/mt32/partialManager.h similarity index 100% rename from sound/softsynth/mt32/partialManager.h rename to audio/softsynth/mt32/partialManager.h diff --git a/sound/softsynth/mt32/structures.h b/audio/softsynth/mt32/structures.h similarity index 100% rename from sound/softsynth/mt32/structures.h rename to audio/softsynth/mt32/structures.h diff --git a/sound/softsynth/mt32/synth.cpp b/audio/softsynth/mt32/synth.cpp similarity index 98% rename from sound/softsynth/mt32/synth.cpp rename to audio/softsynth/mt32/synth.cpp index 6a16db22eca..16460795a54 100644 --- a/sound/softsynth/mt32/synth.cpp +++ b/audio/softsynth/mt32/synth.cpp @@ -162,21 +162,11 @@ void Synth::initReverb(Bit8u newRevMode, Bit8u newRevTime, Bit8u newRevLevel) { } File *Synth::openFile(const char *filename, File::OpenMode mode) { - if (myProp.openFile != NULL) { - return myProp.openFile(myProp.userData, filename, mode); - } - char pathBuf[2048]; - if (myProp.baseDir != NULL) { - strcpy(&pathBuf[0], myProp.baseDir); - strcat(&pathBuf[0], filename); - filename = pathBuf; - } - ANSIFile *file = new ANSIFile(); - if (!file->open(filename, mode)) { - delete file; - return NULL; - } - return file; + // It should never happen that openFile is NULL in our use case. + // Just to cover the case where something is horrible wrong we + // use an assert here. + assert(myProp.openFile != NULL); + return myProp.openFile(myProp.userData, filename, mode); } void Synth::closeFile(File *file) { @@ -326,7 +316,7 @@ bool Synth::initPCMList(Bit16u mapAddress, Bit16u count) { // The number below is confirmed to a reasonable degree of accuracy on CM-32L double STANDARDFREQ = 442.0; float rTune = (float)(STANDARDFREQ * pow(2.0, (0x5000 - rTuneOffset) / 4056.0 - 9.0 / 12.0)); - //printDebug("%f,%d,%d", pTune, tps[i].pitchCoarse, tps[i].pitchFine); + //printDebug("%f,%d,%d", (double)pTune, tps[i].pitchCoarse, tps[i].pitchFine); if (rAddr + rLen > pcmROMSize) { printDebug("Control ROM error: Wave map entry %d points to invalid PCM address 0x%04X, length 0x%04X", i, rAddr, rLen); return false; @@ -347,7 +337,8 @@ bool Synth::initRhythmTimbre(int timbreNum, const Bit8u *mem, unsigned int memLe memcpy(&timbre->common, mem, 14); unsigned int memPos = 14; char drumname[11]; - Common::strlcpy(drumname, timbre->common.name, 11); + memset(drumname, 0, 11); + memcpy(drumname, timbre->common.name, 10); for (int t = 0; t < 4; t++) { if (((timbre->common.pmute >> t) & 0x1) == 0x1) { if (memPos + 58 >= memLen) { @@ -1030,7 +1021,7 @@ bool Synth::refreshSystem() { // The LAPC-I documentation claims a range of 427.5Hz-452.6Hz (similar to what we have here) // The MT-32 documentation claims a range of 432.1Hz-457.6Hz masterTune = 440.0f * powf(2.0f, (mt32ram.system.masterTune - 64.0f) / (128.0f * 12.0f)); - printDebug(" Master Tune: %f", masterTune); + printDebug(" Master Tune: %f", (double)masterTune); printDebug(" Reverb: mode=%d, time=%d, level=%d", mt32ram.system.reverbMode, mt32ram.system.reverbTime, mt32ram.system.reverbLevel); report(ReportType_newReverbMode, &mt32ram.system.reverbMode); report(ReportType_newReverbTime, &mt32ram.system.reverbTime); diff --git a/sound/softsynth/mt32/synth.h b/audio/softsynth/mt32/synth.h similarity index 100% rename from sound/softsynth/mt32/synth.h rename to audio/softsynth/mt32/synth.h diff --git a/sound/softsynth/mt32/tables.cpp b/audio/softsynth/mt32/tables.cpp similarity index 97% rename from sound/softsynth/mt32/tables.cpp rename to audio/softsynth/mt32/tables.cpp index b0414154dc8..eba4d2a520c 100644 --- a/sound/softsynth/mt32/tables.cpp +++ b/audio/softsynth/mt32/tables.cpp @@ -329,7 +329,7 @@ void Tables::initMT32ConstantTables(Synth *synth) { tdist = (lf - 25.0f) / 25.0f; padjtable[lf] = 1.0f - tdist; } - //synth->printDebug("lf %d = padj %f", lf, padjtable[lf]); + //synth->printDebug("lf %d = padj %f", lf, (double)padjtable[lf]); } float lfp, depf, finalval, tlf; @@ -352,7 +352,7 @@ void Tables::initMT32ConstantTables(Synth *synth) { pval = (int)finalval; pitchEnvVal[lf][depat] = pval; - //synth->printDebug("lf %d depat %d pval %d tlf %f lfp %f", lf,depat,pval, tlf, lfp); + //synth->printDebug("lf %d depat %d pval %d tlf %f lfp %f", lf,depat,pval, (double)tlf, (double)lfp); } else { pitchEnvVal[lf][depat] = 4096; //synth->printDebug("lf %d depat %d pval 4096", lf, depat); @@ -402,7 +402,7 @@ void Tables::initMT32ConstantTables(Synth *synth) { tvaBiasMult[lf][distval] = (int)(dval * 256.0f); } } - //synth->printDebug("Ampbias lf %d distval %d = %f (%x) %f", lf, distval, dval, tvaBiasMult[lf][distval],amplog); + //synth->printDebug("Ampbias lf %d distval %d = %f (%x) %f", lf, distval, (double)dval, tvaBiasMult[lf][distval],(double)amplog); } } @@ -430,7 +430,7 @@ void Tables::initMT32ConstantTables(Synth *synth) { tvfBiasMult[lf][distval] = (int)(dval * 256.0f); } } - //synth->printDebug("Fbias lf %d distval %d = %f (%x) %f", lf, distval, dval, tvfBiasMult[lf][distval],amplog); + //synth->printDebug("Fbias lf %d distval %d = %f (%x) %f", lf, distval, (double)dval, tvfBiasMult[lf][distval],(double)amplog); } } } @@ -471,7 +471,7 @@ static void initDep(KeyLookup *keyLookup, float f) { keyLookup->envTimeMult[dep] = (int)(ff * 256.0f); } } - //synth->printDebug("F %f d1 %x d2 %x d3 %x d4 %x d5 %x", f, noteLookup->fildepTable[0], noteLookup->fildepTable[1], noteLookup->fildepTable[2], noteLookup->fildepTable[3], noteLookup->fildepTable[4]); + //synth->printDebug("F %f d1 %x d2 %x d3 %x d4 %x d5 %x", (double)f, noteLookup->fildepTable[0], noteLookup->fildepTable[1], noteLookup->fildepTable[2], noteLookup->fildepTable[3], noteLookup->fildepTable[4]); } Bit16s Tables::clampWF(Synth *synth, const char *n, float ampVal, double input) { @@ -586,8 +586,8 @@ File *Tables::initNote(Synth *synth, NoteLookup *noteLookup, float note, float r initSaw(noteLookup, noteLookup->div2); - //synth->printDebug("Note %f; freq=%f, div=%f", note, freq, rate / freq); - file = initWave(synth, noteLookup, (const float)WGAMP, div2, file); + //synth->printDebug("Note %f; freq=%f, div=%f", (double)note, (double)freq, (double) rate / freq); + file = initWave(synth, noteLookup, WGAMP, div2, file); // Create the pitch tables if (noteLookup->wavTable == NULL) @@ -730,7 +730,7 @@ Tables::Tables() { bool Tables::init(Synth *synth, PCMWaveEntry *pcmWaves, float sampleRate, float masterTune) { if (sampleRate <= 0.0f) { - synth->printDebug("Bad sampleRate (%f <= 0.0f)", sampleRate); + synth->printDebug("Bad sampleRate (%f <= 0.0f)", (double)sampleRate); return false; } if (initialisedSampleRate == 0.0f) { diff --git a/sound/softsynth/mt32/tables.h b/audio/softsynth/mt32/tables.h similarity index 100% rename from sound/softsynth/mt32/tables.h rename to audio/softsynth/mt32/tables.h diff --git a/sound/softsynth/opl/dbopl.cpp b/audio/softsynth/opl/dbopl.cpp similarity index 99% rename from sound/softsynth/opl/dbopl.cpp rename to audio/softsynth/opl/dbopl.cpp index db07eaf8cc5..2c46cfee758 100644 --- a/sound/softsynth/opl/dbopl.cpp +++ b/audio/softsynth/opl/dbopl.cpp @@ -41,10 +41,6 @@ namespace OPL { namespace DOSBox { -#ifndef PI -#define PI 3.14159265358979323846 -#endif - namespace DBOPL { #define OPLRATE ((double)(14318180.0 / 288.0)) @@ -224,7 +220,7 @@ static inline Bits MakeVolume( Bitu wave, Bitu volume ) { } #endif return (sig >> exp); -}; +} static Bits DB_FASTCALL WaveForm0( Bitu i, Bitu volume ) { Bits neg = 0 - (( i >> 9) & 1);//Create ~0 or 0 @@ -418,7 +414,7 @@ Bits Operator::TemplateVolume( ) { } //In sustain phase, but not sustaining, do regular release case RELEASE: - vol += RateForward( releaseAdd );; + vol += RateForward( releaseAdd ); if ( GCC_UNLIKELY(vol >= ENV_MAX) ) { volume = ENV_MAX; SetState( OFF ); @@ -576,7 +572,7 @@ INLINE Bits Operator::GetWave( Bitu index, Bitu vol ) { return (waveBase[ index & waveMask ] * MulTable[ vol >> ENV_EXTRA ]) >> MUL_SH; #elif ( DBOPL_WAVE == WAVE_TABLELOG ) Bit32s wave = waveBase[ index & waveMask ]; - Bit32u total = ( wave & 0x7fff ) + vol << ( 3 - ENV_EXTRA ); + Bit32u total = ( wave & 0x7fff ) + ( vol << ( 3 - ENV_EXTRA ) ); Bit32s sig = ExpTable[ total & 0xff ]; Bit32u exp = total >> 8; Bit32s neg = wave >> 16; @@ -1392,7 +1388,7 @@ void InitTables( void ) { //Add 0.5 for the trunc rounding of the integer cast //Do a PI sinetable instead of the original 0.5 PI for ( int i = 0; i < 512; i++ ) { - SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); + SinTable[i] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (M_PI / 512.0) ) ) / log10(2.0)*256 ); } #endif #if ( DBOPL_WAVE == WAVE_TABLEMUL ) @@ -1406,7 +1402,7 @@ void InitTables( void ) { //Sine Wave Base for ( int i = 0; i < 512; i++ ) { - WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (PI / 512.0) ) * 4084); + WaveTable[ 0x0200 + i ] = (Bit16s)(sin( (i + 0.5) * (M_PI / 512.0) ) * 4084); WaveTable[ 0x0000 + i ] = -WaveTable[ 0x200 + i ]; } //Exponential wave @@ -1418,7 +1414,7 @@ void InitTables( void ) { #if ( DBOPL_WAVE == WAVE_TABLELOG ) //Sine Wave Base for ( int i = 0; i < 512; i++ ) { - WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (PI / 512.0) ) ) / log10(2.0)*256 ); + WaveTable[ 0x0200 + i ] = (Bit16s)( 0.5 - log10( sin( (i + 0.5) * (M_PI / 512.0) ) ) / log10(2.0)*256 ); WaveTable[ 0x0000 + i ] = ((Bit16s)0x8000) | WaveTable[ 0x200 + i]; } //Exponential wave diff --git a/sound/softsynth/opl/dbopl.h b/audio/softsynth/opl/dbopl.h similarity index 100% rename from sound/softsynth/opl/dbopl.h rename to audio/softsynth/opl/dbopl.h diff --git a/sound/softsynth/opl/dosbox.cpp b/audio/softsynth/opl/dosbox.cpp similarity index 100% rename from sound/softsynth/opl/dosbox.cpp rename to audio/softsynth/opl/dosbox.cpp diff --git a/sound/softsynth/opl/dosbox.h b/audio/softsynth/opl/dosbox.h similarity index 98% rename from sound/softsynth/opl/dosbox.h rename to audio/softsynth/opl/dosbox.h index 6dcd3147873..06001cbf047 100644 --- a/sound/softsynth/opl/dosbox.h +++ b/audio/softsynth/opl/dosbox.h @@ -34,7 +34,7 @@ #ifndef DISABLE_DOSBOX_OPL -#include "sound/fmopl.h" +#include "audio/fmopl.h" namespace OPL { namespace DOSBox { diff --git a/sound/softsynth/opl/mame.cpp b/audio/softsynth/opl/mame.cpp similarity index 99% rename from sound/softsynth/opl/mame.cpp rename to audio/softsynth/opl/mame.cpp index 79a5803aec3..e446ccbacfe 100644 --- a/sound/softsynth/opl/mame.cpp +++ b/audio/softsynth/opl/mame.cpp @@ -694,7 +694,7 @@ static int OPLOpenTable(void) { return 0; } /* make total level table */ - for (t = 0; t < EG_ENT - 1 ; t++) { + for (t = 0; t < EG_ENT - 1; t++) { rate = ((1 << TL_BITS) - 1) / pow(10.0, EG_STEP * t / 20); /* dB -> voltage */ TL_TABLE[ t] = (int)rate; TL_TABLE[TL_MAX + t] = -TL_TABLE[t]; @@ -708,7 +708,7 @@ static int OPLOpenTable(void) { /* degree 0 = degree 180 = off */ SIN_TABLE[0] = SIN_TABLE[SIN_ENT /2 ] = &TL_TABLE[EG_ENT - 1]; for (s = 1;s <= SIN_ENT / 4; s++) { - pom = sin(2 * LOCAL_PI * s / SIN_ENT); /* sin */ + pom = sin(2 * M_PI * s / SIN_ENT); /* sin */ pom = 20 * log10(1 / pom); /* decibel */ j = int(pom / EG_STEP); /* TL_TABLE steps */ @@ -739,14 +739,14 @@ static int OPLOpenTable(void) { ENV_CURVE[EG_OFF >> ENV_BITS]= EG_ENT - 1; /* make LFO ams table */ for (i=0; i < AMS_ENT; i++) { - pom = (1.0 + sin(2 * LOCAL_PI * i / AMS_ENT)) / 2; /* sin */ + pom = (1.0 + sin(2 * M_PI * i / AMS_ENT)) / 2; /* sin */ AMS_TABLE[i] = (int)((1.0 / EG_STEP) * pom); /* 1dB */ AMS_TABLE[AMS_ENT + i] = (int)((4.8 / EG_STEP) * pom); /* 4.8dB */ } /* make LFO vibrate table */ for (i=0; i < VIB_ENT; i++) { /* 100cent = 1seminote = 6% ?? */ - pom = (double)VIB_RATE * 0.06 * sin(2 * LOCAL_PI * i / VIB_ENT); /* +-100sect step */ + pom = (double)VIB_RATE * 0.06 * sin(2 * M_PI * i / VIB_ENT); /* +-100sect step */ VIB_TABLE[i] = (int)(VIB_RATE + (pom * 0.07)); /* +- 7cent */ VIB_TABLE[VIB_ENT + i] = (int)(VIB_RATE + (pom * 0.14)); /* +-14cent */ } @@ -1082,10 +1082,10 @@ void OPLResetChip(FM_OPL *OPL) { for (i = 0xff; i >= 0x20; i--) OPLWriteReg(OPL,i,0); /* reset OPerator parameter */ - for (c = 0; c < OPL->max_ch ;c++ ) { + for (c = 0; c < OPL->max_ch; c++) { OPL_CH *CH = &OPL->P_CH[c]; /* OPL->P_CH[c].PAN = OPN_CENTER; */ - for (s = 0; s < 2; s++ ) { + for (s = 0; s < 2; s++) { /* wave table */ CH->SLOT[s].wavetable = &SIN_TABLE[0]; /* CH->SLOT[s].evm = ENV_MOD_RR; */ diff --git a/sound/softsynth/opl/mame.h b/audio/softsynth/opl/mame.h similarity index 99% rename from sound/softsynth/opl/mame.h rename to audio/softsynth/opl/mame.h index f34a00dcc73..8f055d70b62 100644 --- a/sound/softsynth/opl/mame.h +++ b/audio/softsynth/opl/mame.h @@ -33,7 +33,7 @@ #include "common/util.h" #include "common/random.h" -#include "sound/fmopl.h" +#include "audio/fmopl.h" namespace OPL { namespace MAME { diff --git a/sound/softsynth/pcspk.cpp b/audio/softsynth/pcspk.cpp similarity index 96% rename from sound/softsynth/pcspk.cpp rename to audio/softsynth/pcspk.cpp index 052c8fbaba6..e973a1f9127 100644 --- a/sound/softsynth/pcspk.cpp +++ b/audio/softsynth/pcspk.cpp @@ -23,8 +23,8 @@ * */ -#include "sound/softsynth/pcspk.h" -#include "sound/null.h" +#include "audio/softsynth/pcspk.h" +#include "audio/null.h" namespace Audio { @@ -109,7 +109,7 @@ int8 PCSpeaker::generateSine(uint32 x, uint32 oscLength) { return 0; // TODO: Maybe using a look-up-table would be better? - return CLIP((int16) (128 * sin(2.0 * LOCAL_PI * x / oscLength)), -128, 127); + return CLIP((int16) (128 * sin(2.0 * M_PI * x / oscLength)), -128, 127); } int8 PCSpeaker::generateSaw(uint32 x, uint32 oscLength) { diff --git a/sound/softsynth/pcspk.h b/audio/softsynth/pcspk.h similarity index 97% rename from sound/softsynth/pcspk.h rename to audio/softsynth/pcspk.h index 3542fac34d8..bf5def9dc4c 100644 --- a/sound/softsynth/pcspk.h +++ b/audio/softsynth/pcspk.h @@ -25,8 +25,8 @@ #ifndef SOUND_SOFTSYNTH_PCSPK_H #define SOUND_SOFTSYNTH_PCSPK_H -#include "sound/audiostream.h" -#include "sound/mixer.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" #include "common/mutex.h" namespace Audio { diff --git a/sound/softsynth/sid.cpp b/audio/softsynth/sid.cpp similarity index 97% rename from sound/softsynth/sid.cpp rename to audio/softsynth/sid.cpp index 9453f7e3a92..52b5140973d 100644 --- a/sound/softsynth/sid.cpp +++ b/audio/softsynth/sid.cpp @@ -31,7 +31,7 @@ #ifndef DISABLE_SID #include "sid.h" -#include "sound/null.h" +#include "audio/null.h" #include namespace Resid { @@ -1423,4 +1423,34 @@ int SID::clock(cycle_count& delta_t, short* buf, int n, int interleave) { } +// Plugin interface +// (This can only create a null driver since C64 audio support is not part of the +// midi driver architecture. But we need the plugin for the options menu in the launcher +// and for MidiDriver::detectDevice() which is more or less used by all engines.) + +class C64MusicPlugin : public NullMusicPlugin { +public: + const char *getName() const { + return _s("C64 Audio Emulator"); + } + + const char *getId() const { + return "C64"; + } + + MusicDevices getDevices() const; +}; + +MusicDevices C64MusicPlugin::getDevices() const { + MusicDevices devices; + devices.push_back(MusicDevice(this, "", MT_C64)); + return devices; +} + +//#if PLUGIN_ENABLED_DYNAMIC(C64) + //REGISTER_PLUGIN_DYNAMIC(C64, PLUGIN_TYPE_MUSIC, C64MusicPlugin); +//#else + REGISTER_PLUGIN_STATIC(C64, PLUGIN_TYPE_MUSIC, C64MusicPlugin); +//#endif + #endif diff --git a/sound/softsynth/sid.h b/audio/softsynth/sid.h similarity index 100% rename from sound/softsynth/sid.h rename to audio/softsynth/sid.h diff --git a/sound/softsynth/wave6581.cpp b/audio/softsynth/wave6581.cpp similarity index 100% rename from sound/softsynth/wave6581.cpp rename to audio/softsynth/wave6581.cpp diff --git a/sound/softsynth/ym2612.cpp b/audio/softsynth/ym2612.cpp similarity index 99% rename from sound/softsynth/ym2612.cpp rename to audio/softsynth/ym2612.cpp index d8aad99c9d6..91ad0032a48 100644 --- a/sound/softsynth/ym2612.cpp +++ b/audio/softsynth/ym2612.cpp @@ -24,9 +24,9 @@ #include -#include "sound/softsynth/ym2612.h" +#include "audio/softsynth/ym2612.h" #include "common/util.h" -#include "sound/musicplugin.h" +#include "audio/musicplugin.h" #include "common/translation.h" //////////////////////////////////////// @@ -677,14 +677,14 @@ void MidiDriver_YM2612::createLookupTables() { int i; sintbl = new int [2048]; for (i = 0; i < 2048; i++) - sintbl[i] = (int)(0xffff * sin(i/2048.0*2.0*LOCAL_PI)); + sintbl[i] = (int)(0xffff * sin(i/2048.0 * 2.0 * M_PI)); } { int i; powtbl = new int [1025]; for (i = 0; i <= 1024; i++) - powtbl[i] = (int)(0x10000 * pow(2.0, (i-512)/512.0)); + powtbl[i] = (int)(0x10000 * pow(2.0, (i - 512) / 512.0)); } { diff --git a/sound/softsynth/ym2612.h b/audio/softsynth/ym2612.h similarity index 99% rename from sound/softsynth/ym2612.h rename to audio/softsynth/ym2612.h index 841d1d29579..64abfa443e8 100644 --- a/sound/softsynth/ym2612.h +++ b/audio/softsynth/ym2612.h @@ -27,7 +27,7 @@ #include "common/sys.h" -#include "sound/softsynth/emumidi.h" +#include "audio/softsynth/emumidi.h" //////////////////////////////////////// // diff --git a/sound/timestamp.cpp b/audio/timestamp.cpp similarity index 87% rename from sound/timestamp.cpp rename to audio/timestamp.cpp index 002f59a5ea9..604ef62e590 100644 --- a/sound/timestamp.cpp +++ b/audio/timestamp.cpp @@ -23,7 +23,7 @@ * */ -#include "sound/timestamp.h" +#include "audio/timestamp.h" #include "common/algorithm.h" namespace Audio { @@ -148,21 +148,9 @@ Timestamp Timestamp::addMsecs(int ms) const { } void Timestamp::addIntern(const Timestamp &ts) { + assert(_framerate == ts._framerate); _secs += ts._secs; - - if (_framerate == ts._framerate) { - _numFrames += ts._numFrames; - } else { - // We need to multiply by the quotient of the two framerates. - // We cancel the GCD in this fraction to reduce the risk of - // overflows. - const uint g = Common::gcd(_framerate, ts._framerate); - const uint p = _framerate / g; - const uint q = ts._framerate / g; - - _framerate *= q; - _numFrames = _numFrames * q + ts._numFrames * p; - } + _numFrames += ts._numFrames; normalize(); } @@ -187,24 +175,6 @@ Timestamp Timestamp::operator-(const Timestamp &ts) const { return result; } -/* -Timestamp &Timestamp::operator+=(const Timestamp &ts) { - addIntern(ts); - return *this; -} - -Timestamp &Timestamp::operator-=(const Timestamp &ts) { - addIntern(-ts); - return *this; -} -*/ - -/* -int Timestamp::frameDiff(const Timestamp &ts) const { - return (*this - ts).totalNumberOfFrames(); -} -*/ - int Timestamp::frameDiff(const Timestamp &ts) const { int delta = 0; diff --git a/sound/timestamp.h b/audio/timestamp.h similarity index 62% rename from sound/timestamp.h rename to audio/timestamp.h index 49d4490ee41..da5b98087f8 100644 --- a/sound/timestamp.h +++ b/audio/timestamp.h @@ -31,55 +31,62 @@ namespace Audio { /** - * Timestamps allow measuring times with a sub-millisecond granularity, - * and without rounding losses. This is achieved by measuring frames - * instead of milliseconds: Specify an initial time in milliseconds - * plus framerate (in frames per second). + * Timestamps allow specifying points in time and measuring time intervals + * with a sub-millisecond granularity. + * + * When dealing with audio and video decoding, it is often necessary to + * measure time (intervals) in terms of frames, relative to a fixed + * frame rate (that is, a fixed number of frames per seconds). For + * example, in a typical video there are 24 frames per second, and in a + * typical sound there are 44100 frames (i.e. samples for mono sound + * and pairs of samples for stereo) per second. + * + * At the same time, the system clock provided by ScummVM measures time + * in milliseconds. For syncing purposes and other reasons, it is often + * necessary to convert between and compare time measures given on the + * one hand as a frame count, and on the other hand as a number of + * milliseconds. + * + * If handled carelessly, this can introduce rounding errors that + * quickly accumulate, resulting in user noticeable disturbance, such as + * audio and video running out of sync. E.g. a typical approach is to + * measure all time in milliseconds. But with a frame rate of 24 frames + * per second, one frame is 41.66666... milliseconds long. On the other + * hand, if measuring in frames, then similar rounding issue occur when + * converting from milliseconds to frames. + * + * One solution is to use floating point arithmetic to compute with + * fractional frames resp. (milli)seconds. This has other undesirable + * side effects; foremost, some platforms ScummVM runs on still have + * only limited (and slow) floating point support. + * + * This class provides an alternate solution: It stores time in terms of + * frames, but with a twist: Client code can specify arbitrary + * (integral) framerates; but internally, Timestamp modifies the + * framerate to be a multiple of 1000. This way, both numbers of frames + * (relative to the original framerate) as well as milliseconds can be + * represented as integers. This change is completely hidden from the + * user, however. + * + * A Timestamp can be converted to a frame count or milliseconds at + * virtually no cost. Likewise, it is posible to compute the difference + * between two Timestamps in milliseconds or number of frames. + * Timestamps can be easily compared using regular comparison operators, + * resulting in nicely readable code; this is even possible for + * timestamps that are specified using different framerates. + * Client code can modify Timestamps by adding a number of frames + * to it, or adding a number of milliseconds. Adding negative amounts is + * also allowed, and a Timestamp can even represent a "negative time" + * (mainly useful when using the Timestamp to store a time interval). */ class Timestamp { -protected: - /** - * The seconds part of this timestamp. - * The total time in seconds represented by this timestamp can be - * computed as follows: - * _secs + (double)_numFrames / _framerate - */ - int _secs; - - /** - * The number of frames which together with _secs encodes - * the timestamp. The total number of frames represented - * by this timestamp is computed as follows: - * _numFrames + _secs * _framerate - * - * This is always a value greater or equal to zero. - * The only reason this is an int and not an uint is to - * allow intermediate negative values. - */ - int _numFrames; - - /** - * The internal framerate, i.e. the number of frames per second. - * This is computed as the least common multiple of the framerate - * specified by the client code, and 1000. - * This way, we ensure that we can store both frames and - * milliseconds without any rounding losses. - */ - uint _framerate; - - /** - * Factor by which the original framerate specified by the client - * code was multipled to obtain the internal _framerate value. - */ - uint _framerateFactor; - public: /** * Set up a timestamp with a given time and framerate. * @param msecs starting time in milliseconds * @param framerate number of frames per second (must be > 0) */ - Timestamp(uint msecs, uint framerate); + Timestamp(uint msecs = 0, uint framerate = 1); /** * Set up a timestamp with a given time, frames and framerate. @@ -126,11 +133,17 @@ public: // unary minus Timestamp operator-() const; + /** + * Compute the sum of two timestamps. This is only + * allowed if they use the same framerate. + */ Timestamp operator+(const Timestamp &ts) const; - Timestamp operator-(const Timestamp &ts) const; -// Timestamp &operator+=(const Timestamp &ts); -// Timestamp &operator-=(const Timestamp &ts); + /** + * Compute the difference between two timestamps. This is only + * allowed if they use the same framerate. + */ + Timestamp operator-(const Timestamp &ts) const; /** * Computes the number of frames between this timestamp and ts. @@ -176,7 +189,6 @@ public: inline uint framerate() const { return _framerate / _framerateFactor; } protected: - /** * Compare this timestamp to another one and return * a value similar to strcmp. @@ -193,6 +205,44 @@ protected: * Add another timestamp to this one and normalize the result. */ void addIntern(const Timestamp &ts); + +protected: + /** + * The seconds part of this timestamp. + * The total time in seconds represented by this timestamp can be + * computed as follows: + * _secs + (double)_numFrames / _framerate + */ + int _secs; + + /** + * The number of frames which together with _secs encodes the + * timestamp. The total number of *internal* frames represented + * by this timestamp can be computed as follows: + * _numFrames + _secs * _framerate + * To obtain the number of frames with respect to the original + * framerate, this value has to be divided by _framerateFactor. + * + * This is always a value greater or equal to zero. + * The only reason this is an int and not an uint is to + * allow intermediate negative values. + */ + int _numFrames; + + /** + * The internal framerate, i.e. the number of frames per second. + * This is computed as the least common multiple of the framerate + * specified by the client code, and 1000. + * This way, we ensure that we can store both frames and + * milliseconds without any rounding losses. + */ + uint _framerate; + + /** + * Factor by which the original framerate specified by the client + * code was multipled to obtain the internal _framerate value. + */ + uint _framerateFactor; }; diff --git a/backends/audiocd/audiocd.h b/backends/audiocd/audiocd.h new file mode 100644 index 00000000000..95490656e6c --- /dev/null +++ b/backends/audiocd/audiocd.h @@ -0,0 +1,148 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_AUDIOCD_ABSTRACT_H +#define BACKENDS_AUDIOCD_ABSTRACT_H + +#include "common/sys.h" +#include "common/noncopyable.h" + +/** +* Abstract Audio CD manager class. Subclasses implement the actual +* functionality. +*/ +class AudioCDManager : Common::NonCopyable { +public: + virtual ~AudioCDManager() {} + + /** + * A structure containing the current playback information + */ + struct Status { + bool playing; + int track; + int start; + int duration; + int numLoops; + int volume; + int balance; + }; + + /** + * @name Emulated playback functions + * Engines should call these functions. Not all platforms + * support cd playback, and these functions should try to + * emulate it. + */ + //@{ + + /** + * Start audio CD playback + * @param track the track to play. + * @param num_loops how often playback should be repeated (-1 = infinitely often). + * @param start_frame the frame at which playback should start (75 frames = 1 second). + * @param duration the number of frames to play. + * @param only_emulate determines if the track should be emulated only + */ + virtual void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false) = 0; + + /** + * Get if audio is being played. + * @return true if CD or emulated audio is playing + */ + virtual bool isPlaying() const = 0; + + /** + * Set the audio volume + */ + virtual void setVolume(byte volume) = 0; + + /** + * Set the speakers balance + */ + virtual void setBalance(int8 balance) = 0; + + /** + * Stop CD or emulated audio playback. + */ + virtual void stop() = 0; + + /** + * Update CD or emulated audio status. + */ + virtual void update() = 0; + + /** + * Get the playback status. + * @return a Status struct with playback data. + */ + virtual Status getStatus() const = 0; + + //@} + + + /** + * @name Real CD audio methods + * These functions should be called from the emulated + * ones if they can't emulate the audio playback. + */ + //@{ + + /** + * Initialise the specified CD drive for audio playback. + * @param drive the drive id + * @return true if the CD drive was inited succesfully + */ + virtual bool openCD(int drive) = 0; + + /** + * Poll CD status. + * @return true if CD audio is playing + */ + virtual bool pollCD() const = 0; + + /** + * Start CD audio playback. + * @param track the track to play. + * @param num_loops how often playback should be repeated (-1 = infinitely often). + * @param start_frame the frame at which playback should start (75 frames = 1 second). + * @param duration the number of frames to play. + */ + virtual void playCD(int track, int num_loops, int start_frame, int duration) = 0; + + /** + * Stop CD audio playback. + */ + virtual void stopCD() = 0; + + /** + * Update CD audio status. + */ + virtual void updateCD() = 0; + + //@} +}; + +#endif diff --git a/sound/audiocd.cpp b/backends/audiocd/default/default-audiocd.cpp similarity index 71% rename from sound/audiocd.cpp rename to backends/audiocd/default/default-audiocd.cpp index 9a0294ac1a2..10a42f85ce7 100644 --- a/sound/audiocd.cpp +++ b/backends/audiocd/default/default-audiocd.cpp @@ -23,33 +23,24 @@ * */ -#include "sound/audiocd.h" -#include "sound/audiostream.h" -#include "sound/decoders/mp3.h" -#include "sound/decoders/vorbis.h" -#include "sound/decoders/flac.h" -#include "engines/engine.h" -#include "common/util.h" +#include "backends/audiocd/default/default-audiocd.h" +#include "audio/audiostream.h" #include "common/system.h" -DECLARE_SINGLETON(Audio::AudioCDManager) - -namespace Audio { - -AudioCDManager::AudioCDManager() { +DefaultAudioCDManager::DefaultAudioCDManager() { _cd.playing = false; _cd.track = 0; _cd.start = 0; _cd.duration = 0; _cd.numLoops = 0; - _cd.volume = Mixer::kMaxChannelVolume; + _cd.volume = Audio::Mixer::kMaxChannelVolume; _cd.balance = 0; _mixer = g_system->getMixer(); _emulating = false; assert(_mixer); } -void AudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool only_emulate) { +void DefaultAudioCDManager::play(int track, int numLoops, int startFrame, int duration, bool only_emulate) { if (numLoops != 0 || startFrame != 0) { _cd.track = track; _cd.numLoops = numLoops; @@ -65,14 +56,14 @@ void AudioCDManager::play(int track, int numLoops, int startFrame, int duration, Audio::SeekableAudioStream *stream = 0; for (int i = 0; !stream && i < 2; ++i) - stream = SeekableAudioStream::openStreamFile(trackName[i]); + stream = Audio::SeekableAudioStream::openStreamFile(trackName[i]); // Stop any currently playing emulated track _mixer->stopHandle(_handle); if (stream != 0) { - Timestamp start = Timestamp(0, startFrame, 75); - Timestamp end = duration ? Timestamp(0, startFrame + duration, 75) : stream->getLength(); + Audio::Timestamp start = Audio::Timestamp(0, startFrame, 75); + Audio::Timestamp end = duration ? Audio::Timestamp(0, startFrame + duration, 75) : stream->getLength(); /* FIXME: Seems numLoops == 0 and numLoops == 1 both indicate a single repetition, @@ -80,39 +71,38 @@ void AudioCDManager::play(int track, int numLoops, int startFrame, int duration, repetitions. Finally, -1 means infinitely many */ _emulating = true; - _mixer->playStream(Mixer::kMusicSoundType, &_handle, - makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance); - + _mixer->playStream(Audio::Mixer::kMusicSoundType, &_handle, + Audio::makeLoopingAudioStream(stream, start, end, (numLoops < 1) ? numLoops + 1 : numLoops), -1, _cd.volume, _cd.balance); } else { _emulating = false; if (!only_emulate) - g_system->playCD(track, numLoops, startFrame, duration); + playCD(track, numLoops, startFrame, duration); } } } -void AudioCDManager::stop() { +void DefaultAudioCDManager::stop() { if (_emulating) { // Audio CD emulation _mixer->stopHandle(_handle); _emulating = false; } else { // Real Audio CD - g_system->stopCD(); + stopCD(); } } -bool AudioCDManager::isPlaying() const { +bool DefaultAudioCDManager::isPlaying() const { if (_emulating) { // Audio CD emulation return _mixer->isSoundHandleActive(_handle); } else { // Real Audio CD - return g_system->pollCD(); + return pollCD(); } } -void AudioCDManager::setVolume(byte volume) { +void DefaultAudioCDManager::setVolume(byte volume) { _cd.volume = volume; if (_emulating) { // Audio CD emulation @@ -120,7 +110,7 @@ void AudioCDManager::setVolume(byte volume) { _mixer->setChannelVolume(_handle, _cd.volume); } else { // Real Audio CD - + // Unfortunately I can't implement this atm // since SDL doesn't seem to offer an interface method for this. @@ -128,7 +118,7 @@ void AudioCDManager::setVolume(byte volume) { } } -void AudioCDManager::setBalance(int8 balance) { +void DefaultAudioCDManager::setBalance(int8 balance) { _cd.balance = balance; if (_emulating) { // Audio CD emulation @@ -136,7 +126,7 @@ void AudioCDManager::setBalance(int8 balance) { _mixer->setChannelBalance(_handle, _cd.balance); } else { // Real Audio CD - + // Unfortunately I can't implement this atm // since SDL doesn't seem to offer an interface method for this. @@ -144,7 +134,7 @@ void AudioCDManager::setBalance(int8 balance) { } } -void AudioCDManager::updateCD() { +void DefaultAudioCDManager::update() { if (_emulating) { // Check whether the audio track stopped playback if (!_mixer->isSoundHandleActive(_handle)) { @@ -156,16 +146,12 @@ void AudioCDManager::updateCD() { _emulating = false; } } else { - g_system->updateCD(); + updateCD(); } } -AudioCDManager::Status AudioCDManager::getStatus() const { - // TODO: This could be improved for "real" CD playback. - // But to do that, we would have to extend the OSystem interface. +DefaultAudioCDManager::Status DefaultAudioCDManager::getStatus() const { Status info = _cd; info.playing = isPlaying(); return info; } - -} // End of namespace Audio diff --git a/backends/audiocd/default/default-audiocd.h b/backends/audiocd/default/default-audiocd.h new file mode 100644 index 00000000000..9ef3718e158 --- /dev/null +++ b/backends/audiocd/default/default-audiocd.h @@ -0,0 +1,62 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_AUDIOCD_DEFAULT_H +#define BACKENDS_AUDIOCD_DEFAULT_H + +#include "backends/audiocd/audiocd.h" +#include "audio/mixer.h" + +/** + * The default audio cd manager. Implements emulation of audio cd playback. + */ +class DefaultAudioCDManager : public AudioCDManager { +public: + DefaultAudioCDManager(); + virtual ~DefaultAudioCDManager() {} + + void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false); + void stop(); + bool isPlaying() const; + void setVolume(byte volume); + void setBalance(int8 balance); + void update(); + virtual Status getStatus() const; // Subclasses should override for better status results + + virtual bool openCD(int drive) { return false; } + virtual void updateCD() {} + virtual bool pollCD() const { return false; } + virtual void playCD(int track, int num_loops, int start_frame, int duration) {} + virtual void stopCD() {} + +protected: + Audio::SoundHandle _handle; + bool _emulating; + + Status _cd; + Audio::Mixer *_mixer; +}; + +#endif diff --git a/backends/audiocd/sdl/sdl-audiocd.cpp b/backends/audiocd/sdl/sdl-audiocd.cpp new file mode 100644 index 00000000000..eb7d6e0373a --- /dev/null +++ b/backends/audiocd/sdl/sdl-audiocd.cpp @@ -0,0 +1,138 @@ +/* Residual - A 3D game interpreter + * + * 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 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/sys.h" + +#if defined(SDL_BACKEND) + +#include "backends/audiocd/sdl/sdl-audiocd.h" + +SdlAudioCDManager::SdlAudioCDManager() + : + _cdrom(0), + _cdTrack(0), + _cdNumLoops(0), + _cdStartFrame(0), + _cdDuration(0), + _cdEndTime(0), + _cdStopTime(0) { + +} + +SdlAudioCDManager::~SdlAudioCDManager() { + if (_cdrom) { + SDL_CDStop(_cdrom); + SDL_CDClose(_cdrom); + } +} + +bool SdlAudioCDManager::openCD(int drive) { + if (SDL_InitSubSystem(SDL_INIT_CDROM) == -1) + _cdrom = NULL; + else { + _cdrom = SDL_CDOpen(drive); + // Did it open? Check if _cdrom is NULL + if (!_cdrom) { + warning("Couldn't open drive: %s", SDL_GetError()); + } else { + _cdNumLoops = 0; + _cdStopTime = 0; + _cdEndTime = 0; + } + } + + return (_cdrom != NULL); +} + +void SdlAudioCDManager::stopCD() { + // Stop CD Audio in 1/10th of a second + _cdStopTime = SDL_GetTicks() + 100; + _cdNumLoops = 0; +} + +void SdlAudioCDManager::playCD(int track, int num_loops, int start_frame, int duration) { + if (!num_loops && !start_frame) + return; + + if (!_cdrom) + return; + + if (duration > 0) + duration += 5; + + _cdTrack = track; + _cdNumLoops = num_loops; + _cdStartFrame = start_frame; + + SDL_CDStatus(_cdrom); + if (start_frame == 0 && duration == 0) + SDL_CDPlayTracks(_cdrom, track, 0, 1, 0); + else + SDL_CDPlayTracks(_cdrom, track, start_frame, 0, duration); + _cdDuration = duration; + _cdStopTime = 0; + _cdEndTime = SDL_GetTicks() + _cdrom->track[track].length * 1000 / CD_FPS; +} + +bool SdlAudioCDManager::pollCD() const { + if (!_cdrom) + return false; + + return (_cdNumLoops != 0 && (SDL_GetTicks() < _cdEndTime || SDL_CDStatus(_cdrom) == CD_PLAYING)); +} + +void SdlAudioCDManager::updateCD() { + if (!_cdrom) + return; + + if (_cdStopTime != 0 && SDL_GetTicks() >= _cdStopTime) { + SDL_CDStop(_cdrom); + _cdNumLoops = 0; + _cdStopTime = 0; + return; + } + + if (_cdNumLoops == 0 || SDL_GetTicks() < _cdEndTime) + return; + + if (_cdNumLoops != 1 && SDL_CDStatus(_cdrom) != CD_STOPPED) { + // Wait another second for it to be done + _cdEndTime += 1000; + return; + } + + if (_cdNumLoops > 0) + _cdNumLoops--; + + if (_cdNumLoops != 0) { + if (_cdStartFrame == 0 && _cdDuration == 0) + SDL_CDPlayTracks(_cdrom, _cdTrack, 0, 1, 0); + else + SDL_CDPlayTracks(_cdrom, _cdTrack, _cdStartFrame, 0, _cdDuration); + _cdEndTime = SDL_GetTicks() + _cdrom->track[_cdTrack].length * 1000 / CD_FPS; + } +} + +#endif diff --git a/backends/audiocd/sdl/sdl-audiocd.h b/backends/audiocd/sdl/sdl-audiocd.h new file mode 100644 index 00000000000..3e31d983013 --- /dev/null +++ b/backends/audiocd/sdl/sdl-audiocd.h @@ -0,0 +1,53 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_AUDIOCD_SDL_H +#define BACKENDS_AUDIOCD_SDL_H + +#include "backends/audiocd/default/default-audiocd.h" + +#include "backends/platform/sdl/sdl-sys.h" + +/** + * The SDL audio cd manager. Implements real audio cd playback. + */ +class SdlAudioCDManager : public DefaultAudioCDManager { +public: + SdlAudioCDManager(); + virtual ~SdlAudioCDManager(); + +protected: + virtual bool openCD(int drive); + virtual void updateCD(); + virtual bool pollCD() const; + virtual void playCD(int track, int num_loops, int start_frame, int duration); + virtual void stopCD(); + + SDL_CD *_cdrom; + int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration; + uint32 _cdEndTime, _cdStopTime; +}; + +#endif diff --git a/backends/base-backend.cpp b/backends/base-backend.cpp deleted file mode 100644 index 2d15d6f0da5..00000000000 --- a/backends/base-backend.cpp +++ /dev/null @@ -1,80 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 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 "backends/base-backend.h" -#include "backends/events/default/default-events.h" -#include "gui/message.h" - -void BaseBackend::displayMessageOnOSD(const char *msg) { - // Display the message for 1.5 seconds - GUI::TimedMessageDialog dialog(msg, 1500); - dialog.runModal(); -} - - -static Common::EventManager *s_eventManager = 0; - -Common::EventManager *BaseBackend::getEventManager() { - // FIXME/TODO: Eventually this method should be turned into an abstract one, - // to force backends to implement this conciously (even if they - // end up returning the default event manager anyway). - if (!s_eventManager) - s_eventManager = new DefaultEventManager(this); - return s_eventManager; -} - - - -/* - FIXME: Maybe we should push the default config file loading/saving code below - out to all the backends? -*/ - - -#if defined(UNIX) -#if defined(SAMSUNGTV) -#define DEFAULT_CONFIG_FILE "/dtv/usb/sda1/.scummvmrc" -#else -#define DEFAULT_CONFIG_FILE ".residualrc" -#endif -#endif - -#if !defined(UNIX) -#define DEFAULT_CONFIG_FILE "scummvm.ini" -#endif - -Common::SeekableReadStream *BaseBackend::createConfigReadStream() { - Common::FSNode file(DEFAULT_CONFIG_FILE); - return file.createReadStream(); -} - -Common::WriteStream *BaseBackend::createConfigWriteStream() { -#ifdef __DC__ - return 0; -#else - Common::FSNode file(DEFAULT_CONFIG_FILE); - return file.createWriteStream(); -#endif -} diff --git a/backends/events/default/default-events.cpp b/backends/events/default/default-events.cpp index 6d7bb024384..bb440a790f9 100644 --- a/backends/events/default/default-events.cpp +++ b/backends/events/default/default-events.cpp @@ -23,6 +23,8 @@ * */ +#include "common/sys.h" + #if !defined(DISABLE_DEFAULT_EVENTMANAGER) #include "common/system.h" diff --git a/backends/platform/sdl/events.cpp b/backends/events/sdl/sdl-events.cpp similarity index 76% rename from backends/platform/sdl/events.cpp rename to backends/events/sdl/sdl-events.cpp index ab1146a97ab..ab6b1dc4d85 100644 --- a/backends/platform/sdl/events.cpp +++ b/backends/events/sdl/sdl-events.cpp @@ -23,9 +23,14 @@ * */ +#include "common/sys.h" + +#if defined(SDL_BACKEND) + +#include "backends/events/sdl/sdl-events.h" #include "backends/platform/sdl/sdl.h" -#include "common/util.h" -#include "common/events.h" +#include "backends/graphics/graphics.h" +#include "common/config-manager.h" // FIXME move joystick defines out and replace with confile file options // we should really allow users to map any key to a joystick button @@ -46,10 +51,33 @@ #define JOY_BUT_SPACE 4 #define JOY_BUT_F5 5 +SdlEventSource::SdlEventSource() + : _scrollLock(false), _joystick(0), _lastScreenID(0), EventSource() { + // Reset mouse state + memset(&_km, 0, sizeof(_km)); +/* Residual doesn't support this + int joystick_num = ConfMan.getInt("joystick_num"); + if (joystick_num > -1) { + // Initialize SDL joystick subsystem + if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1) { + error("Could not initialize SDL: %s", SDL_GetError()); + } + // Enable joystick + if (SDL_NumJoysticks() > 0) { + printf("Using joystick: %s\n", SDL_JoystickName(0)); + _joystick = SDL_JoystickOpen(joystick_num); + } + }*/ +} +SdlEventSource::~SdlEventSource() { +/* Residual doesn't support this + if (_joystick) + SDL_JoystickClose(_joystick);*/ +} -static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode) { +int SdlEventSource::mapKey(SDLKey key, SDLMod mod, Uint16 unicode) { if (key >= SDLK_F1 && key <= SDLK_F9) { return key - SDLK_F1 + Common::ASCII_F1; } else if (key >= SDLK_KP0 && key <= SDLK_KP9) { @@ -66,25 +94,17 @@ static int mapKey(SDLKey key, SDLMod mod, Uint16 unicode) { return key; } -void OSystem_SDL::fillMouseEvent(Common::Event &event, int x, int y) { +void SdlEventSource::fillMouseEvent(Common::Event &event, int x, int y) { event.mouse.x = x; event.mouse.y = y; // Update the "keyboard mouse" coords _km.x = x; _km.y = y; -/* Residual doesn't support this - // Adjust for the screen scaling - if (!_overlayVisible) { - event.mouse.x /= _videoMode.scaleFactor; - event.mouse.y /= _videoMode.scaleFactor; - if (_videoMode.aspectRatioCorrection) - event.mouse.y = aspect2Real(event.mouse.y); - }*/ } -void OSystem_SDL::handleKbdMouse() { - uint32 curTime = getMillis(); +void SdlEventSource::handleKbdMouse() { + uint32 curTime = g_system->getMillis(); if (curTime >= _km.last_time + _km.delay_time) { _km.last_time = curTime; if (_km.x_down_count == 1) { @@ -153,7 +173,7 @@ void OSystem_SDL::handleKbdMouse() { } } -static void SDLModToOSystemKeyFlags(SDLMod mod, Common::Event &event) { +void SdlEventSource::SDLModToOSystemKeyFlags(SDLMod mod, Common::Event &event) { event.kbd.flags = 0; @@ -178,19 +198,19 @@ static void SDLModToOSystemKeyFlags(SDLMod mod, Common::Event &event) { event.kbd.flags |= Common::KBD_CAPS; } -bool OSystem_SDL::pollEvent(Common::Event &event) { - SDL_Event ev; - ev.type = SDL_NOEVENT; - +bool SdlEventSource::pollEvent(Common::Event &event) { handleKbdMouse(); /* Residual doesn't support this - // If the screen mode changed, send an Common::EVENT_SCREEN_CHANGED - if (_modeChanged) { - _modeChanged = false; + // If the screen changed, send an Common::EVENT_SCREEN_CHANGED + int screenID = ((OSystem_SDL *)g_system)->getGraphicsManager()->getScreenChangeID(); + if (screenID != _lastScreenID) { + _lastScreenID = screenID; event.type = Common::EVENT_SCREEN_CHANGED; return true; - } -*/ + }*/ + + SDL_Event ev; + ev.type = SDL_NOEVENT; while (SDL_PollEvent(&ev)) { preprocessEvents(&ev); if (dispatchSDLEvent(ev, event)) @@ -199,7 +219,7 @@ bool OSystem_SDL::pollEvent(Common::Event &event) { return false; } -bool OSystem_SDL::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) { switch (ev.type) { case SDL_KEYDOWN: return handleKeyDown(ev, event); @@ -219,9 +239,16 @@ bool OSystem_SDL::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) { return handleJoyAxisMotion(ev, event); case SDL_VIDEOEXPOSE: - /* Residual doesn't support this */ - //_forceFull = true; - break; + // HACK: Send a fake event, handled by SdlGraphicsManager + event.type = (Common::EventType)OSystem_SDL::kSdlEventExpose; + return true; + + case SDL_VIDEORESIZE: + // HACK: Send a fake event, handled by OpenGLSdlGraphicsManager + event.type = (Common::EventType)OSystem_SDL::kSdlEventResize; + event.mouse.x = ev.resize.w; + event.mouse.y = ev.resize.h; + return true; case SDL_QUIT: event.type = Common::EVENT_QUIT; @@ -233,7 +260,7 @@ bool OSystem_SDL::dispatchSDLEvent(SDL_Event &ev, Common::Event &event) { } -bool OSystem_SDL::handleKeyDown(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::handleKeyDown(SDL_Event &ev, Common::Event &event) { SDLModToOSystemKeyFlags(SDL_GetModState(), event); @@ -244,42 +271,6 @@ bool OSystem_SDL::handleKeyDown(SDL_Event &ev, Common::Event &event) { if (_scrollLock) event.kbd.flags |= Common::KBD_SCRL; - // Alt-Return and Alt-Enter toggle full screen mode -/* Residual doesn't support this - if (event.kbd.hasFlags(Common::KBD_ALT) && (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_KP_ENTER)) { - beginGFXTransaction(); - setFullscreenMode(!_videoMode.fullscreen); - endGFXTransaction(); -#ifdef USE_OSD - if (_videoMode.fullscreen) - displayMessageOnOSD("Fullscreen mode"); - else - displayMessageOnOSD("Windowed mode"); -#endif - - return false; - }*/ - -/* // Alt-S: Create a screenshot - if (event.kbd.hasFlags(Common::KBD_ALT) && ev.key.keysym.sym == 's') { - char filename[20]; - - for (int n = 0;; n++) { - SDL_RWops *file; - - sprintf(filename, "residual%05d.bmp", n); - file = SDL_RWFromFile(filename, "r"); - if (!file) - break; - SDL_RWclose(file); - } - if (saveScreenshot(filename)) - printf("Saved '%s'\n", filename); - else - printf("Could not save screenshot!\n"); - return false; - } -*/ // Ctrl-m toggles mouse capture if (event.kbd.hasFlags(Common::KBD_CTRL) && ev.key.keysym.sym == 'm') { toggleMouseGrab(); @@ -287,13 +278,13 @@ bool OSystem_SDL::handleKeyDown(SDL_Event &ev, Common::Event &event) { } #if defined(MACOSX) - // On Macintosh', Cmd-Q quits + // On Macintosh, Cmd-Q quits if ((ev.key.keysym.mod & KMOD_META) && ev.key.keysym.sym == 'q') { event.type = Common::EVENT_QUIT; return true; } #elif defined(UNIX) - // On other unices, Control-Q quits + // On other *nix systems, Control-Q quits if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'q') { event.type = Common::EVENT_QUIT; return true; @@ -306,16 +297,11 @@ bool OSystem_SDL::handleKeyDown(SDL_Event &ev, Common::Event &event) { } #endif + // Ctrl-u toggles mute if ((ev.key.keysym.mod & KMOD_CTRL) && ev.key.keysym.sym == 'u') { event.type = Common::EVENT_MUTE; return true; } -/* Residual doesn't support this - // Ctrl-Alt- will change the GFX mode - if ((event.kbd.flags & (Common::KBD_CTRL|Common::KBD_ALT)) == (Common::KBD_CTRL|Common::KBD_ALT)) { - if (handleScalerHotkeys(ev.key)) - return false; - }*/ if (remapKey(ev, event)) return true; @@ -327,38 +313,65 @@ bool OSystem_SDL::handleKeyDown(SDL_Event &ev, Common::Event &event) { return true; } -bool OSystem_SDL::handleKeyUp(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::handleKeyUp(SDL_Event &ev, Common::Event &event) { if (remapKey(ev, event)) return true; + SDLMod mod = SDL_GetModState(); + + // Check if this is an event handled by handleKeyDown(), and stop if it is + + // Check if the Ctrl key is down, so that we can trap cases where the + // user has the Ctrl key down, and has just released a special key + if (mod & KMOD_CTRL) { + if (ev.key.keysym.sym == 'm' || // Ctrl-m toggles mouse capture +#if defined(MACOSX) + // Meta - Q, handled below +#elif defined(UNIX) + ev.key.keysym.sym == 'q' || // On other *nix systems, Control-Q quits +#else + ev.key.keysym.sym == 'z' || // Ctrl-z quit +#endif + ev.key.keysym.sym == 'u') // Ctrl-u toggles mute + return false; + } + + // Same for other keys (Meta and Alt) +#if defined(MACOSX) + if ((mod & KMOD_META) && ev.key.keysym.sym == 'q') + return false; // On Macintosh, Cmd-Q quits +#elif defined(UNIX) + // Control Q has already been handled above +#else + if ((mod & KMOD_ALT) && ev.key.keysym.sym == 'x') + return false; // Alt-x quit +#endif + + // If we reached here, this isn't an event handled by handleKeyDown(), thus + // continue normally + event.type = Common::EVENT_KEYUP; event.kbd.keycode = (Common::KeyCode)ev.key.keysym.sym; event.kbd.ascii = mapKey(ev.key.keysym.sym, ev.key.keysym.mod, ev.key.keysym.unicode); // Ctrl-Alt- will change the GFX mode - SDLModToOSystemKeyFlags(SDL_GetModState(), event); + SDLModToOSystemKeyFlags(mod, event); // Set the scroll lock sticky flag if (_scrollLock) event.kbd.flags |= Common::KBD_SCRL; -/* Residual doesn't support this - if (isScalerHotkey(event)) - // Swallow these key up events - return false;*/ return true; } -bool OSystem_SDL::handleMouseMotion(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::handleMouseMotion(SDL_Event &ev, Common::Event &event) { event.type = Common::EVENT_MOUSEMOVE; fillMouseEvent(event, ev.motion.x, ev.motion.y); - /* Residual doesn't support this */ - //setMousePos(event.mouse.x, event.mouse.y); return true; } -bool OSystem_SDL::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) { if (ev.button.button == SDL_BUTTON_LEFT) event.type = Common::EVENT_LBUTTONDOWN; else if (ev.button.button == SDL_BUTTON_RIGHT) @@ -381,7 +394,7 @@ bool OSystem_SDL::handleMouseButtonDown(SDL_Event &ev, Common::Event &event) { return true; } -bool OSystem_SDL::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) { if (ev.button.button == SDL_BUTTON_LEFT) event.type = Common::EVENT_LBUTTONUP; else if (ev.button.button == SDL_BUTTON_RIGHT) @@ -397,7 +410,7 @@ bool OSystem_SDL::handleMouseButtonUp(SDL_Event &ev, Common::Event &event) { return true; } -bool OSystem_SDL::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) { if (ev.jbutton.button == JOY_BUT_LMOUSE) { event.type = Common::EVENT_LBUTTONDOWN; fillMouseEvent(event, _km.x, _km.y); @@ -428,7 +441,7 @@ bool OSystem_SDL::handleJoyButtonDown(SDL_Event &ev, Common::Event &event) { return true; } -bool OSystem_SDL::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) { if (ev.jbutton.button == JOY_BUT_LMOUSE) { event.type = Common::EVENT_LBUTTONUP; fillMouseEvent(event, _km.x, _km.y); @@ -459,7 +472,7 @@ bool OSystem_SDL::handleJoyButtonUp(SDL_Event &ev, Common::Event &event) { return true; } -bool OSystem_SDL::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) { int axis = ev.jaxis.value; if ( axis > JOY_DEADZONE) { axis -= JOY_DEADZONE; @@ -472,7 +485,7 @@ bool OSystem_SDL::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) { if ( ev.jaxis.axis == JOY_XAXIS) { #ifdef JOY_ANALOG - _km.x_vel = axis/2000; + _km.x_vel = axis / 2000; _km.x_down_count = 0; #else if (axis != 0) { @@ -507,7 +520,7 @@ bool OSystem_SDL::handleJoyAxisMotion(SDL_Event &ev, Common::Event &event) { return true; } -bool OSystem_SDL::remapKey(SDL_Event &ev, Common::Event &event) { +bool SdlEventSource::remapKey(SDL_Event &ev, Common::Event &event) { #ifdef LINUPY // On Yopy map the End button to quit if ((ev.key.keysym.sym == 293)) { @@ -574,3 +587,19 @@ bool OSystem_SDL::remapKey(SDL_Event &ev, Common::Event &event) { #endif return false; } + +void SdlEventSource::toggleMouseGrab() { + if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) + SDL_WM_GrabInput(SDL_GRAB_ON); + else + SDL_WM_GrabInput(SDL_GRAB_OFF); +} + +void SdlEventSource::resetKeyboadEmulation(int16 x_max, int16 y_max) { + _km.x_max = x_max; + _km.y_max = y_max; + _km.delay_time = 25; + _km.last_time = 0; +} + +#endif diff --git a/backends/events/sdl/sdl-events.h b/backends/events/sdl/sdl-events.h new file mode 100644 index 00000000000..115a2f7e0a7 --- /dev/null +++ b/backends/events/sdl/sdl-events.h @@ -0,0 +1,135 @@ +/* Residual - A 3D game interpreter + * + * 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 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$ + * + */ + +#if !defined(BACKEND_EVENTS_SDL_H) && !defined(DISABLE_DEFAULT_EVENTMANAGER) +#define BACKEND_EVENTS_SDL_H + +#include "backends/events/default/default-events.h" + +#include "backends/platform/sdl/sdl-sys.h" + + +/** + * The SDL event source. + */ +class SdlEventSource : public Common::EventSource { +public: + SdlEventSource(); + virtual ~SdlEventSource(); + + /** + * Gets and processes SDL events. + */ + virtual bool pollEvent(Common::Event &event); + + /** + * Resets keyboard emulation after a video screen change + */ + virtual void resetKeyboadEmulation(int16 x_max, int16 y_max); + + /** + * Toggles mouse input grab + */ + virtual void toggleMouseGrab(); + +protected: + /** @name Keyboard mouse emulation + * Disabled by fingolfin 2004-12-18. + * I am keeping the rest of the code in for now, since the joystick + * code (or rather, "hack") uses it, too. + */ + //@{ + + struct KbdMouse { + int16 x, y, x_vel, y_vel, x_max, y_max, x_down_count, y_down_count; + uint32 last_time, delay_time, x_down_time, y_down_time; + }; + KbdMouse _km; + + //@} + + /** Scroll lock state - since SDL doesn't track it */ + bool _scrollLock; + + /** Joystick */ + SDL_Joystick *_joystick; + + /** Last screen id for checking if it was modified */ + int _lastScreenID; + + /** + * Pre process an event before it is dispatched. + */ + virtual void preprocessEvents(SDL_Event *event) {} + + /** + * Dispatchs SDL events for each handler. + */ + virtual bool dispatchSDLEvent(SDL_Event &ev, Common::Event &event); + + + /** @name Event Handlers + * Handlers for specific SDL events, called by SdlEventSource::dispatchSDLEvent(). + * This way, if a managers inherits fromt this SDL events manager, it can + * change the behavior of only a single event, without having to override all + * of SdlEventSource::dispatchSDLEvent(). + */ + //@{ + + virtual bool handleKeyDown(SDL_Event &ev, Common::Event &event); + virtual bool handleKeyUp(SDL_Event &ev, Common::Event &event); + virtual bool handleMouseMotion(SDL_Event &ev, Common::Event &event); + virtual bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event); + virtual bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event); + virtual bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event); + virtual bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event); + virtual bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event); + virtual void handleKbdMouse(); + + //@} + + /** + * Assigns the mouse coords to the mouse event + */ + virtual void fillMouseEvent(Common::Event &event, int x, int y); + + /** + * Remaps key events. This allows platforms to configure + * their custom keys. + */ + virtual bool remapKey(SDL_Event &ev, Common::Event &event); + + /** + * Maps the ASCII value of key + */ + virtual int mapKey(SDLKey key, SDLMod mod, Uint16 unicode); + + /** + * Configures the key modifiers flags status + */ + virtual void SDLModToOSystemKeyFlags(SDLMod mod, Common::Event &event); +}; + +#endif diff --git a/backends/fs/stdiostream.cpp b/backends/fs/stdiostream.cpp index be7ee0a7b76..695e5672fca 100644 --- a/backends/fs/stdiostream.cpp +++ b/backends/fs/stdiostream.cpp @@ -23,6 +23,9 @@ * */ +// Disable symbol overrides so that we can use FILE, fopen etc. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + #include "backends/fs/stdiostream.h" StdioStream::StdioStream(void *handle) : _handle(handle) { diff --git a/backends/fs/windows/windows-fs-factory.cpp b/backends/fs/windows/windows-fs-factory.cpp index c5a74bfbba4..fdabea7a62a 100644 --- a/backends/fs/windows/windows-fs-factory.cpp +++ b/backends/fs/windows/windows-fs-factory.cpp @@ -22,7 +22,11 @@ * $Id$ */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + #if defined(WIN32) + #include "backends/fs/windows/windows-fs-factory.h" #include "backends/fs/windows/windows-fs.cpp" diff --git a/backends/graphics/graphics.h b/backends/graphics/graphics.h new file mode 100644 index 00000000000..bc5fbb60832 --- /dev/null +++ b/backends/graphics/graphics.h @@ -0,0 +1,67 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_GRAPHICS_ABSTRACT_H +#define BACKENDS_GRAPHICS_ABSTRACT_H + +#include "common/system.h" +#include "common/noncopyable.h" +#include "common/keyboard.h" + +/** + * Abstract class for graphics manager. Subclasses + * implement the real functionality. + */ +class GraphicsManager : Common::NonCopyable { +public: + virtual ~GraphicsManager() {} + + virtual bool hasFeature(OSystem::Feature f) = 0; + virtual void setFeatureState(OSystem::Feature f, bool enable) = 0; + virtual bool getFeatureState(OSystem::Feature f) = 0; + + virtual void launcherInitSize(uint w, uint h) = 0; + virtual byte *setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d) = 0; + virtual int16 getHeight() = 0; + virtual int16 getWidth() = 0; + virtual void updateScreen() = 0; + + virtual void showOverlay() = 0; + virtual void hideOverlay() = 0; + virtual Graphics::PixelFormat getOverlayFormat() const = 0; + virtual void clearOverlay() = 0; + virtual void grabOverlay(OverlayColor *buf, int pitch) = 0; + virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h)= 0; + virtual int16 getOverlayHeight() = 0; + virtual int16 getOverlayWidth() = 0; + + virtual bool showMouse(bool visible) = 0; + virtual void warpMouse(int x, int y) = 0; + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) = 0; + + virtual void displayMessageOnOSD(const char *msg) {} +}; + +#endif diff --git a/backends/platform/sdl/graphics.cpp b/backends/graphics/sdl/sdl-graphics.cpp similarity index 71% rename from backends/platform/sdl/graphics.cpp rename to backends/graphics/sdl/sdl-graphics.cpp index 01e7ffbb6e6..6256a29e90e 100644 --- a/backends/platform/sdl/graphics.cpp +++ b/backends/graphics/sdl/sdl-graphics.cpp @@ -23,7 +23,14 @@ * */ +#include "common/sys.h" + +#if defined(SDL_BACKEND) + +#include "backends/graphics/sdl/sdl-graphics.h" +#include "backends/events/sdl/sdl-events.h" #include "backends/platform/sdl/sdl.h" +#include "common/config-manager.h" #include "common/mutex.h" #include "common/translation.h" #include "common/util.h" @@ -32,17 +39,70 @@ #endif #include "graphics/font.h" #include "graphics/fontman.h" -#include "graphics/scaler.h" #include "graphics/surface.h" +SdlGraphicsManager::SdlGraphicsManager(SdlEventSource *sdlEventSource) + : + _sdlEventSource(sdlEventSource), + _screen(0), + _overlayVisible(false), + _overlayscreen(0), + _overlayWidth(0), _overlayHeight(0), + _overlayDirty(true), _overlayNumTex(0) +#ifdef USE_OPENGL + , _overlayTexIds(0) { +#else + { +#endif + if (SDL_InitSubSystem(SDL_INIT_VIDEO) == -1) { + error("Could not initialize SDL: %s", SDL_GetError()); + } + // This is also called in initSDL(), but initializing graphics + // may reset it. + SDL_EnableUNICODE(1); -void OSystem_SDL::launcherInitSize(uint w, uint h) { +#ifdef _WIN32_WCE + if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) { + SDL_VideoInit("windib", 0); + sdlFlags ^= SDL_INIT_VIDEO; + } +#endif +} + +SdlGraphicsManager::~SdlGraphicsManager() { + // Unregister the event observer + if (g_system->getEventManager()->getEventDispatcher() != NULL) + g_system->getEventManager()->getEventDispatcher()->unregisterObserver(this); +} + +void SdlGraphicsManager::initEventObserver() { + // Register the graphics manager as a event observer + g_system->getEventManager()->getEventDispatcher()->registerObserver(this, 10, false); +} + +bool SdlGraphicsManager::hasFeature(OSystem::Feature f) { + return +#ifdef USE_OPENGL + (f == OSystem::kFeatureOpenGL); +#else + false; +#endif +} + +void SdlGraphicsManager::setFeatureState(OSystem::Feature f, bool enable) { +} + +bool SdlGraphicsManager::getFeatureState(OSystem::Feature f) { + return false; +} + +void SdlGraphicsManager::launcherInitSize(uint w, uint h) { closeOverlay(); setupScreen(w, h, false, false); } -byte *OSystem_SDL::setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d) { +byte *SdlGraphicsManager::setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d) { uint32 sdlflags; int bpp; @@ -161,7 +221,7 @@ byte *OSystem_SDL::setupScreen(int screenW, int screenH, bool fullscreen, bool a #define BITMAP_TEXTURE_SIZE 256 -void OSystem_SDL::updateScreen() { +void SdlGraphicsManager::updateScreen() { #ifdef USE_OPENGL if (_opengl) { if (_overlayVisible) { @@ -265,11 +325,11 @@ void OSystem_SDL::updateScreen() { } } -int16 OSystem_SDL::getHeight() { +int16 SdlGraphicsManager::getHeight() { return _screen->h; } -int16 OSystem_SDL::getWidth() { +int16 SdlGraphicsManager::getWidth() { return _screen->w; } @@ -278,7 +338,7 @@ int16 OSystem_SDL::getWidth() { #pragma mark --- Overlays --- #pragma mark - -void OSystem_SDL::showOverlay() { +void SdlGraphicsManager::showOverlay() { if (_overlayVisible) return; @@ -287,7 +347,8 @@ void OSystem_SDL::showOverlay() { clearOverlay(); } -void OSystem_SDL::hideOverlay() { +void SdlGraphicsManager::hideOverlay() { + if (!_overlayVisible) return; @@ -296,7 +357,8 @@ void OSystem_SDL::hideOverlay() { clearOverlay(); } -void OSystem_SDL::clearOverlay() { +void SdlGraphicsManager::clearOverlay() { + if (!_overlayVisible) return; @@ -324,7 +386,7 @@ void OSystem_SDL::clearOverlay() { _overlayDirty = true; } -void OSystem_SDL::grabOverlay(OverlayColor *buf, int pitch) { +void SdlGraphicsManager::grabOverlay(OverlayColor *buf, int pitch) { if (_overlayscreen == NULL) return; @@ -342,7 +404,7 @@ void OSystem_SDL::grabOverlay(OverlayColor *buf, int pitch) { SDL_UnlockSurface(_overlayscreen); } -void OSystem_SDL::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { +void SdlGraphicsManager::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { if (_overlayscreen == NULL) return; @@ -383,16 +445,7 @@ void OSystem_SDL::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, i SDL_UnlockSurface(_overlayscreen); } - -#pragma mark - -#pragma mark --- Mouse --- -#pragma mark - - -bool OSystem_SDL::showMouse(bool visible) { - return false; -} - -void OSystem_SDL::closeOverlay() { +void SdlGraphicsManager::closeOverlay() { if (_overlayscreen) { SDL_FreeSurface(_overlayscreen); _overlayscreen = NULL; @@ -406,111 +459,20 @@ void OSystem_SDL::closeOverlay() { } } -void OSystem_SDL::warpMouse(int x, int y) { +#pragma mark - +#pragma mark --- Mouse --- +#pragma mark - + +bool SdlGraphicsManager::showMouse(bool visible) { + return false; +} + +void SdlGraphicsManager::warpMouse(int x, int y) { SDL_WarpMouse(x, y); -/* Residual doesn't support this - int y1 = y; - - // Don't change mouse position, when mouse is outside of our window (in case of windowed mode) - if (!(SDL_GetAppState( ) & SDL_APPMOUSEFOCUS)) - return; - - if (_videoMode.aspectRatioCorrection && !_overlayVisible) - y1 = real2Aspect(y); - - if (_mouseCurState.x != x || _mouseCurState.y != y) { - if (!_overlayVisible) - SDL_WarpMouse(x * _videoMode.scaleFactor, y1 * _videoMode.scaleFactor); - else - SDL_WarpMouse(x, y1); - - // SDL_WarpMouse() generates a mouse movement event, so - // setMousePos() would be called eventually. However, the - // cannon script in CoMI calls this function twice each time - // the cannon is reloaded. Unless we update the mouse position - // immediately the second call is ignored, causing the cannon - // to change its aim. - - setMousePos(x, y); - }*/ } -void OSystem_SDL::setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { -#ifdef USE_RGB_COLOR - if (!format) - _cursorFormat = Graphics::PixelFormat::createFormatCLUT8(); - else if (format->bytesPerPixel <= _screenFormat.bytesPerPixel) - _cursorFormat = *format; +bool SdlGraphicsManager::notifyEvent(const Common::Event &event) { + return false; +} - if (_cursorFormat.bytesPerPixel < 4) - assert(keycolor < (uint)(1 << (_cursorFormat.bytesPerPixel << 3))); -#else - assert(keycolor <= 0xFF); #endif - - if (w == 0 || h == 0) - return; - -/* Residual doesn't support this - _mouseCurState.hotX = hotspot_x; - _mouseCurState.hotY = hotspot_y; - - _mouseKeyColor = keycolor; - - _cursorTargetScale = cursorTargetScale; - - _mouseTextureId = new GLuint[1]; - glGenTextures(1, _mouseTextureId); - glBindTexture(GL_TEXTURE_2D, _overlayTexIds[i]); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BITMAP_TEXTURE_SIZE, BITMAP_TEXTURE_SIZE, 0, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, NULL); - - glPixelStorei(GL_UNPACK_ALIGNMENT, 2); - glPixelStorei(GL_UNPACK_ROW_LENGTH, _overlayWidth); - glBindTexture(GL_TEXTURE_2D, _overlayTexIds[curTexIdx]); - glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, _mouseWidth, _mouseHeight, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, (byte *)buf + (y * 2 * _mouseWidth) + (2 * x)); - glPixelStorei(GL_UNPACK_ALIGNMENT, 4); - glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); - - if (_mouseCurState.w != (int)w || _mouseCurState.h != (int)h) { - _mouseCurState.w = w; - _mouseCurState.h = h; - - if (_mouseOrigSurface) - SDL_FreeSurface(_mouseOrigSurface); - - _mouseOrigSurface = SDL_CreateRGBSurface(SDL_SWSURFACE | SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, - _mouseCurState.w, - _mouseCurState.h, - 16, - _hwscreen->format->Rmask, - _hwscreen->format->Gmask, - _hwscreen->format->Bmask, - _hwscreen->format->Amask); - - if (_mouseOrigSurface == NULL) - error("allocating _mouseOrigSurface failed"); - SDL_SetColorKey(_mouseOrigSurface, SDL_RLEACCEL | SDL_SRCCOLORKEY | SDL_SRCALPHA, kMouseColorKey); - } - - free(_mouseData); -#ifdef USE_RGB_COLOR - _mouseData = (byte *)malloc(w * h * _cursorFormat.bytesPerPixel); - memcpy(_mouseData, buf, w * h * _cursorFormat.bytesPerPixel); -#else - _mouseData = (byte *)malloc(w * h); - memcpy(_mouseData, buf, w * h); -#endif - - blitCursor();*/ -} - -void OSystem_SDL::toggleMouseGrab() { - if (SDL_WM_GrabInput(SDL_GRAB_QUERY) == SDL_GRAB_OFF) - SDL_WM_GrabInput(SDL_GRAB_ON); - else - SDL_WM_GrabInput(SDL_GRAB_OFF); -} diff --git a/backends/graphics/sdl/sdl-graphics.h b/backends/graphics/sdl/sdl-graphics.h new file mode 100644 index 00000000000..36756a1f607 --- /dev/null +++ b/backends/graphics/sdl/sdl-graphics.h @@ -0,0 +1,111 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_GRAPHICS_SDL_H +#define BACKENDS_GRAPHICS_SDL_H + +#ifdef USE_OPENGL +#include +#endif + +#include "backends/graphics/graphics.h" +#include "graphics/scaler.h" +#include "common/events.h" +#include "common/system.h" + +#include "backends/events/sdl/sdl-events.h" + +#include "backends/platform/sdl/sdl-sys.h" + + +/** + * SDL graphics manager + */ +class SdlGraphicsManager : public GraphicsManager, public Common::EventObserver { +public: + SdlGraphicsManager(SdlEventSource *sdlEventSource); + virtual ~SdlGraphicsManager(); + + virtual void initEventObserver(); + + virtual bool hasFeature(OSystem::Feature f); + virtual void setFeatureState(OSystem::Feature f, bool enable); + virtual bool getFeatureState(OSystem::Feature f); + + virtual void launcherInitSize(uint w, uint h); + byte *setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d); + virtual int16 getHeight(); + virtual int16 getWidth(); + +public: + virtual void updateScreen(); + + virtual void showOverlay(); + virtual void hideOverlay(); + virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; } + virtual void clearOverlay(); + virtual void grabOverlay(OverlayColor *buf, int pitch); + virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); + virtual int16 getOverlayHeight() { return _overlayHeight; } + virtual int16 getOverlayWidth() { return _overlayWidth; } + void closeOverlay(); + + virtual bool showMouse(bool visible); + virtual void warpMouse(int x, int y); + void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL) {} + +#ifdef USE_OSD + virtual void displayMessageOnOSD(const char *msg); +#endif + + // Override from Common::EventObserver + bool notifyEvent(const Common::Event &event); + +protected: + SdlEventSource *_sdlEventSource; + + SDL_Surface *_screen; + +#ifdef USE_OPENGL + bool _opengl; +#endif + bool _fullscreen; + + // overlay + SDL_Surface *_overlayscreen; + bool _overlayVisible; + Graphics::PixelFormat _overlayFormat; + int _overlayWidth, _overlayHeight; + bool _overlayDirty; +#ifdef USE_OPENGL + int _overlayNumTex; + GLuint *_overlayTexIds; +#endif + + /** Force full redraw on next updateScreen */ + bool _forceFull; +}; + +#endif diff --git a/backends/keymapper/remap-dialog.cpp b/backends/keymapper/remap-dialog.cpp index 4a270ad3c59..d672dc16e73 100644 --- a/backends/keymapper/remap-dialog.cpp +++ b/backends/keymapper/remap-dialog.cpp @@ -26,9 +26,9 @@ #ifdef ENABLE_KEYMAPPER -#include "gui/GuiManager.h" -#include "gui/PopUpWidget.h" -#include "gui/ScrollBarWidget.h" +#include "gui/gui-manager.h" +#include "gui/widgets/popup.h" +#include "gui/widgets/scrollbar.h" #include "gui/ThemeEval.h" #include "common/translation.h" diff --git a/backends/log/log.cpp b/backends/log/log.cpp new file mode 100644 index 00000000000..34deb8f97e6 --- /dev/null +++ b/backends/log/log.cpp @@ -0,0 +1,108 @@ +/* Residual - A 3D game interpreter + * + * 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 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 "backends/log/log.h" + +#include "common/stream.h" +#include "common/str.h" +#include "common/system.h" + +#include "base/version.h" + +namespace Backends { +namespace Log { + +Log::Log(OSystem *system) + : _system(system), _stream(0), _startOfLine(true) { + assert(system); +} + +void Log::open(Common::WriteStream *stream) { + // Close the previous log + close(); + + _stream = stream; + + // Output information about the ScummVM version at the start of the log + // file + print(gResidualFullVersion); + print("\n"); + print(gResidualFeatures); + print("\n"); + print("--- Log opened.\n"); + _startOfLine = true; +} + +void Log::close() { + if (_stream) { + // Output a message to indicate that the log was closed successfully + print("--- Log closed successfully.\n"); + + delete _stream; + _stream = 0; + } +} + +void Log::print(const char *message, const bool printTime) { + if (!_stream) + return; + + while (*message) { + if (_startOfLine) { + _startOfLine = false; + if (printTime) + printTimeStamp(); + } + + const char *msgStart = message; + // scan for end of line/string + while (*message && *message != '\n') + ++message; + + if (*message == '\n') { + ++message; + _startOfLine = true; + } + + // TODO: It might be wise to check for write errors and/or incomplete + // writes here, since losing certain bits of the log is not nice. + _stream->write(msgStart, message - msgStart); + } + + _stream->flush(); +} + +void Log::printTimeStamp() { + TimeDate date; + _system->getTimeAndDate(date); + + _stream->writeString(Common::String::format("[%d-%02d-%02d %02d:%02d:%02d] ", + date.tm_year + 1900, date.tm_mon, date.tm_mday, + date.tm_hour, date.tm_min, date.tm_sec)); +} + +} // End of namespace Log +} // End of namespace Backends + diff --git a/backends/log/log.h b/backends/log/log.h new file mode 100644 index 00000000000..3fd578cf871 --- /dev/null +++ b/backends/log/log.h @@ -0,0 +1,132 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_LOG_LOG_H +#define BACKENDS_LOG_LOG_H + +#include "common/sys.h" + +class OSystem; + +namespace Common { +class WriteStream; +} // End of namespace Common + +namespace Backends { +namespace Log { + +/** + * Log file writer. + * + * This can be used by the backends to implement file logging functionality. + */ +class Log { +public: + /** + * Constructor for the logger object. + * + * @param system The OSystem instance to use. Must be non-null. + */ + Log(OSystem *system); + ~Log() { close(); } + + /** + * Opens a new log file. + * + * The previous log, which was handled by this logger, will be closed + * before the new stream is associated. + * + * The current implemention will always call flush after data is written + * to the log file. It might thus be wise to pass an unbuffered write + * stream here to avoid unnecessary overhead. + * @see Common::WriteStream::flush + * + * Calling open with stream being 0 is valid and will result in the same + * behavior as calling close, but it may have additional overhead. + * @see close + * + * This function will output information about the ScummVM version and + * the features built into ScummVM automatically. It will also add a short + * notice to indicate that the log was opened successfully. + * + * @param stream Stream where to output the log contents. + * Note that the stream will be deleted by the logger. + */ + void open(Common::WriteStream *stream); + + /** + * Closes the current log file. + * + * This function will output a line saying that the log was closed + * successfully. This can be used to check whether a log is incomplete + * because of whatever reasons. + */ + void close(); + + /** + * Prints a message to the log stream. + * + * This has optional support to output a timestamp on every new line. + * The timestamp will look like: "[YYYY-MM-DD HH:MM:SS] ". + * Printing of a timestamp is done by default. + * + * It might be noteworthy that this function does not append a new line + * to the given message. + * + * In case no stream is associated with this logger, this function will + * quit immediatly. + * + * @param message The message to write. + * @param printTimeOnNewline Whether to print a timestamp on the start of + * a new line. + */ + void print(const char *message, const bool printTimeOnNewline = true); +private: + /** + * Prints a time stamp in the form: "[YYYY-MM-DD HH:MM:SS] ". + */ + void printTimeStamp(); + + /** + * The OSystem instance used to query data like the time. + */ + OSystem *_system; + + /** + * Where to write the output too. + */ + Common::WriteStream *_stream; + + /** + * Whether we are at the start of a line. + */ + bool _startOfLine; +}; + +} // End of namespace Log +} // End of namespace Backends + +#endif + diff --git a/backends/midi/alsa.cpp b/backends/midi/alsa.cpp index b36be482575..c5e796beaa7 100644 --- a/backends/midi/alsa.cpp +++ b/backends/midi/alsa.cpp @@ -22,14 +22,17 @@ * $Id$ */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + #include "common/sys.h" #if defined(USE_ALSA) #include "common/config-manager.h" #include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include @@ -41,7 +44,7 @@ #if SND_LIB_MAJOR >= 1 || SND_LIB_MINOR >= 6 #define snd_seq_flush_output(x) snd_seq_drain_output(x) -#define snd_seq_set_client_group(x,name) /*nop */ +#define snd_seq_set_client_group(x,name) /*nop */ #define my_snd_seq_open(seqp) snd_seq_open(seqp, "hw", SND_SEQ_OPEN_DUPLEX, 0) #else /* SND_SEQ_OPEN_OUT causes oops on early version of ALSA */ @@ -50,9 +53,8 @@ #define perm_ok(pinfo,bits) ((snd_seq_port_info_get_capability(pinfo) & (bits)) == (bits)) -static int check_permission(snd_seq_port_info_t *pinfo) -{ - if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE)) { +static int check_permission(snd_seq_port_info_t *pinfo) { + if (perm_ok(pinfo, SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE)) { if (!(snd_seq_port_info_get_capability(pinfo) & SND_SEQ_PORT_CAP_NO_EXPORT)) return 1; } @@ -65,10 +67,11 @@ static int check_permission(snd_seq_port_info_t *pinfo) #define ADDR_DELIM ".:" -class MidiDriver_ALSA:public MidiDriver_MPU401 { +class MidiDriver_ALSA : public MidiDriver_MPU401 { public: MidiDriver_ALSA(int client, int port); int open(); + bool isOpen() const { return _isOpen; } void close(); void send(uint32 b); void sysEx(const byte *msg, uint16 length); @@ -80,11 +83,12 @@ private: snd_seq_t *seq_handle; int seq_client, seq_port; int my_client, my_port; + // The volume controller value of the first MIDI channel + int8 _channel0Volume; }; MidiDriver_ALSA::MidiDriver_ALSA(int client, int port) - : _isOpen(false), seq_handle(0), seq_client(client), seq_port(port), my_client(0), my_port(0) -{ + : _isOpen(false), seq_handle(0), seq_client(client), seq_port(port), my_client(0), my_port(0), _channel0Volume(127) { memset(&ev, 0, sizeof(ev)); } @@ -111,7 +115,7 @@ int MidiDriver_ALSA::open() { // with those capabilities. my_port = snd_seq_create_simple_port(seq_handle, "RESIDUAL port 0", 0, - SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); + SND_SEQ_PORT_TYPE_MIDI_GENERIC | SND_SEQ_PORT_TYPE_APPLICATION); if (my_port < 0) { snd_seq_close(seq_handle); @@ -205,24 +209,41 @@ void MidiDriver_ALSA::send(uint32 b) { case 0xB0: /* is it this simple ? Wow... */ snd_seq_ev_set_controller(&ev, chanID, midiCmd[1], midiCmd[2]); + + // We save the volume of the first MIDI channel here to utilize it in + // our workaround for broken USB-MIDI cables. + if (chanID == 0 && midiCmd[1] == 0x07) + _channel0Volume = midiCmd[2]; + send_event(1); break; case 0xC0: snd_seq_ev_set_pgmchange(&ev, chanID, midiCmd[1]); send_event(0); + + // Send a volume change command to work around a firmware bug in common + // USB-MIDI cables. If the first MIDI command in a USB packet is a + // Cx or Dx command, the second command in the packet is dropped + // somewhere. + send(0x07B0 | (_channel0Volume << 16)); break; case 0xD0: snd_seq_ev_set_chanpress(&ev, chanID, midiCmd[1]); send_event(1); + + // Send a volume change command to work around a firmware bug in common + // USB-MIDI cables. If the first MIDI command in a USB packet is a + // Cx or Dx command, the second command in the packet is dropped + // somewhere. + send(0x07B0 | (_channel0Volume << 16)); break; - case 0xE0:{ - // long theBend = ((((long)midiCmd[1] + (long)(midiCmd[2] << 7))) - 0x2000) / 4; - // snd_seq_ev_set_pitchbend(&ev, chanID, theBend); - long theBend = ((long)midiCmd[1] + (long)(midiCmd[2] << 7)) - 0x2000; - snd_seq_ev_set_pitchbend(&ev, chanID, theBend); - send_event(1); - } - break; + case 0xE0: { + // long theBend = ((((long)midiCmd[1] + (long)(midiCmd[2] << 7))) - 0x2000) / 4; + // snd_seq_ev_set_pitchbend(&ev, chanID, theBend); + long theBend = ((long)midiCmd[1] + (long)(midiCmd[2] << 7)) - 0x2000; + snd_seq_ev_set_pitchbend(&ev, chanID, theBend); + send_event(1); + } break; default: warning("Unknown MIDI Command: %08x", (int)b); @@ -277,6 +298,9 @@ typedef Common::List AlsaDevices; AlsaDevice::AlsaDevice(Common::String name, MusicType mt, int client) : _name(name), _type(mt), _client(client) { + // Make sure we do not get any trailing spaces to avoid problems when + // storing the name in the configuration file. + _name.trim(); } Common::String AlsaDevice::getName() { diff --git a/backends/midi/camd.cpp b/backends/midi/camd.cpp index d00b9e7e091..4ee691cd9e6 100644 --- a/backends/midi/camd.cpp +++ b/backends/midi/camd.cpp @@ -22,14 +22,17 @@ * $Id$ */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + #include "common/sys.h" #if defined(__amigaos4__) #include "common/endian.h" #include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include #include @@ -43,6 +46,7 @@ class MidiDriver_CAMD : public MidiDriver_MPU401 { public: MidiDriver_CAMD(); int open(); + bool isOpen() const { return _isOpen; } void close(); void send(uint32 b); void sysEx(const byte *msg, uint16 length); @@ -79,7 +83,7 @@ int MidiDriver_CAMD::open() { } struct MidiNode *midi_node; - midi_node = _ICamd->CreateMidi(MIDI_MsgQueue, 0L, MIDI_SysExSize, 4096L, MIDI_Name, "scummvm", TAG_END); + midi_node = _ICamd->CreateMidi(MIDI_MsgQueue, 0L, MIDI_SysExSize, 4096L, MIDI_Name, "residual", TAG_END); if (!midi_node) { closeAll(); error("Could not create CAMD MIDI node"); diff --git a/backends/midi/coreaudio.cpp b/backends/midi/coreaudio.cpp index f2ae91aabff..63ed7a7f14e 100644 --- a/backends/midi/coreaudio.cpp +++ b/backends/midi/coreaudio.cpp @@ -22,6 +22,11 @@ * $Id$ */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/sys.h" + #ifdef MACOSX // HACK to disable deprecated warnings under Mac OS X 10.5. @@ -37,8 +42,8 @@ #include "common/config-manager.h" #include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include #include @@ -67,7 +72,9 @@ do { \ class MidiDriver_CORE : public MidiDriver_MPU401 { public: MidiDriver_CORE(); + ~MidiDriver_CORE(); int open(); + bool isOpen() const { return _auGraph != 0; } void close(); void send(uint32 b); void sysEx(const byte *msg, uint16 length); @@ -81,10 +88,18 @@ MidiDriver_CORE::MidiDriver_CORE() : _auGraph(0) { } +MidiDriver_CORE::~MidiDriver_CORE() { + if (_auGraph) { + AUGraphStop(_auGraph); + DisposeAUGraph(_auGraph); + _auGraph = 0; + } +} + int MidiDriver_CORE::open() { OSStatus err = 0; - if (_auGraph) + if (isOpen()) return MERR_ALREADY_OPEN; // Open the Music Device. @@ -171,7 +186,6 @@ bail: void MidiDriver_CORE::close() { MidiDriver_MPU401::close(); - if (_auGraph) { AUGraphStop(_auGraph); DisposeAUGraph(_auGraph); @@ -180,7 +194,7 @@ void MidiDriver_CORE::close() { } void MidiDriver_CORE::send(uint32 b) { - assert(_auGraph != NULL); + assert(isOpen()); byte status_byte = (b & 0x000000FF); byte first_byte = (b & 0x0000FF00) >> 8; @@ -193,7 +207,7 @@ void MidiDriver_CORE::sysEx(const byte *msg, uint16 length) { unsigned char buf[266]; assert(length + 2 <= ARRAYSIZE(buf)); - assert(_auGraph != NULL); + assert(isOpen()); // Add SysEx frame buf[0] = 0xF0; diff --git a/backends/midi/coremidi.cpp b/backends/midi/coremidi.cpp index 217f3799836..b8410c59b8f 100644 --- a/backends/midi/coremidi.cpp +++ b/backends/midi/coremidi.cpp @@ -22,12 +22,17 @@ * $Id$ */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/sys.h" + #ifdef MACOSX #include "common/config-manager.h" #include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include @@ -51,6 +56,7 @@ public: MidiDriver_CoreMIDI(); ~MidiDriver_CoreMIDI(); int open(); + bool isOpen() const { return mOutPort != 0 && mDest != 0; } void close(); void send(uint32 b); void sysEx(const byte *msg, uint16 length); @@ -65,7 +71,7 @@ MidiDriver_CoreMIDI::MidiDriver_CoreMIDI() : mClient(0), mOutPort(0), mDest(0) { OSStatus err; - err = MIDIClientCreate(CFSTR("ScummVM MIDI Driver for OS X"), NULL, NULL, &mClient); + err = MIDIClientCreate(CFSTR("Residual MIDI Driver for OS X"), NULL, NULL, &mClient); } MidiDriver_CoreMIDI::~MidiDriver_CoreMIDI() { @@ -75,7 +81,7 @@ MidiDriver_CoreMIDI::~MidiDriver_CoreMIDI() { } int MidiDriver_CoreMIDI::open() { - if (mDest) + if (isOpen()) return MERR_ALREADY_OPEN; OSStatus err = noErr; @@ -86,7 +92,7 @@ int MidiDriver_CoreMIDI::open() { if (dests > 0 && mClient) { mDest = MIDIGetDestination(0); err = MIDIOutputPortCreate( mClient, - CFSTR("scummvm_output_port"), + CFSTR("residual_output_port"), &mOutPort); } else { return MERR_DEVICE_NOT_AVAILABLE; @@ -101,7 +107,7 @@ int MidiDriver_CoreMIDI::open() { void MidiDriver_CoreMIDI::close() { MidiDriver_MPU401::close(); - if (mOutPort && mDest) { + if (isOpen()) { MIDIPortDispose(mOutPort); mOutPort = 0; mDest = 0; @@ -109,8 +115,7 @@ void MidiDriver_CoreMIDI::close() { } void MidiDriver_CoreMIDI::send(uint32 b) { - assert(mOutPort != 0); - assert(mDest != 0); + assert(isOpen()); // Extract the MIDI data byte status_byte = (b & 0x000000FF); @@ -153,8 +158,7 @@ void MidiDriver_CoreMIDI::send(uint32 b) { } void MidiDriver_CoreMIDI::sysEx(const byte *msg, uint16 length) { - assert(mOutPort != 0); - assert(mDest != 0); + assert(isOpen()); byte buf[384]; MIDIPacketList *packetList = (MIDIPacketList *)buf; diff --git a/backends/midi/dmedia.cpp b/backends/midi/dmedia.cpp index 1087de630f9..ca0b62ce8a6 100644 --- a/backends/midi/dmedia.cpp +++ b/backends/midi/dmedia.cpp @@ -27,13 +27,18 @@ * some code liberated from seq.cpp and coremidi.cpp */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/sys.h" + #if defined(IRIX) #include "common/sys.h" #include "common/util.h" #include "common/config-manager.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include #include @@ -52,6 +57,7 @@ class MidiDriver_DMEDIA : public MidiDriver_MPU401 { public: MidiDriver_DMEDIA(); int open(); + bool isOpen() const { return _isOpen; } void close(); void send(uint32 b); void sysEx(const byte *msg, uint16 length); @@ -87,8 +93,8 @@ int MidiDriver_DMEDIA::open() { return -1; } - if (getenv("SCUMMVM_MIDIPORT")) { - _deviceNum = atoi(getenv("SCUMMVM_MIDIPORT")); + if (getenv("RESIDUAL_MIDIPORT")) { + _deviceNum = atoi(getenv("RESIDUAL_MIDIPORT")); _midiportName = mdGetName(_deviceNum); } else { var = ConfMan.get("dmedia_port").c_str(); @@ -174,7 +180,7 @@ void MidiDriver_DMEDIA::sysEx (const byte *msg, uint16 length) { memcpy(buf, msg, length); buf[length] = MD_EOX; event.sysexmsg = buf; - event.msglen = length; + event.msglen = length; event.msg[0] = MD_SYSEX; event.msg[1] = 0; event.msg[2] = 0; diff --git a/backends/midi/seq.cpp b/backends/midi/seq.cpp index ab66651d434..64f4af2a2c5 100644 --- a/backends/midi/seq.cpp +++ b/backends/midi/seq.cpp @@ -28,16 +28,20 @@ * both the QuickTime support and (vkeybd http://www.alsa-project.org/~iwai/alsa.html) */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + #include "common/sys.h" #if defined(USE_SEQ_MIDI) #include "common/util.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include #include +#include //////////////////////////////////////// // @@ -51,6 +55,7 @@ class MidiDriver_SEQ : public MidiDriver_MPU401 { public: MidiDriver_SEQ(); int open(); + bool isOpen() const { return _isOpen; } void close(); void send(uint32 b); void sysEx(const byte *msg, uint16 length); @@ -75,14 +80,14 @@ int MidiDriver_SEQ::open() { _isOpen = true; device = 0; - device_name = getenv("SCUMMVM_MIDI"); + device_name = getenv("RESIDUAL_MIDI"); if (device_name == NULL) { - warning("SCUMMVM_MIDI environment variable not set, using /dev/sequencer"); + warning("RESIDUAL_MIDI environment variable not set, using /dev/sequencer"); device_name = dev_seq; } - device = (::open((device_name), O_RDWR, 0)); + device = ::open((device_name), O_RDWR, 0); if ((device_name == NULL) || (device < 0)) { if (device_name == NULL) @@ -95,8 +100,8 @@ int MidiDriver_SEQ::open() { error("Cannot open /dev/null to dump midi output"); } - if (getenv("SCUMMVM_MIDIPORT")) - _device_num = atoi(getenv("SCUMMVM_MIDIPORT")); + if (getenv("RESIDUAL_MIDIPORT")) + _device_num = atoi(getenv("RESIDUAL_MIDIPORT")); return 0; } @@ -144,10 +149,11 @@ void MidiDriver_SEQ::send(uint32 b) { warning("MidiDriver_SEQ::send: unknown : %08x", (int)b); break; } - (void)write(device, buf, position); + if (write(device, buf, position) == -1) + warning("MidiDriver_SEQ::send: write failed (%s)", strerror(errno)); } -void MidiDriver_SEQ::sysEx (const byte *msg, uint16 length) { +void MidiDriver_SEQ::sysEx(const byte *msg, uint16 length) { unsigned char buf [266*4]; int position = 0; const byte *chr = msg; @@ -169,7 +175,8 @@ void MidiDriver_SEQ::sysEx (const byte *msg, uint16 length) { buf[position++] = _device_num; buf[position++] = 0; - (void)write(device, buf, position); + if (write(device, buf, position) == -1) + warning("MidiDriver_SEQ::send: write failed (%s)", strerror(errno)); } diff --git a/backends/midi/stmidi.cpp b/backends/midi/stmidi.cpp index ca47d5e77ef..173eb58d7e2 100644 --- a/backends/midi/stmidi.cpp +++ b/backends/midi/stmidi.cpp @@ -34,17 +34,23 @@ * cycles. I might change so sysex messages are sent the other way later. */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/sys.h" + #if defined __MINT__ #include -#include "sound/mpu401.h" +#include "audio/mpu401.h" #include "common/util.h" -#include "sound/musicplugin.h" +#include "audio/musicplugin.h" class MidiDriver_STMIDI : public MidiDriver_MPU401 { public: - MidiDriver_STMIDI() : _isOpen (false) { } + MidiDriver_STMIDI() : _isOpen (false) { } int open(); + bool isOpen() const { return _isOpen; } void close(); void send(uint32 b); void sysEx(const byte *msg, uint16 length); @@ -54,7 +60,7 @@ private: }; int MidiDriver_STMIDI::open() { - if ((_isOpen) && (!Bcostat(4))) + if (_isOpen && (!Bcostat(4))) return MERR_ALREADY_OPEN; warning("ST Midi Port Open"); _isOpen = true; @@ -118,36 +124,36 @@ void MidiDriver_STMIDI::sysEx (const byte *msg, uint16 length) { class StMidiMusicPlugin : public MusicPluginObject { public: - const char *getName() const { - return "STMIDI"; - } + const char *getName() const { + return "STMIDI"; + } - const char *getId() const { - return "stmidi"; - } + const char *getId() const { + return "stmidi"; + } - MusicDevices getDevices() const; - Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; + MusicDevices getDevices() const; + Common::Error createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle = 0) const; }; MusicDevices StMidiMusicPlugin::getDevices() const { - MusicDevices devices; - // TODO: Return a different music type depending on the configuration - // TODO: List the available devices - devices.push_back(MusicDevice(this, "", MT_GM)); - return devices; + MusicDevices devices; + // TODO: Return a different music type depending on the configuration + // TODO: List the available devices + devices.push_back(MusicDevice(this, "", MT_GM)); + return devices; } Common::Error StMidiMusicPlugin::createInstance(MidiDriver **mididriver, MidiDriver::DeviceHandle) const { - *mididriver = new MidiDriver_STMIDI(); + *mididriver = new MidiDriver_STMIDI(); - return Common::kNoError; + return Common::kNoError; } //#if PLUGIN_ENABLED_DYNAMIC(STMIDI) - //REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); + //REGISTER_PLUGIN_DYNAMIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); //#else - REGISTER_PLUGIN_STATIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); + REGISTER_PLUGIN_STATIC(STMIDI, PLUGIN_TYPE_MUSIC, StMidiMusicPlugin); //#endif #endif diff --git a/backends/midi/timidity.cpp b/backends/midi/timidity.cpp index fccbd6f2b5e..a62242fbf0f 100644 --- a/backends/midi/timidity.cpp +++ b/backends/midi/timidity.cpp @@ -34,13 +34,18 @@ * */ -#if defined (UNIX) +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/sys.h" + +#if defined(USE_TIMIDITY) #include "common/util.h" #include "common/endian.h" #include "common/str.h" -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include #include @@ -87,49 +92,50 @@ class MidiDriver_TIMIDITY : public MidiDriver_MPU401 { public: MidiDriver_TIMIDITY(); - int open(); - void close(); - void send(uint32 b); - void sysEx(const byte *msg, uint16 length); + int open(); + bool isOpen() const { return _isOpen; } + void close(); + void send(uint32 b); + void sysEx(const byte *msg, uint16 length); private: /* standart routine to extract ip address from a string */ - in_addr_t host_to_addr(const char* address); + in_addr_t host_to_addr(const char* address); /* creates a tcp connection to TiMidity server, returns filedesc (like open()) */ - int connect_to_server(const char* hostname, unsigned short tcp_port); + int connect_to_server(const char* hostname, unsigned short tcp_port); /* send command to the server; printf-like; returns reply string */ - char *timidity_ctl_command(const char *fmt, ...) GCC_PRINTF(2, 3); + char *timidity_ctl_command(const char *fmt, ...) GCC_PRINTF(2, 3); /* timidity data socket-related stuff */ - void timidity_meta_seq(int p1, int p2, int p3); - int timidity_sync(int centsec); - int timidity_eot(); + void timidity_meta_seq(int p1, int p2, int p3); + int timidity_sync(int centsec); + int timidity_eot(); /* write() analogue for any midi data */ - void timidity_write_data(const void *buf, size_t nbytes); + void timidity_write_data(const void *buf, size_t nbytes); /* get single line of server reply on control connection */ - int fdgets(char *buff, size_t buff_size); + int fdgets(char *buff, size_t buff_size); /* teardown connection to server */ - void teardown(); + void teardown(); /* close (if needed) and nullify both control and data filedescs */ - void close_all(); + void close_all(); private: - bool _isOpen; - int _device_num; + bool _isOpen; + int _device_num; - int _control_fd; - int _data_fd; + int _control_fd; + int _data_fd; /* buffer for partial data read from _control_fd - from timidity-io.c, see fdgets() */ - char _controlbuffer[BUFSIZ]; - int _controlbuffer_count; /* beginning of read pointer */ - int _controlbuffer_size; /* end of read pointer */ + char _controlbuffer[BUFSIZ]; + int _controlbuffer_count; /* beginning of read pointer */ + int _controlbuffer_size; /* end of read pointer */ }; MidiDriver_TIMIDITY::MidiDriver_TIMIDITY() { @@ -144,9 +150,9 @@ MidiDriver_TIMIDITY::MidiDriver_TIMIDITY() { } int MidiDriver_TIMIDITY::open() { - char *res; - char timidity_host[MAXHOSTNAMELEN]; - int timidity_port, data_port, i; + char *res; + char timidity_host[MAXHOSTNAMELEN]; + int timidity_port, data_port, i; /* count ourselves open */ if (_isOpen) @@ -228,8 +234,8 @@ int MidiDriver_TIMIDITY::open() { /* * From seq.cpp */ - if (getenv("SCUMMVM_MIDIPORT")) - _device_num = atoi(getenv("SCUMMVM_MIDIPORT")); + if (getenv("RESIDUAL_MIDIPORT")) + _device_num = atoi(getenv("RESIDUAL_MIDIPORT")); return 0; } @@ -332,7 +338,11 @@ char *MidiDriver_TIMIDITY::timidity_ctl_command(const char *fmt, ...) { buff[len++] = '\n'; /* write command to control socket */ - (void)write(_control_fd, buff, len); + if (write(_control_fd, buff, len) == -1) { + warning("TiMidity: CONTROL WRITE FAILED (%s)", strerror(errno)); + // TODO: Disable output? + //close_all(); + } } while (1) { @@ -418,10 +428,9 @@ void MidiDriver_TIMIDITY::timidity_write_data(const void *buf, size_t nbytes) { } int MidiDriver_TIMIDITY::fdgets(char *buff, size_t buff_size) { - int n, len, count, size; + int n, count, size; char *buff_endp = buff + buff_size - 1, *pbuff, *beg; - len = 0; count = _controlbuffer_count; size = _controlbuffer_size; pbuff = _controlbuffer; diff --git a/backends/midi/windows.cpp b/backends/midi/windows.cpp index 0634ccd8462..69ee9b6c0d2 100644 --- a/backends/midi/windows.cpp +++ b/backends/midi/windows.cpp @@ -22,6 +22,11 @@ * $Id$ */ +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/sys.h" + #if defined(WIN32) && !defined(_WIN32_WCE) #define WIN32_LEAN_AND_MEAN @@ -29,8 +34,8 @@ // winnt.h defines ARRAYSIZE, but we want our own one... #undef ARRAYSIZE -#include "sound/musicplugin.h" -#include "sound/mpu401.h" +#include "audio/musicplugin.h" +#include "audio/mpu401.h" #include "common/config-manager.h" #include "common/translation.h" @@ -56,6 +61,7 @@ private: public: MidiDriver_WIN(int deviceIndex) : _isOpen(false), _device(deviceIndex) { } int open(); + bool isOpen() const { return _isOpen; } void close(); void send(uint32 b); void sysEx(const byte *msg, uint16 length); @@ -88,6 +94,8 @@ void MidiDriver_WIN::close() { } void MidiDriver_WIN::send(uint32 b) { + assert(_isOpen); + union { DWORD dwData; BYTE bData[4]; diff --git a/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.cpp b/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.cpp new file mode 100644 index 00000000000..012c334fcda --- /dev/null +++ b/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.cpp @@ -0,0 +1,129 @@ +/* Residual - A 3D game interpreter + * + * 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 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$ + * + */ + +#if defined(MACOSX) || defined(GP2X) + +#include "backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h" + +DoubleBufferSDLMixerManager::DoubleBufferSDLMixerManager() + : + _soundMutex(0), _soundCond(0), _soundThread(0), + _soundThreadIsRunning(false), _soundThreadShouldQuit(false) { + +} + +DoubleBufferSDLMixerManager::~DoubleBufferSDLMixerManager() { + deinitThreadedMixer(); +} + +void DoubleBufferSDLMixerManager::startAudio() { + _soundThreadIsRunning = false; + _soundThreadShouldQuit = false; + + // Create mutex and condition variable + _soundMutex = SDL_CreateMutex(); + _soundCond = SDL_CreateCond(); + + // Create two sound buffers + _activeSoundBuf = 0; + uint bufSize = _obtainedRate.samples * 4; + _soundBufSize = bufSize; + _soundBuffers[0] = (byte *)calloc(1, bufSize); + _soundBuffers[1] = (byte *)calloc(1, bufSize); + + _soundThreadIsRunning = true; + + // Finally start the thread + _soundThread = SDL_CreateThread(mixerProducerThreadEntry, this); + + SdlMixerManager::startAudio(); +} + +void DoubleBufferSDLMixerManager::mixerProducerThread() { + byte nextSoundBuffer; + + SDL_LockMutex(_soundMutex); + while (true) { + // Wait till we are allowed to produce data + SDL_CondWait(_soundCond, _soundMutex); + + if (_soundThreadShouldQuit) + break; + + // Generate samples and put them into the next buffer + nextSoundBuffer = _activeSoundBuf ^ 1; + _mixer->mixCallback(_soundBuffers[nextSoundBuffer], _soundBufSize); + + // Swap buffers + _activeSoundBuf = nextSoundBuffer; + } + SDL_UnlockMutex(_soundMutex); +} + +int SDLCALL DoubleBufferSDLMixerManager::mixerProducerThreadEntry(void *arg) { + DoubleBufferSDLMixerManager *mixer = (DoubleBufferSDLMixerManager *)arg; + assert(mixer); + mixer->mixerProducerThread(); + return 0; +} + +void DoubleBufferSDLMixerManager::deinitThreadedMixer() { + // Kill thread?? _soundThread + + if (_soundThreadIsRunning) { + // Signal the producer thread to end, and wait for it to actually finish. + _soundThreadShouldQuit = true; + SDL_CondBroadcast(_soundCond); + SDL_WaitThread(_soundThread, NULL); + + // Kill the mutex & cond variables. + // Attention: AT this point, the mixer callback must not be running + // anymore, else we will crash! + SDL_DestroyMutex(_soundMutex); + SDL_DestroyCond(_soundCond); + + _soundThreadIsRunning = false; + + free(_soundBuffers[0]); + free(_soundBuffers[1]); + } +} + +void DoubleBufferSDLMixerManager::callbackHandler(byte *samples, int len) { + assert(_mixer); + assert((int)_soundBufSize == len); + + // Lock mutex, to ensure our data is not overwritten by the producer thread + SDL_LockMutex(_soundMutex); + + // Copy data from the current sound buffer + memcpy(samples, _soundBuffers[_activeSoundBuf], len); + + // Unlock mutex and wake up the produced thread + SDL_UnlockMutex(_soundMutex); + SDL_CondSignal(_soundCond); +} + +#endif diff --git a/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h b/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h new file mode 100644 index 00000000000..059693d48dc --- /dev/null +++ b/backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h @@ -0,0 +1,69 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_MIXER_DOUBLEBUFFERSDL_H +#define BACKENDS_MIXER_DOUBLEBUFFERSDL_H + +#include "backends/mixer/sdl/sdl-mixer.h" + +/** + * SDL mixer manager with double buffering support. + */ +class DoubleBufferSDLMixerManager : public SdlMixerManager { +public: + DoubleBufferSDLMixerManager(); + virtual ~DoubleBufferSDLMixerManager(); + +protected: + SDL_mutex *_soundMutex; + SDL_cond *_soundCond; + SDL_Thread *_soundThread; + bool _soundThreadIsRunning; + bool _soundThreadShouldQuit; + + byte _activeSoundBuf; + uint _soundBufSize; + byte *_soundBuffers[2]; + + /** + * Handles and swap the sound buffers + */ + void mixerProducerThread(); + + /** + * Finish the mixer manager + */ + void deinitThreadedMixer(); + + /** + * Callback entry point for the sound thread + */ + static int SDLCALL mixerProducerThreadEntry(void *arg); + + virtual void startAudio(); + virtual void callbackHandler(byte *samples, int len); +}; + +#endif diff --git a/backends/mixer/sdl/sdl-mixer.cpp b/backends/mixer/sdl/sdl-mixer.cpp new file mode 100644 index 00000000000..cd33bb845dc --- /dev/null +++ b/backends/mixer/sdl/sdl-mixer.cpp @@ -0,0 +1,143 @@ +/* Residual - A 3D game interpreter + * + * 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 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$ + * + */ + +#if defined(SDL_BACKEND) + +#include "backends/mixer/sdl/sdl-mixer.h" +#include "common/system.h" +#include "common/config-manager.h" + +#ifdef GP2X +#define SAMPLES_PER_SEC 11025 +#else +#define SAMPLES_PER_SEC 22050 +#endif +//#define SAMPLES_PER_SEC 44100 + +SdlMixerManager::SdlMixerManager() + : + _mixer(0), + _audioSuspended(false) { + +} + +SdlMixerManager::~SdlMixerManager() { + _mixer->setReady(false); + + SDL_CloseAudio(); + + delete _mixer; +} + +void SdlMixerManager::init() { + // Start SDL Audio subsystem + if (SDL_InitSubSystem(SDL_INIT_AUDIO) == -1) { + error("Could not initialize SDL: %s", SDL_GetError()); + } + + // Get the desired audio specs + SDL_AudioSpec desired = getAudioSpec(SAMPLES_PER_SEC); + + // Start SDL audio with the desired specs + if (SDL_OpenAudio(&desired, &_obtainedRate) != 0) { + warning("Could not open audio device: %s", SDL_GetError()); + + _mixer = new Audio::MixerImpl(g_system, desired.freq); + assert(_mixer); + _mixer->setReady(false); + } else { + debug(1, "Output sample rate: %d Hz", _obtainedRate.freq); + + _mixer = new Audio::MixerImpl(g_system, _obtainedRate.freq); + assert(_mixer); + _mixer->setReady(true); + + startAudio(); + } +} + +SDL_AudioSpec SdlMixerManager::getAudioSpec(uint32 outputRate) { + SDL_AudioSpec desired; + + // Determine the desired output sampling frequency. + uint32 samplesPerSec = 0; + if (ConfMan.hasKey("output_rate")) + samplesPerSec = ConfMan.getInt("output_rate"); + if (samplesPerSec <= 0) + samplesPerSec = outputRate; + + // Determine the sample buffer size. We want it to store enough data for + // at least 1/16th of a second (though at most 8192 samples). Note + // that it must be a power of two. So e.g. at 22050 Hz, we request a + // sample buffer size of 2048. + uint32 samples = 8192; + while (samples * 16 > samplesPerSec * 2) + samples >>= 1; + + memset(&desired, 0, sizeof(desired)); + desired.freq = samplesPerSec; + desired.format = AUDIO_S16SYS; + desired.channels = 2; + desired.samples = (uint16)samples; + desired.callback = sdlCallback; + desired.userdata = this; + + return desired; +} + +void SdlMixerManager::startAudio() { + // Start the sound system + SDL_PauseAudio(0); +} + +void SdlMixerManager::callbackHandler(byte *samples, int len) { + assert(_mixer); + _mixer->mixCallback(samples, len); +} + +void SdlMixerManager::sdlCallback(void *this_, byte *samples, int len) { + SdlMixerManager *manager = (SdlMixerManager *)this_; + assert(manager); + + manager->callbackHandler(samples, len); +} + +void SdlMixerManager::suspendAudio() { + SDL_CloseAudio(); + _audioSuspended = true; +} + +int SdlMixerManager::resumeAudio() { + if (!_audioSuspended) + return -2; + if (SDL_OpenAudio(&_obtainedRate, NULL) < 0){ + return -1; + } + SDL_PauseAudio(0); + _audioSuspended = false; + return 0; +} + +#endif diff --git a/backends/mixer/sdl/sdl-mixer.h b/backends/mixer/sdl/sdl-mixer.h new file mode 100644 index 00000000000..74ea6a06898 --- /dev/null +++ b/backends/mixer/sdl/sdl-mixer.h @@ -0,0 +1,100 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_MIXER_SDL_H +#define BACKENDS_MIXER_SDL_H + +#include "backends/platform/sdl/sdl-sys.h" +#include "audio/mixer_intern.h" + +/** + * SDL mixer manager. It wraps the actual implementation + * of the Audio:Mixer used by the engine, and setups + * the SDL audio subsystem and the callback for the + * audio mixer implementation. + */ +class SdlMixerManager { +public: + SdlMixerManager(); + virtual ~SdlMixerManager(); + + /** + * Initialize and setups the mixer + */ + virtual void init(); + + /** + * Get the audio mixer implementation + */ + Audio::Mixer *getMixer() { return (Audio::Mixer *)_mixer; } + + // Used by LinuxMoto Port + + /** + * Pauses the audio system + */ + virtual void suspendAudio(); + + /** + * Resumes the audio system + */ + virtual int resumeAudio(); + +protected: + /** The mixer implementation */ + Audio::MixerImpl *_mixer; + + /** + * The obtained audio specification after opening the + * audio system. + */ + SDL_AudioSpec _obtainedRate; + + /** State of the audio system */ + bool _audioSuspended; + + /** + * Returns the desired audio specification + */ + virtual SDL_AudioSpec getAudioSpec(uint32 rate); + + /** + * Starts SDL audio + */ + virtual void startAudio(); + + /** + * Handles the audio callback + */ + virtual void callbackHandler(byte *samples, int len); + + /** + * The mixer callback entry point. Static functions can't be overrided + * by subclasses, so it invokes the non-static function callbackHandler() + */ + static void sdlCallback(void *this_, byte *samples, int len); +}; + +#endif diff --git a/backends/modular-backend.cpp b/backends/modular-backend.cpp new file mode 100644 index 00000000000..24a17ee4f76 --- /dev/null +++ b/backends/modular-backend.cpp @@ -0,0 +1,201 @@ +/* Residual - A 3D game interpreter + * + * 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 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 "backends/modular-backend.h" + +#include "backends/fs/fs-factory.h" +#include "backends/events/default/default-events.h" +#include "backends/audiocd/default/default-audiocd.h" +#include "backends/mutex/mutex.h" +#include "backends/graphics/graphics.h" + +#include "gui/message.h" + +ModularBackend::ModularBackend() + : + _fsFactory(0), + _eventManager(0), + _savefileManager(0), + _timerManager(0), + _mutexManager(0), + _graphicsManager(0), + _mixer(0), + _audiocdManager(0) { + +} + +ModularBackend::~ModularBackend() { + delete _fsFactory; + _fsFactory = 0; + delete _graphicsManager; + _graphicsManager = 0; + delete _eventManager; + _eventManager = 0; + delete _mixer; + _mixer = 0; + delete _audiocdManager; + _audiocdManager = 0; + delete _savefileManager; + _savefileManager = 0; + delete _timerManager; + _timerManager = 0; + delete _mutexManager; + _mutexManager = 0; +} + +bool ModularBackend::hasFeature(Feature f) { + return _graphicsManager->hasFeature(f); +} + +void ModularBackend::setFeatureState(Feature f, bool enable) { + return _graphicsManager->setFeatureState(f, enable); +} + +bool ModularBackend::getFeatureState(Feature f) { + return _graphicsManager->getFeatureState(f); +} + +GraphicsManager *ModularBackend::getGraphicsManager() { + assert(_graphicsManager); + return (GraphicsManager *)_graphicsManager; +} + +void ModularBackend::launcherInitSize(uint w, uint h) { + _graphicsManager->launcherInitSize(w, h); +} + +byte *ModularBackend::setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d) { + return _graphicsManager->setupScreen(screenW, screenH, fullscreen, accel3d); +} + +int16 ModularBackend::getHeight() { + return _graphicsManager->getHeight(); +} + +int16 ModularBackend::getWidth() { + return _graphicsManager->getWidth(); +} + +void ModularBackend::updateScreen() { + _graphicsManager->updateScreen(); +} + +void ModularBackend::showOverlay() { + _graphicsManager->showOverlay(); +} + +void ModularBackend::hideOverlay() { + _graphicsManager->hideOverlay(); +} + +Graphics::PixelFormat ModularBackend::getOverlayFormat() const { + return _graphicsManager->getOverlayFormat(); +} + +void ModularBackend::clearOverlay() { + _graphicsManager->clearOverlay(); +} + +void ModularBackend::grabOverlay(OverlayColor *buf, int pitch) { + _graphicsManager->grabOverlay(buf, pitch); +} + +void ModularBackend::copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h) { + _graphicsManager->copyRectToOverlay(buf, pitch, x, y, w, h); +} + +int16 ModularBackend::getOverlayHeight() { + return _graphicsManager->getOverlayHeight(); +} + +int16 ModularBackend::getOverlayWidth() { + return _graphicsManager->getOverlayWidth(); +} + +bool ModularBackend::showMouse(bool visible) { + return _graphicsManager->showMouse(visible); +} + +void ModularBackend::warpMouse(int x, int y) { + _graphicsManager->warpMouse(x, y); +} + +void ModularBackend::setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format) { + _graphicsManager->setMouseCursor(buf, w, h, hotspotX, hotspotY, keycolor, cursorTargetScale, format); +} + +Common::TimerManager *ModularBackend::getTimerManager() { + assert(_timerManager); + return _timerManager; +} + +Common::EventManager *ModularBackend::getEventManager() { + assert(_eventManager); + return _eventManager; +} + +OSystem::MutexRef ModularBackend::createMutex() { + assert(_mutexManager); + return _mutexManager->createMutex(); +} + +void ModularBackend::lockMutex(MutexRef mutex) { + assert(_mutexManager); + _mutexManager->lockMutex(mutex); +} + +void ModularBackend::unlockMutex(MutexRef mutex) { + assert(_mutexManager); + _mutexManager->unlockMutex(mutex); +} + +void ModularBackend::deleteMutex(MutexRef mutex) { + assert(_mutexManager); + _mutexManager->deleteMutex(mutex); +} + +Audio::Mixer *ModularBackend::getMixer() { + assert(_mixer); + return (Audio::Mixer *)_mixer; +} + +AudioCDManager *ModularBackend::getAudioCDManager() { + assert(_audiocdManager); + return _audiocdManager; +} + +void ModularBackend::displayMessageOnOSD(const char *msg) { + _graphicsManager->displayMessageOnOSD(msg); +} + +Common::SaveFileManager *ModularBackend::getSavefileManager() { + assert(_savefileManager); + return _savefileManager; +} + +FilesystemFactory *ModularBackend::getFilesystemFactory() { + assert(_fsFactory); + return _fsFactory; +} diff --git a/backends/modular-backend.h b/backends/modular-backend.h new file mode 100644 index 00000000000..155611069ca --- /dev/null +++ b/backends/modular-backend.h @@ -0,0 +1,154 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_MODULAR_BACKEND_H +#define BACKENDS_MODULAR_BACKEND_H + +#include "common/system.h" +#include "common/timer.h" +#include "common/savefile.h" + +class GraphicsManager; +class MutexManager; + +/** + * Base class for modular backends. + * + * It wraps most functions to their manager equivalent, but not + * all OSystem functions are implemented here. + * + * A backend derivated from this class, will need to implement + * these functions on its own: + * OSystem::pollEvent() + * OSystem::createConfigReadStream() + * OSystem::createConfigWriteStream() + * OSystem::getMillis() + * OSystem::delayMillis() + * OSystem::getTimeAndDate() + * + * And, it should also initialize all the managers variables + * declared in this class, or override their related functions. + */ +class ModularBackend : public OSystem { +public: + ModularBackend(); + virtual ~ModularBackend(); + + /** @name Features */ + //@{ + + virtual bool hasFeature(Feature f); + virtual void setFeatureState(Feature f, bool enable); + virtual bool getFeatureState(Feature f); + + //@} + + /** @name Graphics */ + //@{ + + virtual GraphicsManager *getGraphicsManager(); + virtual void launcherInitSize(uint w, uint h); + virtual byte *setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d); + + virtual int16 getHeight(); + virtual int16 getWidth(); + virtual void updateScreen(); + + virtual void showOverlay(); + virtual void hideOverlay(); + virtual Graphics::PixelFormat getOverlayFormat() const; + virtual void clearOverlay(); + virtual void grabOverlay(OverlayColor *buf, int pitch); + virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); + virtual int16 getOverlayHeight(); + virtual int16 getOverlayWidth(); + + virtual bool showMouse(bool visible); + virtual void warpMouse(int x, int y); + virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspotX, int hotspotY, uint32 keycolor, int cursorTargetScale = 1, const Graphics::PixelFormat *format = NULL); + + //@} + + /** @name Events and Time */ + //@{ + + virtual Common::TimerManager *getTimerManager(); + virtual Common::EventManager *getEventManager(); + virtual Common::HardwareKeySet *getHardwareKeySet() { return 0; } + + //@} + + /** @name Mutex handling */ + //@{ + + virtual MutexRef createMutex(); + virtual void lockMutex(MutexRef mutex); + virtual void unlockMutex(MutexRef mutex); + virtual void deleteMutex(MutexRef mutex); + + //@} + + /** @name Sound */ + //@{ + + virtual Audio::Mixer *getMixer(); + + //@} + + /** @name Audio CD */ + //@{ + + virtual AudioCDManager *getAudioCDManager(); + + //@} + + /** @name Miscellaneous */ + //@{ + + virtual Common::SaveFileManager *getSavefileManager(); + virtual FilesystemFactory *getFilesystemFactory(); + virtual void quit() { exit(0); } + virtual void setWindowCaption(const char *caption) {} + virtual void displayMessageOnOSD(const char *msg); + + //@} + +protected: + /** @name Managers variables */ + //@{ + + FilesystemFactory *_fsFactory; + Common::EventManager *_eventManager; + Common::SaveFileManager *_savefileManager; + Common::TimerManager *_timerManager; + MutexManager *_mutexManager; + GraphicsManager *_graphicsManager; + Audio::Mixer *_mixer; + AudioCDManager *_audiocdManager; + + //@} +}; + +#endif diff --git a/backends/module.mk b/backends/module.mk index ac6fa2bdbcc..c447dbe251b 100644 --- a/backends/module.mk +++ b/backends/module.mk @@ -2,16 +2,22 @@ MODULE := backends MODULE_OBJS := \ base-backend.o \ + modular-backend.o \ + audiocd/default/default-audiocd.o \ + audiocd/sdl/sdl-audiocd.o \ events/default/default-events.o \ + events/sdl/sdl-events.o \ fs/abstract-fs.o \ fs/stdiostream.o \ fs/amigaos4/amigaos4-fs-factory.o \ fs/posix/posix-fs-factory.o \ fs/windows/windows-fs-factory.o \ + graphics/sdl/sdl-graphics.o \ keymapper/action.o \ keymapper/keymap.o \ keymapper/keymapper.o \ keymapper/remap-dialog.o \ + log/log.o \ midi/alsa.o \ midi/camd.o \ midi/coreaudio.o \ @@ -21,6 +27,9 @@ MODULE_OBJS := \ midi/timidity.o \ midi/dmedia.o \ midi/windows.o \ + mixer/doublebuffersdl/doublebuffersdl-mixer.o \ + mixer/sdl/sdl-mixer.o \ + mutex/sdl/sdl-mutex.o \ plugins/posix/posix-provider.o \ plugins/sdl/sdl-provider.o \ plugins/win32/win32-provider.o \ @@ -28,6 +37,7 @@ MODULE_OBJS := \ saves/default/default-saves.o \ saves/posix/posix-saves.o \ timer/default/default-timer.o \ + timer/sdl/sdl-timer.o \ vkeybd/image-map.o \ vkeybd/polygon.o \ vkeybd/virtual-keyboard.o \ @@ -42,7 +52,8 @@ endif ifeq ($(BACKEND),ds) MODULE_OBJS += \ fs/ds/ds-fs-factory.o \ - fs/ds/ds-fs.o + fs/ds/ds-fs.o \ + plugins/ds/ds-provider.o endif ifeq ($(BACKEND),n64) @@ -53,7 +64,8 @@ endif ifeq ($(BACKEND),ps2) MODULE_OBJS += \ - fs/ps2/ps2-fs-factory.o + fs/ps2/ps2-fs-factory.o \ + plugins/ps2/ps2-provider.o endif ifeq ($(BACKEND),psp) @@ -67,7 +79,8 @@ endif ifeq ($(BACKEND),wii) MODULE_OBJS += \ - fs/wii/wii-fs-factory.o + fs/wii/wii-fs-factory.o \ + plugins/wii/wii-provider.o endif # Include common rules diff --git a/backends/mutex/mutex.h b/backends/mutex/mutex.h new file mode 100644 index 00000000000..d7143c8e90d --- /dev/null +++ b/backends/mutex/mutex.h @@ -0,0 +1,46 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_MUTEX_ABSTRACT_H +#define BACKENDS_MUTEX_ABSTRACT_H + +#include "common/system.h" +#include "common/noncopyable.h" + +/** + * Abstract class for mutex manager. Subclasses + * implement the real functionality. + */ +class MutexManager : Common::NonCopyable { +public: + virtual ~MutexManager() {} + + virtual OSystem::MutexRef createMutex() = 0; + virtual void lockMutex(OSystem::MutexRef mutex) = 0; + virtual void unlockMutex(OSystem::MutexRef mutex) = 0; + virtual void deleteMutex(OSystem::MutexRef mutex) = 0; +}; + +#endif diff --git a/backends/mutex/sdl/sdl-mutex.cpp b/backends/mutex/sdl/sdl-mutex.cpp new file mode 100644 index 00000000000..d2900842d69 --- /dev/null +++ b/backends/mutex/sdl/sdl-mutex.cpp @@ -0,0 +1,50 @@ +/* Residual - A 3D game interpreter + * + * 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 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/sys.h" + +#if defined(SDL_BACKEND) + +#include "backends/mutex/sdl/sdl-mutex.h" +#include "backends/platform/sdl/sdl-sys.h" + + +OSystem::MutexRef SdlMutexManager::createMutex() { + return (OSystem::MutexRef) SDL_CreateMutex(); +} + +void SdlMutexManager::lockMutex(OSystem::MutexRef mutex) { + SDL_mutexP((SDL_mutex *) mutex); +} + +void SdlMutexManager::unlockMutex(OSystem::MutexRef mutex) { + SDL_mutexV((SDL_mutex *) mutex); +} + +void SdlMutexManager::deleteMutex(OSystem::MutexRef mutex) { + SDL_DestroyMutex((SDL_mutex *) mutex); +} + +#endif diff --git a/backends/mutex/sdl/sdl-mutex.h b/backends/mutex/sdl/sdl-mutex.h new file mode 100644 index 00000000000..c38283c7797 --- /dev/null +++ b/backends/mutex/sdl/sdl-mutex.h @@ -0,0 +1,43 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKENDS_MUTEX_SDL_H +#define BACKENDS_MUTEX_SDL_H + +#include "backends/mutex/mutex.h" + +/** + * SDL mutex manager + */ +class SdlMutexManager : public MutexManager { +public: + virtual OSystem::MutexRef createMutex(); + virtual void lockMutex(OSystem::MutexRef mutex); + virtual void unlockMutex(OSystem::MutexRef mutex); + virtual void deleteMutex(OSystem::MutexRef mutex); +}; + + +#endif diff --git a/backends/platform/dc/Makefile b/backends/platform/dc/Makefile deleted file mode 100644 index ed1caed477d..00000000000 --- a/backends/platform/dc/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# $URL$ -# $Id$ - -ronindir = /usr/local/ronin - -srcdir = .. - -VPATH = $(srcdir) - -CXX = sh-elf-g++ -ml -m4-single-only -CXXFLAGS= -O3 -Wno-multichar -funroll-loops -fschedule-insns2 -fomit-frame-pointer -fdelete-null-pointer-checks -fno-exceptions -I$(srcdir)/lua -I$(srcdir) -I$(ronindir)/include -D__DC__ -LDFLAGS = -Wl,-Ttext,0x8c010000,-Map,$@.map -nostartfiles $(ronindir)/lib/crt0.o -LIBS = -L$(ronindir)/lib -lronin -lz -lm - - -DRIVER_OBJS = \ - driver_ronin.o \ - driver_ronin_gfx.o \ - driver_ronin_sound.o \ - driver_ronin_event.o \ - matrix_ops.o \ - texture_manager.o - - -include $(srcdir)/Makefile.common - - diff --git a/backends/platform/dc/driver_ronin.cpp b/backends/platform/dc/driver_ronin.cpp deleted file mode 100644 index f2a4a3e54cd..00000000000 --- a/backends/platform/dc/driver_ronin.cpp +++ /dev/null @@ -1,73 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 "debug.h" -#include "driver_ronin.h" - -#include -#include - - -DriverRonin::DriverRonin() -{ - //FIXME - reportf("%s\n", __func__); - - cdfs_init(); - - initEvent(); - initGfx(); - initSound(); -} - -DriverRonin::~DriverRonin() -{ - //FIXME - reportf("%s\n", __func__); -} - - -void DriverRonin::quit() -{ - //FIXME - reportf("%s\n", __func__); -} - -MutexRef DriverRonin::createMutex() { - return (MutexRef)NULL; -} - -void DriverRonin::lockMutex(MutexRef mutex) { - ; -} - -void DriverRonin::unlockMutex(MutexRef mutex) { - ; -} - -void DriverRonin::deleteMutex(MutexRef mutex) { - ; -} - diff --git a/backends/platform/dc/driver_ronin.h b/backends/platform/dc/driver_ronin.h deleted file mode 100644 index e2482e03884..00000000000 --- a/backends/platform/dc/driver_ronin.h +++ /dev/null @@ -1,182 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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$ - * - */ - -#ifndef DRIVER_RONIN_H -#define DRIVER_RONIN_H - -#include "bits.h" -#include "vector3d.h" -#include "color.h" -#include "model.h" -#include "colormap.h" -#include "bitmap.h" -#include "driver.h" -#include "matrix_ops.h" -#include "texture_manager.h" - -#include - -#define SOUND_BUFFER_SHIFT 3 - -class DriverRonin : public Driver, MatrixOps, TextureManager { -public: - DriverRonin(); - virtual ~DriverRonin(); - - void setupCamera(float fov, float nclip, float fclip, float roll); - void positionCamera(Vector3d pos, Vector3d interest); - - void toggleFullscreenMode(); - void clearScreen(); - void flipBuffer(); - - bool isHardwareAccelerated(); - - void startActorDraw(Vector3d pos, float yaw, float pitch, float roll); - void finishActorDraw(); - - void set3DMode(); - - void translateViewpoint(Vector3d pos, float pitch, float yaw, float roll); - void translateViewpoint(); - - void drawHierachyNode(const Model::HierNode *node); - void drawModelFace(const Model::Face *face, float *vertices, float *vertNormals, float *textureVerts); - - void disableLights(); - void setupLight(Scene::Light *light, int lightId); - - void createMaterial(Material *material, const char *data, const CMap *cmap); - void selectMaterial(const Material *material); - void destroyMaterial(Material *material); - - void createBitmap(Bitmap *bitmap); - void drawBitmap(const Bitmap *bitmap); - void destroyBitmap(Bitmap *bitmap); - - void drawDepthBitmap(int x, int y, int w, int h, char *data); - void drawBitmap(); - void dimScreen(); - void dimRegion(int x, int y, int w, int h, float level); - - Bitmap *getScreenshot(int w, int h); - void storeDisplay(); - void copyStoredToDisplay(); - - void drawEmergString(int x, int y, const char *text, const Color &fgColor); - void loadEmergFont(); - TextObjectHandle *createTextBitmap(uint8 *bitmap, int width, int height, const Color &fgColor); - void drawTextBitmap(int x, int y, TextObjectHandle *handle); - void destroyTextBitmap(TextObjectHandle *handle); - - void drawRectangle(PrimitiveObject *primitive); - void drawLine(PrimitiveObject *primitive); - - void prepareSmushFrame(int width, int height, byte *bitmap); - void drawSmushFrame(int offsetX, int offsetY); - - const char *getVideoDeviceName(); - - const ControlDescriptor *listControls(); - int getNumControls(); - bool controlIsAxis(int num); - float getControlAxis(int num); - bool getControlState(int num); - bool pollEvent(Event &event); - uint32 getMillis(); - void delayMillis(uint msecs); - void setTimerCallback(TimerProc callback, int interval); - - MutexRef createMutex(); - void lockMutex(MutexRef mutex); - void unlockMutex(MutexRef mutex); - void deleteMutex(MutexRef mutex); - - bool setSoundCallback(SoundProc proc, void *param); - void clearSoundCallback(); - int getOutputSampleRate() const; - - void quit(); - -private: - // Gfx - int _polyCount; - void *_smushTex; - float _u_scale, _v_scale; - // Event - int _devpoll; - uint32 _msecs; - unsigned int _t0; - uint32 _timer_duration, _timer_next_expiry; - bool _timer_active; - int (*_timer_callback) (int); - class JoyState { - public: - bool present; - unsigned short buttons; - unsigned char rtrigger; - unsigned char ltrigger; - unsigned char joyx; - unsigned char joyy; - unsigned char joyx2; - unsigned char joyy2; - } _joy1_state, _joy2_state; - class MouseState { - public: - bool present; - unsigned char buttons; - short axis1; - short axis2; - short axis3; - short axis4; - short axis5; - short axis6; - short axis7; - short axis8; - } _mouse_state; - class KeyboardState { - public: - bool present; - byte flags; - unsigned char shift; - unsigned char key[6]; - } _kbd_state; - // Sound - SoundProc _sound_proc; - void *_sound_proc_param; - int temp_sound_buffer[RING_BUFFER_SAMPLES>>SOUND_BUFFER_SHIFT]; - - void initEvent(); - void initGfx(); - void initSound(); - bool checkInput(struct mapledev *pad, Event &event); - bool checkJoystick(struct mapledev *pad, JoyState &state, int base, Event &event); - bool checkMouse(struct mapledev *pad, Event &event); - bool checkKeyboard(struct mapledev *pad, Event &event); - uint16 makeAscii(int keycode, int shift_state); - void checkSound(); -}; - -#endif diff --git a/backends/platform/dc/driver_ronin_event.cpp b/backends/platform/dc/driver_ronin_event.cpp deleted file mode 100644 index 0e8ffff16af..00000000000 --- a/backends/platform/dc/driver_ronin_event.cpp +++ /dev/null @@ -1,602 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 "debug.h" -#include "driver_ronin.h" - -#include -#include - -// Control allocation - -/* Controller: 16 buttons, 6 axises */ -/* Mouse: 8 buttons, 8 axises */ - -/* 0x02 - 0x9f Keyboard */ -/* 0xa0 - 0xb7 Controller 1 */ -/* 0xb8 - 0xcf Controller 2 */ -/* 0xd0 - 0xdf Mouse */ -/* 0xe0 - 0xe7 Shift keys */ - - -#define JOY1 0xa0 -#define JOY2 0xb8 -#define MOUSE 0xd0 - - -static const Driver::ControlDescriptor controls[] = { - { "KEY_ESCAPE", 0x29 }, - { "KEY_1", 0x1e }, - { "KEY_2", 0x1f }, - { "KEY_3", 0x20 }, - { "KEY_4", 0x21 }, - { "KEY_5", 0x22 }, - { "KEY_6", 0x23 }, - { "KEY_7", 0x24 }, - { "KEY_8", 0x25 }, - { "KEY_9", 0x26 }, - { "KEY_0", 0x27 }, - { "KEY_MINUS", 0x2d }, - { "KEY_EQUALS", 0x2e }, - { "KEY_BACK", 0x2a }, - { "KEY_TAB", 0x2b }, - { "KEY_Q", 0x14 }, - { "KEY_W", 0x1a }, - { "KEY_E", 0x08 }, - { "KEY_R", 0x15 }, - { "KEY_T", 0x17 }, - { "KEY_Y", 0x1c }, - { "KEY_U", 0x18 }, - { "KEY_I", 0x0c }, - { "KEY_O", 0x12 }, - { "KEY_P", 0x13 }, - { "KEY_LBRACKET", 0x2f }, - { "KEY_RBRACKET", 0x30 }, - { "KEY_RETURN", 0x28 }, - { "KEY_LCONTROL", 0xe0 }, - { "KEY_A", 0x04 }, - { "KEY_S", 0x16 }, - { "KEY_D", 0x07 }, - { "KEY_F", 0x09 }, - { "KEY_G", 0x0a }, - { "KEY_H", 0x0b }, - { "KEY_J", 0x0d }, - { "KEY_K", 0x0e }, - { "KEY_L", 0x0f }, - { "KEY_SEMICOLON", 0x33 }, - { "KEY_APOSTROPHE", 0x34 }, - { "KEY_GRAVE", 0x32 }, - { "KEY_LSHIFT", 0xe1 }, - { "KEY_BACKSLASH", 0x87 }, - { "KEY_Z", 0x1d }, - { "KEY_X", 0x1b }, - { "KEY_C", 0x06 }, - { "KEY_V", 0x19 }, - { "KEY_B", 0x05 }, - { "KEY_N", 0x11 }, - { "KEY_M", 0x10 }, - { "KEY_COMMA", 0x36 }, - { "KEY_PERIOD", 0x37 }, - { "KEY_SLASH", 0x38 }, - { "KEY_RSHIFT", 0xe5 }, - { "KEY_MULTIPLY", 0x55 }, - { "KEY_LMENU", 0xe2 }, - { "KEY_SPACE", 0x2c }, - { "KEY_CAPITAL", 0x39 }, - { "KEY_F1", 0x3a }, - { "KEY_F2", 0x3b }, - { "KEY_F3", 0x3c }, - { "KEY_F4", 0x3d }, - { "KEY_F5", 0x3e }, - { "KEY_F6", 0x3f }, - { "KEY_F7", 0x40 }, - { "KEY_F8", 0x41 }, - { "KEY_F9", 0x42 }, - { "KEY_F10", 0x43 }, - { "KEY_NUMLOCK", 0x53 }, - { "KEY_SCROLL", 0x47 }, - { "KEY_NUMPAD7", 0x5f }, - { "KEY_NUMPAD8", 0x60 }, - { "KEY_NUMPAD9", 0x61 }, - { "KEY_SUBTRACT", 0x56 }, - { "KEY_NUMPAD4", 0x5c }, - { "KEY_NUMPAD5", 0x5d }, - { "KEY_NUMPAD6", 0x5e }, - { "KEY_ADD", 0x57 }, - { "KEY_NUMPAD1", 0x59 }, - { "KEY_NUMPAD2", 0x5a }, - { "KEY_NUMPAD3", 0x5b }, - { "KEY_NUMPAD0", 0x62 }, - { "KEY_DECIMAL", 0x63 }, - { "KEY_F11", 0x44 }, - { "KEY_F12", 0x45 }, - { "KEY_STOP", 0x48 }, - { "KEY_NUMPADENTER", 0x58 }, - { "KEY_RCONTROL", 0xe4 }, - { "KEY_DIVIDE", 0x54 }, - { "KEY_SYSRQ", 0x46 }, - { "KEY_RMENU", 0xe6 }, - { "KEY_HOME", 0x4a }, - { "KEY_UP", 0x52 }, - { "KEY_PRIOR", 0x4b }, - { "KEY_LEFT", 0x50 }, - { "KEY_RIGHT", 0x4f }, - { "KEY_END", 0x4d }, - { "KEY_DOWN", 0x51 }, - { "KEY_NEXT", 0x4e }, - { "KEY_INSERT", 0x49 }, - { "KEY_DELETE", 0x4c }, - { "KEY_LWIN", 0xe3 }, - { "KEY_RWIN", 0xe7 }, - { "KEY_APPS", 0x65 }, - { "KEY_JOY1_B1", JOY1+0x02 }, - { "KEY_JOY1_B2", JOY1+0x01 }, - { "KEY_JOY1_B3", JOY1+0x00 }, - { "KEY_JOY1_B4", JOY1+0x0b }, - { "KEY_JOY1_B5", JOY1+0x0a }, - { "KEY_JOY1_B6", JOY1+0x09 }, - { "KEY_JOY1_B7", JOY1+0x08 }, - { "KEY_JOY1_B8", JOY1+0x03 }, - { "KEY_JOY1_B9", JOY1+0x0e }, - { "KEY_JOY1_B10", JOY1+0x0f }, - { "KEY_JOY1_HLEFT", JOY1+0x06 }, - { "KEY_JOY1_HUP", JOY1+0x04 }, - { "KEY_JOY1_HRIGHT", JOY1+0x07 }, - { "KEY_JOY1_HDOWN", JOY1+0x05 }, - { "KEY_JOY2_B1", JOY2+0x02 }, - { "KEY_JOY2_B2", JOY2+0x01 }, - { "KEY_JOY2_B3", JOY2+0x00 }, - { "KEY_JOY2_B4", JOY2+0x0b }, - { "KEY_JOY2_B5", JOY2+0x0a }, - { "KEY_JOY2_B6", JOY2+0x09 }, - { "KEY_JOY2_B7", JOY2+0x08 }, - { "KEY_JOY2_B8", JOY2+0x03 }, - { "KEY_JOY2_B9", JOY2+0x0e }, - { "KEY_JOY2_B10", JOY2+0x0f }, - { "KEY_JOY2_HLEFT", JOY2+0x06 }, - { "KEY_JOY2_HUP", JOY2+0x04 }, - { "KEY_JOY2_HRIGHT", JOY2+0x07 }, - { "KEY_JOY2_HDOWN", JOY2+0x05 }, - { "KEY_MOUSE_B1", MOUSE+0x02 }, - { "KEY_MOUSE_B2", MOUSE+0x01 }, - { "KEY_MOUSE_B3", MOUSE+0x00 }, - { "KEY_MOUSE_B4", MOUSE+0x03 }, - { "AXIS_JOY1_X", JOY1+0x12 }, - { "AXIS_JOY1_Y", JOY1+0x13 }, - { "AXIS_JOY1_Z", JOY1+0x10 }, - { "AXIS_JOY1_R", JOY1+0x11 }, - { "AXIS_JOY1_U", JOY1+0x14 }, - { "AXIS_JOY1_V", JOY1+0x15 }, - { "AXIS_JOY2_X", JOY2+0x12 }, - { "AXIS_JOY2_Y", JOY2+0x13 }, - { "AXIS_JOY2_Z", JOY2+0x10 }, - { "AXIS_JOY2_R", JOY2+0x11 }, - { "AXIS_JOY2_U", JOY2+0x14 }, - { "AXIS_JOY2_V", JOY2+0x15 }, - { "AXIS_MOUSE_X", MOUSE+0x08 }, - { "AXIS_MOUSE_Y", MOUSE+0x09 }, - { "AXIS_MOUSE_Z", MOUSE+0x0a }, - { NULL, 0 } -}; - -const Driver::ControlDescriptor *DriverRonin::listControls() -{ - return controls; -} - -int DriverRonin::getNumControls() -{ - return 0xe8; -} - -bool DriverRonin::controlIsAxis(int num) -{ - return (num >= JOY1+0x10 && num <= JOY1+0x15) || - (num >= JOY2+0x10 && num <= JOY2+0x15) || - (num >= MOUSE+0x08 && num <= MOUSE+0x0f); -} - -float DriverRonin::getControlAxis(int num) -{ - JoyState *state; - if(num >= MOUSE+0x08 && num <= MOUSE+0x0f) { - short *axis = &_mouse_state.axis1 + (num - MOUSE+0x08); - return *axis * 1.0/0x200; - } else if(num >= JOY1+0x10 && num <= JOY1+0x15) { - num -= JOY1+0x10; - state = &_joy1_state; - } else if(num >= JOY2+0x10 && num <= JOY2+0x15) { - num -= JOY2+0x10; - state = &_joy2_state; - } else - return 0; - - unsigned char *axis = &state->rtrigger + num; - if(num < 2) - // Triggers - return *axis * 1.0/256; - else - // Joystick X/Y - return *axis * 1.0/128 - 1.0; -} - -bool DriverRonin::getControlState(int num) -{ - if(num >= 2 && num <= 0x9f) { - for(int i=0; i<6; i++) - if(_kbd_state.key[i] == num) - return true; - } else if(num >= 0xe0 && num <= 0xe7) { - return (_kbd_state.shift & (1 << (num-0xe0))) != 0; - } else if(num >= JOY1 && num <= JOY1+0x0f) { - return (_joy1_state.buttons & (1 << (num-JOY1))) != 0; - } else if(num >= JOY2 && num <= JOY2+0x0f) { - return (_joy2_state.buttons & (1 << (num-JOY2))) != 0; - } else if(num >= MOUSE && num <= MOUSE+0x07) { - return (_mouse_state.buttons & (1 << (num-MOUSE))) != 0; - } - return false; -} - -uint16 DriverRonin::makeAscii(int keycode, int shift_state) -{ - if(keycode >= 0x04 && keycode <= 0x1d) { - uint16 ascii = keycode + ('a' - 0x04); - if(shift_state & KBD_SHIFT) - ascii -= ('a' - 'A'); - if(shift_state & KBD_CTRL) - ascii &= 0x1f; - return ascii; - } else if(keycode >= 0x1e && keycode <= 0x26) - return keycode + ((shift_state & KBD_SHIFT)? - ('!'-0x1e) : ('1'-0x1e)); - else if(keycode >= 0x59 && keycode <= 0x61) - return keycode + ('1'-0x59); - else if(keycode >= 0x2d && keycode <= 0x38 && keycode != 0x31) - return ((shift_state & KBD_SHIFT)? - "=¯`{ }+*½<>?" : - "-^@[ ];:§,./")[keycode - 0x2d]; - else if(keycode >= 0x54 && keycode <= 0x57) - return "/*-+"[keycode-0x54]; - else switch(keycode) { - case 0x27: - return ((shift_state & KBD_SHIFT)? '~' : '0'); - case 0x62: - return '0'; - case 0x28: case 0x58: - return 13; - case 0x29: - return 27; - case 0x2a: - return 8; - case 0x2b: - return 9; - case 0x2c: - return ' '; - case 0x4c: - return 127; - case 0x63: - return '.'; - case 0x64: case 0x87: - return ((shift_state & KBD_SHIFT)? '_' : '\\'); - case 0x89: - return ((shift_state & KBD_SHIFT)? '|' : '¥'); break; - } - - return 0; -} - -bool DriverRonin::checkJoystick(struct mapledev *pad, JoyState &state, int base, Event &event) -{ - if(!state.present) { - state.present = true; - state.buttons = 0; - } - - state.rtrigger = pad->cond.controller.rtrigger; - state.ltrigger = pad->cond.controller.ltrigger; - state.joyx = pad->cond.controller.joyx; - state.joyy = pad->cond.controller.joyy; - state.joyx2 = pad->cond.controller.joyx2; - state.joyy2 = pad->cond.controller.joyy2; - - unsigned short buttons = ~pad->cond.controller.buttons; - if(buttons != state.buttons) { - int up = state.buttons & ~buttons; - int down = buttons & ~state.buttons; - for(int i=0; i<8; i++) - if(up & (i<cond.mouse.axis1; - _mouse_state.axis2 = pad->cond.mouse.axis2; - _mouse_state.axis3 = pad->cond.mouse.axis3; - _mouse_state.axis4 = pad->cond.mouse.axis4; - _mouse_state.axis5 = pad->cond.mouse.axis5; - _mouse_state.axis6 = pad->cond.mouse.axis6; - _mouse_state.axis7 = pad->cond.mouse.axis7; - _mouse_state.axis8 = pad->cond.mouse.axis8; - - unsigned char buttons = (~pad->cond.mouse.buttons) & 0xff; - if(buttons != _mouse_state.buttons) { - int up = _mouse_state.buttons & ~buttons; - int down = buttons & ~_mouse_state.buttons; - for(int i=0; i<8; i++) - if(up & (i<cond.kbd.shift & 0x11) - _flags |= KBD_CTRL; - if(pad->cond.kbd.shift & 0x22) - _flags |= KBD_SHIFT; - if(pad->cond.kbd.shift & 0x44) - _flags |= KBD_ALT; - - if(!_kbd_state.present) { - _kbd_state.present = true; - _kbd_state.shift = 0; - memset(_kbd_state.key, 0, sizeof(_kbd_state.key)); - } - - _kbd_state.flags = _flags; - - if(pad->cond.kbd.shift != _kbd_state.shift) { - int up = _kbd_state.shift & ~pad->cond.kbd.shift; - int down = pad->cond.kbd.shift & ~_kbd_state.shift; - for(int i=0; i<8; i++) - if(up & (i<cond.kbd.shift; - } - - if(!memcmp(pad->cond.kbd.key, _kbd_state.key, sizeof(_kbd_state.key))) - return false; - - for(int i=5; i>=0; --i) { - unsigned char old_key = _kbd_state.key[i]; - if(old_key >= 2 && old_key <= 0x9f) { - int found = false; - for(int j=0; j<6; j++) - if(pad->cond.kbd.key[j] == old_key) { - found = true; - break; - } - if(!found) { - event.type = EVENT_KEYUP; - event.kbd.num = old_key; - event.kbd.ascii = makeAscii(old_key, _flags); - event.kbd.flags = _flags; -#ifdef KBD_DEBUG - printf("KEYUP %02x state=[", old_key); - for(int z=0; z<6; z++) - printf((z == i?"<%02x> ":"%02x "), _kbd_state.key[z]); - printf("] cond=["); - for(int z=0; z<6; z++) - printf("%02x ", pad->cond.kbd.key[z]); - printf("]\n"); -#endif - _kbd_state.key[i] = 0; - return true; - } - } - } - for(int i=0; i<6; i++) { - unsigned char new_key = pad->cond.kbd.key[i]; - if(new_key >= 2 && new_key <= 0x9f) { - int found = false; - int free_pos = -1; - for(int j=0; j<6; j++) - if(_kbd_state.key[j] == new_key) { - found = true; - break; - } else if(free_pos < 0 && - (_kbd_state.key[j] < 2 || - _kbd_state.key[j] > 0xa0)) - free_pos = j; - if(!found && free_pos >= 0) { - event.type = EVENT_KEYDOWN; - event.kbd.num = new_key; - event.kbd.ascii = makeAscii(new_key, _flags); - event.kbd.flags = _flags; -#ifdef KBD_DEBUG - printf("KEYDOWN %02x state=[", new_key); - for(int z=0; z<6; z++) - printf((z == free_pos?"{%02x} ":"%02x "), _kbd_state.key[z]); - printf("] cond=["); - for(int z=0; z<6; z++) - printf((z==i? "<%02x> ":"%02x "), pad->cond.kbd.key[z]); - printf("]\n"); -#endif - _kbd_state.key[free_pos] = new_key; - return true; - } - } - } - - memcpy(_kbd_state.key, pad->cond.kbd.key, sizeof(_kbd_state.key)); - return false; -} - -bool DriverRonin::checkInput(struct mapledev *pad, Event &event) -{ - int joyCnt=0, mouseCnt=0, kbdCnt=0; - for(int i=0; i<4; i++, pad++) - if((pad->func & MAPLE_FUNC_CONTROLLER) && - joyCnt < 2) { - if(checkJoystick(pad, (joyCnt? _joy2_state - : _joy1_state), - (joyCnt? JOY2 : JOY1), event)) - return true; - joyCnt++; - } else if((pad->func & MAPLE_FUNC_MOUSE) && - mouseCnt < 1) { - if(checkMouse(pad, event)) - return true; - mouseCnt++; - } else if((pad->func & MAPLE_FUNC_KEYBOARD) && - kbdCnt < 1) { - if(checkKeyboard(pad, event)) - return true; - kbdCnt++; - } - return false; -} - -bool DriverRonin::pollEvent(Event &event) -{ - unsigned int t = Timer(); - - if(_timer_active && ((int)(t-_timer_next_expiry))>=0) { - _timer_duration = _timer_callback(_timer_duration); - _timer_next_expiry = t+USEC_TO_TIMER(1000*_timer_duration); - } - - if(((int)(t-_devpoll))<0) - return false; - - _devpoll += USEC_TO_TIMER(17000); - if(((int)(t-_devpoll))>=0) - _devpoll = t + USEC_TO_TIMER(17000); - - getMillis(); - int mask = getimask(); - setimask(15); - checkSound(); - bool r = checkInput(locked_get_pads(), event); - setimask(mask); - return r; -} - -uint32 DriverRonin::getMillis() -{ - unsigned int t = Timer(); - unsigned int dm, dt = t - _t0; - - _t0 = t; - dm = (dt << 6)/3125U; - dt -= (dm * 3125U)>>6; - _t0 -= dt; - - return _msecs += dm; -} - -void DriverRonin::delayMillis(uint msecs) -{ - getMillis(); - unsigned int t, start = Timer(); - int time = (((unsigned int)msecs)*100000U)>>11; - while(((int)((t = Timer())-start))=0) { - _timer_duration = _timer_callback(_timer_duration); - _timer_next_expiry = t+USEC_TO_TIMER(1000*_timer_duration); - } - checkSound(); - } - getMillis(); -} - -void DriverRonin::setTimerCallback(TimerProc callback, int interval) -{ - if (callback != NULL) { - _timer_duration = interval; - _timer_next_expiry = Timer() + USEC_TO_TIMER(1000*interval); - _timer_callback = callback; - _timer_active = true; - } else { - _timer_active = false; - } -} - -void DriverRonin::initEvent() -{ - _devpoll = 0; - _msecs = 0; - _t0 = 0; - _timer_active = false; - maple_init(); - _joy1_state.present = false; - _joy2_state.present = false; - _mouse_state.present = false; - _kbd_state.present = false; - _kbd_state.flags = 0; -} diff --git a/backends/platform/dc/driver_ronin_gfx.cpp b/backends/platform/dc/driver_ronin_gfx.cpp deleted file mode 100644 index df8387ef82d..00000000000 --- a/backends/platform/dc/driver_ronin_gfx.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 "debug.h" -#include "colormap.h" -#include "material.h" -#include "driver_ronin.h" - -#include -#include -#include - -void DriverRonin::toggleFullscreenMode() -{ - //FIXME - reportf("%s\n", __func__); -} - -bool DriverRonin::isHardwareAccelerated() -{ - reportf("%s\n", __func__); - return true; -} - -void DriverRonin::setupCamera(float fov, float nclip, float fclip, float roll) -{ - //FIXME - //reportf("%s\n", __func__); - - clearMatrixStack(); - - float cot_fov = 1 / std::tan(fov * (LOCAL_PI / 180 / 2)); - float frustum[4][4] = { - { (-640/2) * cot_fov, 0, 0, 0 }, - { 0, (480/2 / 0.75) * cot_fov, 0, 0 }, - { 640/2, 480/2, (nclip + fclip) / (nclip - fclip), 1 }, - { 0, 0, 2*(nclip*fclip) / (nclip - fclip), 0 } - }; - loadMatrix(&frustum); - rotateZ( roll ); -} - -void DriverRonin::positionCamera(Vector3d pos, Vector3d interest) -{ - //FIXME - //reportf("%s\n", __func__); - float fx = interest.x() - pos.x(), - fy = interest.y() - pos.y(), - fz = interest.z() - pos.z(); - float n; - RROOT(fx*fx + fy*fy + fz*fz, n); - fx *= n; - fy *= n; - fz *= n; - float sx = 0, sy = 0, sz = 0; - if (fx == 0.0 && fy == 0.0) { - sx = -fz; - sz = fx; - } else { - sx = fy; - sy = -fx; - } - float m[4][4] = { - { sx, sy*fz-sz*fy, -fx, 0 }, - { sy, sz*fx-sx*fz, -fy, 0 }, - { sz, sx*fy-sy*fx, -fz, 0 }, - { 0, 0, 0, 1 } - }; - applyMatrix(&m); - translate(-pos.x(), -pos.y(), -pos.z()); -} - -void DriverRonin::clearScreen() -{ - struct polygon_list mypoly; - struct packed_colour_vertex_list myvertex; - - if(!_polyCount) - ta_begin_frame(); - - mypoly.cmd = - TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST| - TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR; - mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS/*|TA_POLYMODE1_NO_Z_UPDATE*/; - mypoly.mode2 = - TA_POLYMODE2_BLEND_SRC|TA_POLYMODE2_FOG_DISABLED; - mypoly.texture = 0; - - mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0; - - ta_commit_list(&mypoly); - - myvertex.cmd = TA_CMD_VERTEX; - myvertex.ocolour = 0; - myvertex.colour = 0xff00ff; - myvertex.z = 0.01; - myvertex.u = 0.0; - myvertex.v = 0.0; - - myvertex.x = 0; - myvertex.y = 0; - ta_commit_list(&myvertex); - - myvertex.x = 640; - ta_commit_list(&myvertex); - - myvertex.x = 0; - myvertex.y = 480; - ta_commit_list(&myvertex); - - myvertex.x = 640; - myvertex.cmd |= TA_CMD_VERTEX_EOS; - ta_commit_list(&myvertex); - - _polyCount++; - - //FIXME - // reportf("%s\n", __func__); -} - -void commit_dummy_transpoly() -{ - struct polygon_list mypoly; - - mypoly.cmd = - TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_TRANSPARENT|TA_CMD_POLYGON_SUBLIST| - TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR; - mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE; - mypoly.mode2 = - TA_POLYMODE2_BLEND_SRC_ALPHA|TA_POLYMODE2_BLEND_DST_INVALPHA| - TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_ENABLE_ALPHA; - mypoly.texture = 0; - mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0; - ta_commit_list(&mypoly); -} - -void DriverRonin::flipBuffer() -{ - if(_polyCount) { - ta_commit_end(); - commit_dummy_transpoly(); - ta_commit_frame(); - _polyCount = 0; - } -} - -void DriverRonin::startActorDraw(Vector3d pos, float yaw, float pitch, float roll) -{ - //FIXME - //reportf("%s\n", __func__); - translateViewpoint(pos, pitch, yaw, roll); -} - -void DriverRonin::finishActorDraw() -{ - //FIXME - //reportf("%s\n", __func__); - translateViewpoint(); -} - -void DriverRonin::set3DMode() -{ - //FIXME - //reportf("%s\n", __func__); -} - -void DriverRonin::translateViewpoint(Vector3d pos, float pitch, float yaw, float roll) -{ - //FIXME - //reportf("%s\n", __func__); - pushMatrix(); - translate(pos.x(), pos.y(), pos.z()); - rotateZ( -yaw ); - rotateX( -pitch ); - rotateY( -roll ); -} - -void DriverRonin::translateViewpoint() -{ - //FIXME - //reportf("%s\n", __func__); - popMatrix(); -} - -void DriverRonin::drawHierachyNode(const Model::HierNode *node) -{ - //FIXME - //reportf("%s\n", __func__); - translateViewpoint(node->_animPos / node->_totalWeight, node->_animPitch / node->_totalWeight, node->_animYaw / node->_totalWeight, node->_animRoll / node->_totalWeight); - if (node->_hierVisible) { - if (node->_mesh != NULL && node->_meshVisible) { - pushMatrix(); - translate(node->_pivot.x(), node->_pivot.y(), node->_pivot.z()); - node->_mesh->draw(); - popMatrix(); - } - - if (node->_child != NULL) { - node->_child->draw(); - } - } - translateViewpoint(); - - if (node->_sibling != NULL) - node->_sibling->draw(); -} - -void DriverRonin::drawModelFace(const Model::Face *face, float *vertices, float *vertNormals, float *textureVerts) -{ - //FIXME - //reportf("%s\n", __func__); - - struct packed_colour_vertex_list myvertex; - - myvertex.cmd = TA_CMD_VERTEX; - myvertex.ocolour = 0; - myvertex.colour = 0x00ff00; - myvertex.u = 0.0; - myvertex.v = 0.0; - - for (int i = 0; i < face->_numVertices; ) { - int j = i&1? i>>1 : face->_numVertices-1-(i>>1); - float *v = vertices + 3*face->_vertices[j]; - - if(face->_texVertices != NULL) { - float *t = textureVerts + 2*face->_texVertices[j]; - myvertex.u = t[0] * _u_scale; - myvertex.v = t[1] * _v_scale; - //printf("%f %f\n", myvertex.u, myvertex.v); - } - - if(++i == face->_numVertices) - myvertex.cmd |= TA_CMD_VERTEX_EOS; - - ta_commit_vertex(&myvertex, v[0], v[1], v[2]); - } -} - -void DriverRonin::disableLights() -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::setupLight(Scene::Light *light, int lightId) -{ - //FIXME - //reportf("%s\n", __func__); -} - -void DriverRonin::createMaterial(Material *material, const char *data, const CMap *cmap) -{ - //FIXME - reportf("%s\n", __func__); - reportf("%d x %d x %d\n", material->_width, material->_height, material->_numImages); - if(data != NULL && material->_numImages > 0) { - Texture *tex = allocateTexture(material->_width, material->_height, material->_numImages); - material->_textures = tex; - for(int i=0; i_numImages; i++) { - tex->setTexture(i, (const uint8 *)data, cmap); - data += material->_width * material->_height + 24; - } - } else { - material->_textures = 0; - } -} - -void DriverRonin::selectMaterial(const Material *material) -{ - //FIXME - //reportf("%s\n", __func__); - struct polygon_list mypoly; - - if(!_polyCount) - ta_begin_frame(); - - if(material->_textures) { - mypoly.cmd = - TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST| - TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR| - TA_CMD_POLYGON_TEXTURED|TA_CMD_POLYGON_GOURAUD_SHADING; - mypoly.mode1 = TA_POLYMODE1_Z_GREATEREQUAL; //TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE; - ((Texture *)material->_textures)->setup(material->_currImage, mypoly, _u_scale, _v_scale); - } else { - - // reportf("%d x %d x %d\n", material->_width, material->_height, material->_numImages); - - mypoly.cmd = - TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST| - TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR| - TA_CMD_POLYGON_GOURAUD_SHADING; - mypoly.mode1 = TA_POLYMODE1_Z_GREATEREQUAL; //TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE; - mypoly.mode2 = - TA_POLYMODE2_BLEND_SRC|TA_POLYMODE2_FOG_DISABLED; - mypoly.texture = 0; - } - - mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0; - - ta_commit_list(&mypoly); - - _polyCount++; -} - -void DriverRonin::destroyMaterial(Material *material) -{ - //FIXME - reportf("%s\n", __func__); - if(material->_textures) - freeTexture((Texture *)material->_textures); -} - -#define QACR0 (*(volatile unsigned int *)(void *)0xff000038) -#define QACR1 (*(volatile unsigned int *)(void *)0xff00003c) -#define SQ_WAIT_STORE_QUEUES() do { unsigned int *d = (unsigned int *)0xe0000000; d[0] = d[8] = 0; } while(0) -static void texture_memcpy64(void *dest, void *src, int cnt) -{ - unsigned int *s = (unsigned int *)src; - unsigned int *d = (unsigned int *)(void *) - (0xe0000000 | (((unsigned long)dest) & 0x03ffffc0)); - unsigned int old_qacr0 = QACR0; - unsigned int old_qacr1 = QACR1; - SQ_WAIT_STORE_QUEUES(); - QACR0 = ((0xa4000000>>26)<<2)&0x1c; - QACR1 = ((0xa4000000>>26)<<2)&0x1c; - while(cnt--) { - d[0] = *s++; - d[1] = *s++; - d[2] = *s++; - d[3] = *s++; - asm("pref @%0" : : "r" (s+16)); - d[4] = *s++; - d[5] = *s++; - d[6] = *s++; - d[7] = *s++; - asm("pref @%0" : : "r" (d)); - d += 8; - d[0] = *s++; - d[1] = *s++; - d[2] = *s++; - d[3] = *s++; - asm("pref @%0" : : "r" (s+16)); - d[4] = *s++; - d[5] = *s++; - d[6] = *s++; - d[7] = *s++; - asm("pref @%0" : : "r" (d)); - d += 8; - } - SQ_WAIT_STORE_QUEUES(); - QACR0 = old_qacr0; - QACR1 = old_qacr1; -} - -void DriverRonin::createBitmap(Bitmap *bitmap) -{ - static int x = 0; - - //FIXME - reportf("%s %p\n", __func__, bitmap); - - printf("format = %d, numImages = %d, w x h = %d x %d\n", - bitmap->_format, bitmap->_numImages, - bitmap->_width, bitmap->_height); - bitmap->_texIds = NULL; - if(bitmap->_format == 1 && ++x <= 3) { - bitmap->_texIds = ta_txalloc(bitmap->_width * bitmap->_height * 2); - texture_memcpy64(bitmap->_texIds, bitmap->_data[0], - (bitmap->_height*bitmap->_width)>>5); - } - if(true) { - for(int i=0; i_numImages; i++) { - delete[] bitmap->_data[i]; - } - delete[] bitmap->_data; - bitmap->_data = NULL; - } -} - -void DriverRonin::drawBitmap(const Bitmap *bitmap) -{ - struct polygon_list mypoly; - struct packed_colour_vertex_list myvertex; - - if(bitmap->_format != 1 || !bitmap->_texIds) - return; - - if(!_polyCount) - ta_begin_frame(); - - mypoly.cmd = - TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST| - TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|TA_CMD_POLYGON_TEXTURED; - mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS/*|TA_POLYMODE1_NO_Z_UPDATE*/; - mypoly.mode2 = - TA_POLYMODE2_BLEND_SRC|TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_TEXTURE_REPLACE| - TA_POLYMODE2_U_SIZE_1024|TA_POLYMODE2_V_SIZE_1024; - mypoly.texture = TA_TEXTUREMODE_RGB565|TA_TEXTUREMODE_NON_TWIDDLED| - TA_TEXTUREMODE_STRIDE|TA_TEXTUREMODE_ADDRESS(bitmap->_texIds); - - mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0; - - ta_commit_list(&mypoly); - - myvertex.cmd = TA_CMD_VERTEX; - myvertex.ocolour = 0; - myvertex.colour = 0; - myvertex.z = 0.01; - myvertex.u = 0.0; - myvertex.v = 0.0; - - myvertex.x = bitmap->_x; - myvertex.y = bitmap->_y; - ta_commit_list(&myvertex); - - myvertex.x += bitmap->_width; - myvertex.u = bitmap->_width*(1/1024.0); - ta_commit_list(&myvertex); - - myvertex.x = bitmap->_x; - myvertex.y += bitmap->_height; - myvertex.u = 0.0; - myvertex.v = bitmap->_height*(1/1024.0); - ta_commit_list(&myvertex); - - myvertex.x += bitmap->_width; - myvertex.u = bitmap->_width*(1/1024.0); - myvertex.cmd |= TA_CMD_VERTEX_EOS; - ta_commit_list(&myvertex); - - _polyCount++; - - //FIXME - //reportf("%s %p\n", __func__, bitmap); -} - -void DriverRonin::destroyBitmap(Bitmap *bitmap) -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::drawDepthBitmap(int x, int y, int w, int h, char *data) -{ - //FIXME - reportf("%s\n", __func__); -} - -Bitmap *DriverRonin::getScreenshot(int w, int h) -{ - //FIXME - reportf("%s\n", __func__); - return NULL; -} - -void DriverRonin::storeDisplay() -{ - //FIXME - //reportf("%s\n", __func__); -} - -void DriverRonin::copyStoredToDisplay() -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::dimScreen() -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::dimRegion(int x, int y, int w, int h, float level) -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::drawEmergString(int x, int y, const char *text, const Color &fgColor) -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::loadEmergFont() -{ - //FIXME - reportf("%s\n", __func__); -} - -Driver::TextObjectHandle *DriverRonin::createTextBitmap(uint8 *bitmap, int width, int height, const Color &fgColor) -{ - //FIXME - reportf("%s\n", __func__); - return new TextObjectHandle; -} - -void DriverRonin::drawTextBitmap(int x, int y, TextObjectHandle *handle) -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::destroyTextBitmap(TextObjectHandle *handle) -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::drawRectangle(PrimitiveObject *primitive) -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::drawLine(PrimitiveObject *primitive) -{ - //FIXME - reportf("%s\n", __func__); -} - -void DriverRonin::prepareSmushFrame(int width, int height, byte *bitmap) -{ - //FIXME - //reportf("%s(%d,%d,%p)\n", __func__, width, height, bitmap); - assert(width == 640 && height == 480); - texture_memcpy64(_smushTex, bitmap, (640*480)>>5); -} - -void DriverRonin::drawSmushFrame(int offsetX, int offsetY) -{ - //FIXME - // reportf("%s(%d,%d)\n", __func__, offsetX, offsetY); - - struct polygon_list mypoly; - struct packed_colour_vertex_list myvertex; - - if(!_polyCount) - ta_begin_frame(); - - mypoly.cmd = - TA_CMD_POLYGON|TA_CMD_POLYGON_TYPE_OPAQUE|TA_CMD_POLYGON_SUBLIST| - TA_CMD_POLYGON_STRIPLENGTH_2|TA_CMD_POLYGON_PACKED_COLOUR|TA_CMD_POLYGON_TEXTURED; - mypoly.mode1 = TA_POLYMODE1_Z_ALWAYS|TA_POLYMODE1_NO_Z_UPDATE; - mypoly.mode2 = - TA_POLYMODE2_BLEND_SRC|TA_POLYMODE2_FOG_DISABLED|TA_POLYMODE2_TEXTURE_REPLACE| - TA_POLYMODE2_U_SIZE_1024|TA_POLYMODE2_V_SIZE_1024; - mypoly.texture = TA_TEXTUREMODE_RGB565|TA_TEXTUREMODE_NON_TWIDDLED| - TA_TEXTUREMODE_STRIDE|TA_TEXTUREMODE_ADDRESS(_smushTex); - - mypoly.red = mypoly.green = mypoly.blue = mypoly.alpha = 0; - - ta_commit_list(&mypoly); - - myvertex.cmd = TA_CMD_VERTEX; - myvertex.ocolour = 0; - myvertex.colour = 0; - myvertex.z = 0.01; - myvertex.u = 0.0; - myvertex.v = 0.0; - - myvertex.x = offsetX; - myvertex.y = offsetY; - ta_commit_list(&myvertex); - - myvertex.x += 640; - myvertex.u = 640*(1/1024.0); - ta_commit_list(&myvertex); - - myvertex.x = offsetX; - myvertex.y += 480; - myvertex.u = 0.0; - myvertex.v = 480*(1/1024.0); - ta_commit_list(&myvertex); - - myvertex.x += 640; - myvertex.u = 640*(1/1024.0); - myvertex.cmd |= TA_CMD_VERTEX_EOS; - ta_commit_list(&myvertex); - - _polyCount++; -} - -const char *DriverRonin::getVideoDeviceName() -{ - return "Dreamcast PowerVR Video Device"; -} - -void DriverRonin::initGfx() -{ - _polyCount = 0; - dc_setup_ta(); - initTextures(); - *(volatile unsigned int *)(0xa05f80e4) = 640/32; //stride - - _smushTex = ta_txalloc(640 * 480 * 2); -} diff --git a/backends/platform/dc/driver_ronin_sound.cpp b/backends/platform/dc/driver_ronin_sound.cpp deleted file mode 100644 index 35a1fbc9930..00000000000 --- a/backends/platform/dc/driver_ronin_sound.cpp +++ /dev/null @@ -1,106 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 "debug.h" -#include "driver_ronin.h" - -#include -#include - -EXTERN_C void *memcpy4s(void *s1, const void *s2, unsigned int n); - -bool DriverRonin::setSoundCallback(SoundProc proc, void *param) -{ - assert(SAMPLE_MODE == 0); - - _sound_proc_param = param; - _sound_proc = proc; - - return true; -} - -void DriverRonin::clearSoundCallback() -{ - _sound_proc = NULL; - _sound_proc_param = NULL; - stop_sound(); -} - -int DriverRonin::getOutputSampleRate() const -{ - //FIXME - /// XXX reportf("%s\n", __func__); - return read_sound_int(&SOUNDSTATUS->freq); -} - -void DriverRonin::checkSound() -{ - int n; - int curr_ring_buffer_samples; - - if(!_sound_proc) - return; - - if(read_sound_int(&SOUNDSTATUS->mode) != MODE_PLAY) - start_sound(); - - curr_ring_buffer_samples = read_sound_int(&SOUNDSTATUS->ring_length); - - n = read_sound_int(&SOUNDSTATUS->samplepos); - - if((n-=fillpos)<0) - n += curr_ring_buffer_samples; - - n = ADJUST_BUFFER_SIZE(n-10); - - if(n<100) - return; - - _sound_proc(_sound_proc_param, (byte*)temp_sound_buffer, - 2*SAMPLES_TO_BYTES(n)); - - if(fillpos+n > curr_ring_buffer_samples) { - int r = curr_ring_buffer_samples - fillpos; - memcpy4s(RING_BUF+fillpos, temp_sound_buffer, SAMPLES_TO_BYTES(r)); - fillpos = 0; - n -= r; - memcpy4s(RING_BUF, temp_sound_buffer+r, SAMPLES_TO_BYTES(n)); - } else { - memcpy4s(RING_BUF+fillpos, temp_sound_buffer, SAMPLES_TO_BYTES(n)); - } - if((fillpos += n) >= curr_ring_buffer_samples) - fillpos = 0; -} - -void DriverRonin::initSound() -{ - _sound_proc = NULL; - - init_arm(); - stop_sound(); - do_sound_command(CMD_SET_FREQ_EXP(FREQ_22050_EXP)); - do_sound_command(CMD_SET_STEREO(1)); - do_sound_command(CMD_SET_BUFFER(SOUND_BUFFER_SHIFT)); -} diff --git a/backends/platform/dc/main.cpp b/backends/platform/dc/main.cpp deleted file mode 100644 index 888c71bd683..00000000000 --- a/backends/platform/dc/main.cpp +++ /dev/null @@ -1,192 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 "stdafx.h" -#include "debug.h" -#include "bitmap.h" -#include "resource.h" -#include "lua.h" -#include "registry.h" -#include "localize.h" -#include "engine.h" -#include "timer.h" -#include "smush.h" -#include "driver_ronin.h" - -#include "mixer/mixer.h" - -#include "imuse/imuse.h" - -#define Timer RoninTimer - -#include -#include - -#undef Timer - -// Hacky global toggles for experimental/debug code -bool ZBUFFER_GLOBAL, SHOWFPS_GLOBAL, TINYGL_GLOBAL; -enDebugLevels debugLevel = DEBUG_NONE; - -static bool g_lua_initialized = false; -Driver *g_driver = NULL; - -void quit(); - -int main() { - int i; - -#ifndef NOSERIAL - serial_init(57600); - usleep(2000000); - printf("Serial OK\r\n"); -#endif - - atexit(quit); - - g_registry = new Registry(); - g_registry->set("DataDir", "/GRIMDATA"); - g_registry->set("good_times", "TRUE"); - - g_driver = new DriverRonin(); - g_engine = new Engine(); - g_resourceloader = new ResourceLoader(); - g_localizer = new Localizer(); - g_mixer = new SoundMixer(); - g_mixer->setVolume(255); - g_timer = new Timer(); - g_smush = new Smush(); - g_imuse = new Imuse(20); - - Bitmap *splash_bm = NULL; - splash_bm = g_resourceloader->loadBitmap("splash.bm"); - splash_bm->ref(); - - g_driver->clearScreen(); - splash_bm->draw(); - g_driver->flipBuffer(); - - splash_bm->deref(); - - lua_iolibopen(); - lua_strlibopen(); - lua_mathlibopen(); - - register_lua(); - g_lua_initialized = true; - - bundle_dofile("_system.lua"); - - lua_pushnil(); // resumeSave - lua_pushnil(); // bootParam -// lua_pushnumber(0); // bootParam - lua_call("BOOT"); - - g_engine->setMode(ENGINE_MODE_NORMAL); - g_engine->mainLoop(); - - quit(); - - return 0; -} - -void quit() { - if (g_lua_initialized) { - lua_removelibslists(); - lua_close(); - g_lua_initialized = false; - } - if (g_registry) { - g_registry->save(); - delete g_registry; - g_registry = NULL; - } - if (g_smush) { - delete g_smush; - g_smush = NULL; - } - if (g_imuse) { - delete g_imuse; - g_imuse = NULL; - } - if (g_localizer) { - delete g_localizer; - g_localizer = NULL; - } - if (g_engine) { - delete g_engine; - g_engine = NULL; - } - if (g_resourceloader) { - delete g_resourceloader; - g_resourceloader = NULL; - } - if (g_timer) { - delete g_timer; - g_timer = NULL; - } - if (g_mixer) { - delete g_mixer; - g_mixer = NULL; - } - if (g_driver) { - delete g_driver; - g_driver = NULL; - } - - report("Exiting to IP slave...\n"); - ((void (*)())0x8cf00000)(); -} - -int system(const char *command) -{ - return -1; -} - -int remove(const char *pathname) -{ - return -1; -} - -int unlink(const char *pathname) -{ - return -1; -} - -int rename(const char *oldpath, const char *newpath) -{ - return -1; -} - -char *tmpnam(char *s) -{ - return NULL; -} - -clock_t clock(void) -{ - return 0; -} - diff --git a/backends/platform/dc/matrix_ops.cpp b/backends/platform/dc/matrix_ops.cpp deleted file mode 100644 index 93a94fb6443..00000000000 --- a/backends/platform/dc/matrix_ops.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 "matrix_ops.h" - -#include -#include -#include -#include - -#define DEG(X) ((int)(X*(65536.0/360.0))) - -void MatrixOps::pushMatrix() -{ - assert(_matrix_depth < MAX_MATRIX_STACK_DEPTH); - save_matrix(&_matrix_stack[_matrix_depth++]); -} - -void MatrixOps::popMatrix() -{ - assert(_matrix_depth > 0); - load_matrix(&_matrix_stack[--_matrix_depth]); -} - -void MatrixOps::translate(float x, float y, float z) -{ - static float matrix[4][4] = { - { 1.0, 0.0, 0.0, 0.0 }, - { 0.0, 1.0, 0.0, 0.0 }, - { 0.0, 0.0, 1.0, 0.0 }, - { 0.0, 0.0, 0.0, 1.0 }, - }; - matrix[3][0] = x; - matrix[3][1] = y; - matrix[3][2] = z; - apply_matrix(&matrix); -} - -void MatrixOps::rotateX(float deg) -{ - static float matrix[4][4] = { - { 1.0, 0.0, 0.0, 0.0 }, - { 0.0, 1.0, 0.0, 0.0 }, - { 0.0, 0.0, 1.0, 0.0 }, - { 0.0, 0.0, 0.0, 1.0 }, - }; - float s, c; - SINCOS(DEG(deg), s, c); - matrix[1][1] = matrix[2][2] = c; - matrix[1][2] = -(matrix[2][1] = s); - apply_matrix(&matrix); -} - -void MatrixOps::rotateY(float deg) -{ - static float matrix[4][4] = { - { 1.0, 0.0, 0.0, 0.0 }, - { 0.0, 1.0, 0.0, 0.0 }, - { 0.0, 0.0, 1.0, 0.0 }, - { 0.0, 0.0, 0.0, 1.0 }, - }; - float s, c; - SINCOS(DEG(deg), s, c); - matrix[0][0] = matrix[2][2] = c; - matrix[2][0] = -(matrix[0][2] = s); - apply_matrix(&matrix); -} - -void MatrixOps::rotateZ(float deg) -{ - static float matrix[4][4] = { - { 1.0, 0.0, 0.0, 0.0 }, - { 0.0, 1.0, 0.0, 0.0 }, - { 0.0, 0.0, 1.0, 0.0 }, - { 0.0, 0.0, 0.0, 1.0 }, - }; - float s, c; - SINCOS(DEG(deg), s, c); - matrix[0][0] = matrix[1][1] = c; - matrix[0][1] = -(matrix[1][0] = s); - apply_matrix(&matrix); -} - diff --git a/backends/platform/dc/matrix_ops.h b/backends/platform/dc/matrix_ops.h deleted file mode 100644 index 885d731cdb3..00000000000 --- a/backends/platform/dc/matrix_ops.h +++ /dev/null @@ -1,50 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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$ - * - */ - -#ifndef MATRIX_OPS_H -#define MATRIX_OPS_H - -#include - -#define MAX_MATRIX_STACK_DEPTH 16 - -class MatrixOps { - private: - int _matrix_depth; - float _matrix_stack[MAX_MATRIX_STACK_DEPTH][4][4]; - - public: - void clearMatrixStack() { _matrix_depth = 0; } - void loadMatrix(float (*m)[4][4]) { load_matrix(m); } - void applyMatrix(float (*m)[4][4]) { apply_matrix(m); } - void pushMatrix(); - void popMatrix(); - void translate(float x, float y, float z); - void rotateX(float deg); - void rotateY(float deg); - void rotateZ(float deg); -}; - -#endif diff --git a/backends/platform/dc/texture_manager.cpp b/backends/platform/dc/texture_manager.cpp deleted file mode 100644 index 8ca733d2bdd..00000000000 --- a/backends/platform/dc/texture_manager.cpp +++ /dev/null @@ -1,232 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 "debug.h" -#include "colormap.h" -#include "material.h" -#include "texture_manager.h" - -static int twiddletab[1024]; - -static void init_twiddletab() -{ - int x; - for(x=0; x<1024; x++) - twiddletab[x] = (x&1)|((x&2)<<1)|((x&4)<<2)|((x&8)<<3)|((x&16)<<4)| - ((x&32)<<5)|((x&64)<<6)|((x&128)<<7)|((x&256)<<8)|((x&512)<<9); -} - -TextureManager::Texture::Texture(uint16 *tex, unsigned int fsz, int width, int height, int cnt) - : _data(tex), _width(width), _height(height), _cnt(cnt), _framesize(fsz) -{ - _texture = TA_TEXTUREMODE_ARGB1555|TA_TEXTUREMODE_ADDRESS(_data); - _mode2 = TA_POLYMODE2_BLEND_SRC|TA_POLYMODE2_FOG_DISABLED| - TA_POLYMODE2_TEXTURE_REPLACE|TA_POLYMODE2_BILINEAR_FILTER; - - switch(_width) { - case 4: - /* XXX */ - case 8: - _mode2 |= TA_POLYMODE2_U_SIZE_8; - _uscale = 1.0/8; - break; - case 16: - _mode2 |= TA_POLYMODE2_U_SIZE_16; - _uscale = 1.0/16; - break; - case 32: - _mode2 |= TA_POLYMODE2_U_SIZE_32; - _uscale = 1.0/32; - break; - case 64: - _mode2 |= TA_POLYMODE2_U_SIZE_64; - _uscale = 1.0/64; - break; - case 128: - _mode2 |= TA_POLYMODE2_U_SIZE_128; - _uscale = 1.0/128; - break; - case 256: - _mode2 |= TA_POLYMODE2_U_SIZE_256; - _uscale = 1.0/256; - break; - default: - assert(0); - break; - } - switch(_height) { - case 4: - /* XXX */ - case 8: - _mode2 |= TA_POLYMODE2_V_SIZE_8; - _vscale = 1.0/8; - break; - case 16: - _mode2 |= TA_POLYMODE2_V_SIZE_16; - _vscale = 1.0/16; - break; - case 32: - _mode2 |= TA_POLYMODE2_V_SIZE_32; - _vscale = 1.0/32; - break; - case 64: - _mode2 |= TA_POLYMODE2_V_SIZE_64; - _vscale = 1.0/64; - break; - case 128: - _mode2 |= TA_POLYMODE2_V_SIZE_128; - _vscale = 1.0/128; - break; - case 256: - _mode2 |= TA_POLYMODE2_V_SIZE_256; - _vscale = 1.0/256; - break; - default: - assert(0); - break; - } - assert((_width > 4 && _height > 4) || (_width == 4 && _height == 4)); -} - -void TextureManager::Texture:: -setTextureTwiddled(uint16 *tex, const uint8 *data, - const CMap *cmap, int sz, int extra) -{ - for(int y=0; y_colors+3*n; - t = 0x8000 | - ((c[0]<<7)&0x7c00)| - ((c[1]<<2)&0x03e0)| - ((c[2]>>3)&0x001f); - } - *(uint16*)(((twiddletab[x]<<2)|(twiddletab[y]<<1)) - + (char *)tex) = t; - } -} - -void TextureManager::Texture::setTexture(int n, const uint8 *data, const CMap *cmap) -{ - uint16 *tex = (uint16 *)(n * _framesize + (char *)_data); - - if(_width == _height) - setTextureTwiddled(tex, data, cmap, _width); - else if(_width > _height) { - const uint8 *d2 = data; - uint16 *t2 = tex; - unsigned int fsz = _height * _height * 2; - for(int x = 0; x < _width; x += _height) { - setTextureTwiddled(t2, d2, cmap, _height, _width - _height); - d2 += _height; - t2 += _height * _height; - } - } else { - const uint8 *d2 = data; - uint16 *t2 = tex; - for(int x = 0; x < _height; x += _width) { - setTextureTwiddled(t2, d2, cmap, _width); - d2 += _width * _width; - t2 += _width * _width; - } - } -} - -TextureManager::Texture *TextureManager::allocateTexture(int width, int height, int cnt) -{ - unsigned int framesize = width * height * 2; - uint16 *tex = (uint16 *) allocateTexMem(framesize * cnt); - return new Texture(tex, framesize, width, height, cnt); -} - -void TextureManager::freeTexture(Texture *t) -{ - freeTexMem(t->getMemory(), t->getFrameSize()*t->getCnt()); - delete t; -} - -void *TextureManager::allocateTexMem(unsigned int size) -{ - assert(size > 0 && !(size&7)); - // First fit - FreeListNode *n, **link; - for(link = &_freeListHead; (n = *link) != NULL; link = &n->next) - if(n->size >= size) - break; - assert(n != NULL); - if(n->size > size) { - FreeListNode *n2 = (FreeListNode *)(size + (char *)n); - n2->size = n->size - size; - n2->next = n->next; - *link = n2; - } else { - *link = n->next; - } - return (void *)n; -} - -void TextureManager::freeTexMem(void *mem, unsigned int size) -{ - assert(size > 0 && !(size&7) && mem != NULL); - - FreeListNode *n, **link; - for(link = &_freeListHead; (n = *link) != NULL; link = &n->next) - if(mem == (n->size + (char *)n)) - break; - else if(mem < n) { - n = NULL; - break; - } else - assert(mem > (n->size + (char *)n)); - if(n == NULL) { - n = (FreeListNode *)mem; - n->size = size; - n->next = *link; - *link = n; - } else { - n->size += size; - } - - // Join this block with the next one if possible - if((char *)n->next == n->size + (char *)n) { - n->size += n->next->size; - n->next = n->next->next; - } - - assert(n->next == NULL || (char *)n->next > n->size + (char *)n); -} - -void TextureManager::initTextures() -{ - unsigned int aperture = 0x180000; - _freeListHead = (FreeListNode *)ta_txalloc(aperture); - _freeListHead->next = NULL; - _freeListHead->size = aperture; - init_twiddletab(); -} diff --git a/backends/platform/dc/texture_manager.h b/backends/platform/dc/texture_manager.h deleted file mode 100644 index c4972b5de88..00000000000 --- a/backends/platform/dc/texture_manager.h +++ /dev/null @@ -1,75 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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$ - * - */ - -#ifndef TEXTURE_MANAGER_H -#define TEXTURE_MANAGER_H - -#include "bits.h" -#include "colormap.h" - -#include - -class TextureManager { - public: - class Texture { - public: - Texture(uint16 *tex, unsigned int fsz, int width, int height, int cnt); - void setTexture(int n, const uint8 *data, const CMap *cmap); - void setup(int n, struct polygon_list &list, float &uscale, float &vscale) { - list.mode2 = _mode2; - list.texture = _texture + TA_TEXTUREMODE_ADDRESS(n*_framesize); - uscale = _uscale; - vscale = _vscale; - } - uint16 *getMemory() const { return _data; } - unsigned int getFrameSize() const { return _framesize; } - uint16 getCnt() const { return _cnt; } - private: - static void setTextureTwiddled(uint16 *tex, const uint8 *data, - const CMap *cmap, int sz, int extra=0); - unsigned int _mode2, _texture; - float _uscale, _vscale; - uint16 *_data; - uint16 _width, _height, _cnt; - unsigned int _framesize; - }; - - TextureManager() : _freeListHead(NULL) {} - Texture *allocateTexture(int width, int height, int cnt); - void freeTexture(Texture *t); - void initTextures(); - - private: - struct FreeListNode { - struct FreeListNode *next; - unsigned int size; - }; - FreeListNode *_freeListHead; - void *allocateTexMem(unsigned int size); - void freeTexMem(void *mem, unsigned int size); -}; - -#endif - diff --git a/backends/platform/sdl/amigaos/amigaos-main.cpp b/backends/platform/sdl/amigaos/amigaos-main.cpp new file mode 100644 index 00000000000..0206697b20d --- /dev/null +++ b/backends/platform/sdl/amigaos/amigaos-main.cpp @@ -0,0 +1,56 @@ +/* Residual - A 3D game interpreter + * + * 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 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/sys.h" + +#if defined(__amigaos4__) + +#include "backends/platform/sdl/amigaos/amigaos.h" +#include "backends/plugins/sdl/sdl-provider.h" +#include "base/main.h" + +int main(int argc, char *argv[]) { + + // Create our OSystem instance + g_system = new OSystem_AmigaOS(); + assert(g_system); + + // Pre initialize the backend + ((OSystem_AmigaOS *)g_system)->init(); + +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new SDLPluginProvider()); +#endif + + // Invoke the actual Residual main entry point: + int res = residual_main(argc, argv); + + // Free OSystem + delete (OSystem_AmigaOS *)g_system; + + return res; +} + +#endif diff --git a/backends/platform/sdl/amigaos/amigaos.cpp b/backends/platform/sdl/amigaos/amigaos.cpp new file mode 100644 index 00000000000..b708ec1a761 --- /dev/null +++ b/backends/platform/sdl/amigaos/amigaos.cpp @@ -0,0 +1,41 @@ +/* Residual - A 3D game interpreter + * + * 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 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/scummsys.h" + +#ifdef __amigaos4__ + +#include "backends/platform/sdl/amigaos/amigaos.h" +#include "backends/fs/amigaos4/amigaos4-fs-factory.h" + +void OSystem_AmigaOS::init() { + // Initialze File System Factory + _fsFactory = new AmigaOSFilesystemFactory(); + + // Invoke parent implementation of this method + OSystem_SDL::init(); +} + +#endif diff --git a/backends/platform/sdl/amigaos/amigaos.h b/backends/platform/sdl/amigaos/amigaos.h new file mode 100644 index 00000000000..2e25aa409c7 --- /dev/null +++ b/backends/platform/sdl/amigaos/amigaos.h @@ -0,0 +1,39 @@ +/* Residual - A 3D game interpreter + * + * 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 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 PLATFORM_SDL_AMIGAOS_H +#define PLATFORM_SDL_AMIGAOS_H + +#include "backends/platform/sdl/sdl.h" + +class OSystem_AmigaOS : public OSystem_SDL { +public: + OSystem_AmigaOS() {} + virtual ~OSystem_AmigaOS() {} + + virtual void init(); +}; + +#endif diff --git a/backends/platform/sdl/macosx/macosx-main.cpp b/backends/platform/sdl/macosx/macosx-main.cpp new file mode 100644 index 00000000000..705ac6c3875 --- /dev/null +++ b/backends/platform/sdl/macosx/macosx-main.cpp @@ -0,0 +1,56 @@ +/* Residual - A 3D game interpreter + * + * 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 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/scummsys.h" + +#ifdef MACOSX + +#include "backends/platform/sdl/macosx/macosx.h" +#include "backends/plugins/sdl/sdl-provider.h" +#include "base/main.h" + +int main(int argc, char *argv[]) { + + // Create our OSystem instance + g_system = new OSystem_MacOSX(); + assert(g_system); + + // Pre initialize the backend + ((OSystem_MacOSX *)g_system)->init(); + +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new SDLPluginProvider()); +#endif + + // Invoke the actual Residual main entry point: + int res = residual_main(argc, argv); + + // Free OSystem + delete (OSystem_MacOSX *)g_system; + + return res; +} + +#endif diff --git a/backends/platform/sdl/macosx/macosx.cpp b/backends/platform/sdl/macosx/macosx.cpp new file mode 100644 index 00000000000..041c78bacc7 --- /dev/null +++ b/backends/platform/sdl/macosx/macosx.cpp @@ -0,0 +1,81 @@ +/* Residual - A 3D game interpreter + * + * 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 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$ + * + */ + +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/scummsys.h" + +#ifdef MACOSX + +#include "backends/platform/sdl/macosx/macosx.h" +#include "backends/mixer/doublebuffersdl/doublebuffersdl-mixer.h" + +#include "common/archive.h" +#include "common/fs.h" + +#include "CoreFoundation/CoreFoundation.h" + +OSystem_MacOSX::OSystem_MacOSX() + : + OSystem_POSIX("Library/Preferences/Residual Preferences") { +} + +void OSystem_MacOSX::initBackend() { + // Create the mixer manager + if (_mixer == 0) { + _mixerManager = new DoubleBufferSDLMixerManager(); + + // Setup and start mixer + _mixerManager->init(); + } + + // Invoke parent implementation of this method + OSystem_POSIX::initBackend(); +} + +void OSystem_MacOSX::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { + // Invoke parent implementation of this method + OSystem_POSIX::addSysArchivesToSearchSet(s, priority); + + // Get URL of the Resource directory of the .app bundle + CFURLRef fileUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); + if (fileUrl) { + // Try to convert the URL to an absolute path + UInt8 buf[MAXPATHLEN]; + if (CFURLGetFileSystemRepresentation(fileUrl, true, buf, sizeof(buf))) { + // Success: Add it to the search path + Common::String bundlePath((const char *)buf); + s.add("__OSX_BUNDLE__", new Common::FSDirectory(bundlePath), priority); + } + CFRelease(fileUrl); + } +} + +void OSystem_MacOSX::setupIcon() { + // Don't set icon on OS X, as we use a nicer external icon there. +} + +#endif diff --git a/backends/platform/sdl/macosx/macosx.h b/backends/platform/sdl/macosx/macosx.h new file mode 100644 index 00000000000..911a2ac4178 --- /dev/null +++ b/backends/platform/sdl/macosx/macosx.h @@ -0,0 +1,40 @@ +/* Residual - A 3D game interpreter + * + * 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 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 PLATFORM_SDL_MACOSX_H +#define PLATFORM_SDL_MACOSX_H + +#include "backends/platform/sdl/posix/posix.h" + +class OSystem_MacOSX : public OSystem_POSIX { +public: + OSystem_MacOSX(); + + virtual void initBackend(); + virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); + virtual void setupIcon(); +}; + +#endif diff --git a/backends/platform/sdl/main.cpp b/backends/platform/sdl/main.cpp index 621e9a69838..d77c896c370 100644 --- a/backends/platform/sdl/main.cpp +++ b/backends/platform/sdl/main.cpp @@ -23,47 +23,44 @@ * */ -// Fix for bug #2895217 "MSVC compilation broken with r47595": -// We need to keep this on top of the "common/scummsys.h" include, -// otherwise we will get errors about the windows headers redefining -// "ARRAYSIZE" for example. -#if defined(WIN32) && !defined(__SYMBIAN32__) -#define WIN32_LEAN_AND_MEAN -#include -// winnt.h defines ARRAYSIZE, but we want our own one... -#undef ARRAYSIZE -#endif - #include "common/sys.h" // Several SDL based ports use a custom main, and hence do not want to compile // of this file. The following "#if" ensures that. -#if !defined(__MAEMO__) && !defined(_WIN32_WCE) && !defined(CAANOO) && !defined(GP2XWIZ) && !defined(LINUXMOTO) && !defined(OPENPANDORA) && !defined(__SYMBIAN32__) && !defined(DINGUX) - +#if !defined(UNIX) && \ + !defined(WIN32) && \ + !defined(__MAEMO__) && \ + !defined(__SYMBIAN32__) && \ + !defined(_WIN32_WCE) && \ + !defined(__amigaos4__) && \ + !defined(DINGUX) && \ + !defined(CAANOO) && \ + !defined(LINUXMOTO) && \ + !defined(OPENPANDORA) #include "backends/platform/sdl/sdl.h" #include "backends/plugins/sdl/sdl-provider.h" #include "base/main.h" -#ifdef WIN32 -int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) { - SDL_SetModuleHandle(GetModuleHandle(NULL)); - return main(__argc, __argv); -} -#endif - int main(int argc, char *argv[]) { // Create our OSystem instance g_system = new OSystem_SDL(); assert(g_system); + // Pre initialize the backend + ((OSystem_SDL *)g_system)->init(); + #ifdef DYNAMIC_MODULES PluginManager::instance().addPluginProvider(new SDLPluginProvider()); #endif // Invoke the actual Residual main entry point: int res = residual_main(argc, argv); + + // Free OSystem + delete (OSystem_SDL *)g_system; + return res; } diff --git a/backends/platform/sdl/module.mk b/backends/platform/sdl/module.mk index 43751a57b26..87a0e3d658e 100644 --- a/backends/platform/sdl/module.mk +++ b/backends/platform/sdl/module.mk @@ -1,12 +1,34 @@ MODULE := backends/platform/sdl MODULE_OBJS := \ - events.o \ - graphics.o \ hardwarekeys.o \ main.o \ sdl.o +ifdef UNIX +MODULE_OBJS += \ + posix/posix-main.o \ + posix/posix.o +endif + +ifdef MACOSX +MODULE_OBJS += \ + macosx/macosx-main.o \ + macosx/macosx.o +endif + +ifdef WIN32 +MODULE_OBJS += \ + win32/win32-main.o \ + win32/win32.o +endif + +ifdef AMIGAOS +MODULE_OBJS += \ + amigaos/amigaos-main.o \ + amigaos/amigaos.o +endif + # We don't use rules.mk but rather manually update OBJS and MODULE_DIRS. MODULE_OBJS := $(addprefix $(MODULE)/, $(MODULE_OBJS)) OBJS := $(MODULE_OBJS) $(OBJS) diff --git a/backends/platform/sdl/posix/posix-main.cpp b/backends/platform/sdl/posix/posix-main.cpp new file mode 100644 index 00000000000..67add5175c2 --- /dev/null +++ b/backends/platform/sdl/posix/posix-main.cpp @@ -0,0 +1,56 @@ +/* Residual - A 3D game interpreter + * + * 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 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/scummsys.h" + +#if defined(UNIX) && !defined(MACOSX) && !defined(SAMSUNGTV) && !defined(WEBOS) && !defined(LINUXMOTO) && !defined(GPH_DEVICE) && !defined(GP2X) && !defined(DINGUX) && !defined(OPENPANDORA) + +#include "backends/platform/sdl/posix/posix.h" +#include "backends/plugins/sdl/sdl-provider.h" +#include "base/main.h" + +int main(int argc, char *argv[]) { + + // Create our OSystem instance + g_system = new OSystem_POSIX(); + assert(g_system); + + // Pre initialize the backend + ((OSystem_POSIX *)g_system)->init(); + +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new SDLPluginProvider()); +#endif + + // Invoke the actual Residual main entry point: + int res = residual_main(argc, argv); + + // Free OSystem + delete (OSystem_POSIX *)g_system; + + return res; +} + +#endif diff --git a/backends/platform/sdl/posix/posix.cpp b/backends/platform/sdl/posix/posix.cpp new file mode 100644 index 00000000000..354feb9e017 --- /dev/null +++ b/backends/platform/sdl/posix/posix.cpp @@ -0,0 +1,129 @@ +/* Residual - A 3D game interpreter + * + * 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 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/scummsys.h" + +#ifdef UNIX + +#include "backends/platform/sdl/posix/posix.h" +#include "backends/saves/posix/posix-saves.h" +#include "backends/fs/posix/posix-fs-factory.h" + +#include +#include + +OSystem_POSIX::OSystem_POSIX(Common::String baseConfigName) + : + _baseConfigName(baseConfigName) { +} + +void OSystem_POSIX::init() { + // Initialze File System Factory + _fsFactory = new POSIXFilesystemFactory(); + + // Invoke parent implementation of this method + OSystem_SDL::init(); +} + +void OSystem_POSIX::initBackend() { + // Create the savefile manager + if (_savefileManager == 0) + _savefileManager = new POSIXSaveFileManager(); + + // Invoke parent implementation of this method + OSystem_SDL::initBackend(); +} + +Common::String OSystem_POSIX::getDefaultConfigFileName() { + char configFile[MAXPATHLEN]; + + // On UNIX type systems, by default we store the config file inside + // to the HOME directory of the user. + const char *home = getenv("HOME"); + if (home != NULL && strlen(home) < MAXPATHLEN) + snprintf(configFile, MAXPATHLEN, "%s/%s", home, _baseConfigName.c_str()); + else + strcpy(configFile, _baseConfigName.c_str()); + + return configFile; +} + +Common::WriteStream *OSystem_POSIX::createLogFile() { + const char *home = getenv("HOME"); + if (home == NULL) + return 0; + + Common::String logFile(home); +#ifdef MACOSX + logFile += "/Library"; +#else + logFile += "/.residual"; +#endif + + struct stat sb; + + // Check whether the dir exists + if (stat(logFile.c_str(), &sb) == -1) { + // The dir does not exist, or stat failed for some other reason. + if (errno != ENOENT) + return 0; + + // If the problem was that the path pointed to nothing, try + // to create the dir. + if (mkdir(logFile.c_str(), 0755) != 0) + return 0; + } else if (!S_ISDIR(sb.st_mode)) { + // Path is no directory. Oops + return 0; + } + +#ifdef MACOSX + logFile += "/Logs"; +#else + logFile += "/logs"; +#endif + + // Check whether the dir exists + if (stat(logFile.c_str(), &sb) == -1) { + // The dir does not exist, or stat failed for some other reason. + if (errno != ENOENT) + return 0; + + // If the problem was that the path pointed to nothing, try + // to create the dir. + if (mkdir(logFile.c_str(), 0755) != 0) + return 0; + } else if (!S_ISDIR(sb.st_mode)) { + // Path is no directory. Oops + return 0; + } + + logFile += "/residual.log"; + + Common::FSNode file(logFile); + return file.createWriteStream(); +} + +#endif diff --git a/backends/platform/sdl/posix/posix.h b/backends/platform/sdl/posix/posix.h new file mode 100644 index 00000000000..b3b948d1e2e --- /dev/null +++ b/backends/platform/sdl/posix/posix.h @@ -0,0 +1,50 @@ +/* Residual - A 3D game interpreter + * + * 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 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 PLATFORM_SDL_POSIX_H +#define PLATFORM_SDL_POSIX_H + +#include "backends/platform/sdl/sdl.h" + +class OSystem_POSIX : public OSystem_SDL { +public: + // Let the subclasses be able to change _baseConfigName in the constructor + OSystem_POSIX(Common::String baseConfigName = ".residualrc"); + virtual ~OSystem_POSIX() {} + + virtual void init(); + virtual void initBackend(); + +protected: + // Base string for creating the default path and filename + // for the configuration file + Common::String _baseConfigName; + + virtual Common::String getDefaultConfigFileName(); + + virtual Common::WriteStream *createLogFile(); +}; + +#endif diff --git a/backends/platform/sdl/sdl-sys.h b/backends/platform/sdl/sdl-sys.h new file mode 100644 index 00000000000..d61b7548ee7 --- /dev/null +++ b/backends/platform/sdl/sdl-sys.h @@ -0,0 +1,57 @@ +/* Residual - A 3D game interpreter + * + * 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 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 BACKEND_SDL_SYS_H +#define BACKEND_SDL_SYS_H + +// The purpose of this header is to include the SDL headers in a uniform +// fashion, even on the Symbian port. +// Moreover, it contains a workaround for the fact that SDL_rwops.h uses +// a FILE pointer in one place, which conflicts with common/forbidden.h. + + +#include "common/sys.h" + +// Remove FILE override from common/forbidden.h, and replace +// it with an alternate slightly less unfriendly override. +#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_FILE) +#undef FILE +typedef struct { int FAKE; } FAKE_FILE; +#define FILE FAKE_FILE +#endif + +#if defined(__SYMBIAN32__) +#include +#else +#include +#endif + +// Finally forbid FILE again (if it was forbidden to start with) +#if !defined(FORBIDDEN_SYMBOL_ALLOW_ALL) && !defined(FORBIDDEN_SYMBOL_EXCEPTION_FILE) +#undef FILE +#define FILE FORBIDDEN_SYMBOL_REPLACEMENT +#endif + +#endif diff --git a/backends/platform/sdl/sdl.cpp b/backends/platform/sdl/sdl.cpp index 60ce56b0ac2..91de4fe8393 100644 --- a/backends/platform/sdl/sdl.cpp +++ b/backends/platform/sdl/sdl.cpp @@ -23,234 +23,166 @@ * */ -#if defined(WIN32) +#ifdef WIN32 #define WIN32_LEAN_AND_MEAN #include -// winnt.h defines ARRAYSIZE, but we want our own one... - this is needed before including util.h -#undef ARRAYSIZE +#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one... #endif #include "backends/platform/sdl/sdl.h" -#include "common/archive.h" #include "common/config-manager.h" -#include "common/debug.h" #include "common/EventRecorder.h" -#include "common/util.h" -#ifdef UNIX - #include "backends/saves/posix/posix-saves.h" -#else - #include "backends/saves/default/default-saves.h" -#endif -#include "backends/timer/default/default-timer.h" -#include "sound/mixer_intern.h" +#include "backends/saves/default/default-saves.h" +#include "backends/audiocd/sdl/sdl-audiocd.h" +#include "backends/events/sdl/sdl-events.h" +#include "backends/mutex/sdl/sdl-mutex.h" +#include "backends/timer/sdl/sdl-timer.h" +#include "backends/graphics/sdl/sdl-graphics.h" #include "icons/residual.xpm" #include // for getTimeAndDate() -//#define SAMPLES_PER_SEC 11025 -#define SAMPLES_PER_SEC 22050 -//#define SAMPLES_PER_SEC 44100 - - -/* - * Include header files needed for the getFilesystemFactory() method. - */ -#if defined(__amigaos4__) - #include "backends/fs/amigaos4/amigaos4-fs-factory.h" -#elif defined(UNIX) - #include "backends/fs/posix/posix-fs-factory.h" -#elif defined(WIN32) - #include "backends/fs/windows/windows-fs-factory.h" +#ifdef USE_DETECTLANG +#ifndef WIN32 +#include +#endif // !WIN32 #endif +OSystem_SDL::OSystem_SDL() + : + _inited(false), + _initedSDL(false), + _logger(0), + _mixerManager(0), + _eventSource(0) { -#if defined(UNIX) -#ifdef MACOSX -#define DEFAULT_CONFIG_FILE "Library/Preferences/Residual Preferences" -#elif defined(SAMSUNGTV) -#define DEFAULT_CONFIG_FILE "/dtv/usb/sda1/.residualrc" -#else -#define DEFAULT_CONFIG_FILE ".residualrc" -#endif -#else -#define DEFAULT_CONFIG_FILE "residual.ini" -#endif +} -#if defined(MACOSX) || defined(IPHONE) -#include "CoreFoundation/CoreFoundation.h" -#endif +OSystem_SDL::~OSystem_SDL() { + SDL_ShowCursor(SDL_ENABLE); + + // Delete the various managers here. Note that the ModularBackend + // destructor would also take care of this for us. However, various + // of our managers must be deleted *before* we call SDL_Quit(). + // Hence, we perform the destruction on our own. + delete _savefileManager; + _savefileManager = 0; + delete _graphicsManager; + _graphicsManager = 0; + delete _eventManager; + _eventManager = 0; + delete _eventSource; + _eventSource = 0; + delete _audiocdManager; + _audiocdManager = 0; + delete _mixerManager; + _mixerManager = 0; + delete _timerManager; + _timerManager = 0; + delete _mutexManager; + _mutexManager = 0; + + delete _logger; + _logger = 0; + + SDL_Quit(); +} + +void OSystem_SDL::init() { + // Initialize SDL + initSDL(); + + if (!_logger) + _logger = new Backends::Log::Log(this); + + if (_logger) { + Common::WriteStream *logFile = createLogFile(); + if (logFile) + _logger->open(logFile); + } -static Uint32 timer_handler(Uint32 interval, void *param) { - ((DefaultTimerManager *)param)->handler(); - return interval; + // Creates the early needed managers, if they don't exist yet + // (we check for this to allow subclasses to provide their own). + if (_mutexManager == 0) + _mutexManager = new SdlMutexManager(); + + if (_timerManager == 0) + _timerManager = new SdlTimerManager(); } void OSystem_SDL::initBackend() { + // Check if backend has not been initialized assert(!_inited); - int joystick_num = ConfMan.getInt("joystick_num"); - uint32 sdlFlags = SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_TIMER; + // Create the default event source, in case a custom backend + // manager didn't provide one yet. + if (_eventSource == 0) + _eventSource = new SdlEventSource(); - if (ConfMan.hasKey("disable_sdl_parachute")) - sdlFlags |= SDL_INIT_NOPARACHUTE; + int graphicsManagerType = 0; -#ifdef _WIN32_WCE - if (ConfMan.hasKey("use_GDI") && ConfMan.getBool("use_GDI")) { - SDL_VideoInit("windib", 0); - sdlFlags ^= SDL_INIT_VIDEO; - } -#endif - - if (joystick_num > -1) - sdlFlags |= SDL_INIT_JOYSTICK; - - if (SDL_Init(sdlFlags) == -1) { - error("Could not initialize SDL: %s", SDL_GetError()); + if (_graphicsManager == 0) { + if (_graphicsManager == 0) { + _graphicsManager = new SdlGraphicsManager(_eventSource); + graphicsManagerType = 0; + } } - // disabled for now in Residual - //SDL_ShowCursor(SDL_DISABLE); + // Creates the backend managers, if they don't exist yet (we check + // for this to allow subclasses to provide their own). + if (_eventManager == 0) + _eventManager = new DefaultEventManager(_eventSource); - // Enable unicode support if possible - SDL_EnableUNICODE(1); + // We have to initialize the graphics manager before the event manager + // so the virtual keyboard can be initialized, but we have to add the + // graphics manager as an event observer after initializing the event + // manager. + if (graphicsManagerType == 0) + ((SdlGraphicsManager *)_graphicsManager)->initEventObserver(); -#if !defined(MACOSX) && !defined(__SYMBIAN32__) + if (_savefileManager == 0) + _savefileManager = new DefaultSaveFileManager(); + + if (_mixerManager == 0) { + _mixerManager = new SdlMixerManager(); + + // Setup and start mixer + _mixerManager->init(); + } + + if (_audiocdManager == 0) + _audiocdManager = new SdlAudioCDManager(); // Setup a custom program icon. - // Don't set icon on OS X, as we use a nicer external icon there. - // Don't for Symbian: it uses the EScummVM.aif file for the icon. setupIcon(); -#endif - - // enable joystick - if (joystick_num > -1 && SDL_NumJoysticks() > 0) { - printf("Using joystick: %s\n", SDL_JoystickName(0)); - _joystick = SDL_JoystickOpen(joystick_num); - } - - - // Create the savefile manager, if none exists yet (we check for this to - // allow subclasses to provide their own). - if (_savefile == 0) { -#ifdef UNIX - _savefile = new POSIXSaveFileManager(); -#else - _savefile = new DefaultSaveFileManager(); -#endif - } - - // Create and hook up the mixer, if none exists yet (we check for this to - // allow subclasses to provide their own). - if (_mixer == 0) { - setupMixer(); - } - - // Create and hook up the timer manager, if none exists yet (we check for - // this to allow subclasses to provide their own). - if (_timer == 0) { - // Note: We could implement a custom SDLTimerManager by using - // SDL_AddTimer. That might yield better timer resolution, but it would - // also change the semantics of a timer: Right now, ScummVM timers - // *never* run in parallel, due to the way they are implemented. If we - // switched to SDL_AddTimer, each timer might run in a separate thread. - // However, not all our code is prepared for that, so we can't just - // switch. Still, it's a potential future change to keep in mind. - _timer = new DefaultTimerManager(); - _timerID = SDL_AddTimer(10, &timer_handler, _timer); - } - - // Invoke parent implementation of this method - OSystem::initBackend(); _inited = true; } -OSystem_SDL::OSystem_SDL() - : - _screen(0), - _overlayVisible(false), - _overlayscreen(0), - _overlayWidth(0), _overlayHeight(0), - _overlayDirty(true), _overlayNumTex(0), -#ifdef USE_OPENGL - _overlayTexIds(0), +void OSystem_SDL::initSDL() { + // Check if SDL has not been initialized + if (!_initedSDL) { + uint32 sdlFlags = 0; + if (ConfMan.hasKey("disable_sdl_parachute")) + sdlFlags |= SDL_INIT_NOPARACHUTE; + +#ifdef WEBOS + // WebOS needs this flag or otherwise the application won't start + sdlFlags |= SDL_INIT_VIDEO; #endif - _cdrom(0), - _joystick(0), -#if MIXER_DOUBLE_BUFFERING - _soundMutex(0), _soundCond(0), _soundThread(0), - _soundThreadIsRunning(false), _soundThreadShouldQuit(false), -#endif - _fsFactory(0), - _savefile(0), - _mixer(0), - _timer(0) { + // Initialize SDL (SDL Subsystems are initiliazed in the corresponding sdl managers) + if (SDL_Init(sdlFlags) == -1) + error("Could not initialize SDL: %s", SDL_GetError()); - // reset mouse state - memset(&_km, 0, sizeof(_km)); + // Enable unicode support if possible + SDL_EnableUNICODE(1); - _inited = false; - - - #if defined(__amigaos4__) - _fsFactory = new AmigaOSFilesystemFactory(); - #elif defined(UNIX) - _fsFactory = new POSIXFilesystemFactory(); - #elif defined(WIN32) - _fsFactory = new WindowsFilesystemFactory(); - #elif defined(__SYMBIAN32__) - // Do nothing since its handled by the Symbian SDL inheritance - #else - #error Unknown and unsupported FS backend - #endif -} - -OSystem_SDL::~OSystem_SDL() { - SDL_RemoveTimer(_timerID); - closeMixer(); - closeOverlay(); - delete _savefile; - delete _timer; -} - -uint32 OSystem_SDL::getMillis() { - uint32 millis = SDL_GetTicks(); - g_eventRec.processMillis(millis); - return millis; -} - -void OSystem_SDL::delayMillis(uint msecs) { - SDL_Delay(msecs); -} - -void OSystem_SDL::getTimeAndDate(TimeDate &td) const { - time_t curTime = time(0); - struct tm t = *localtime(&curTime); - td.tm_sec = t.tm_sec; - td.tm_min = t.tm_min; - td.tm_hour = t.tm_hour; - td.tm_mday = t.tm_mday; - td.tm_mon = t.tm_mon; - td.tm_year = t.tm_year; -} - -Common::TimerManager *OSystem_SDL::getTimerManager() { - assert(_timer); - return _timer; -} - -Common::SaveFileManager *OSystem_SDL::getSavefileManager() { - assert(_savefile); - return _savefile; -} - -FilesystemFactory *OSystem_SDL::getFilesystemFactory() { - assert(_fsFactory); - return _fsFactory; + _initedSDL = true; + } } void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) { @@ -264,88 +196,10 @@ void OSystem_SDL::addSysArchivesToSearchSet(Common::SearchSet &s, int priority) } #endif -#ifdef MACOSX - // Get URL of the Resource directory of the .app bundle - CFURLRef fileUrl = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if (fileUrl) { - // Try to convert the URL to an absolute path - UInt8 buf[MAXPATHLEN]; - if (CFURLGetFileSystemRepresentation(fileUrl, true, buf, sizeof(buf))) { - // Success: Add it to the search path - Common::String bundlePath((const char *)buf); - s.add("__OSX_BUNDLE__", new Common::FSDirectory(bundlePath), priority); - } - CFRelease(fileUrl); - } - -#endif - } - -static Common::String getDefaultConfigFileName() { - char configFile[MAXPATHLEN]; -#if defined (WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) - OSVERSIONINFO win32OsVersion; - ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO)); - win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&win32OsVersion); - // Check for non-9X version of Windows. - if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) { - // Use the Application Data directory of the user profile. - if (win32OsVersion.dwMajorVersion >= 5) { - if (!GetEnvironmentVariable("APPDATA", configFile, sizeof(configFile))) - error("Unable to access application data directory"); - } else { - if (!GetEnvironmentVariable("USERPROFILE", configFile, sizeof(configFile))) - error("Unable to access user profile directory"); - - strcat(configFile, "\\Application Data"); - CreateDirectory(configFile, NULL); - } - - strcat(configFile, "\\Residual"); - CreateDirectory(configFile, NULL); - strcat(configFile, "\\" DEFAULT_CONFIG_FILE); - - FILE *tmp = NULL; - if ((tmp = fopen(configFile, "r")) == NULL) { - // Check windows directory - char oldConfigFile[MAXPATHLEN]; - GetWindowsDirectory(oldConfigFile, MAXPATHLEN); - strcat(oldConfigFile, "\\" DEFAULT_CONFIG_FILE); - if ((tmp = fopen(oldConfigFile, "r"))) { - strcpy(configFile, oldConfigFile); - - fclose(tmp); - } - } else { - fclose(tmp); - } - } else { - // Check windows directory - GetWindowsDirectory(configFile, MAXPATHLEN); - strcat(configFile, "\\" DEFAULT_CONFIG_FILE); - } -#elif defined(UNIX) - // On UNIX type systems, by default we store the config file inside - // to the HOME directory of the user. - // - // GP2X is Linux based but Home dir can be read only so do not use - // it and put the config in the executable dir. - // - // On the iPhone, the home dir of the user when you launch the app - // from the Springboard, is /. Which we don't want. - const char *home = getenv("HOME"); - if (home != NULL && strlen(home) < MAXPATHLEN) - snprintf(configFile, MAXPATHLEN, "%s/%s", home, DEFAULT_CONFIG_FILE); - else - strcpy(configFile, DEFAULT_CONFIG_FILE); -#else - strcpy(configFile, DEFAULT_CONFIG_FILE); -#endif - - return configFile; +Common::String OSystem_SDL::getDefaultConfigFileName() { + return "residual.ini"; } Common::SeekableReadStream *OSystem_SDL::createConfigReadStream() { @@ -376,81 +230,102 @@ void OSystem_SDL::setWindowCaption(const char *caption) { SDL_WM_SetCaption(cap.c_str(), cap.c_str()); } -bool OSystem_SDL::hasFeature(Feature f) { - return -#ifdef USE_OPENGL - (f == kFeatureOpenGL); -#else - false; -#endif -} - -void OSystem_SDL::setFeatureState(Feature f, bool enable) { - switch (f) { - case kFeatureFullscreenMode: - //setFullscreenMode(enable); - break; -/* case kFeatureAspectRatioCorrection: - //setAspectRatioCorrection(enable); - break; - case kFeatureAutoComputeDirtyRects: - if (enable) - _modeFlags |= DF_WANT_RECT_OPTIM; - else - _modeFlags &= ~DF_WANT_RECT_OPTIM; - break; - case kFeatureIconifyWindow: - if (enable) - SDL_WM_IconifyWindow();*/ - break; - default: - break; - } -} - -bool OSystem_SDL::getFeatureState(Feature f) { - switch (f) { - case kFeatureFullscreenMode: - return _fullscreen; -/* case kFeatureAspectRatioCorrection: - return _videoMode.aspectRatioCorrection; - case kFeatureAutoComputeDirtyRects: - return _modeFlags & DF_WANT_RECT_OPTIM;*/ - default: - return false; - } -} - -void OSystem_SDL::deinit() { - if (_cdrom) { - SDL_CDStop(_cdrom); - SDL_CDClose(_cdrom); - } - if (_joystick) - SDL_JoystickClose(_joystick); - - SDL_ShowCursor(SDL_ENABLE); - - SDL_RemoveTimer(_timerID); - closeMixer(); - - - delete _timer; - - SDL_Quit(); - - // Event Manager requires save manager for storing - // recorded events - delete getEventManager(); - delete _savefile; -} - void OSystem_SDL::quit() { - deinit(); - -#if !defined(SAMSUNGTV) + delete this; exit(0); +} + +void OSystem_SDL::fatalError() { + delete this; + exit(1); +} + + +void OSystem_SDL::logMessage(LogMessageType::Type type, const char *message) { + ModularBackend::logMessage(type, message); + if (_logger) + _logger->print(message); + +#if defined( USE_WINDBG ) +#if defined( _WIN32_WCE ) + TCHAR buf_unicode[1024]; + MultiByteToWideChar(CP_ACP, 0, message, strlen(message) + 1, buf_unicode, sizeof(buf_unicode)); + OutputDebugString(buf_unicode); + + if (type == LogMessageType::kError) { +#ifndef DEBUG + drawError(message); +#else + int cmon_break_into_the_debugger_if_you_please = *(int *)(message + 1); // bus error + printf("%d", cmon_break_into_the_debugger_if_you_please); // don't optimize the int out #endif + } + +#else + OutputDebugString(message); +#endif +#endif +} + +Common::String OSystem_SDL::getSystemLanguage() const { +#ifdef USE_DETECTLANG +#ifdef WIN32 + // We can not use "setlocale" (at least not for MSVC builds), since it + // will return locales like: "English_USA.1252", thus we need a special + // way to determine the locale string for Win32. + char langName[9]; + char ctryName[9]; + + const LCID languageIdentifier = GetThreadLocale(); + + // GetLocalInfo is only supported starting from Windows 2000, according to this: + // http://msdn.microsoft.com/en-us/library/dd318101%28VS.85%29.aspx + // On the other hand the locale constants used, seem to exist on Windows 98 too, + // check this for that: http://msdn.microsoft.com/en-us/library/dd464799%28v=VS.85%29.aspx + // + // I am not exactly sure what is the truth now, it might be very well that this breaks + // support for systems older than Windows 2000.... + // + // TODO: Check whether this (or ScummVM at all ;-) works on a system with Windows 98 for + // example and if it does not and we still want Windows 9x support, we should definitly + // think of another solution. + if (GetLocaleInfo(languageIdentifier, LOCALE_SISO639LANGNAME, langName, sizeof(langName)) != 0 && + GetLocaleInfo(languageIdentifier, LOCALE_SISO3166CTRYNAME, ctryName, sizeof(ctryName)) != 0) { + Common::String localeName = langName; + localeName += "_"; + localeName += ctryName; + + return localeName; + } else { + return ModularBackend::getSystemLanguage(); + } +#else // WIN32 + // Activating current locale settings + const char *locale = setlocale(LC_ALL, ""); + + // Detect the language from the locale + if (!locale) { + return ModularBackend::getSystemLanguage(); + } else { + int length = 0; + + // Strip out additional information, like + // ".UTF-8" or the like. We do this, since + // our translation languages are usually + // specified without any charset information. + for (int i = 0; locale[i]; ++i, ++length) { + // TODO: Check whether "@" should really be checked + // here. + if (locale[i] == '.' || locale[i] == ' ' || locale[i] == '@') + break; + } + + return Common::String(locale, length); + } +#endif // WIN32 +#else // USE_DETECTLANG + return ModularBackend::getSystemLanguage(); +#endif // USE_DETECTLANG } void OSystem_SDL::setupIcon() { @@ -505,289 +380,34 @@ void OSystem_SDL::setupIcon() { free(icon); } -OSystem::MutexRef OSystem_SDL::createMutex() { - return (MutexRef) SDL_CreateMutex(); +uint32 OSystem_SDL::getMillis() { + uint32 millis = SDL_GetTicks(); + g_eventRec.processMillis(millis); + return millis; } -void OSystem_SDL::lockMutex(MutexRef mutex) { - SDL_mutexP((SDL_mutex *) mutex); +void OSystem_SDL::delayMillis(uint msecs) { + SDL_Delay(msecs); } -void OSystem_SDL::unlockMutex(MutexRef mutex) { - SDL_mutexV((SDL_mutex *) mutex); -} - -void OSystem_SDL::deleteMutex(MutexRef mutex) { - SDL_DestroyMutex((SDL_mutex *) mutex); -} - -#pragma mark - -#pragma mark --- Audio --- -#pragma mark - - -#if MIXER_DOUBLE_BUFFERING - -void OSystem_SDL::mixerProducerThread() { - byte nextSoundBuffer; - - SDL_LockMutex(_soundMutex); - while (true) { - // Wait till we are allowed to produce data - SDL_CondWait(_soundCond, _soundMutex); - - if (_soundThreadShouldQuit) - break; - - // Generate samples and put them into the next buffer - nextSoundBuffer = _activeSoundBuf ^ 1; - _mixer->mixCallback(_soundBuffers[nextSoundBuffer], _soundBufSize); - - // Swap buffers - _activeSoundBuf = nextSoundBuffer; - } - SDL_UnlockMutex(_soundMutex); -} - -int SDLCALL OSystem_SDL::mixerProducerThreadEntry(void *arg) { - OSystem_SDL *this_ = (OSystem_SDL *)arg; - assert(this_); - this_->mixerProducerThread(); - return 0; -} - - -void OSystem_SDL::initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize) { - _soundThreadIsRunning = false; - _soundThreadShouldQuit = false; - - // Create mutex and condition variable - _soundMutex = SDL_CreateMutex(); - _soundCond = SDL_CreateCond(); - - // Create two sound buffers - _activeSoundBuf = 0; - _soundBufSize = bufSize; - _soundBuffers[0] = (byte *)calloc(1, bufSize); - _soundBuffers[1] = (byte *)calloc(1, bufSize); - - _soundThreadIsRunning = true; - - // Finally start the thread - _soundThread = SDL_CreateThread(mixerProducerThreadEntry, this); -} - -void OSystem_SDL::deinitThreadedMixer() { - // Kill thread?? _soundThread - - if (_soundThreadIsRunning) { - // Signal the producer thread to end, and wait for it to actually finish. - _soundThreadShouldQuit = true; - SDL_CondBroadcast(_soundCond); - SDL_WaitThread(_soundThread, NULL); - - // Kill the mutex & cond variables. - // Attention: AT this point, the mixer callback must not be running - // anymore, else we will crash! - SDL_DestroyMutex(_soundMutex); - SDL_DestroyCond(_soundCond); - - _soundThreadIsRunning = false; - - free(_soundBuffers[0]); - free(_soundBuffers[1]); - } -} - - -void OSystem_SDL::mixCallback(void *arg, byte *samples, int len) { - OSystem_SDL *this_ = (OSystem_SDL *)arg; - assert(this_); - assert(this_->_mixer); - - assert((int)this_->_soundBufSize == len); - - // Lock mutex, to ensure our data is not overwritten by the producer thread - SDL_LockMutex(this_->_soundMutex); - - // Copy data from the current sound buffer - memcpy(samples, this_->_soundBuffers[this_->_activeSoundBuf], len); - - // Unlock mutex and wake up the produced thread - SDL_UnlockMutex(this_->_soundMutex); - SDL_CondSignal(this_->_soundCond); -} - -#else - -void OSystem_SDL::mixCallback(void *sys, byte *samples, int len) { - OSystem_SDL *this_ = (OSystem_SDL *)sys; - assert(this_); - assert(this_->_mixer); - - this_->_mixer->mixCallback(samples, len); -} - -#endif - -void OSystem_SDL::setupMixer() { - SDL_AudioSpec desired; - - // Determine the desired output sampling frequency. - uint32 samplesPerSec = 0; - if (ConfMan.hasKey("output_rate")) - samplesPerSec = ConfMan.getInt("output_rate"); - if (samplesPerSec <= 0) - samplesPerSec = SAMPLES_PER_SEC; - - // Determine the sample buffer size. We want it to store enough data for - // at least 1/16th of a second (though at most 8192 samples). Note - // that it must be a power of two. So e.g. at 22050 Hz, we request a - // sample buffer size of 2048. - uint32 samples = 8192; - while (samples * 16 > samplesPerSec * 2) - samples >>= 1; - - memset(&desired, 0, sizeof(desired)); - desired.freq = samplesPerSec; - desired.format = AUDIO_S16SYS; - desired.channels = 2; - desired.samples = (uint16)samples; - desired.callback = mixCallback; - desired.userdata = this; - - assert(!_mixer); - if (SDL_OpenAudio(&desired, &_obtainedRate) != 0) { - warning("Could not open audio device: %s", SDL_GetError()); - _mixer = new Audio::MixerImpl(this, samplesPerSec); - assert(_mixer); - _mixer->setReady(false); - } else { - // Note: This should be the obtained output rate, but it seems that at - // least on some platforms SDL will lie and claim it did get the rate - // even if it didn't. Probably only happens for "weird" rates, though. - samplesPerSec = _obtainedRate.freq; - debug(1, "Output sample rate: %d Hz", samplesPerSec); - - // Create the mixer instance and start the sound processing - _mixer = new Audio::MixerImpl(this, samplesPerSec); - assert(_mixer); - _mixer->setReady(true); - -#if MIXER_DOUBLE_BUFFERING - initThreadedMixer(_mixer, _obtainedRate.samples * 4); -#endif - - // start the sound system - SDL_PauseAudio(0); - } -} - -void OSystem_SDL::closeMixer() { - if (_mixer) - _mixer->setReady(false); - - SDL_CloseAudio(); - - delete _mixer; - _mixer = 0; - -#if MIXER_DOUBLE_BUFFERING - deinitThreadedMixer(); -#endif - +void OSystem_SDL::getTimeAndDate(TimeDate &td) const { + time_t curTime = time(0); + struct tm t = *localtime(&curTime); + td.tm_sec = t.tm_sec; + td.tm_min = t.tm_min; + td.tm_hour = t.tm_hour; + td.tm_mday = t.tm_mday; + td.tm_mon = t.tm_mon; + td.tm_year = t.tm_year; } Audio::Mixer *OSystem_SDL::getMixer() { - assert(_mixer); - return _mixer; + assert(_mixerManager); + return _mixerManager->getMixer(); } -#pragma mark - -#pragma mark --- CD Audio --- -#pragma mark - - -bool OSystem_SDL::openCD(int drive) { - if (SDL_InitSubSystem(SDL_INIT_CDROM) == -1) - _cdrom = NULL; - else { - _cdrom = SDL_CDOpen(drive); - // Did it open? Check if _cdrom is NULL - if (!_cdrom) { - warning("Couldn't open drive: %s", SDL_GetError()); - } else { - _cdNumLoops = 0; - _cdStopTime = 0; - _cdEndTime = 0; - } - } - - return (_cdrom != NULL); +SdlMixerManager *OSystem_SDL::getMixerManager() { + assert(_mixerManager); + return _mixerManager; } -void OSystem_SDL::stopCD() { /* Stop CD Audio in 1/10th of a second */ - _cdStopTime = SDL_GetTicks() + 100; - _cdNumLoops = 0; -} - -void OSystem_SDL::playCD(int track, int num_loops, int start_frame, int duration) { - if (!num_loops && !start_frame) - return; - - if (!_cdrom) - return; - - if (duration > 0) - duration += 5; - - _cdTrack = track; - _cdNumLoops = num_loops; - _cdStartFrame = start_frame; - - SDL_CDStatus(_cdrom); - if (start_frame == 0 && duration == 0) - SDL_CDPlayTracks(_cdrom, track, 0, 1, 0); - else - SDL_CDPlayTracks(_cdrom, track, start_frame, 0, duration); - _cdDuration = duration; - _cdStopTime = 0; - _cdEndTime = SDL_GetTicks() + _cdrom->track[track].length * 1000 / CD_FPS; -} - -bool OSystem_SDL::pollCD() { - if (!_cdrom) - return false; - - return (_cdNumLoops != 0 && (SDL_GetTicks() < _cdEndTime || SDL_CDStatus(_cdrom) == CD_PLAYING)); -} - -void OSystem_SDL::updateCD() { - if (!_cdrom) - return; - - if (_cdStopTime != 0 && SDL_GetTicks() >= _cdStopTime) { - SDL_CDStop(_cdrom); - _cdNumLoops = 0; - _cdStopTime = 0; - return; - } - - if (_cdNumLoops == 0 || SDL_GetTicks() < _cdEndTime) - return; - - if (_cdNumLoops != 1 && SDL_CDStatus(_cdrom) != CD_STOPPED) { - // Wait another second for it to be done - _cdEndTime += 1000; - return; - } - - if (_cdNumLoops > 0) - _cdNumLoops--; - - if (_cdNumLoops != 0) { - if (_cdStartFrame == 0 && _cdDuration == 0) - SDL_CDPlayTracks(_cdrom, _cdTrack, 0, 1, 0); - else - SDL_CDPlayTracks(_cdrom, _cdTrack, _cdStartFrame, 0, _cdDuration); - _cdEndTime = SDL_GetTicks() + _cdrom->track[_cdTrack].length * 1000 / CD_FPS; - } -} diff --git a/backends/platform/sdl/sdl.h b/backends/platform/sdl/sdl.h index ead1002ffa5..e7c7a3fb26e 100644 --- a/backends/platform/sdl/sdl.h +++ b/backends/platform/sdl/sdl.h @@ -23,239 +23,101 @@ * */ -#ifndef SDL_COMMON_H -#define SDL_COMMON_H +#ifndef PLATFORM_SDL_H +#define PLATFORM_SDL_H -#if defined(__SYMBIAN32__) -#include -#else -#include +#include "backends/platform/sdl/sdl-sys.h" #ifdef USE_OPENGL #include #endif -#endif -#include "backends/base-backend.h" -#include "graphics/scaler.h" +#include "backends/modular-backend.h" +#include "backends/mixer/sdl/sdl-mixer.h" +#include "backends/events/sdl/sdl-events.h" +#include "backends/log/log.h" - -namespace Audio { - class MixerImpl; -} - -#if defined(MACOSX) -// On Mac OS X, we need to double buffer the audio buffer, else anything -// which produces sampled data with high latency (like the MT-32 emulator) -// will sound terribly. -// This could be enabled for more / most ports in the future, but needs some -// testing. -#define MIXER_DOUBLE_BUFFERING 1 -#endif - -class OSystem_SDL : public BaseBackend { +/** + * Base OSystem class for all SDL ports. + */ +class OSystem_SDL : public ModularBackend { public: OSystem_SDL(); virtual ~OSystem_SDL(); + /** + * Pre-initialize backend. It should be called after + * instantiating the backend. Early needed managers are + * created here. + */ + virtual void init(); + + /** + * Get the Mixer Manager instance. Not to confuse with getMixer(), + * that returns Audio::Mixer. The Mixer Manager is a SDL wrapper class + * for the Audio::Mixer. Used by other managers. + */ + virtual SdlMixerManager *getMixerManager(); + + // Override functions from ModularBackend and OSystem virtual void initBackend(); - - // Set the size of the video bitmap. - // Typically, 320x200 - virtual void launcherInitSize(uint w, uint h); - - virtual byte *setupScreen(int screenW, int screenH, bool fullscreen, bool accel3d); - - // Update the dirty areas of the screen - void updateScreen(); - - // Either show or hide the mouse cursor - bool showMouse(bool visible); - - // Warp the mouse cursor. Where set_mouse_pos() only informs the - // backend of the mouse cursor's current position, this function - // actually moves the cursor to the specified position. - virtual void warpMouse(int x, int y); // overloaded by CE backend (FIXME) - - // Set the bitmap that's used when drawing the cursor. - virtual void setMouseCursor(const byte *buf, uint w, uint h, int hotspot_x, int hotspot_y, uint32 keycolor, int cursorTargetScale, const Graphics::PixelFormat *format); // overloaded by CE backend (FIXME) - - // Get the number of milliseconds since the program was started. - uint32 getMillis(); - - // Delay for a specified amount of milliseconds - void delayMillis(uint msecs); - - // Get the next event. - // Returns true if an event was retrieved. - virtual bool pollEvent(Common::Event &event); // overloaded by CE backend - -protected: - virtual bool dispatchSDLEvent(SDL_Event &ev, Common::Event &event); - - // Handlers for specific SDL events, called by pollEvent. - // This way, if a backend inherits fromt the SDL backend, it can - // change the behavior of only a single event, without having to override all - // of pollEvent. - virtual bool handleKeyDown(SDL_Event &ev, Common::Event &event); - virtual bool handleKeyUp(SDL_Event &ev, Common::Event &event); - virtual bool handleMouseMotion(SDL_Event &ev, Common::Event &event); - virtual bool handleMouseButtonDown(SDL_Event &ev, Common::Event &event); - virtual bool handleMouseButtonUp(SDL_Event &ev, Common::Event &event); - virtual bool handleJoyButtonDown(SDL_Event &ev, Common::Event &event); - virtual bool handleJoyButtonUp(SDL_Event &ev, Common::Event &event); - virtual bool handleJoyAxisMotion(SDL_Event &ev, Common::Event &event); - -public: - - - // Define all hardware keys for keymapper virtual Common::HardwareKeySet *getHardwareKeySet(); + virtual void quit(); + virtual void fatalError(); - // Set function that generates samples - virtual void setupMixer(); - static void mixCallback(void *s, byte *samples, int len); + // Logging + virtual void logMessage(LogMessageType::Type type, const char *message); - virtual void closeMixer(); - - virtual Audio::Mixer *getMixer(); - - // Poll CD status - // Returns true if cd audio is playing - bool pollCD(); - - // Play CD audio track - void playCD(int track, int num_loops, int start_frame, int duration); - - // Stop CD audio track - void stopCD(); - - // Update CD audio status - void updateCD(); - - // Quit - virtual void quit(); // overloaded by CE backend - - void deinit(); - - virtual void getTimeAndDate(TimeDate &t) const; - virtual Common::TimerManager *getTimerManager(); - - // Mutex handling - MutexRef createMutex(); - void lockMutex(MutexRef mutex); - void unlockMutex(MutexRef mutex); - void deleteMutex(MutexRef mutex); - - // Overlay - virtual Graphics::PixelFormat getOverlayFormat() const { return _overlayFormat; } - - virtual void showOverlay(); - virtual void hideOverlay(); - virtual void clearOverlay(); - virtual void grabOverlay(OverlayColor *buf, int pitch); - virtual void copyRectToOverlay(const OverlayColor *buf, int pitch, int x, int y, int w, int h); - virtual int16 getHeight(); - virtual int16 getWidth(); - virtual int16 getOverlayHeight() { return _overlayHeight; } - virtual int16 getOverlayWidth() { return _overlayWidth; } + virtual Common::String getSystemLanguage() const; virtual void setWindowCaption(const char *caption); - virtual bool openCD(int drive); - - virtual bool hasFeature(Feature f); - virtual void setFeatureState(Feature f, bool enable); - virtual bool getFeatureState(Feature f); - virtual void preprocessEvents(SDL_Event *event) {} - - virtual Common::SaveFileManager *getSavefileManager(); - virtual FilesystemFactory *getFilesystemFactory(); virtual void addSysArchivesToSearchSet(Common::SearchSet &s, int priority = 0); - virtual Common::SeekableReadStream *createConfigReadStream(); virtual Common::WriteStream *createConfigWriteStream(); + virtual uint32 getMillis(); + virtual void delayMillis(uint msecs); + virtual void getTimeAndDate(TimeDate &td) const; + virtual Audio::Mixer *getMixer(); + + // HACK: Special SDL events types + enum SdlEvent { + kSdlEventExpose = 100, + kSdlEventResize = 101 + }; protected: bool _inited; - SDL_AudioSpec _obtainedRate; + bool _initedSDL; + /** + * Mixer manager that configures and setups SDL for + * the wrapped Audio::Mixer, the true mixer. + */ + SdlMixerManager *_mixerManager; -#ifdef USE_OPENGL - bool _opengl; -#endif - bool _fullscreen; - SDL_Surface *_screen; + /** + * The event source we use for obtaining SDL events. + */ + SdlEventSource *_eventSource; - // overlay - SDL_Surface *_overlayscreen; - bool _overlayVisible; - Graphics::PixelFormat _overlayFormat; - int _overlayWidth, _overlayHeight; - bool _overlayDirty; - int _overlayNumTex; -#ifdef USE_OPENGL - GLuint *_overlayTexIds; -#endif + /** + * Initialze the SDL library. + */ + virtual void initSDL(); - void closeOverlay(); + /** + * Setup the window icon. + */ + virtual void setupIcon(); - // CD Audio - SDL_CD *_cdrom; - int _cdTrack, _cdNumLoops, _cdStartFrame, _cdDuration; - uint32 _cdEndTime, _cdStopTime; + /** + * Get the file path where the user configuration + * of ScummVM will be saved. + */ + virtual Common::String getDefaultConfigFileName(); - // Keyboard mouse emulation. Disabled by fingolfin 2004-12-18. - // I am keeping the rest of the code in for now, since the joystick - // code (or rather, "hack") uses it, too. - struct KbdMouse { - int16 x, y, x_vel, y_vel, x_max, y_max, x_down_count, y_down_count; - uint32 last_time, delay_time, x_down_time, y_down_time; - }; - // mouse - KbdMouse _km; - // Scroll lock state - since SDL doesn't track it - bool _scrollLock; - - // joystick - SDL_Joystick *_joystick; -#ifdef MIXER_DOUBLE_BUFFERING - SDL_mutex *_soundMutex; - SDL_cond *_soundCond; - SDL_Thread *_soundThread; - bool _soundThreadIsRunning; - bool _soundThreadShouldQuit; - - byte _activeSoundBuf; - uint _soundBufSize; - byte *_soundBuffers[2]; - - void mixerProducerThread(); - static int SDLCALL mixerProducerThreadEntry(void *arg); - void initThreadedMixer(Audio::MixerImpl *mixer, uint bufSize); - void deinitThreadedMixer(); -#endif - - FilesystemFactory *_fsFactory; - Common::SaveFileManager *_savefile; - Audio::MixerImpl *_mixer; - - SDL_TimerID _timerID; - Common::TimerManager *_timer; - -protected: - - - /** Set the position of the virtual mouse cursor. */ - void setMousePos(int x, int y); - virtual void fillMouseEvent(Common::Event &event, int x, int y); // overloaded by CE backend - void toggleMouseGrab(); - - - void setupIcon(); - void handleKbdMouse(); - - virtual bool remapKey(SDL_Event &ev, Common::Event &event); - - bool handleScalerHotkeys(const SDL_KeyboardEvent &key); + // Logging + virtual Common::WriteStream *createLogFile() { return 0; } + Backends::Log::Log *_logger; }; #endif diff --git a/backends/platform/sdl/win32/win32-main.cpp b/backends/platform/sdl/win32/win32-main.cpp new file mode 100644 index 00000000000..4ef691f50b4 --- /dev/null +++ b/backends/platform/sdl/win32/win32-main.cpp @@ -0,0 +1,71 @@ +/* Residual - A 3D game interpreter + * + * 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 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$ + * + */ + +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/sys.h" + +#ifdef WIN32 + +// Fix for bug #2895217 "MSVC compilation broken with r47595": +// We need to keep this on top of the "common/scummsys.h"(base/main.h) include, +// otherwise we will get errors about the windows headers redefining +// "ARRAYSIZE" for example. +#define WIN32_LEAN_AND_MEAN +#include +#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one... + +#include "backends/platform/sdl/win32/win32.h" +#include "backends/plugins/sdl/sdl-provider.h" +#include "base/main.h" + +int __stdcall WinMain(HINSTANCE /*hInst*/, HINSTANCE /*hPrevInst*/, LPSTR /*lpCmdLine*/, int /*iShowCmd*/) { + SDL_SetModuleHandle(GetModuleHandle(NULL)); + return main(__argc, __argv); +} + +int main(int argc, char *argv[]) { + // Create our OSystem instance + g_system = new OSystem_Win32(); + assert(g_system); + + // Pre initialize the backend + ((OSystem_Win32 *)g_system)->init(); + +#ifdef DYNAMIC_MODULES + PluginManager::instance().addPluginProvider(new SDLPluginProvider()); +#endif + + // Invoke the actual Residual main entry point: + int res = residual_main(argc, argv); + + // Free OSystem + delete (OSystem_Win32 *)g_system; + + return res; +} + +#endif diff --git a/backends/platform/sdl/win32/win32.cpp b/backends/platform/sdl/win32/win32.cpp new file mode 100644 index 00000000000..3e3fe3f3a7e --- /dev/null +++ b/backends/platform/sdl/win32/win32.cpp @@ -0,0 +1,171 @@ +/* Residual - A 3D game interpreter + * + * 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 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$ + * + */ + +// Disable symbol overrides so that we can use system headers. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + +#include "common/sys.h" + +#ifdef WIN32 + +#define WIN32_LEAN_AND_MEAN +#include +#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one... + +#include "backends/platform/sdl/win32/win32.h" +#include "backends/fs/windows/windows-fs-factory.h" + +#define DEFAULT_CONFIG_FILE "residual.ini" + +//#define HIDE_CONSOLE + +#ifdef HIDE_CONSOLE +struct SdlConsoleHidingWin32 { + DWORD myPid; + DWORD myTid; + HWND consoleHandle; +}; + +// console hiding for win32 +static BOOL CALLBACK initBackendFindConsoleWin32Proc(HWND hWnd, LPARAM lParam) { + DWORD pid, tid; + SdlConsoleHidingWin32 *variables = (SdlConsoleHidingWin32 *)lParam; + tid = GetWindowThreadProcessId(hWnd, &pid); + if ((tid == variables->myTid) && (pid == variables->myPid)) { + variables->consoleHandle = hWnd; + return FALSE; + } + return TRUE; +} + +#endif + +void OSystem_Win32::init() { +#ifdef HIDE_CONSOLE + // console hiding for win32 + SdlConsoleHidingWin32 consoleHidingWin32; + consoleHidingWin32.consoleHandle = 0; + consoleHidingWin32.myPid = GetCurrentProcessId(); + consoleHidingWin32.myTid = GetCurrentThreadId(); + EnumWindows (initBackendFindConsoleWin32Proc, (LPARAM)&consoleHidingWin32); + + if (!ConfMan.getBool("show_console")) { + if (consoleHidingWin32.consoleHandle) { + // We won't find a window with our TID/PID in case we were started from command-line + ShowWindow(consoleHidingWin32.consoleHandle, SW_HIDE); + } + } +#endif + + // Initialze File System Factory + _fsFactory = new WindowsFilesystemFactory(); + + // Invoke parent implementation of this method + OSystem_SDL::init(); +} + +Common::String OSystem_Win32::getDefaultConfigFileName() { + char configFile[MAXPATHLEN]; + + OSVERSIONINFO win32OsVersion; + ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO)); + win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&win32OsVersion); + // Check for non-9X version of Windows. + if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) { + // Use the Application Data directory of the user profile. + if (win32OsVersion.dwMajorVersion >= 5) { + if (!GetEnvironmentVariable("APPDATA", configFile, sizeof(configFile))) + error("Unable to access application data directory"); + } else { + if (!GetEnvironmentVariable("USERPROFILE", configFile, sizeof(configFile))) + error("Unable to access user profile directory"); + + strcat(configFile, "\\Application Data"); + CreateDirectory(configFile, NULL); + } + + strcat(configFile, "\\Residual"); + CreateDirectory(configFile, NULL); + strcat(configFile, "\\" DEFAULT_CONFIG_FILE); + + FILE *tmp = NULL; + if ((tmp = fopen(configFile, "r")) == NULL) { + // Check windows directory + char oldConfigFile[MAXPATHLEN]; + GetWindowsDirectory(oldConfigFile, MAXPATHLEN); + strcat(oldConfigFile, "\\" DEFAULT_CONFIG_FILE); + if ((tmp = fopen(oldConfigFile, "r"))) { + strcpy(configFile, oldConfigFile); + + fclose(tmp); + } + } else { + fclose(tmp); + } + } else { + // Check windows directory + GetWindowsDirectory(configFile, MAXPATHLEN); + strcat(configFile, "\\" DEFAULT_CONFIG_FILE); + } + + return configFile; +} + +Common::WriteStream *OSystem_Win32::createLogFile() { + char logFile[MAXPATHLEN]; + + OSVERSIONINFO win32OsVersion; + ZeroMemory(&win32OsVersion, sizeof(OSVERSIONINFO)); + win32OsVersion.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); + GetVersionEx(&win32OsVersion); + // Check for non-9X version of Windows. + if (win32OsVersion.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS) { + // Use the Application Data directory of the user profile. + if (win32OsVersion.dwMajorVersion >= 5) { + if (!GetEnvironmentVariable("APPDATA", logFile, sizeof(logFile))) + error("Unable to access application data directory"); + } else { + if (!GetEnvironmentVariable("USERPROFILE", logFile, sizeof(logFile))) + error("Unable to access user profile directory"); + + strcat(logFile, "\\Application Data"); + CreateDirectory(logFile, NULL); + } + + strcat(logFile, "\\Residual"); + CreateDirectory(logFile, NULL); + strcat(logFile, "\\Logs"); + CreateDirectory(logFile, NULL); + strcat(logFile, "\\residual.log"); + + Common::FSNode file(logFile); + return file.createWriteStream(); + } else { + return 0; + } +} + +#endif diff --git a/backends/plugins/dc/dc-provider.h b/backends/platform/sdl/win32/win32.h similarity index 73% rename from backends/plugins/dc/dc-provider.h rename to backends/platform/sdl/win32/win32.h index dbe1db3f2b2..fd2f0e37b22 100644 --- a/backends/plugins/dc/dc-provider.h +++ b/backends/platform/sdl/win32/win32.h @@ -23,20 +23,18 @@ * */ -#ifndef BACKENDS_PLUGINS_DC_H -#define BACKENDS_PLUGINS_DC_H +#ifndef PLATFORM_SDL_WIN32_H +#define PLATFORM_SDL_WIN32_H -#include "base/plugins.h" +#include "backends/platform/sdl/sdl.h" -#if defined(DYNAMIC_MODULES) && defined(__DC__) +class OSystem_Win32 : public OSystem_SDL { +public: + virtual void init(); -class DCPluginProvider : public FilePluginProvider { protected: - Plugin* createPlugin(const Common::FSNode &node) const; - - bool isPluginFilename(const Common::FSNode &node) const; + virtual Common::String getDefaultConfigFileName(); + virtual Common::WriteStream *createLogFile(); }; -#endif // defined(DYNAMIC_MODULES) && defined(__DC__) - #endif diff --git a/backends/plugins/dc/dc-provider.cpp b/backends/plugins/dc/dc-provider.cpp deleted file mode 100644 index 6eaa92b2400..00000000000 --- a/backends/plugins/dc/dc-provider.cpp +++ /dev/null @@ -1,100 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 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$ - * - */ - -#if defined(DYNAMIC_MODULES) && defined(__DC__) - -#include "backends/plugins/dc/dc-provider.h" -#include "backends/plugins/dynamic-plugin.h" -#include "common/fs.h" - -#include "dcloader.h" - - -class DCPlugin : public DynamicPlugin { -protected: - void *_dlHandle; - Common::String _filename; - - virtual VoidFunc findSymbol(const char *symbol) { - void *func = dlsym(_dlHandle, symbol); - if (!func) - warning("Failed loading symbol '%s' from plugin '%s' (%s)", symbol, _filename.c_str(), dlerror()); - - // FIXME HACK: This is a HACK to circumvent a clash between the ISO C++ - // standard and POSIX: ISO C++ disallows casting between function pointers - // and data pointers, but dlsym always returns a void pointer. For details, - // see e.g. . - assert(sizeof(VoidFunc) == sizeof(func)); - VoidFunc tmp; - memcpy(&tmp, &func, sizeof(VoidFunc)); - return tmp; - } - -public: - DCPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} - - bool loadPlugin() { - assert(!_dlHandle); - _dlHandle = dlopen(_filename.c_str(), RTLD_LAZY); - - if (!_dlHandle) { - warning("Failed loading plugin '%s' (%s)", _filename.c_str(), dlerror()); - return false; - } - - bool ret = DynamicPlugin::loadPlugin(); - - if (ret) - dlforgetsyms(_dlHandle); - - return ret; - } - - void unloadPlugin() { - DynamicPlugin::unloadPlugin(); - if (_dlHandle) { - if (dlclose(_dlHandle) != 0) - warning("Failed unloading plugin '%s' (%s)", _filename.c_str(), dlerror()); - _dlHandle = 0; - } - } -}; - - -Plugin* DCPluginProvider::createPlugin(const Common::FSNode &node) const { - return new DCPlugin(node.getPath()); -} - -bool DCPluginProvider::isPluginFilename(const Common::FSNode &node) const { - // Check the plugin suffix - Common::String filename = node.getName(); - if (!filename.hasSuffix(".PLG")) - return false; - - return true; -} - -#endif // defined(DYNAMIC_MODULES) && defined(__DC__) diff --git a/backends/plugins/dynamic-plugin.h b/backends/plugins/dynamic-plugin.h index 6cd7a0b7551..3ca05d444b0 100644 --- a/backends/plugins/dynamic-plugin.h +++ b/backends/plugins/dynamic-plugin.h @@ -37,7 +37,12 @@ protected: virtual VoidFunc findSymbol(const char *symbol) = 0; + const Common::String _filename; + public: + DynamicPlugin(const Common::String &filename) : + _filename(filename) {} + virtual bool loadPlugin() { // Validate the plugin API version IntFunc verFunc = (IntFunc)findSymbol("PLUGIN_getVersion"); @@ -97,6 +102,10 @@ public: virtual void unloadPlugin() { delete _pluginObject; } + + virtual const char *getFileName() const { + return _filename.c_str(); + } }; #endif diff --git a/backends/plugins/posix/posix-provider.cpp b/backends/plugins/posix/posix-provider.cpp index 1ca3a7bca2b..53c756ced9b 100644 --- a/backends/plugins/posix/posix-provider.cpp +++ b/backends/plugins/posix/posix-provider.cpp @@ -23,6 +23,8 @@ * */ +#include "common/sys.h" + #if defined(DYNAMIC_MODULES) && defined(UNIX) #include "backends/plugins/posix/posix-provider.h" @@ -35,7 +37,6 @@ class POSIXPlugin : public DynamicPlugin { protected: void *_dlHandle; - Common::String _filename; virtual VoidFunc findSymbol(const char *symbol) { void *func = dlsym(_dlHandle, symbol); @@ -54,7 +55,7 @@ protected: public: POSIXPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} + : DynamicPlugin(filename), _dlHandle(0) {} bool loadPlugin() { assert(!_dlHandle); diff --git a/backends/plugins/sdl/sdl-provider.cpp b/backends/plugins/sdl/sdl-provider.cpp index 914989cac99..b001a48f38b 100644 --- a/backends/plugins/sdl/sdl-provider.cpp +++ b/backends/plugins/sdl/sdl-provider.cpp @@ -23,20 +23,19 @@ * */ +#include "common/sys.h" + #if defined(DYNAMIC_MODULES) && defined(SDL_BACKEND) #include "backends/plugins/sdl/sdl-provider.h" #include "backends/plugins/dynamic-plugin.h" #include "common/fs.h" -#include "SDL.h" -#include "SDL_loadso.h" - +#include "backends/platform/sdl/sdl-sys.h" class SDLPlugin : public DynamicPlugin { protected: void *_dlHandle; - Common::String _filename; virtual VoidFunc findSymbol(const char *symbol) { void *func = SDL_LoadFunction(_dlHandle, symbol); @@ -55,7 +54,7 @@ protected: public: SDLPlugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} + : DynamicPlugin(filename), _dlHandle(0) {} bool loadPlugin() { assert(!_dlHandle); diff --git a/backends/plugins/win32/win32-provider.cpp b/backends/plugins/win32/win32-provider.cpp index 24077b2dcac..633979a3697 100644 --- a/backends/plugins/win32/win32-provider.cpp +++ b/backends/plugins/win32/win32-provider.cpp @@ -23,6 +23,8 @@ * */ +#include "common/sys.h" + #if defined(DYNAMIC_MODULES) && defined(_WIN32) #include "backends/plugins/win32/win32-provider.h" @@ -49,7 +51,6 @@ private: protected: void *_dlHandle; - Common::String _filename; virtual VoidFunc findSymbol(const char *symbol) { #ifndef _WIN32_WCE @@ -65,7 +66,7 @@ protected: public: Win32Plugin(const Common::String &filename) - : _dlHandle(0), _filename(filename) {} + : DynamicPlugin(filename), _dlHandle(0) {} bool loadPlugin() { assert(!_dlHandle); diff --git a/backends/saves/default/default-saves.cpp b/backends/saves/default/default-saves.cpp index 241c2ed6dac..ae2ffc4d7c8 100644 --- a/backends/saves/default/default-saves.cpp +++ b/backends/saves/default/default-saves.cpp @@ -23,6 +23,8 @@ * */ +#include "common/sys.h" + #if !defined(DISABLE_DEFAULT_SAVEFILEMANAGER) #include "backends/saves/default/default-saves.h" @@ -34,8 +36,9 @@ #include "common/config-manager.h" #include "common/zlib.h" +#ifndef _WIN32_WCE #include // for removeSavefile() - +#endif DefaultSaveFileManager::DefaultSaveFileManager() { } diff --git a/backends/saves/posix/posix-saves.cpp b/backends/saves/posix/posix-saves.cpp index 3fe32180201..7d95bfc9505 100644 --- a/backends/saves/posix/posix-saves.cpp +++ b/backends/saves/posix/posix-saves.cpp @@ -23,6 +23,8 @@ * */ +#include "common/sys.h" + #if defined(UNIX) && !defined(DISABLE_DEFAULT_SAVEFILEMANAGER) #include "backends/saves/posix/posix-saves.h" diff --git a/backends/saves/savefile.cpp b/backends/saves/savefile.cpp index 84fb3da5258..450e809d7dc 100644 --- a/backends/saves/savefile.cpp +++ b/backends/saves/savefile.cpp @@ -31,8 +31,7 @@ namespace Common { -bool SaveFileManager::renameSavefile(const String &oldFilename, const String &newFilename) { - +bool SaveFileManager::copySavefile(const String &oldFilename, const String &newFilename) { InSaveFile *inFile = 0; OutSaveFile *outFile = 0; uint32 size = 0; @@ -57,9 +56,8 @@ bool SaveFileManager::renameSavefile(const String &oldFilename, const String &ne if (!error) { outFile->write(buffer, size); outFile->finalize(); - if (!outFile->err()) { - success = removeSavefile(oldFilename); - } + + success = !outFile->err(); } } @@ -71,6 +69,13 @@ bool SaveFileManager::renameSavefile(const String &oldFilename, const String &ne return success; } +bool SaveFileManager::renameSavefile(const String &oldFilename, const String &newFilename) { + if (!copySavefile(oldFilename, newFilename)) + return false; + + return removeSavefile(oldFilename); +} + String SaveFileManager::popErrorDesc() { String err = _errorDesc; clearError(); diff --git a/backends/timer/default/default-timer.cpp b/backends/timer/default/default-timer.cpp index 220f6c68923..d88ab585c70 100644 --- a/backends/timer/default/default-timer.cpp +++ b/backends/timer/default/default-timer.cpp @@ -34,7 +34,7 @@ struct TimerSlot { uint32 interval; // in microseconds uint32 nextFireTime; // in milliseconds - uint32 nextFireTimeMicro; // mircoseconds part of nextFire + uint32 nextFireTimeMicro; // microseconds part of nextFire TimerSlot *next; }; diff --git a/backends/timer/default/default-timer.h b/backends/timer/default/default-timer.h index 4ee07006640..83a9c6441f7 100644 --- a/backends/timer/default/default-timer.h +++ b/backends/timer/default/default-timer.h @@ -40,9 +40,9 @@ private: public: DefaultTimerManager(); - ~DefaultTimerManager(); - bool installTimerProc(TimerProc proc, int32 interval, void *refCon); - void removeTimerProc(TimerProc proc); + virtual ~DefaultTimerManager(); + virtual bool installTimerProc(TimerProc proc, int32 interval, void *refCon); + virtual void removeTimerProc(TimerProc proc); /** * Timer callback, to be invoked at regular time intervals by the backend. diff --git a/backends/timer/sdl/sdl-timer.cpp b/backends/timer/sdl/sdl-timer.cpp new file mode 100644 index 00000000000..6a72701a902 --- /dev/null +++ b/backends/timer/sdl/sdl-timer.cpp @@ -0,0 +1,53 @@ + +/* Residual - A 3D game interpreter + * + * 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 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/sys.h" + +#if defined(SDL_BACKEND) + +#include "backends/timer/sdl/sdl-timer.h" + +static Uint32 timer_handler(Uint32 interval, void *param) { + ((DefaultTimerManager *)param)->handler(); + return interval; +} + +SdlTimerManager::SdlTimerManager() { + // Initializes the SDL timer subsystem + if (SDL_InitSubSystem(SDL_INIT_TIMER) == -1) { + error("Could not initialize SDL: %s", SDL_GetError()); + } + + // Creates the timer callback + _timerID = SDL_AddTimer(10, &timer_handler, this); +} + +SdlTimerManager::~SdlTimerManager() { + // Removes the timer callback + SDL_RemoveTimer(_timerID); +} + +#endif diff --git a/backends/base-backend.h b/backends/timer/sdl/sdl-timer.h similarity index 69% rename from backends/base-backend.h rename to backends/timer/sdl/sdl-timer.h index 7ebedcdd75f..3264cf591c4 100644 --- a/backends/base-backend.h +++ b/backends/timer/sdl/sdl-timer.h @@ -23,19 +23,24 @@ * */ -#ifndef BACKENDS_BASE_BACKEND_H -#define BACKENDS_BASE_BACKEND_H +#ifndef BACKENDS_TIMER_SDL_H +#define BACKENDS_TIMER_SDL_H -#include "common/system.h" -#include "backends/events/default/default-events.h" +#include "backends/timer/default/default-timer.h" -class BaseBackend : public OSystem, Common::EventSource { +#include "backends/platform/sdl/sdl-sys.h" + +/** + * SDL timer manager. Setups the timer callback for + * DefaultTimerManager. + */ +class SdlTimerManager : public DefaultTimerManager { public: - virtual Common::EventManager *getEventManager(); - virtual void displayMessageOnOSD(const char *msg); + SdlTimerManager(); + virtual ~SdlTimerManager(); - virtual Common::SeekableReadStream *createConfigReadStream(); - virtual Common::WriteStream *createConfigWriteStream(); +protected: + SDL_TimerID _timerID; }; diff --git a/backends/vkeybd/image-map.cpp b/backends/vkeybd/image-map.cpp index 0b18a16ee0b..55264db1894 100644 --- a/backends/vkeybd/image-map.cpp +++ b/backends/vkeybd/image-map.cpp @@ -23,6 +23,8 @@ * */ +#include "common/sys.h" + #ifdef ENABLE_VKEYBD #include "backends/vkeybd/image-map.h" diff --git a/backends/vkeybd/packs/vkeybdpack.py b/backends/vkeybd/packs/vkeybdpack.py index 130e4b737b8..b0cd4c45e99 100644 --- a/backends/vkeybd/packs/vkeybdpack.py +++ b/backends/vkeybd/packs/vkeybdpack.py @@ -16,9 +16,9 @@ def buildPack(packName): if not os.path.isdir(packName): print ("Invalid pack name: " + packName) return - + zf = zipfile.ZipFile(packName + ".zip", 'w') - + zf.compress_type = zipfile.ZIP_DEFLATED print ("Building '" + packName + "' pack:") @@ -28,9 +28,9 @@ def buildPack(packName): if os.path.isfile(filename) and not filename[0] == '.' and filename.endswith(PACK_FILE_EXTENSIONS): zf.write(filename, './' + filename, compress_type=compression) print (" Adding file: " + filename) - + os.chdir('../') - + zf.close() def buildAllPacks(): @@ -49,13 +49,13 @@ def printUsage(): print (" Builds the pack called 'packname'.\n") def main(): - + if len(sys.argv) == 2 and sys.argv[1] == "makeall": buildAllPacks() - + elif len(sys.argv) == 3 and sys.argv[1] == "make": buildPack(sys.argv[2]) - + else: printUsage() diff --git a/backends/vkeybd/polygon.cpp b/backends/vkeybd/polygon.cpp index 2b099edc10e..407bda99c71 100644 --- a/backends/vkeybd/polygon.cpp +++ b/backends/vkeybd/polygon.cpp @@ -23,6 +23,8 @@ * */ +#include "common/sys.h" + #ifdef ENABLE_VKEYBD #include "backends/vkeybd/polygon.h" diff --git a/backends/vkeybd/virtual-keyboard-gui.cpp b/backends/vkeybd/virtual-keyboard-gui.cpp index 478f8fe968f..248de7e6795 100644 --- a/backends/vkeybd/virtual-keyboard-gui.cpp +++ b/backends/vkeybd/virtual-keyboard-gui.cpp @@ -23,13 +23,15 @@ * */ +#include "common/sys.h" + #ifdef ENABLE_VKEYBD #include "backends/vkeybd/virtual-keyboard-gui.h" #include "graphics/cursorman.h" #include "graphics/fontman.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" namespace Common { diff --git a/backends/vkeybd/virtual-keyboard-parser.cpp b/backends/vkeybd/virtual-keyboard-parser.cpp index e3980de825b..e98e995db3e 100644 --- a/backends/vkeybd/virtual-keyboard-parser.cpp +++ b/backends/vkeybd/virtual-keyboard-parser.cpp @@ -23,6 +23,7 @@ * */ +#include "common/sys.h" #ifdef ENABLE_VKEYBD @@ -34,6 +35,7 @@ #include "common/system.h" #include "common/archive.h" #include "common/tokenizer.h" +#include "common/stream.h" #include "graphics/imagedec.h" @@ -270,7 +272,7 @@ bool VirtualKeyboardParser::parserCallback_layout(ParserNode *node) { int r, g, b; if (node->values.contains("transparent_color")) { - if (!parseIntegerKey(node->values["transparent_color"].c_str(), 3, &r, &g, &b)) + if (!parseIntegerKey(node->values["transparent_color"], 3, &r, &g, &b)) return parserError("Could not parse color value"); } else { // default to purple @@ -281,7 +283,7 @@ bool VirtualKeyboardParser::parserCallback_layout(ParserNode *node) { _mode->transparentColor = format.RGBToColor(r, g, b); if (node->values.contains("display_font_color")) { - if (!parseIntegerKey(node->values["display_font_color"].c_str(), 3, &r, &g, &b)) + if (!parseIntegerKey(node->values["display_font_color"], 3, &r, &g, &b)) return parserError("Could not parse color value"); } else { r = g = b = 0; // default to black @@ -336,7 +338,7 @@ byte VirtualKeyboardParser::parseFlags(const String& flags) { bool VirtualKeyboardParser::parseRect(Rect &rect, const String& coords) { int x1, y1, x2, y2; - if (!parseIntegerKey(coords.c_str(), 4, &x1, &y1, &x2, &y2)) + if (!parseIntegerKey(coords, 4, &x1, &y1, &x2, &y2)) return parserError("Invalid coords for rect area"); rect.left = x1; rect.top = y1; diff --git a/backends/vkeybd/virtual-keyboard.cpp b/backends/vkeybd/virtual-keyboard.cpp index fcf31b4fbaf..14c50d23320 100644 --- a/backends/vkeybd/virtual-keyboard.cpp +++ b/backends/vkeybd/virtual-keyboard.cpp @@ -23,6 +23,8 @@ * */ +#include "common/sys.h" + #ifdef ENABLE_VKEYBD #include "backends/vkeybd/virtual-keyboard.h" diff --git a/base/commandLine.cpp b/base/commandLine.cpp index 1520c4fbaf8..b2d0af6b852 100644 --- a/base/commandLine.cpp +++ b/base/commandLine.cpp @@ -117,6 +117,7 @@ static void usage(const char *s, ...) { void registerDefaults() { + // Graphics ConfMan.registerDefault("fullscreen", false); ConfMan.registerDefault("soft_renderer", "true"); @@ -131,6 +132,10 @@ void registerDefaults() { ConfMan.registerDefault("native_mt32", false); ConfMan.registerDefault("enable_gs", false); ConfMan.registerDefault("midi_gain", 100); + + ConfMan.registerDefault("mt32_device", "null"); + ConfMan.registerDefault("gm_device", "null"); + ConfMan.registerDefault("cdrom", 0); // Game specific @@ -149,6 +154,14 @@ void registerDefaults() { ConfMan.registerDefault("record_file_name", "record.bin"); ConfMan.registerDefault("record_temp_file_name", "record.tmp"); ConfMan.registerDefault("record_time_file_name", "record.time"); + +#if 0 + // NEW CODE TO HIDE CONSOLE FOR WIN32 +#ifdef WIN32 + // console hiding for win32 + ConfMan.registerDefault("show_console", false); +#endif +#endif } // @@ -430,6 +443,15 @@ Common::String parseCommandLine(Common::StringMap &settings, int argc, const cha END_OPTION #endif +#if 0 + // NEW CODE TO HIDE CONSOLE FOR WIN32 +#ifdef WIN32 + // console hiding for win32 + DO_LONG_OPTION_BOOL("show-console") + END_OPTION +#endif +#endif + unknownOption: // If we get till here, the option is unhandled and hence unknown. usage("Unrecognized option '%s'", argv[i]); @@ -462,6 +484,10 @@ static void listTargets() { using namespace Common; const ConfigManager::DomainMap &domains = ConfMan.getGameDomains(); ConfigManager::DomainMap::const_iterator iter; + + Common::Array targets; + targets.reserve(domains.size()); + for (iter = domains.begin(); iter != domains.end(); ++iter) { Common::String name(iter->_key); Common::String description(iter->_value.getVal("description")); @@ -476,9 +502,13 @@ static void listTargets() { description = g.description(); } - printf("%-20s %s\n", name.c_str(), description.c_str()); - + targets.push_back(Common::String::format("%-20s %s", name.c_str(), description.c_str())); } + + Common::sort(targets.begin(), targets.end()); + + for (Common::Array::const_iterator i = targets.begin(), end = targets.end(); i != end; ++i) + printf("%s\n", i->c_str()); } /** Lists all usable themes */ diff --git a/base/internal_version.h b/base/internal_version.h index 8c053a3787e..27e05899195 100644 --- a/base/internal_version.h +++ b/base/internal_version.h @@ -2,13 +2,12 @@ #error This file may only be included by base/version.cpp #endif -#ifndef RESIDUAL_SVN_REVISION -#define RESIDUAL_SVN_REVISION -#endif - #ifdef RELEASE_BUILD -#undef RESIDUAL_SVN_REVISION -#define RESIDUAL_SVN_REVISION +#undef RESIDUAL_REVISION #endif -#define RESIDUAL_VERSION "0.0.6svn" RESIDUAL_SVN_REVISION +#ifndef RESIDUAL_REVISION +#define RESIDUAL_REVISION +#endif + +#define RESIDUAL_VERSION "0.0.6git" RESIDUAL_REVISION diff --git a/base/internal_version.h.in b/base/internal_version.h.in index 661923f65a1..3ff2dca0516 100644 --- a/base/internal_version.h.in +++ b/base/internal_version.h.in @@ -2,13 +2,12 @@ #error This file may only be included by base/version.cpp #endif -#ifndef RESIDUAL_SVN_REVISION -#define RESIDUAL_SVN_REVISION -#endif - #ifdef RELEASE_BUILD -#undef RESIDUAL_SVN_REVISION -#define RESIDUAL_SVN_REVISION +#undef RESIDUAL_REVISION #endif -#define RESIDUAL_VERSION "@VERSION@" RESIDUAL_SVN_REVISION +#ifndef RESIDUAL_REVISION +#define RESIDUAL_REVISION +#endif + +#define RESIDUAL_VERSION "@VERSION@" RESIDUAL_REVISION diff --git a/base/main.cpp b/base/main.cpp index 87e845b282d..30811d0ea76 100644 --- a/base/main.cpp +++ b/base/main.cpp @@ -40,7 +40,7 @@ #include "common/archive.h" #include "common/config-manager.h" #include "common/debug.h" -#include "common/debug-channels.h" +#include "common/debug-channels.h" /* for debug manager */ #include "common/events.h" #include "common/EventRecorder.h" #include "common/file.h" @@ -49,12 +49,12 @@ #include "common/tokenizer.h" #include "common/translation.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/message.h" #include "gui/error.h" -#include "sound/audiocd.h" -#include "sound/mididrv.h" +#include "audio/mididrv.h" +#include "audio/musicplugin.h" /* for music manager */ #include "backends/keymapper/keymapper.h" @@ -105,7 +105,8 @@ static const EnginePlugin *detectPlugin() { // Query the plugins and find one that will handle the specified gameid printf("User picked target '%s' (gameid '%s')...\n", ConfMan.getActiveDomainName().c_str(), gameid.c_str()); printf("%s", " Looking for a plugin supporting this gameid... "); - GameDescriptor game = EngineMan.findGame(gameid, &plugin); + + GameDescriptor game = EngineMan.findGame(gameid, &plugin); if (plugin == 0) { printf("failed\n"); @@ -214,12 +215,12 @@ static Common::Error runGame(const EnginePlugin *plugin, OSystem &system, const // Inform backend that the engine finished system.engineDone(); - // We clear all debug levels again even though the engine should do it - DebugMan.clearAllDebugChannels(); - // Free up memory delete engine; + // We clear all debug levels again even though the engine should do it + DebugMan.clearAllDebugChannels(); + // Reset the file/directory mappings SearchMan.clear(); @@ -238,6 +239,9 @@ static void setupGraphics(OSystem &system) { // Set initial window caption system.setWindowCaption(gResidualFullVersion); + + // Clear the main screen + //system.fillScreen(0); } static void setupKeymapper(OSystem &system) { @@ -296,7 +300,7 @@ extern "C" int residual_main(int argc, const char * const argv[]) { Common::StringMap settings; command = Base::parseCommandLine(settings, argc, argv); - // Load the config file (possibly overriden via command line): + // Load the config file (possibly overridden via command line): if (settings.contains("config")) { ConfMan.loadConfigFile(settings["config"]); settings.erase("config"); @@ -322,9 +326,9 @@ extern "C" int residual_main(int argc, const char * const argv[]) { settings.erase("debugflags"); } - // Load the plugins. - PluginManager::instance().loadPlugins(); - + PluginManager::instance().init(); + PluginManager::instance().loadAllPlugins(); // load plugins for cached plugin manager + // If we received an invalid music parameter via command line we check this here. // We can't check this before loading the music plugins. // On the other hand we cannot load the plugins before we know the file paths (in case of external plugins). @@ -339,6 +343,7 @@ extern "C" int residual_main(int argc, const char * const argv[]) { // config file and the plugins have been loaded. Common::Error res; + // TODO: deal with settings that require plugins to be loaded if ((res = Base::processSettings(command, settings)) != Common::kArgumentNotProcessed) return res; @@ -348,6 +353,12 @@ extern "C" int residual_main(int argc, const char * const argv[]) { setupGraphics(system); + // Init the different managers that are used by the engines. + // Do it here to prevent fragmentation later + system.getAudioCDManager(); + MusicManager::instance(); + Common::DebugManager::instance(); + // Init the event manager. As the virtual keyboard is loaded here, it must // take place after the backend is initiated and the screen has been setup system.getEventManager()->init(); @@ -381,6 +392,13 @@ extern "C" int residual_main(int argc, const char * const argv[]) { // Try to run the game Common::Error result = runGame(plugin, system, specialDebug); + #if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES) + // do our best to prevent fragmentation by unloading as soon as we can + PluginManager::instance().unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); + // reallocate the config manager to get rid of any fragmentation + ConfMan.defragment(); + #endif + // Did an error occur ? if (result != Common::kNoError) { // Shows an informative error dialog if starting the selected game failed. @@ -405,33 +423,24 @@ extern "C" int residual_main(int argc, const char * const argv[]) { // Clear the active config domain ConfMan.setActiveDomain(""); - // PluginManager::instance().unloadPlugins(); - PluginManager::instance().loadPlugins(); + PluginManager::instance().loadAllPlugins(); // only for cached manager + } else { - // A dialog would be nicer, but we don't have any - // screen to draw on yet. - warning("%s", _("Could not find any engine capable of running the selected game")); GUI::displayErrorDialog(_("Could not find any engine capable of running the selected game")); } - // We will destroy the AudioCDManager singleton here to save some memory. - // This will not make the CD audio stop, one would have to enable this: - //AudioCD.stop(); - // but the engine is responsible for stopping CD playback anyway and - // this way we catch engines not doing it properly. For some more - // information about why AudioCDManager::destroy does not stop the CD - // playback read the FIXME in sound/audiocd.h - Audio::AudioCDManager::destroy(); - // reset the graphics to default setupGraphics(system); launcherDialog(); } - PluginManager::instance().unloadPlugins(); + PluginManager::instance().unloadAllPlugins(); PluginManager::destroy(); + GUI::GuiManager::destroy(); Common::ConfigManager::destroy(); Common::SearchManager::destroy(); - GUI::GuiManager::destroy(); +#ifdef USE_TRANSLATION + Common::TranslationManager::destroy(); +#endif return 0; } diff --git a/base/plugins.cpp b/base/plugins.cpp index d32e7aea1f9..da29f9fcc45 100644 --- a/base/plugins.cpp +++ b/base/plugins.cpp @@ -27,9 +27,9 @@ #include "common/func.h" #include "common/debug.h" +#include "common/config-manager.h" #ifdef DYNAMIC_MODULES -#include "common/config-manager.h" #include "common/fs.h" #endif @@ -92,6 +92,56 @@ public: LINK_PLUGIN(GRIM) #endif + // Music plugins + // TODO: Use defines to disable or enable each MIDI driver as a + // static/dynamic plugin, like it's done for the engines + LINK_PLUGIN(AUTO) + LINK_PLUGIN(NULL) + #if defined(WIN32) && !defined(_WIN32_WCE) && !defined(__SYMBIAN32__) + LINK_PLUGIN(WINDOWS) + #endif + #if defined(USE_ALSA) + LINK_PLUGIN(ALSA) + #endif + #if defined(USE_SEQ_MIDI) + LINK_PLUGIN(SEQ) + #endif + #if defined(__MINT__) + LINK_PLUGIN(STMIDI) + #endif + #if defined(IRIX) + LINK_PLUGIN(DMEDIA) + #endif + #if defined(__amigaos4__) + LINK_PLUGIN(CAMD) + #endif + #if defined(MACOSX) + LINK_PLUGIN(COREAUDIO) + LINK_PLUGIN(COREMIDI) + #endif + #ifdef USE_FLUIDSYNTH + LINK_PLUGIN(FLUIDSYNTH) + #endif + #ifdef USE_MT32EMU + LINK_PLUGIN(MT32) + #endif + #if defined(__ANDROID__) + LINK_PLUGIN(EAS) + #endif + LINK_PLUGIN(ADLIB) + LINK_PLUGIN(PCSPK) + LINK_PLUGIN(PCJR) + LINK_PLUGIN(CMS) + #ifndef DISABLE_SID + LINK_PLUGIN(C64) + #endif +// LINK_PLUGIN(AMIGA) + LINK_PLUGIN(APPLEIIGS) + LINK_PLUGIN(TOWNS) + #if defined(USE_TIMIDITY) + LINK_PLUGIN(TIMIDITY) + #endif + return pl; } }; @@ -166,7 +216,19 @@ void FilePluginProvider::addCustomDirectories(Common::FSList &dirs) const { #pragma mark - -DECLARE_SINGLETON(PluginManager) +PluginManager *PluginManager::_instance = NULL; + +PluginManager &PluginManager::instance() { + if (_instance) + return *_instance; + +#if defined(UNCACHED_PLUGINS) && defined(DYNAMIC_MODULES) + _instance = new PluginManagerUncached(); +#else + _instance = new PluginManager(); +#endif + return *_instance; +} PluginManager::PluginManager() { // Always add the static plugin provider. @@ -175,7 +237,7 @@ PluginManager::PluginManager() { PluginManager::~PluginManager() { // Explicitly unload all loaded plugins - unloadPlugins(); + unloadAllPlugins(); // Delete the plugin providers for (ProviderList::iterator pp = _providers.begin(); @@ -189,62 +251,166 @@ void PluginManager::addPluginProvider(PluginProvider *pp) { _providers.push_back(pp); } -void PluginManager::loadPlugins() { +/** + * This should only be called once by main() + **/ +void PluginManagerUncached::init() { + unloadAllPlugins(); + _allEnginePlugins.clear(); + + // Resize our pluginsInMem list to prevent fragmentation + _pluginsInMem[PLUGIN_TYPE_ENGINE].resize(2); + unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); // empty the engine plugins + + for (ProviderList::iterator pp = _providers.begin(); + pp != _providers.end(); + ++pp) { + PluginList pl((*pp)->getPlugins()); + + for (PluginList::iterator p = pl.begin(); p != pl.end(); ++p) { + // This is a 'hack' based on the assumption that we have no sound + // file plugins. Currently this is the case. If it changes, we + // should find a fast way of detecting whether a plugin is a + // music or an engine plugin. + if ((*pp)->isFilePluginProvider()) { + _allEnginePlugins.push_back(*p); + } else if ((*p)->loadPlugin()) { // and this is the proper method + if ((*p)->getType() == PLUGIN_TYPE_ENGINE) { + (*p)->unloadPlugin(); + _allEnginePlugins.push_back(*p); + } else { // add non-engine plugins to the 'in-memory' list + // these won't ever get unloaded + addToPluginsInMemList(*p); + } + } + } + } +} + +/** + * Try to load the plugin by searching in the ConfigManager for a matching + * gameId under the domain 'plugin_files'. + **/ +bool PluginManagerUncached::loadPluginFromGameId(const Common::String &gameId) { + Common::ConfigManager::Domain *domain = ConfMan.getDomain("plugin_files"); + + if (domain) { + if (domain->contains(gameId)) { + Common::String filename = (*domain)[gameId]; + + if (loadPluginByFileName(filename)) { + return true; + } + } + } + return false; +} + +/** + * Load a plugin with a filename taken from ConfigManager. + **/ +bool PluginManagerUncached::loadPluginByFileName(const Common::String &filename) { + if (filename.empty()) + return false; + + unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); + + PluginList::iterator i; + for (i = _allEnginePlugins.begin(); i != _allEnginePlugins.end(); ++i) { + if (Common::String((*i)->getFileName()) == filename && (*i)->loadPlugin()) { + addToPluginsInMemList(*i); + _currentPlugin = i; + return true; + } + } + return false; +} + +/** + * Update the config manager with a plugin file name that we found can handle + * the game. + **/ +void PluginManagerUncached::updateConfigWithFileName(const Common::String &gameId) { + // Check if we have a filename for the current plugin + if ((*_currentPlugin)->getFileName()) { + if (!ConfMan.hasMiscDomain("plugin_files")) + ConfMan.addMiscDomain("plugin_files"); + + Common::ConfigManager::Domain *domain = ConfMan.getDomain("plugin_files"); + assert(domain); + (*domain)[gameId] = (*_currentPlugin)->getFileName(); + + ConfMan.flushToDisk(); + } +} + +void PluginManagerUncached::loadFirstPlugin() { + unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); + + // let's try to find one we can load + for (_currentPlugin = _allEnginePlugins.begin(); _currentPlugin != _allEnginePlugins.end(); ++_currentPlugin) { + if ((*_currentPlugin)->loadPlugin()) { + addToPluginsInMemList(*_currentPlugin); + break; + } + } +} + +bool PluginManagerUncached::loadNextPlugin() { + unloadPluginsExcept(PLUGIN_TYPE_ENGINE, NULL, false); + + for (++_currentPlugin; _currentPlugin != _allEnginePlugins.end(); ++_currentPlugin) { + if ((*_currentPlugin)->loadPlugin()) { + addToPluginsInMemList(*_currentPlugin); + return true; + } + } + return false; // no more in list +} + +/** + * Used by only the cached plugin manager. The uncached manager can only have + * one plugin in memory at a time. + **/ +void PluginManager::loadAllPlugins() { for (ProviderList::iterator pp = _providers.begin(); pp != _providers.end(); ++pp) { PluginList pl((*pp)->getPlugins()); Common::for_each(pl.begin(), pl.end(), Common::bind1st(Common::mem_fun(&PluginManager::tryLoadPlugin), this)); } - } -void PluginManager::unloadPlugins() { +void PluginManager::unloadAllPlugins() { for (int i = 0; i < PLUGIN_TYPE_MAX; i++) unloadPluginsExcept((PluginType)i, NULL); } -void PluginManager::unloadPluginsExcept(PluginType type, const Plugin *plugin) { +void PluginManager::unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin /*=true*/) { Plugin *found = NULL; - for (PluginList::iterator p = _plugins[type].begin(); p != _plugins[type].end(); ++p) { + for (PluginList::iterator p = _pluginsInMem[type].begin(); p != _pluginsInMem[type].end(); ++p) { if (*p == plugin) { found = *p; } else { (*p)->unloadPlugin(); - delete *p; + if (deletePlugin) + delete *p; } } - _plugins[type].clear(); + _pluginsInMem[type].clear(); if (found != NULL) { - _plugins[type].push_back(found); + _pluginsInMem[type].push_back(found); } } +/* + * Used only by the cached plugin manager since it deletes the plugin. + */ bool PluginManager::tryLoadPlugin(Plugin *plugin) { assert(plugin); // Try to load the plugin if (plugin->loadPlugin()) { - // The plugin is valid, see if it provides the same module as an - // already loaded one and should replace it. - bool found = false; - - PluginList::iterator pl = _plugins[plugin->getType()].begin(); - while (!found && pl != _plugins[plugin->getType()].end()) { - if (!strcmp(plugin->getName(), (*pl)->getName())) { - // Found a duplicated module. Replace the old one. - found = true; - delete *pl; - *pl = plugin; - debug(1, "Replaced the duplicated plugin: '%s'", plugin->getName()); - } - pl++; - } - - if (!found) { - // If it provides a new module, just add it to the list of known plugins. - _plugins[plugin->getType()].push_back(plugin); - } - + addToPluginsInMemList(plugin); return true; } else { // Failed to load the plugin @@ -253,14 +419,82 @@ bool PluginManager::tryLoadPlugin(Plugin *plugin) { } } +/** + * Add to the list of plugins loaded in memory. + */ +void PluginManager::addToPluginsInMemList(Plugin *plugin) { + bool found = false; + // The plugin is valid, see if it provides the same module as an + // already loaded one and should replace it. + + PluginList::iterator pl = _pluginsInMem[plugin->getType()].begin(); + while (!found && pl != _pluginsInMem[plugin->getType()].end()) { + if (!strcmp(plugin->getName(), (*pl)->getName())) { + // Found a duplicated module. Replace the old one. + found = true; + delete *pl; + *pl = plugin; + debug(1, "Replaced the duplicated plugin: '%s'", plugin->getName()); + } + pl++; + } + + if (!found) { + // If it provides a new module, just add it to the list of known plugins in memory. + _pluginsInMem[plugin->getType()].push_back(plugin); + } +} // Engine plugins #include "engines/metaengine.h" -DECLARE_SINGLETON(EngineManager) +DECLARE_SINGLETON(EngineManager); +/** + * This function works for both cached and uncached PluginManagers. + * For the cached version, most of the logic here will short circuit. + * + * For the uncached version, we first try to find the plugin using the gameId + * and only if we can't find it there, we loop through the plugins. + **/ GameDescriptor EngineManager::findGame(const Common::String &gameName, const EnginePlugin **plugin) const { + GameDescriptor result; + + // First look for the game using the plugins in memory. This is critical + // for calls coming from inside games + result = findGameInLoadedPlugins(gameName, plugin); + if (!result.gameid().empty()) { + return result; + } + + // Now look for the game using the gameId. This is much faster than scanning plugin + // by plugin + if (PluginMan.loadPluginFromGameId(gameName)) { + result = findGameInLoadedPlugins(gameName, plugin); + if (!result.gameid().empty()) { + return result; + } + } + + // We failed to find it using the gameid. Scan the list of plugins + PluginMan.loadFirstPlugin(); + do { + result = findGameInLoadedPlugins(gameName, plugin); + if (!result.gameid().empty()) { + // Update with new plugin file name + PluginMan.updateConfigWithFileName(gameName); + break; + } + } while (PluginMan.loadNextPlugin()); + + return result; +} + +/** + * Find the game within the plugins loaded in memory + **/ +GameDescriptor EngineManager::findGameInLoadedPlugins(const Common::String &gameName, const EnginePlugin **plugin) const { // Find the GameDescriptor for this target const EnginePlugin::List &plugins = getPlugins(); GameDescriptor result; @@ -268,13 +502,14 @@ GameDescriptor EngineManager::findGame(const Common::String &gameName, const Eng if (plugin) *plugin = 0; - EnginePlugin::List::const_iterator iter = plugins.begin(); + EnginePlugin::List::const_iterator iter; + for (iter = plugins.begin(); iter != plugins.end(); ++iter) { result = (**iter)->findGame(gameName.c_str()); if (!result.gameid().empty()) { if (plugin) *plugin = *iter; - break; + return result; } } return result; @@ -282,16 +517,17 @@ GameDescriptor EngineManager::findGame(const Common::String &gameName, const Eng GameList EngineManager::detectGames(const Common::FSList &fslist) const { GameList candidates; - - const EnginePlugin::List &plugins = getPlugins(); - - // Iterate over all known games and for each check if it might be - // the game in the presented directory. + EnginePlugin::List plugins; EnginePlugin::List::const_iterator iter; - for (iter = plugins.begin(); iter != plugins.end(); ++iter) { - candidates.push_back((**iter)->detectGames(fslist)); - } - + PluginManager::instance().loadFirstPlugin(); + do { + plugins = getPlugins(); + // Iterate over all known games and for each check if it might be + // the game in the presented directory. + for (iter = plugins.begin(); iter != plugins.end(); ++iter) { + candidates.push_back((**iter)->detectGames(fslist)); + } + } while (PluginManager::instance().loadNextPlugin()); return candidates; } @@ -302,9 +538,9 @@ const EnginePlugin::List &EngineManager::getPlugins() const { // Music plugins -#include "sound/musicplugin.h" +#include "audio/musicplugin.h" -DECLARE_SINGLETON(MusicManager) +DECLARE_SINGLETON(MusicManager); const MusicPlugin::List &MusicManager::getPlugins() const { return (const MusicPlugin::List &)PluginManager::instance().getPlugins(PLUGIN_TYPE_MUSIC); diff --git a/base/plugins.h b/base/plugins.h index b392d4e19f0..b4cced35968 100644 --- a/base/plugins.h +++ b/base/plugins.h @@ -30,6 +30,7 @@ #include "common/error.h" #include "common/singleton.h" #include "common/util.h" +//#include "backends/plugins/elf/version.h" namespace Common { class FSList; @@ -72,7 +73,7 @@ enum PluginType { }; // TODO: Make the engine API version depend on ScummVM's version -// because of the backlinking (posibly from the SVN revision) +// because of the backlinking (posibly from the checkout revision) #define PLUGIN_TYPE_ENGINE_VERSION 1 #define PLUGIN_TYPE_MUSIC_VERSION 1 @@ -90,6 +91,21 @@ extern int pluginTypeVersions[PLUGIN_TYPE_MAX]; #define PLUGIN_ENABLED_DYNAMIC(ID) \ (ENABLE_##ID && (ENABLE_##ID == DYNAMIC_PLUGIN) && DYNAMIC_MODULES) +// see comments in backends/plugins/elf/elf-provider.cpp +#if defined(USE_ELF_LOADER) && defined(ELF_LOADER_CXA_ATEXIT) +#define PLUGIN_DYNAMIC_DSO_HANDLE \ + uint32 __dso_handle __attribute__((visibility("hidden"))) = 0; +#else +#define PLUGIN_DYNAMIC_DSO_HANDLE +#endif + +#ifdef USE_ELF_LOADER +#define PLUGIN_DYNAMIC_BUILD_DATE \ + PLUGIN_EXPORT const char *PLUGIN_getBuildDate() { return gResidualPluginBuildDate; } +#else +#define PLUGIN_DYNAMIC_BUILD_DATE +#endif + /** * REGISTER_PLUGIN_STATIC is a convenience macro which is used to declare * the plugin interface for static plugins. Code (such as game engines) @@ -119,6 +135,8 @@ extern int pluginTypeVersions[PLUGIN_TYPE_MAX]; */ #define REGISTER_PLUGIN_DYNAMIC(ID,TYPE,PLUGINCLASS) \ extern "C" { \ + PLUGIN_DYNAMIC_DSO_HANDLE \ + PLUGIN_DYNAMIC_BUILD_DATE \ PLUGIN_EXPORT int32 PLUGIN_getVersion() { return PLUGIN_VERSION; } \ PLUGIN_EXPORT int32 PLUGIN_getType() { return TYPE; } \ PLUGIN_EXPORT int32 PLUGIN_getTypeVersion() { return TYPE##_VERSION; } \ @@ -134,11 +152,11 @@ extern int pluginTypeVersions[PLUGIN_TYPE_MAX]; // Abstract plugins /** - * Abstract base class for the plugin objects which handle plugins - * instantiation. Subclasses for this may be used for engine plugins - * and other types of plugins. - * - * FIXME: This class needs better documentation, esp. how it differs from class Plugin + * Abstract base class for the plugin objects which handle plugins + * instantiation. Subclasses for this may be used for engine plugins and other + * types of plugins. An existing PluginObject refers to an executable file + * loaded in memory and ready to run. The plugin, on the other hand, is just + * a handle to the file/object, whether it's loaded in memory or not. */ class PluginObject { public: @@ -151,9 +169,8 @@ public: /** * Abstract base class for the plugin system. * Subclasses for this can be used to wrap both static and dynamic - * plugins. - * - * FIXME: This class needs better documentation, esp. how it differs from class PluginObject + * plugins. This class refers to a plugin which may or may not be loaded in + * memory. */ class Plugin { protected: @@ -171,8 +188,19 @@ public: virtual bool loadPlugin() = 0; // TODO: Rename to load() ? virtual void unloadPlugin() = 0; // TODO: Rename to unload() ? + /** + * The following functions query information from the plugin object once + * it's loaded into memory. + **/ PluginType getType() const; const char *getName() const; + + /** + * The getFileName() function gets the name of the plugin file for those + * plugins that have files (ie. not static). It doesn't require the plugin + * object to be loaded into memory, unlike getName() + **/ + virtual const char *getFileName() const { return 0; } }; /** List of Plugin instances. */ @@ -212,6 +240,11 @@ public: * @return a list of Plugin instances */ virtual PluginList getPlugins() = 0; + + /** + * @return whether or not object is a FilePluginProvider. + */ + virtual bool isFilePluginProvider() { return false; } }; #ifdef DYNAMIC_MODULES @@ -234,6 +267,11 @@ public: */ virtual PluginList getPlugins(); + /** + * @return whether or not object is a FilePluginProvider. + */ + bool isFilePluginProvider() { return true; } + protected: /** * Create a Plugin instance from a loadable code module with the specified name. @@ -266,31 +304,70 @@ protected: #endif // DYNAMIC_MODULES +#define PluginMan PluginManager::instance() + /** * Singleton class which manages all plugins, including loading them, * managing all Plugin class instances, and unloading them. */ -class PluginManager : public Common::Singleton { +class PluginManager { +protected: typedef Common::Array ProviderList; -private: - PluginList _plugins[PLUGIN_TYPE_MAX]; + + PluginList _pluginsInMem[PLUGIN_TYPE_MAX]; ProviderList _providers; bool tryLoadPlugin(Plugin *plugin); - - friend class Common::Singleton; + void addToPluginsInMemList(Plugin *plugin); + + static PluginManager *_instance; PluginManager(); public: - ~PluginManager(); + virtual ~PluginManager(); + + static void destroy() { delete _instance; _instance = 0; } + static PluginManager &instance(); void addPluginProvider(PluginProvider *pp); - void loadPlugins(); - void unloadPlugins(); - void unloadPluginsExcept(PluginType type, const Plugin *plugin); + // Functions used by the uncached PluginManager + virtual void init() {} + virtual void loadFirstPlugin() {} + virtual bool loadNextPlugin() { return false; } + virtual bool loadPluginFromGameId(const Common::String &gameId) { return false; } + virtual void updateConfigWithFileName(const Common::String &gameId) {} + + // Functions used only by the cached PluginManager + virtual void loadAllPlugins(); + void unloadAllPlugins(); - const PluginList &getPlugins(PluginType t) { return _plugins[t]; } + void unloadPluginsExcept(PluginType type, const Plugin *plugin, bool deletePlugin = true); + + const PluginList &getPlugins(PluginType t) { return _pluginsInMem[t]; } +}; + +/** + * Uncached version of plugin manager + * Keeps only one dynamic plugin in memory at a time + **/ +class PluginManagerUncached : public PluginManager { +protected: + friend class PluginManager; + PluginList _allEnginePlugins; + PluginList::iterator _currentPlugin; + + PluginManagerUncached() {} + bool loadPluginByFileName(const Common::String &filename); + +public: + virtual void init(); + virtual void loadFirstPlugin(); + virtual bool loadNextPlugin(); + virtual bool loadPluginFromGameId(const Common::String &gameId); + virtual void updateConfigWithFileName(const Common::String &gameId); + + virtual void loadAllPlugins() {} // we don't allow this }; #endif diff --git a/base/version.cpp b/base/version.cpp index 7cb49b84da4..a8da01a2fa6 100644 --- a/base/version.cpp +++ b/base/version.cpp @@ -92,6 +92,10 @@ const char *gResidualFeatures = "" "SEQ " #endif +#ifdef USE_TIMIDITY + "TiMidity " +#endif + #ifdef USE_RGB_COLOR "RGB " #endif @@ -107,5 +111,9 @@ const char *gResidualFeatures = "" #ifdef USE_FLUIDSYNTH "FluidSynth " #endif + +#ifdef USE_THEORADEC + "Theora " +#endif ; diff --git a/common/EventRecorder.cpp b/common/EventRecorder.cpp index 1bbe403ae69..2c521be036d 100644 --- a/common/EventRecorder.cpp +++ b/common/EventRecorder.cpp @@ -27,33 +27,34 @@ #include "common/config-manager.h" #include "common/random.h" +#include "common/savefile.h" -DECLARE_SINGLETON(Common::EventRecorder) +DECLARE_SINGLETON(Common::EventRecorder); namespace Common { #define RECORD_SIGNATURE 0x54455354 #define RECORD_VERSION 1 -void readRecord(Common::InSaveFile *inFile, uint32 &diff, Common::Event &event) { +void readRecord(SeekableReadStream *inFile, uint32 &diff, Event &event) { diff = inFile->readUint32LE(); - event.type = (Common::EventType)inFile->readUint32LE(); + event.type = (EventType)inFile->readUint32LE(); switch (event.type) { - case Common::EVENT_KEYDOWN: - case Common::EVENT_KEYUP: - event.kbd.keycode = (Common::KeyCode)inFile->readSint32LE(); + case EVENT_KEYDOWN: + case EVENT_KEYUP: + event.kbd.keycode = (KeyCode)inFile->readSint32LE(); event.kbd.ascii = inFile->readUint16LE(); event.kbd.flags = inFile->readByte(); break; - case Common::EVENT_MOUSEMOVE: - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_LBUTTONUP: - case Common::EVENT_RBUTTONDOWN: - case Common::EVENT_RBUTTONUP: - case Common::EVENT_WHEELUP: - case Common::EVENT_WHEELDOWN: + case EVENT_MOUSEMOVE: + case EVENT_LBUTTONDOWN: + case EVENT_LBUTTONUP: + case EVENT_RBUTTONDOWN: + case EVENT_RBUTTONUP: + case EVENT_WHEELUP: + case EVENT_WHEELDOWN: event.mouse.x = inFile->readSint16LE(); event.mouse.y = inFile->readSint16LE(); break; @@ -62,25 +63,25 @@ void readRecord(Common::InSaveFile *inFile, uint32 &diff, Common::Event &event) } } -void writeRecord(Common::OutSaveFile *outFile, uint32 diff, const Common::Event &event) { +void writeRecord(WriteStream *outFile, uint32 diff, const Event &event) { outFile->writeUint32LE(diff); outFile->writeUint32LE((uint32)event.type); switch (event.type) { - case Common::EVENT_KEYDOWN: - case Common::EVENT_KEYUP: + case EVENT_KEYDOWN: + case EVENT_KEYUP: outFile->writeSint32LE(event.kbd.keycode); outFile->writeUint16LE(event.kbd.ascii); outFile->writeByte(event.kbd.flags); break; - case Common::EVENT_MOUSEMOVE: - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_LBUTTONUP: - case Common::EVENT_RBUTTONDOWN: - case Common::EVENT_RBUTTONUP: - case Common::EVENT_WHEELUP: - case Common::EVENT_WHEELDOWN: + case EVENT_MOUSEMOVE: + case EVENT_LBUTTONDOWN: + case EVENT_LBUTTONUP: + case EVENT_RBUTTONDOWN: + case EVENT_RBUTTONUP: + case EVENT_WHEELUP: + case EVENT_WHEELDOWN: outFile->writeSint16LE(event.mouse.x); outFile->writeSint16LE(event.mouse.y); break; @@ -109,7 +110,7 @@ EventRecorder::~EventRecorder() { } void EventRecorder::init() { - Common::String recordModeString = ConfMan.get("record_mode"); + String recordModeString = ConfMan.get("record_mode"); if (recordModeString.compareToIgnoreCase("record") == 0) { _recordMode = kRecorderRecord; } else { @@ -143,7 +144,6 @@ void EventRecorder::init() { } uint32 sign; - uint32 version; uint32 randomSourceCount; if (_recordMode == kRecorderPlayback) { _playbackCount = 0; @@ -167,7 +167,8 @@ void EventRecorder::init() { if (sign != RECORD_SIGNATURE) { error("Unknown record file signature"); } - version = _playbackFile->readUint32LE(); + + _playbackFile->readUint32LE(); // version // conf vars ConfMan.setBool("subtitles", _playbackFile->readByte() != 0); @@ -236,7 +237,7 @@ void EventRecorder::deinit() { for (uint i = 0; i < _recordCount; ++i) { uint32 tempDiff; - Common::Event tempEvent; + Event tempEvent; readRecord(_playbackFile, tempDiff, tempEvent); writeRecord(_recordFile, tempDiff, tempEvent); } @@ -252,7 +253,7 @@ void EventRecorder::deinit() { g_system->deleteMutex(_recorderMutex); } -void EventRecorder::registerRandomSource(Common::RandomSource &rnd, const char *name) { +void EventRecorder::registerRandomSource(RandomSource &rnd, const char *name) { if (_recordMode == kRecorderRecord) { RandomSourceRecord rec; rec.name = name; @@ -305,11 +306,11 @@ void EventRecorder::processMillis(uint32 &millis) { g_system->unlockMutex(_timeMutex); } -bool EventRecorder::notifyEvent(const Common::Event &ev) { +bool EventRecorder::notifyEvent(const Event &ev) { if (_recordMode != kRecorderRecord) return false; - Common::StackLock lock(_recorderMutex); + StackLock lock(_recorderMutex); ++_eventCount; writeRecord(_recordFile, _eventCount - _lastEventCount, ev); @@ -320,11 +321,11 @@ bool EventRecorder::notifyEvent(const Common::Event &ev) { return false; } -bool EventRecorder::pollEvent(Common::Event &ev) { +bool EventRecorder::pollEvent(Event &ev) { if (_recordMode != kRecorderPlayback) return false; - Common::StackLock lock(_recorderMutex); + StackLock lock(_recorderMutex); ++_eventCount; if (!_hasPlaybackEvent) { @@ -338,13 +339,13 @@ bool EventRecorder::pollEvent(Common::Event &ev) { if (_hasPlaybackEvent) { if (_playbackDiff <= (_eventCount - _lastEventCount)) { switch (_playbackEvent.type) { - case Common::EVENT_MOUSEMOVE: - case Common::EVENT_LBUTTONDOWN: - case Common::EVENT_LBUTTONUP: - case Common::EVENT_RBUTTONDOWN: - case Common::EVENT_RBUTTONUP: - case Common::EVENT_WHEELUP: - case Common::EVENT_WHEELDOWN: + case EVENT_MOUSEMOVE: + case EVENT_LBUTTONDOWN: + case EVENT_LBUTTONUP: + case EVENT_RBUTTONDOWN: + case EVENT_RBUTTONUP: + case EVENT_WHEELUP: + case EVENT_WHEELDOWN: g_system->warpMouse(_playbackEvent.mouse.x, _playbackEvent.mouse.y); break; default: diff --git a/common/EventRecorder.h b/common/EventRecorder.h index cc05307079d..3691de29cb5 100644 --- a/common/EventRecorder.h +++ b/common/EventRecorder.h @@ -29,7 +29,6 @@ #include "common/sys.h" #include "common/events.h" #include "common/singleton.h" -#include "common/savefile.h" #include "common/mutex.h" #include "common/array.h" @@ -38,6 +37,8 @@ namespace Common { class RandomSource; +class SeekableReadStream; +class WriteStream; /** * Our generic event recorder. @@ -45,7 +46,7 @@ class RandomSource; * TODO: Add more documentation. */ class EventRecorder : private EventSource, private EventObserver, public Singleton { - friend class Common::Singleton; + friend class Singleton; EventRecorder(); ~EventRecorder(); public: @@ -53,40 +54,40 @@ public: void deinit(); /** Register random source so it can be serialized in game test purposes */ - void registerRandomSource(Common::RandomSource &rnd, const char *name); + void registerRandomSource(RandomSource &rnd, const char *name); /** TODO: Add documentation, this is only used by the backend */ void processMillis(uint32 &millis); private: - bool notifyEvent(const Common::Event &ev); - bool pollEvent(Common::Event &ev); + bool notifyEvent(const Event &ev); + bool pollEvent(Event &ev); bool allowMapping() const { return false; } class RandomSourceRecord { public: - Common::String name; + String name; uint32 seed; }; - Common::Array _randomSourceRecords; + Array _randomSourceRecords; bool _recordSubtitles; volatile uint32 _recordCount; volatile uint32 _lastRecordEvent; volatile uint32 _recordTimeCount; - Common::OutSaveFile *_recordFile; - Common::OutSaveFile *_recordTimeFile; - Common::MutexRef _timeMutex; - Common::MutexRef _recorderMutex; + WriteStream *_recordFile; + WriteStream *_recordTimeFile; + MutexRef _timeMutex; + MutexRef _recorderMutex; volatile uint32 _lastMillis; volatile uint32 _playbackCount; volatile uint32 _playbackDiff; volatile bool _hasPlaybackEvent; volatile uint32 _playbackTimeCount; - Common::Event _playbackEvent; - Common::InSaveFile *_playbackFile; - Common::InSaveFile *_playbackTimeFile; + Event _playbackEvent; + SeekableReadStream *_playbackFile; + SeekableReadStream *_playbackTimeFile; volatile uint32 _eventCount; volatile uint32 _lastEventCount; @@ -97,9 +98,9 @@ private: kRecorderPlayback = 2 }; volatile RecordMode _recordMode; - Common::String _recordFileName; - Common::String _recordTempFileName; - Common::String _recordTimeFileName; + String _recordFileName; + String _recordTempFileName; + String _recordTimeFileName; }; } // End of namespace Common diff --git a/common/algorithm.h b/common/algorithm.h index a3c3ad2d0f2..109bcc421b1 100644 --- a/common/algorithm.h +++ b/common/algorithm.h @@ -242,13 +242,20 @@ void sort(T first, T last) { */ template T gcd(T a, T b) { - if (a <= 0) a = -a; - if (b <= 0) b = -b; + // Note: We check for <= instead of < to avoid spurious compiler + // warnings if T is an unsigned type, i.e. warnings like "comparison + // of unsigned expression < 0 is always false". + if (a <= 0) + a = -a; + if (b <= 0) + b = -b; + while (a > 0) { T tmp = a; a = b % a; b = tmp; } + return b; } diff --git a/common/archive.cpp b/common/archive.cpp index b2643fd3cb6..164e78674c8 100644 --- a/common/archive.cpp +++ b/common/archive.cpp @@ -290,5 +290,5 @@ void SearchManager::clear() { } // namespace Common -DECLARE_SINGLETON(Common::SearchManager) +DECLARE_SINGLETON(Common::SearchManager); diff --git a/common/array.h b/common/array.h index ab96165f04d..0fb5d055118 100644 --- a/common/array.h +++ b/common/array.h @@ -150,7 +150,7 @@ public: insert_aux(_storage + idx, &element, &element + 1); } - void insert_at(int idx, const Array &array) { + void insert_at(int idx, const Array &array) { assert(idx >= 0 && (uint)idx <= _size); insert_aux(_storage + idx, array.begin(), array.end()); } diff --git a/common/bufferedstream.h b/common/bufferedstream.h new file mode 100644 index 00000000000..16412a568f9 --- /dev/null +++ b/common/bufferedstream.h @@ -0,0 +1,68 @@ +/* Residual - A 3D game interpreter + * + * 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 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_BUFFEREDSTREAM_H +#define COMMON_BUFFEREDSTREAM_H + +#include "common/stream.h" + +namespace Common { + +/** + * Take an arbitrary ReadStream and wrap it in a custom stream which + * transparently provides buffering. + * Users can specify how big the buffer should be, and whether the wrapped + * stream should be disposed when the wrapper is disposed. + * + * It is safe to call this with a NULL parameter (in this case, NULL is + * returned). + */ +ReadStream *wrapBufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream); + +/** + * Take an arbitrary SeekableReadStream and wrap it in a custom stream which + * transparently provides buffering. + * Users can specify how big the buffer should be, and whether the wrapped + * stream should be disposed when the wrapper is disposed. + * + * It is safe to call this with a NULL parameter (in this case, NULL is + * returned). + */ +SeekableReadStream *wrapBufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream); + +/** + * Take an arbitrary WriteStream and wrap it in a custom stream which + * transparently provides buffering. + * Users can specify how big the buffer should be. Currently, the + * parent stream is \em always disposed when the wrapper is disposed. + * + * It is safe to call this with a NULL parameter (in this case, NULL is + * returned). + */ +WriteStream *wrapBufferedWriteStream(WriteStream *parentStream, uint32 bufSize); + +} // End of namespace Common + +#endif diff --git a/common/config-file.cpp b/common/config-file.cpp index f77370577ac..14956c034f7 100644 --- a/common/config-file.cpp +++ b/common/config-file.cpp @@ -95,11 +95,11 @@ bool ConfigFile::loadFromStream(SeekableReadStream &stream) { if (line.size() == 0) { // Do nothing - } else if (line[0] == '#') { + } else if (line[0] == '#' || line[0] == ';' || line.hasPrefix("//")) { // Accumulate comments here. Once we encounter either the start // of a new section, or a key-value-pair, we associate the value - // of the 'comment' variable with that entity. The semicolon - // comment is used for Living Books games in Mohawk. + // of the 'comment' variable with that entity. The semicolon and + // C++-style comments are used for Living Books games in Mohawk. comment += line; #ifdef _WIN32 comment += "\r\n"; diff --git a/common/config-manager.cpp b/common/config-manager.cpp index 7322d8ca894..1cd1c3338fe 100644 --- a/common/config-manager.cpp +++ b/common/config-manager.cpp @@ -29,7 +29,7 @@ #include "common/util.h" #include "common/system.h" -DECLARE_SINGLETON(Common::ConfigManager) +DECLARE_SINGLETON(Common::ConfigManager); static bool isValidDomainName(const Common::String &domName) { const char *p = domName.c_str(); @@ -53,12 +53,34 @@ const char *ConfigManager::kKeymapperDomain = "keymapper"; ConfigManager::ConfigManager() : _activeDomain(0) { } +void ConfigManager::defragment() { + ConfigManager *newInstance = new ConfigManager(); + newInstance->copyFrom(*_singleton); + delete _singleton; + _singleton = newInstance; +} + +void ConfigManager::copyFrom(ConfigManager &source) { + _transientDomain = source._transientDomain; + _gameDomains = source._gameDomains; + _miscDomains = source._miscDomains; + _appDomain = source._appDomain; + _defaultsDomain = source._defaultsDomain; +#ifdef ENABLE_KEYMAPPER + _keymapperDomain = source._keymapperDomain; +#endif + _domainSaveOrder = source._domainSaveOrder; + _activeDomainName = source._activeDomainName; + _activeDomain = &_gameDomains[_activeDomainName]; + _filename = source._filename; +} + void ConfigManager::loadDefaultConfigFile() { // Open the default config file assert(g_system); SeekableReadStream *stream = g_system->createConfigReadStream(); - _filename.clear(); // clear the filename to indicate that we are using the default config file + _filename.clear(); // clear the filename to indicate that we are using the default config file // ... load it, if available ... if (stream) { @@ -69,7 +91,7 @@ void ConfigManager::loadDefaultConfigFile() { } else { // No config file -> create new one! - printf("Default configuration file missing, creating a new one\n"); + debug("Default configuration file missing, creating a new one"); flushToDisk(); } @@ -81,20 +103,59 @@ void ConfigManager::loadConfigFile(const String &filename) { FSNode node(filename); File cfg_file; if (!cfg_file.open(node)) { - printf("Creating configuration file: %s\n", filename.c_str()); + debug("Creating configuration file: %s", filename.c_str()); } else { - printf("Using configuration file: %s\n", _filename.c_str()); + debug("Using configuration file: %s", _filename.c_str()); loadFromStream(cfg_file); } } +/** + * Add a ready-made domain based on its name and contents + * The domain name should not already exist in the ConfigManager. + **/ +void ConfigManager::addDomain(const Common::String &domainName, const ConfigManager::Domain &domain) { + if (domainName.empty()) + return; + if (domainName == kApplicationDomain) { + _appDomain = domain; +#ifdef ENABLE_KEYMAPPER + } else if (domainName == kKeymapperDomain) { + _keymapperDomain = domain; +#endif + } else if (domain.contains("gameid")) { + // If the domain contains "gameid" we assume it's a game domain + if (_gameDomains.contains(domainName)) + warning("Game domain %s already exists in ConfigManager", domainName.c_str()); + + _gameDomains[domainName] = domain; + + _domainSaveOrder.push_back(domainName); + + // Check if we have the same misc domain. For older config files + // we could have 'ghost' domains with the same name, so delete + // the ghost domain + if (_miscDomains.contains(domainName)) + _miscDomains.erase(domainName); + } else { + // Otherwise it's a miscellaneous domain + if (_miscDomains.contains(domainName)) + warning("Misc domain %s already exists in ConfigManager", domainName.c_str()); + + _miscDomains[domainName] = domain; + } +} + + void ConfigManager::loadFromStream(SeekableReadStream &stream) { - String domain; + String domainName; String comment; + Domain domain; int lineno = 0; _appDomain.clear(); _gameDomains.clear(); + _miscDomains.clear(); _transientDomain.clear(); _domainSaveOrder.clear(); @@ -125,6 +186,9 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) { #endif } else if (line[0] == '[') { // It's a new domain which begins here. + // Determine where the previously accumulated domain goes, if we accumulated anything. + addDomain(domainName, domain); + domain.clear(); const char *p = line.c_str() + 1; // Get the domain name, and check whether it's valid (that // is, verify that it only consists of alphanumerics, @@ -137,21 +201,11 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) { else if (*p != ']') error("Config file buggy: Invalid character '%c' occurred in section name in line %d", *p, lineno); - domain = String(line.c_str() + 1, p); + domainName = String(line.c_str() + 1, p); - // Store domain comment - if (domain == kApplicationDomain) { - _appDomain.setDomainComment(comment); -#ifdef ENABLE_KEYMAPPER - } else if (domain == kKeymapperDomain) { - _keymapperDomain.setDomainComment(comment); -#endif - } else { - _gameDomains[domain].setDomainComment(comment); - } + domain.setDomainComment(comment); comment.clear(); - _domainSaveOrder.push_back(domain); } else { // This line should be a line with a 'key=value' pair, or an empty one. @@ -165,7 +219,7 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) { continue; // If no domain has been set, this config file is invalid! - if (domain.empty()) { + if (domainName.empty()) { error("Config file buggy: Key/value pair found outside a domain in line %d", lineno); } @@ -183,21 +237,15 @@ void ConfigManager::loadFromStream(SeekableReadStream &stream) { value.trim(); // Finally, store the key/value pair in the active domain - set(key, value, domain); + domain[key] = value; // Store comment - if (domain == kApplicationDomain) { - _appDomain.setKVComment(key, comment); -#ifdef ENABLE_KEYMAPPER - } else if (domain == kKeymapperDomain) { - _keymapperDomain.setKVComment(key, comment); -#endif - } else { - _gameDomains[domain].setKVComment(key, comment); - } + domain.setKVComment(key, comment); comment.clear(); } } + + addDomain(domainName, domain); // Add the last domain found } void ConfigManager::flushToDisk() { @@ -208,7 +256,7 @@ void ConfigManager::flushToDisk() { // Write to the default config file assert(g_system); stream = g_system->createConfigWriteStream(); - if (!stream) // If writing to the config file is not possible, do nothing + if (!stream) // If writing to the config file is not possible, do nothing return; } else { DumpFile *dump = new DumpFile(); @@ -231,6 +279,13 @@ void ConfigManager::flushToDisk() { writeDomain(*stream, kKeymapperDomain, _keymapperDomain); #endif + DomainMap::const_iterator d; + + // Write the miscellaneous domains next + for (d = _miscDomains.begin(); d != _miscDomains.end(); ++d) { + writeDomain(*stream, d->_key, d->_value); + } + // First write the domains in _domainSaveOrder, in that order. // Note: It's possible for _domainSaveOrder to list domains which // are not present anymore, so we validate each name. @@ -241,8 +296,6 @@ void ConfigManager::flushToDisk() { } } - DomainMap::const_iterator d; - // Now write the domains which haven't been written yet for (d = _gameDomains.begin(); d != _gameDomains.end(); ++d) { if (find(_domainSaveOrder.begin(), _domainSaveOrder.end(), d->_key) == _domainSaveOrder.end()) @@ -256,7 +309,7 @@ void ConfigManager::flushToDisk() { void ConfigManager::writeDomain(WriteStream &stream, const String &name, const Domain &domain) { if (domain.empty()) - return; // Don't bother writing empty domains. + return; // Don't bother writing empty domains. // WORKAROUND: Fix for bug #1972625 "ALL: On-the-fly targets are // written to the config file": Do not save domains that came from @@ -329,6 +382,8 @@ const ConfigManager::Domain *ConfigManager::getDomain(const String &domName) con #endif if (_gameDomains.contains(domName)) return &_gameDomains[domName]; + if (_miscDomains.contains(domName)) + return &_miscDomains[domName]; return 0; } @@ -347,6 +402,8 @@ ConfigManager::Domain *ConfigManager::getDomain(const String &domName) { #endif if (_gameDomains.contains(domName)) return &_gameDomains[domName]; + if (_miscDomains.contains(domName)) + return &_miscDomains[domName]; return 0; } @@ -393,7 +450,7 @@ void ConfigManager::removeKey(const String &key, const String &domName) { if (!domain) error("ConfigManager::removeKey(%s, %s) called on non-existent domain", - key.c_str(), domName.c_str()); + key.c_str(), domName.c_str()); domain->erase(key); } @@ -402,7 +459,7 @@ void ConfigManager::removeKey(const String &key, const String &domName) { #pragma mark - -const String & ConfigManager::get(const String &key) const { +const String &ConfigManager::get(const String &key) const { if (_transientDomain.contains(key)) return _transientDomain[key]; else if (_activeDomain && _activeDomain->contains(key)) @@ -413,7 +470,7 @@ const String & ConfigManager::get(const String &key) const { return _defaultsDomain.getVal(key); } -const String & ConfigManager::get(const String &key, const String &domName) const { +const String &ConfigManager::get(const String &key, const String &domName) const { // FIXME: For now we continue to allow empty domName to indicate // "use 'default' domain". This is mainly needed for the SCUMM ConfigDialog // and should be removed ASAP. @@ -424,7 +481,7 @@ const String & ConfigManager::get(const String &key, const String &domName) cons if (!domain) error("ConfigManager::get(%s,%s) called on non-existent domain", - key.c_str(), domName.c_str()); + key.c_str(), domName.c_str()); if (domain->contains(key)) return (*domain)[key]; @@ -448,7 +505,7 @@ int ConfigManager::getInt(const String &key, const String &domName) const { int ivalue = (int)strtol(value.c_str(), &errpos, 0); if (value.c_str() == errpos) error("ConfigManager::getInt(%s,%s): '%s' is not a valid integer", - key.c_str(), domName.c_str(), errpos); + key.c_str(), domName.c_str(), errpos); return ivalue; } @@ -462,7 +519,7 @@ bool ConfigManager::getBool(const String &key, const String &domName) const { return false; error("ConfigManager::getBool(%s,%s): '%s' is not a valid bool", - key.c_str(), domName.c_str(), value.c_str()); + key.c_str(), domName.c_str(), value.c_str()); } @@ -494,7 +551,7 @@ void ConfigManager::set(const String &key, const String &value, const String &do if (!domain) error("ConfigManager::set(%s,%s,%s) called on non-existent domain", - key.c_str(), value.c_str(), domName.c_str()); + key.c_str(), value.c_str(), domName.c_str()); (*domain)[key] = value; @@ -509,7 +566,7 @@ void ConfigManager::set(const String &key, const String &value, const String &do // But doing this here seems rather evil... need to comb the options dialog // code to find out if it's still necessary, and if that's the case, how // to replace it in a clean fashion... -/* +#if 0 if (domName == kTransientDomain) _transientDomain[key] = value; else { @@ -523,13 +580,11 @@ void ConfigManager::set(const String &key, const String &value, const String &do _transientDomain.erase(key); } } -*/ +#endif } void ConfigManager::setInt(const String &key, int value, const String &domName) { - char tmp[128]; - snprintf(tmp, sizeof(tmp), "%i", value); - set(key, String(tmp), domName); + set(key, String::format("%i", value), domName); } void ConfigManager::setBool(const String &key, bool value, const String &domName) { @@ -549,9 +604,7 @@ void ConfigManager::registerDefault(const String &key, const char *value) { } void ConfigManager::registerDefault(const String &key, int value) { - char tmp[128]; - snprintf(tmp, sizeof(tmp), "%i", value); - registerDefault(key, tmp); + registerDefault(key, String::format("%i", value)); } void ConfigManager::registerDefault(const String &key, bool value) { @@ -586,13 +639,38 @@ void ConfigManager::addGameDomain(const String &domName) { _domainSaveOrder.push_back(domName); } +void ConfigManager::addMiscDomain(const String &domName) { + assert(!domName.empty()); + assert(isValidDomainName(domName)); + + _miscDomains[domName]; +} + void ConfigManager::removeGameDomain(const String &domName) { assert(!domName.empty()); assert(isValidDomainName(domName)); _gameDomains.erase(domName); } +void ConfigManager::removeMiscDomain(const String &domName) { + assert(!domName.empty()); + assert(isValidDomainName(domName)); + _miscDomains.erase(domName); +} + + void ConfigManager::renameGameDomain(const String &oldName, const String &newName) { + renameDomain(oldName, newName, _gameDomains); +} + +void ConfigManager::renameMiscDomain(const String &oldName, const String &newName) { + renameDomain(oldName, newName, _miscDomains); +} + +/** + * Common private function to rename both game and misc domains + **/ +void ConfigManager::renameDomain(const String &oldName, const String &newName, DomainMap &map) { if (oldName == newName) return; @@ -602,13 +680,13 @@ void ConfigManager::renameGameDomain(const String &oldName, const String &newNam assert(isValidDomainName(newName)); // _gameDomains[newName].merge(_gameDomains[oldName]); - Domain &oldDom = _gameDomains[oldName]; - Domain &newDom = _gameDomains[newName]; + Domain &oldDom = map[oldName]; + Domain &newDom = map[newName]; Domain::const_iterator iter; for (iter = oldDom.begin(); iter != oldDom.end(); ++iter) newDom[iter->_key] = iter->_value; - _gameDomains.erase(oldName); + map.erase(oldName); } bool ConfigManager::hasGameDomain(const String &domName) const { @@ -616,10 +694,13 @@ bool ConfigManager::hasGameDomain(const String &domName) const { return isValidDomainName(domName) && _gameDomains.contains(domName); } +bool ConfigManager::hasMiscDomain(const String &domName) const { + assert(!domName.empty()); + return isValidDomainName(domName) && _miscDomains.contains(domName); +} #pragma mark - - void ConfigManager::Domain::setDomainComment(const String &comment) { _domainComment = comment; } @@ -637,4 +718,5 @@ bool ConfigManager::Domain::hasKVComment(const String &key) const { return _keyValueComments.contains(key); } -} // End of namespace Common +} // End of namespace Common + diff --git a/common/config-manager.h b/common/config-manager.h index 09adb5ada91..b0a776ea2f6 100644 --- a/common/config-manager.h +++ b/common/config-manager.h @@ -137,19 +137,32 @@ public: void addGameDomain(const String &domName); void removeGameDomain(const String &domName); void renameGameDomain(const String &oldName, const String &newName); + + void addMiscDomain(const String &domName); + void removeMiscDomain(const String &domName); + void renameMiscDomain(const String &oldName, const String &newName); + bool hasGameDomain(const String &domName) const; + bool hasMiscDomain(const String &domName) const; + const DomainMap & getGameDomains() const { return _gameDomains; } DomainMap & getGameDomains() { return _gameDomains; } + static void defragment(); // move in memory to reduce fragmentation + void copyFrom(ConfigManager &source); + private: friend class Singleton; ConfigManager(); void loadFromStream(SeekableReadStream &stream); + void addDomain(const Common::String &domainName, const Domain &domain); void writeDomain(WriteStream &stream, const String &name, const Domain &domain); + void renameDomain(const String &oldName, const String &newName, DomainMap &map); Domain _transientDomain; DomainMap _gameDomains; + DomainMap _miscDomains; // Any other domains Domain _appDomain; Domain _defaultsDomain; diff --git a/common/debug.cpp b/common/debug.cpp index 685d88a9320..9c2b5bc0d97 100644 --- a/common/debug.cpp +++ b/common/debug.cpp @@ -25,29 +25,14 @@ #include "common/debug.h" #include "common/debug-channels.h" #include "common/util.h" +#include "common/system.h" #include // For va_list etc. - -#ifdef __PLAYSTATION2__ - // for those replaced fopen/fread/etc functions - #include "backends/platform/ps2/fileio.h" - - #define fputs(str, file) ps2_fputs(str, file) - #define fflush(a) ps2_fflush(a) -#endif - -#ifdef __DS__ - #include "backends/fs/ds/ds-fs.h" - - #define fputs(str, file) DS::std_fwrite(str, strlen(str), 1, file) - #define fflush(file) DS::std_fflush(file) -#endif - // TODO: Move gDebugLevel into namespace Common. int gDebugLevel = -1; -DECLARE_SINGLETON(Common::DebugManager) +DECLARE_SINGLETON(Common::DebugManager); namespace Common { @@ -119,31 +104,15 @@ bool DebugManager::isDebugChannelEnabled(uint32 channel) { return (gDebugChannelsEnabled & channel) != 0; } - - -static OutputFormatter s_debugOutputFormatter = 0; - -void setDebugOutputFormatter(OutputFormatter f) { - s_debugOutputFormatter = f; -} - } // End of namespace Common #ifndef DISABLE_TEXT_CONSOLE static void debugHelper(const char *s, va_list va, bool caret = true) { - char in_buf[STRINGBUFLEN]; char buf[STRINGBUFLEN]; - vsnprintf(in_buf, STRINGBUFLEN, s, va); - // Next, give the active engine (if any) a chance to augment the message, - // but only if not used from debugN. - if (caret && Common::s_debugOutputFormatter) { - (*Common::s_debugOutputFormatter)(buf, in_buf, STRINGBUFLEN); - } else { - strncpy(buf, in_buf, STRINGBUFLEN); - } + vsnprintf(buf, STRINGBUFLEN, s, va); buf[STRINGBUFLEN-1] = '\0'; if (caret) { @@ -151,19 +120,10 @@ static void debugHelper(const char *s, va_list va, bool caret = true) { strcat(buf, "\n"); } - fputs(buf, stdout); - -#if defined( USE_WINDBG ) -#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); + if (g_system) + g_system->logMessage(LogMessageType::kDebug, buf); + // TODO: Think of a good fallback in case we do not have + // any OSystem yet. } void debug(const char *s, ...) { @@ -186,6 +146,14 @@ void debug(int level, const char *s, ...) { } +void debugN(const char *s, ...) { + va_list va; + + va_start(va, s); + debugHelper(s, va, false); + va_end(va); +} + void debugN(int level, const char *s, ...) { va_list va; diff --git a/common/debug.h b/common/debug.h index fd994bcff50..839357f62b6 100644 --- a/common/debug.h +++ b/common/debug.h @@ -26,23 +26,12 @@ #define COMMON_DEBUG_H #include "common/sys.h" -#include "common/textconsole.h" - -namespace Common { - -/** - * Set the output formatter used by debug() and related functions. - */ -void setDebugOutputFormatter(OutputFormatter f); - - -} // End of namespace Common - #ifdef DISABLE_TEXT_CONSOLE inline void debug(const char *s, ...) {} inline void debug(int level, const char *s, ...) {} +inline void debugN(const char *s, ...) {} inline void debugN(int level, const char *s, ...) {} inline void debugC(int level, uint32 engineChannel, const char *s, ...) {} inline void debugC(uint32 engineChannel, const char *s, ...) {} @@ -67,6 +56,12 @@ void debug(const char *s, ...) GCC_PRINTF(1, 2); */ void debug(int level, const char *s, ...) GCC_PRINTF(2, 3); +/** + * Print a debug message to the text console (stdout). + * Does not append a newline. + */ +void debugN(const char *s, ...) GCC_PRINTF(1, 2); + /** * Print a debug message to the text console (stdout), but only if * the gDebugLevel equals at least the specified level. diff --git a/common/endian.h b/common/endian.h index dba6c059cea..5866ac56026 100644 --- a/common/endian.h +++ b/common/endian.h @@ -141,27 +141,13 @@ /** * A wrapper macro used around four character constants, like 'DATA', to - * ensure portability. Typical usage: MKID_BE('DATA'). + * ensure portability. Typical usage: MKTAG('D','A','T','A'). * * Why is this necessary? The C/C++ standard does not define the endianess to * be used for character constants. Hence if one uses multi-byte character * constants, a potential portability problem opens up. - * - * Fortunately, a semi-standard has been established: On almost all systems - * and compilers, multi-byte character constants are encoded using the big - * endian convention (probably in analogy to the encoding of string constants). - * Still some systems differ. This is why we provide the MKID_BE macro. If - * you wrap your four character constants with it, the result will always be - * BE encoded, even on systems which differ from the default BE encoding. - * - * For the latter systems we provide the INVERSE_MKID override. */ -#if defined(INVERSE_MKID) -#define MKID_BE(a) SWAP_CONSTANT_32(a) - -#else -# define MKID_BE(a) ((uint32)(a)) -#endif +#define MKTAG(a0,a1,a2,a3) ((uint32)((a3) | ((a2) << 8) | ((a1) << 16) | ((a0) << 24))) // Functions for reading/writing native Integers, // this transparently handles the need for alignment @@ -331,8 +317,6 @@ #elif defined(SYSTEM_BIG_ENDIAN) - #define MKID_BE(a) ((uint32)(a)) - #define READ_BE_UINT16(a) READ_UINT16(a) #define READ_BE_UINT32(a) READ_UINT32(a) diff --git a/common/events.h b/common/events.h index ec673fb895f..5bb713b59c1 100644 --- a/common/events.h +++ b/common/events.h @@ -81,30 +81,6 @@ enum EventType { /** * Data structure for an event. A pointer to an instance of Event * can be passed to pollEvent. - * @todo Rework/document this structure. It should be made 100% clear which - * field is valid for which event type. - * Implementation wise, we might want to use the classic - * union-of-structs trick. It goes roughly like this: - * struct BasicEvent { - * EventType type; - * }; - * struct MouseMovedEvent : BasicEvent { - * Common::Point pos; - * }; - * struct MouseButtonEvent : MouseMovedEvent { - * int button; - * }; - * struct KeyEvent : BasicEvent { - * ... - * }; - * ... - * union Event { - * EventType type; - * MouseMovedEvent mouse; - * MouseButtonEvent button; - * KeyEvent key; - * ... - * }; */ struct Event { /** The type of the event. */ @@ -354,8 +330,8 @@ public: /** * Return a bitmask with the button states: - * - bit 0: left button up=1, down=0 - * - bit 1: right button up=1, down=0 + * - bit 0: left button up=0, down=1 + * - bit 1: right button up=0, down=1 */ virtual int getButtonState() const = 0; diff --git a/common/hashmap.cpp b/common/hashmap.cpp index 1a66ad59eb8..f58646272a4 100644 --- a/common/hashmap.cpp +++ b/common/hashmap.cpp @@ -89,7 +89,7 @@ void updateHashCollisionStats(int collisions, int dummyHits, int lookups, int ar g_max_capacity = MAX(g_max_capacity, arrsize); g_max_size = MAX(g_max_size, nele); - fprintf(stdout, "%d hashmaps: colls %.1f; dummies hit %.1f, lookups %.1f; ratio %.3f%%; size %f (max: %d); capacity %f (max: %d)\n", + debug("%d hashmaps: colls %.1f; dummies hit %.1f, lookups %.1f; ratio %.3f%%; size %f (max: %d); capacity %f (max: %d)", g_totalHashmaps, g_collisions / g_totalHashmaps, g_dummyHits / g_totalHashmaps, @@ -97,7 +97,7 @@ void updateHashCollisionStats(int collisions, int dummyHits, int lookups, int ar 100 * g_collPerLook / g_totalHashmaps, g_size / g_totalHashmaps, g_max_size, g_capacity / g_totalHashmaps, g_max_capacity); - fprintf(stdout, " %d less than %d; %d less than %d; %d less than %d; %d less than %d\n", + debug(" %d less than %d; %d less than %d; %d less than %d; %d less than %d", g_stats[0], 2*8/3, g_stats[1],2*16/3, g_stats[2],2*32/3, diff --git a/common/hashmap.h b/common/hashmap.h index 46946e37d7c..8d795d157ea 100644 --- a/common/hashmap.h +++ b/common/hashmap.h @@ -29,28 +29,46 @@ #ifndef COMMON_HASHMAP_H #define COMMON_HASHMAP_H +/** + * @def DEBUG_HASH_COLLISIONS + * Enable the following #define if you want to check how many collisions the + * code produces (many collisions indicate either a bad hash function, or a + * hash table that is too small). + */ +//#define DEBUG_HASH_COLLISIONS + +/** + * @def USE_HASHMAP_MEMORY_POOL + * Enable the following define to let HashMaps use a memory pool for the + nodes they contain. * This increases memory usage, but also can improve + speed quite a bit. + */ +#define USE_HASHMAP_MEMORY_POOL + + #include "common/func.h" #include "common/str.h" #include "common/util.h" -#define USE_HASHMAP_MEMORY_POOL +#ifdef DEBUG_HASH_COLLISIONS +#include "common/debug.h" +#endif + #ifdef USE_HASHMAP_MEMORY_POOL #include "common/memorypool.h" #endif + + namespace Common { // The sgi IRIX MIPSpro Compiler has difficulties with nested templates. // This and the other __sgi conditionals below work around these problems. -#if defined(__sgi) && !defined(__GNUC__) +// The Intel C++ Compiler suffers from the same problems. +#if (defined(__sgi) && !defined(__GNUC__)) || defined(__INTEL_COMPILER) template class IteratorImpl; #endif -// Enable the following #define if you want to check how many collisions the -// code produces (many collisions indicate either a bad hash function, or a -// hash table that is too small). -//#define DEBUG_HASH_COLLISIONS - /** * HashMap maps objects of type Key to objects of type Val. @@ -124,8 +142,8 @@ private: } void assign(const HM_t &map); - int lookup(const Key &key) const; - int lookupAndCreateIfMissing(const Key &key); + uint lookup(const Key &key) const; + uint lookupAndCreateIfMissing(const Key &key); void expandStorage(uint newCapacity); #if !defined(__sgi) || defined(__GNUC__) @@ -138,7 +156,7 @@ private: template class IteratorImpl { friend class HashMap; -#if defined(__sgi) && !defined(__GNUC__) +#if (defined(__sgi) && !defined(__GNUC__)) || defined(__INTEL_COMPILER) template friend class Common::IteratorImpl; #else template friend class IteratorImpl; @@ -222,6 +240,7 @@ public: void clear(bool shrinkArray = 0); + void erase(iterator entry); void erase(const Key &key); uint size() const { return _size; } @@ -437,7 +456,7 @@ void HashMap::expandStorage(uint newCapacity) { } template -int HashMap::lookup(const Key &key) const { +uint HashMap::lookup(const Key &key) const { const uint hash = _hash(key); uint ctr = hash & _mask; for (uint perturb = hash; ; perturb >>= HASHMAP_PERTURB_SHIFT) { @@ -459,7 +478,7 @@ int HashMap::lookup(const Key &key) const { #ifdef DEBUG_HASH_COLLISIONS _lookups++; - fprintf(stderr, "collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d\n", + debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d", _collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups), (const void *)this, _mask+1, _size); #endif @@ -468,7 +487,7 @@ int HashMap::lookup(const Key &key) const { } template -int HashMap::lookupAndCreateIfMissing(const Key &key) { +uint HashMap::lookupAndCreateIfMissing(const Key &key) { const uint hash = _hash(key); uint ctr = hash & _mask; const uint NONE_FOUND = _mask + 1; @@ -497,7 +516,7 @@ int HashMap::lookupAndCreateIfMissing(const Key & #ifdef DEBUG_HASH_COLLISIONS _lookups++; - fprintf(stderr, "collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d\n", + debug("collisions %d, dummies hit %d, lookups %d, ratio %f in HashMap %p; size %d num elements %d", _collisions, _dummyHits, _lookups, ((double) _collisions / (double)_lookups), (const void *)this, _mask+1, _size); #endif @@ -572,6 +591,23 @@ void HashMap::setVal(const Key &key, const Val &v _storage[ctr]->_value = val; } +template +void HashMap::erase(iterator entry) { + // Check whether we have a valid iterator + assert(entry._hashmap == this); + const uint ctr = entry._idx; + assert(ctr <= _mask); + Node * const node = _storage[ctr]; + assert(node != NULL); + assert(node != HASHMAP_DUMMY_NODE); + + // If we remove a key, we replace it with a dummy node. + freeNode(node); + _storage[ctr] = HASHMAP_DUMMY_NODE; + _size--; + _deleted++; +} + template void HashMap::erase(const Key &key) { diff --git a/common/keyboard.h b/common/keyboard.h index baa5c3150ef..8e553076a29 100644 --- a/common/keyboard.h +++ b/common/keyboard.h @@ -290,7 +290,7 @@ struct KeyState { * you can write * if (keystate.flags & KBD_CTRL) { ... } */ - bool hasFlags(byte f) { + bool hasFlags(byte f) const { return f == (flags & ~(KBD_NUM|KBD_CAPS|KBD_SCRL)); } diff --git a/common/list.h b/common/list.h index 7fc287dbb68..1f99f5d9043 100644 --- a/common/list.h +++ b/common/list.h @@ -185,7 +185,7 @@ public: } uint size() const { - int n = 0; + uint n = 0; for (const NodeBase *cur = _anchor._next; cur != &_anchor; cur = cur->_next) ++n; return n; diff --git a/common/macresman.cpp b/common/macresman.cpp index 85f3b3a5117..1dcd7171608 100644 --- a/common/macresman.cpp +++ b/common/macresman.cpp @@ -30,6 +30,8 @@ #include "common/fs.h" #include "common/macresman.h" #include "common/md5.h" +#include "common/substream.h" +#include "common/memstream.h" #ifdef MACOSX #include "common/config-manager.h" @@ -73,38 +75,43 @@ void MacResManager::close() { delete _stream; _stream = 0; } -bool MacResManager::hasDataFork() { +bool MacResManager::hasDataFork() const { return !_baseFileName.empty(); } -bool MacResManager::hasResFork() { +bool MacResManager::hasResFork() const { return !_baseFileName.empty() && _mode != kResForkNone; } -uint32 MacResManager::getResForkSize() { +uint32 MacResManager::getResForkDataSize() const { if (!hasResFork()) return 0; - return _resForkSize; + _stream->seek(_resForkOffset + 4); + return _stream->readUint32BE(); } -bool MacResManager::getResForkMD5(char *md5str, uint32 length) { +String MacResManager::computeResForkMD5AsString(uint32 length) const { if (!hasResFork()) - return false; + return String(); - ReadStream *stream = new SeekableSubReadStream(_stream, _resForkOffset, _resForkOffset + _resForkSize); - bool retVal = md5_file_string(*stream, md5str, MIN(length, _resForkSize)); - delete stream; - return retVal; + _stream->seek(_resForkOffset); + uint32 dataOffset = _stream->readUint32BE() + _resForkOffset; + /* uint32 mapOffset = */ _stream->readUint32BE(); + uint32 dataLength = _stream->readUint32BE(); + + + SeekableSubReadStream resForkStream(_stream, dataOffset, dataOffset + dataLength); + return computeStreamMD5AsString(resForkStream, MIN(length, _resForkSize)); } -bool MacResManager::open(Common::String filename) { +bool MacResManager::open(String filename) { close(); #ifdef MACOSX // Check the actual fork on a Mac computer - Common::String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc"; - Common::SeekableReadStream *macResForkRawStream = StdioStream::makeFromPath(fullPath, false); + String fullPath = ConfMan.get("path") + "/" + filename + "/..namedfork/rsrc"; + SeekableReadStream *macResForkRawStream = StdioStream::makeFromPath(fullPath, false); if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) { _baseFileName = filename; @@ -114,7 +121,7 @@ bool MacResManager::open(Common::String filename) { delete macResForkRawStream; #endif - Common::File *file = new Common::File(); + File *file = new File(); // First, let's try to see if the Mac converted name exists if (file->open("._" + filename) && loadFromAppleDouble(*file)) { @@ -158,13 +165,13 @@ bool MacResManager::open(Common::String filename) { return false; } -bool MacResManager::open(Common::FSNode path, Common::String filename) { +bool MacResManager::open(FSNode path, String filename) { close(); #ifdef MACOSX // Check the actual fork on a Mac computer - Common::String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc"; - Common::SeekableReadStream *macResForkRawStream = StdioStream::makeFromPath(fullPath, false); + String fullPath = path.getPath() + "/" + filename + "/..namedfork/rsrc"; + SeekableReadStream *macResForkRawStream = StdioStream::makeFromPath(fullPath, false); if (macResForkRawStream && loadFromRawFork(*macResForkRawStream)) { _baseFileName = filename; @@ -175,7 +182,7 @@ bool MacResManager::open(Common::FSNode path, Common::String filename) { #endif // First, let's try to see if the Mac converted name exists - Common::FSNode fsNode = path.getChild("._" + filename); + FSNode fsNode = path.getChild("._" + filename); if (fsNode.exists() && !fsNode.isDirectory()) { SeekableReadStream *stream = fsNode.createReadStream(); if (loadFromAppleDouble(*stream)) { @@ -228,7 +235,7 @@ bool MacResManager::open(Common::FSNode path, Common::String filename) { return false; } -bool MacResManager::loadFromAppleDouble(Common::SeekableReadStream &stream) { +bool MacResManager::loadFromAppleDouble(SeekableReadStream &stream) { if (stream.readUint32BE() != 0x00051607) // tag return false; @@ -241,8 +248,8 @@ bool MacResManager::loadFromAppleDouble(Common::SeekableReadStream &stream) { uint32 offset = stream.readUint32BE(); uint32 length = stream.readUint32BE(); // length - if (id == 1) { - // Found the data fork! + if (id == 2) { + // Found the resource fork! _resForkOffset = offset; _mode = kResForkAppleDouble; _resForkSize = length; @@ -253,7 +260,7 @@ bool MacResManager::loadFromAppleDouble(Common::SeekableReadStream &stream) { return false; } -bool MacResManager::isMacBinary(Common::SeekableReadStream &stream) { +bool MacResManager::isMacBinary(SeekableReadStream &stream) { byte infoHeader[MBI_INFOHDR]; int resForkOffset = -1; @@ -281,7 +288,7 @@ bool MacResManager::isMacBinary(Common::SeekableReadStream &stream) { return true; } -bool MacResManager::loadFromMacBinary(Common::SeekableReadStream &stream) { +bool MacResManager::loadFromMacBinary(SeekableReadStream &stream) { byte infoHeader[MBI_INFOHDR]; stream.read(infoHeader, MBI_INFOHDR); @@ -310,14 +317,14 @@ bool MacResManager::loadFromMacBinary(Common::SeekableReadStream &stream) { return load(stream); } -bool MacResManager::loadFromRawFork(Common::SeekableReadStream &stream) { +bool MacResManager::loadFromRawFork(SeekableReadStream &stream) { _mode = kResForkRaw; _resForkOffset = 0; _resForkSize = stream.size(); return load(stream); } -bool MacResManager::load(Common::SeekableReadStream &stream) { +bool MacResManager::load(SeekableReadStream &stream) { if (_mode == kResForkNone) return false; @@ -345,7 +352,7 @@ bool MacResManager::load(Common::SeekableReadStream &stream) { return true; } -Common::SeekableReadStream *MacResManager::getDataFork() { +SeekableReadStream *MacResManager::getDataFork() { if (!_stream) return NULL; @@ -355,7 +362,7 @@ Common::SeekableReadStream *MacResManager::getDataFork() { return new SeekableSubReadStream(_stream, MBI_INFOHDR, MBI_INFOHDR + dataSize); } - Common::File *file = new Common::File(); + File *file = new File(); if (file->open(_baseFileName)) return file; delete file; @@ -368,7 +375,7 @@ MacResIDArray MacResManager::getResIDArray(uint32 typeID) { MacResIDArray res; for (int i = 0; i < _resMap.numTypes; i++) - if (_resTypes[i].id == typeID) { + if (_resTypes[i].id == typeID) { typeNum = i; break; } @@ -398,7 +405,7 @@ MacResTagArray MacResManager::getResTagArray() { return tagArray; } -Common::String MacResManager::getResName(uint32 typeID, uint16 resID) { +String MacResManager::getResName(uint32 typeID, uint16 resID) const { int typeNum = -1; for (int i = 0; i < _resMap.numTypes; i++) @@ -417,7 +424,7 @@ Common::String MacResManager::getResName(uint32 typeID, uint16 resID) { return ""; } -Common::SeekableReadStream *MacResManager::getResource(uint32 typeID, uint16 resID) { +SeekableReadStream *MacResManager::getResource(uint32 typeID, uint16 resID) { int typeNum = -1; int resNum = -1; @@ -449,7 +456,7 @@ Common::SeekableReadStream *MacResManager::getResource(uint32 typeID, uint16 res return _stream->readStream(len); } -Common::SeekableReadStream *MacResManager::getResource(const Common::String &filename) { +SeekableReadStream *MacResManager::getResource(const String &filename) { for (uint32 i = 0; i < _resMap.numTypes; i++) { for (uint32 j = 0; j < _resTypes[i].items; j++) { if (_resLists[i][j].nameOffset != -1 && filename.equalsIgnoreCase(_resLists[i][j].name)) { @@ -468,7 +475,7 @@ Common::SeekableReadStream *MacResManager::getResource(const Common::String &fil return 0; } -Common::SeekableReadStream *MacResManager::getResource(uint32 typeID, const Common::String &filename) { +SeekableReadStream *MacResManager::getResource(uint32 typeID, const String &filename) { for (uint32 i = 0; i < _resMap.numTypes; i++) { if (_resTypes[i].id != typeID) continue; @@ -543,120 +550,110 @@ void MacResManager::readMap() { } } -void MacResManager::convertCrsrCursor(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize) { - Common::MemoryReadStream dis(data, datasize); - int i, b; - byte imageByte; - byte *iconData; - int pixelsPerByte, bpp; - int ctSize; - byte bitmask; - int iconRowBytes, iconBounds[4]; - int iconDataSize; +void MacResManager::convertCrsrCursor(SeekableReadStream *data, byte **cursor, int &w, int &h, int &hotspotX, + int &hotspotY, int &keycolor, bool colored, byte **palette, int &palSize) { - dis.readUint16BE(); // type - dis.readUint32BE(); // offset to pixel map - dis.readUint32BE(); // offset to pixel data - dis.readUint32BE(); // expanded cursor data - dis.readUint16BE(); // expanded data depth - dis.readUint32BE(); // reserved + data->readUint16BE(); // type + data->readUint32BE(); // offset to pixel map + data->readUint32BE(); // offset to pixel data + data->readUint32BE(); // expanded cursor data + data->readUint16BE(); // expanded data depth + data->readUint32BE(); // reserved // Grab B/W icon data - *cursor = (byte *)malloc(16 * 16); - for (i = 0; i < 32; i++) { - imageByte = dis.readByte(); - for (b = 0; b < 8; b++) - cursor[0][i*8+b] = (byte)((imageByte & (0x80 >> b)) > 0? 0x0F: 0x00); + *cursor = new byte[16 * 16]; + for (int i = 0; i < 32; i++) { + byte imageByte = data->readByte(); + for (int b = 0; b < 8; b++) + cursor[0][i * 8 + b] = (byte)((imageByte & (0x80 >> b)) > 0 ? 0x0F : 0x00); } // Apply mask data - for (i = 0; i < 32; i++) { - imageByte = dis.readByte(); - for (b = 0; b < 8; b++) + for (int i = 0; i < 32; i++) { + byte imageByte = data->readByte(); + for (int b = 0; b < 8; b++) if ((imageByte & (0x80 >> b)) == 0) - cursor[0][i*8+b] = 0xff; + cursor[0][i * 8 + b] = 0xff; } - *hotspot_y = dis.readUint16BE(); - *hotspot_x = dis.readUint16BE(); - *w = *h = 16; - *keycolor = 0xff; + hotspotY = data->readUint16BE(); + hotspotX = data->readUint16BE(); + w = h = 16; + keycolor = 0xff; // Use b/w cursor on backends which don't support cursor palettes if (!colored) return; - dis.readUint32BE(); // reserved - dis.readUint32BE(); // cursorID + data->readUint32BE(); // reserved + data->readUint32BE(); // cursorID // Color version of cursor - dis.readUint32BE(); // baseAddr + data->readUint32BE(); // baseAddr // Keep only lowbyte for now - dis.readByte(); - iconRowBytes = dis.readByte(); + data->readByte(); + int iconRowBytes = data->readByte(); if (!iconRowBytes) return; - iconBounds[0] = dis.readUint16BE(); - iconBounds[1] = dis.readUint16BE(); - iconBounds[2] = dis.readUint16BE(); - iconBounds[3] = dis.readUint16BE(); + int iconBounds[4]; + iconBounds[0] = data->readUint16BE(); + iconBounds[1] = data->readUint16BE(); + iconBounds[2] = data->readUint16BE(); + iconBounds[3] = data->readUint16BE(); - dis.readUint16BE(); // pmVersion - dis.readUint16BE(); // packType - dis.readUint32BE(); // packSize + data->readUint16BE(); // pmVersion + data->readUint16BE(); // packType + data->readUint32BE(); // packSize - dis.readUint32BE(); // hRes - dis.readUint32BE(); // vRes + data->readUint32BE(); // hRes + data->readUint32BE(); // vRes - dis.readUint16BE(); // pixelType - dis.readUint16BE(); // pixelSize - dis.readUint16BE(); // cmpCount - dis.readUint16BE(); // cmpSize + data->readUint16BE(); // pixelType + data->readUint16BE(); // pixelSize + data->readUint16BE(); // cmpCount + data->readUint16BE(); // cmpSize - dis.readUint32BE(); // planeByte - dis.readUint32BE(); // pmTable - dis.readUint32BE(); // reserved + data->readUint32BE(); // planeByte + data->readUint32BE(); // pmTable + data->readUint32BE(); // reserved // Pixel data for cursor - iconDataSize = iconRowBytes * (iconBounds[3] - iconBounds[1]); - iconData = (byte *)malloc(iconDataSize); - dis.read(iconData, iconDataSize); + int iconDataSize = iconRowBytes * (iconBounds[3] - iconBounds[1]); + byte *iconData = new byte[iconDataSize]; + data->read(iconData, iconDataSize); // Color table - dis.readUint32BE(); // ctSeed - dis.readUint16BE(); // ctFlag - ctSize = dis.readUint16BE() + 1; + data->readUint32BE(); // ctSeed + data->readUint16BE(); // ctFlag + uint16 ctSize = data->readUint16BE() + 1; - *palette = (byte *)malloc(ctSize * 4); + *palette = new byte[ctSize * 3]; // Read just high byte of 16-bit color for (int c = 0; c < ctSize; c++) { // We just use indices 0..ctSize, so ignore color ID - dis.readUint16BE(); // colorID[c] + data->readUint16BE(); // colorID[c] - palette[0][c * 4 + 0] = dis.readByte(); - dis.readByte(); + palette[0][c * 3 + 0] = data->readByte(); + data->readByte(); - palette[0][c * 4 + 1] = dis.readByte(); - dis.readByte(); + palette[0][c * 3 + 1] = data->readByte(); + data->readByte(); - palette[0][c * 4 + 2] = dis.readByte(); - dis.readByte(); - - palette[0][c * 4 + 3] = 0; + palette[0][c * 3 + 2] = data->readByte(); + data->readByte(); } - *palSize = ctSize; + palSize = ctSize; - pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes; - bpp = 8 / pixelsPerByte; + int pixelsPerByte = (iconBounds[2] - iconBounds[0]) / iconRowBytes; + int bpp = 8 / pixelsPerByte; // build a mask to make sure the pixels are properly shifted out - bitmask = 0; + int bitmask = 0; for (int m = 0; m < bpp; m++) { bitmask <<= 1; bitmask |= 1; @@ -664,16 +661,16 @@ void MacResManager::convertCrsrCursor(byte *data, int datasize, byte **cursor, i // Extract pixels from bytes for (int j = 0; j < iconDataSize; j++) - for (b = 0; b < pixelsPerByte; b++) { + for (int b = 0; b < pixelsPerByte; b++) { int idx = j * pixelsPerByte + (pixelsPerByte - 1 - b); if (cursor[0][idx] != 0xff) // if mask is not there cursor[0][idx] = (byte)((iconData[j] >> (b * bpp)) & bitmask); } - free(iconData); + delete[] iconData; - assert(datasize - dis.pos() == 0); + assert(data->size() - data->pos() == 0); } } // End of namespace Common diff --git a/common/macresman.h b/common/macresman.h index d2a08e5fc9b..1d90fae01a2 100644 --- a/common/macresman.h +++ b/common/macresman.h @@ -23,6 +23,15 @@ * */ +/** + * @file + * Macintosh resource fork manager used in engines: + * - groovie + * - mohawk + * - sci + * - scumm + */ + #include "common/array.h" #include "common/file.h" @@ -33,12 +42,12 @@ namespace Common { class FSNode; -typedef Common::Array MacResIDArray; -typedef Common::Array MacResTagArray; +typedef Array MacResIDArray; +typedef Array MacResTagArray; /** - * Class for reading Mac Binary files. - * Is able to read dumped resource forks too. + * Class for handling Mac data and resource forks. + * It can read from raw, MacBinary, and AppleDouble formats. */ class MacResManager { @@ -46,56 +55,112 @@ public: MacResManager(); ~MacResManager(); - bool open(Common::String filename); - bool open(Common::FSNode path, Common::String filename); - void close(); - - bool hasDataFork(); - bool hasResFork(); - - static bool isMacBinary(Common::SeekableReadStream &stream); + /** + * Open a Mac data/resource fork pair. + * @param filename The base file name of the file + * @note This will check for the raw resource fork, MacBinary, and AppleDouble formats. + * @return True on success + */ + bool open(String filename); /** - * Read resource from the Mac Binary file + * Open a Mac data/resource fork pair. + * @param path The path that holds the forks + * @param filename The base file name of the file + * @note This will check for the raw resource fork, MacBinary, and AppleDouble formats. + * @return True on success + */ + bool open(FSNode path, String filename); + + /** + * Close the Mac data/resource fork pair. + */ + void close(); + + /** + * Query whether or not we have a data fork present. + * @return True if the data fork is present + */ + bool hasDataFork() const; + + /** + * Query whether or not we have a data fork present. + * @return True if the resource fork is present + */ + bool hasResFork() const; + + /** + * Check if the given stream is in the MacBinary format. + * @param stream The stream we're checking + */ + static bool isMacBinary(SeekableReadStream &stream); + + /** + * Read resource from the MacBinary file * @param typeID FourCC of the type * @param resID Resource ID to fetch * @return Pointer to a SeekableReadStream with loaded resource */ - Common::SeekableReadStream *getResource(uint32 typeID, uint16 resID); + SeekableReadStream *getResource(uint32 typeID, uint16 resID); /** - * Read resource from the Mac Binary file + * Read resource from the MacBinary file * @note This will take the first resource that matches this name, regardless of type - * @param filename filename of the resource + * @param filename file name of the resource * @return Pointer to a SeekableReadStream with loaded resource */ - Common::SeekableReadStream *getResource(const Common::String &filename); + SeekableReadStream *getResource(const String &filename); /** - * Read resource from the Mac Binary file + * Read resource from the MacBinary file * @param typeID FourCC of the type - * @param filename filename of the resource + * @param filename file name of the resource * @return Pointer to a SeekableReadStream with loaded resource */ - Common::SeekableReadStream *getResource(uint32 typeID, const Common::String &filename); + SeekableReadStream *getResource(uint32 typeID, const String &filename); - Common::SeekableReadStream *getDataFork(); - Common::String getResName(uint32 typeID, uint16 resID); - uint32 getResForkSize(); - bool getResForkMD5(char *md5str, uint32 length); + /** + * Retrieve the data fork + * @return The stream if present, 0 otherwise + */ + SeekableReadStream *getDataFork(); - Common::String getBaseFileName() { return _baseFileName; } + /** + * Get the name of a given resource + * @param typeID FourCC of the type + * @param resID Resource ID to fetch + * @return The name of a given resource and an empty string if not present + */ + String getResName(uint32 typeID, uint16 resID) const; + + /** + * Get the size of the data portion of the resource fork + * @return The size of the data portion of the resource fork + */ + uint32 getResForkDataSize() const; + + /** + * Calculate the MD5 checksum of the resource fork + * @param length The maximum length to compute for + * @return The MD5 checksum of the resource fork + */ + String computeResForkMD5AsString(uint32 length = 0) const; + + /** + * Get the base file name of the data/resource fork pair + * @return The base file name of the data/resource fork pair + */ + String getBaseFileName() const { return _baseFileName; } /** * Convert cursor from crsr format to format suitable for feeding to CursorMan - * @param data Pointer to the cursor data - * @param datasize Size of the cursor data + * @param data Pointer to the cursor datax * @param cursor Pointer to memory where result cursor will be stored. The memory * block will be malloc()'ed * @param w Pointer to int where the cursor width will be stored * @param h Pointer to int where the cursor height will be stored - * @param hotspot_x Storage for cursor hotspot X coordinate - * @param hotspot_Y Storage for cursor hotspot Y coordinate + * @param hotspotX Storage for cursor hotspot X coordinate + * @param hotspotY Storage for cursor hotspot Y coordinate * @param keycolor Pointer to int where the transpared color value will be stored * @param colored If set to true then colored cursor will be returned (if any). * b/w version will be used otherwise @@ -103,8 +168,8 @@ public: * The memory will be malloc()'ed * @param palSize Pointer to integer where the palette size will be stored. */ - static void convertCrsrCursor(byte *data, int datasize, byte **cursor, int *w, int *h, - int *hotspot_x, int *hotspot_y, int *keycolor, bool colored, byte **palette, int *palSize); + static void convertCrsrCursor(SeekableReadStream *data, byte **cursor, int &w, int &h, int &hotspotX, + int &hotspotY, int &keycolor, bool colored, byte **palette, int &palSize); /** * Return list of resource IDs with specified type ID @@ -117,14 +182,14 @@ public: MacResTagArray getResTagArray(); private: - Common::SeekableReadStream *_stream; - Common::String _baseFileName; + SeekableReadStream *_stream; + String _baseFileName; - bool load(Common::SeekableReadStream &stream); + bool load(SeekableReadStream &stream); - bool loadFromRawFork(Common::SeekableReadStream &stream); - bool loadFromMacBinary(Common::SeekableReadStream &stream); - bool loadFromAppleDouble(Common::SeekableReadStream &stream); + bool loadFromRawFork(SeekableReadStream &stream); + bool loadFromMacBinary(SeekableReadStream &stream); + bool loadFromAppleDouble(SeekableReadStream &stream); enum { kResForkNone = 0, diff --git a/common/md5.cpp b/common/md5.cpp index 958107eafa6..9e42d1a4bbe 100644 --- a/common/md5.cpp +++ b/common/md5.cpp @@ -246,7 +246,7 @@ void md5_finish(md5_context *ctx, uint8 digest[16]) { } -bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) { +bool computeStreamMD5(ReadStream &stream, uint8 digest[16], uint32 length) { #ifdef DISABLE_MD5 memset(digest, 0, 16); @@ -267,12 +267,14 @@ bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) { while ((i = stream.read(buf, readlen)) > 0) { md5_update(&ctx, buf, i); - length -= i; - if (restricted && length == 0) - break; + if (restricted) { + length -= i; + if (length == 0) + break; - if (restricted && sizeof(buf) > length) - readlen = length; + if (sizeof(buf) > length) + readlen = length; + } } md5_finish(&ctx, digest); @@ -280,16 +282,16 @@ bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length) { return true; } -bool md5_file_string(ReadStream &stream, char *md5str, uint32 length) { +String computeStreamMD5AsString(ReadStream &stream, uint32 length) { + String md5; uint8 digest[16]; - if (!md5_file(stream, digest, length)) - return false; - - for (int i = 0; i < 16; i++) { - snprintf(md5str + i*2, 3, "%02x", (int)digest[i]); + if (computeStreamMD5(stream, digest, length)) { + for (int i = 0; i < 16; i++) { + md5 += String::format("%02x", (int)digest[i]); + } } - return true; + return md5; } } // End of namespace Common diff --git a/common/md5.h b/common/md5.h index afa7f39658e..017b419f82f 100644 --- a/common/md5.h +++ b/common/md5.h @@ -26,18 +26,35 @@ #define COMMON_MD5_H #include "common/sys.h" +#include "common/str.h" namespace Common { class ReadStream; -bool md5_file(ReadStream &stream, uint8 digest[16], uint32 length = 0); +/** + * Compute the MD5 checksum of the content of the given ReadStream. + * The 128 bit MD5 checksum is returned directly in the array digest. + * If length is set to a positive value, then only the first length + * bytes of the stream are used to compute the checksum. + * @param[in] stream the stream of whose data the MD5 is computed + * @param[out] digest the computed MD5 checksum + * @param[in] length the number of bytes for which to compute the checksum; 0 means all + * @return true on success, false if an error occurred + */ +bool computeStreamMD5(ReadStream &stream, uint8 digest[16], uint32 length = 0); -// The following method work similar to the above one, but -// instead of computing the binary MD5 digest, it produces -// a human readable lowercase hexstring representing the digest. -// The md5str parameter must point to a buffer of 32+1 chars. -bool md5_file_string(ReadStream &stream, char *md5str, uint32 length = 0); +/** + * Compute the MD5 checksum of the content of the given ReadStream. + * The 128 bit MD5 checksum is converted to a human readable + * lowercase hex string of length 32. + * If length is set to a positive value, then only the first length + * bytes of the stream are used to compute the checksum. + * @param[in] stream the stream of whose data the MD5 is computed + * @param[in] length the number of bytes for which to compute the checksum; 0 means all + * @return the MD5 as a hex string on success, and an empty string if an error occurred + */ +String computeStreamMD5AsString(ReadStream &stream, uint32 length = 0); } // End of namespace Common diff --git a/common/memorypool.cpp b/common/memorypool.cpp index 90a47ae9f22..0713a48a762 100644 --- a/common/memorypool.cpp +++ b/common/memorypool.cpp @@ -161,7 +161,7 @@ void MemoryPool::freeUnusedPages() { } } -// printf("freed %d pages out of %d\n", (int)freedPagesCount, (int)_pages.size()); +// debug("freed %d pages out of %d", (int)freedPagesCount, (int)_pages.size()); // Remove all now unused pages size_t newSize = 0; diff --git a/common/memorypool.h b/common/memorypool.h index c7215c34fd6..8bf98a4788e 100644 --- a/common/memorypool.h +++ b/common/memorypool.h @@ -66,7 +66,7 @@ public: * Constructor for a memory pool with the given chunk size. * @param chunkSize the chunk size of this memory pool */ - MemoryPool(size_t chunkSize); + explicit MemoryPool(size_t chunkSize); ~MemoryPool(); /** diff --git a/common/memstream.h b/common/memstream.h new file mode 100644 index 00000000000..ac07fe2bb71 --- /dev/null +++ b/common/memstream.h @@ -0,0 +1,173 @@ +/* Residual - A 3D game interpreter + * + * 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 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_MEMSTREAM_H +#define COMMON_MEMSTREAM_H + +#include "common/stream.h" + +namespace Common { + +/** + * Simple memory based 'stream', which implements the ReadStream interface for + * a plain memory block. + */ +class MemoryReadStream : public SeekableReadStream { +private: + const byte * const _ptrOrig; + const byte *_ptr; + const uint32 _size; + uint32 _pos; + DisposeAfterUse::Flag _disposeMemory; + bool _eos; + +public: + + /** + * This constructor takes a pointer to a memory buffer and a length, and + * wraps it. If disposeMemory is true, the MemoryReadStream takes ownership + * of the buffer and hence free's it when destructed. + */ + MemoryReadStream(const byte *dataPtr, uint32 dataSize, DisposeAfterUse::Flag disposeMemory = DisposeAfterUse::NO) : + _ptrOrig(dataPtr), + _ptr(dataPtr), + _size(dataSize), + _pos(0), + _disposeMemory(disposeMemory), + _eos(false) {} + + ~MemoryReadStream() { + if (_disposeMemory) + free(const_cast(_ptrOrig)); + } + + uint32 read(void *dataPtr, uint32 dataSize); + + bool eos() const { return _eos; } + void clearErr() { _eos = false; } + + int32 pos() const { return _pos; } + int32 size() const { return _size; } + + bool seek(int32 offs, int whence = SEEK_SET); +}; + + +/** + * This is a MemoryReadStream subclass which adds non-endian + * read methods whose endianness is set on the stream creation. + */ +class MemoryReadStreamEndian : public MemoryReadStream, public ReadStreamEndian { +public: + MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian) + : MemoryReadStream(buf, len), ReadStreamEndian(bigEndian) {} +}; + +/** + * Simple memory based 'stream', which implements the WriteStream interface for + * a plain memory block. + */ +class MemoryWriteStream : public WriteStream { +private: + byte *_ptr; + const uint32 _bufSize; + uint32 _pos; +public: + MemoryWriteStream(byte *buf, uint32 len) : _ptr(buf), _bufSize(len), _pos(0) {} + + uint32 write(const void *dataPtr, uint32 dataSize) { + // Write at most as many bytes as are still available... + if (dataSize > _bufSize - _pos) + dataSize = _bufSize - _pos; + memcpy(_ptr, dataPtr, dataSize); + _ptr += dataSize; + _pos += dataSize; + return dataSize; + } + + uint32 pos() const { return _pos; } + uint32 size() const { return _bufSize; } +}; + +/** + * A sort of hybrid between MemoryWriteStream and Array classes. A stream + * that grows as it's written to. + */ +class MemoryWriteStreamDynamic : public WriteStream { +private: + uint32 _capacity; + uint32 _size; + byte *_ptr; + byte *_data; + uint32 _pos; + DisposeAfterUse::Flag _disposeMemory; + + void ensureCapacity(uint32 new_len) { + if (new_len <= _capacity) + return; + + byte *old_data = _data; + + _capacity = new_len + 32; + _data = (byte *)malloc(_capacity); + _ptr = _data + _pos; + + if (old_data) { + // Copy old data + memcpy(_data, old_data, _size); + free(old_data); + } + + _size = new_len; + } +public: + MemoryWriteStreamDynamic(DisposeAfterUse::Flag disposeMemory = DisposeAfterUse::NO) : _capacity(0), _size(0), _ptr(0), _data(0), _pos(0), _disposeMemory(disposeMemory) {} + + ~MemoryWriteStreamDynamic() { + if (_disposeMemory) + free(_data); + } + + uint32 write(const void *dataPtr, uint32 dataSize) { + ensureCapacity(_pos + dataSize); + memcpy(_ptr, dataPtr, dataSize); + _ptr += dataSize; + _pos += dataSize; + if (_pos > _size) + _size = _pos; + return dataSize; + } + + uint32 pos() const { return _pos; } + uint32 size() const { return _size; } + + byte *getData() { return _data; } + + bool seek(int32 offset, int whence = SEEK_SET); +}; + +} // End of namespace Common + +#endif diff --git a/common/messages.cpp b/common/messages.cpp deleted file mode 100644 index bd53f177375..00000000000 --- a/common/messages.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/* generated by po2c 1.0.2 - Do not modify */ - -#include -#include - -static const char * _po2c_msgids[] = { - NULL -}; - -struct _po2c_msg { - int msgid; - const char * msgstr; -}; - -static struct { - const char * lang; - const char * charset; - struct _po2c_msg * msgs; -} _po2c_langs[] = { - { NULL, NULL, NULL } -}; - -// code - -static const PoMessageEntry *_currentTranslation = NULL; -static int _currentTranslationMessageEntryCount = 0; -static const char *_currentTranslationCharset = NULL; - -void po2c_setlang(const char *lang) { - _currentTranslation = NULL; - _currentTranslationMessageEntryCount = 0; - _currentTranslationCharset = NULL; - - // if lang is NULL or "", deactivate it - if (lang == NULL || *lang == '\0') - return; - - // searches for a valid language array - for (int i = 0; _currentTranslation == NULL && _translations[i].lang != NULL; ++i) { - if (strcmp(lang, _translations[i].lang) == 0) { - _currentTranslation = _translations[i].msgs; - _currentTranslationCharset = _translations[i].charset; - } - } - - // try partial searches - for (int i = 0; _currentTranslation == NULL && _translations[i].lang != NULL; ++i) { - if (strncmp(lang, _translations[i].lang, 2) == 0) { - _currentTranslation = _translations[i].msgs; - _currentTranslationCharset = _translations[i].charset; - } - } - - // if found, count entries - if (_currentTranslation != NULL) { - for (const PoMessageEntry *m = _currentTranslation; m->msgid != -1; ++m) - ++_currentTranslationMessageEntryCount; - } -} - -const char *po2c_gettext(const char *msgid) { - // if no language is set or msgid is empty, return msgid as is - if (_currentTranslation == NULL || *msgid == '\0') - return msgid; - - // binary-search for the msgid - int leftIndex = 0; - int rightIndex = _currentTranslationMessageEntryCount - 1; - - while (rightIndex >= leftIndex) { - const int midIndex = (leftIndex + rightIndex) / 2; - const PoMessageEntry * const m = &_currentTranslation[midIndex]; - - const int compareResult = strcmp(msgid, _messageIds[m->msgid]); - - if (compareResult == 0) - return m->msgstr; - else if (compareResult < 0) - rightIndex = midIndex - 1; - else - leftIndex = midIndex + 1; - } - - return msgid; -} - -const char *po2c_getcharset(void) { - if (_currentTranslationCharset) - return _currentTranslationCharset; - else - return "ASCII"; -} - -int po2c_getnumlangs(void) { - return ARRAYSIZE(_translations) - 1; -} - -const char *po2c_getlang(const int num) { - assert(num < ARRAYSIZE(_translations)); - return _translations[num].lang; -} diff --git a/common/module.mk b/common/module.mk index 9ff2b198b94..4fbc3a9ad43 100644 --- a/common/module.mk +++ b/common/module.mk @@ -16,6 +16,7 @@ MODULE_OBJS := \ md5.o \ mutex.o \ random.o \ + rational.o \ str.o \ stream.o \ system.o \ diff --git a/common/mutex.h b/common/mutex.h index eb8ee7e372a..bb9e78b04cf 100644 --- a/common/mutex.h +++ b/common/mutex.h @@ -49,8 +49,8 @@ class StackLock { void lock(); void unlock(); public: - StackLock(MutexRef mutex, const char *mutexName = NULL); - StackLock(const Mutex &mutex, const char *mutexName = NULL); + explicit StackLock(MutexRef mutex, const char *mutexName = NULL); + explicit StackLock(const Mutex &mutex, const char *mutexName = NULL); ~StackLock(); }; diff --git a/common/ptr.h b/common/ptr.h index ebcbcb6a3a7..aab16a02c7b 100644 --- a/common/ptr.h +++ b/common/ptr.h @@ -243,7 +243,7 @@ public: operator bool() const { return _pointer != 0; } ~ScopedPtr() { - delete _pointer; + delete _pointer; } /** @@ -277,7 +277,6 @@ private: PointerType _pointer; }; - } // End of namespace Common #endif diff --git a/common/rational.cpp b/common/rational.cpp new file mode 100644 index 00000000000..1ed7fe73698 --- /dev/null +++ b/common/rational.cpp @@ -0,0 +1,325 @@ +/* Residual - A 3D game interpreter + * + * 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 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/debug.h" +#include "common/rational.h" +#include "common/util.h" +#include "common/algorithm.h" + +namespace Common { + +Rational::Rational() { + _num = 1; + _denom = 1; +} + +Rational::Rational(int num) { + _num = num; + _denom = 1; +} + +Rational::Rational(int num, int denom) { + assert(denom != 0); + + if (denom > 0) { + _num = num; + _denom = denom; + } else { + _num = -num; + _denom = -denom; + } + + cancel(); +} + +void Rational::cancel() { + // Cancel the fraction by dividing both the num and the denom + // by their greatest common divisor. + + const int gcd = Common::gcd(_num, _denom); + + _num /= gcd; + _denom /= gcd; +} + +Rational &Rational::operator=(const Rational &right) { + _num = right._num; + _denom = right._denom; + + return *this; +} + +Rational &Rational::operator=(int right) { + _num = right; + _denom = 1; + + return *this; +} + +Rational &Rational::operator+=(const Rational &right) { + // Cancel common factors to avoid unnecessary overflow. + // Note that the result is *not* always normalized. + const int gcd = Common::gcd(_denom, right._denom); + + _num = _num * (right._denom / gcd); + _denom = _denom / gcd; + _num += right._num * _denom; + _denom *= right._denom; + + cancel(); + + return *this; +} + +Rational &Rational::operator-=(const Rational &right) { + // Cancel common factors to avoid unnecessary overflow. + // Note that the result is *not* always normalized. + const int gcd = Common::gcd(_denom, right._denom); + + _num = _num * (right._denom / gcd); + _denom = _denom / gcd; + _num -= right._num * _denom; + _denom *= right._denom; + + cancel(); + + return *this; +} + +Rational &Rational::operator*=(const Rational &right) { + // Cross-cancel to avoid unnecessary overflow; + // the result then is automatically normalized + const int gcd1 = Common::gcd(_num, right._denom); + const int gcd2 = Common::gcd(right._num, _denom); + + _num = (_num / gcd1) * (right._num / gcd2); + _denom = (_denom / gcd2) * (right._denom / gcd1); + + return *this; +} + +Rational &Rational::operator/=(const Rational &right) { + return *this *= right.getInverse(); +} + +Rational &Rational::operator+=(int right) { + return *this += Rational(right); +} + +Rational &Rational::operator-=(int right) { + return *this -= Rational(right); +} + +Rational &Rational::operator*=(int right) { + return *this *= Rational(right); +} + +Rational &Rational::operator/=(int right) { + return *this /= Rational(right); +} + +const Rational Rational::operator-() const { + return Rational(-_num, _denom); +} + +const Rational Rational::operator+(const Rational &right) const { + Rational tmp = *this; + tmp += right; + return tmp; +} + +const Rational Rational::operator-(const Rational &right) const { + Rational tmp = *this; + tmp -= right; + return tmp; +} + +const Rational Rational::operator*(const Rational &right) const { + Rational tmp = *this; + tmp *= right; + return tmp; +} + +const Rational Rational::operator/(const Rational &right) const { + Rational tmp = *this; + tmp /= right; + return tmp; +} + +const Rational Rational::operator+(int right) const { + Rational tmp = *this; + tmp += right; + return tmp; +} + +const Rational Rational::operator-(int right) const { + Rational tmp = *this; + tmp -= right; + return tmp; +} + +const Rational Rational::operator*(int right) const { + Rational tmp = *this; + tmp *= right; + return tmp; +} + +const Rational Rational::operator/(int right) const { + Rational tmp = *this; + tmp /= right; + return tmp; +} + +bool Rational::operator==(const Rational &right) const { + return (_num == right._num) && (_denom == right._denom); +} + +bool Rational::operator!=(const Rational &right) const { + return (_num != right._num) || (_denom != right._denom); +} + +bool Rational::operator>(const Rational &right) const { + return (_num * right._denom) > (right._num * _denom); +} + +bool Rational::operator<(const Rational &right) const { + return (_num * right._denom) < (right._num * _denom); +} + +bool Rational::operator>=(const Rational &right) const { + return (_num * right._denom) >= (right._num * _denom); +} + +bool Rational::operator<=(const Rational &right) const { + return (_num * right._denom) <= (right._num * _denom); +} + +bool Rational::operator==(int right) const { + return (_denom == 1) && (_num == right); +} + +bool Rational::operator!=(int right) const { + return (_denom != 1) || (_num != right); +} + +bool Rational::operator>(int right) const { + return *this > Rational(right, 1); +} + +bool Rational::operator<(int right) const { + return *this < Rational(right, 1); +} + +bool Rational::operator>=(int right) const { + return *this >= Rational(right, 1); +} + +bool Rational::operator<=(int right) const { + return *this <= Rational(right, 1); +} + +void Rational::invert() { + assert(_num != 0); + + SWAP(_num, _denom); + + if (_denom < 0) { + _denom = -_denom; + _num = -_num; + } +} + +Rational Rational::getInverse() const { + Rational inverse = *this; + + inverse.invert(); + + return inverse; +} + +int Rational::toInt() const { + return _num / _denom; +} + +double Rational::toDouble() const { + return ((double)_num) / ((double)_denom); +} + +frac_t Rational::toFrac() const { + return (_num * FRAC_ONE) / _denom; +} + +const Rational operator+(int left, const Rational &right) { + Rational tmp(left); + tmp += right; + return tmp; +} + +const Rational operator-(int left, const Rational &right) { + Rational tmp(left); + tmp -= right; + return tmp; +} + +const Rational operator*(int left, const Rational &right) { + Rational tmp(left); + tmp *= right; + return tmp; +} + +const Rational operator/(int left, const Rational &right) { + Rational tmp(left); + tmp /= right; + return tmp; +} + +void Rational::debugPrint(int debuglevel, const char *caption) const { + debug(debuglevel, "%s %d/%d", caption, _num, _denom); +} + +bool operator==(int left, const Rational &right) { + return right == left; +} + +bool operator!=(int left, const Rational &right) { + return right != left; +} + +bool operator>(int left, const Rational &right) { + return right < left; +} + +bool operator<(int left, const Rational &right) { + return right > left; +} + +bool operator>=(int left, const Rational &right) { + return right <= left; +} + +bool operator<=(int left, const Rational &right) { + return right >= left; +} + +} // End of namespace Common diff --git a/common/rational.h b/common/rational.h new file mode 100644 index 00000000000..efbf2bfd6b7 --- /dev/null +++ b/common/rational.h @@ -0,0 +1,109 @@ +/* Residual - A 3D game interpreter + * + * 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 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_RATIONAL_H +#define COMMON_RATIONAL_H + +#include "common/sys.h" +#include "common/frac.h" + +namespace Common { + +/** A simple rational class that holds fractions. */ +class Rational { +public: + Rational(); + Rational(int num); + Rational(int num, int denom); + + Rational &operator=(const Rational &right); + Rational &operator=(int right); + + Rational &operator+=(const Rational &right); + Rational &operator-=(const Rational &right); + Rational &operator*=(const Rational &right); + Rational &operator/=(const Rational &right); + + Rational &operator+=(int right); + Rational &operator-=(int right); + Rational &operator*=(int right); + Rational &operator/=(int right); + + const Rational operator-() const; + + const Rational operator+(const Rational &right) const; + const Rational operator-(const Rational &right) const; + const Rational operator*(const Rational &right) const; + const Rational operator/(const Rational &right) const; + + const Rational operator+(int right) const; + const Rational operator-(int right) const; + const Rational operator*(int right) const; + const Rational operator/(int right) const; + + bool operator==(const Rational &right) const; + bool operator!=(const Rational &right) const; + bool operator>(const Rational &right) const; + bool operator<(const Rational &right) const; + bool operator>=(const Rational &right) const; + bool operator<=(const Rational &right) const; + + bool operator==(int right) const; + bool operator!=(int right) const; + bool operator>(int right) const; + bool operator<(int right) const; + bool operator>=(int right) const; + bool operator<=(int right) const; + + void invert(); + Rational getInverse() const; + + int toInt() const; + double toDouble() const; + frac_t toFrac() const; + + void debugPrint(int debuglevel = 0, const char *caption = "Rational:") const; + +private: + int _num; + int _denom; + + void cancel(); +}; + +const Rational operator+(int left, const Rational &right); +const Rational operator-(int left, const Rational &right); +const Rational operator*(int left, const Rational &right); +const Rational operator/(int left, const Rational &right); + +bool operator==(int left, const Rational &right); +bool operator!=(int left, const Rational &right); +bool operator>(int left, const Rational &right); +bool operator<(int left, const Rational &right); +bool operator>=(int left, const Rational &right); +bool operator<=(int left, const Rational &right); + +} // End of namespace Common + +#endif diff --git a/common/rect.h b/common/rect.h index b2c07385e6c..a4f492689f7 100644 --- a/common/rect.h +++ b/common/rect.h @@ -43,6 +43,18 @@ struct Point { Point(int16 x1, int16 y1) : x(x1), y(y1) {} bool operator==(const Point &p) const { return x == p.x && y == p.y; } bool operator!=(const Point &p) const { return x != p.x || y != p.y; } + Point operator+(const Point &delta) const { return Point(x + delta.x, y + delta.y); } + Point operator-(const Point &delta) const { return Point(x - delta.x, y - delta.y); } + + void operator+=(const Point &delta) { + x += delta.x; + y += delta.y; + } + + void operator-=(const Point &delta) { + x -= delta.x; + y -= delta.y; + } /** * Return the square of the distance between this point and the point p. diff --git a/common/savefile.h b/common/savefile.h index 64ac2ea6618..6609730741e 100644 --- a/common/savefile.h +++ b/common/savefile.h @@ -135,6 +135,14 @@ public: */ virtual bool renameSavefile(const String &oldName, const String &newName); + /** + * Copy the given savefile. + * @param oldName Old name. + * @param newName New name. + * @return true if no error occurred. false otherwise. + */ + virtual bool copySavefile(const String &oldName, const String &newName); + /** * Request a list of available savegames with a given DOS-style pattern, * also known as "glob" in the UNIX world. Refer to the Common::matchString() diff --git a/common/serializer.h b/common/serializer.h new file mode 100644 index 00000000000..cb4d6fddbbd --- /dev/null +++ b/common/serializer.h @@ -0,0 +1,257 @@ +/* Residual - A 3D game interpreter + * + * 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 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_SERIALIZER_H +#define COMMON_SERIALIZER_H + +#include "common/stream.h" +#include "common/str.h" + +namespace Common { + + +#define SYNC_AS(SUFFIX,TYPE,SIZE) \ + template \ + void syncAs ## SUFFIX(T &val, Version minVersion = 0, Version maxVersion = kLastVersion) { \ + if (_version < minVersion || _version > maxVersion) \ + return; \ + if (_loadStream) \ + val = static_cast(_loadStream->read ## SUFFIX()); \ + else { \ + TYPE tmp = val; \ + _saveStream->write ## SUFFIX(tmp); \ + } \ + _bytesSynced += SIZE; \ + } + + +/** + * This class allows syncing / serializing data (primarily game savestates) + * between memory and Read/WriteStreams. + * It optionally supports versioning the serialized data (client code must + * use the syncVersion() method for this). This makes it possible to support + * multiple versions of a savegame format with a single codepath + * + * This class was heavily inspired by the save/load code in the SCUMM engine. + * + * @todo Maybe rename this to Synchronizer? + * + * @todo One feature the SCUMM code has but that is missing here: Support for + * syncing arrays of a given type and *fixed* size; and also support + * for when the array size changed between versions. Also, support for + * 2D-arrays. + * + * @todo Proper error handling! + */ +class Serializer { +public: + typedef uint32 Version; + static const Version kLastVersion = 0xFFFFFFFF; + +protected: + Common::SeekableReadStream *_loadStream; + Common::WriteStream *_saveStream; + + uint _bytesSynced; + + Version _version; + +public: + Serializer(Common::SeekableReadStream *in, Common::WriteStream *out) + : _loadStream(in), _saveStream(out), _bytesSynced(0), _version(0) { + assert(in || out); + } + virtual ~Serializer() {} + + inline bool isSaving() { return (_saveStream != 0); } + inline bool isLoading() { return (_loadStream != 0); } + + // WORKAROUND for bugs #2892515 "BeOS: tinsel does not compile" and + // #2892510 "BeOS: Cruise does not compile". gcc 2.95.3, which is used + // for BeOS fails due to an internal compiler error, when we place the + // following function definitions in another place. Before this work- + // around the following SYNC_AS definitions were placed at the end + // of the class declaration. This caused an internal compiler error + // in the line "syncAsUint32LE(_version);" of + // "bool syncVersion(Version currentVersion)". + SYNC_AS(Byte, byte, 1) + + SYNC_AS(Uint16LE, uint16, 2) + SYNC_AS(Uint16BE, uint16, 2) + SYNC_AS(Sint16LE, int16, 2) + SYNC_AS(Sint16BE, int16, 2) + + SYNC_AS(Uint32LE, uint32, 4) + SYNC_AS(Uint32BE, uint32, 4) + SYNC_AS(Sint32LE, int32, 4) + SYNC_AS(Sint32BE, int32, 4) + + /** + * Returns true if an I/O failure occurred. + * This flag is never cleared automatically. In order to clear it, + * client code has to call clearErr() explicitly. + */ + bool err() const { + if (_saveStream) + return _saveStream->err(); + else + return _loadStream->err(); + } + + /** + * Reset the I/O error status as returned by err(). + */ + void clearErr() { + if (_saveStream) + _saveStream->clearErr(); + else + _loadStream->clearErr(); + } + + /** + * Sync the "version" of the savegame we are loading/creating. + * @param currentVersion current format version, used when writing a new file + * @return true if the version of the savestate is not too new. + */ + bool syncVersion(Version currentVersion) { + _version = currentVersion; + syncAsUint32LE(_version); + return _version <= currentVersion; + } + + /** + * Return the version of the savestate being serialized. Useful if the engine + * needs to perform additional adjustments when loading old savestates. + */ + Version getVersion() const { return _version; } + + + /** + * Return the total number of bytes synced so far. + */ + uint bytesSynced() const { return _bytesSynced; } + + /** + * Skip a number of bytes in the data stream. + * This is useful to skip obsolete fields in old savestates. + */ + void skip(uint32 size, Version minVersion = 0, Version maxVersion = kLastVersion) { + if (_version < minVersion || _version > maxVersion) + return; // Ignore anything which is not supposed to be present in this save game version + + _bytesSynced += size; + if (isLoading()) + _loadStream->skip(size); + else { + while (size--) + _saveStream->writeByte(0); + } + } + + /** + * Sync a block of arbitrary fixed-length data. + */ + void syncBytes(byte *buf, uint32 size, Version minVersion = 0, Version maxVersion = kLastVersion) { + if (_version < minVersion || _version > maxVersion) + return; // Ignore anything which is not supposed to be present in this save game version + + if (isLoading()) + _loadStream->read(buf, size); + else + _saveStream->write(buf, size); + _bytesSynced += size; + } + + /** + * Sync a 'magic id' of up to 256 bytes, and return whether it matched. + * When saving, this will simply write out the magic id and return true. + * When loading, this will read the specified number of bytes, compare it + * to the given magic id and return true on a match, false otherwise. + * + * A typical magic id is a FOURCC like 'MAGI'. + * + * @param magic magic id as a byte sequence + * @param size length of the magic id in bytes + * @return true if the magic id matched, false otherwise + */ + bool matchBytes(const char *magic, byte size, Version minVersion = 0, Version maxVersion = kLastVersion) { + if (_version < minVersion || _version > maxVersion) + return true; // Ignore anything which is not supposed to be present in this save game version + + bool match; + if (isSaving()) { + _saveStream->write(magic, size); + match = true; + } else { + char buf[256]; + _loadStream->read(buf, size); + match = (0 == memcmp(buf, magic, size)); + } + _bytesSynced += size; + return match; + } + + /** + * Sync a C-string, by treating it as a zero-terminated byte sequence. + * @todo Replace this method with a special Syncer class for Common::String + */ + void syncString(Common::String &str, Version minVersion = 0, Version maxVersion = kLastVersion) { + if (_version < minVersion || _version > maxVersion) + return; // Ignore anything which is not supposed to be present in this save game version + + if (isLoading()) { + char c; + str.clear(); + while ((c = _loadStream->readByte())) { + str += c; + _bytesSynced++; + } + _bytesSynced++; + } else { + _saveStream->writeString(str); + _saveStream->writeByte(0); + _bytesSynced += str.size() + 1; + } + } + +}; + +#undef SYNC_AS + + +// Mixin class / interface +// TODO: Maybe rename this to Syncable ? +class Serializable { +public: + virtual ~Serializable() {} + + // Maybe rename this method to "syncWithSerializer" or "syncUsingSerializer" ? + virtual void saveLoadWithSerializer(Serializer &ser) = 0; +}; + + +} // End of namespace Common + +#endif diff --git a/common/singleton.h b/common/singleton.h index bbce238b062..5b1af731783 100644 --- a/common/singleton.h +++ b/common/singleton.h @@ -39,8 +39,6 @@ private: Singleton(const Singleton &); Singleton &operator=(const Singleton &); - static T *_singleton; - /** * The default object factory used by the template class Singleton. * By specialising this template function, one can make a singleton use a @@ -89,6 +87,8 @@ protected: #endif typedef T SingletonBaseType; + + static T *_singleton; }; /** @@ -100,9 +100,7 @@ protected: * namespace Common is referenced. */ #define DECLARE_SINGLETON(T) \ - namespace Common { \ - template<> T *Singleton::_singleton = 0; \ - } // End of namespace Common + template<> T *Common::Singleton::_singleton = 0 } // End of namespace Common diff --git a/common/str.cpp b/common/str.cpp index aaf74fc7783..acb8ac91e67 100644 --- a/common/str.cpp +++ b/common/str.cpp @@ -430,7 +430,7 @@ uint String::hash() const { } // static -String String::printf(const char *fmt, ...) { +String String::format(const char *fmt, ...) { String output; assert(output.isStorageIntern()); @@ -439,12 +439,20 @@ String String::printf(const char *fmt, ...) { int len = vsnprintf(output._str, _builtinCapacity, fmt, va); va_end(va); - if (len == -1) { - // MSVC doesn't return the size the full string would take up. - // Try increasing the size of the string until it fits. + if (len == -1 || len == _builtinCapacity - 1) { + // MSVC and IRIX don't return the size the full string would take up. + // MSVC returns -1, IRIX returns the number of characters actually written, + // which is at the most the size of the buffer minus one, as the string is + // truncated to fit. // We assume MSVC failed to output the correct, null-terminated string // if the return value is either -1 or size. + // For IRIX, because we lack a better mechanism, we assume failure + // if the return value equals size - 1. + // The downside to this is that whenever we try to format a string where the + // size is 1 below the built-in capacity, the size is needlessly increased. + + // Try increasing the size of the string until it fits. int size = _builtinCapacity; do { size *= 2; @@ -455,7 +463,7 @@ String String::printf(const char *fmt, ...) { va_start(va, fmt); len = vsnprintf(output._str, size, fmt, va); va_end(va); - } while (len == -1 || len >= size); + } while (len == -1 || len >= size - 1); output._size = len; } else if (len < (int)_builtinCapacity) { // vsnprintf succeeded diff --git a/common/str.h b/common/str.h index e06455fc717..826974518d5 100644 --- a/common/str.h +++ b/common/str.h @@ -218,7 +218,7 @@ public: /** * Printf-like function. Returns a formatted String. */ - static Common::String printf(const char *fmt, ...) GCC_PRINTF(1,2); + static Common::String format(const char *fmt, ...) GCC_PRINTF(1,2); public: typedef char * iterator; @@ -288,7 +288,7 @@ extern char *trim(char *t); Common::String lastPathComponent(const Common::String &path, const char sep); /** - * Normalize a gien path to a canonical form. In particular: + * Normalize a given path to a canonical form. In particular: * - trailing separators are removed: /foo/bar/ -> /foo/bar * - double separators (= empty components) are removed: /foo//bar -> /foo/bar * - dot components are removed: /foo/./bar -> /foo/bar diff --git a/common/stream.cpp b/common/stream.cpp index 414f5f8c585..dfb92817346 100644 --- a/common/stream.cpp +++ b/common/stream.cpp @@ -24,6 +24,9 @@ */ #include "common/stream.h" +#include "common/memstream.h" +#include "common/substream.h" +#include "common/bufferedstream.h" #include "common/str.h" #include "common/util.h" @@ -33,7 +36,7 @@ void WriteStream::writeString(const String &str) { write(str.c_str(), str.size()); } -MemoryReadStream *ReadStream::readStream(uint32 dataSize) { +SeekableReadStream *ReadStream::readStream(uint32 dataSize) { void *buf = malloc(dataSize); dataSize = read(buf, dataSize); assert(dataSize > 0); @@ -49,13 +52,6 @@ uint32 MemoryReadStream::read(void *dataPtr, uint32 dataSize) { } memcpy(dataPtr, _ptr, dataSize); - if (_encbyte) { - byte *p = (byte *)dataPtr; - byte *end = p + dataSize; - while (p < end) - *p++ ^= _encbyte; - } - _ptr += dataSize; _pos += dataSize; @@ -89,6 +85,33 @@ bool MemoryReadStream::seek(int32 offs, int whence) { return true; // FIXME: STREAM REWRITE } +bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) { + // Pre-Condition + assert(_pos <= _size); + switch (whence) { + case SEEK_END: + // SEEK_END works just like SEEK_SET, only 'reversed', + // i.e. from the end. + offs = _size + offs; + // Fall through + case SEEK_SET: + _ptr = _data + offs; + _pos = offs; + break; + + case SEEK_CUR: + _ptr += offs; + _pos += offs; + break; + } + // Post-Condition + assert(_pos <= _size); + + return true; // FIXME: STREAM REWRITE +} + +#pragma mark - + enum { LF = 0x0A, CR = 0x0D @@ -222,6 +245,37 @@ bool SeekableSubReadStream::seek(int32 offset, int whence) { return ret; } + +#pragma mark - + +namespace { + +/** + * Wrapper class which adds buffering to any given ReadStream. + * Users can specify how big the buffer should be, and whether the + * wrapped stream should be disposed when the wrapper is disposed. + */ +class BufferedReadStream : virtual public ReadStream { +protected: + ReadStream *_parentStream; + DisposeAfterUse::Flag _disposeParentStream; + byte *_buf; + uint32 _pos; + bool _eos; // end of stream + uint32 _bufSize; + uint32 _realBufSize; + +public: + BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream); + virtual ~BufferedReadStream(); + + virtual bool eos() const { return _eos; } + virtual bool err() const { return _parentStream->err(); } + virtual void clearErr() { _eos = false; _parentStream->clearErr(); } + + virtual uint32 read(void *dataPtr, uint32 dataSize); +}; + BufferedReadStream::BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) : _parentStream(parentStream), _disposeParentStream(disposeParentStream), @@ -286,10 +340,39 @@ uint32 BufferedReadStream::read(void *dataPtr, uint32 dataSize) { // Satisfy the request from the buffer memcpy(dataPtr, _buf + _pos, dataSize); _pos += dataSize; - } + } return alreadyRead + dataSize; } +} // End of nameless namespace + + +ReadStream *wrapBufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) { + if (parentStream) + return new BufferedReadStream(parentStream, bufSize, disposeParentStream); + return 0; +} + +#pragma mark - + +namespace { + +/** + * Wrapper class which adds buffering to any given SeekableReadStream. + * @see BufferedReadStream + */ +class BufferedSeekableReadStream : public BufferedReadStream, public SeekableReadStream { +protected: + SeekableReadStream *_parentStream; +public: + BufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); + + virtual int32 pos() const { return _parentStream->pos() - (_bufSize - _pos); } + virtual int32 size() const { return _parentStream->size(); } + + virtual bool seek(int32 offset, int whence = SEEK_SET); +}; + BufferedSeekableReadStream::BufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) : BufferedReadStream(parentStream, bufSize, disposeParentStream), _parentStream(parentStream) { @@ -301,7 +384,7 @@ bool BufferedSeekableReadStream::seek(int32 offset, int whence) { // Note: We could try to handle SEEK_END and SEEK_SET, too, but // since they are rarely used, it seems not worth the effort. _eos = false; // seeking always cancels EOS - + if (whence == SEEK_CUR && (int)_pos + offset >= 0 && _pos + offset <= _bufSize) { _pos += offset; @@ -319,82 +402,94 @@ bool BufferedSeekableReadStream::seek(int32 offset, int whence) { return true; } -BufferedWriteStream::BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) - : _parentStream(parentStream), - _disposeParentStream(disposeParentStream), - _pos(0), - _bufSize(bufSize) { +} // End of nameless namespace - assert(parentStream); - _buf = new byte[bufSize]; - assert(_buf); +SeekableReadStream *wrapBufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream) { + if (parentStream) + return new BufferedSeekableReadStream(parentStream, bufSize, disposeParentStream); + return 0; } -BufferedWriteStream::~BufferedWriteStream() { - assert(flush()); - - if (_disposeParentStream) +#pragma mark - + +namespace { + +/** + * Wrapper class which adds buffering to any WriteStream. + */ +class BufferedWriteStream : public WriteStream { +protected: + WriteStream *_parentStream; + byte *_buf; + uint32 _pos; + const uint32 _bufSize; + + /** + * Write out the data in the buffer. + * + * @note This method is identical to flush() (which actually is + * implemented by calling this method), except that it is not + * virtual, hence there is less overhead calling it. + */ + bool flushBuffer() { + const uint32 bytesToWrite = _pos; + + if (bytesToWrite) { + _pos = 0; + if (_parentStream->write(_buf, bytesToWrite) != bytesToWrite) + return false; + } + return true; + } + +public: + BufferedWriteStream(WriteStream *parentStream, uint32 bufSize) + : _parentStream(parentStream), + _pos(0), + _bufSize(bufSize) { + + assert(parentStream); + _buf = new byte[bufSize]; + assert(_buf); + } + + virtual ~BufferedWriteStream() { + const bool flushResult = flushBuffer(); + assert(flushResult); + delete _parentStream; - - delete[] _buf; -} -uint32 BufferedWriteStream::write(const void *dataPtr, uint32 dataSize) { - // check if we have enough space for writing to the buffer - if (_bufSize - _pos >= dataSize) { - memcpy(_buf + _pos, dataPtr, dataSize); - _pos += dataSize; - } else if (_bufSize >= dataSize) { // check if we can flush the buffer and load the data - // flush the buffer - assert(flushBuffer()); - memcpy(_buf, dataPtr, dataSize); - _pos += dataSize; - } else { // too big for our buffer - // flush the buffer - assert(flushBuffer()); - return _parentStream->write(dataPtr, dataSize); + delete[] _buf; } - return dataSize; -} -bool BufferedWriteStream::flushBuffer() { - uint32 bytesToWrite = _pos; - - if (bytesToWrite) { - _pos = 0; - if (_parentStream->write(_buf, bytesToWrite) != bytesToWrite) - return false; + virtual uint32 write(const void *dataPtr, uint32 dataSize) { + // check if we have enough space for writing to the buffer + if (_bufSize - _pos >= dataSize) { + memcpy(_buf + _pos, dataPtr, dataSize); + _pos += dataSize; + } else if (_bufSize >= dataSize) { // check if we can flush the buffer and load the data + const bool flushResult = flushBuffer(); + assert(flushResult); + memcpy(_buf, dataPtr, dataSize); + _pos += dataSize; + } else { // too big for our buffer + const bool flushResult = flushBuffer(); + assert(flushResult); + return _parentStream->write(dataPtr, dataSize); + } + return dataSize; } - return true; -} -bool BufferedWriteStream::flush() { - return flushBuffer(); -} + virtual bool flush() { return flushBuffer(); } -bool MemoryWriteStreamDynamic::seek(int32 offs, int whence) { - // Pre-Condition - assert(_pos <= _size); - switch (whence) { - case SEEK_END: - // SEEK_END works just like SEEK_SET, only 'reversed', - // i.e. from the end. - offs = _size + offs; - // Fall through - case SEEK_SET: - _ptr = _data + offs; - _pos = offs; - break; +}; - case SEEK_CUR: - _ptr += offs; - _pos += offs; - break; - } - // Post-Condition - assert(_pos <= _size); +} // End of nameless namespace - return true; // FIXME: STREAM REWRITE +WriteStream *wrapBufferedWriteStream(WriteStream *parentStream, uint32 bufSize) { + if (parentStream) + return new BufferedWriteStream(parentStream, bufSize); + return 0; } } // End of namespace Common diff --git a/common/stream.h b/common/stream.h index d46a7ca3e66..ce768484d17 100644 --- a/common/stream.h +++ b/common/stream.h @@ -32,7 +32,7 @@ namespace Common { class String; -class MemoryReadStream; +class SeekableReadStream; /** * Virtual base class for both ReadStream and WriteStream. @@ -301,7 +301,7 @@ public: * the end of the stream was reached. Which can be determined by * calling err() and eos(). */ - MemoryReadStream *readStream(uint32 dataSize); + SeekableReadStream *readStream(uint32 dataSize); }; @@ -389,78 +389,18 @@ public: virtual String readLine(); }; - /** - * SubReadStream provides access to a ReadStream restricted to the range - * [currentPosition, currentPosition+end). - * - * Manipulating the parent stream directly /will/ mess up a substream. - * Likewise, manipulating two substreams of a parent stream will cause them to - * step on each others toes. + * This is a ReadStream mixin subclass which adds non-endian read + * methods whose endianness is set during the stream creation. */ -class SubReadStream : virtual public ReadStream { -protected: - ReadStream *_parentStream; - DisposeAfterUse::Flag _disposeParentStream; - uint32 _pos; - uint32 _end; - bool _eos; -public: - SubReadStream(ReadStream *parentStream, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO) - : _parentStream(parentStream), - _disposeParentStream(disposeParentStream), - _pos(0), - _end(end), - _eos(false) { - assert(parentStream); - } - ~SubReadStream() { - if (_disposeParentStream) - delete _parentStream; - } - - virtual bool eos() const { return _eos; } - virtual bool err() const { return _parentStream->err(); } - virtual void clearErr() { _eos = false; _parentStream->clearErr(); } - virtual uint32 read(void *dataPtr, uint32 dataSize); -}; - -/* - * SeekableSubReadStream provides access to a SeekableReadStream restricted to - * the range [begin, end). - * The same caveats apply to SeekableSubReadStream as do to SeekableReadStream. - * - * Manipulating the parent stream directly /will/ mess up a substream. - * @see SubReadStream - */ -class SeekableSubReadStream : public SubReadStream, public SeekableReadStream { -protected: - SeekableReadStream *_parentStream; - uint32 _begin; -public: - SeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); - - virtual int32 pos() const { return _pos - _begin; } - virtual int32 size() const { return _end - _begin; } - - virtual bool seek(int32 offset, int whence = SEEK_SET); -}; - -/** - * This is a wrapper around SeekableSubReadStream, but it adds non-endian - * read methods whose endianness is set on the stream creation. - * - * Manipulating the parent stream directly /will/ mess up a substream. - * @see SubReadStream - */ -class SeekableSubReadStreamEndian : public SeekableSubReadStream { +class ReadStreamEndian : virtual public ReadStream { private: const bool _bigEndian; public: - SeekableSubReadStreamEndian(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool bigEndian = false, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO) - : SeekableSubReadStream(parentStream, begin, end, disposeParentStream), _bigEndian(bigEndian) { - } + ReadStreamEndian(bool bigEndian) : _bigEndian(bigEndian) {} + + bool isBE() const { return _bigEndian; } uint16 readUint16() { uint16 val; @@ -484,230 +424,14 @@ public: }; /** - * Wrapper class which adds buffering to any given ReadStream. - * Users can specify how big the buffer should be, and whether the - * wrapped stream should be disposed when the wrapper is disposed. + * This is a SeekableReadStream subclass which adds non-endian read + * methods whose endianness is set during the stream creation. */ -class BufferedReadStream : virtual public ReadStream { -protected: - ReadStream *_parentStream; - DisposeAfterUse::Flag _disposeParentStream; - byte *_buf; - uint32 _pos; - bool _eos; // end of stream - uint32 _bufSize; - uint32 _realBufSize; - +class SeekableReadStreamEndian : public SeekableReadStream, public ReadStreamEndian { public: - BufferedReadStream(ReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); - virtual ~BufferedReadStream(); - - virtual bool eos() const { return _eos; } - virtual bool err() const { return _parentStream->err(); } - virtual void clearErr() { _eos = false; _parentStream->clearErr(); } - - virtual uint32 read(void *dataPtr, uint32 dataSize); + SeekableReadStreamEndian(bool bigEndian) : ReadStreamEndian(bigEndian) {} }; -/** - * Wrapper class which adds buffering to any given SeekableReadStream. - * @see BufferedReadStream - */ -class BufferedSeekableReadStream : public BufferedReadStream, public SeekableReadStream { -protected: - SeekableReadStream *_parentStream; -public: - BufferedSeekableReadStream(SeekableReadStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); - - virtual int32 pos() const { return _parentStream->pos() - (_bufSize - _pos); } - virtual int32 size() const { return _parentStream->size(); } - - virtual bool seek(int32 offset, int whence = SEEK_SET); -}; - -/** - * Wrapper class which adds buffering to any WriteStream. - */ -class BufferedWriteStream : public WriteStream { -protected: - WriteStream *_parentStream; - DisposeAfterUse::Flag _disposeParentStream; - byte *_buf; - uint32 _pos; - uint32 _bufSize; - bool flushBuffer(); // write out the data in the buffer - -public: - BufferedWriteStream(WriteStream *parentStream, uint32 bufSize, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); - virtual ~BufferedWriteStream(); - - virtual uint32 write(const void *dataPtr, uint32 dataSize); - virtual bool flush(); -}; - -/** - * Simple memory based 'stream', which implements the ReadStream interface for - * a plain memory block. - */ -class MemoryReadStream : public SeekableReadStream { -private: - const byte * const _ptrOrig; - const byte *_ptr; - const uint32 _size; - uint32 _pos; - byte _encbyte; - DisposeAfterUse::Flag _disposeMemory; - bool _eos; - -public: - - /** - * This constructor takes a pointer to a memory buffer and a length, and - * wraps it. If disposeMemory is true, the MemoryReadStream takes ownership - * of the buffer and hence free's it when destructed. - */ - MemoryReadStream(const byte *dataPtr, uint32 dataSize, DisposeAfterUse::Flag disposeMemory = DisposeAfterUse::NO) : - _ptrOrig(dataPtr), - _ptr(dataPtr), - _size(dataSize), - _pos(0), - _encbyte(0), - _disposeMemory(disposeMemory), - _eos(false) {} - - ~MemoryReadStream() { - if (_disposeMemory) - free(const_cast(_ptrOrig)); - } - - void setEnc(byte value) { _encbyte = value; } - - uint32 read(void *dataPtr, uint32 dataSize); - - bool eos() const { return _eos; } - void clearErr() { _eos = false; } - - int32 pos() const { return _pos; } - int32 size() const { return _size; } - - bool seek(int32 offs, int whence = SEEK_SET); -}; - - -/** - * This is a wrapper around MemoryReadStream, but it adds non-endian - * read methods whose endianness is set on the stream creation. - */ -class MemoryReadStreamEndian : public Common::MemoryReadStream { -private: - const bool _bigEndian; - -public: - MemoryReadStreamEndian(const byte *buf, uint32 len, bool bigEndian = false) : MemoryReadStream(buf, len), _bigEndian(bigEndian) {} - - uint16 readUint16() { - uint16 val; - read(&val, 2); - return (_bigEndian) ? TO_BE_16(val) : TO_LE_16(val); - } - - uint32 readUint32() { - uint32 val; - read(&val, 4); - return (_bigEndian) ? TO_BE_32(val) : TO_LE_32(val); - } - - FORCEINLINE int16 readSint16() { - return (int16)readUint16(); - } - - FORCEINLINE int32 readSint32() { - return (int32)readUint32(); - } -}; - -/** - * Simple memory based 'stream', which implements the WriteStream interface for - * a plain memory block. - */ -class MemoryWriteStream : public WriteStream { -private: - byte *_ptr; - const uint32 _bufSize; - uint32 _pos; -public: - MemoryWriteStream(byte *buf, uint32 len) : _ptr(buf), _bufSize(len), _pos(0) {} - - uint32 write(const void *dataPtr, uint32 dataSize) { - // Write at most as many bytes as are still available... - if (dataSize > _bufSize - _pos) - dataSize = _bufSize - _pos; - memcpy(_ptr, dataPtr, dataSize); - _ptr += dataSize; - _pos += dataSize; - return dataSize; - } - - uint32 pos() const { return _pos; } - uint32 size() const { return _bufSize; } -}; - -/** - * A sort of hybrid between MemoryWriteStream and Array classes. A stream - * that grows as it's written to. - */ -class MemoryWriteStreamDynamic : public Common::WriteStream { -private: - uint32 _capacity; - uint32 _size; - byte *_ptr; - byte *_data; - uint32 _pos; - DisposeAfterUse::Flag _disposeMemory; - - void ensureCapacity(uint32 new_len) { - if (new_len <= _capacity) - return; - - byte *old_data = _data; - - _capacity = new_len + 32; - _data = (byte *)malloc(_capacity); - _ptr = _data + _pos; - - if (old_data) { - // Copy old data - memcpy(_data, old_data, _size); - free(old_data); - } - - _size = new_len; - } -public: - MemoryWriteStreamDynamic(DisposeAfterUse::Flag disposeMemory = DisposeAfterUse::NO) : _capacity(0), _size(0), _ptr(0), _data(0), _pos(0), _disposeMemory(disposeMemory) {} - - ~MemoryWriteStreamDynamic() { - if (_disposeMemory) - free(_data); - } - - uint32 write(const void *dataPtr, uint32 dataSize) { - ensureCapacity(_pos + dataSize); - memcpy(_ptr, dataPtr, dataSize); - _ptr += dataSize; - _pos += dataSize; - if (_pos > _size) - _size = _pos; - return dataSize; - } - - uint32 pos() const { return _pos; } - uint32 size() const { return _size; } - - byte *getData() { return _data; } - - bool seek(int32 offset, int whence = SEEK_SET); -}; } // End of namespace Common diff --git a/common/substream.h b/common/substream.h new file mode 100644 index 00000000000..6cf68d4adfc --- /dev/null +++ b/common/substream.h @@ -0,0 +1,107 @@ +/* Residual - A 3D game interpreter + * + * 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 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_SUBSTREAM_H +#define COMMON_SUBSTREAM_H + +#include "common/stream.h" + +namespace Common { + +/** + * SubReadStream provides access to a ReadStream restricted to the range + * [currentPosition, currentPosition+end). + * + * Manipulating the parent stream directly /will/ mess up a substream. + * Likewise, manipulating two substreams of a parent stream will cause them to + * step on each others toes. + */ +class SubReadStream : virtual public ReadStream { +protected: + ReadStream *_parentStream; + DisposeAfterUse::Flag _disposeParentStream; + uint32 _pos; + uint32 _end; + bool _eos; +public: + SubReadStream(ReadStream *parentStream, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO) + : _parentStream(parentStream), + _disposeParentStream(disposeParentStream), + _pos(0), + _end(end), + _eos(false) { + assert(parentStream); + } + ~SubReadStream() { + if (_disposeParentStream) + delete _parentStream; + } + + virtual bool eos() const { return _eos; } + virtual bool err() const { return _parentStream->err(); } + virtual void clearErr() { _eos = false; _parentStream->clearErr(); } + virtual uint32 read(void *dataPtr, uint32 dataSize); +}; + +/* + * SeekableSubReadStream provides access to a SeekableReadStream restricted to + * the range [begin, end). + * The same caveats apply to SeekableSubReadStream as do to SeekableReadStream. + * + * Manipulating the parent stream directly /will/ mess up a substream. + * @see SubReadStream + */ +class SeekableSubReadStream : public SubReadStream, public SeekableReadStream { +protected: + SeekableReadStream *_parentStream; + uint32 _begin; +public: + SeekableSubReadStream(SeekableReadStream *parentStream, uint32 begin, uint32 end, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO); + + virtual int32 pos() const { return _pos - _begin; } + virtual int32 size() const { return _end - _begin; } + + virtual bool seek(int32 offset, int whence = SEEK_SET); +}; + +/** + * This is a SeekableSubReadStream subclass which adds non-endian + * read methods whose endianness is set on the stream creation. + * + * Manipulating the parent stream directly /will/ mess up a substream. + * @see SubReadStream + */ +class SeekableSubReadStreamEndian : public SeekableSubReadStream, public ReadStreamEndian { +public: + SeekableSubReadStreamEndian(SeekableReadStream *parentStream, uint32 begin, uint32 end, bool bigEndian, DisposeAfterUse::Flag disposeParentStream = DisposeAfterUse::NO) + : SeekableSubReadStream(parentStream, begin, end, disposeParentStream), + ReadStreamEndian(bigEndian) { + } +}; + + +} // End of namespace Common + +#endif diff --git a/common/sys.h b/common/sys.h index 559d84f77dd..d9b763e60cb 100644 --- a/common/sys.h +++ b/common/sys.h @@ -8,12 +8,12 @@ * 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. @@ -94,6 +94,11 @@ #include #include #include + // MSVC does not define M_PI, M_SQRT2 and other math defines by default. + // _USE_MATH_DEFINES must be defined in order to have these defined, thus + // we enable it here. For more information, check: + // http://msdn.microsoft.com/en-us/library/4hwaceh6(v=VS.100).aspx + #define _USE_MATH_DEFINES #include #endif @@ -232,30 +237,11 @@ // You need to set this manually if necessary // #define SYSTEM_NEED_ALIGNMENT - #if defined(__DECCXX) // Assume alpha architecture - #define INVERSE_MKID - #define SYSTEM_NEED_ALIGNMENT - #endif - -#elif defined(__PALMOS_TRAPS__) || defined (__PALMOS_ARMLET__) - -#ifdef __PALMOS_ARMLET__ - #include -#endif - #define SYSTEM_LITTLE_ENDIAN - - #define strcasecmp stricmp - #define strncasecmp strnicmp - - #define SYSTEM_NEED_ALIGNMENT - #define STRINGBUFLEN 256 - - extern const char *RESIDUAL_SAVEPATH; - - #if !defined(COMPILE_ZODIAC) && !defined(COMPILE_OS5) - # define NEWGUI_256 - #else - # undef UNUSED + // Very BAD hack following, used to avoid triggering an assert in uClibc dingux library + // "toupper" when pressing keyboard function keys. + #if defined(DINGUX) + #undef toupper + #define toupper(c) (((c & 0xFF) >= 97) && ((c & 0xFF) <= 122) ? ((c & 0xFF) - 32) : (c & 0xFF)) #endif #elif defined(__DC__) @@ -313,6 +299,7 @@ #elif defined(__PSP__) #include + #include "backends/platform/psp/memory.h" #define SYSTEM_LITTLE_ENDIAN #define SYSTEM_NEED_ALIGNMENT @@ -357,6 +344,10 @@ #if !defined(FORCEINLINE) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) #define FORCEINLINE inline __attribute__((__always_inline__)) #endif +#elif defined(__INTEL_COMPILER) + #define NORETURN_POST __attribute__((__noreturn__)) + #define PACKED_STRUCT __attribute__((__packed__)) + #define GCC_PRINTF(x,y) __attribute__((__format__(printf, x, y))) #else #define PACKED_STRUCT #define GCC_PRINTF(x,y) @@ -422,5 +413,4 @@ typedef uint16 OverlayColor; #endif - #endif diff --git a/common/system.cpp b/common/system.cpp index e5ffaf8019a..ce469db48d4 100644 --- a/common/system.cpp +++ b/common/system.cpp @@ -23,8 +23,27 @@ * */ +// Disable symbol overrides so that we can use system headers. +// FIXME: Necessary for the PS2 port, should get rid of this eventually. +#define FORBIDDEN_SYMBOL_ALLOW_ALL + #include "common/system.h" +#ifdef __PLAYSTATION2__ + // for those replaced fopen/fread/etc functions + #include "backends/platform/ps2/fileio.h" + + #define fputs(str, file) ps2_fputs(str, file) + #define fflush(a) ps2_fflush(a) +#endif + +#ifdef __DS__ + #include "backends/fs/ds/ds-fs.h" + + #define fputs(str, file) DS::std_fwrite(str, strlen(str), 1, file) + #define fflush(file) DS::std_fflush(file) +#endif + OSystem *g_system = 0; OSystem::OSystem() { @@ -33,10 +52,23 @@ OSystem::OSystem() { OSystem::~OSystem() { } -bool OSystem::openCD(int drive) { - return false; +void OSystem::fatalError() { + quit(); + exit(1); } -bool OSystem::pollCD() { - return false; +void OSystem::logMessage(LogMessageType::Type type, const char *message) { + FILE *output = 0; + + if (type == LogMessageType::kDebug) + output = stdout; + else + output = stderr; + + fputs(message, output); + fflush(output); +} + +Common::String OSystem::getSystemLanguage() const { + return "en_US"; } diff --git a/common/system.h b/common/system.h index 037c847d4b8..471e91ac0f7 100644 --- a/common/system.h +++ b/common/system.h @@ -52,6 +52,7 @@ namespace Common { class HardwareKeySet; } +class AudioCDManager; class FilesystemFactory; /** @@ -72,8 +73,25 @@ struct TimeDate { int tm_year; ///< year - 1900 }; +namespace LogMessageType { + +enum Type { + kError, + kWarning, + kDebug +}; + +} // End of namespace LogMessageType + /** - * Interface for Residual backends. + * Interface for ScummVM backends. If you want to port ScummVM to a system + * which is not currently covered by any of our backends, this is the place + * to start. ScummVM will create an instance of a subclass of this interface + * and use it to interact with the system. + * + * In particular, a backend provides a video surface for ScummVM to draw in; + * methods to create timers, to handle user input events, + * control audio CD playback, and sound output. */ class OSystem : Common::NonCopyable { protected: @@ -121,21 +139,6 @@ public: */ kFeatureFullscreenMode, - /** - * Control aspect ratio correction. Aspect ratio correction is used to - * correct games running at 320x200 (i.e with an aspect ratio of 8:5), - * but which on their original hardware were displayed with the - * standard 4:3 ratio (that is, the original graphics used non-square - * pixels). When the backend support this, then games running at - * 320x200 pixels should be scaled up to 320x240 pixels. For all other - * resolutions, ignore this feature flag. - * @note You can find utility functions in common/scaler.h which can - * be used to implement aspect ratio correction. In particular, - * stretch200To240() can stretch a rect, including (very fast) - * interpolation, and works in-place. - */ - kFeatureAspectRatioCorrection, - /** * Determine whether a virtual keyboard is too be shown or not. * This would mostly be implemented by backends for hand held devices, @@ -468,46 +471,14 @@ public: - /** - * @name Audio CD - * The methods in this group deal with Audio CD playback. - * The default implementation simply does nothing. - * This is the lower level implementation as provided by the - * backends. The engines should use the Audio::AudioCDManager - * class instead of using it directly. - */ + /** @name Audio CD */ //@{ /** - * Initialise the specified CD drive for audio playback. - * @return true if the CD drive was inited succesfully + * Return the audio cd manager. For more information, refer to the + * AudioCDManager documentation. */ - virtual bool openCD(int drive); - - /** - * Poll CD status. - * @return true if CD audio is playing - */ - virtual bool pollCD(); - - /** - * Start audio CD playback. - * @param track the track to play. - * @param num_loops how often playback should be repeated (-1 = infinitely often). - * @param start_frame the frame at which playback should start (75 frames = 1 second). - * @param duration the number of frames to play. - */ - virtual void playCD(int track, int num_loops, int start_frame, int duration) {} - - /** - * Stop audio CD playback. - */ - virtual void stopCD() {} - - /** - * Update cdrom audio status. - */ - virtual void updateCD() {} + virtual AudioCDManager *getAudioCDManager() = 0; //@} @@ -518,6 +489,13 @@ public: /** Quit (exit) the application. */ virtual void quit() = 0; + /** + * Signals that a fatal error inside the client code has happened. + * + * This should quit the application. + */ + virtual void fatalError(); + /** * Set a window caption or any other comparable status display to the * given value. The caption must be a pure ISO LATIN 1 string. Passing a @@ -528,6 +506,22 @@ public: */ virtual void setWindowCaption(const char *caption) {} + /** + * Display a message in an 'on screen display'. That is, display it in a + * fashion where it is visible on or near the screen (e.g. in a transparent + * rectangle over the regular screen content; or in a message box beneath + * it; etc.). + * + * Currently, only pure ASCII messages can be expected to show correctly. + * + * @note There is a default implementation in BaseBackend which uses a + * TimedMessageDialog to display the message. Hence implementing + * this is optional. + * + * @param msg the message to display on screen + */ + virtual void displayMessageOnOSD(const char *msg) = 0; + /** * Return the SaveFileManager, used to store and load savestates * and other modifiable persistent game data. For more information, @@ -570,6 +564,38 @@ public: */ virtual Common::WriteStream *createConfigWriteStream() = 0; + /** + * Logs a given message. + * + * It is up to the backend where to log the different messages. + * The backend should aim at using a non-buffered output for it + * so that no log data is lost in case of a crash. + * + * The default implementation outputs them on stdout/stderr. + * + * @param type the type of the message + * @param message the message itself + */ + virtual void logMessage(LogMessageType::Type type, const char *message); + + /** + * Returns the locale of the system. + * + * This returns the currently set up locale of the system, on which + * ScummVM is run. + * + * The format of the locale is language_country. These should match + * the POSIX locale values. + * + * For information about POSIX locales read here: + * http://en.wikipedia.org/wiki/Locale#POSIX-type_platforms + * + * The default implementation returns "en_US". + * + * @return locale of the system + */ + virtual Common::String getSystemLanguage() const; + //@} }; diff --git a/common/textconsole.cpp b/common/textconsole.cpp index c98d6e06ef8..4f3ac4e2ee4 100644 --- a/common/textconsole.cpp +++ b/common/textconsole.cpp @@ -25,32 +25,6 @@ #include "common/textconsole.h" #include "common/system.h" -#ifdef _WIN32_WCE -// This is required for the debugger attachment -extern bool isSmartphone(); -#endif - -#ifdef __PLAYSTATION2__ - // for those replaced fopen/fread/etc functions - #include "backends/platform/ps2/fileio.h" - - #define fputs(str, file) ps2_fputs(str, file) -#endif - -#ifdef __DS__ - #include "backends/fs/ds/ds-fs.h" - - #define fputs(str, file) DS::std_fwrite(str, strlen(str), 1, file) -#endif - -#ifdef ANDROID - #include -#endif - -#ifdef __PSP__ - #include "backends/platform/psp/trace.h" -#endif - namespace Common { static OutputFormatter s_errorOutputFormatter = 0; @@ -79,24 +53,12 @@ void warning(const char *s, ...) { vsnprintf(buf, STRINGBUFLEN, s, va); va_end(va); -#if defined( ANDROID ) - __android_log_write(ANDROID_LOG_WARN, "ScummVM", buf); -#elif !defined (__SYMBIAN32__) - fputs("WARNING: ", stderr); - fputs(buf, stderr); - fputs("!\n", stderr); -#endif + Common::String output = Common::String::format("WARNING: %s!\n", buf); -#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 + if (g_system) + g_system->logMessage(LogMessageType::kWarning, output.c_str()); + // TODO: Think of a good fallback in case we do not have + // any OSystem yet. } #endif @@ -119,53 +81,22 @@ void NORETURN_PRE error(const char *s, ...) { strncpy(buf_output, buf_input, STRINGBUFLEN); } - buf_output[STRINGBUFLEN-3] = '\0'; - buf_output[STRINGBUFLEN-2] = '\0'; - buf_output[STRINGBUFLEN-1] = '\0'; + 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 (g_system) + g_system->logMessage(LogMessageType::kError, buf_output); + // TODO: Think of a good fallback in case we do not have + // any OSystem yet. // 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 ANDROID - __android_log_assert("Fatal error", "ScummVM", "%s", buf_output); -#endif - -#ifdef __SYMBIAN32__ - Symbian::FatalError(buf_output); -#endif - -#ifdef __PSP__ - PspDebugTrace(false, "%s", buf_output); // write to file -#endif - - // Finally exit. quit() will terminate the program if g_system is present if (g_system) - g_system->quit(); + g_system->fatalError(); #if defined(SAMSUNGTV) // FIXME diff --git a/common/translation.cpp b/common/translation.cpp index 38482fd7145..05b8bbacea5 100644 --- a/common/translation.cpp +++ b/common/translation.cpp @@ -31,17 +31,16 @@ #define TRANSLATIONS_DAT_VER 2 -#include "translation.h" +#include "common/translation.h" #include "common/archive.h" #include "common/config-manager.h" +#include "common/file.h" +#include "common/fs.h" +#include "common/system.h" -DECLARE_SINGLETON(Common::TranslationManager) +#ifdef USE_TRANSLATION -#ifdef USE_DETECTLANG -#ifndef WIN32 -#include -#endif // !WIN32 -#endif +DECLARE_SINGLETON(Common::TranslationManager); namespace Common { @@ -49,74 +48,9 @@ bool operator<(const TLanguage &l, const TLanguage &r) { return strcmp(l.name, r.name) < 0; } -#ifdef USE_TRANSLATION - -// Translation enabled - TranslationManager::TranslationManager() : _currentLang(-1) { loadTranslationsInfoDat(); -#ifdef USE_DETECTLANG -#ifdef WIN32 - // We can not use "setlocale" (at least not for MSVC builds), since it - // will return locales like: "English_USA.1252", thus we need a special - // way to determine the locale string for Win32. - char langName[9]; - char ctryName[9]; - - const LCID languageIdentifier = GetThreadLocale(); - - // GetLocalInfo is only supported starting from Windows 2000, according to this: - // http://msdn.microsoft.com/en-us/library/dd318101%28VS.85%29.aspx - // On the other hand the locale constants used, seem to exist on Windows 98 too, - // check this for that: http://msdn.microsoft.com/en-us/library/dd464799%28v=VS.85%29.aspx - // - // I am not exactly sure what is the truth now, it might be very well that this breaks - // support for systems older than Windows 2000.... - // - // TODO: Check whether this (or ScummVM at all ;-) works on a system with Windows 98 for - // example and if it does not and we still want Windows 9x support, we should definitly - // think of another solution. - if (GetLocaleInfo(languageIdentifier, LOCALE_SISO639LANGNAME, langName, sizeof(langName)) != 0 && - GetLocaleInfo(languageIdentifier, LOCALE_SISO3166CTRYNAME, ctryName, sizeof(ctryName)) != 0) { - _syslang = langName; - _syslang += "_"; - _syslang += ctryName; - } else { - _syslang = "C"; - } -#else // WIN32 - // Activating current locale settings - const char *locale = setlocale(LC_ALL, ""); - - // Detect the language from the locale - if (!locale) { - _syslang = "C"; - } else { - int length = 0; - - // Strip out additional information, like - // ".UTF-8" or the like. We do this, since - // our translation languages are usually - // specified without any charset information. - for (int i = 0; locale[i]; ++i) { - // TODO: Check whether "@" should really be checked - // here. - if (locale[i] == '.' || locale[i] == ' ' || locale[i] == '@') { - length = i; - break; - } - - length = i; - } - - _syslang = String(locale, length); - } -#endif // WIN32 -#else // USE_DETECTLANG - _syslang = "C"; -#endif // USE_DETECTLANG - // Set the default language setLanguage(""); } @@ -124,43 +58,68 @@ TranslationManager::TranslationManager() : _currentLang(-1) { TranslationManager::~TranslationManager() { } -void TranslationManager::setLanguage(const char *lang) { - // Get lang index +int32 TranslationManager::findMatchingLanguage(const String &lang) { + uint langLength = lang.size(); + uint numLangs = _langs.size(); + + // Try to match languages of the same length or longer ones + // that can be cut at the length of the given one. + for (uint i = 0; i < numLangs; ++i) { + uint iLength = _langs[i].size(); + if (iLength >= langLength) { + // Found a candidate; compare the full string by default. + String cmpLang = _langs[i]; + + if ((iLength > langLength) && (_langs[i][langLength] == '_')) { + // It has a separation mark at the length of the + // requested language, so we can cut it. + cmpLang = String(_langs[i].c_str(), langLength); + } + if (lang.equalsIgnoreCase(cmpLang)) + return i; + } + } + + // Couldn't find a matching language. + return -1; +} + +void TranslationManager::setLanguage(const String &lang) { + // Get lang index. int langIndex = -1; String langStr(lang); if (langStr.empty()) - langStr = _syslang; + langStr = g_system->getSystemLanguage(); - // Searching for a valid language - for (unsigned int i = 0; i < _langs.size() && langIndex == -1; ++i) { - if (langStr == _langs[i]) - langIndex = i; + // Search for the given language or a variant of it. + langIndex = findMatchingLanguage(langStr); + + // Try to find a partial match taking away parts of the original language. + const char *lastSep; + String langCut(langStr); + while ((langIndex == -1) && (lastSep = strrchr(langCut.c_str(), '_'))) { + langCut = String(langCut.c_str(), lastSep); + langIndex = findMatchingLanguage(langCut); } - // Try partial match - for (unsigned int i = 0; i < _langs.size() && langIndex == -1; ++i) { - if (strncmp(langStr.c_str(), _langs[i].c_str(), 2) == 0) - langIndex = i; - } - - // Load messages for that lang - // Call it even if the index is -1 to unload previously loaded translations + // Load messages for that language. + // Call it even if the index is -1 to unload previously loaded translations. if (langIndex != _currentLang) { loadLanguageDat(langIndex); _currentLang = langIndex; } } -const char *TranslationManager::getTranslation(const char *message) { +const char *TranslationManager::getTranslation(const char *message) const { return getTranslation(message, NULL); } -const char *TranslationManager::getTranslation(const char *message, const char *context) { - // if no language is set or message is empty, return msgid as is +const char *TranslationManager::getTranslation(const char *message, const char *context) const { + // If no language is set or message is empty, return msgid as is if (_currentTranslationMessages.empty() || *message == '\0') return message; - // binary-search for the msgid + // Binary-search for the msgid int leftIndex = 0; int rightIndex = _currentTranslationMessages.size() - 1; @@ -207,23 +166,23 @@ const char *TranslationManager::getTranslation(const char *message, const char * return message; } -const char *TranslationManager::getCurrentCharset() { +String TranslationManager::getCurrentCharset() const { if (_currentCharset.empty()) return "ASCII"; - return _currentCharset.c_str(); + return _currentCharset; } -const char *TranslationManager::getCurrentLanguage() { +String TranslationManager::getCurrentLanguage() const { if (_currentLang == -1) return "C"; - return _langs[_currentLang].c_str(); + return _langs[_currentLang]; } -String TranslationManager::getTranslation(const String &message) { +String TranslationManager::getTranslation(const String &message) const { return getTranslation(message.c_str()); } -String TranslationManager::getTranslation(const String &message, const String &context) { +String TranslationManager::getTranslation(const String &message, const String &context) const { return getTranslation(message.c_str(), context.c_str()); } @@ -240,7 +199,7 @@ const TLangArray TranslationManager::getSupportedLanguageNames() const { return languages; } -int TranslationManager::parseLanguage(const String lang) { +int TranslationManager::parseLanguage(const String &lang) const { for (unsigned int i = 0; i < _langs.size(); i++) { if (lang == _langs[i]) return i + 1; @@ -249,7 +208,7 @@ int TranslationManager::parseLanguage(const String lang) { return kTranslationBuiltinId; } -const char *TranslationManager::getLangById(int id) { +String TranslationManager::getLangById(int id) const { switch (id) { case kTranslationAutodetectId: return ""; @@ -257,7 +216,7 @@ const char *TranslationManager::getLangById(int id) { return "C"; default: if (id >= 0 && id - 1 < (int)_langs.size()) - return _langs[id - 1].c_str(); + return _langs[id - 1]; } // In case an invalid ID was specified, we will output a warning @@ -270,18 +229,18 @@ bool TranslationManager::openTranslationsFile(File& inFile) { // First try to open it directly (i.e. using the SearchMan). if (inFile.open("translations.dat")) return true; - + // Then look in the Themepath if we can find the file. if (ConfMan.hasKey("themepath")) return openTranslationsFile(FSNode(ConfMan.get("themepath")), inFile); - + return false; } bool TranslationManager::openTranslationsFile(const FSNode &node, File& inFile, int depth) { if (!node.exists() || !node.isReadable() || !node.isDirectory()) return false; - + // Check if we can find the file in this directory // Since File::open(FSNode) makes all the needed tests, it is not really // necessary to make them here. But it avoid printing warnings. @@ -290,21 +249,21 @@ bool TranslationManager::openTranslationsFile(const FSNode &node, File& inFile, if (inFile.open(fileNode)) return true; } - + // Check if we exceeded the given recursion depth if (depth - 1 == -1) - return false; - + return false; + // Otherwise look for it in sub-directories FSList fileList; if (!node.getChildren(fileList, FSNode::kListDirectoriesOnly)) return false; - + for (FSList::iterator i = fileList.begin(); i != fileList.end(); ++i) { if (openTranslationsFile(*i, inFile, depth == -1 ? - 1 : depth - 1)) return true; } - + // Not found in this directory or its sub-directories return false; } @@ -324,7 +283,7 @@ void TranslationManager::loadTranslationsInfoDat() { // Get number of translations int nbTranslations = in.readUint16BE(); - + // Skip all the block sizes for (int i = 0; i < nbTranslations + 2; ++i) in.readUint16BE(); @@ -335,10 +294,10 @@ void TranslationManager::loadTranslationsInfoDat() { for (int i = 0; i < nbTranslations; ++i) { len = in.readUint16BE(); in.read(buf, len); - _langs[i] = String(buf, len); + _langs[i] = String(buf, len - 1); len = in.readUint16BE(); in.read(buf, len); - _langNames[i] = String(buf, len); + _langNames[i] = String(buf, len - 1); } // Read messages @@ -347,7 +306,7 @@ void TranslationManager::loadTranslationsInfoDat() { for (int i = 0; i < numMessages; ++i) { len = in.readUint16BE(); in.read(buf, len); - _messageIds[i] = String(buf, len); + _messageIds[i] = String(buf, len - 1); } } @@ -374,7 +333,7 @@ void TranslationManager::loadLanguageDat(int index) { // Get number of translations int nbTranslations = in.readUint16BE(); if (nbTranslations != (int)_langs.size()) { - warning("The 'translations.dat' file has changed since starting ScummVM. GUI translation will not be available"); + warning("The 'translations.dat' file has changed since starting Residual. GUI translation will not be available"); return; } @@ -395,18 +354,18 @@ void TranslationManager::loadLanguageDat(int index) { // Read charset len = in.readUint16BE(); in.read(buf, len); - _currentCharset = String(buf, len); + _currentCharset = String(buf, len - 1); // Read messages for (int i = 0; i < nbMessages; ++i) { _currentTranslationMessages[i].msgid = in.readUint16BE(); len = in.readUint16BE(); in.read(buf, len); - _currentTranslationMessages[i].msgstr = String(buf, len); + _currentTranslationMessages[i].msgstr = String(buf, len - 1); len = in.readUint16BE(); if (len > 0) { in.read(buf, len); - _currentTranslationMessages[i].msgctxt = String(buf, len); + _currentTranslationMessages[i].msgctxt = String(buf, len - 1); } } } @@ -435,54 +394,6 @@ bool TranslationManager::checkHeader(File &in) { return true; } -#else // USE_TRANSLATION - -// Translation disabled - - -TranslationManager::TranslationManager() {} - -TranslationManager::~TranslationManager() {} - -void TranslationManager::setLanguage(const char *lang) {} - -const char *TranslationManager::getLangById(int id) { - return ""; -} - -int TranslationManager::parseLanguage(const String lang) { - return kTranslationBuiltinId; -} - -const char *TranslationManager::getTranslation(const char *message) { - return message; -} - -String TranslationManager::getTranslation(const String &message) { - return message; -} - -const char *TranslationManager::getTranslation(const char *message, const char *) { - return message; -} - -String TranslationManager::getTranslation(const String &message, const String &) { - return message; -} - -const TLangArray TranslationManager::getSupportedLanguageNames() const { - return TLangArray(); -} - -const char *TranslationManager::getCurrentCharset() { - return "ASCII"; -} - -const char *TranslationManager::getCurrentLanguage() { - return "C"; -} - -#endif // USE_TRANSLATION - } // End of namespace Common +#endif // USE_TRANSLATION diff --git a/common/translation.h b/common/translation.h index 7affa60ce6b..bf29d552b0f 100644 --- a/common/translation.h +++ b/common/translation.h @@ -27,11 +27,14 @@ #include "common/singleton.h" #include "common/str-array.h" -#include "common/file.h" -#include "common/fs.h" + +#ifdef USE_TRANSLATION namespace Common { +class File; +class FSNode; + enum TranslationIDs { kTranslationAutodetectId = 0, kTranslationBuiltinId = 1000 @@ -73,7 +76,7 @@ public: * @param id Id of the language * @return the matching string description of the language */ - const char *getLangById(int id); + String getLangById(int id) const; /** * Sets the current translation language to the one specified in the @@ -82,7 +85,7 @@ public: * * @param lang Language to setup. */ - void setLanguage(const char *lang); + void setLanguage(const String &lang); /** * Sets the current translation language to the one specified by the @@ -101,22 +104,22 @@ public: * @return id of the language or kTranslationBuiltinId in case the * language could not be found. */ - int parseLanguage(const String lang); + int parseLanguage(const String &lang) const; /** * Returns the translation into the current language of the parameter * message. In case the message isn't found in the translation catalog, * it returns the original untranslated message. */ - const char *getTranslation(const char *message); + const char *getTranslation(const char *message) const; /** * Returns the translation into the current language of the parameter * message. In case the message isn't found in the translation catalog, * it returns the original untranslated message. */ - String getTranslation(const String &message); - + String getTranslation(const String &message) const; + /** * Returns the translation into the current language of the parameter * message. In case the message isn't found in the translation catalog, @@ -126,8 +129,8 @@ public: * translation, otherwise it will look for a translation for the same * massage without a context or with a different context. */ - const char *getTranslation(const char *message, const char *context); - + const char *getTranslation(const char *message, const char *context) const; + /** * Returns the translation into the current language of the parameter * message. In case the message isn't found in the translation catalog, @@ -137,7 +140,7 @@ public: * translation, otherwise it will look for a translation for the same * massage without a context or with a different context. */ - String getTranslation(const String &message, const String &context); + String getTranslation(const String &message, const String &context) const; /** * Returns a list of supported languages. @@ -149,15 +152,23 @@ public: /** * Returns charset specified by selected translation language */ - const char *getCurrentCharset(); + String getCurrentCharset() const; /** * Returns currently selected translation language */ - const char *getCurrentLanguage(); + String getCurrentLanguage() const; private: -#ifdef USE_TRANSLATION + /** + * Tries to find the given language or a derivate of it. + * + * @param lang Language string + * @return id of the language or -1 in case no matching language could + * be found. + */ + int32 findMatchingLanguage(const String &lang); + /** * Find the translations.dat file. It looks first using the SearchMan and * then if needed using the Themepath. If found it opens the given File @@ -188,7 +199,6 @@ private: */ bool checkHeader(File &in); - String _syslang; StringArray _langs; StringArray _langNames; @@ -196,23 +206,24 @@ private: Array _currentTranslationMessages; String _currentCharset; int _currentLang; -#endif }; } // End of namespace Common #define TransMan Common::TranslationManager::instance() -#ifdef USE_TRANSLATION #define _(str) TransMan.getTranslation(str) #define _c(str, context) TransMan.getTranslation(str, context) -#else + +#else // !USE_TRANSLATION + #define _(str) str #define _c(str, context) str -#endif + +#endif // USE_TRANSLATION #define _s(str) str #define _sc(str, ctxt) str -#define DECLARE_TRANSLATION_ADDITIONAL_CONTEXT(str, ctxt) +#define DECLARE_TRANSLATION_ADDITIONAL_CONTEXT(str, ctxt) -#endif +#endif // COMMON_TRANSLATION_H diff --git a/common/unzip.cpp b/common/unzip.cpp index 2fce50de7d5..39e79c78d9d 100644 --- a/common/unzip.cpp +++ b/common/unzip.cpp @@ -106,6 +106,7 @@ typedef struct { #include "common/fs.h" #include "common/unzip.h" #include "common/file.h" +#include "common/memstream.h" #include "common/hashmap.h" #include "common/hash-str.h" @@ -373,7 +374,7 @@ typedef struct { unz_file_info_internal cur_file_info_internal; /* private info about it*/ } cached_file_in_zip; -typedef Common::HashMap ZipHash; /* unz_s contain internal information about the zipfile @@ -401,7 +402,7 @@ typedef struct { /* =========================================================================== Read a byte from a gz_stream; update next_in and avail_in. Return EOF for end of file. - IN assertion: the stream s has been sucessfully opened for reading. + IN assertion: the stream s has been successfully opened for reading. */ @@ -1147,7 +1148,7 @@ int unzReadCurrentFile(unzFile file, voidp buf, unsigned len) { return UNZ_PARAMERROR; - if ((pfile_in_zip_read_info->read_buffer == NULL)) + if (pfile_in_zip_read_info->read_buffer == NULL) return UNZ_END_OF_LIST_OF_FILE; if (len==0) return 0; diff --git a/common/util.cpp b/common/util.cpp index e720d80ed12..fd4a6511b25 100644 --- a/common/util.cpp +++ b/common/util.cpp @@ -38,20 +38,20 @@ void hexdump(const byte *data, int len, int bytesPerLine, int startOffset) { byte c; int offset = startOffset; while (len >= bytesPerLine) { - printf("%06x: ", offset); + debugN("%06x: ", offset); for (i = 0; i < bytesPerLine; i++) { - printf("%02x ", data[i]); + debugN("%02x ", data[i]); if (i % 4 == 3) - printf(" "); + debugN(" "); } - printf(" |"); + debugN(" |"); for (i = 0; i < bytesPerLine; i++) { c = data[i]; if (c < 32 || c >= 127) c = '.'; - printf("%c", c); + debugN("%c", c); } - printf("|\n"); + debugN("|\n"); data += bytesPerLine; len -= bytesPerLine; offset += bytesPerLine; @@ -60,25 +60,25 @@ void hexdump(const byte *data, int len, int bytesPerLine, int startOffset) { if (len <= 0) return; - printf("%06x: ", offset); + debugN("%06x: ", offset); for (i = 0; i < bytesPerLine; i++) { if (i < len) - printf("%02x ", data[i]); + debugN("%02x ", data[i]); else - printf(" "); + debugN(" "); if (i % 4 == 3) - printf(" "); + debugN(" "); } - printf(" |"); + debugN(" |"); for (i = 0; i < len; i++) { c = data[i]; if (c < 32 || c >= 127) c = '.'; - printf("%c", c); + debugN("%c", c); } for (; i < bytesPerLine; i++) - printf(" "); - printf("|\n"); + debugN(" "); + debugN("|\n"); } @@ -107,29 +107,29 @@ bool parseBool(const Common::String &val, bool &valAsBool) { const LanguageDescription g_languages[] = { - { "zh-cn", "Chinese (China)", ZH_CNA }, - { "zh", "Chinese (Taiwan)", ZH_TWN }, - { "cz", "Czech", CZ_CZE }, - { "nl", "Dutch", NL_NLD }, - { "en", "English", EN_ANY }, // Generic English (when only one game version exist) - { "gb", "English (GB)", EN_GRB }, - { "us", "English (US)", EN_USA }, - { "fr", "French", FR_FRA }, - { "de", "German", DE_DEU }, - { "gr", "Greek", GR_GRE }, - { "he", "Hebrew", HE_ISR }, - { "hb", "Hebrew", HE_ISR }, // Deprecated - { "hu", "Hungarian", HU_HUN }, - { "it", "Italian", IT_ITA }, - { "jp", "Japanese", JA_JPN }, - { "kr", "Korean", KO_KOR }, - { "nb", "Norwegian Bokm\xE5l", NB_NOR }, - { "pl", "Polish", PL_POL }, - { "br", "Portuguese", PT_BRA }, - { "ru", "Russian", RU_RUS }, - { "es", "Spanish", ES_ESP }, - { "se", "Swedish", SE_SWE }, - { 0, 0, UNK_LANG } + { "zh-cn"/*, "zh_CN"*/, "Chinese (China)", ZH_CNA }, + { "zh"/*, "zh_TW"*/, "Chinese (Taiwan)", ZH_TWN }, + { "cz"/*, "cs_CZ"*/, "Czech", CZ_CZE }, + { "nl"/*, "nl_NL"*/, "Dutch", NL_NLD }, + { "en"/*, "en"*/, "English", EN_ANY }, // Generic English (when only one game version exist) + { "gb"/*, "en_GB"*/, "English (GB)", EN_GRB }, + { "us"/*, "en_US"*/, "English (US)", EN_USA }, + { "fr"/*, "fr_FR"*/, "French", FR_FRA }, + { "de"/*, "de_DE"*/, "German", DE_DEU }, + { "gr"/*, "el_GR"*/, "Greek", GR_GRE }, + { "he"/*, "he_IL"*/, "Hebrew", HE_ISR }, + { "hb"/*, "he_IL"*/, "Hebrew", HE_ISR }, // Deprecated + { "hu"/*, "hu_HU"*/, "Hungarian", HU_HUN }, + { "it"/*, "it_IT"*/, "Italian", IT_ITA }, + { "jp"/*, "ja_JP"*/, "Japanese", JA_JPN }, + { "kr"/*, "ko_KR"*/, "Korean", KO_KOR }, + { "nb"/*, "nb_NO"*/, "Norwegian Bokm\xE5l", NB_NOR }, // TODO Someone should verify the unix locale + { "pl"/*, "pl_PL"*/, "Polish", PL_POL }, + { "br"/*, "pt_BR"*/, "Portuguese", PT_BRA }, + { "ru"/*, "ru_RU"*/, "Russian", RU_RUS }, + { "es"/*, "es_ES"*/, "Spanish", ES_ESP }, + { "se"/*, "sv_SE"*/, "Swedish", SE_SWE }, + { 0/*, 0*/, 0, UNK_LANG } }; Language parseLanguage(const String &str) { @@ -145,6 +145,19 @@ Language parseLanguage(const String &str) { return UNK_LANG; } +/*Language parseLanguageFromLocale(const char *locale) { + if (!locale || !*locale) + return UNK_LANG; + + const LanguageDescription *l = g_languages; + for (; l->code; ++l) { + if (!strcmp(l->unixLocale, locale)) + return l->id; + } + + return UNK_LANG; +}*/ + const char *getLanguageCode(Language id) { const LanguageDescription *l = g_languages; for (; l->code; ++l) { @@ -154,6 +167,15 @@ const char *getLanguageCode(Language id) { return 0; } +/*const char *getLanguageLocale(Language id) { + const LanguageDescription *l = g_languages; + for (; l->code; ++l) { + if (l->id == id) + return l->unixLocale; + } + return 0; +}*/ + const char *getLanguageDescription(Language id) { const LanguageDescription *l = g_languages; for (; l->code; ++l) { diff --git a/common/util.h b/common/util.h index 6deb614304b..ac3429b57aa 100644 --- a/common/util.h +++ b/common/util.h @@ -29,6 +29,11 @@ #include "common/textconsole.h" #include "common/str.h" +#ifdef WIN32 +#ifdef ARRAYSIZE +#undef ARRAYSIZE // winnt.h defines ARRAYSIZE, but we want our own one... +#endif +#endif /** * Check whether a given pointer is aligned correctly. @@ -62,6 +67,21 @@ template inline void SWAP(T &a, T &b) { T tmp = a; a = b; b = tmp; } */ #define ARRAYSIZE(x) ((int)(sizeof(x) / sizeof(x[0]))) + +/** + * @def SCUMMVM_CURRENT_FUNCTION + * This macro evaluates to the current function's name on compilers supporting this. + */ +#if defined(__GNUC__) +# define SCUMMVM_CURRENT_FUNCTION __PRETTY_FUNCTION__ +#elif defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901) +# define SCUMMVM_CURRENT_FUNCTION __func__ +#elif defined(_MSC_VER) && _MSC_VER >= 1300 +# define SCUMMVM_CURRENT_FUNCTION __FUNCTION__ +#else +# define SCUMMVM_CURRENT_FUNCTION "" +#endif + #ifndef round #define round(x) ((x > 0.0) ? floor((x) + 0.5) : ceil((x) - 0.5)) #endif @@ -122,6 +142,7 @@ enum Language { struct LanguageDescription { const char *code; + //const char *unixLocale; const char *description; Common::Language id; }; @@ -134,6 +155,10 @@ extern Language parseLanguage(const String &str); extern const char *getLanguageCode(Language id); extern const char *getLanguageDescription(Language id); +// locale <-> Language conversion is disabled, since it is not used currently +/*extern const char *getLanguageLocale(Language id); +extern Language parseLanguageFromLocale(const char *locale);*/ + /** * List of game platforms. Specifying a platform for a target can be used to * give the game engines a hint for which platform the game data file are. diff --git a/common/xmlparser.cpp b/common/xmlparser.cpp index a0e4c1e6039..1cd785a4767 100644 --- a/common/xmlparser.cpp +++ b/common/xmlparser.cpp @@ -27,10 +27,25 @@ #include "common/util.h" #include "common/archive.h" #include "common/fs.h" +#include "common/memstream.h" namespace Common { -bool XMLParser::loadFile(const Common::String &filename) { +XMLParser::~XMLParser() { + while (!_activeKey.empty()) + freeNode(_activeKey.pop()); + + delete _XMLkeys; + delete _stream; + + for (List::iterator i = _layoutList.begin(); + i != _layoutList.end(); ++i) + delete *i; + + _layoutList.clear(); +} + +bool XMLParser::loadFile(const String &filename) { _stream = SearchMan.createReadStreamForMember(filename); if (!_stream) return false; @@ -54,7 +69,7 @@ bool XMLParser::loadBuffer(const byte *buffer, uint32 size, DisposeAfterUse::Fla return true; } -bool XMLParser::loadStream(Common::SeekableReadStream *stream) { +bool XMLParser::loadStream(SeekableReadStream *stream) { _stream = stream; _fileName = "File Stream"; return true; @@ -158,10 +173,10 @@ bool XMLParser::parseActiveKey(bool closed) { if (layout->children.contains(key->name)) { key->layout = layout->children[key->name]; - Common::StringMap localMap = key->values; + StringMap localMap = key->values; int keyCount = localMap.size(); - for (Common::List::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) { + for (List::const_iterator i = key->layout->properties.begin(); i != key->layout->properties.end(); ++i) { if (i->required && !localMap.contains(i->name)) return parserError("Missing required property '%s' inside key '%s'", i->name.c_str(), key->name.c_str()); else if (localMap.contains(i->name)) @@ -198,7 +213,7 @@ bool XMLParser::parseActiveKey(bool closed) { return true; } -bool XMLParser::parseKeyValue(Common::String keyName) { +bool XMLParser::parseKeyValue(String keyName) { assert(_activeKey.empty() == false); if (_activeKey.top()->values.contains(keyName)) @@ -229,6 +244,47 @@ bool XMLParser::parseKeyValue(Common::String keyName) { return true; } +bool XMLParser::parseIntegerKey(const char *key, int count, ...) { + bool result; + va_list args; + va_start(args, count); + result = vparseIntegerKey(key, count, args); + va_end(args); + return result; +} + +bool XMLParser::parseIntegerKey(const String &key, int count, ...) { + bool result; + va_list args; + va_start(args, count); + result = vparseIntegerKey(key.c_str(), count, args); + va_end(args); + return result; +} + +bool XMLParser::vparseIntegerKey(const char *key, int count, va_list args) { + char *parseEnd; + int *num_ptr; + + while (count--) { + while (isspace(*key)) + key++; + + num_ptr = va_arg(args, int*); + *num_ptr = strtol(key, &parseEnd, 10); + + key = parseEnd; + + while (isspace(*key)) + key++; + + if (count && *key++ != ',') + return false; + } + + return (*key == 0); +} + bool XMLParser::closeKey() { bool ignore = false; bool result = true; @@ -410,5 +466,61 @@ bool XMLParser::parse() { return true; } +bool XMLParser::skipSpaces() { + if (!isspace(_char)) + return false; + + while (_char && isspace(_char)) + _char = _stream->readByte(); + + return true; } +bool XMLParser::skipComments() { + if (_char == '<') { + _char = _stream->readByte(); + + if (_char != '!') { + _stream->seek(-1, SEEK_CUR); + _char = '<'; + return false; + } + + if (_stream->readByte() != '-' || _stream->readByte() != '-') + return parserError("Malformed comment syntax."); + + _char = _stream->readByte(); + + while (_char) { + if (_char == '-') { + if (_stream->readByte() == '-') { + + if (_stream->readByte() != '>') + return parserError("Malformed comment (double-hyphen inside comment body)."); + + _char = _stream->readByte(); + return true; + } + } + + _char = _stream->readByte(); + } + + return parserError("Comment has no closure."); + } + + return false; +} + +bool XMLParser::parseToken() { + _token.clear(); + + while (isValidNameChar(_char)) { + _token += _char; + _char = _stream->readByte(); + } + + return isspace(_char) != 0 || _char == '>' || _char == '=' || _char == '/'; +} + +} // End of namespace Common diff --git a/common/xmlparser.h b/common/xmlparser.h index b27f240d1ac..6eb391709fe 100644 --- a/common/xmlparser.h +++ b/common/xmlparser.h @@ -27,7 +27,7 @@ #define XML_PARSER_H #include "common/sys.h" -#include "common/stream.h" +#include "common/types.h" #include "common/list.h" #include "common/hashmap.h" @@ -38,14 +38,7 @@ namespace Common { class FSNode; - -/* - XMLParser.cpp/h -- Generic XML Parser - ===================================== - - External documentation available at: - http://www.smartlikearoboc.com/scummvm_doc/xmlparser_doc.html -*/ +class SeekableReadStream; #define MAX_XML_DEPTH 8 @@ -103,19 +96,7 @@ public: */ XMLParser() : _XMLkeys(0), _stream(0) {} - virtual ~XMLParser() { - while (!_activeKey.empty()) - freeNode(_activeKey.pop()); - - delete _XMLkeys; - delete _stream; - - for (Common::List::iterator i = _layoutList.begin(); - i != _layoutList.end(); ++i) - delete *i; - - _layoutList.clear(); - } + virtual ~XMLParser(); /** Active state for the parser */ enum ParserState { @@ -133,16 +114,16 @@ public: struct XMLKeyLayout; struct ParserNode; - typedef Common::HashMap ChildMap; + typedef HashMap ChildMap; /** nested struct representing the layout of the XML file */ struct XMLKeyLayout { struct XMLKeyProperty { - Common::String name; + String name; bool required; }; - Common::List properties; + List properties; ChildMap children; virtual bool doCallback(XMLParser *parent, ParserNode *node) = 0; @@ -156,8 +137,8 @@ public: /** Struct representing a parsed node */ struct ParserNode { - Common::String name; - Common::StringMap values; + String name; + StringMap values; bool ignore; bool header; int depth; @@ -181,7 +162,7 @@ public: * * @param filename Name of the file to load. */ - bool loadFile(const Common::String &filename); + bool loadFile(const String &filename); bool loadFile(const FSNode &node); @@ -198,7 +179,7 @@ public: */ bool loadBuffer(const byte *buffer, uint32 size, DisposeAfterUse::Flag disposable = DisposeAfterUse::NO); - bool loadStream(Common::SeekableReadStream *stream); + bool loadStream(SeekableReadStream *stream); void close(); @@ -283,7 +264,7 @@ protected: /** * Parses the value of a given key. There's no reason to overload this. */ - bool parseKeyValue(Common::String keyName); + bool parseKeyValue(String keyName); /** * Called once a key has been parsed. It handles the closing/cleanup of the @@ -293,65 +274,22 @@ protected: /** * Prints an error message when parsing fails and stops the parser. - * Parser error always returns "false" so we can pass the return value directly - * and break down the parsing. + * Parser error always returns "false" so we can pass the return value + * directly and break down the parsing. */ bool parserError(const char *errorString, ...) GCC_PRINTF(2, 3); /** - * Skips spaces/whitelines etc. Returns true if any spaces were skipped. + * Skips spaces/whitelines etc. + * @return true if any spaces were skipped. */ - bool skipSpaces() { - if (!isspace(_char)) - return false; - - while (_char && isspace(_char)) - _char = _stream->readByte(); - - return true; - } + bool skipSpaces(); /** * Skips comment blocks and comment lines. - * Returns true if any comments were skipped. - * Overload this if you want to disable comments on your XML syntax - * or to change the commenting syntax. + * @return true if any comments were skipped. */ - virtual bool skipComments() { - if (_char == '<') { - _char = _stream->readByte(); - - if (_char != '!') { - _stream->seek(-1, SEEK_CUR); - _char = '<'; - return false; - } - - if (_stream->readByte() != '-' || _stream->readByte() != '-') - return parserError("Malformed comment syntax."); - - _char = _stream->readByte(); - - while (_char) { - if (_char == '-') { - if (_stream->readByte() == '-') { - - if (_stream->readByte() != '>') - return parserError("Malformed comment (double-hyphen inside comment body)."); - - _char = _stream->readByte(); - return true; - } - } - - _char = _stream->readByte(); - } - - return parserError("Comment has no closure."); - } - - return false; - } + bool skipComments(); /** * Check if a given character can be part of a KEY or VALUE name. @@ -364,18 +302,8 @@ protected: /** * Parses a the first textual token found. - * There's no reason to overload this. */ - bool parseToken() { - _token.clear(); - - while (isValidNameChar(_char)) { - _token += _char; - _char = _stream->readByte(); - } - - return isspace(_char) != 0 || _char == '>' || _char == '=' || _char == '/'; - } + bool parseToken(); /** * Parses the values inside an integer key. @@ -395,32 +323,9 @@ protected: * by reference. * @returns True if the parsing succeeded. */ - bool parseIntegerKey(const char *key, int count, ...) { - char *parseEnd; - int *num_ptr; - - va_list args; - va_start(args, count); - - while (count--) { - while (isspace(*key)) - key++; - - num_ptr = va_arg(args, int*); - *num_ptr = strtol(key, &parseEnd, 10); - - key = parseEnd; - - while (isspace(*key)) - key++; - - if (count && *key++ != ',') - return false; - } - - va_end(args); - return (*key == 0); - } + bool parseIntegerKey(const char *key, int count, ...); + bool parseIntegerKey(const String &keyStr, int count, ...); + bool vparseIntegerKey(const char *key, int count, va_list args); bool parseXMLHeader(ParserNode *node); @@ -431,21 +336,21 @@ protected: */ virtual void cleanup() {} - Common::List _layoutList; + List _layoutList; private: char _char; SeekableReadStream *_stream; - Common::String _fileName; + String _fileName; ParserState _state; /** Internal state of the parser */ - Common::String _error; /** Current error message */ - Common::String _token; /** Current text token */ + String _error; /** Current error message */ + String _token; /** Current text token */ - Common::Stack _activeKey; /** Node stack of the parsed keys */ + Stack _activeKey; /** Node stack of the parsed keys */ }; -} +} // End of namespace Common #endif diff --git a/common/zlib.cpp b/common/zlib.cpp index 76351718f4a..0a77c005a74 100644 --- a/common/zlib.cpp +++ b/common/zlib.cpp @@ -25,6 +25,7 @@ #include "common/zlib.h" #include "common/util.h" +#include "common/stream.h" #if defined(USE_ZLIB) #ifdef __SYMBIAN32__ diff --git a/common/zlib.h b/common/zlib.h index 9fec0f80339..010185f8bdd 100644 --- a/common/zlib.h +++ b/common/zlib.h @@ -27,10 +27,12 @@ #define COMMON_ZLIB_H #include "common/sys.h" -#include "common/stream.h" namespace Common { +class SeekableReadStream; +class WriteStream; + #if defined(USE_ZLIB) /** @@ -54,7 +56,7 @@ bool uncompress(byte *dst, unsigned long *dstLen, const byte *src, unsigned long * It is safe to call this with a NULL parameter (in this case, NULL is * returned). */ -Common::SeekableReadStream *wrapCompressedReadStream(Common::SeekableReadStream *toBeWrapped); +SeekableReadStream *wrapCompressedReadStream(SeekableReadStream *toBeWrapped); /** * Take an arbitrary WriteStream and wrap it in a custom stream which provides @@ -65,7 +67,7 @@ Common::SeekableReadStream *wrapCompressedReadStream(Common::SeekableReadStream * It is safe to call this with a NULL parameter (in this case, NULL is * returned). */ -Common::WriteStream *wrapCompressedWriteStream(Common::WriteStream *toBeWrapped); +WriteStream *wrapCompressedWriteStream(WriteStream *toBeWrapped); } // End of namespace Common diff --git a/configure b/configure index 934e50164be..7f68064872f 100755 --- a/configure +++ b/configure @@ -88,7 +88,12 @@ _flac=auto _mad=auto _alsa=auto _seq_midi=auto +_timidity=auto +_zlib=auto +_theoradec=auto _fluidsynth=auto +_opengl=auto +_opengles=auto _readline=auto # Default option behaviour yes/no _debug_build=auto @@ -98,6 +103,7 @@ _mt32emu=no _enable_prof=no _unix=no _global_constructors=no +_elf_loader=no # Default vkeybd/keymapper options _vkeybd=no _keymapper=no @@ -134,15 +140,15 @@ NASM="" # to make it possible to change e.g. the location of the # man pages independently of that of the engine data files, # which are placed inside $datadir/residual -exec_prefix=NONE prefix=NONE +exec_prefix=NONE bindir='${exec_prefix}/bin' +libdir='${exec_prefix}/lib' datarootdir='${prefix}/share' datadir='${datarootdir}/residual' -docdir='${datarootdir}/doc/residual' -libdir='${exec_prefix}/lib' -#localedir='${datarootdir}/locale' mandir='${datarootdir}/man' +docdir='${datarootdir}/doc/residual' +#localedir='${datarootdir}/locale' # For cross compiling _host="" @@ -166,10 +172,10 @@ cc_check_no_clean() { echo "$CXX $LDFLAGS $CXXFLAGS $TMPC -o $TMPO$HOSTEXEEXT $@" >> "$TMPLOG" rm -f "$TMPO$HOSTEXEEXT" ( $CXX $LDFLAGS $CXXFLAGS "$TMPC" -o "$TMPO$HOSTEXEEXT" "$@" ) >> "$TMPLOG" 2>&1 - TMP="$?" - echo "return code: $TMP" >> "$TMPLOG" + TMPR="$?" + echo "return code: $TMPR" >> "$TMPLOG" echo >> "$TMPLOG" - return "$TMP" + return "$TMPR" } cc_check_clean() { @@ -178,9 +184,9 @@ cc_check_clean() { cc_check() { cc_check_no_clean "$@" - TMP="$?" + TMPR="$?" cc_check_clean - return "$TMP" + return "$TMPR" } cc_check_define() { @@ -320,7 +326,7 @@ get_system_exe_extension() { case $1 in arm-riscos) _exeext=",ff8" - ;; + ;; dreamcast | ds | gamecube | n64 | ps2 | psp | wii) _exeext=".elf" ;; @@ -647,7 +653,13 @@ Optional Libraries: --with-zlib-prefix=DIR Prefix where zlib is installed (optional) - --with-fluidsynth-prefix=DIR Prefix where libfluidsynth is + --with-opengl-prefix=DIR Prefix where OpenGL (ES) is installed (optional) + --disable-opengl disable OpenGL (ES) support [autodetect] + + --with-theoradec-prefix=DIR Prefix where libtheoradec is installed (optional) + --disable-theoradec disable Theora decoder [autodetect] + + --with-fluidsynth-prefix=DIR Prefix where libfluidsynth is installed (optional) --disable-fluidsynth disable fluidsynth MIDI driver [autodetect] @@ -679,8 +691,10 @@ for ac_option in $@; do case "$ac_option" in --enable-alsa) _alsa=yes ;; --disable-alsa) _alsa=no ;; - --enable-seq-midi) _seq_midi=yes ;; - --disable-seq-midi) _seq_midi=no ;; + --enable-seq-midi) _seq_midi=yes ;; + --disable-seq-midi) _seq_midi=no ;; + --enable-timidity) _timidity=yes ;; + --disable-timidity) _timidity=no ;; --enable-vorbis) _vorbis=yes ;; --disable-vorbis) _vorbis=no ;; --enable-tremor) _tremor=yes ;; @@ -691,9 +705,13 @@ for ac_option in $@; do --disable-mad) _mad=no ;; --enable-nasm) _nasm=yes ;; --disable-nasm) _nasm=no ;; + --disable-theoradec) _theoradec=no ;; + --enable-theoradec) _theoradec=yes ;; --disable-fluidsynth) _fluidsynth=no ;; --enable-readline) _readline=yes ;; --disable-readline) _readline=no ;; + --enable-opengl) _opengl=yes ;; + --disable-opengl) _opengl=no ;; --enable-verbose-build) _verbose_build=yes ;; --enable-plugins) _dynamic_modules=yes ;; --default-dynamic) _plugins_default=dynamic ;; @@ -742,6 +760,11 @@ for ac_option in $@; do MAD_CFLAGS="-I$arg/include" MAD_LIBS="-L$arg/lib" ;; + --with-theoradec-prefix=*) + arg=`echo $ac_option | cut -d '=' -f 2` + THEORADEC_CFLAGS="-I$arg/include" + THEORADEC_LIBS="-L$arg/lib" + ;; --with-zlib-prefix=*) arg=`echo $ac_option | cut -d '=' -f 2` ZLIB_CFLAGS="-I$arg/include" @@ -752,6 +775,11 @@ for ac_option in $@; do READLINE_CFLAGS="-I$arg/include" READLINE_LIBS="-L$arg/lib" ;; + --with-opengl-prefix=*) + arg=`echo $ac_option | cut -d '=' -f 2` + OPENGL_CFLAGS="-I$arg/include" + OPENGL_LIBS="-L$arg/lib" + ;; --backend=*) _backend=`echo $ac_option | cut -d '=' -f 2` ;; @@ -787,17 +815,17 @@ for ac_option in $@; do --host=*) _host=`echo $ac_option | cut -d '=' -f 2` ;; - --exec-prefix=*) - exec_prefix=`echo $ac_option | cut -d '=' -f 2` - ;; --prefix=*) prefix=`echo $ac_option | cut -d '=' -f 2` ;; + --exec-prefix=*) + exec_prefix=`echo $ac_option | cut -d '=' -f 2` + ;; --bindir=*) bindir=`echo $ac_option | cut -d '=' -f 2` ;; - --mandir=*) - mandir=`echo $ac_option | cut -d '=' -f 2` + --libdir=*) + libdir=`echo $ac_option | cut -d '=' -f 2` ;; --datarootdir=*) datarootdir=`echo $ac_option | cut -d '=' -f 2` @@ -805,8 +833,11 @@ for ac_option in $@; do --datadir=*) datadir=`echo $ac_option | cut -d '=' -f 2` ;; - --libdir=*) - libdir=`echo $ac_option | cut -d '=' -f 2` + --mandir=*) + mandir=`echo $ac_option | cut -d '=' -f 2` + ;; + --docdir=*) + docdir=`echo $ac_option | cut -d '=' -f 2` ;; --enable-all-engines) engine_enable_all @@ -831,10 +862,10 @@ get_system_exe_extension $guessed_host NATIVEEXEEXT=$_exeext case $_host in -android) +android | android-v7a) _host_os=android _host_cpu=arm - _host_alias=arm-oe-linux-androideabi + _host_alias=arm-linux-androideabi ;; arm-riscos) _host_os=riscos @@ -852,7 +883,7 @@ caanoo) if test "$_release_build" = auto; then # Enable release build by default. _release_build=yes - fi + fi ;; dingux) _host_os=linux @@ -888,7 +919,7 @@ gp2x) if test "$_release_build" = auto; then # Enable release build by default. _release_build=yes - fi + fi ;; gp2xwiz) _host_os=gph-linux @@ -902,7 +933,7 @@ gp2xwiz) if test "$_release_build" = auto; then # Enable release build by default. _release_build=yes - fi + fi ;; i586-mingw32msvc) _host_os=mingw32msvc @@ -927,7 +958,7 @@ motomagx) _host_cpu=arm _host_alias=arm-linux-gnueabi ;; -n64) +n64) _host_os=n64 _host_cpu=mips _host_alias=mips64 @@ -948,7 +979,7 @@ openpandora) if test "$_release_build" = auto; then # Enable release build by default. _release_build=yes - fi + fi ;; ppc-amigaos) _host_os=amigaos @@ -986,6 +1017,11 @@ samsungtv) _host_cpu=arm _host_alias=arm-linux-gnueabi ;; +webos) + _host_os=webos + _host_cpu=arm + _host_alias=arm-none-linux-gnueabi + ;; wii) _host_os=wii _host_cpu=ppc @@ -1039,16 +1075,17 @@ fi # Determine extension used for executables # get_system_exe_extension $_host_os +HOSTEXEPRE= HOSTEXEEXT=$_exeext # # Determine separator used for $PATH # case $_host_os in -os2-emx* ) +os2-emx*) SEPARATOR=";" ;; -* ) +*) SEPARATOR=":" ;; esac @@ -1062,6 +1099,10 @@ android) echo "Please set ANDROID_SDK in your environment. export ANDROID_SDK=" exit 1 fi + if test -z "$ANDROID_NDK"; then + echo "Please set ANDROID_NDK in your environment. export ANDROID_NDK=" + exit 1 + fi ;; ds | gamecube | wii) if test -z "$DEVKITPRO"; then @@ -1088,6 +1129,16 @@ psp) exit 1 fi ;; +webos) + if test -z "$WEBOS_SDK"; then + echo "Please set WEBOS_SDK in your environment. export WEBOS_SDK=" + exit 1 + fi + if test -z "$WEBOS_PDK"; then + echo "Please set WEBOS_PDK in your environment. export WEBOS_PDK=" + exit 1 + fi + ;; *) ;; esac @@ -1154,6 +1205,21 @@ LD=$CXX # echocheck "compiler version" +# We first check whether we have an Intel compiler here, since the Intel compiler +# can also fake itself as an gcc (to ease compatibility with common Linux etc. +# programs). +have_icc=no +cc_check_define __INTEL_COMPILER && have_icc=yes + +if test "$have_icc" = yes; then + add_line_to_config_mk 'HAVE_ICC = 1' + + # Make ICC error our on unknown command line options instead of printing + # a warning. This is for example required to make the -Wglobal-destructors + # detection work correctly. + CXXFLAGS="$CXXFLAGS -diag-error 10006,10148" +fi + have_gcc=no cc_check_define __GNUC__ && have_gcc=yes @@ -1175,6 +1241,11 @@ if test "$have_gcc" = yes; then cxx_version="$cxx_version, bad" cxx_verc_fail=yes fi +elif test "$have_icc" = yes; then + cxx_version="`( $CXX -dumpversion ) 2>/dev/null`" + _cxx_major="`echo "${cxx_version}" | sed -ne 's/\([0-9][0-9]*\)\..*/\1/gp'`" + _cxx_minor="`echo "${cxx_version}" | sed -ne 's/[0-9][0-9]*\.\([0-9][0-9]*\)/\1/gp'`" + cxx_version="ICC $cxx_version, ok" else # TODO: Big scary warning about unsupported compilers cxx_version=`( $CXX -version ) 2>&1` @@ -1270,18 +1341,18 @@ int main() { return 0; } EOF -if $CXX $CXXFLAGS -c -o $TMPO.o tmp_find_type_with_size.cpp 2>/dev/null ; then - break -else - if test "$datatype" = "unknown"; then - echo "couldn't find data type with $1 bytes" - exit 1 - fi - continue -fi -done -cc_check_clean tmp_find_type_with_size.cpp -echo $datatype + if $CXX $CXXFLAGS -c -o $TMPO.o tmp_find_type_with_size.cpp 2>/dev/null ; then + break + else + if test "$datatype" = "unknown"; then + echo "couldn't find data type with $1 bytes" + exit 1 + fi + continue + fi + done + cc_check_clean tmp_find_type_with_size.cpp + echo $datatype } # @@ -1306,27 +1377,27 @@ EOF # echo_n "Type with 1 byte... " type_1_byte=`find_type_with_size 1` -TMP="$?" +TMPR="$?" echo "$type_1_byte" -test $TMP -eq 0 || exit 1 # check exit code of subshell +test $TMPR -eq 0 || exit 1 # check exit code of subshell echo_n "Type with 2 bytes... " type_2_byte=`find_type_with_size 2` -TMP="$?" +TMPR="$?" echo "$type_2_byte" -test $TMP -eq 0 || exit 1 # check exit code of subshell +test $TMPR -eq 0 || exit 1 # check exit code of subshell echo_n "Type with 4 bytes... " type_4_byte=`find_type_with_size 4` -TMP="$?" +TMPR="$?" echo "$type_4_byte" -test $TMP -eq 0 || exit 1 # check exit code of subshell +test $TMPR -eq 0 || exit 1 # check exit code of subshell echo_n "Type with 8 bytes... " type_8_byte=`find_type_with_size 8` -TMP="$?" +TMPR="$?" echo "$type_8_byte" -if test $TMP -eq 0; then +if test $TMPR -eq 0; then _def_64bit_type_signed="typedef signed $type_8_byte int64;" _def_64bit_type_unsigned="typedef unsigned $type_8_byte uint64;" fi @@ -1363,15 +1434,39 @@ echo $_host_os case $_host_os in amigaos*) DEFINES="$DEFINES -DMINIGL -DUSE_OPENGL" - CXXFLAGS="$CXXFLAGS -mcrt=newlib -mstrict-align -mcpu=750 -mtune=7400" - LDFLAGS="$LDFLAGS -mcrt=newlib -use-dynld -Lsobjs:" LIBS="$LIBS -lGL -lGLU" + CXXFLAGS="$CXXFLAGS -mcrt=newlib -mstrict-align -mcpu=750 -mtune=7400" + LDFLAGS="$LDFLAGS -mcrt=newlib -use-dynld -L/sdk/local/newlib/lib" # We have to use 'long' for our 4 byte typedef because AmigaOS already typedefs (u)int32 # as (unsigned) long, and consequently we'd get a compiler error otherwise. type_4_byte='long' + add_line_to_config_mk 'AMIGAOS = 1' ;; android) - CXXFLAGS="$CXXFLAGS -Os -msoft-float -mtune=xscale -march=armv5te -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__ -D__ARM_ARCH_5TE__" + case $_host in + android) + CXXFLAGS="$CXXFLAGS -march=armv5te -mtune=xscale -msoft-float" + ;; + android-v7a) + CXXFLAGS="$CXXFLAGS -march=armv7-a -mfloat-abi=softfp -mfpu=vfp" + LDFLAGS="$LDFLAGS -Wl,--fix-cortex-a8" + ;; + esac + CXXFLAGS="$CXXFLAGS --sysroot=$ANDROID_NDK/platforms/android-4/arch-arm" + CXXFLAGS="$CXXFLAGS -fpic -ffunction-sections -funwind-tables" + if test "$_debug_build" = yes; then + CXXFLAGS="$CXXFLAGS -fno-omit-frame-pointer -fno-strict-aliasing" + else + CXXFLAGS="$CXXFLAGS -fomit-frame-pointer -fstrict-aliasing" + fi + CXXFLAGS="$CXXFLAGS -finline-limit=300" + CXXFLAGS="$CXXFLAGS -Os -mthumb-interwork" + CXXFLAGS="$CXXFLAGS -D__ARM_ARCH_5__ -D__ARM_ARCH_5T__" + CXXFLAGS="$CXXFLAGS -D__ARM_ARCH_5E__ -D__ARM_ARCH_5TE__" + # supress 'mangling of 'va_list' has changed in GCC 4.4' + CXXFLAGS="$CXXFLAGS -Wno-psabi" + LDFLAGS="$LDFLAGS --sysroot=$ANDROID_NDK/platforms/android-4/arch-arm" + LDFLAGS="$LDFLAGS -mthumb-interwork" add_line_to_config_mk "ANDROID_SDK = $ANDROID_SDK" _unix=yes _seq_midi=no @@ -1411,29 +1506,41 @@ case $_host_os in CXXFLAGS="$CXXFLAGS -isystem $DEVKITPRO/libnds/include -isystem $DEVKITPRO/devkitARM/arm-eabi/include" CXXFLAGS="$CXXFLAGS -mcpu=arm9tdmi -mtune=arm9tdmi -fomit-frame-pointer -mthumb-interwork" CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fno-strict-aliasing" - LDFLAGS="$LDFLAGS -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt -Wl,--gc-sections" + CXXFLAGS="$CXXFLAGS -fuse-cxa-atexit" + LDFLAGS="$LDFLAGS -specs=ds_arm9.specs -mthumb-interwork -mno-fpu -Wl,-Map,map.txt" + if test "$_dynamic_modules" = no ; then + LDFLAGS="$LDFLAGS -Wl,--gc-sections" + else + LDFLAGS="$LDFLAGS -Wl,--no-gc-sections" + # TODO automate this required 2 step linking phase + # LDFLAGS="$LDFLAGS -Wl,--retain-symbols-file,ds.syms" + fi LDFLAGS="$LDFLAGS -L$DEVKITPRO/libnds/lib" LIBS="$LIBS -lnds9" ;; freebsd*) DEFINES="$DEFINES -DUSE_OPENGL" + LIBS="$LIBS -lGL -lGLU -L/usr/X11/lib" LDFLAGS="$LDFLAGS -L/usr/local/lib" CXXFLAGS="$CXXFLAGS -I/usr/local/include" - LIBS="$LIBS -lGL -lGLU -L/usr/X11/lib" _unix=yes ;; gamecube) CXXFLAGS="$CXXFLAGS -Os -mogc -mcpu=750 -meabi -mhard-float" CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fmodulo-sched" + CXXFLAGS="$CXXFLAGS -fuse-cxa-atexit" CXXFLAGS="$CXXFLAGS -I$DEVKITPRO/libogc/include" # libogc is required to link the cc tests (includes _start()) LDFLAGS="$LDFLAGS -mogc -mcpu=750 -L$DEVKITPRO/libogc/lib/cube -logc" + if test "$_dynamic_modules" = "yes" ; then + # retarded toolchain patch forces --gc-sections, overwrite it + LDFLAGS="$LDFLAGS -Wl,--no-gc-sections" + fi ;; haiku*) DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" # Needs -lnetwork for the timidity MIDI driver LIBS="$LIBS -lnetwork" - CXXFLAGS="$CXXFLAGS -fhuge-objects" _unix=yes _seq_midi=no ;; @@ -1449,14 +1556,15 @@ case $_host_os in if test -z "$_host"; then CXXFLAGS="$CXXFLAGS $(getconf LFS_CFLAGS 2>/dev/null)" fi + _unix=yes DEFINES="$DEFINES -DUSE_OPENGL" LIBS="$LIBS -lGL -lGLU -L/usr/X11/lib" - _unix=yes ;; mingw*) DEFINES="$DEFINES -DWIN32 -D__USE_MINGW_ANSI_STDIO=0 -DUSE_OPENGL" LIBS="$LIBS -lmingw32 -lwinmm -lopengl32 -lglu32" OBJS="$OBJS residualico.o" + add_line_to_config_mk 'WIN32 = 1' ;; mint*) DEFINES="$DEFINES -DSYSTEM_NOT_SUPPORTING_D_TYPE" @@ -1484,15 +1592,28 @@ case $_host_os in LIBS="$LIBS -lnsl -lsocket" _unix=yes ;; + webos) + LDFLAGS="$LDFLAGS -L$WEBOS_PDK/device/lib -L$WEBOS_PDK/device/usr/lib" + LDFLAGS="$LDFLAGS -Wl,--allow-shlib-undefined" + LDFLAGS="$LDFLAGS --sysroot=$WEBOS_PDK/arm-gcc/sysroot" + add_line_to_config_mk "WEBOS_SDK = $WEBOS_SDK" + _unix=yes + _seq_midi=no + ;; wii) CXXFLAGS="$CXXFLAGS -Os -mrvl -mcpu=750 -meabi -mhard-float" CXXFLAGS="$CXXFLAGS -ffunction-sections -fdata-sections -fmodulo-sched" + CXXFLAGS="$CXXFLAGS -fuse-cxa-atexit" CXXFLAGS="$CXXFLAGS -I$DEVKITPRO/libogc/include" # libogc is required to link the cc tests (includes _start()) LDFLAGS="$LDFLAGS -mrvl -mcpu=750 -L$DEVKITPRO/libogc/lib/wii -logc" + if test "$_dynamic_modules" = "yes" ; then + # retarded toolchain patch forces --gc-sections, overwrite it + LDFLAGS="$LDFLAGS -Wl,--no-gc-sections" + fi ;; wince) - CXXFLAGS="$CXXFLAGS -O3 -march=armv4 -mtune=xscale" + CXXFLAGS="$CXXFLAGS -O3 -fno-inline-functions -march=armv4 -mtune=xscale" DEFINES="$DEFINES -D_WIN32_WCE=300 -D__ARM__ -D_ARM_ -DUNICODE -DFPM_DEFAULT -DNONSTANDARD_PORT" DEFINES="$DEFINES -DWIN32 -Dcdecl= -D__cdecl__=" ;; @@ -1507,16 +1628,22 @@ if test -n "$_host"; then # Cross-compiling mode - add your target here if needed echo "Cross-compiling to $_host" case "$_host" in - android) - DEFINES="$DEFINES -DANDROID -DUSE_ARM_SMUSH_ASM" + android | android-v7a) _unix=yes _need_memalign=yes + # we link a .so as default + LDFLAGS="$LDFLAGS -shared -Wl,-Bsymbolic,--no-undefined" + HOSTEXEPRE=lib + HOSTEXEEXT=.so add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' _backend="android" _port_mk="backends/platform/android/android.mk" + _build_scalers=no _seq_midi=no + _mt32emu=no + _timidity=no ;; arm-linux|arm*-linux-gnueabi|arm-*-linux) _unix=yes @@ -1534,9 +1661,9 @@ if test -n "$_host"; then _need_memalign=yes ;; caanoo) + # This uses the GPH backend. + DEFINES="$DEFINES -DGPH_DEVICE" DEFINES="$DEFINES -DCAANOO -DREDUCE_MEMORY_USAGE" - # Disable DOSBOX OPL for now. - DEFINES="$DEFINES -DDISABLE_DOSBOX_OPL" if test "$_debug_build" = yes; then DEFINES="$DEFINES -DGPH_DEBUG" else @@ -1552,17 +1679,16 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' _backend="gph" _build_hq_scalers=no - _mt32emu=no _vkeybd=yes _seq_midi=no _port_mk="backends/platform/gph/caanoo-bundle.mk" - ;; + ;; *darwin*) _ranlib=$_host-ranlib _strip=$_host-strip ;; dingux) - DEFINES="$DEFINES -DUNIX -DDINGUX -DDISABLE_DOSBOX_OPL" + DEFINES="$DEFINES -DUNIX -DDINGUX -DDISABLE_DOSBOX_OPL -DREDUCE_MEMORY_USAGE" ASFLAGS="$ASFLAGS" CXXFLAGS="$CXXFLAGS -msoft-float -mips32" _need_memalign=yes @@ -1621,9 +1747,9 @@ if test -n "$_host"; then add_line_to_config_h "#define USE_WII_DI" ;; gp2x) + # This uses the GPH backend. + DEFINES="$DEFINES -DGPH_DEVICE" DEFINES="$DEFINES -DGP2X -DREDUCE_MEMORY_USAGE" - # Disable DOSBOX OPL for now. - DEFINES="$DEFINES -DDISABLE_DOSBOX_OPL" if test "$_debug_build" = yes; then DEFINES="$DEFINES -DGPH_DEBUG" fi @@ -1635,17 +1761,18 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' - _backend="gp2x" + _backend="gph" _build_hq_scalers=no - _mt32emu=no _vkeybd=yes _seq_midi=no - _port_mk="backends/platform/gp2x/gp2x-bundle.mk" + _mt32emu=no + _timidity=no + _port_mk="backends/platform/gph/gp2x-bundle.mk" ;; gp2xwiz) + # This uses the GPH backend. + DEFINES="$DEFINES -DGPH_DEVICE" DEFINES="$DEFINES -DGP2XWIZ -DREDUCE_MEMORY_USAGE" - # Disable DOSBOX OPL for now. - DEFINES="$DEFINES -DDISABLE_DOSBOX_OPL" if test "$_debug_build" = yes; then DEFINES="$DEFINES -DGPH_DEBUG" fi @@ -1658,9 +1785,10 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' _backend="gph" _build_hq_scalers=no - _mt32emu=no _vkeybd=yes _seq_midi=no + _mt32emu=no + _timidity=no _port_mk="backends/platform/gph/gp2xwiz-bundle.mk" ;; iphone) @@ -1689,6 +1817,8 @@ if test -n "$_host"; then _ranlib=$_host-ranlib ;; mips-sgi*) + LDFLAGS="$LDFLAGS -static-libgcc" + LIBS="$LIBS -laudio" _endian=big _need_memalign=yes ;; @@ -1740,7 +1870,7 @@ if test -n "$_host"; then _dynamic_modules=no _plugins_default=static # Force use of libmad, libtremor and zlib - _mad=yes + _mad=no _tremor=yes _zlib=yes _port_mk="backends/platform/n64/n64.mk" @@ -1755,8 +1885,6 @@ if test -n "$_host"; then ;; openpandora) DEFINES="$DEFINES -DOPENPANDORA -DREDUCE_MEMORY_USAGE" - # Disable DOSBOX OPL for now. - DEFINES="$DEFINES -DDISABLE_DOSBOX_OPL" if test "$_release_build" = no; then DEFINES="$DEFINES -DOP_DEBUG" else @@ -1772,11 +1900,11 @@ if test -n "$_host"; then add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' _backend="openpandora" _build_hq_scalers=yes - _mt32emu=no _vkeybd=no + _mt32emu=no _seq_midi=no _port_mk="backends/platform/openpandora/op-bundle.mk" - ;; + ;; ppc-amigaos) _endian=big _need_memalign=yes @@ -1831,6 +1959,23 @@ if test -n "$_host"; then _mt32emu=no _vkeybd=yes ;; + webos) + _unix=yes + _need_memalign=yes + add_line_to_config_mk 'USE_ARM_SOUND_ASM = 1' + add_line_to_config_mk 'USE_ARM_SMUSH_ASM = 1' + add_line_to_config_mk 'USE_ARM_GFX_ASM = 1' + add_line_to_config_mk 'USE_ARM_COSTUME_ASM = 1' + add_line_to_config_mk 'USE_ARM_SCALER_ASM = 1' + _backend="webos" + _port_mk="backends/platform/webos/webos.mk" + _build_scalers=no + _timidity=no + _mt32emu=no + _seq_midi=no + _vkeybd=no + _keymapper=yes + ;; wii) _endian=big _need_memalign=yes @@ -1928,12 +2073,13 @@ case $_endian in ;; esac -add_to_config_h_if_yes $_have_x86 '#define HAVE_X86' +add_to_config_h_if_yes $_have_x86 'HAVE_X86' add_to_config_h_if_yes $_need_memalign '#define SYSTEM_NEED_ALIGNMENT' if test "$_unix" = yes ; then DEFINES="$DEFINES -DUNIX" + add_line_to_config_mk 'UNIX = 1' fi # @@ -1954,6 +2100,32 @@ _def_plugin="/* -> plugins disabled */" if test "$_dynamic_modules" = yes ; then echo_n "Checking whether building plugins is supported... " case $_host_os in + android) +_def_plugin=' +#define PLUGIN_PREFIX "lib" +#define PLUGIN_SUFFIX ".so" +' +# Work around an Android 2.0+ run-time linker bug: +# The linker doesn't actually look in previously +# loaded libraries when trying to resolve symbols - +# effectively turning all dlopen(RTLD_GLOBAL) calls +# into dlopen(RTLD_LOCAL). It *does* look in +# DT_NEEDED libraries, so the workaround is to add an +# (otherwise unnecessary) dependency from plugins back +# to the main libscummvm.so. +_mak_plugins=' +DYNAMIC_MODULES := 1 +PLUGIN_PREFIX := lib +PLUGIN_SUFFIX := .so +PLUGIN_EXTRA_DEPS = libresidual.so +CXXFLAGS += -DDYNAMIC_MODULES +CXXFLAGS += -fpic +PLUGIN_LDFLAGS += $(LDFLAGS) -L. -lresidual +PRE_OBJS_FLAGS := -Wl,-export-dynamic -Wl,-whole-archive +POST_OBJS_FLAGS := -Wl,-no-whole-archive +LIBS += -ldl +' + ;; darwin*) _def_plugin=' #define PLUGIN_PREFIX "" @@ -1980,11 +2152,18 @@ _mak_plugins=' DYNAMIC_MODULES := 1 PLUGIN_PREFIX := PLUGIN_SUFFIX := .plg -PLUGIN_EXTRA_DEPS = $(abspath $(srcdir)/backends/platform/dc/plugin.x $(srcdir)/backends/platform/dc/plugin.syms) $(EXECUTABLE) +PLUGIN_EXTRA_DEPS = $(abspath $(srcdir)/backends/platform/dc/plugin.x $(srcdir)/backends/platform/dc/plugin.syms) $(EXECUTABLE) backends/platform/dc/plugin_head.o CXXFLAGS += -DDYNAMIC_MODULES -PLUGIN_LDFLAGS = -ml -m4-single-only -nostartfiles -Wl,-q,-T$(srcdir)/backends/platform/dc/plugin.x,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/dc/plugin.syms -L$(ronindir)/lib +PLUGIN_LDFLAGS = -ml -m4-single-only -nostartfiles -Wl,-q,-T$(srcdir)/backends/platform/dc/plugin.x,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/dc/plugin.syms -L$(ronindir)/lib backends/platform/dc/plugin_head.o PRE_OBJS_FLAGS := -Wl,--whole-archive POST_OBJS_FLAGS := -Wl,--no-whole-archive +' + ;; + ds) + _elf_loader=yes + DEFINES="$DEFINES -DARM_TARGET -DELF_LOADER_CXA_ATEXIT -DUNCACHED_PLUGINS -DELF_NO_MEM_MANAGER" +_mak_plugins=' +PLUGIN_LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/ds/plugin.ld -mthumb-interwork -mno-fpu ' ;; freebsd*) @@ -2002,6 +2181,13 @@ CXXFLAGS += -fpic PLUGIN_LDFLAGS += -shared PRE_OBJS_FLAGS := -Wl,-export-dynamic -Wl,-whole-archive POST_OBJS_FLAGS := -Wl,-no-whole-archive +' + ;; + gamecube | wii) + _elf_loader=yes + DEFINES="$DEFINES -DPPC_TARGET -DELF_LOADER_CXA_ATEXIT -DUNCACHED_PLUGINS" +_mak_plugins=' +PLUGIN_LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/wii/plugin.ld ' ;; gph*) @@ -2022,7 +2208,7 @@ POST_OBJS_FLAGS := -Wl,-no-whole-archive LIBS += -ldl ' ;; - linux*|android) + linux* | webos) _def_plugin=' #define PLUGIN_PREFIX "lib" #define PLUGIN_SUFFIX ".so" @@ -2056,21 +2242,20 @@ PRE_OBJS_FLAGS := -Wl,--whole-archive POST_OBJS_FLAGS := -Wl,--export-all-symbols -Wl,--no-whole-archive -Wl,--out-implib,./libscummvm.a ' ;; - psp) -_def_plugin=' -#define PLUGIN_PREFIX "" -#define PLUGIN_SUFFIX ".plg" -' + ps2) + _elf_loader=yes + DEFINES="$DEFINES -DMIPS_TARGET" _mak_plugins=' -DYNAMIC_MODULES := 1 -PLUGIN_PREFIX := -PLUGIN_SUFFIX := .plg -PLUGIN_EXTRA_DEPS = $(EXECUTABLE) -CXXFLAGS += -DDYNAMIC_MODULES -LDFLAGS += -Wl,-T$(srcdir)/backends/platform/psp/main_prog.ld -PLUGIN_LDFLAGS = -nostartfiles -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/platform/psp/plugin.syms,-T$(srcdir)/backends/platform/psp/plugin.ld -lstdc++ -lc -lm -PRE_OBJS_FLAGS := -Wl,--whole-archive -POST_OBJS_FLAGS := -Wl,--no-whole-archive +LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -T$(srcdir)/backends/plugins/ps2/main_prog.ld +PLUGIN_LDFLAGS += -mno-crt0 $(PS2SDK)/ee/startup/crt0.o -Wl,-T$(srcdir)/backends/plugins/ps2/plugin.ld -lstdc++ -lc +' + ;; + psp) + _elf_loader=yes + DEFINES="$DEFINES -DMIPS_TARGET -DUNCACHED_PLUGINS" +_mak_plugins=' +LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/psp/main_prog.ld +PLUGIN_LDFLAGS += -Wl,-T$(srcdir)/backends/plugins/psp/plugin.ld -lstdc++ -lc ' ;; *) @@ -2082,6 +2267,27 @@ POST_OBJS_FLAGS := -Wl,--no-whole-archive echo "$_dynamic_modules" fi +# +# Check whether integrated ELF loader support is requested +# +define_in_config_if_yes "$_elf_loader" 'USE_ELF_LOADER' + +if test "$_elf_loader" = yes; then + CXXFLAGS="$CXXFLAGS -DDYNAMIC_MODULES" + _def_plugin=' +#define PLUGIN_PREFIX "" +#define PLUGIN_SUFFIX ".plg" +' + _mak_plugins=' +DYNAMIC_MODULES := 1 +PLUGIN_PREFIX := +PLUGIN_SUFFIX := .plg +PLUGIN_EXTRA_DEPS = $(EXECUTABLE) +PLUGIN_LDFLAGS = -nostartfiles backends/plugins/elf/version.o -Wl,-q,--just-symbols,$(EXECUTABLE),--retain-symbols-file,$(srcdir)/backends/plugins/elf/plugin.syms +PRE_OBJS_FLAGS := -Wl,--whole-archive +POST_OBJS_FLAGS := -Wl,--no-whole-archive +'"$_mak_plugins" +fi # # Check whether integrated MT-32 emulator support is requested @@ -2089,6 +2295,7 @@ fi define_in_config_if_yes "$_mt32emu" 'USE_MT32EMU' + # # Check for math lib # @@ -2211,6 +2418,33 @@ fi define_in_config_h_if_yes "$_alsa" 'USE_ALSA' echo "$_alsa" +# +# +# Check for Theora Decoder +# +echocheck "libtheoradec >= 1.0" +if test "$_vorbis" = no ; then + echo "skipping. no vorbis" + _theoradec=notsupported +fi +if test "$_theoradec" = auto ; then + _theoradec=no + cat > $TMPC << EOF +#include +#include +int main(void) { th_ycbcr_buffer yuv; th_decode_ycbcr_out(NULL, yuv); } +EOF + cc_check $THEORADEC_CFLAGS $THEORADEC_LIBS -ltheoradec && _theoradec=yes +fi +if test "$_theoradec" = yes ; then + LIBS="$LIBS $THEORADEC_LIBS -ltheoradec" + INCLUDES="$INCLUDES $THEORADEC_CFLAGS" +fi +define_in_config_if_yes "$_theoradec" 'USE_THEORADEC' +if test ! "$_theoradec" = notsupported ; then + echo "$_theoradec" +fi + # # Check for SEQ MIDI # @@ -2224,6 +2458,19 @@ fi define_in_config_h_if_yes "$_seq_midi" 'USE_SEQ_MIDI' echo "$_seq_midi" +# +# Check for TiMidity(++) +# +echocheck "TiMidity" +if test "$_timidity" = auto ; then + # TODO: Is there a good possibility of auto detecting whether we + # should include TiMidity support? It can only be used on Unix + # currently so we use that as "detection" for now. + _timidity="$_unix" +fi +define_in_config_h_if_yes "$_timidity" 'USE_TIMIDITY' +echo "$_timidity" + # # Check for ZLib # @@ -2237,7 +2484,6 @@ EOF cc_check $ZLIB_CFLAGS $ZLIB_LIBS -lz && _zlib=yes if test "$_zlib" = yes ; then - _def_zlib='#define USE_ZLIB' LIBS="$LIBS $ZLIB_LIBS -lz" INCLUDES="$INCLUDES $ZLIB_CFLAGS" else @@ -2312,6 +2558,90 @@ define_in_config_h_if_yes "$_readline" 'USE_READLINE' define_in_config_h_if_yes "$_text_console" 'USE_TEXT_CONSOLE' +# +# Check for OpenGL (ES) +# +echocheck "OpenGL" +if test "$_opengl" = auto ; then + _opengl=no + if test "$_backend" = "sdl" ; then + # Try different header filenames + # 1) GL/gl.h This is usually used on POSIX and Windows systems + # 2) OpenGL/gl.h This is used on Mac OS X + # 3) GLES/gl.h This is used for OpenGL ES 1.x + for i in "GL/gl.h" "OpenGL/gl.h" "GLES/gl.h"; do + # Test the current header for OpenGL + cat > $TMPC << EOF +#include <$i> +int main(void) { return GL_VERSION_1_1; } +EOF + cc_check $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS && _opengl=yes && break + + # Test the current header for OpenGL ES + cat > $TMPC << EOF +#include <$i> +int main(void) { return GL_OES_VERSION_1_1; } +EOF + cc_check $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS && _opengl=yes && _opengles=yes && break + done + fi +fi +if test "$_opengl" = yes ; then + # Our simple test case + cat > $TMPC << EOF +int main(void) { return 0; } +EOF + + _opengl=no + # Try different library names + if test "$_opengles" = "yes" ; then + # 1) GLES_CM This is usually used for OpenGL ES 1.1 (Common profile) + # 2) GLESv1_CM This is used by the Windows Mali OpenGL ES 1.1 Emulator + # 3) glesv1 This is used by the Linux Mali OpenGL ES 1.1 Emulator + _opengles=no + for lib in "-lGLES_CM" "-lGLESv1_CM" "-lglesv1"; do + if cc_check_no_clean $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS $lib + then + _opengl=yes + _opengles=yes + OPENGL_LIBS="$OPENGL_LIBS $lib" + break + fi + done + else + # 1) -framework OpenGL This is used on Mac OS X + # 2) GL This is usually used on POSIX systems + # 3) opengl32 This is used on Windows + # + # We try "-framework OpenGL" first here to assure it will always be + # picked up by the configure script on Mac OS X, even when a libGL + # exists. + for lib in "-framework OpenGL" "-lGL" "-lopengl32"; do + if cc_check_no_clean $DEFINES $OPENGL_CFLAGS $OPENGL_LIBS $lib + then + _opengl=yes + OPENGL_LIBS="$OPENGL_LIBS $lib" + break + fi + done + fi + cc_check_clean + + if test "$_opengl" = yes ; then + LIBS="$LIBS $OPENGL_LIBS" + INCLUDES="$INCLUDES $OPENGL_CFLAGS" + fi +fi + +if test "$_opengles" = "yes" ; then + echo "yes (OpenGL ES)" +else + echo "$_opengl" +fi + +define_in_config_if_yes "$_opengl" "USE_OPENGL" +define_in_config_if_yes "$_opengles" "USE_GLES" + # # Check for nasm # @@ -2350,14 +2680,14 @@ if test "$_have_x86" = yes ; then _nasm=no else case $_host_os in - os2-emx*) - NASMFLAGS="$NASMFLAGS -f aout" + darwin*) + NASMFLAGS="$NASMFLAGS -f macho" ;; mingw*) NASMFLAGS="$NASMFLAGS -f win32" ;; - darwin*) - NASMFLAGS="$NASMFLAGS -f macho" + os2-emx*) + NASMFLAGS="$NASMFLAGS -f aout" ;; *) NASMFLAGS="$NASMFLAGS -f elf" @@ -2410,9 +2740,17 @@ fi test "x$prefix" = xNONE && prefix=/usr/local test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' -DEFINES="$DEFINES -DDATA_PATH=\\\"$_datadir\\\"" -DEFINES="$DEFINES -DPLUGIN_DIRECTORY=\\\"$_libdir/residual\\\"" +DEFINES="$DEFINES -DDATA_PATH=\\\"$datadir\\\"" +case $_backend in + openpandora) + # Add ../plugins as a path so plugins can be found when running from a .PND. + DEFINES="$DEFINES -DPLUGIN_DIRECTORY=\\\"../plugins\\\"" + ;; + *) + DEFINES="$DEFINES -DPLUGIN_DIRECTORY=\\\"$libdir/residual\\\"" + ;; +esac # # Set variables for profiling. @@ -2453,6 +2791,15 @@ fi # case $_backend in android) + # ssp at this point so the cxxtests link + if test "$_debug_build" = yes; then + CXXFLAGS="$CXXFLAGS -fstack-protector" + else + CXXFLAGS="$CXXFLAGS -fno-stack-protector" + fi + CXXFLAGS="$CXXFLAGS -Wa,--noexecstack" + LDFLAGS="$LDFLAGS -Wl,-z,noexecstack" + static_libs='' system_libs='' for lib in $LIBS; do @@ -2469,20 +2816,9 @@ case $_backend in # -lgcc is carefully placed here - we want to catch # all toolchain symbols in *our* libraries rather # than pick up anything unhygenic from the Android libs. - LIBS="-Wl,-Bstatic $static_libs -Wl,-Bdynamic -lgcc $system_libs -lstdc++ -llog -lGLESv1_CM" - DEFINES="$DEFINES -D__ANDROID__ -DANDROID_BACKEND -DREDUCE_MEMORY_USAGE" - add_line_to_config_mk 'PLUGIN_LDFLAGS += $(LDFLAGS) -Wl,-shared,-Bsymbolic' - - # Work around an Android 2.0+ run-time linker bug: - # The linker doesn't actually look in previously - # loaded libraries when trying to resolve symbols - - # effectively turning all dlopen(RTLD_GLOBAL) calls - # into dlopen(RTLD_LOCAL). It *does* look in - # DT_NEEDED libraries, so the workaround is to add an - # (otherwise unnecessary) dependency from plugins back - # to the main libscummvm.so. - add_line_to_config_mk 'PLUGIN_LDFLAGS += -Lbuild.tmp -lscummvm' - add_line_to_config_mk 'PLUGIN_EXTRA_DEPS += build.tmp/libscummvm.so' + LIBS="-Wl,-Bstatic $static_libs" + LIBS="$LIBS -Wl,-Bdynamic -lgcc $system_libs -llog -lGLESv1_CM" + DEFINES="$DEFINES -DREDUCE_MEMORY_USAGE" ;; dc) INCLUDES="$INCLUDES "'-I$(srcdir)/backends/platform/dc -isystem $(ronindir)/include' @@ -2508,12 +2844,14 @@ case $_backend in INCLUDES="$INCLUDES `$_sdlconfig --prefix="$_sdlpath" --cflags`" LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`" LDFLAGS="$LDFLAGS" + DEFINES="$DEFINES -DSDL_BACKEND" ;; gph) find_sdlconfig INCLUDES="$INCLUDES `$_sdlconfig --prefix="$_sdlpath" --cflags`" LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`" LDFLAGS="$LDFLAGS" + DEFINES="$DEFINES -DSDL_BACKEND" ;; iphone) OBJCFLAGS="$OBJCFLAGS --std=c99" @@ -2545,12 +2883,14 @@ case $_backend in # TODO ps2 DEFINES="$DEFINES -D_EE -DFORCE_RTL" INCLUDES="$INCLUDES -I$PS2SDK/ee/include -I$PS2SDK/common/include -I$PS2SDK/ports/include" - LDFLAGS="$LDFLAGS -mno-crt0 $PS2SDK/ee/startup/crt0.o -T $PS2SDK/ee/startup/linkfile" + if test "$_dynamic_modules" = no ; then + LDFLAGS="$LDFLAGS -mno-crt0 $PS2SDK/ee/startup/crt0.o -T $PS2SDK/ee/startup/linkfile" + fi LDFLAGS="$LDFLAGS -L$PS2SDK/ee/lib -L$PS2SDK/ports/lib" LIBS="$LIBS -lmc -lpad -lmouse -lhdd -lpoweroff -lsjpcm -lm -lc -lfileXio -lkernel -lstdc++ " ;; psp) - DEFINES="$DEFINES -D__PSP__ -DDISABLE_TEXT_CONSOLE -DDISABLE_COMMAND_LINE -DDISABLE_DOSBOX_OPL" + DEFINES="$DEFINES -D__PSP__ -DDISABLE_COMMAND_LINE -DDISABLE_DOSBOX_OPL" LIBS="$LIBS -lpng -Wl,-Map,mapfile.txt" ;; samsungtv) @@ -2567,6 +2907,12 @@ case $_backend in LIBS="$LIBS `$_sdlconfig --prefix="$_sdlpath" --libs`" DEFINES="$DEFINES -DSDL_BACKEND" ;; + webos) + INCLUDES="$INCLUDES -I$WEBOS_PDK/include -I$WEBOS_PDK/include/SDL -I$WEBOS_PDK/device/usr/include" + LIBS="$LIBS -lSDL -lpdl" + DEFINES="$DEFINES -DSDL_BACKEND -DWEBOS" + MODULES="$MODULES backends/platform/sdl" + ;; wii) DEFINES="$DEFINES -D__WII__ -DGEKKO" case $_host_os in @@ -2581,6 +2927,7 @@ case $_backend in wince) INCLUDES="$INCLUDES "'-I$(srcdir) -I$(srcdir)/backends/platform/wince -I$(srcdir)/engines -I$(srcdir)/backends/platform/wince/missing/gcc -I$(srcdir)/backends/platform/wince/CEgui -I$(srcdir)/backends/platform/wince/CEkeys' LIBS="$LIBS -static -lSDL" + DEFINES="$DEFINES -DSDL_BACKEND" ;; *) echo "support for $_backend backend not implemented in configure script yet" @@ -2597,7 +2944,7 @@ if test "$have_gcc" = yes ; then case $_host_os in # newlib-based system include files suppress non-C89 function # declarations under __STRICT_ANSI__ - amigaos* | android | ds | dreamcast | gamecube | mingw* | n64 | psp | wii | wince ) + amigaos* | android | dreamcast | ds | gamecube | mingw* | n64 | psp | ps2 | wii | wince ) CXXFLAGS="$CXXFLAGS -W -Wno-unused-parameter" ;; *) @@ -2614,6 +2961,8 @@ if test "$have_gcc" = yes ; then else CXXFLAGS="$CXXFLAGS -Wconversion" fi; +elif test "$have_icc" = yes ; then + add_line_to_config_mk 'CXX_UPDATE_DEP_FLAG = -MMD -MF "$(*D)/$(DEPDIR)/$(*F).d" -MQ "$@" -MP' fi; # Some platforms use certain GNU extensions in header files @@ -2621,7 +2970,10 @@ case $_host_os in android | gamecube | psp | wii) ;; *) - CXXFLAGS="$CXXFLAGS -pedantic" + # ICC does not support pedantic + if test "$have_icc" = no ; then + CXXFLAGS="$CXXFLAGS -pedantic" + fi ;; esac @@ -2732,20 +3084,6 @@ typedef signed $type_4_byte int32; $_def_64bit_type_unsigned #endif -/* Libs */ -$_def_vorbis -$_def_tremor -$_def_flac -$_def_mad -$_def_alsa -$_def_zlib -$_def_fluidsynth -$_def_readline - -/* Options */ -$_def_text_console -$_def_mt32emu - /* Plugin settings */ $_def_plugin @@ -2774,6 +3112,7 @@ STATICLIBPATH=$_staticlibpath BACKEND := $_backend MODULES += $MODULES MODULE_DIRS += $MODULE_DIRS +EXEPRE := $HOSTEXEPRE EXEEXT := $HOSTEXEEXT NASM := $NASM NASMFLAGS := $NASMFLAGS @@ -2781,11 +3120,11 @@ NASMFLAGS := $NASMFLAGS prefix = $prefix exec_prefix = $exec_prefix bindir = $bindir +libdir = $libdir datarootdir = $datarootdir datadir = $datadir -docdir = $docdir -libdir = $libdir mandir = $mandir +docdir = $docdir $_config_mk_data diff --git a/devtools/create_project/codeblocks.cpp b/devtools/create_project/codeblocks.cpp new file mode 100644 index 00000000000..7a88afc0a67 --- /dev/null +++ b/devtools/create_project/codeblocks.cpp @@ -0,0 +1,263 @@ +/* Residual - A 3D game interpreter + * + * 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 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 "codeblocks.h" + +#include + +namespace CreateProjectTool { + +CodeBlocksProvider::CodeBlocksProvider(StringList &global_warnings, std::map &project_warnings, const int version) + : ProjectProvider(global_warnings, project_warnings, version) { +} + +void CodeBlocksProvider::createWorkspace(const BuildSetup &setup) { + std::ofstream workspace((setup.outputDir + '/' + "scummvm.workspace").c_str()); + if (!workspace) + error("Could not open \"" + setup.outputDir + '/' + "scummvm.workspace\" for writing"); + + workspace << "\n" + "\n"; + + workspace << "\t\n"; + + writeReferences(workspace); + + // Note we assume that the UUID map only includes UUIDs for enabled engines! + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + if (i->first == "scummvm") + continue; + + workspace << "\t\tfirst << ".cbp\" />\n"; + } + + workspace << "\t\n" + ""; +} + +// HACK We need to pre-process library names +// since the MSVC and mingw precompiled +// librarie have different names :( +std::string processLibraryName(std::string name) { + // Remove "_static" in lib name + size_t pos = name.find("_static"); + if (pos != std::string::npos) + return name.replace(pos, 7, ""); + + // Replace "zlib" by "libz" + if (name == "zlib") + return "libz"; + + return name; +} + +void CodeBlocksProvider::createProjectFile(const std::string &name, const std::string &, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList) { + + const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension(); + std::ofstream project(projectFile.c_str()); + if (!project) + error("Could not open \"" + projectFile + "\" for writing"); + + project << "\n" + "\n" + "\t\n" + "\t\n" + "\t\t\n" + ""; + +} + +void CodeBlocksProvider::writeWarnings(const std::string &name, std::ofstream &output) const { + + // Global warnings + for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) + output << "\t\t\t\t\t\n"; + + // Check for project-specific warnings: + std::map::iterator warningsIterator = _projectWarnings.find(name); + if (warningsIterator != _projectWarnings.end()) + for (StringList::const_iterator i = warningsIterator->second.begin(); i != warningsIterator->second.end(); ++i) + output << "\t\t\t\t\t\n"; + +} + +void CodeBlocksProvider::writeDefines(const StringList &defines, std::ofstream &output) const { + for (StringList::const_iterator i = defines.begin(); i != defines.end(); ++i) + output << "\t\t\t\t\t\n"; +} + +void CodeBlocksProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, + const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) { + + for (FileNode::NodeList::const_iterator i = dir.children.begin(); i != dir.children.end(); ++i) { + const FileNode *node = *i; + + if (!node->children.empty()) { + writeFileListToProject(*node, projectFile, indentation + 1, duplicate, objPrefix + node->name + '_', filePrefix + node->name + '/'); + } else { + std::string name, ext; + splitFilename(node->name, name, ext); + + if (ext == "rc") { + projectFile << "\t\tname) << "\">\n" + "\t\t\t\n"; + } else if (ext == "asm") { + projectFile << "\t\tname) << "\">\n" + "\t\t\t\n"; + } else { + projectFile << "\t\tname) << "\" />\n"; + } + } + } +} + +void CodeBlocksProvider::writeReferences(std::ofstream &output) { + output << "\t\t\n"; + + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + if (i->first == "scummvm") + continue; + + output << "\t\t\tfirst << ".cbp\" />\n"; + } + + output << "\t\t\n"; +} + +const char *CodeBlocksProvider::getProjectExtension() { + return ".cbp"; +} + + +} // End of CreateProjectTool namespace diff --git a/devtools/create_project/codeblocks.h b/devtools/create_project/codeblocks.h new file mode 100644 index 00000000000..b8976ce4da1 --- /dev/null +++ b/devtools/create_project/codeblocks.h @@ -0,0 +1,60 @@ +/* Residual - A 3D game interpreter + * + * 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 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 TOOLS_CREATE_PROJECT_CODEBLOCKS_H +#define TOOLS_CREATE_PROJECT_CODEBLOCKS_H + +#include "create_project.h" + +namespace CreateProjectTool { + +class CodeBlocksProvider : public ProjectProvider { +public: + CodeBlocksProvider(StringList &global_warnings, std::map &project_warnings, const int version = 0); + +protected: + + void createWorkspace(const BuildSetup &setup); + + void createOtherBuildFiles(const BuildSetup &) {} + + void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList); + + void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, + const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); + + void writeReferences(std::ofstream &output); + + const char *getProjectExtension(); + +private: + void writeWarnings(const std::string &name, std::ofstream &output) const; + void writeDefines(const StringList &defines, std::ofstream &output) const; +}; + +} // End of CreateProjectTool namespace + +#endif // TOOLS_CREATE_PROJECT_CODEBLOCKS_H diff --git a/devtools/create_project/codeblocks/create_project.cbp b/devtools/create_project/codeblocks/create_project.cbp new file mode 100644 index 00000000000..9078ddcd518 --- /dev/null +++ b/devtools/create_project/codeblocks/create_project.cbp @@ -0,0 +1,56 @@ + + + + + + diff --git a/devtools/create_project/create_project.cpp b/devtools/create_project/create_project.cpp new file mode 100644 index 00000000000..2fca776dd0f --- /dev/null +++ b/devtools/create_project/create_project.cpp @@ -0,0 +1,1230 @@ +/* Residual - A 3D game interpreter + * + * 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 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$ + * + */ + +// HACK to allow building with the SDL backend on MinGW +// see bug #1800764 "TOOLS: MinGW tools building broken" +#ifdef main +#undef main +#endif // main + +#include "create_project.h" +#include "codeblocks.h" + +#include "msvc.h" +#include "visualstudio.h" +#include "msbuild.h" + +#include +#include + +#include +#include +#include + +#include +#include +#include + +#if (defined(_WIN32) || defined(WIN32)) && !defined(__GNUC__) +#define USE_WIN32_API +#endif + +#ifdef USE_WIN32_API +#include +#else +#include +#include +#include +#include +#endif + +namespace { +/** + * Converts the given path to only use slashes as + * delimiters. + * This means that for example the path: + * foo/bar\test.txt + * will be converted to: + * foo/bar/test.txt + * + * @param path Path string. + * @return Converted path. + */ +std::string unifyPath(const std::string &path); + +/** + * Returns the last path component. + * + * @param path Path string. + * @return Last path component. + */ +std::string getLastPathComponent(const std::string &path); + +/** + * Display the help text for the program. + * + * @param exe Name of the executable. + */ +void displayHelp(const char *exe); + +/** + * Structure for describing an FSNode. This is a very minimalistic + * description, which includes everything we need. + * It only contains the name of the node and whether it is a directory + * or not. + */ +struct FSNode { + FSNode() : name(), isDirectory(false) {} + FSNode(const std::string &n, bool iD) : name(n), isDirectory(iD) {} + + std::string name; ///< Name of the file system node + bool isDirectory; ///< Whether it is a directory or not +}; + +typedef std::list FileList; +} // End of anonymous namespace + +enum ProjectType { + kProjectNone, + kProjectCodeBlocks, + kProjectMSVC +}; + +int main(int argc, char *argv[]) { +#ifndef USE_WIN32_API + // Initialize random number generator for UUID creation + std::srand(std::time(0)); +#endif + + if (argc < 2) { + displayHelp(argv[0]); + return -1; + } + + const std::string srcDir = argv[1]; + + BuildSetup setup; + setup.srcDir = unifyPath(srcDir); + + if (setup.srcDir.at(setup.srcDir.size() - 1) == '/') + setup.srcDir.erase(setup.srcDir.size() - 1); + + setup.filePrefix = setup.srcDir; + setup.outputDir = '.'; + + setup.engines = parseConfigure(setup.srcDir); + + if (setup.engines.empty()) { + std::cout << "WARNING: No engines found in configure file or configure file missing in \"" << setup.srcDir << "\"\n"; + return 0; + } + + setup.features = getAllFeatures(); + + ProjectType projectType = kProjectNone; + int msvcVersion = 9; + + // Parse command line arguments + using std::cout; + for (int i = 2; i < argc; ++i) { + if (!std::strcmp(argv[i], "--list-engines")) { + cout << " The following enables are available in the ScummVM source distribution\n" + " located at \"" << srcDir << "\":\n"; + + cout << " state | name | description\n\n"; + cout.setf(std::ios_base::left, std::ios_base::adjustfield); + for (EngineDescList::const_iterator j = setup.engines.begin(); j != setup.engines.end(); ++j) + cout << ' ' << (j->enable ? " enabled" : "disabled") << " | " << std::setw((std::streamsize)15) << j->name << std::setw((std::streamsize)0) << " | " << j->desc << "\n"; + cout.setf(std::ios_base::right, std::ios_base::adjustfield); + + return 0; + + } else if (!std::strcmp(argv[i], "--codeblocks")) { + if (projectType != kProjectNone) { + std::cerr << "ERROR: You cannot pass more than one project type!\n"; + return -1; + } + + projectType = kProjectCodeBlocks; + + } else if (!std::strcmp(argv[i], "--msvc")) { + if (projectType != kProjectNone) { + std::cerr << "ERROR: You cannot pass more than one project type!\n"; + return -1; + } + + projectType = kProjectMSVC; + + } else if (!std::strcmp(argv[i], "--msvc-version")) { + if (i + 1 >= argc) { + std::cerr << "ERROR: Missing \"version\" parameter for \"--msvc-version\"!\n"; + return -1; + } + + msvcVersion = atoi(argv[++i]); + + if (msvcVersion != 8 && msvcVersion != 9 && msvcVersion != 10) { + std::cerr << "ERROR: Unsupported version: \"" << msvcVersion << "\" passed to \"--msvc-version\"!\n"; + return -1; + } + } else if (!strncmp(argv[i], "--enable-", 9)) { + const char *name = &argv[i][9]; + if (!*name) { + std::cerr << "ERROR: Invalid command \"" << argv[i] << "\"\n"; + return -1; + } + + if (!std::strcmp(name, "all-engines")) { + for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j) + j->enable = true; + } else if (!setEngineBuildState(name, setup.engines, true)) { + // If none found, we'll try the features list + if (!setFeatureBuildState(name, setup.features, true)) { + std::cerr << "ERROR: \"" << name << "\" is neither an engine nor a feature!\n"; + return -1; + } + } + } else if (!strncmp(argv[i], "--disable-", 10)) { + const char *name = &argv[i][10]; + if (!*name) { + std::cerr << "ERROR: Invalid command \"" << argv[i] << "\"\n"; + return -1; + } + + if (!std::strcmp(name, "all-engines")) { + for (EngineDescList::iterator j = setup.engines.begin(); j != setup.engines.end(); ++j) + j->enable = false; + } else if (!setEngineBuildState(name, setup.engines, false)) { + // If none found, we'll try the features list + if (!setFeatureBuildState(name, setup.features, false)) { + std::cerr << "ERROR: \"" << name << "\" is neither an engine nor a feature!\n"; + return -1; + } + } + } else if (!std::strcmp(argv[i], "--file-prefix")) { + if (i + 1 >= argc) { + std::cerr << "ERROR: Missing \"prefix\" parameter for \"--file-prefix\"!\n"; + return -1; + } + + setup.filePrefix = unifyPath(argv[++i]); + if (setup.filePrefix.at(setup.filePrefix.size() - 1) == '/') + setup.filePrefix.erase(setup.filePrefix.size() - 1); + } else if (!std::strcmp(argv[i], "--output-dir")) { + if (i + 1 >= argc) { + std::cerr << "ERROR: Missing \"path\" parameter for \"--output-dirx\"!\n"; + return -1; + } + + setup.outputDir = unifyPath(argv[++i]); + if (setup.outputDir.at(setup.outputDir.size() - 1) == '/') + setup.outputDir.erase(setup.outputDir.size() - 1); + + } else if (!std::strcmp(argv[i], "--build-events")) { + setup.runBuildEvents = true; + } else { + std::cerr << "ERROR: Unknown parameter \"" << argv[i] << "\"\n"; + return -1; + } + } + + // Print status + cout << "Enabled engines:\n\n"; + for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) { + if (i->enable) + cout << " " << i->desc << '\n'; + } + + cout << "\nDisabled engines:\n\n"; + for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) { + if (!i->enable) + cout << " " << i->desc << '\n'; + } + + cout << "\nEnabled features:\n\n"; + for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) { + if (i->enable) + cout << " " << i->description << '\n'; + } + + cout << "\nDisabled features:\n\n"; + for (FeatureList::const_iterator i = setup.features.begin(); i != setup.features.end(); ++i) { + if (!i->enable) + cout << " " << i->description << '\n'; + } + + // Setup defines and libraries + setup.defines = getEngineDefines(setup.engines); + setup.libraries = getFeatureLibraries(setup.features); + + // Add features + StringList featureDefines = getFeatureDefines(setup.features); + setup.defines.splice(setup.defines.begin(), featureDefines); + + // Windows only has support for the SDL backend, so we hardcode it here (along with winmm) + setup.defines.push_back("WIN32"); + setup.defines.push_back("SDL_BACKEND"); + setup.libraries.push_back("sdl"); + setup.libraries.push_back("winmm"); + +// Initialize global & project-specific warnings +#define SET_GLOBAL_WARNINGS(...) \ + { \ + std::string global[PP_NARG(__VA_ARGS__)] = { __VA_ARGS__ }; \ + globalWarnings.assign(global, global + (sizeof(global) / sizeof(global[0]))); \ + } + +#define SET_WARNINGS(name, ...) \ + { \ + std::string project[PP_NARG(__VA_ARGS__)] = { __VA_ARGS__ }; \ + projectWarnings[name].assign(project, project + (sizeof(project) / sizeof(project[0]))); \ + } + + // List of global warnings and map of project-specific warnings + StringList globalWarnings; + std::map projectWarnings; + + CreateProjectTool::ProjectProvider *provider = NULL; + + switch (projectType) { + default: + case kProjectNone: + std::cerr << "ERROR: No project type has been specified!\n"; + return -1; + + case kProjectCodeBlocks: + //////////////////////////////////////////////////////////////////////////// + // Code::Blocks is using GCC behind the scenes, so we need to pass a list + // of options to enable or disable warnings + //////////////////////////////////////////////////////////////////////////// + // + // -Wall + // enable all warnings + // + // -Wno-long-long -Wno-multichar -Wno-unknown-pragmas -Wno-reorder + // disable annoying and not-so-useful warnings + // + // -Wpointer-arith -Wcast-qual -Wcast-align + // -Wshadow -Wimplicit -Wnon-virtual-dtor -Wwrite-strings + // enable even more warnings... + // + // -fno-rtti -fno-exceptions -fcheck-new + // disable RTTI and exceptions, and enable checking of pointers returned + // by "new" + // + //////////////////////////////////////////////////////////////////////////// + + SET_GLOBAL_WARNINGS("-Wall", "-Wno-long-long", "-Wno-multichar", "-Wno-unknown-pragmas", "-Wno-reorder", + "-Wpointer-arith", "-Wcast-qual", "-Wcast-align", "-Wshadow", "-Wimplicit", + "-Wnon-virtual-dtor", "-Wwrite-strings", "-fno-rtti", "-fno-exceptions", "-fcheck-new"); + + provider = new CreateProjectTool::CodeBlocksProvider(globalWarnings, projectWarnings); + + break; + + case kProjectMSVC: + //////////////////////////////////////////////////////////////////////////// + // For Visual Studio, all warnings are on by default in the project files, + // so we pass a list of warnings to disable globally or per-project + // + // Tracker reference: + // https://sourceforge.net/tracker/?func=detail&aid=2909981&group_id=37116&atid=418822 + //////////////////////////////////////////////////////////////////////////// + // + // 4068 (unknown pragma) + // only used in scumm engine to mark code sections + // + // 4100 (unreferenced formal parameter) + // + // 4103 (alignment changed after including header, may be due to missing #pragma pack(pop)) + // used by pack-start / pack-end + // + // 4127 (conditional expression is constant) + // used in a lot of engines + // + // 4244 ('conversion' conversion from 'type1' to 'type2', possible loss of data) + // throws tons and tons of warnings, most of them false positives + // + // 4250 ('class1' : inherits 'class2::member' via dominance) + // two or more members have the same name. Should be harmless + // + // 4310 (cast truncates constant value) + // used in some engines + // + // 4351 (new behavior: elements of array 'array' will be default initialized) + // a change in behavior in Visual Studio 2005. We want the new behavior, so it can be disabled + // + // 4512 ('class' : assignment operator could not be generated) + // some classes use const items and the default assignment operator cannot be generated + // + // 4702 (unreachable code) + // mostly thrown after error() calls (marked as NORETURN) + // + // 4706 (assignment within conditional expression) + // used in a lot of engines + // + // 4800 ('type' : forcing value to bool 'true' or 'false' (performance warning)) + // + // 4996 ('function': was declared deprecated) + // disabling it removes all the non-standard unsafe functions warnings (strcpy_s, etc.) + // + // 6211 (Leaking memory due to an exception. Consider using a local catch block to clean up memory) + // we disable exceptions + // + // 6204 (possible buffer overrun in call to : use of unchecked parameter ) + // 6385 (invalid data: accessing , the readable size is bytes, but bytes may be read) + // 6386 (buffer overrun: accessing , the writable size is bytes, but bytes may be written) + // give way too many false positives + // + //////////////////////////////////////////////////////////////////////////// + // + // 4189 (local variable is initialized but not referenced) + // false positive in lure engine + // + // 4355 ('this' : used in base member initializer list) + // only disabled for specific engines where it is used in a safe way + // + // 4510 ('class' : default constructor could not be generated) + // + // 4511 ('class' : copy constructor could not be generated) + // + // 4610 (object 'class' can never be instantiated - user-defined constructor required) + // "correct" but harmless (as is 4510) + // + //////////////////////////////////////////////////////////////////////////// + + SET_GLOBAL_WARNINGS("4068", "4100", "4103", "4127", "4244", "4250", "4310", "4351", "4512", "4702", "4706", "4800", "4996", "6204", "6211", "6385", "6386"); + SET_WARNINGS("agi", "4510", "4610"); + SET_WARNINGS("agos", "4511"); + SET_WARNINGS("lure", "4189", "4355"); + SET_WARNINGS("kyra", "4355"); + SET_WARNINGS("m4", "4355"); + + if (msvcVersion == 8 || msvcVersion == 9) + provider = new CreateProjectTool::VisualStudioProvider(globalWarnings, projectWarnings, msvcVersion); + else + provider = new CreateProjectTool::MSBuildProvider(globalWarnings, projectWarnings, msvcVersion); + + break; + } + + provider->createProject(setup); + + delete provider; +} + +namespace { +std::string unifyPath(const std::string &path) { + std::string result = path; + std::replace(result.begin(), result.end(), '\\', '/'); + return result; +} + +std::string getLastPathComponent(const std::string &path) { + std::string::size_type pos = path.find_last_of('/'); + if (pos == std::string::npos) + return path; + else + return path.substr(pos + 1); +} + +void displayHelp(const char *exe) { + using std::cout; + + cout << "Usage:\n" + << exe << " path\\to\\source [optional options]\n" + << "\n" + << " Creates project files for the ScummVM source located at \"path\\to\\source\".\n" + " The project files will be created in the directory where tool is run from and\n" + " will include \"path\\to\\source\" for relative file paths, thus be sure that you\n" + " pass a relative file path like \"..\\..\\trunk\".\n" + "\n" + " Additionally there are the following switches for changing various settings:\n" + "\n" + "Project specific settings:\n" + " --codeblock build Code::Blocks project files\n" + " --msvc build Visual Studio project files\n" + " --file-prefix prefix allow overwriting of relative file prefix in the\n" + " MSVC project files. By default the prefix is the\n" + " \"path\\to\\source\" argument\n" + " --output-dir path overwrite path, where the project files are placed\n" + " By default this is \".\", i.e. the current working\n" + " directory\n" + "\n" + "MSVC specific settings:\n" + " --msvc-version version set the targeted MSVC version. Possible values:\n" + " 8 stands for \"Visual Studio 2005\"\n" + " 9 stands for \"Visual Studio 2008\"\n" + " 10 stands for \"Visual Studio 2010\"\n" + " The default is \"9\", thus \"Visual Studio 2008\"\n" + " --build-events Run custom build events as part of the build\n" + " (default: false)\n" + "\n" + "ScummVM engine settings:\n" + " --list-engines list all available engines and their default state\n" + " --enable-engine enable building of the engine with the name \"engine\"\n" + " --disable-engine disable building of the engine with the name \"engine\"\n" + " --enable-all-engines enable building of all engines\n" + " --disable-all-engines disable building of all engines\n" + "\n" + "ScummVM optional feature settings:\n" + " --enable-name enable inclusion of the feature \"name\"\n" + " --disable-name disable inclusion of the feature \"name\"\n" + "\n" + " There are the following features available:\n" + "\n"; + + cout << " state | name | description\n\n"; + const FeatureList features = getAllFeatures(); + cout.setf(std::ios_base::left, std::ios_base::adjustfield); + for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i) + cout << ' ' << (i->enable ? " enabled" : "disabled") << " | " << std::setw((std::streamsize)15) << i->name << std::setw((std::streamsize)0) << " | " << i->description << '\n'; + cout.setf(std::ios_base::right, std::ios_base::adjustfield); +} + +typedef StringList TokenList; + +/** + * Takes a given input line and creates a list of tokens out of it. + * + * A token in this context is separated by whitespaces. A special case + * are quotation marks though. A string inside quotation marks is treated + * as single token, even when it contains whitespaces. + * + * Thus for example the input: + * foo bar "1 2 3 4" ScummVM + * will create a list with the following entries: + * "foo", "bar", "1 2 3 4", "ScummVM" + * As you can see the quotation marks will get *removed* too. + * + * @param input The text to be tokenized. + * @return A list of tokens. + */ +TokenList tokenize(const std::string &input); + +/** + * Try to parse a given line and create an engine definition + * out of the result. + * + * This may take *any* input line, when the line is not used + * to define an engine the result of the function will be "false". + * + * Note that the contents of "engine" are undefined, when this + * function returns "false". + * + * @param line Text input line. + * @param engine Reference to an object, where the engine information + * is to be stored in. + * @return "true", when parsing succeeded, "false" otherwise. + */ +bool parseEngine(const std::string &line, EngineDesc &engine); +} // End of anonymous namespace + +EngineDescList parseConfigure(const std::string &srcDir) { + std::string configureFile = srcDir + "/configure"; + + std::ifstream configure(configureFile.c_str()); + if (!configure) + return EngineDescList(); + + std::string line; + EngineDescList engines; + + for (;;) { + std::getline(configure, line); + if (configure.eof()) + break; + + if (configure.fail()) + error("Failed while reading from " + configureFile); + + EngineDesc desc; + if (parseEngine(line, desc)) + engines.push_back(desc); + } + + return engines; +} + +bool isSubEngine(const std::string &name, const EngineDescList &engines) { + for (EngineDescList::const_iterator i = engines.begin(); i != engines.end(); ++i) { + if (std::find(i->subEngines.begin(), i->subEngines.end(), name) != i->subEngines.end()) + return true; + } + + return false; +} + +bool setEngineBuildState(const std::string &name, EngineDescList &engines, bool enable) { + if (enable && isSubEngine(name, engines)) { + // When we enable a sub engine, we need to assure that the parent is also enabled, + // thus we enable both sub engine and parent over here. + EngineDescList::iterator engine = std::find(engines.begin(), engines.end(), name); + if (engine != engines.end()) { + engine->enable = enable; + + for (engine = engines.begin(); engine != engines.end(); ++engine) { + if (std::find(engine->subEngines.begin(), engine->subEngines.end(), name) != engine->subEngines.end()) { + engine->enable = true; + break; + } + } + + return true; + } + } else { + EngineDescList::iterator engine = std::find(engines.begin(), engines.end(), name); + if (engine != engines.end()) { + engine->enable = enable; + + // When we disable an einge, we also need to disable all the sub engines. + if (!enable && !engine->subEngines.empty()) { + for (StringList::const_iterator j = engine->subEngines.begin(); j != engine->subEngines.end(); ++j) { + EngineDescList::iterator subEngine = std::find(engines.begin(), engines.end(), *j); + if (subEngine != engines.end()) + subEngine->enable = false; + } + } + + return true; + } + } + + return false; +} + +StringList getEngineDefines(const EngineDescList &engines) { + StringList result; + + for (EngineDescList::const_iterator i = engines.begin(); i != engines.end(); ++i) { + if (i->enable) { + std::string define = "ENABLE_" + i->name; + std::transform(define.begin(), define.end(), define.begin(), toupper); + result.push_back(define); + } + } + + return result; +} + +namespace { +bool parseEngine(const std::string &line, EngineDesc &engine) { + // Format: + // add_engine engine_name "Readable Description" enable_default ["SubEngineList"] + TokenList tokens = tokenize(line); + + if (tokens.size() < 4) + return false; + + TokenList::const_iterator token = tokens.begin(); + + if (*token != "add_engine") + return false; + ++token; + + engine.name = *token; ++token; + engine.desc = *token; ++token; + engine.enable = (*token == "yes"); ++token; + if (token != tokens.end()) + engine.subEngines = tokenize(*token); + + return true; +} + +TokenList tokenize(const std::string &input) { + TokenList result; + + std::string::size_type sIdx = input.find_first_not_of(" \t"); + std::string::size_type nIdx = std::string::npos; + + if (sIdx == std::string::npos) + return result; + + do { + if (input.at(sIdx) == '\"') { + ++sIdx; + nIdx = input.find_first_of('\"', sIdx); + } else { + nIdx = input.find_first_of(' ', sIdx); + } + + if (nIdx != std::string::npos) { + result.push_back(input.substr(sIdx, nIdx - sIdx)); + sIdx = input.find_first_not_of(" \t", nIdx + 1); + } else { + result.push_back(input.substr(sIdx)); + break; + } + } while (sIdx != std::string::npos); + + return result; +} +} // End of anonymous namespace + +namespace { +const Feature s_features[] = { + // Libraries + { "libz", "USE_ZLIB", "zlib", true, "zlib (compression) support" }, + { "mad", "USE_MAD", "libmad", true, "libmad (MP3) support" }, + { "vorbis", "USE_VORBIS", "libvorbisfile_static libvorbis_static libogg_static", true, "Ogg Vorbis support" }, + { "flac", "USE_FLAC", "libFLAC_static", true, "FLAC support" }, + { "png", "USE_PNG", "libpng", true, "libpng support" }, + { "theora", "USE_THEORADEC", "libtheora_static", true, "Theora decoding support" }, + { "mpeg2", "USE_MPEG2", "libmpeg2", false, "mpeg2 codec for cutscenes" }, + + // ScummVM feature flags + { "scalers", "USE_SCALERS", "", true, "Scalers" }, + { "hqscalers", "USE_HQ_SCALERS", "", true, "HQ scalers" }, + { "16bit", "USE_RGB_COLOR", "", true, "16bit color support" }, + { "mt32emu", "USE_MT32EMU", "", true, "integrated MT-32 emulator" }, + { "nasm", "USE_NASM", "", true, "IA-32 assembly support" }, // This feature is special in the regard, that it needs additional handling. + { "opengl", "USE_OPENGL", "opengl32", true, "OpenGL support" }, + { "indeo3", "USE_INDEO3", "", true, "Indeo3 codec support"}, + { "translation", "USE_TRANSLATION", "", true, "Translation support" }, + { "langdetect", "USE_DETECTLANG", "", true, "System language detection support" } // This feature actually depends on "translation", there + // is just no current way of properly detecting this... +}; +} // End of anonymous namespace + +FeatureList getAllFeatures() { + const size_t featureCount = sizeof(s_features) / sizeof(s_features[0]); + + FeatureList features; + for (size_t i = 0; i < featureCount; ++i) + features.push_back(s_features[i]); + + return features; +} + +StringList getFeatureDefines(const FeatureList &features) { + StringList defines; + + for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i) { + if (i->enable && i->define && i->define[0]) + defines.push_back(i->define); + } + + return defines; +} + +StringList getFeatureLibraries(const FeatureList &features) { + StringList libraries; + + for (FeatureList::const_iterator i = features.begin(); i != features.end(); ++i) { + if (i->enable && i->libraries && i->libraries[0]) { + StringList fLibraries = tokenize(i->libraries); + libraries.splice(libraries.end(), fLibraries); + } + } + + return libraries; +} + +bool setFeatureBuildState(const std::string &name, FeatureList &features, bool enable) { + FeatureList::iterator i = std::find(features.begin(), features.end(), name); + if (i != features.end()) { + i->enable = enable; + return true; + } else { + return false; + } +} + +namespace CreateProjectTool { + +////////////////////////////////////////////////////////////////////////// +// Utilities +////////////////////////////////////////////////////////////////////////// + +std::string convertPathToWin(const std::string &path) { + std::string result = path; + std::replace(result.begin(), result.end(), '/', '\\'); + return result; +} + +std::string getIndent(const int indentation) { + std::string result; + for (int i = 0; i < indentation; ++i) + result += '\t'; + return result; +} + +void splitFilename(const std::string &fileName, std::string &name, std::string &ext) { + const std::string::size_type dot = fileName.find_last_of('.'); + name = (dot == std::string::npos) ? fileName : fileName.substr(0, dot); + ext = (dot == std::string::npos) ? std::string() : fileName.substr(dot + 1); +} + +bool producesObjectFile(const std::string &fileName) { + std::string n, ext; + splitFilename(fileName, n, ext); + + if (ext == "cpp" || ext == "c" || ext == "asm") + return true; + else + return false; +} + +/** + * Checks whether the give file in the specified directory is present in the given + * file list. + * + * This function does as special match against the file list. It will not take file + * extensions into consideration, when the extension of a file in the specified + * directory is one of "h", "cpp", "c" or "asm". + * + * @param dir Parent directory of the file. + * @param fileName File name to match. + * @param fileList List of files to match against. + * @return "true" when the file is in the list, "false" otherwise. + */ +bool isInList(const std::string &dir, const std::string &fileName, const StringList &fileList) { + std::string compareName, extensionName; + splitFilename(fileName, compareName, extensionName); + + if (!extensionName.empty()) + compareName += '.'; + + for (StringList::const_iterator i = fileList.begin(); i != fileList.end(); ++i) { + if (i->compare(0, dir.size(), dir)) + continue; + + // When no comparison name is given, we try to match whether a subset of + // the given directory should be included. To do that we must assure that + // the first character after the substring, having the same size as dir, must + // be a path delimiter. + if (compareName.empty()) { + if (i->size() >= dir.size() + 1 && i->at(dir.size()) == '/') + return true; + else + continue; + } + + const std::string lastPathComponent = getLastPathComponent(*i); + if (!producesObjectFile(fileName) && extensionName != "h") { + if (fileName == lastPathComponent) + return true; + } else { + if (!lastPathComponent.compare(0, compareName.size(), compareName)) + return true; + } + } + + return false; +} + +/** + * A strict weak compare predicate for sorting a list of + * "FileNode *" entries. + * + * It will sort directory nodes before file nodes. + * + * @param l Left-hand operand. + * @param r Right-hand operand. + * @return "true" if and only if l should be sorted before r. + */ +bool compareNodes(const FileNode *l, const FileNode *r) { + if (!l) { + return false; + } else if (!r) { + return true; + } else { + if (l->children.empty() && !r->children.empty()) { + return false; + } else if (!l->children.empty() && r->children.empty()) { + return true; + } else { + return l->name < r->name; + } + } +} + +/** + * Returns a list of all files and directories in the specified + * path. + * + * @param dir Directory which should be listed. + * @return List of all children. + */ +FileList listDirectory(const std::string &dir) { + FileList result; +#ifdef USE_WIN32_API + WIN32_FIND_DATA fileInformation; + HANDLE fileHandle = FindFirstFile((dir + "/*").c_str(), &fileInformation); + + if (fileHandle == INVALID_HANDLE_VALUE) + return result; + + do { + if (fileInformation.cFileName[0] == '.') + continue; + + result.push_back(FSNode(fileInformation.cFileName, (fileInformation.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0)); + } while (FindNextFile(fileHandle, &fileInformation) == TRUE); + + FindClose(fileHandle); +#else + DIR *dirp = opendir(dir.c_str()); + struct dirent *dp = NULL; + + if (dirp == NULL) + return result; + + while ((dp = readdir(dirp)) != NULL) { + if (dp->d_name[0] == '.') + continue; + + struct stat st; + if (stat((dir + '/' + dp->d_name).c_str(), &st)) + continue; + + result.push_back(FSNode(dp->d_name, S_ISDIR(st.st_mode))); + } + + closedir(dirp); +#endif + return result; +} + +/** + * Scans the specified directory against files, which should be included + * in the project files. It will not include files present in the exclude list. + * + * @param dir Directory in which to search for files. + * @param includeList Files to include in the project. + * @param excludeList Files to exclude from the project. + * @return Returns a file node for the specific directory. + */ +FileNode *scanFiles(const std::string &dir, const StringList &includeList, const StringList &excludeList) { + FileList files = listDirectory(dir); + + if (files.empty()) + return 0; + + FileNode *result = new FileNode(dir); + assert(result); + + for (FileList::const_iterator i = files.begin(); i != files.end(); ++i) { + if (i->isDirectory) { + const std::string subDirName = dir + '/' + i->name; + if (!isInList(subDirName, std::string(), includeList)) + continue; + + FileNode *subDir = scanFiles(subDirName, includeList, excludeList); + + if (subDir) { + subDir->name = i->name; + result->children.push_back(subDir); + } + continue; + } + + if (isInList(dir, i->name, excludeList)) + continue; + + std::string name, ext; + splitFilename(i->name, name, ext); + + if (ext != "h") { + if (!isInList(dir, i->name, includeList)) + continue; + } + + FileNode *child = new FileNode(i->name); + assert(child); + result->children.push_back(child); + } + + if (result->children.empty()) { + delete result; + return 0; + } else { + result->children.sort(compareNodes); + return result; + } +} + +////////////////////////////////////////////////////////////////////////// +// Project Provider methods +////////////////////////////////////////////////////////////////////////// +ProjectProvider::ProjectProvider(StringList &global_warnings, std::map &project_warnings, const int version) + : _version(version), _globalWarnings(global_warnings), _projectWarnings(project_warnings) { +} + +void ProjectProvider::createProject(const BuildSetup &setup) { + _uuidMap = createUUIDMap(setup); + + // We also need to add the UUID of the main project file. + const std::string svmUUID = _uuidMap["scummvm"] = createUUID(); + + // Create Solution/Workspace file + createWorkspace(setup); + + StringList in, ex; + + // Create engine project files + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + if (i->first == "scummvm") + continue; + + in.clear(); ex.clear(); + const std::string moduleDir = setup.srcDir + "/engines/" + i->first; + + createModuleList(moduleDir, setup.defines, in, ex); + createProjectFile(i->first, i->second, setup, moduleDir, in, ex); + } + + // Last but not least create the main ScummVM project file. + in.clear(); ex.clear(); + + // File list for the ScummVM project file + createModuleList(setup.srcDir + "/backends", setup.defines, in, ex); + createModuleList(setup.srcDir + "/backends/platform/sdl", setup.defines, in, ex); + createModuleList(setup.srcDir + "/base", setup.defines, in, ex); + createModuleList(setup.srcDir + "/common", setup.defines, in, ex); + createModuleList(setup.srcDir + "/engines", setup.defines, in, ex); + createModuleList(setup.srcDir + "/graphics", setup.defines, in, ex); + createModuleList(setup.srcDir + "/gui", setup.defines, in, ex); + createModuleList(setup.srcDir + "/audio", setup.defines, in, ex); + createModuleList(setup.srcDir + "/audio/softsynth/mt32", setup.defines, in, ex); + createModuleList(setup.srcDir + "/video", setup.defines, in, ex); + + // Resource files + in.push_back(setup.srcDir + "/icons/scummvm.ico"); + in.push_back(setup.srcDir + "/dists/scummvm.rc"); + + // Various text files + in.push_back(setup.srcDir + "/AUTHORS"); + in.push_back(setup.srcDir + "/COPYING"); + in.push_back(setup.srcDir + "/COPYING.LGPL"); + in.push_back(setup.srcDir + "/COPYRIGHT"); + in.push_back(setup.srcDir + "/NEWS"); + in.push_back(setup.srcDir + "/README"); + in.push_back(setup.srcDir + "/TODO"); + + // Create the scummvm project file. + createProjectFile("scummvm", svmUUID, setup, setup.srcDir, in, ex); + + // Create other misc. build files + createOtherBuildFiles(setup); +} + +ProjectProvider::UUIDMap ProjectProvider::createUUIDMap(const BuildSetup &setup) const { + UUIDMap result; + + for (EngineDescList::const_iterator i = setup.engines.begin(); i != setup.engines.end(); ++i) { + if (!i->enable || isSubEngine(i->name, setup.engines)) + continue; + + result[i->name] = createUUID(); + } + + return result; +} + +std::string ProjectProvider::createUUID() const { +#ifdef USE_WIN32_API + UUID uuid; + if (UuidCreate(&uuid) != RPC_S_OK) + error("UuidCreate failed"); + + unsigned char *string = 0; + if (UuidToStringA(&uuid, &string) != RPC_S_OK) + error("UuidToStringA failed"); + + std::string result = std::string((char *)string); + std::transform(result.begin(), result.end(), result.begin(), toupper); + RpcStringFreeA(&string); + return result; +#else + unsigned char uuid[16]; + + for (int i = 0; i < 16; ++i) + uuid[i] = (unsigned char)((std::rand() / (double)(RAND_MAX)) * 0xFF); + + uuid[8] &= 0xBF; uuid[8] |= 0x80; + uuid[6] &= 0x4F; uuid[6] |= 0x40; + + std::stringstream uuidString; + uuidString << std::hex << std::uppercase << std::setfill('0'); + for (int i = 0; i < 16; ++i) { + uuidString << std::setw(2) << (int)uuid[i]; + if (i == 3 || i == 5 || i == 7 || i == 9) { + uuidString << std::setw(0) << '-'; + } + } + + return uuidString.str(); +#endif +} + +void ProjectProvider::addFilesToProject(const std::string &dir, std::ofstream &projectFile, + const StringList &includeList, const StringList &excludeList, + const std::string &filePrefix) { + // Check for duplicate object file names + StringList duplicate; + + for (StringList::const_iterator i = includeList.begin(); i != includeList.end(); ++i) { + const std::string fileName = getLastPathComponent(*i); + + // Leave out non object file names. + if (fileName.size() < 2 || fileName.compare(fileName.size() - 2, 2, ".o")) + continue; + + // Check whether an duplicate has been found yet + if (std::find(duplicate.begin(), duplicate.end(), fileName) != duplicate.end()) + continue; + + // Search for duplicates + StringList::const_iterator j = i; ++j; + for (; j != includeList.end(); ++j) { + if (fileName == getLastPathComponent(*j)) { + duplicate.push_back(fileName); + break; + } + } + } + + FileNode *files = scanFiles(dir, includeList, excludeList); + + writeFileListToProject(*files, projectFile, 0, duplicate, std::string(), filePrefix + '/'); + + delete files; +} + +void ProjectProvider::createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const { + const std::string moduleMkFile = moduleDir + "/module.mk"; + std::ifstream moduleMk(moduleMkFile.c_str()); + if (!moduleMk) + error(moduleMkFile + " is not present"); + + includeList.push_back(moduleMkFile); + + std::stack shouldInclude; + shouldInclude.push(true); + + bool hadModule = false; + std::string line; + for (;;) { + std::getline(moduleMk, line); + + if (moduleMk.eof()) + break; + + if (moduleMk.fail()) + error("Failed while reading from " + moduleMkFile); + + TokenList tokens = tokenize(line); + if (tokens.empty()) + continue; + + TokenList::const_iterator i = tokens.begin(); + if (*i == "MODULE") { + if (hadModule) + error("More than one MODULE definition in " + moduleMkFile); + // Format: "MODULE := path/to/module" + if (tokens.size() < 3) + error("Malformed MODULE definition in " + moduleMkFile); + ++i; + if (*i != ":=") + error("Malformed MODULE definition in " + moduleMkFile); + ++i; + + std::string moduleRoot = unifyPath(*i); + if (moduleDir.compare(moduleDir.size() - moduleRoot.size(), moduleRoot.size(), moduleRoot)) + error("MODULE root " + moduleRoot + " does not match base dir " + moduleDir); + + hadModule = true; + } else if (*i == "MODULE_OBJS") { + if (tokens.size() < 3) + error("Malformed MODULE_OBJS definition in " + moduleMkFile); + ++i; + + // This is not exactly correct, for example an ":=" would usually overwrite + // all already added files, but since we do only save the files inside + // includeList or excludeList currently, we couldn't handle such a case easily. + // (includeList and excludeList should always preserve their entries, not added + // by this function, thus we can't just clear them on ":=" or "="). + // But hopefully our module.mk files will never do such things anyway. + if (*i != ":=" && *i != "+=" && *i != "=") + error("Malformed MODULE_OBJS definition in " + moduleMkFile); + + ++i; + + while (i != tokens.end()) { + if (*i == "\\") { + std::getline(moduleMk, line); + tokens = tokenize(line); + i = tokens.begin(); + } else { + if (shouldInclude.top()) + includeList.push_back(moduleDir + "/" + unifyPath(*i)); + else + excludeList.push_back(moduleDir + "/" + unifyPath(*i)); + ++i; + } + } + } else if (*i == "ifdef") { + if (tokens.size() < 2) + error("Malformed ifdef in " + moduleMkFile); + ++i; + + if (std::find(defines.begin(), defines.end(), *i) == defines.end()) + shouldInclude.push(false); + else + shouldInclude.push(true); + } else if (*i == "ifndef") { + if (tokens.size() < 2) + error("Malformed ifndef in " + moduleMkFile); + ++i; + + if (std::find(defines.begin(), defines.end(), *i) == defines.end()) + shouldInclude.push(true); + else + shouldInclude.push(false); + } else if (*i == "else") { + shouldInclude.top() = !shouldInclude.top(); + } else if (*i == "endif") { + if (shouldInclude.size() <= 1) + error("endif without ifdef found in " + moduleMkFile); + shouldInclude.pop(); + } else if (*i == "elif") { + error("Unsupported operation 'elif' in " + moduleMkFile); + } else if (*i == "ifeq") { + //XXX + shouldInclude.push(false); + } + } + + if (shouldInclude.size() != 1) + error("Malformed file " + moduleMkFile); +} + +} // End of anonymous namespace + +void error(const std::string &message) { + std::cerr << "ERROR: " << message << "!" << std::endl; + std::exit(-1); +} diff --git a/devtools/create_project/create_project.h b/devtools/create_project/create_project.h new file mode 100644 index 00000000000..ad698a56a7d --- /dev/null +++ b/devtools/create_project/create_project.h @@ -0,0 +1,443 @@ +/* Residual - A 3D game interpreter + * + * 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 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 TOOLS_CREATE_PROJECT_H +#define TOOLS_CREATE_PROJECT_H + +#include +#include +#include + +#include + +// The PP_NARG macro returns the number of arguments that have been passed to it. +#define PP_NARG(...) \ + PP_NARG_(__VA_ARGS__,PP_RSEQ_N()) +#define PP_NARG_(...) \ + PP_ARG_N(__VA_ARGS__) +#define PP_ARG_N( \ + _1, _2, _3, _4, _5, _6, _7, _8, _9,_10, \ + _11,_12,_13,_14,_15,_16,_17,_18,_19,_20, \ + _21,_22,_23,_24,_25,_26,_27,_28,_29,_30, \ + _31,_32,_33,_34,_35,_36,_37,_38,_39,_40, \ + _41,_42,_43,_44,_45,_46,_47,_48,_49,_50, \ + _51,_52,_53,_54,_55,_56,_57,_58,_59,_60, \ + _61,_62,_63,N,...) N +#define PP_RSEQ_N() \ + 63,62,61,60, \ + 59,58,57,56,55,54,53,52,51,50, \ + 49,48,47,46,45,44,43,42,41,40, \ + 39,38,37,36,35,34,33,32,31,30, \ + 29,28,27,26,25,24,23,22,21,20, \ + 19,18,17,16,15,14,13,12,11,10, \ + 9,8,7,6,5,4,3,2,1,0 + +#define SET_VALUES(list, ...) \ + { \ + std::string values[PP_NARG(__VA_ARGS__)] = { __VA_ARGS__ }; \ + list.assign(values, values + (sizeof(values) / sizeof(values[0]))); \ + } + +typedef std::list StringList; + +/** + * Structure to describe a game engine to be built into ScummVM. + * + * We do get the game engines available by parsing the "configure" + * script of our source distribution. See "parseConfigure" for more + * information on that. + * @see parseConfigure + */ +struct EngineDesc { + /** + * The name of the engine. We use this to determine the directory + * the engine is in and to create the define, which needs to be + * set to enable the engine. + */ + std::string name; + + /** + * A human readable description of the engine. We will use this + * to display a description of the engine to the user in the list + * of which engines are built and which are disabled. + */ + std::string desc; + + /** + * Whether the engine should be included in the build or not. + */ + bool enable; + + /** + * A list of all available sub engine names. Sub engines are engines + * which are built on top of an existing engines and can be only + * enabled when the parten engine is enabled. + */ + StringList subEngines; + + bool operator==(const std::string &n) const { + return (name == n); + } +}; + +typedef std::list EngineDescList; + +/** + * This function parses the ScummVM configure file and creates a list + * of available engines. + * + * It will also automatically setup the default build state (enabled + * or disabled) to the state specified in the "configure" file. + * + * @param srcDir Path to the root of the ScummVM source. + * @return List of available engines. + */ +EngineDescList parseConfigure(const std::string &srcDir); + +/** + * Checks whether the specified engine is a sub engine. To determine this + * there is a fully setup engine list needed. + * + * @param name Name of the engine to check. + * @param engines List of engines. + * @return "true", when the engine is a sub engine, "false" otherwise. + */ +bool isSubEngine(const std::string &name, const EngineDescList &engines); + +/** + * Enables or disables the specified engine in the engines list. + * + * This function also disables all sub engines of an engine, when it is + * to be disabled. + * Also this function does enable the parent of a sub engine, when a + * sub engine is to be enabled. + * + * @param name Name of the engine to be enabled or disabled. + * @param engines The list of engines, which should be operated on. + * @param enable Whether the engine should be enabled or disabled. + * @return "true", when it succeeded, "false" otherwise. + */ +bool setEngineBuildState(const std::string &name, EngineDescList &engines, bool enable); + +/** + * Returns a list of all defines, according to the engine list passed. + * + * @param features The list of engines, which should be operated on. (this may contain engines, which are *not* enabled!) + */ +StringList getEngineDefines(const EngineDescList &engines); + +/** + * Structure to define a given feature, usually an external library, + * used to build ScummVM. + */ +struct Feature { + const char *name; ///< Name of the feature + const char *define; ///< Define of the feature + + const char *libraries; ///< Libraries, which need to be linked, for the feature + + bool enable; ///< Whether the feature is enabled or not + + const char *description; ///< Human readable description of the feature + + bool operator==(const std::string &n) const { + return (name == n); + } +}; +typedef std::list FeatureList; + +/** + * Creates a list of all features available for MSVC. + * + * @return A list including all features available. + */ +FeatureList getAllFeatures(); + +/** + * Returns a list of all defines, according to the feature set + * passed. + * + * @param features List of features for the build (this may contain features, which are *not* enabled!) + */ +StringList getFeatureDefines(const FeatureList &features); + +/** + * Returns a list of all external library files, according to the + * feature set passed. + * + * @param features List of features for the build (this may contain features, which are *not* enabled!) + */ +StringList getFeatureLibraries(const FeatureList &features); + +/** + * Sets the state of a given feature. This can be used to + * either include or exclude an feature. + * + * @param name Name of the feature. + * @param features List of features to operate on. + * @param enable Whether the feature should be enabled or disabled. + * @return "true", when it succeeded, "false" otherwise. + */ +bool setFeatureBuildState(const std::string &name, FeatureList &features, bool enable); + +/** + * Structure to describe a build setup. + * + * This includes various information about which engines to + * enable, which features should be built into ScummVM. + * It also contains the path to the ScummVM souce root. + */ +struct BuildSetup { + std::string srcDir; ///< Path to the ScummVM sources. + std::string filePrefix; ///< Prefix for the relative path arguments in the project files. + std::string outputDir; ///< Path where to put the MSVC project files. + + EngineDescList engines; ///< Engine list for the build (this may contain engines, which are *not* enabled!). + FeatureList features; ///< Feature list for the build (this may contain features, which are *not* enabled!). + + StringList defines; ///< List of all defines for the build. + StringList libraries; ///< List of all external libraries required for the build. + + bool runBuildEvents; + + BuildSetup() { + runBuildEvents = false; + } +}; + +/** + * Quits the program with the specified error message. + * + * @param message The error message to print to stderr. + */ +#if defined(__GNUC__) + #define NORETURN_POST __attribute__((__noreturn__)) +#elif defined(_MSC_VER) + #define NORETURN_PRE __declspec(noreturn) +#endif + +#ifndef NORETURN_PRE +#define NORETURN_PRE +#endif + +#ifndef NORETURN_POST +#define NORETURN_POST +#endif +void NORETURN_PRE error(const std::string &message) NORETURN_POST; + +namespace CreateProjectTool { + +/** + * Gets a proper sequence of \t characters for the given + * indentation level. + * + * For example with an indentation level of 2 this will + * produce: + * \t\t + * + * @param indentation The indentation level + * @return Sequence of \t characters. + */ +std::string getIndent(const int indentation); + +/** + * Converts the given path to only use backslashes. + * This means that for example the path: + * foo/bar\test.txt + * will be converted to: + * foo\bar\test.txt + * + * @param path Path string. + * @return Converted path. + */ +std::string convertPathToWin(const std::string &path); + +/** + * Splits a file name into name and extension. + * The file name must be only the filename, no + * additional path name. + * + * @param fileName Filename to split + * @param name Reference to a string, where to store the name. + * @param ext Reference to a string, where to store the extension. + */ +void splitFilename(const std::string &fileName, std::string &name, std::string &ext); + +/** + * Checks whether the given file will produce an object file or not. + * + * @param fileName Name of the file. + * @return "true" when it will produce a file, "false" otherwise. + */ +bool producesObjectFile(const std::string &fileName); + +/** + * Structure representing a file tree. This contains two + * members: name and children. "name" holds the name of + * the node. "children" does contain all the node's children. + * When the list "children" is empty, the node is a file entry, + * otherwise it's a directory. + */ +struct FileNode { + typedef std::list NodeList; + + explicit FileNode(const std::string &n) : name(n), children() {} + + ~FileNode() { + for (NodeList::iterator i = children.begin(); i != children.end(); ++i) + delete *i; + } + + std::string name; ///< Name of the node + NodeList children; ///< List of children for the node +}; + +class ProjectProvider { +public: + typedef std::map UUIDMap; + + /** + * Instantiate new ProjectProvider class + * + * @param global_warnings List of warnings that apply to all projects + * @param project_warnings List of project-specific warnings + * @param version Target project version. + */ + ProjectProvider(StringList &global_warnings, std::map &project_warnings, const int version = 0); + virtual ~ProjectProvider() {} + + /** + * Creates all build files + * + * @param setup Description of the desired build setup. + */ + void createProject(const BuildSetup &setup); + +protected: + const int _version; ///< Target project version + StringList &_globalWarnings; ///< Global warnings + std::map &_projectWarnings; ///< Per-project warnings + + UUIDMap _uuidMap; ///< List of (project name, UUID) pairs + + /** + * Create workspace/solution file + * + * @param setup Description of the desired build setup. + */ + virtual void createWorkspace(const BuildSetup &setup) = 0; + + /** + * Create other files (such as build properties) + * + * @param setup Description of the desired build setup. + */ + virtual void createOtherBuildFiles(const BuildSetup &setup) = 0; + + /** + * Create a project file for the specified list of files. + * + * @param name Name of the project file. + * @param uuid UUID of the project file. + * @param setup Description of the desired build. + * @param moduleDir Path to the module. + * @param includeList Files to include (must have "moduleDir" as prefix). + * @param excludeList Files to exclude (must have "moduleDir" as prefix). + */ + virtual void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList) = 0; + + /** + * Writes file entries for the specified directory node into + * the given project file. It will also take care of duplicate + * object files. + * + * @param dir Directory node. + * @param projectFile File stream to write to. + * @param indentation Indentation level to use. + * @param duplicate List of duplicate object file names. + * @param objPrefix Prefix to use for object files, which would name clash. + * @param filePrefix Generic prefix to all files of the node. + */ + virtual void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, + const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) = 0; + + /** + * Output a list of project references to the file stream + * + * @param output File stream to write to. + */ + virtual void writeReferences(std::ofstream &) {}; + + /** + * Get the file extension for project files + */ + virtual const char *getProjectExtension() { return ""; } + + /** + * Adds files of the specified directory recursively to given project file. + * + * @param dir Path to the directory. + * @param projectFile Output stream object, where all data should be written to. + * @param includeList Files to include (must have a relative directory as prefix). + * @param excludeList Files to exclude (must have a relative directory as prefix). + * @param filePrefix Prefix to use for relative path arguments. + */ + void addFilesToProject(const std::string &dir, std::ofstream &projectFile, + const StringList &includeList, const StringList &excludeList, + const std::string &filePrefix); + + /** + * Creates a list of files of the specified module. This also + * creates a list of files, which should not be included. + * All filenames will have "moduleDir" as prefix. + * + * @param moduleDir Path to the module. + * @param defines List of set defines. + * @param includeList Reference to a list, where included files should be added. + * @param excludeList Reference to a list, where excluded files should be added. + */ + void createModuleList(const std::string &moduleDir, const StringList &defines, StringList &includeList, StringList &excludeList) const; + + /** + * Creates an UUID for every enabled engine of the + * passed build description. + * + * @param setup Description of the desired build. + * @return A map, which includes UUIDs for all enabled engines. + */ + UUIDMap createUUIDMap(const BuildSetup &setup) const; + + /** + * Creates an UUID and returns it in string representation. + * + * @return A new UUID as string. + */ + std::string createUUID() const; +}; + +} // End of CreateProjectTool namespace + +#endif // TOOLS_CREATE_PROJECT_H diff --git a/devtools/create_project/module.mk b/devtools/create_project/module.mk new file mode 100644 index 00000000000..4382fe176ca --- /dev/null +++ b/devtools/create_project/module.mk @@ -0,0 +1,20 @@ +# $URL$ +# $Id$ + +MODULE := devtools/create_project + +MODULE_OBJS := \ + create_project.o \ + codeblocks.o \ + msvc.o \ + visualstudio.o \ + msbuild.o + +# Set the name of the executable +TOOL_EXECUTABLE := create_project + +# Include common rules +include $(srcdir)/rules.mk + +# Silence variadic macros warning for C++ (disabled as this is included globally) +#CXXFLAGS := $(CXXFLAGS) -Wno-variadic-macros diff --git a/devtools/create_project/msbuild.cpp b/devtools/create_project/msbuild.cpp new file mode 100644 index 00000000000..54f8247e2b6 --- /dev/null +++ b/devtools/create_project/msbuild.cpp @@ -0,0 +1,516 @@ +/* Residual - A 3D game interpreter + * + * 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 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 "msbuild.h" + +#include + +#include + +namespace CreateProjectTool { + +////////////////////////////////////////////////////////////////////////// +// MSBuild Provider (Visual Studio 2010) +////////////////////////////////////////////////////////////////////////// + +MSBuildProvider::MSBuildProvider(StringList &global_warnings, std::map &project_warnings, const int version) + : MSVCProvider(global_warnings, project_warnings, version) { + +} + +const char *MSBuildProvider::getProjectExtension() { + return ".vcxproj"; +} + +const char *MSBuildProvider::getPropertiesExtension() { + return ".props"; +} + +int MSBuildProvider::getVisualStudioVersion() { + return 2010; +} + +#define OUTPUT_CONFIGURATION_MSBUILD(config, platform) \ + (project << "\t\t\n" \ + "\t\t\t" << config << "\n" \ + "\t\t\t" << platform << "\n" \ + "\t\t\n") + +#define OUTPUT_CONFIGURATION_TYPE_MSBUILD(config) \ + (project << "\t\n" \ + "\t\t" << (name == "scummvm" ? "Application" : "StaticLibrary") << "\n" \ + "\t\n") + +#define OUTPUT_PROPERTIES_MSBUILD(config, properties) \ + (project << "\t\n" \ + "\t\t\n" \ + "\t\t\n" \ + "\t\n") + +void MSBuildProvider::createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList) { + const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension(); + std::ofstream project(projectFile.c_str()); + if (!project) + error("Could not open \"" + projectFile + "\" for writing"); + + project << "\n" + "\n" + "\t\n"; + + OUTPUT_CONFIGURATION_MSBUILD("Debug", "Win32"); + OUTPUT_CONFIGURATION_MSBUILD("Debug", "x64"); + OUTPUT_CONFIGURATION_MSBUILD("Analysis", "Win32"); + OUTPUT_CONFIGURATION_MSBUILD("Analysis", "x64"); + OUTPUT_CONFIGURATION_MSBUILD("Release", "Win32"); + OUTPUT_CONFIGURATION_MSBUILD("Release", "x64"); + + project << "\t\n"; + + // Project name & Guid + project << "\t\n" + "\t\t{" << uuid << "}\n" + "\t\t" << name << "\n" + "\t\tWin32Proj\n" + "\t\n"; + + // Shared configuration + project << "\t\n"; + + OUTPUT_CONFIGURATION_TYPE_MSBUILD("Release|Win32"); + OUTPUT_CONFIGURATION_TYPE_MSBUILD("Analysis|Win32"); + OUTPUT_CONFIGURATION_TYPE_MSBUILD("Debug|Win32"); + OUTPUT_CONFIGURATION_TYPE_MSBUILD("Release|x64"); + OUTPUT_CONFIGURATION_TYPE_MSBUILD("Analysis|x64"); + OUTPUT_CONFIGURATION_TYPE_MSBUILD("Debug|x64"); + + project << "\t\n" + "\t\n" + "\t\n"; + + OUTPUT_PROPERTIES_MSBUILD("Release|Win32", "ScummVM_Release.props"); + OUTPUT_PROPERTIES_MSBUILD("Analysis|Win32", "ScummVM_Analysis.props"); + OUTPUT_PROPERTIES_MSBUILD("Debug|Win32", "ScummVM_Debug.props"); + OUTPUT_PROPERTIES_MSBUILD("Release|x64", "ScummVM_Release64.props"); + OUTPUT_PROPERTIES_MSBUILD("Analysis|x64", "ScummVM_Analysis64.props"); + OUTPUT_PROPERTIES_MSBUILD("Debug|x64", "ScummVM_Debug64.props"); + + project << "\t\n"; + + // Project-specific settings (analysis uses debug properties) + outputProjectSettings(project, name, setup, false, true, false); + outputProjectSettings(project, name, setup, false, true, true); + outputProjectSettings(project, name, setup, true, true, false); + outputProjectSettings(project, name, setup, false, false, false); + outputProjectSettings(project, name, setup, false, false, true); + outputProjectSettings(project, name, setup, true, false, false); + + // Files + std::string modulePath; + if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) { + modulePath = moduleDir.substr(setup.srcDir.size()); + if (!modulePath.empty() && modulePath.at(0) == '/') + modulePath.erase(0, 1); + } + + if (modulePath.size()) + addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix + '/' + modulePath); + else + addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix); + + // Output references for scummvm project + if (name == "scummvm") + writeReferences(project); + + project << "\t\n" + "\t\n" + "\t\n" + "\n"; + + // Output filter file if necessary + createFiltersFile(setup, name); +} + +#define OUTPUT_FILTER_MSBUILD(files, action) \ + if (!files.empty()) { \ + filters << "\t\n"; \ + for (std::list::const_iterator entry = files.begin(); entry != files.end(); ++entry) { \ + if ((*entry).filter != "") { \ + filters << "\t\t<" action " Include=\"" << (*entry).path << "\">\n" \ + "\t\t\t" << (*entry).filter << "\n" \ + "\t\t\n"; \ + } else { \ + filters << "\t\t<" action " Include=\"" << (*entry).path << "\" />\n"; \ + } \ + } \ + filters << "\t\n"; \ + } + +void MSBuildProvider::createFiltersFile(const BuildSetup &setup, const std::string &name) { + // No filters => no need to create a filter file + if (_filters.empty()) + return; + + // Sort all list alphabetically + _filters.sort(); + _compileFiles.sort(); + _includeFiles.sort(); + _otherFiles.sort(); + _resourceFiles.sort(); + _asmFiles.sort(); + + const std::string filtersFile = setup.outputDir + '/' + name + getProjectExtension() + ".filters"; + std::ofstream filters(filtersFile.c_str()); + if (!filters) + error("Could not open \"" + filtersFile + "\" for writing"); + + filters << "\n" + "\n"; + + // Output the list of filters + filters << "\t\n"; + for (std::list::iterator filter = _filters.begin(); filter != _filters.end(); ++filter) { + filters << "\t\t\n" + "\t\t\t" << createUUID() << "\n" + "\t\t\n"; + } + filters << "\t\n"; + + // Output files + OUTPUT_FILTER_MSBUILD(_compileFiles, "ClCompile") + OUTPUT_FILTER_MSBUILD(_includeFiles, "ClInclude") + OUTPUT_FILTER_MSBUILD(_otherFiles, "None") + OUTPUT_FILTER_MSBUILD(_resourceFiles, "ResourceCompile") + OUTPUT_FILTER_MSBUILD(_asmFiles, "CustomBuild") + + filters << ""; +} + +void MSBuildProvider::writeReferences(std::ofstream &output) { + output << "\t\n"; + + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + if (i->first == "scummvm") + continue; + + output << "\tfirst << ".vcxproj\">\n" + "\t\t{" << i->second << "}\n" + "\t\n"; + } + + output << "\t\n"; +} + +void MSBuildProvider::outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) { + const std::string configuration = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug")); + + // Check for project-specific warnings: + std::map::iterator warningsIterator = _projectWarnings.find(name); + + // Nothing to add here, move along! + if (name != "scummvm" && name != "sword25" && name != "tinsel" && warningsIterator == _projectWarnings.end()) + return; + + std::string warnings = ""; + if (warningsIterator != _projectWarnings.end()) + for (StringList::const_iterator i = warningsIterator->second.begin(); i != warningsIterator->second.end(); ++i) + warnings += *i + ';'; + + project << "\t\n" + "\t\t\n"; + + // Compile configuration + if (name == "scummvm" || name == "sword25") { + project << "\t\t\tfalse\n"; + } else { + if (name == "tinsel" && !isRelease) + project << "\t\t\tProgramDatabase\n"; + + if (warningsIterator != _projectWarnings.end()) + project << "\t\t\t" << warnings << ";%(DisableSpecificWarnings)\n"; + } + + project << "\t\t\n"; + + // Link configuration for scummvm project + if (name == "scummvm") { + std::string libraries; + + for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) + libraries += *i + ".lib;"; + + project << "\t\t\n" + "\t\t\t$(OutDir)scummvm.exe\n" + "\t\t\t" << libraries << "%(AdditionalDependencies)\n" + "\t\t\n"; + + if (setup.runBuildEvents) { + // Only generate revision number in debug builds + if (!isRelease) { + project << "\t\t\n" + "\t\t\tGenerate internal_version.h\n" + "\t\t\t" << getPreBuildEvent() << "\n" + "\t\t\n"; + } + + // Copy data files to the build folder + project << "\t\t\n" + "\t\t\tCopy data files to the build folder\n" + "\t\t\t" << getPostBuildEvent(isWin32) << "\n" + "\t\t\n"; + } + } + + project << "\t\n"; +} + +void MSBuildProvider::outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix) { + + std::string warnings; + for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) + warnings += *i + ';'; + + std::string definesList; + for (StringList::const_iterator i = defines.begin(); i != defines.end(); ++i) + definesList += *i + ';'; + + properties << "\n" + "\n" + "\t\n" + "\t\t<_ProjectFileVersion>10.0.30319.1\n" + "\t\t<_PropertySheetDisplayName>ScummVM_Global\n" + "\t\t$(SCUMMVM_LIBS)\\bin;$(ExecutablePath)\n" + "\t\t$(SCUMMVM_LIBS)\\lib\\" << (bits == 32 ? "x86" : "x64") << ";$(LibraryPath)\n" + "\t\t$(SCUMMVM_LIBS)\\include;$(IncludePath)\n" + "\t\t$(Configuration)" << bits << "\\\n" + "\t\t$(Configuration)" << bits << "/$(ProjectName)\\\n" + "\t\n" + "\t\n" + "\t\t\n" + "\t\t\ttrue\n" + "\t\t\t" << warnings << ";%(DisableSpecificWarnings)\n" + "\t\t\t$(SCUMMVM_LIBS)\\include;" << prefix << ";" << prefix << "\\engines;%(AdditionalIncludeDirectories)\n" + "\t\t\t" << definesList << "%(PreprocessorDefinitions)\n" + "\t\t\t\n" + "\t\t\tfalse\n" + "\t\t\tLevel4\n" + "\t\t\tfalse\n" + "\t\t\tDefault\n" + "\t\t\n" + "\t\t\n" + "\t\t\t%(IgnoreSpecificDefaultLibraries)\n" + "\t\t\tConsole\n" + "\t\t\tWinMainCRTStartup\n" + "\t\t\n" + "\t\t\n" + "\t\t\tHAS_INCLUDE_SET;%(PreprocessorDefinitions)\n" + "\t\t\t" << prefix << ";%(AdditionalIncludeDirectories)\n" + "\t\t\n" + "\t\n" + "\n"; + + properties.flush(); +} + +void MSBuildProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) { + const std::string outputType = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug")); + const std::string outputBitness = (isWin32 ? "32" : "64"); + + std::ofstream properties((setup.outputDir + '/' + "ScummVM_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); + if (!properties) + error("Could not open \"" + setup.outputDir + '/' + "ScummVM_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); + + properties << "\n" + "\n" + "\t\n" + "\t\t\n" + "\t\n" + "\t\n" + "\t\t<_ProjectFileVersion>10.0.30319.1\n" + "\t\t<_PropertySheetDisplayName>ScummVM_" << outputType << outputBitness << "\n" + "\t\t" << (isRelease ? "false" : "true") << "\n" + "\t\n" + "\t\n" + "\t\t\n"; + + if (isRelease) { + properties << "\t\t\ttrue\n" + "\t\t\ttrue\n" + "\t\t\tWIN32;RELEASE_BUILD;%(PreprocessorDefinitions)\n" + "\t\t\ttrue\n" + "\t\t\tfalse\n" + "\t\t\t\n" + "\t\t\t" << (enableAnalysis ? "true" : "false") << "\n" + "\t\t\n" + "\t\t\n" + "\t\t\t%(IgnoreSpecificDefaultLibraries)\n" + "\t\t\ttrue\n"; + } else { + properties << "\t\t\tDisabled\n" + "\t\t\tWIN32;%(PreprocessorDefinitions)\n" + "\t\t\ttrue\n" + "\t\t\tEnableFastChecks\n" + "\t\t\tMultiThreadedDebug\n" + "\t\t\ttrue\n" + "\t\t\tfalse\n" + "\t\t\t" << (isWin32 ? "EditAndContinue" : "ProgramDatabase") << "\n" // For x64 format Edit and continue is not supported, thus we default to Program Database + "\t\t\t" << (enableAnalysis ? "true" : "false") << "\n" + "\t\t\n" + "\t\t\n" + "\t\t\ttrue\n" + "\t\t\tlibcmt.lib;%(IgnoreSpecificDefaultLibraries)\n"; + } + + properties << "\t\t\n" + "\t\n" + "\n"; + + properties.flush(); + properties.close(); +} + +#define OUTPUT_NASM_COMMAND_MSBUILD(config) \ + projectFile << "\t\t\tnasm.exe -f win32 -g -o \"$(IntDir)" << (isDuplicate ? (*entry).prefix : "") << "%(Filename).obj\" \"%(FullPath)\"\n" \ + "\t\t\t$(IntDir)" << (isDuplicate ? (*entry).prefix : "") << "%(Filename).obj;%(Outputs)\n"; + +#define OUPUT_FILES_MSBUILD(files, action) \ + if (!files.empty()) { \ + projectFile << "\t\n"; \ + for (std::list::const_iterator entry = files.begin(); entry != files.end(); ++entry) { \ + projectFile << "\t\t<" action " Include=\"" << (*entry).path << "\" />\n"; \ + } \ + projectFile << "\t\n"; \ + } + +bool hasEnding(std::string const &fullString, std::string const &ending) { + if (fullString.length() > ending.length()) { + return (0 == fullString.compare (fullString.length() - ending.length(), ending.length(), ending)); + } else { + return false; + } +} + + +void MSBuildProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int, const StringList &duplicate, + const std::string &objPrefix, const std::string &filePrefix) { + // Reset lists + _filters.clear(); + _compileFiles.clear(); + _includeFiles.clear(); + _otherFiles.clear(); + _resourceFiles.clear(); + _asmFiles.clear(); + + // Compute the list of files + _filters.push_back(""); // init filters + computeFileList(dir, duplicate, objPrefix, filePrefix); + _filters.pop_back(); // remove last empty filter + + // Output compile files + if (!_compileFiles.empty()) { + projectFile << "\t\n"; + for (std::list::const_iterator entry = _compileFiles.begin(); entry != _compileFiles.end(); ++entry) { + const bool isDuplicate = (std::find(duplicate.begin(), duplicate.end(), (*entry).name + ".o") != duplicate.end()); + + // Deal with duplicated file names + if (isDuplicate) { + projectFile << "\t\t\n" + "\t\t\t$(IntDir)" << (*entry).prefix << "%(Filename).obj\n"; + + if (hasEnding((*entry).path, "base\\version.cpp")) + projectFile << "\t\t\tSCUMMVM_REVISION#" $(SCUMMVM_REVISION_STRING)";%(PreprocessorDefinitions)\n"; + + projectFile << "\t\t\n"; + } else { + projectFile << "\t\t\n"; + } + } + projectFile << "\t\n"; + } + + // Output include, other and resource files + OUPUT_FILES_MSBUILD(_includeFiles, "ClInclude") + OUPUT_FILES_MSBUILD(_otherFiles, "None") + OUPUT_FILES_MSBUILD(_resourceFiles, "ResourceCompile") + + // Output asm files + if (!_asmFiles.empty()) { + projectFile << "\t\n"; + for (std::list::const_iterator entry = _asmFiles.begin(); entry != _asmFiles.end(); ++entry) { + + const bool isDuplicate = (std::find(duplicate.begin(), duplicate.end(), (*entry).name + ".o") != duplicate.end()); + + projectFile << "\t\t\n" + "\t\t\tDocument\n"; + + OUTPUT_NASM_COMMAND_MSBUILD("Debug") + OUTPUT_NASM_COMMAND_MSBUILD("Analysis") + OUTPUT_NASM_COMMAND_MSBUILD("Release") + + projectFile << "\t\t\n"; + } + projectFile << "\t\n"; + } +} + +void MSBuildProvider::computeFileList(const FileNode &dir, const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) { + for (FileNode::NodeList::const_iterator i = dir.children.begin(); i != dir.children.end(); ++i) { + const FileNode *node = *i; + + if (!node->children.empty()) { + // Update filter + std::string _currentFilter = _filters.back(); + _filters.back().append((_filters.back() == "" ? "" : "\\") + node->name); + + computeFileList(*node, duplicate, objPrefix + node->name + '_', filePrefix + node->name + '/'); + + // Reset filter + _filters.push_back(_currentFilter); + } else { + // Filter files by extension + std::string name, ext; + splitFilename(node->name, name, ext); + + FileEntry entry; + entry.name = name; + entry.path = convertPathToWin(filePrefix + node->name); + entry.filter = _filters.back(); + entry.prefix = objPrefix; + + if (ext == "cpp" || ext == "c") + _compileFiles.push_back(entry); + else if (ext == "h") + _includeFiles.push_back(entry); + else if (ext == "rc") + _resourceFiles.push_back(entry); + else if (ext == "asm") + _asmFiles.push_back(entry); + else + _otherFiles.push_back(entry); + } + } +} + +} // End of CreateProjectTool namespace diff --git a/devtools/create_project/msbuild.h b/devtools/create_project/msbuild.h new file mode 100644 index 00000000000..bab59c0cb4f --- /dev/null +++ b/devtools/create_project/msbuild.h @@ -0,0 +1,82 @@ +/* Residual - A 3D game interpreter + * + * 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 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 TOOLS_CREATE_PROJECT_MSBUILD_H +#define TOOLS_CREATE_PROJECT_MSBUILD_H + +#include "msvc.h" + +namespace CreateProjectTool { + +class MSBuildProvider : public MSVCProvider { +public: + MSBuildProvider(StringList &global_warnings, std::map &project_warnings, const int version); + +protected: + void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList); + + void outputProjectSettings(std::ofstream &project, const std::string &name, const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis); + + void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, + const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); + + void writeReferences(std::ofstream &output); + + void outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix); + + void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis); + + const char *getProjectExtension(); + const char *getPropertiesExtension(); + int getVisualStudioVersion(); + +private: + struct FileEntry { + std::string name; + std::string path; + std::string filter; + std::string prefix; + + bool operator<(const FileEntry& rhs) const { + return path.compare(rhs.path) == -1; // Not exactly right for alphabetical order, but good enough + } + }; + typedef std::list FileEntries; + + std::list _filters; // list of filters (we need to create a GUID for each filter id) + FileEntries _compileFiles; + FileEntries _includeFiles; + FileEntries _otherFiles; + FileEntries _asmFiles; + FileEntries _resourceFiles; + + void computeFileList(const FileNode &dir, const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); + void createFiltersFile(const BuildSetup &setup, const std::string &name); +}; + +} // End of CreateProjectTool namespace + +#endif // TOOLS_CREATE_PROJECT_MSBUILD_H diff --git a/devtools/create_project/msvc.cpp b/devtools/create_project/msvc.cpp new file mode 100644 index 00000000000..39446080684 --- /dev/null +++ b/devtools/create_project/msvc.cpp @@ -0,0 +1,177 @@ +/* Residual - A 3D game interpreter + * + * 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 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 "msvc.h" + +#include + +#include + +namespace CreateProjectTool { + +////////////////////////////////////////////////////////////////////////// +// MSVC Provider (Base class) +////////////////////////////////////////////////////////////////////////// +MSVCProvider::MSVCProvider(StringList &global_warnings, std::map &project_warnings, const int version) + : ProjectProvider(global_warnings, project_warnings, version) { +} + +void MSVCProvider::createWorkspace(const BuildSetup &setup) { + UUIDMap::const_iterator svmUUID = _uuidMap.find("scummvm"); + if (svmUUID == _uuidMap.end()) + error("No UUID for \"scummvm\" project created"); + + const std::string svmProjectUUID = svmUUID->second; + assert(!svmProjectUUID.empty()); + + std::string solutionUUID = createUUID(); + + std::ofstream solution((setup.outputDir + '/' + "scummvm.sln").c_str()); + if (!solution) + error("Could not open \"" + setup.outputDir + '/' + "scummvm.sln\" for writing"); + + solution << "Microsoft Visual Studio Solution File, Format Version " << _version + 1 << ".00\n"; + solution << "# Visual Studio " << getVisualStudioVersion() << "\n"; + + solution << "Project(\"{" << solutionUUID << "}\") = \"scummvm\", \"scummvm" << getProjectExtension() << "\", \"{" << svmProjectUUID << "}\"\n"; + + // Project dependencies are moved to vcxproj files in Visual Studio 2010 + if (_version < 10) + writeReferences(solution); + + solution << "EndProject\n"; + + // Note we assume that the UUID map only includes UUIDs for enabled engines! + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + if (i->first == "scummvm") + continue; + + solution << "Project(\"{" << solutionUUID << "}\") = \"" << i->first << "\", \"" << i->first << getProjectExtension() << "\", \"{" << i->second << "}\"\n" + << "EndProject\n"; + } + + solution << "Global\n" + "\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n" + "\t\tDebug|Win32 = Debug|Win32\n" + "\t\tAnalysis|Win32 = Analysis|Win32\n" + "\t\tRelease|Win32 = Release|Win32\n" + "\t\tDebug|x64 = Debug|x64\n" + "\t\tAnalysis|x64 = Analysis|x64\n" + "\t\tRelease|x64 = Release|x64\n" + "\tEndGlobalSection\n" + "\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n"; + + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + solution << "\t\t{" << i->second << "}.Debug|Win32.ActiveCfg = Debug|Win32\n" + "\t\t{" << i->second << "}.Debug|Win32.Build.0 = Debug|Win32\n" + "\t\t{" << i->second << "}.Analysis|Win32.ActiveCfg = Analysis|Win32\n" + "\t\t{" << i->second << "}.Analysis|Win32.Build.0 = Analysis|Win32\n" + "\t\t{" << i->second << "}.Release|Win32.ActiveCfg = Release|Win32\n" + "\t\t{" << i->second << "}.Release|Win32.Build.0 = Release|Win32\n" + "\t\t{" << i->second << "}.Debug|x64.ActiveCfg = Debug|x64\n" + "\t\t{" << i->second << "}.Debug|x64.Build.0 = Debug|x64\n" + "\t\t{" << i->second << "}.Analysis|x64.ActiveCfg = Analysis|x64\n" + "\t\t{" << i->second << "}.Analysis|x64.Build.0 = Analysis|x64\n" + "\t\t{" << i->second << "}.Release|x64.ActiveCfg = Release|x64\n" + "\t\t{" << i->second << "}.Release|x64.Build.0 = Release|x64\n"; + } + + solution << "\tEndGlobalSection\n" + "\tGlobalSection(SolutionProperties) = preSolution\n" + "\t\tHideSolutionNode = FALSE\n" + "\tEndGlobalSection\n" + "EndGlobal\n"; +} + +void MSVCProvider::createOtherBuildFiles(const BuildSetup &setup) { + // Create the global property file + createGlobalProp(setup); + + // Create the configuration property files (for Debug and Release with 32 and 64bits versions) + // Note: we use the debug properties for the analysis configuration + createBuildProp(setup, true, false, false); + createBuildProp(setup, true, true, false); + createBuildProp(setup, false, false, false); + createBuildProp(setup, false, false, true); + createBuildProp(setup, false, true, false); + createBuildProp(setup, false, true, true); +} + +void MSVCProvider::createGlobalProp(const BuildSetup &setup) { + std::ofstream properties((setup.outputDir + '/' + "ScummVM_Global" + getPropertiesExtension()).c_str()); + if (!properties) + error("Could not open \"" + setup.outputDir + '/' + "ScummVM_Global" + getPropertiesExtension() + "\" for writing"); + + outputGlobalPropFile(properties, 32, setup.defines, convertPathToWin(setup.filePrefix)); + properties.close(); + + properties.open((setup.outputDir + '/' + "ScummVM_Global64" + getPropertiesExtension()).c_str()); + if (!properties) + error("Could not open \"" + setup.outputDir + '/' + "ScummVM_Global64" + getPropertiesExtension() + "\" for writing"); + + // HACK: We must disable the "nasm" feature for x64. To achieve that we must duplicate the feature list and + // recreate a define list. + FeatureList x64Features = setup.features; + setFeatureBuildState("nasm", x64Features, false); + StringList x64Defines = getFeatureDefines(x64Features); + StringList x64EngineDefines = getEngineDefines(setup.engines); + x64Defines.splice(x64Defines.end(), x64EngineDefines); + + // HACK: This definitly should not be here, but otherwise we would not define SDL_BACKEND for x64. + x64Defines.push_back("WIN32"); + x64Defines.push_back("SDL_BACKEND"); + + outputGlobalPropFile(properties, 64, x64Defines, convertPathToWin(setup.filePrefix)); +} + +std::string MSVCProvider::getPreBuildEvent() const { + std::string cmdLine = ""; + + cmdLine = "@echo off\n" + "echo Executing Pre-Build script...\n" + "echo.\n" + "@call "$(SolutionDir)../../devtools/create_project/scripts/prebuild.cmd" "$(SolutionDir)/../.."\n" + "EXIT /B0"; + + return cmdLine; +} + +std::string MSVCProvider::getPostBuildEvent(bool isWin32) const { + std::string cmdLine = ""; + + cmdLine = "@echo off\n" + "echo Executing Post-Build script...\n" + "echo.\n" + "@call "$(SolutionDir)../../devtools/create_project/scripts/postbuild.cmd" "$(SolutionDir)/../.." "$(OutDir)" "; + + cmdLine += (isWin32) ? "x86" : "x64"; + + cmdLine += "\n" + "EXIT /B0"; + + return cmdLine; +} + +} // End of CreateProjectTool namespace diff --git a/devtools/create_project/msvc.h b/devtools/create_project/msvc.h new file mode 100644 index 00000000000..66bf7fe61ec --- /dev/null +++ b/devtools/create_project/msvc.h @@ -0,0 +1,100 @@ +/* Residual - A 3D game interpreter + * + * 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 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 TOOLS_CREATE_PROJECT_MSVC_H +#define TOOLS_CREATE_PROJECT_MSVC_H + +#include "create_project.h" + +namespace CreateProjectTool { + +class MSVCProvider : public ProjectProvider { +public: + MSVCProvider(StringList &global_warnings, std::map &project_warnings, const int version); + +protected: + + void createWorkspace(const BuildSetup &setup); + + void createOtherBuildFiles(const BuildSetup &setup); + + /** + * Create the global project properties. + * + * @param setup Description of the desired build setup. + */ + void createGlobalProp(const BuildSetup &setup); + + /** + * Outputs a property file based on the input parameters. + * + * It can be easily used to create different global properties files + * for a 64 bit and a 32 bit version. It will also take care that the + * two platform configurations will output their files into different + * directories. + * + * @param properties File stream in which to write the property settings. + * @param bits Number of bits the platform supports. + * @param defines Defines the platform needs to have set. + * @param prefix File prefix, used to add additional include paths. + */ + virtual void outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix) = 0; + + /** + * Generates the project properties for debug and release settings. + * + * @param setup Description of the desired build setup. + * @param isRelease Type of property file + * @param isWin32 Bitness of property file + * @param enableAnalysis PREfast support + */ + virtual void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) = 0; + + /** + * Get the file extension for property files + */ + virtual const char *getPropertiesExtension() = 0; + + /** + * Get the Visual Studio version (used by the VS shell extension to launch the correct VS version) + */ + virtual int getVisualStudioVersion() = 0; + + /** + * Get the command line for the revision tool (shared between all Visual Studio based providers) + */ + std::string getPreBuildEvent() const; + + /** + * Get the command line for copying data files to the build directory + * + * @param isWin32 Bitness of property file + */ + std::string getPostBuildEvent(bool isWin32) const; +}; + +} // End of CreateProjectTool namespace + +#endif // TOOLS_CREATE_PROJECT_MSVC_H diff --git a/devtools/create_project/msvc10/create_project.sln b/devtools/create_project/msvc10/create_project.sln new file mode 100644 index 00000000000..69eeb8ed196 --- /dev/null +++ b/devtools/create_project/msvc10/create_project.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcxproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/devtools/create_project/msvc10/create_project.vcxproj b/devtools/create_project/msvc10/create_project.vcxproj new file mode 100644 index 00000000000..532d6dba29f --- /dev/null +++ b/devtools/create_project/msvc10/create_project.vcxproj @@ -0,0 +1,117 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + + {CF177559-077D-4A08-AABE-BE0FD35F6C63} + create_project + + + + Application + MultiByte + true + + + Application + MultiByte + + + + + + + + + + + + + <_ProjectFileVersion>10.0.30319.1 + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + $(SolutionDir)$(Configuration)\ + $(Configuration)\ + + + + Disabled + true + EnableFastChecks + MultiThreadedDebugDLL + Level4 + EditAndContinue + false + 4003;4512;4127 + + + Rpcrt4.lib;%(AdditionalDependencies) + true + MachineX86 + + + xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc10\ +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc9\ +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc8\ +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\ + + + + + MaxSpeed + true + MultiThreadedDLL + true + Level3 + ProgramDatabase + 4003;4512;4127 + + + Rpcrt4.lib;%(AdditionalDependencies) + true + true + true + MachineX86 + + + xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc10\ +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc9\ +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\msvc8\ +xcopy /Y $(TargetPath) $(SolutionDir)\..\..\..\dists\codeblocks\ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/devtools/create_project/msvc10/create_project.vcxproj.filters b/devtools/create_project/msvc10/create_project.vcxproj.filters new file mode 100644 index 00000000000..7922e1e6f75 --- /dev/null +++ b/devtools/create_project/msvc10/create_project.vcxproj.filters @@ -0,0 +1,59 @@ + + + + + {2e3580c8-ec3a-4c81-8351-b668c668db2a} + + + {31aaf58c-d3cb-4ed6-8eca-163b4a9b31a6} + + + {f980f6fb-41b6-4161-b035-58b200c85cad} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + scripts + + + scripts + + + scripts + + + \ No newline at end of file diff --git a/devtools/create_project/msvc8/create_project.sln b/devtools/create_project/msvc8/create_project.sln new file mode 100644 index 00000000000..4a0152f33f5 --- /dev/null +++ b/devtools/create_project/msvc8/create_project.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 9.00 +# Visual Studio 2005 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/devtools/create_project/msvc8/create_project.vcproj b/devtools/create_project/msvc8/create_project.vcproj new file mode 100644 index 00000000000..bc3b2437acf --- /dev/null +++ b/devtools/create_project/msvc8/create_project.vcproj @@ -0,0 +1,235 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/devtools/create_project/msvc9/create_project.sln b/devtools/create_project/msvc9/create_project.sln new file mode 100644 index 00000000000..df754e1d789 --- /dev/null +++ b/devtools/create_project/msvc9/create_project.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "create_project", "create_project.vcproj", "{CF177559-077D-4A08-AABE-BE0FD35F6C63}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Release|Win32 = Release|Win32 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.ActiveCfg = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Debug|Win32.Build.0 = Debug|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.ActiveCfg = Release|Win32 + {CF177559-077D-4A08-AABE-BE0FD35F6C63}.Release|Win32.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/devtools/create_project/msvc9/create_project.vcproj b/devtools/create_project/msvc9/create_project.vcproj new file mode 100644 index 00000000000..c89b88a1c9a --- /dev/null +++ b/devtools/create_project/msvc9/create_project.vcproj @@ -0,0 +1,236 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/devtools/create_project/visualstudio.cpp b/devtools/create_project/visualstudio.cpp new file mode 100644 index 00000000000..23a256d570d --- /dev/null +++ b/devtools/create_project/visualstudio.cpp @@ -0,0 +1,378 @@ +/* Residual - A 3D game interpreter + * + * 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 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 "visualstudio.h" + +#include + +#include + +namespace CreateProjectTool { + +////////////////////////////////////////////////////////////////////////// +// Visual Studio Provider (Visual Studio 2005 & 2008) +////////////////////////////////////////////////////////////////////////// + +VisualStudioProvider::VisualStudioProvider(StringList &global_warnings, std::map &project_warnings, const int version) + : MSVCProvider(global_warnings, project_warnings, version) { +} + +const char *VisualStudioProvider::getProjectExtension() { + return ".vcproj"; +} + +const char *VisualStudioProvider::getPropertiesExtension() { + return ".vsprops"; +} + +int VisualStudioProvider::getVisualStudioVersion() { + if (_version == 9) + return 2008; + + if (_version == 8) + return 2005; + + error("Unsupported version passed to createScummVMSolution"); +} + +#define OUTPUT_CONFIGURATION_SCUMMVM(config, platform, props) { \ + project << "\t\t\n" \ + "\t\t\t\n" \ + "\t\t\t\n" \ + "\t\t\n"; \ +} + +#define OUTPUT_CONFIGURATION_SCUMMVM_DEBUG(config, platform, props, isWin32) { \ + project << "\t\t\n" \ + "\t\t\t\n" \ + "\t\t\t\n"; \ + if (setup.runBuildEvents) { \ + project << "\t\t\t\n" \ + "\t\t\t\n"; \ + } \ + project << "\t\t\n"; \ +} + +#define OUTPUT_CONFIGURATION(config, platform, props) { \ + project << "\t\t\n" \ + "\t\t\t\n" \ + "\t\t\n"; \ +} + +void VisualStudioProvider::createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList) { + const std::string projectFile = setup.outputDir + '/' + name + getProjectExtension(); + std::ofstream project(projectFile.c_str()); + if (!project) + error("Could not open \"" + projectFile + "\" for writing"); + + project << "\n" + "= 9) + project << "\tTargetFrameworkVersion=\"131072\"\n"; + + project << "\t>\n" + "\t\n" + "\t\t\n" + "\t\t\n" + "\t\n" + "\t\n"; + + // Check for project-specific warnings: + std::map< std::string, std::list >::iterator warningsIterator = _projectWarnings.find(name); + + if (name == "scummvm") { + std::string libraries; + + for (StringList::const_iterator i = setup.libraries.begin(); i != setup.libraries.end(); ++i) + libraries += ' ' + *i + ".lib"; + + // Win32 + OUTPUT_CONFIGURATION_SCUMMVM_DEBUG("Debug", "Win32", "", true); + OUTPUT_CONFIGURATION_SCUMMVM_DEBUG("Analysis", "Win32", "", true); + OUTPUT_CONFIGURATION_SCUMMVM("Release", "Win32", ""); + + // x64 + // For 'x64' we must disable NASM support. Usually we would need to disable the "nasm" feature for that and + // re-create the library list, BUT since NASM doesn't link any additional libraries, we can just use the + // libraries list created for IA-32. If that changes in the future, we need to adjust this part! + OUTPUT_CONFIGURATION_SCUMMVM_DEBUG("Debug", "x64", "64", true); + OUTPUT_CONFIGURATION_SCUMMVM_DEBUG("Analysis", "x64", "64", true); + OUTPUT_CONFIGURATION_SCUMMVM("Release", "x64", "64"); + + } else { + std::string warnings = ""; + if (warningsIterator != _projectWarnings.end()) + for (StringList::const_iterator i = warningsIterator->second.begin(); i != warningsIterator->second.end(); ++i) + warnings += *i + ';'; + + std::string toolConfig; + toolConfig = (!warnings.empty() ? "DisableSpecificWarnings=\"" + warnings + "\"" : ""); + toolConfig += (name == "tinsel" ? "DebugInformationFormat=\"3\" " : ""); + toolConfig += (name == "sword25" ? "DisableLanguageExtensions=\"false\" " : ""); + + // Win32 + OUTPUT_CONFIGURATION("Debug", "Win32", ""); + OUTPUT_CONFIGURATION("Analysis", "Win32", ""); + OUTPUT_CONFIGURATION("Release", "Win32", ""); + OUTPUT_CONFIGURATION("Debug", "x64", "64"); + OUTPUT_CONFIGURATION("Analysis", "x64", "64"); + OUTPUT_CONFIGURATION("Release", "x64", "64"); + } + + project << "\t\n" + "\t\n"; + + std::string modulePath; + if (!moduleDir.compare(0, setup.srcDir.size(), setup.srcDir)) { + modulePath = moduleDir.substr(setup.srcDir.size()); + if (!modulePath.empty() && modulePath.at(0) == '/') + modulePath.erase(0, 1); + } + + if (modulePath.size()) + addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix + '/' + modulePath); + else + addFilesToProject(moduleDir, project, includeList, excludeList, setup.filePrefix); + + project << "\t\n" + "\n"; +} + +void VisualStudioProvider::writeReferences(std::ofstream &output) { + output << "\tProjectSection(ProjectDependencies) = postProject\n"; + + for (UUIDMap::const_iterator i = _uuidMap.begin(); i != _uuidMap.end(); ++i) { + if (i->first == "scummvm") + continue; + + output << "\t\t{" << i->second << "} = {" << i->second << "}\n"; + } + + output << "\tEndProjectSection\n"; +} + +void VisualStudioProvider::outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix) { + std::string warnings; + for (StringList::const_iterator i = _globalWarnings.begin(); i != _globalWarnings.end(); ++i) + warnings += *i + ';'; + + std::string definesList; + for (StringList::const_iterator i = defines.begin(); i != defines.end(); ++i) { + if (i != defines.begin()) + definesList += ';'; + definesList += *i; + } + + properties << "\n" + "\n" + "\t\n" + "\t\n" + "\t\n" + "\t\n" + "\n"; + + properties.flush(); +} + +void VisualStudioProvider::createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis) { + const std::string outputType = (enableAnalysis ? "Analysis" : (isRelease ? "Release" : "Debug")); + const std::string outputBitness = (isWin32 ? "32" : "64"); + + std::ofstream properties((setup.outputDir + '/' + "ScummVM_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension()).c_str()); + if (!properties) + error("Could not open \"" + setup.outputDir + '/' + "ScummVM_" + outputType + (isWin32 ? "" : "64") + getPropertiesExtension() + "\" for writing"); + + properties << "\n" + "\n" + "\t\n" + "\t\n" + "\t\n" + "\n"; + + properties.flush(); + properties.close(); +} + +void VisualStudioProvider::writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, + const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix) { + const std::string indentString = getIndent(indentation + 2); + + if (indentation) + projectFile << getIndent(indentation + 1) << "\n"; + + for (FileNode::NodeList::const_iterator i = dir.children.begin(); i != dir.children.end(); ++i) { + const FileNode *node = *i; + + if (!node->children.empty()) { + writeFileListToProject(*node, projectFile, indentation + 1, duplicate, objPrefix + node->name + '_', filePrefix + node->name + '/'); + } else { + if (producesObjectFile(node->name)) { + std::string name, ext; + splitFilename(node->name, name, ext); + const bool isDuplicate = (std::find(duplicate.begin(), duplicate.end(), name + ".o") != duplicate.end()); + + if (ext == "asm") { + std::string objFileName = "$(IntDir)\\"; + if (isDuplicate) + objFileName += objPrefix; + objFileName += "$(InputName).obj"; + + const std::string toolLine = indentString + "\t\t\n"; + + // NASM is not supported for x64, thus we do not need to add additional entries here :-). + projectFile << indentString << "name) << "\">\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\n"; + } else { + if (isDuplicate) { + const std::string toolLine = indentString + "\t\t\n"; + + projectFile << indentString << "name) << "\">\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\t\n" + << toolLine + << indentString << "\t\n" + << indentString << "\n"; + } else { + projectFile << indentString << "name) << "\" />\n"; + } + } + } else { + projectFile << indentString << "name) << "\" />\n"; + } + } + } + + if (indentation) + projectFile << getIndent(indentation + 1) << "\n"; +} + +} // End of CreateProjectTool namespace diff --git a/devtools/create_project/visualstudio.h b/devtools/create_project/visualstudio.h new file mode 100644 index 00000000000..989428798c5 --- /dev/null +++ b/devtools/create_project/visualstudio.h @@ -0,0 +1,57 @@ +/* Residual - A 3D game interpreter + * + * 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 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 TOOLS_CREATE_PROJECT_VISUALSTUDIO_H +#define TOOLS_CREATE_PROJECT_VISUALSTUDIO_H + +#include "msvc.h" + +namespace CreateProjectTool { + +class VisualStudioProvider : public MSVCProvider { +public: + VisualStudioProvider(StringList &global_warnings, std::map &project_warnings, const int version); + +protected: + void createProjectFile(const std::string &name, const std::string &uuid, const BuildSetup &setup, const std::string &moduleDir, + const StringList &includeList, const StringList &excludeList); + + void writeFileListToProject(const FileNode &dir, std::ofstream &projectFile, const int indentation, + const StringList &duplicate, const std::string &objPrefix, const std::string &filePrefix); + + void writeReferences(std::ofstream &output); + + void outputGlobalPropFile(std::ofstream &properties, int bits, const StringList &defines, const std::string &prefix); + + void createBuildProp(const BuildSetup &setup, bool isRelease, bool isWin32, bool enableAnalysis); + + const char *getProjectExtension(); + const char *getPropertiesExtension(); + int getVisualStudioVersion(); +}; + +} // End of CreateProjectTool namespace + +#endif // TOOLS_CREATE_PROJECT_VISUALSTUDIO_H diff --git a/tools/credits.pl b/devtools/credits.pl old mode 100755 new mode 100644 similarity index 98% rename from tools/credits.pl rename to devtools/credits.pl index d546cb635ab..44208f893e0 --- a/tools/credits.pl +++ b/devtools/credits.pl @@ -62,20 +62,24 @@ sub html_entities_to_ascii { # For now we hardcode these mappings # á -> a # é -> e + # ì -> i # ó -> o # ø -> o # ö -> o / oe # ä -> a # ü -> ue + # å -> aa # & -> & # ł -> l # Š -> S $text =~ s/á/a/g; $text =~ s/é/e/g; + $text =~ s/ì/i/g; $text =~ s/ó/o/g; $text =~ s/ø/o/g; $text =~ s/ł/l/g; $text =~ s/Š/S/g; + $text =~ s/å/aa/g; $text =~ s/ä/a/g; $text =~ s/ü/ue/g; @@ -95,10 +99,12 @@ sub html_entities_to_cpp { # The numerical values are octal! $text =~ s/á/\\341/g; $text =~ s/é/\\351/g; + $text =~ s/ì/\\354/g; $text =~ s/ó/\\363/g; $text =~ s/ø/\\370/g; $text =~ s/ł/l/g; $text =~ s/Š/S/g; + $text =~ s/å/\\345/g; $text =~ s/ä/\\344/g; $text =~ s/ö/\\366/g; @@ -110,13 +116,16 @@ sub html_entities_to_cpp { } # Convert HTML entities to RTF codes +# This is using the Mac OS Roman encoding sub html_entities_to_rtf { my $text = shift; $text =~ s/á/\\'87/g; $text =~ s/é/\\'8e/g; + $text =~ s/ì/\\'93/g; $text =~ s/ó/\\'97/g; $text =~ s/ø/\\'bf/g; + $text =~ s/å/\\'8c/g; # The following numerical values are octal! $text =~ s/ł/\\uc0\\u322 /g; $text =~ s/Š/\\uc0\\u540 /g; @@ -137,8 +146,10 @@ sub html_entities_to_tex { $text =~ s/á/\\'a/g; $text =~ s/é/\\'e/g; + $text =~ s/ì/\\`\\i/g; $text =~ s/ó/\\'o/g; $text =~ s/ø/{\\o}/g; + $text =~ s/å/\\aa /g; $text =~ s/ł/{\\l}/g; $text =~ s/Š/{\\v S}/g; diff --git a/devtools/module.mk b/devtools/module.mk new file mode 100644 index 00000000000..daf2d2a9f51 --- /dev/null +++ b/devtools/module.mk @@ -0,0 +1,29 @@ +# $URL$ +# $Id$ + +MODULE := devtools + +MODULE_DIRS += \ + devtools/ + +####################################################################### +# Tools directory +####################################################################### + +DEVTOOLS := + +include $(srcdir)/devtools/*/module.mk + +.PHONY: $(srcdir)/devtools/*/module.mk + +# Make sure the 'all' / 'clean' targets build/clean the devtools, too +#all: +clean: clean-devtools + +# Main target +devtools: $(DEVTOOLS) + +clean-devtools: + -$(RM) $(DEVTOOLS) + +.PHONY: clean-devtools devtools diff --git a/tools/update-version.pl b/devtools/update-version.pl similarity index 100% rename from tools/update-version.pl rename to devtools/update-version.pl diff --git a/dists/macosx/Info.plist b/dists/macosx/Info.plist index e104ca29740..dcde819825c 100644 --- a/dists/macosx/Info.plist +++ b/dists/macosx/Info.plist @@ -1,5 +1,5 @@ - + CFBundleDevelopmentRegion @@ -9,7 +9,7 @@ CFBundleExecutable residual CFBundleGetInfoString - 0.0.6svn + 0.0.6git CFBundleIconFile residual.icns CFBundleIdentifier @@ -21,9 +21,9 @@ CFBundlePackageType APPL CFBundleShortVersionString - 0.0.6svn + 0.0.6git CFBundleVersion - 0.0.6svn + 0.0.6git NSPrincipalClass NSApplication diff --git a/dists/residual.desktop b/dists/residual.desktop index 8232445b245..5806061ea3f 100644 --- a/dists/residual.desktop +++ b/dists/residual.desktop @@ -1,5 +1,6 @@ [Desktop Entry] Name=Residual +Comment=Interpreter for several 3D games Exec=residual Icon=residual Terminal=false diff --git a/dists/residual.rc b/dists/residual.rc index fde31666918..bdddfe32e95 100644 --- a/dists/residual.rc +++ b/dists/residual.rc @@ -7,34 +7,35 @@ IDI_ICON ICON DISCARDABLE "../../icons/residual.ico" #endif VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,6,0 - PRODUCTVERSION 0,0,6,0 - FILEFLAGSMASK 0x3fL + FILEVERSION 0,0,6,0 + PRODUCTVERSION 0,0,6,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK #ifdef _DEBUG - FILEFLAGS 0x1L + FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0 #endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "StringFileInfo" BEGIN - BLOCK "040904b0" + BLOCK "040904b0" // US English, Unicode BEGIN VALUE "Comments", "\0" VALUE "FileDescription", "http://residual.sourceforge.net/\0" - VALUE "FileVersion", "0.0.6svn\0" + VALUE "FileVersion", "0.0.6git\0" VALUE "InternalName", "residual\0" VALUE "LegalCopyright", "Copyrights information are in AUTHORS file\0" VALUE "OriginalFilename", "residual.exe\0" VALUE "ProductName", "Residual\0" - VALUE "ProductVersion", "0.0.6svn\0" + VALUE "ProductVersion", "0.0.6git\0" END END + BLOCK "VarFileInfo" BEGIN - VALUE "Translation", 0x409, 1200 + VALUE "Translation", 0x409, 1200 // US English, Unicode END END diff --git a/dists/residual.rc.in b/dists/residual.rc.in index ec58f9e2f68..bc1ec4eeed7 100644 --- a/dists/residual.rc.in +++ b/dists/residual.rc.in @@ -7,21 +7,21 @@ IDI_ICON ICON DISCARDABLE "../../icons/residual.ico" #endif VS_VERSION_INFO VERSIONINFO - FILEVERSION @VER_MAJOR@,@VER_MINOR@,@VER_PATCH@,0 - PRODUCTVERSION @VER_MAJOR@,@VER_MINOR@,@VER_PATCH@,0 - FILEFLAGSMASK 0x3fL + FILEVERSION @VER_MAJOR@,@VER_MINOR@,@VER_PATCH@,0 + PRODUCTVERSION @VER_MAJOR@,@VER_MINOR@,@VER_PATCH@,0 + FILEFLAGSMASK VS_FFI_FILEFLAGSMASK #ifdef _DEBUG - FILEFLAGS 0x1L + FILEFLAGS VS_FF_DEBUG #else - FILEFLAGS 0x0L + FILEFLAGS 0 #endif - FILEOS 0x40004L - FILETYPE 0x1L - FILESUBTYPE 0x0L + FILEOS VOS_NT_WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN BEGIN BLOCK "StringFileInfo" BEGIN - BLOCK "040904b0" + BLOCK "040904b0" // US English, Unicode BEGIN VALUE "Comments", "\0" VALUE "FileDescription", "http://residual.sourceforge.net/\0" @@ -33,8 +33,9 @@ BEGIN VALUE "ProductVersion", "@VERSION@\0" END END + BLOCK "VarFileInfo" BEGIN - VALUE "Translation", 0x409, 1200 + VALUE "Translation", 0x409, 1200 // US English, Unicode END END diff --git a/engines/advancedDetector.cpp b/engines/advancedDetector.cpp index c29911a45a0..6911a3894f3 100644 --- a/engines/advancedDetector.cpp +++ b/engines/advancedDetector.cpp @@ -226,7 +226,7 @@ bool cleanupPirated(ADGameDescList &matched) { // We ruled out all variants and now have nothing if (matched.empty()) { - + warning("Illegitimate copy of the game detected. We give no support in such cases %d", matched.size()); return true; @@ -244,18 +244,21 @@ GameList AdvancedMetaEngine::detectGames(const Common::FSList &fslist) const { if (cleanupPirated(matches)) return detectedGames; - // Use fallback detector if there were no matches by other means if (matches.empty()) { + // Use fallback detector if there were no matches by other means const ADGameDescription *fallbackDesc = fallbackDetect(fslist); if (fallbackDesc != 0) { GameDescriptor desc(toGameDescriptor(*fallbackDesc, params.list)); updateGameDescriptor(desc, fallbackDesc, params); detectedGames.push_back(desc); } - } else for (uint i = 0; i < matches.size(); i++) { // Otherwise use the found matches - GameDescriptor desc(toGameDescriptor(*matches[i], params.list)); - updateGameDescriptor(desc, matches[i], params); - detectedGames.push_back(desc); + } else { + // Otherwise use the found matches + for (uint i = 0; i < matches.size(); i++) { + GameDescriptor desc(toGameDescriptor(*matches[i], params.list)); + updateGameDescriptor(desc, matches[i], params); + detectedGames.push_back(desc); + } } return detectedGames; @@ -354,7 +357,7 @@ Common::Error AdvancedMetaEngine::createInstance(OSystem *syst, Engine **engine) struct SizeMD5 { int size; - char md5[32+1]; + Common::String md5; }; typedef Common::HashMap SizeMD5Map; @@ -371,7 +374,7 @@ static void reportUnknown(const Common::FSNode &path, const SizeMD5Map &filesSiz printf("of the game you tried to add and its version/language/etc.:\n"); for (SizeMD5Map::const_iterator file = filesSizeMD5.begin(); file != filesSizeMD5.end(); ++file) - printf(" {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5, file->_value.size); + printf(" {\"%s\", 0, \"%s\", %d},\n", file->_key.c_str(), file->_value.md5.c_str(), file->_value.size); printf("\n"); } @@ -400,7 +403,7 @@ static void composeFileHashMap(const Common::FSList &fslist, FileMap &allFiles, matched = true; break; } - + if (!matched) continue; @@ -446,34 +449,37 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p Common::String fname = fileDesc->fileName; SizeMD5 tmp; + if (filesSizeMD5.contains(fname)) + continue; + + // FIXME/TODO: We don't handle the case that a file is listed as a regular + // file and as one with resource fork. + if (g->flags & ADGF_MACRESFORK) { Common::MacResManager *macResMan = new Common::MacResManager(); - + if (macResMan->open(parent, fname)) { - if (!macResMan->getResForkMD5(tmp.md5, params.md5Bytes)) - tmp.md5[0] = 0; - tmp.size = macResMan->getResForkSize(); - debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5); + tmp.md5 = macResMan->computeResForkMD5AsString(params.md5Bytes); + tmp.size = macResMan->getResForkDataSize(); + debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str()); filesSizeMD5[fname] = tmp; } delete macResMan; } else { - if (allFiles.contains(fname) && !filesSizeMD5.contains(fname)) { + if (allFiles.contains(fname)) { debug(3, "+ %s", fname.c_str()); Common::File testFile; if (testFile.open(allFiles[fname])) { tmp.size = (int32)testFile.size(); - if (!md5_file_string(testFile, tmp.md5, params.md5Bytes)) - tmp.md5[0] = 0; + tmp.md5 = Common::computeStreamMD5AsString(testFile, params.md5Bytes); } else { tmp.size = -1; - tmp.md5[0] = 0; } - - debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5); + + debug(3, "> '%s': '%s'", fname.c_str(), tmp.md5.c_str()); filesSizeMD5[fname] = tmp; } } @@ -502,6 +508,7 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p continue; bool allFilesPresent = true; + int curFilesMatched = 0; // Try to match all files for this game for (fileDesc = g->filesDescriptions; fileDesc->fileName; fileDesc++) { @@ -513,8 +520,8 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p break; } - if (fileDesc->md5 != NULL && 0 != strcmp(fileDesc->md5, filesSizeMD5[tstr].md5)) { - debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesSizeMD5[tstr].md5); + if (fileDesc->md5 != NULL && fileDesc->md5 != filesSizeMD5[tstr].md5) { + debug(3, "MD5 Mismatch. Skipping (%s) (%s)", fileDesc->md5, filesSizeMD5[tstr].md5.c_str()); fileMissing = true; break; } @@ -526,12 +533,13 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p } debug(3, "Matched file: %s", tstr.c_str()); + curFilesMatched++; } // We found at least one entry with all required files present. // That means that we got new variant of the game. // - // Wihtout this check we would have errorneous checksum display + // Without this check we would have erroneous checksum display // where only located files will be enlisted. // // Potentially this could rule out variants where some particular file @@ -544,22 +552,11 @@ static ADGameDescList detectGame(const Common::FSList &fslist, const ADParams &p debug(2, "Found game: %s (%s %s/%s) (%d)", g->gameid, g->extra, getPlatformDescription(g->platform), getLanguageDescription(g->language), i); - // Count the number of matching files. Then, only keep those - // entries which match a maximal amount of files. - int curFilesMatched = 0; - for (fileDesc = g->filesDescriptions; fileDesc->fileName; fileDesc++) - curFilesMatched++; - if (curFilesMatched > maxFilesMatched) { debug(2, " ... new best match, removing all previous candidates"); maxFilesMatched = curFilesMatched; - for (uint j = 0; j < matched.size();) { - if (matched[j]->flags & ADGF_KEEPMATCH) - ++j; - else - matched.remove_at(j); - } + matched.clear(); // Remove any prior, lower ranked matches. matched.push_back(g); } else if (curFilesMatched == maxFilesMatched) { matched.push_back(g); @@ -622,7 +619,7 @@ static ADGameDescList detectGameFilebased(const FileMap &allFiles, const ADParam matchedDesc = agdesc; maxNumMatchedFiles = numMatchedFiles; - debug(4, "and overriden"); + debug(4, "and overridden"); } } } diff --git a/engines/advancedDetector.h b/engines/advancedDetector.h index e6faa0216ee..6344020e0cc 100644 --- a/engines/advancedDetector.h +++ b/engines/advancedDetector.h @@ -49,7 +49,6 @@ enum ADGameFlags { ADGF_ADDENGLISH = (1 << 24), // always add English as language option ADGF_MACRESFORK = (1 << 25), // the md5 for this entry will be calculated from the resource fork ADGF_USEEXTRAASTITLE = (1 << 26), // Extra field value will be used as main game title, not gameid - ADGF_KEEPMATCH = (1 << 27), // this entry is kept even when there are matched entries with more files ADGF_DROPLANGUAGE = (1 << 28), // don't add language to gameid ADGF_CD = (1 << 29), // add "-cd" to gameid ADGF_DEMO = (1 << 30) // add "-demo" to gameid diff --git a/engines/dialogs.cpp b/engines/dialogs.cpp index fa186ec4d81..27484c34750 100644 --- a/engines/dialogs.cpp +++ b/engines/dialogs.cpp @@ -33,9 +33,10 @@ #include "graphics/scaler.h" #include "gui/about.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/launcher.h" -#include "gui/ListWidget.h" +#include "gui/widgets/list.h" +#include "gui/message.h" #include "gui/options.h" #include "gui/saveload.h" #include "gui/ThemeEval.h" @@ -48,9 +49,6 @@ #include "gui/KeysDialog.h" #endif -using GUI::CommandSender; -using GUI::StaticTextWidget; - class ConfigDialog : public GUI::OptionsDialog { protected: #ifdef SMALL_SCREEN_DEVICE @@ -75,15 +73,15 @@ MainMenuDialog::MainMenuDialog(Engine *engine) _logo->useThemeTransparency(true); _logo->setGfx(g_gui.theme()->getImageSurface(GUI::ThemeEngine::kImageLogoSmall)); } else { - StaticTextWidget *title = new StaticTextWidget(this, "GlobalMenu.Title", "Residual"); + GUI::StaticTextWidget *title = new GUI::StaticTextWidget(this, "GlobalMenu.Title", "Residual"); title->setAlign(Graphics::kTextAlignCenter); } #else - StaticTextWidget *title = new StaticTextWidget(this, "GlobalMenu.Title", "Residual"); + GUI::StaticTextWidget *title = new GUI::StaticTextWidget(this, "GlobalMenu.Title", "Residual"); title->setAlign(Graphics::kTextAlignCenter); #endif - StaticTextWidget *version = new StaticTextWidget(this, "GlobalMenu.Version", gResidualVersionDate); + GUI::StaticTextWidget *version = new GUI::StaticTextWidget(this, "GlobalMenu.Version", gResidualVersionDate); version->setAlign(Graphics::kTextAlignCenter); new GUI::ButtonWidget(this, "GlobalMenu.Resume", _("~R~esume"), 0, kPlayCmd, 'P'); @@ -102,7 +100,6 @@ MainMenuDialog::MainMenuDialog(Engine *engine) // To enable "Help", an engine needs to use a subclass of MainMenuDialog // (at least for now, we might change how this works in the future). _helpButton = new GUI::ButtonWidget(this, "GlobalMenu.Help", _("~H~elp"), 0, kHelpCmd); - _helpButton->setEnabled(false); new GUI::ButtonWidget(this, "GlobalMenu.About", _("~A~bout"), 0, kAboutCmd); @@ -130,7 +127,7 @@ MainMenuDialog::~MainMenuDialog() { delete _saveDialog; } -void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { +void MainMenuDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { case kPlayCmd: close(); @@ -147,8 +144,13 @@ void MainMenuDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 dat case kAboutCmd: _aboutDialog->runModal(); break; - case kHelpCmd: - // Not handled here -- needs to be handled by a subclass (for now) + case kHelpCmd: { + GUI::MessageDialog dialog( + "Sorry, this engine does not currently provide in-game help. " + "Please consult the README for basic information, and for " + "instructions on how to obtain further assistance."); + dialog.runModal(); + } break; case kRTLCmd: { Common::Event eventRTL; @@ -174,6 +176,15 @@ void MainMenuDialog::reflowLayout() { _loadButton->setEnabled(_engine->canLoadGameStateCurrently()); if (_engine->hasFeature(Engine::kSupportsSavingDuringRuntime)) _saveButton->setEnabled(_engine->canSaveGameStateCurrently()); + + // Overlay size might have changed since the construction of the dialog. + // Update labels when it might be needed + // FIXME: it might be better to declare GUI::StaticTextWidget::setLabel() virtual + // and to reimplement it in GUI::ButtonWidget to handle the hotkey. + if (g_system->getOverlayWidth() > 320) + _rtlButton->setLabel(_rtlButton->cleanupHotkey(_("~R~eturn to Launcher"))); + else + _rtlButton->setLabel(_rtlButton->cleanupHotkey(_c("~R~eturn to Launcher", "lowres"))); #ifndef DISABLE_FANCY_THEMES if (g_gui.xmlEval()->getVar("Globals.ShowGlobalMenuLogo", 0) == 1 && g_gui.theme()->supportsImages()) { @@ -182,16 +193,16 @@ void MainMenuDialog::reflowLayout() { _logo->useThemeTransparency(true); _logo->setGfx(g_gui.theme()->getImageSurface(GUI::ThemeEngine::kImageLogoSmall)); - GUI::StaticTextWidget *title = (StaticTextWidget *)findWidget("GlobalMenu.Title"); + GUI::StaticTextWidget *title = (GUI::StaticTextWidget *)findWidget("GlobalMenu.Title"); if (title) { removeWidget(title); title->setNext(0); delete title; } } else { - GUI::StaticTextWidget *title = (StaticTextWidget *)findWidget("GlobalMenu.Title"); + GUI::StaticTextWidget *title = (GUI::StaticTextWidget *)findWidget("GlobalMenu.Title"); if (!title) { - title = new StaticTextWidget(this, "GlobalMenu.Title", "ScummVM"); + title = new GUI::StaticTextWidget(this, "GlobalMenu.Title", "Residual"); title->setAlign(Graphics::kTextAlignCenter); } @@ -208,12 +219,12 @@ void MainMenuDialog::reflowLayout() { } void MainMenuDialog::save() { - Common::String gameId = ConfMan.get("gameid"); + const Common::String gameId = ConfMan.get("gameid"); const EnginePlugin *plugin = 0; EngineMan.findGame(gameId, &plugin); - int slot = _saveDialog->runModal(plugin, ConfMan.getActiveDomainName()); + int slot = _saveDialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); if (slot >= 0) { Common::String result(_saveDialog->getResultString()); @@ -231,12 +242,12 @@ void MainMenuDialog::save() { } void MainMenuDialog::load() { - Common::String gameId = ConfMan.get("gameid"); + const Common::String gameId = ConfMan.get("gameid"); const EnginePlugin *plugin = 0; EngineMan.findGame(gameId, &plugin); - int slot = _loadDialog->runModal(plugin, ConfMan.getActiveDomainName()); + int slot = _loadDialog->runModalWithPluginAndTarget(plugin, ConfMan.getActiveDomainName()); if (slot >= 0) { // FIXME: For now we just ignore the return @@ -316,7 +327,7 @@ ConfigDialog::~ConfigDialog() { #endif } -void ConfigDialog::handleCommand(CommandSender *sender, uint32 cmd, uint32 data) { +void ConfigDialog::handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data) { switch (cmd) { case kKeysCmd: diff --git a/engines/engine.cpp b/engines/engine.cpp index 24ba2e008ac..020047b2855 100644 --- a/engines/engine.cpp +++ b/engines/engine.cpp @@ -46,9 +46,9 @@ #include "gui/debugger.h" #include "gui/message.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" -#include "sound/mixer.h" +#include "audio/mixer.h" #include "graphics/cursorman.h" @@ -94,10 +94,11 @@ Engine::Engine(OSystem *syst) _saveFileMan(_system->getSavefileManager()), _targetName(ConfMan.getActiveDomainName()), _pauseLevel(0), + _pauseStartTime(0), + _engineStartTime(_system->getMillis()), _mainMenuDialog(NULL) { g_engine = this; - Common::setDebugOutputFormatter(defaultOutputFormatter); Common::setErrorOutputFormatter(defaultOutputFormatter); Common::setErrorHandler(defaultErrorHandler); @@ -121,7 +122,7 @@ Engine::~Engine() { } -void GUIErrorMessage(const Common::String msg) { +void GUIErrorMessage(const Common::String &msg) { g_system->setWindowCaption("Error"); g_system->launcherInitSize(640, 400); GUI::MessageDialog dialog(msg); @@ -217,9 +218,12 @@ void Engine::pauseEngine(bool pause) { _pauseLevel--; if (_pauseLevel == 1 && pause) { + _pauseStartTime = _system->getMillis(); pauseEngineIntern(true); } else if (_pauseLevel == 0) { pauseEngineIntern(false); + _engineStartTime += _system->getMillis() - _pauseStartTime; + _pauseStartTime = 0; } } @@ -235,6 +239,24 @@ void Engine::openMainMenuDialog() { syncSoundSettings(); } +uint32 Engine::getTotalPlayTime() const { + if (!_pauseLevel) + return _system->getMillis() - _engineStartTime; + else + return _pauseStartTime - _engineStartTime; +} + +void Engine::setTotalPlayTime(uint32 time) { + const uint32 currentTime = _system->getMillis(); + + // We need to reset the pause start time here in case the engine is already + // paused to avoid any incorrect play time counting. + if (_pauseLevel > 0) + _pauseStartTime = currentTime; + + _engineStartTime = currentTime - time; +} + int Engine::runDialog(GUI::Dialog &dialog) { pauseEngine(true); int result = dialog.runModal(); @@ -244,7 +266,6 @@ int Engine::runDialog(GUI::Dialog &dialog) { } void Engine::syncSoundSettings() { - // Sync the engine with the config manager int soundVolumeMusic = ConfMan.getInt("music_volume"); int soundVolumeSFX = ConfMan.getInt("sfx_volume"); @@ -254,6 +275,7 @@ void Engine::syncSoundSettings() { if (ConfMan.hasKey("mute")) mute = ConfMan.getBool("mute"); + _mixer->setVolumeForSoundType(Audio::Mixer::kPlainSoundType, (mute ? 0 : Audio::Mixer::kMaxMixerVolume)); _mixer->setVolumeForSoundType(Audio::Mixer::kMusicSoundType, (mute ? 0 : soundVolumeMusic)); _mixer->setVolumeForSoundType(Audio::Mixer::kSFXSoundType, (mute ? 0 : soundVolumeSFX)); _mixer->setVolumeForSoundType(Audio::Mixer::kSpeechSoundType, (mute ? 0 : soundVolumeSpeech)); diff --git a/engines/engine.h b/engines/engine.h index de8928c00f5..266a07cab7e 100644 --- a/engines/engine.h +++ b/engines/engine.h @@ -47,7 +47,7 @@ namespace GUI { /** * Initializes graphics and shows error message. */ -void GUIErrorMessage(const Common::String msg); +void GUIErrorMessage(const Common::String &msg); class Engine { @@ -74,6 +74,17 @@ private: */ int _pauseLevel; + /** + * The time when the pause was started. + */ + uint32 _pauseStartTime; + + /** + * The time when the engine was started. This value is used to calculate + * the current play time of the game running. + */ + int32 _engineStartTime; + public: @@ -152,6 +163,15 @@ public: * Notify the engine that the sound settings in the config manager may have * changed and that it hence should adjust any internal volume etc. values * accordingly. + * The default implementation sets the volume levels of all mixer sound + * types according to the config entries of the active domain. + * When overwriting, call the default implementation first, then adjust the + * volumes further (if required). + * + * @note When setting volume levels, respect the "mute" config entry. + * @note The volume for the plain sound type is reset to the maximum + * volume. If the engine can associate its own value for this + * type, it needs to overwrite this member and set it accordingly. * @todo find a better name for this */ virtual void syncSoundSettings(); @@ -234,6 +254,24 @@ public: */ void openMainMenuDialog(); + /** + * Get the total play time. + * + * @return How long the player has been playing in ms. + */ + uint32 getTotalPlayTime() const; + + /** + * Set the game time counter to the specified time. + * + * This can be used to set the play time counter after loading a savegame + * for example. Another use case is in case the engine wants to exclude + * time from the counter the user spent in original engine dialogs. + * + * @param time Play time to set up in ms. + */ + void setTotalPlayTime(uint32 time = 0); + inline Common::TimerManager *getTimerManager() { return _timer; } inline Common::EventManager *getEventManager() { return _eventMan; } inline Common::SaveFileManager *getSaveFileManager() { return _saveFileMan; } diff --git a/engines/game.h b/engines/game.h index d3f64adba02..7de78563f82 100644 --- a/engines/game.h +++ b/engines/game.h @@ -28,7 +28,6 @@ #include "common/array.h" #include "common/hash-str.h" -#include "engines/savestate.h" // TODO: Push this #include out to .cpp files needing it /** * A simple structure used to map gameids (like "monkey", "sword1", ...) to diff --git a/engines/grim/colormap.h b/engines/grim/colormap.h index 1736eda3081..2c5e7931d51 100644 --- a/engines/grim/colormap.h +++ b/engines/grim/colormap.h @@ -40,7 +40,7 @@ public: CMap(const char *fileName, const char *data, int len) : Object() { _fname = fileName; - if (len < 4 || READ_BE_UINT32(data) != MKID_BE('CMP ')) + if (len < 4 || READ_BE_UINT32(data) != MKTAG('C','M','P',' ')) error("Invalid magic loading colormap"); memcpy(_colors, data + 64, sizeof(_colors)); } diff --git a/engines/grim/costume.cpp b/engines/grim/costume.cpp index 7164619f591..6338ae7598b 100644 --- a/engines/grim/costume.cpp +++ b/engines/grim/costume.cpp @@ -918,25 +918,25 @@ void Costume::Chore::update() { } Costume::Component *Costume::loadComponent (tag32 tag, Costume::Component *parent, int parentID, const char *name, Costume::Component *prevComponent) { - if (FROM_BE_32(tag) == MKID_BE('MMDL')) + if (FROM_BE_32(tag) == MKTAG('M','M','D','L')) return new MainModelComponent(parent, parentID, name, prevComponent, tag); - else if (FROM_BE_32(tag) == MKID_BE('MODL')) + else if (FROM_BE_32(tag) == MKTAG('M','O','D','L')) return new ModelComponent(parent, parentID, name, prevComponent, tag); - else if (FROM_BE_32(tag) == MKID_BE('CMAP')) + else if (FROM_BE_32(tag) == MKTAG('C','M','A','P')) return new ColormapComponent(parent, parentID, name, tag); - else if (FROM_BE_32(tag) == MKID_BE('KEYF')) + else if (FROM_BE_32(tag) == MKTAG('K','E','Y','F')) return new KeyframeComponent(parent, parentID, name, tag); - else if (FROM_BE_32(tag) == MKID_BE('MESH')) + else if (FROM_BE_32(tag) == MKTAG('M','E','S','H')) return new MeshComponent(parent, parentID, name, tag); - else if (FROM_BE_32(tag) == MKID_BE('LUAV')) + else if (FROM_BE_32(tag) == MKTAG('L','U','A','V')) return new LuaVarComponent(parent, parentID, name, tag); - else if (FROM_BE_32(tag) == MKID_BE('IMLS')) + else if (FROM_BE_32(tag) == MKTAG('I','M','L','S')) return new SoundComponent(parent, parentID, name, tag); - else if (FROM_BE_32(tag) == MKID_BE('BKND')) + else if (FROM_BE_32(tag) == MKTAG('B','K','N','D')) return new BitmapComponent(parent, parentID, name, tag); - else if (FROM_BE_32(tag) == MKID_BE('MAT ')) + else if (FROM_BE_32(tag) == MKTAG('M','A','T',' ')) return new MaterialComponent(parent, parentID, name, tag); - else if (FROM_BE_32(tag) == MKID_BE('SPRT')) + else if (FROM_BE_32(tag) == MKTAG('S','P','R','T')) return NULL;// new SpriteComponent(parent, parentID, name); char t[4]; @@ -951,7 +951,7 @@ Model::HierNode *Costume::getModelNodes() { continue; // Needs to handle Main Models (pigeons) and normal Models // (when Manny climbs the rope) - if (FROM_BE_32(_components[i]->tag()) == MKID_BE('MMDL')) + if (FROM_BE_32(_components[i]->tag()) == MKTAG('M','M','D','L')) return dynamic_cast(_components[i])->hierarchy(); } return NULL; @@ -1230,12 +1230,12 @@ void Costume::saveState(SaveGame *state) const { state->writeLESint32(c->_visible); state->writeVector3d(c->_matrix._pos); - if (FROM_BE_32(c->_tag) == MKID_BE('KEYF')) { + if (FROM_BE_32(c->_tag) == MKTAG('K','E','Y','F')) { KeyframeComponent *f = static_cast(c); state->writeLESint32(f->_active); state->writeLESint32(f->_repeatMode); state->writeLESint32(f->_currTime); - } else if (FROM_BE_32(c->_tag) == MKID_BE('MESH')) { + } else if (FROM_BE_32(c->_tag) == MKTAG('M','E','S','H')) { state->writeLESint32(static_cast(c)->node()->_meshVisible); } } @@ -1270,15 +1270,15 @@ bool Costume::restoreState(SaveGame *state) { if (c) { c->_visible = state->readLESint32(); c->_matrix._pos = state->readVector3d(); - if (FROM_BE_32(c->_tag) == MKID_BE('MODL') || FROM_BE_32(c->_tag) == MKID_BE('MMDL')) { + if (FROM_BE_32(c->_tag) == MKTAG('M','O','D','L') || FROM_BE_32(c->_tag) == MKTAG('M','M','D','L')) { ModelComponent *m = static_cast(c); m->hierarchy()->_hierVisible = c->_visible; - } else if (FROM_BE_32(c->_tag) == MKID_BE('KEYF')) { + } else if (FROM_BE_32(c->_tag) == MKTAG('K','E','Y','F')) { KeyframeComponent *f = static_cast(c); f->_active = state->readLESint32(); f->_repeatMode = state->readLESint32(); f->_currTime = state->readLESint32(); - } else if (FROM_BE_32(c->_tag) == MKID_BE('MESH')) { + } else if (FROM_BE_32(c->_tag) == MKTAG('M','E','S','H')) { static_cast(c)->node()->_meshVisible = state->readLESint32(); } } diff --git a/engines/grim/imuse/imuse.cpp b/engines/grim/imuse/imuse.cpp index 609178e831c..922ddb913fa 100644 --- a/engines/grim/imuse/imuse.cpp +++ b/engines/grim/imuse/imuse.cpp @@ -31,9 +31,9 @@ #include "engines/grim/imuse/imuse.h" -#include "sound/audiostream.h" -#include "sound/mixer.h" -#include "sound/decoders/raw.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" +#include "audio/decoders/raw.h" namespace Grim { diff --git a/engines/grim/imuse/imuse_sndmgr.cpp b/engines/grim/imuse/imuse_sndmgr.cpp index e54c8219288..df8de72d559 100644 --- a/engines/grim/imuse/imuse_sndmgr.cpp +++ b/engines/grim/imuse/imuse_sndmgr.cpp @@ -53,28 +53,28 @@ void ImuseSndMgr::countElements(byte *ptr, int &numRegions, int &numJumps) { do { tag = READ_BE_UINT32(ptr); ptr += 4; switch(tag) { - case MKID_BE('TEXT'): - case MKID_BE('STOP'): - case MKID_BE('FRMT'): - case MKID_BE('DATA'): + case MKTAG('T','E','X','T'): + case MKTAG('S','T','O','P'): + case MKTAG('F','R','M','T'): + case MKTAG('D','A','T','A'): size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('REGN'): + case MKTAG('R','E','G','N'): numRegions++; size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('JUMP'): + case MKTAG('J','U','M','P'): numJumps++; size = READ_BE_UINT32(ptr); ptr += size + 4; break; default: error("ImuseSndMgr::countElements() Unknown MAP tag '%s'", Common::tag2string(tag).c_str()); } - } while (tag != MKID_BE('DATA')); + } while (tag != MKTAG('D','A','T','A')); } void ImuseSndMgr::parseSoundHeader(byte *ptr, SoundDesc *sound, int &headerSize) { - if (READ_BE_UINT32(ptr) == MKID_BE('RIFF')) { + if (READ_BE_UINT32(ptr) == MKTAG('R','I','F','F')) { sound->region = new Region[1]; sound->jump = new Jump[1]; sound->numJumps = 0; @@ -85,7 +85,7 @@ void ImuseSndMgr::parseSoundHeader(byte *ptr, SoundDesc *sound, int &headerSize) sound->freq = READ_LE_UINT32(ptr + 24); sound->channels = *(ptr + 22); headerSize = 44; - } else if (READ_BE_UINT32(ptr) == MKID_BE('iMUS')) { + } else if (READ_BE_UINT32(ptr) == MKTAG('i','M','U','S')) { uint32 tag; int32 size = 0; byte *s_ptr = ptr; @@ -103,23 +103,23 @@ void ImuseSndMgr::parseSoundHeader(byte *ptr, SoundDesc *sound, int &headerSize) do { tag = READ_BE_UINT32(ptr); ptr += 4; switch(tag) { - case MKID_BE('FRMT'): + case MKTAG('F','R','M','T'): ptr += 12; sound->bits = READ_BE_UINT32(ptr); ptr += 4; sound->freq = READ_BE_UINT32(ptr); ptr += 4; sound->channels = READ_BE_UINT32(ptr); ptr += 4; break; - case MKID_BE('TEXT'): - case MKID_BE('STOP'): + case MKTAG('T','E','X','T'): + case MKTAG('S','T','O','P'): size = READ_BE_UINT32(ptr); ptr += size + 4; break; - case MKID_BE('REGN'): + case MKTAG('R','E','G','N'): ptr += 4; sound->region[curIndexRegion].offset = READ_BE_UINT32(ptr); ptr += 4; sound->region[curIndexRegion].length = READ_BE_UINT32(ptr); ptr += 4; curIndexRegion++; break; - case MKID_BE('JUMP'): + case MKTAG('J','U','M','P'): ptr += 4; sound->jump[curIndexJump].offset = READ_BE_UINT32(ptr); ptr += 4; sound->jump[curIndexJump].dest = READ_BE_UINT32(ptr); ptr += 4; @@ -127,13 +127,13 @@ void ImuseSndMgr::parseSoundHeader(byte *ptr, SoundDesc *sound, int &headerSize) sound->jump[curIndexJump].fadeDelay = READ_BE_UINT32(ptr); ptr += 4; curIndexJump++; break; - case MKID_BE('DATA'): + case MKTAG('D','A','T','A'): ptr += 4; break; default: error("ImuseSndMgr::prepareSound(%s) Unknown MAP tag '%s'", sound->name, Common::tag2string(tag).c_str()); } - } while (tag != MKID_BE('DATA')); + } while (tag != MKTAG('D','A','T','A')); headerSize = ptr - s_ptr; int i; for (i = 0; i < sound->numRegions; i++) { diff --git a/engines/grim/imuse/imuse_sndmgr.h b/engines/grim/imuse/imuse_sndmgr.h index e93d9fc59e6..ac937cf7ca1 100644 --- a/engines/grim/imuse/imuse_sndmgr.h +++ b/engines/grim/imuse/imuse_sndmgr.h @@ -26,8 +26,8 @@ #ifndef GRIM_IMUSE_SNDMGR_H #define GRIM_IMUSE_SNDMGR_H -#include "sound/mixer.h" -#include "sound/audiostream.h" +#include "audio/mixer.h" +#include "audio/audiostream.h" namespace Grim { diff --git a/engines/grim/keyframe.cpp b/engines/grim/keyframe.cpp index 3e9f380674e..28a0640612e 100644 --- a/engines/grim/keyframe.cpp +++ b/engines/grim/keyframe.cpp @@ -36,7 +36,7 @@ KeyframeAnim::KeyframeAnim(const char *fname, const char *data, int len) : Object() { _fname = fname; - if (len >= 4 && READ_BE_UINT32(data) == MKID_BE('FYEK')) + if (len >= 4 && READ_BE_UINT32(data) == MKTAG('F','Y','E','K')) loadBinary(data, len); else { TextSplitter ts(data, len); diff --git a/engines/grim/lab.cpp b/engines/grim/lab.cpp index dacddf6971c..35b53340bad 100644 --- a/engines/grim/lab.cpp +++ b/engines/grim/lab.cpp @@ -42,7 +42,7 @@ bool Lab::open(const Common::String &filename) { if (!_f->open(filename)) return false; - if (_f->readUint32BE() != MKID_BE('LABN')) { + if (_f->readUint32BE() != MKTAG('L','A','B','N')) { close(); return false; } diff --git a/engines/grim/lipsync.cpp b/engines/grim/lipsync.cpp index 415cbd5381f..21dfe7bb527 100644 --- a/engines/grim/lipsync.cpp +++ b/engines/grim/lipsync.cpp @@ -40,7 +40,7 @@ LipSync::LipSync(const char *filename, const char *data, int len) : uint16 readPhoneme; int j; - if (READ_BE_UINT32(data) != MKID_BE('LIP!')) { + if (READ_BE_UINT32(data) != MKTAG('L','I','P','!')) { error("Invalid file format in %s", filename); } else { _numEntries = (len - 8) / 4; diff --git a/engines/grim/localize.cpp b/engines/grim/localize.cpp index 390a400e75e..e7d4dcd861f 100644 --- a/engines/grim/localize.cpp +++ b/engines/grim/localize.cpp @@ -64,7 +64,7 @@ Localizer::Localizer() { data[filesize] = '\0'; f.close(); - if (filesize < 4 || READ_BE_UINT32(data) != MKID_BE('RCNE')) + if (filesize < 4 || READ_BE_UINT32(data) != MKTAG('R','C','N','E')) error("Invalid magic reading grim.tab"); // Decode the data diff --git a/engines/grim/lua/lstate.cpp b/engines/grim/lua/lstate.cpp index 358db8563b5..1db39f65420 100644 --- a/engines/grim/lua/lstate.cpp +++ b/engines/grim/lua/lstate.cpp @@ -151,10 +151,10 @@ void callHook(lua_Function func, const char *filename, int32 line) { else if (lua_istable(lua_getparam(i))) fprintf(output, "{...}"); else if (lua_isuserdata(lua_getparam(i))) { - if (lua_tag(lua_getparam(i)) == MKID_BE('ACTR')) { + if (lua_tag(lua_getparam(i)) == MKTAG('A','C','T','R')) { Actor *a = static_cast(lua_getuserdata(lua_getparam(i))); fprintf(output, "", a->name()); - } else if (lua_tag(lua_getparam(i)) == MKID_BE('COLR')) { + } else if (lua_tag(lua_getparam(i)) == MKTAG('C','O','L','R')) { Color *c = static_cast(lua_getuserdata(lua_getparam(i))); fprintf(output, "", c->red(), c->green(), c->blue()); } else diff --git a/engines/grim/lua_v1.cpp b/engines/grim/lua_v1.cpp index 1e80f9bb23a..87d2cac2151 100644 --- a/engines/grim/lua_v1.cpp +++ b/engines/grim/lua_v1.cpp @@ -213,7 +213,7 @@ static void MakeColor() { b = clamp_color((int)lua_getnumber(bObj)); Color *c = new Color (r, g ,b); - lua_pushusertag(c, MKID_BE('COLR')); + lua_pushusertag(c, MKTAG('C','O','L','R')); } static void GetColorComponents() { @@ -266,12 +266,12 @@ static void LoadActor() { name = ""; else name = lua_getstring(nameObj); - lua_pushusertag(new Actor(name), MKID_BE('ACTR')); + lua_pushusertag(new Actor(name), MKTAG('A','C','T','R')); } static void GetActorTimeScale() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; /* Actor *actor = static_cast(lua_getuserdata(actorObj));*/ // TODO lua_pushnumber(actor->getTimeScale()); @@ -282,7 +282,7 @@ static void GetActorTimeScale() { static void SetSelectedActor() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); // TODO there is missing some check here: else lua_pushnil() @@ -296,7 +296,7 @@ static void SetSelectedActor() { static void GetCameraActor() { // TODO verify what is going on with selected actor Actor *actot = g_grim->selectedActor(); - lua_pushusertag(actot, MKID_BE('ACTR')); + lua_pushusertag(actot, MKTAG('A','C','T','R')); } @@ -325,7 +325,7 @@ static void setDefaultObjectParams(TextObjectDefaults *defaults, lua_Object tabl lua_pushobject(lua_getref(refTextObjectFont)); keyObj = lua_gettable(); if (keyObj) { - if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKID_BE('FONT')) { + if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKTAG('F','O','N','T')) { defaults->font = static_cast(lua_getuserdata(keyObj)); } } @@ -352,7 +352,7 @@ static void setDefaultObjectParams(TextObjectDefaults *defaults, lua_Object tabl lua_pushobject(lua_getref(refTextObjectFGColor)); keyObj = lua_gettable(); if (keyObj) { - if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKID_BE('COLR')) { + if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKTAG('C','O','L','R')) { defaults->fgColor = static_cast(lua_getuserdata(keyObj)); } } @@ -361,7 +361,7 @@ static void setDefaultObjectParams(TextObjectDefaults *defaults, lua_Object tabl lua_pushobject(lua_getref(refTextObjectBGColor)); keyObj = lua_gettable(); if (keyObj) { - if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKID_BE('COLR')) { + if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKTAG('C','O','L','R')) { //defaults->bgColor = static_cast(lua_getuserdata(keyObj)); warning("setDefaultObjectParams: dummy BGColor"); } @@ -371,7 +371,7 @@ static void setDefaultObjectParams(TextObjectDefaults *defaults, lua_Object tabl lua_pushobject(lua_getref(refTextObjectFXColor)); keyObj = lua_gettable(); if (keyObj) { - if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKID_BE('COLR')) { + if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKTAG('C','O','L','R')) { //defaults->fxColor = static_cast(lua_getuserdata(keyObj)); warning("setDefaultObjectParams: dummy FXColor"); } @@ -425,9 +425,9 @@ static void SetActorTalkColor() { lua_Object actorObj = lua_getparam(1); lua_Object colorObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; - if (!lua_isuserdata(colorObj) && lua_tag(colorObj) != MKID_BE('COLR')) + if (!lua_isuserdata(colorObj) && lua_tag(colorObj) != MKTAG('C','O','L','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); Color *color = static_cast(lua_getuserdata(colorObj)); @@ -436,13 +436,13 @@ static void SetActorTalkColor() { static void GetActorTalkColor() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } Actor *actor = static_cast(lua_getuserdata(actorObj)); Color *color = new Color(actor->talkColor()); - lua_pushusertag(color, MKID_BE('COLR')); + lua_pushusertag(color, MKTAG('C','O','L','R')); } static bool findCostume(lua_Object costumeObj, Actor *actor, Costume **costume) { @@ -469,7 +469,7 @@ static void SetActorRestChore() { Costume *costume; int chore; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR') || + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') || (!lua_isnumber(choreObj) && !lua_isnil(choreObj))) { return; } @@ -494,7 +494,7 @@ static void SetActorWalkChore() { Costume *costume; int chore; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR') || + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') || (!lua_isnumber(choreObj) && !lua_isnil(choreObj))) { return; } @@ -519,7 +519,7 @@ static void SetActorTurnChores() { lua_Object costumeObj = lua_getparam(4); Costume *costume; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR') || + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') || (!lua_isnumber(leftChoreObj) && !lua_isnumber(rightChoreObj))) { return; } @@ -542,7 +542,7 @@ static void SetActorTalkChore() { Costume *costume; int chore; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR') || + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') || !lua_isnumber(indexObj) || (!lua_isnumber(choreObj) && !lua_isnil(choreObj))) { return; } @@ -574,7 +574,7 @@ static void SetActorMumblechore() { Costume *costume; int chore; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR') || + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') || (!lua_isnumber(choreObj) && !lua_isnil(choreObj))) { return; } @@ -597,7 +597,7 @@ static void SetActorMumblechore() { static void SetActorVisibility() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -611,7 +611,7 @@ static void PutActorAt() { lua_Object xObj = lua_getparam(2); lua_Object yObj = lua_getparam(3); lua_Object zObj = lua_getparam(4); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isnumber(xObj) || !lua_isnumber(yObj) || !lua_isnumber(zObj)) @@ -627,7 +627,7 @@ static void PutActorAt() { static void GetActorPos() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -640,7 +640,7 @@ static void GetActorPos() { static void SetActorRot() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -661,7 +661,7 @@ static void SetActorRot() { static void GetActorRot() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -673,7 +673,7 @@ static void GetActorRot() { static void IsActorTurning() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -684,11 +684,11 @@ static void GetAngleBetweenActors() { lua_Object actor1Obj = lua_getparam(1); lua_Object actor2Obj = lua_getparam(2); - if (!lua_isuserdata(actor1Obj) || lua_tag(actor1Obj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actor1Obj) || lua_tag(actor1Obj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } - if (!lua_isuserdata(actor2Obj) || lua_tag(actor2Obj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actor2Obj) || lua_tag(actor2Obj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } @@ -717,7 +717,7 @@ static void GetActorYawToPoint() { lua_Object pointObj = lua_getparam(2); lua_Object xObj, yObj, zObj; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } @@ -755,7 +755,7 @@ static void PutActorInSet() { lua_Object actorObj = lua_getparam(1); lua_Object setObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -791,7 +791,7 @@ static void SetActorWalkRate() { lua_Object actorObj = lua_getparam(1); lua_Object rateObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isnumber(rateObj)) return; @@ -803,7 +803,7 @@ static void SetActorWalkRate() { static void GetActorWalkRate() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -814,7 +814,7 @@ static void SetActorTurnRate() { lua_Object actorObj = lua_getparam(1); lua_Object rateObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isnumber(rateObj)) return; @@ -826,7 +826,7 @@ static void SetActorTurnRate() { static void WalkActorForward() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); actor->walkForward(); @@ -836,7 +836,7 @@ static void SetActorReflection() { lua_Object actorObj = lua_getparam(1); lua_Object angleObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -848,7 +848,7 @@ static void GetActorPuckVector() { lua_Object actorObj = lua_getparam(1); lua_Object addObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } @@ -878,13 +878,13 @@ static void WalkActorTo() { lua_Object tyObj = lua_getparam(6); lua_Object tzObj = lua_getparam(7); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Graphics::Vector3d destVec; Actor *actor = static_cast(lua_getuserdata(actorObj)); if (!lua_isnumber(xObj)) { - if (!lua_isuserdata(xObj) || lua_tag(xObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(xObj) || lua_tag(xObj) != MKTAG('A','C','T','R')) return; Actor *destActor = static_cast(lua_getuserdata(xObj)); destVec = destActor->pos(); @@ -907,7 +907,7 @@ static void WalkActorTo() { static void ActorToClean() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } @@ -922,7 +922,7 @@ static void ActorToClean() { static void IsActorMoving() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -984,7 +984,7 @@ static void Enumerate3DDevices() { static void IsActorResting() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1003,7 +1003,7 @@ static void GetActorNodeLocation() { lua_Object actorObj = lua_getparam(1); lua_Object nodeObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isnumber(nodeObj)) @@ -1046,7 +1046,7 @@ static void SetActorWalkDominate() { lua_Object actorObj = lua_getparam(1); // lua_Object modeObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; /* bool mode = lua_isnil(modeObj) != 0; @@ -1059,7 +1059,7 @@ static void SetActorColormap() { lua_Object actorObj = lua_getparam(1); lua_Object nameObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1076,7 +1076,7 @@ static void TurnActor() { lua_Object actorObj = lua_getparam(1); lua_Object dirObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isnumber(dirObj)) @@ -1092,7 +1092,7 @@ static void PushActorCostume() { lua_Object actorObj = lua_getparam(1); lua_Object nameObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isstring(nameObj)) @@ -1107,7 +1107,7 @@ static void SetActorCostume() { lua_Object actorObj = lua_getparam(1); lua_Object costumeObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1130,7 +1130,7 @@ static void GetActorCostume() { lua_Object actorObj = lua_getparam(1); lua_Object costumeObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } @@ -1153,7 +1153,7 @@ static void GetActorCostume() { static void PopActorCostume() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1166,7 +1166,7 @@ static void PopActorCostume() { static void GetActorCostumeDepth() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } @@ -1194,7 +1194,7 @@ static void PlayActorChore() { lua_Object choreObj = lua_getparam(2); lua_Object costumeObj = lua_getparam(3); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1223,7 +1223,7 @@ static void CompleteActorChore() { lua_Object choreObj = lua_getparam(2); lua_Object costumeObj = lua_getparam(3); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1252,7 +1252,7 @@ static void PlayActorChoreLooping() { lua_Object choreObj = lua_getparam(2); lua_Object costumeObj = lua_getparam(3); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1281,7 +1281,7 @@ static void SetActorChoreLooping() { lua_Object choreObj = lua_getparam(2); lua_Object costumeObj = lua_getparam(4); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1306,7 +1306,7 @@ static void StopActorChore() { lua_Object choreObj = lua_getparam(2); lua_Object costumeObj = lua_getparam(3); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1331,7 +1331,7 @@ static void IsActorChoring() { lua_Object choreObj = lua_getparam(2); lua_Object costumeObj = lua_getparam(4); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1373,7 +1373,7 @@ static void ActorLookAt() { lua_Object zObj = lua_getparam(4); lua_Object rateObj = lua_getparam(5); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); if (!actor->currentCostume()) @@ -1412,7 +1412,7 @@ static void ActorLookAt() { if (lua_isnumber(rateObj)) actor->setLookAtRate(lua_getnumber(rateObj)); - } else if (lua_isuserdata(xObj) && lua_tag(xObj) == MKID_BE('ACTR')) { // look at another actor + } else if (lua_isuserdata(xObj) && lua_tag(xObj) == MKTAG('A','C','T','R')) { // look at another actor Actor *lookedAct = static_cast(lua_getuserdata(xObj)); actor->setLookAtVector(lookedAct->pos()); @@ -1439,13 +1439,13 @@ static void TurnActorTo() { lua_Object zObj = lua_getparam(4); float x, y, z; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } Actor *actor = static_cast(lua_getuserdata(actorObj)); - if (lua_isuserdata(xObj) && lua_tag(xObj) == MKID_BE('ACTR')) { + if (lua_isuserdata(xObj) && lua_tag(xObj) == MKTAG('A','C','T','R')) { Actor *destActor = static_cast(lua_getuserdata(xObj)); x = destActor->pos().x(); y = destActor->pos().y(); @@ -1483,13 +1483,13 @@ static void PointActorAt() { lua_Object zObj = lua_getparam(4); float x, y, z; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } Actor *actor = static_cast(lua_getuserdata(actorObj)); - if (lua_isuserdata(xObj) && lua_tag(xObj) == MKID_BE('ACTR')) { + if (lua_isuserdata(xObj) && lua_tag(xObj) == MKTAG('A','C','T','R')) { Actor *destActor = static_cast(lua_getuserdata(xObj)); x = destActor->pos().x(); y = destActor->pos().y(); @@ -1523,8 +1523,8 @@ static void WalkActorVector() { // lua_Object zObj = lua_getparam(5); // lua_Object param6Obj = lua_getparam(6); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR') || - !lua_isuserdata(actor2Obj) || lua_tag(actor2Obj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R') || + !lua_isuserdata(actor2Obj) || lua_tag(actor2Obj) != MKTAG('A','C','T','R')) return; // Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1640,7 +1640,7 @@ static void SetActorPitch() { lua_Object actorObj = lua_getparam(1); lua_Object pitchObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1652,7 +1652,7 @@ static void SetActorLookRate() { lua_Object actorObj = lua_getparam(1); lua_Object rateObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isnumber(rateObj)) @@ -1669,7 +1669,7 @@ static void SetActorLookRate() { static void GetActorLookRate() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1688,7 +1688,7 @@ static void SetActorHead() { lua_Object maxPitchObj = lua_getparam(6); lua_Object maxYawObj = lua_getparam(7); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isnumber(joint1Obj) || !lua_isnumber(joint2Obj) || !lua_isnumber(joint3Obj) || !lua_isnumber(maxRollObj) || !lua_isnumber(maxPitchObj) || !lua_isnumber(maxYawObj)) @@ -1708,7 +1708,7 @@ static void SetActorHead() { static void PutActorAtInterest() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1742,7 +1742,7 @@ static void SetActorFollowBoxes() { lua_Object modeObj = lua_getparam(2); bool mode = true; - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1760,7 +1760,7 @@ static void SetActorConstrain() { lua_Object actorObj = lua_getparam(1); // lua_Object constrainObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; // Actor *actor = static_cast(lua_getuserdata(actorObj)); @@ -1779,7 +1779,7 @@ static void GetVisibleThings() { actor = g_grim->selectedActor(); else return; - } else if (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKID_BE('ACTR')) { + } else if (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKTAG('A','C','T','R')) { actor = static_cast(lua_getuserdata(actorObj)); } assert(actor); @@ -1794,7 +1794,7 @@ static void GetVisibleThings() { // Consider the active actor visible if (actor == a || actor->angleTo(*a) < 90) { lua_pushobject(result); - lua_pushusertag(a, MKID_BE('ACTR')); + lua_pushusertag(a, MKTAG('A','C','T','R')); lua_pushnumber(1); lua_settable(); } @@ -1813,7 +1813,7 @@ static void SetShadowColor() { static void KillActorShadows() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) { + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) { lua_pushnil(); return; } @@ -2080,10 +2080,10 @@ static void SayLine() { Common::String msg; lua_Object paramObj = lua_getparam(paramId++); - if ((lua_isuserdata(paramObj) && lua_tag(paramObj) == MKID_BE('ACTR')) + if ((lua_isuserdata(paramObj) && lua_tag(paramObj) == MKTAG('A','C','T','R')) || lua_isstring(paramObj) || lua_istable(paramObj)) { Actor *actor = NULL;//some_Actor, maybe some current actor - if (lua_isuserdata(paramObj) && lua_tag(paramObj) == MKID_BE('ACTR')) { + if (lua_isuserdata(paramObj) && lua_tag(paramObj) == MKTAG('A','C','T','R')) { actor = static_cast(lua_getuserdata(paramObj)); paramObj = lua_getparam(paramId++); } @@ -2160,8 +2160,8 @@ static void InputDialog() { static void IsMessageGoing() { lua_Object actorObj = lua_getparam(1); - if (!actorObj || (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKID_BE('ACTR')) || lua_isnil(actorObj)) { - if (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKID_BE('ACTR')) { + if (!actorObj || (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKTAG('A','C','T','R')) || lua_isnil(actorObj)) { + if (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKTAG('A','C','T','R')) { Actor *actor = static_cast(lua_getuserdata(actorObj)); if (actor) { pushbool(actor->talking()); @@ -2178,7 +2178,7 @@ static void IsMessageGoing() { static void ShutUpActor() { lua_Object actorObj = lua_getparam(1); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; Actor *actor = static_cast(lua_getuserdata(actorObj)); if (actor) @@ -2224,7 +2224,7 @@ static void GetActorSector() { lua_Object actorObj = lua_getparam(1); lua_Object typeObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isnumber(typeObj)) return; @@ -2244,7 +2244,7 @@ static void GetActorSector() { static void IsActorInSector() { lua_Object actorObj = lua_getparam(1); lua_Object nameObj = lua_getparam(2); - if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKID_BE('ACTR')) + if (!lua_isuserdata(actorObj) || lua_tag(actorObj) != MKTAG('A','C','T','R')) return; if (!lua_isstring(nameObj)) { lua_pushnil(); @@ -2629,7 +2629,7 @@ static void SetSoundPosition() { return; lua_Object actorObj = lua_getparam(argId++); - if (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKID_BE('ACTR')) { + if (lua_isuserdata(actorObj) && lua_tag(actorObj) == MKTAG('A','C','T','R')) { Actor *actor = static_cast(lua_getuserdata(actorObj)); if (!actor) return; @@ -2809,12 +2809,12 @@ static void GetImage() { BitmapPtr ptr = g_resourceloader->getBitmap(bitmapName).object(); Bitmap *image = ptr.object(); image->reference(); - lua_pushusertag(image, MKID_BE('VBUF')); + lua_pushusertag(image, MKTAG('V','B','U','F')); } static void FreeImage() { lua_Object param = lua_getparam(1); - if (!lua_isuserdata(param) || lua_tag(param) != MKID_BE('VBUF')) + if (!lua_isuserdata(param) || lua_tag(param) != MKTAG('V','B','U','F')) return; Bitmap *bitmap = static_cast(lua_getuserdata(param)); bitmap->dereference(); @@ -2823,7 +2823,7 @@ static void FreeImage() { static void BlastImage() { lua_Object param = lua_getparam(1); - if (!lua_isuserdata(param) || lua_tag(param) != MKID_BE('VBUF')) + if (!lua_isuserdata(param) || lua_tag(param) != MKTAG('V','B','U','F')) return; Bitmap *bitmap = static_cast(lua_getuserdata(param)); lua_Object xObj = lua_getparam(2); @@ -2865,7 +2865,7 @@ void setTextObjectParams(TextObject *textObject, lua_Object tableObj) { lua_pushobject(lua_getref(refTextObjectFont)); keyObj = lua_gettable(); if (keyObj) { - if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKID_BE('FONT')) { + if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKTAG('F','O','N','T')) { textObject->setFont(static_cast(lua_getuserdata(keyObj))); } } @@ -2892,7 +2892,7 @@ void setTextObjectParams(TextObject *textObject, lua_Object tableObj) { lua_pushobject(lua_getref(refTextObjectFGColor)); keyObj = lua_gettable(); if (keyObj) { - if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKID_BE('COLR')) { + if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKTAG('C','O','L','R')) { textObject->setFGColor(static_cast(lua_getuserdata(keyObj))); } } @@ -2901,7 +2901,7 @@ void setTextObjectParams(TextObject *textObject, lua_Object tableObj) { lua_pushobject(lua_getref(refTextObjectBGColor)); keyObj = lua_gettable(); if (keyObj) { - if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKID_BE('COLR')) { + if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKTAG('C','O','L','R')) { //textObject->setBGColor(static_cast(lua_getuserdata(keyObj))); warning("setTextObjectParams: dummy BGColor"); } @@ -2911,7 +2911,7 @@ void setTextObjectParams(TextObject *textObject, lua_Object tableObj) { lua_pushobject(lua_getref(refTextObjectFXColor)); keyObj = lua_gettable(); if (keyObj) { - if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKID_BE('COLR')) { + if (lua_isuserdata(keyObj) && lua_tag(keyObj) == MKTAG('C','O','L','R')) { //textObject->setFXColor(static_cast(lua_getuserdata(keyObj))); warning("setTextObjectParams: dummy FXColor"); } @@ -2970,7 +2970,7 @@ static void Exit() { static void KillTextObject() { lua_Object textObj = lua_getparam(1); - if (lua_isuserdata(textObj) && lua_tag(textObj) == MKID_BE('TEXT')) { + if (lua_isuserdata(textObj) && lua_tag(textObj) == MKTAG('T', 'E', 'X', 'T')) { TextObject *textObject = static_cast(lua_getuserdata(textObj)); textObject->setDisabled(true); } @@ -2983,7 +2983,7 @@ static void ChangeTextObject() { const char *line; lua_Object textObj = lua_getparam(1); int paramId = 2; - if (lua_isuserdata(textObj) && lua_tag(textObj) == MKID_BE('TEXT')) { + if (lua_isuserdata(textObj) && lua_tag(textObj) == MKTAG('T', 'E', 'X', 'T')) { TextObject *textObject = static_cast(lua_getuserdata(textObj)); do { lua_Object paramObj = lua_getparam(paramId++); @@ -3046,7 +3046,7 @@ static void MakeTextObject() { textObject->createBitmap(); g_grim->registerTextObject(textObject); - lua_pushusertag(textObject, MKID_BE('TEXT')); + lua_pushusertag(textObject, MKTAG('T', 'E', 'X', 'T')); if (!(g_grim->getGameFlags() & GF_DEMO)) { lua_pushnumber(textObject->getBitmapWidth()); lua_pushnumber(textObject->getBitmapHeight()); @@ -3056,7 +3056,7 @@ static void MakeTextObject() { static void GetTextObjectDimensions() { lua_Object textObj = lua_getparam(1); - if (lua_isuserdata(textObj) && lua_tag(textObj) == MKID_BE('TEXT')) { + if (lua_isuserdata(textObj) && lua_tag(textObj) == MKTAG('T', 'E', 'X', 'T')) { TextObject *textObject = static_cast(lua_getuserdata(textObj)); lua_pushnumber(textObject->getBitmapWidth()); lua_pushnumber(textObject->getBitmapHeight()); @@ -3075,7 +3075,7 @@ static void ExpireText() { static void GetTextCharPosition() { lua_Object textObj = lua_getparam(1); - if (lua_isuserdata(textObj) && lua_tag(textObj) == MKID_BE('TEXT')) { + if (lua_isuserdata(textObj) && lua_tag(textObj) == MKTAG('T', 'E', 'X', 'T')) { TextObject *textObject = static_cast(lua_getuserdata(textObj)); int pos = (int)lua_getnumber(lua_getparam(2)); lua_pushnumber(textObject->getTextCharPosition(pos)); @@ -3202,7 +3202,7 @@ static void DrawPolygon() { lua_pushobject(tableObj2); lua_pushstring("color"); lua_Object colorObj = lua_gettable(); - if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) { + if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) { color = static_cast(lua_getuserdata(colorObj)); } lua_pushobject(tableObj2); @@ -3250,7 +3250,7 @@ static void DrawPolygon() { PrimitiveObject *p = new PrimitiveObject(); p->createPolygon(p1, p2, p3, p4, color); g_grim->registerPrimitiveObject(p); - lua_pushusertag(p, MKID_BE('PRIM')); + lua_pushusertag(p, MKTAG('P','R','I','M')); } static void DrawLine() { @@ -3280,7 +3280,7 @@ static void DrawLine() { lua_pushobject(tableObj); lua_pushstring("color"); lua_Object colorObj = lua_gettable(); - if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) { + if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) { color = static_cast(lua_getuserdata(colorObj)); } lua_pushobject(tableObj); @@ -3293,7 +3293,7 @@ static void DrawLine() { PrimitiveObject *p = new PrimitiveObject(); p->createLine(p1, p2, color); // TODO Add layer support g_grim->registerPrimitiveObject(p); - lua_pushusertag(p, MKID_BE('PRIM')); + lua_pushusertag(p, MKTAG('P','R','I','M')); } static void ChangePrimitive() { @@ -3301,7 +3301,7 @@ static void ChangePrimitive() { Color color; lua_Object param1 = lua_getparam(1); - if (!lua_isuserdata(param1) || lua_tag(param1) != MKID_BE('PRIM')) + if (!lua_isuserdata(param1) || lua_tag(param1) != MKTAG('P','R','I','M')) return; lua_Object tableObj = lua_getparam(2); @@ -3323,7 +3323,7 @@ static void ChangePrimitive() { lua_pushobject(tableObj); lua_pushstring("color"); lua_Object colorObj = lua_gettable(); - if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) { + if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) { color = static_cast(lua_getuserdata(colorObj)); pmodify->setColor(color); } @@ -3430,7 +3430,7 @@ static void DrawRectangle() { lua_pushobject(tableObj); lua_pushstring("color"); lua_Object colorObj = lua_gettable(); - if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) { + if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) { color = static_cast(lua_getuserdata(colorObj)); } @@ -3444,7 +3444,7 @@ static void DrawRectangle() { PrimitiveObject *p = new PrimitiveObject(); p->createRectangle(p1, p2, color, filled); g_grim->registerPrimitiveObject(p); - lua_pushusertag(p, MKID_BE('PRIM')); // FIXME: we use PRIM usetag here + lua_pushusertag(p, MKTAG('P','R','I','M')); // FIXME: we use PRIM usetag here } static void BlastRect() { @@ -3473,7 +3473,7 @@ static void BlastRect() { lua_pushobject(tableObj); lua_pushstring("color"); lua_Object colorObj = lua_gettable(); - if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKID_BE('COLR')) { + if (lua_isuserdata(colorObj) && lua_tag(colorObj) == MKTAG('C','O','L','R')) { color = static_cast(lua_getuserdata(colorObj)); } @@ -3521,12 +3521,12 @@ static void NewObjectState() { ObjectState *state = new ObjectState(setupID, pos, bitmap, zbitmap, transparency); g_grim->registerObjectState(state); g_grim->currScene()->addObjectState(state); - lua_pushusertag(state, MKID_BE('STAT')); + lua_pushusertag(state, MKTAG('S','T','A','T')); } static void FreeObjectState() { lua_Object param = lua_getparam(1); - if (!lua_isuserdata(param) || lua_tag(param) != MKID_BE('STAT')) + if (!lua_isuserdata(param) || lua_tag(param) != MKTAG('S','T','A','T')) return; ObjectState *state = static_cast(lua_getuserdata(param)); g_grim->currScene()->deleteObjectState(state); @@ -3534,7 +3534,7 @@ static void FreeObjectState() { static void SendObjectToBack() { lua_Object param = lua_getparam(1); - if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('STAT')) { + if (lua_isuserdata(param) && lua_tag(param) == MKTAG('S','T','A','T')) { ObjectState *state = static_cast(lua_getuserdata(param)); g_grim->currScene()->moveObjectStateToFirst(state); } @@ -3542,7 +3542,7 @@ static void SendObjectToBack() { static void SendObjectToFront() { lua_Object param = lua_getparam(1); - if (lua_isuserdata(param) && lua_tag(param) == MKID_BE('STAT')) { + if (lua_isuserdata(param) && lua_tag(param) == MKTAG('S','T','A','T')) { ObjectState *state = static_cast(lua_getuserdata(param)); g_grim->currScene()->moveObjectStateToLast(state); } @@ -3550,7 +3550,7 @@ static void SendObjectToFront() { static void SetObjectType() { lua_Object param = lua_getparam(1); - if (!lua_isuserdata(param) || lua_tag(param) != MKID_BE('STAT')) + if (!lua_isuserdata(param) || lua_tag(param) != MKTAG('S','T','A','T')) return; ObjectState *state = static_cast(lua_getuserdata(param)); int val = (int)lua_getnumber(lua_getparam(2)); @@ -3571,7 +3571,7 @@ static void ScreenShot() { Bitmap *screenshot = g_driver->getScreenshot(width, height); g_grim->setMode(mode); if (screenshot) { - lua_pushusertag(screenshot, MKID_BE('VBUF')); + lua_pushusertag(screenshot, MKTAG('V','B','U','F')); } else { lua_pushnil(); } @@ -3599,7 +3599,7 @@ static void GetSaveGameImage() { savedState->read(data, dataSize); screenshot = g_grim->registerBitmap(data, width, height, "screenshot"); if (screenshot) { - lua_pushusertag(screenshot, MKID_BE('VBUF')); + lua_pushusertag(screenshot, MKTAG('V','B','U','F')); } else { lua_pushnil(); warning("Could not restore screenshot from file"); @@ -3719,7 +3719,7 @@ static void LockFont() { Font *result = ptr.object(); result->reference(); if (result) { - lua_pushusertag(result, MKID_BE('FONT')); + lua_pushusertag(result, MKTAG('F','O','N','T')); return; } } @@ -3807,19 +3807,19 @@ void typeOverride() { if (lua_isuserdata(data)) { switch (lua_tag(data)) { - case MKID_BE('ACTR'): + case MKTAG('A','C','T','R'): lua_pushstring("actor"); lua_pushnumber(lua_tag(data)); return; - case MKID_BE('COST'): + case MKTAG('C','O','S','T'): lua_pushstring("costume"); lua_pushnumber(lua_tag(data)); return; - case MKID_BE('SET '): + case MKTAG('S','E','T',' '): lua_pushstring("set"); lua_pushnumber(lua_tag(data)); return; - case MKID_BE('KEYF'): + case MKTAG('K','E','Y','F'): lua_pushstring("keyframe"); lua_pushnumber(lua_tag(data)); return; @@ -3861,7 +3861,7 @@ void concatFallback() { sprintf(strPtr, "(nil)"); else if (lua_isstring(params[i])) sprintf(strPtr, "%s", lua_getstring(params[i])); - else if (lua_tag(params[i]) == MKID_BE('ACTR')) { + else if (lua_tag(params[i]) == MKTAG('A','C','T','R')) { Actor *a = static_cast(lua_getuserdata(params[i])); sprintf(strPtr, "(actor%p:%s)", (void *)a, (a->currentCostume() && a->currentCostume()->getModelNodes()) ? diff --git a/engines/grim/model.cpp b/engines/grim/model.cpp index b6ffe66838e..178282d8f88 100644 --- a/engines/grim/model.cpp +++ b/engines/grim/model.cpp @@ -40,7 +40,7 @@ Model::Model(const char *filename, const char *data, int len, CMap *cmap) : _fname = filename; _headNode = NULL; - if (len >= 4 && READ_BE_UINT32(data) == MKID_BE('LDOM')) + if (len >= 4 && READ_BE_UINT32(data) == MKTAG('L','D','O','M')) loadBinary(data, cmap); else { TextSplitter ts(data, len); diff --git a/engines/grim/object.cpp b/engines/grim/object.cpp index 2441d7e6ecf..86b9f9cd117 100644 --- a/engines/grim/object.cpp +++ b/engines/grim/object.cpp @@ -1,12 +1,36 @@ +/* Residual - A 3D game interpreter + * + * 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. -#include "object.h" -#include "engines/grim/savegame.h" + * 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 "engines/grim/lua/lobject.h" +#include "engines/grim/savegame.h" #include "engines/grim/font.h" +#include "engines/grim/object.h" -DECLARE_SINGLETON(Grim::ObjectManager) + +DECLARE_SINGLETON(Grim::ObjectManager); namespace Grim { diff --git a/engines/grim/smush/smush.cpp b/engines/grim/smush/smush.cpp index 348fb02036f..5d945be6b52 100644 --- a/engines/grim/smush/smush.cpp +++ b/engines/grim/smush/smush.cpp @@ -28,9 +28,9 @@ #include "common/file.h" #include "common/events.h" -#include "sound/audiostream.h" -#include "sound/mixer.h" -#include "sound/decoders/raw.h" +#include "audio/audiostream.h" +#include "audio/mixer.h" +#include "audio/decoders/raw.h" #include "engines/grim/smush/smush.h" @@ -171,7 +171,7 @@ void Smush::handleFrame() { } tag = _file.readUint32BE(); - if (tag == MKID_BE('ANNO')) { + if (tag == MKTAG('A','N','N','O')) { char *anno; byte *data; @@ -203,16 +203,16 @@ void Smush::handleFrame() { tag = _file.readUint32BE(); } - assert(tag == MKID_BE('FRME')); + assert(tag == MKTAG('F','R','M','E')); size = _file.readUint32BE(); byte *frame = new byte[size]; _file.read(frame, size); do { - if (READ_BE_UINT32(frame + pos) == MKID_BE('Bl16')) { + if (READ_BE_UINT32(frame + pos) == MKTAG('B','l','1','6')) { _blocky16.decode(_internalBuffer, frame + pos + 8); pos += READ_BE_UINT32(frame + pos + 4) + 8; - } else if (READ_BE_UINT32(frame + pos) == MKID_BE('Wave')) { + } else if (READ_BE_UINT32(frame + pos) == MKTAG('W','a','v','e')) { int decompressed_size = READ_BE_UINT32(frame + pos + 8); if (decompressed_size < 0) handleWave(frame + pos + 8 + 4 + 8, READ_BE_UINT32(frame + pos + 8 + 8)); @@ -339,13 +339,13 @@ void Smush::handleFrameDemo() { } tag = _f.readUint32BE(); - assert(tag == MKID_BE('FRME')); + assert(tag == MKTAG('F','R','M','E')); size = _f.readUint32BE(); byte *frame = new byte[size]; _f.read(frame, size); do { - if (READ_BE_UINT32(frame + pos) == MKID_BE('FOBJ')) { + if (READ_BE_UINT32(frame + pos) == MKTAG('F','O','B','J')) { _x = READ_LE_UINT16(frame + pos + 10); _y = READ_LE_UINT16(frame + pos + 12); int width = READ_LE_UINT16(frame + pos + 14); @@ -361,13 +361,13 @@ void Smush::handleFrameDemo() { } _blocky8.decode(_internalBuffer, frame + pos + 8 + 14); pos += READ_BE_UINT32(frame + pos + 4) + 8; - } else if (READ_BE_UINT32(frame + pos) == MKID_BE('IACT')) { + } else if (READ_BE_UINT32(frame + pos) == MKTAG('I','A','C','T')) { handleIACT(frame + pos + 8, READ_BE_UINT32(frame + pos + 4)); int offset = READ_BE_UINT32(frame + pos + 4) + 8; if (offset & 1) offset += 1; pos += offset; - } else if (READ_BE_UINT32(frame + pos) == MKID_BE('XPAL')) { + } else if (READ_BE_UINT32(frame + pos) == MKTAG('X','P','A','L')) { handleDeltaPalette(frame + pos + 8, READ_BE_UINT32(frame + pos + 4)); pos += READ_BE_UINT32(frame + pos + 4) + 8; } else { @@ -399,15 +399,15 @@ void Smush::handleFramesHeader() { int pos = 0; tag = _file.readUint32BE(); - assert(tag == MKID_BE('FLHD')); + assert(tag == MKTAG('F','L','H','D')); size = _file.readUint32BE(); byte *f_header = new byte[size]; _file.read(f_header, size); do { - if (READ_BE_UINT32(f_header + pos) == MKID_BE('Bl16')) { + if (READ_BE_UINT32(f_header + pos) == MKTAG('B','l','1','6')) { pos += READ_BE_UINT32(f_header + pos + 4) + 8; - } else if (READ_BE_UINT32(f_header + pos) == MKID_BE('Wave')) { + } else if (READ_BE_UINT32(f_header + pos) == MKTAG('W','a','v','e')) { _freq = READ_LE_UINT32(f_header + pos + 8); _channels = READ_LE_UINT32(f_header + pos + 12); pos += 20; @@ -426,11 +426,11 @@ bool Smush::setupAnimDemo(const char *file) { return false; tag = _f.readUint32BE(); - assert(tag == MKID_BE('ANIM')); + assert(tag == MKTAG('A','N','I','M')); size = _f.readUint32BE(); tag = _f.readUint32BE(); - assert(tag == MKID_BE('AHDR')); + assert(tag == MKTAG('A','H','D','R')); size = _f.readUint32BE(); _f.readUint16BE(); // version @@ -466,11 +466,11 @@ bool Smush::setupAnim(const char *file, bool looping, int x, int y) { return false; tag = _file.readUint32BE(); - assert(tag == MKID_BE('SANM')); + assert(tag == MKTAG('S','A','N','M')); size = _file.readUint32BE(); tag = _file.readUint32BE(); - assert(tag == MKID_BE('SHDR')); + assert(tag == MKTAG('S','H','D','R')); size = _file.readUint32BE(); byte *s_header = new byte[size]; _file.read(s_header, size); diff --git a/engines/grim/smush/smush.h b/engines/grim/smush/smush.h index dfff15f9791..8538cdf9267 100644 --- a/engines/grim/smush/smush.h +++ b/engines/grim/smush/smush.h @@ -37,8 +37,8 @@ #include "engines/grim/smush/blocky8.h" #include "engines/grim/smush/blocky16.h" -#include "sound/mixer.h" -#include "sound/audiostream.h" +#include "audio/mixer.h" +#include "audio/audiostream.h" namespace Grim { diff --git a/engines/metaengine.h b/engines/metaengine.h index 3cf47ad0db1..aa166b022bd 100644 --- a/engines/metaengine.h +++ b/engines/metaengine.h @@ -231,6 +231,7 @@ private: friend class Common::Singleton; public: + GameDescriptor findGameInLoadedPlugins(const Common::String &gameName, const EnginePlugin **plugin = NULL) const; GameDescriptor findGame(const Common::String &gameName, const EnginePlugin **plugin = NULL) const; GameList detectGames(const Common::FSList &fslist) const; const EnginePlugin::List &getPlugins() const; diff --git a/engines/savestate.cpp b/engines/savestate.cpp index 60decfd6ec7..5cfd1075d35 100644 --- a/engines/savestate.cpp +++ b/engines/savestate.cpp @@ -70,3 +70,9 @@ void SaveStateDescriptor::setPlayTime(int hours, int minutes) { snprintf(buffer, 32, "%.2d:%.2d", hours, minutes); setVal("play_time", buffer); } + +void SaveStateDescriptor::setPlayTime(uint32 msecs) { + uint minutes = msecs / 60000; + setPlayTime(minutes / 60, minutes % 60); +} + diff --git a/engines/savestate.h b/engines/savestate.h index 8272d32d55b..da9d1d57176 100644 --- a/engines/savestate.h +++ b/engines/savestate.h @@ -127,6 +127,11 @@ public: * Sets the 'play_time' key properly, based on the given values. */ void setPlayTime(int hours, int minutes); + + /** + * Sets the 'play_time' key properly, based on the given value. + */ + void setPlayTime(uint32 msecs); }; /** List of savestates. */ diff --git a/graphics/VectorRenderer.cpp b/graphics/VectorRenderer.cpp index 135734ed268..7a1a031379d 100644 --- a/graphics/VectorRenderer.cpp +++ b/graphics/VectorRenderer.cpp @@ -20,6 +20,7 @@ * * $URL$ * $Id$ + * */ #include "common/util.h" diff --git a/graphics/VectorRenderer.h b/graphics/VectorRenderer.h index 325d1365cb0..1aa0f4c0fa0 100644 --- a/graphics/VectorRenderer.h +++ b/graphics/VectorRenderer.h @@ -20,6 +20,7 @@ * * $URL$ * $Id$ + * */ #ifndef VECTOR_RENDERER_H diff --git a/graphics/VectorRendererSpec.cpp b/graphics/VectorRendererSpec.cpp index b63a49a4999..f7bcd1e9e88 100644 --- a/graphics/VectorRendererSpec.cpp +++ b/graphics/VectorRendererSpec.cpp @@ -255,7 +255,7 @@ void VectorRendererSpec:: fillSurface() { byte *ptr = (byte *)_activeSurface->getBasePtr(0, 0); - int h = _activeSurface->h ; + int h = _activeSurface->h; int pitch = _activeSurface->pitch; if (Base::_fillMode == kFillBackground) { diff --git a/graphics/colormasks.h b/graphics/colormasks.h index aed5df9ad70..48e442625bc 100644 --- a/graphics/colormasks.h +++ b/graphics/colormasks.h @@ -20,6 +20,7 @@ * * $URL$ * $Id$ + * */ #ifndef GRAPHICS_COLORMASKS_H diff --git a/graphics/cursorman.cpp b/graphics/cursorman.cpp index 48020814066..f93f9a707f6 100644 --- a/graphics/cursorman.cpp +++ b/graphics/cursorman.cpp @@ -27,7 +27,7 @@ #include "common/system.h" #include "common/stack.h" -DECLARE_SINGLETON(Graphics::CursorManager) +DECLARE_SINGLETON(Graphics::CursorManager); namespace Graphics { @@ -186,7 +186,7 @@ CursorManager::Cursor::~Cursor() { CursorManager::Palette::Palette(const byte *colors, uint start, uint num) { _start = start; _num = num; - _size = 4 * num; + _size = 3 * num; if (num) { _data = new byte[_size]; diff --git a/graphics/cursorman.h b/graphics/cursorman.h index 26d771028dd..d42bd490668 100644 --- a/graphics/cursorman.h +++ b/graphics/cursorman.h @@ -130,7 +130,7 @@ public: * The palette entries from 'start' till (start+num-1) will be replaced * so a full palette updated is accomplished via start=0, num=256. * - * The palette data is specified in the same interleaved RGBA format as + * The palette data is specified in the same interleaved RGB format as * used by all backends. * * @param colors the new palette data, in interleaved RGB format diff --git a/graphics/font.cpp b/graphics/font.cpp index 098ca9b8ca4..8910b789523 100644 --- a/graphics/font.cpp +++ b/graphics/font.cpp @@ -224,6 +224,11 @@ int bdf_read_header(Common::SeekableReadStream &fp, NewFontData* pf) { warning("Error: EOF on file"); return 0; } + + /* note: the way sscanf is used here ensures that a terminating null + character is automatically added. Refer to: + http://pubs.opengroup.org/onlinepubs/009695399/functions/fscanf.html */ + if (isprefix(buf, "FONT ")) { /* not required*/ if (sscanf(buf, "FONT %[^\n]", facename) != 1) { warning("Error: bad 'FONT'"); @@ -506,7 +511,11 @@ int bdf_read_bitmaps(Common::SeekableReadStream &fp, NewFontData* pf) { /* reallocate bits array to actual bits used*/ if (ofs < pf->bits_size) { - pf->bits = (bitmap_t *)realloc(pf->bits, ofs * sizeof(bitmap_t)); + bitmap_t *tmp = (bitmap_t *)realloc(pf->bits, ofs * sizeof(bitmap_t)); + if (tmp != NULL || ofs == 0) + pf->bits = tmp; + else + error("bdf_read_bitmaps: Error while reallocating memory"); pf->bits_size = ofs; } else { diff --git a/graphics/font.h b/graphics/font.h index 48e03942e20..3f9f332a6ff 100644 --- a/graphics/font.h +++ b/graphics/font.h @@ -38,9 +38,9 @@ namespace Graphics { /** Text alignment modes */ enum TextAlign { kTextAlignInvalid, - kTextAlignLeft, ///< Text should be aligned to the left - kTextAlignCenter, ///< Text should be centered - kTextAlignRight ///< Text should be aligned to the right + kTextAlignLeft, ///< Text should be aligned to the left + kTextAlignCenter, ///< Text should be centered + kTextAlignRight ///< Text should be aligned to the right }; /** @@ -53,12 +53,46 @@ public: Font() {} virtual ~Font() {} + /** + * Query the height of the font. + * + * @return font height. + */ virtual int getFontHeight() const = 0; + + /** + * Query the maximum width of the font. + * + * @return maximum font width. + */ virtual int getMaxCharWidth() const = 0; + /** + * Query the width of a specific character. + * + * @param chr The character to query the width of. + * @return The character's width. + */ virtual int getCharWidth(byte chr) const = 0; + + /** + * Draw a character at a specific point on a surface. + * + * Note that the point describes the top left edge point of the + * character's bounding box. + * + * The Font implemenation should take care of not drawing outside of the + * specified surface. + * + * @param dst The surface to drawn on. + * @param chr The character to draw. + * @param x The x coordinate where to draw the character. + * @param y The y coordinate where to draw the character. + * @param color The color of the character. + */ virtual void drawChar(Surface *dst, byte chr, int x, int y, uint32 color) const = 0; + // TODO: Add doxygen comments to this void drawString(Surface *dst, const Common::String &str, int x, int y, int w, uint32 color, TextAlign align = kTextAlignLeft, int deltax = 0, bool useEllipsis = true) const; /** @@ -74,15 +108,17 @@ public: * It returns the maximal width of any of the new lines (i.e. a value which is less * or equal to maxWidth). * - * @param str the string to word wrap - * @param maxWidth the maximum width a line may have - * @param lines the string list to which the text lines from str are appended + * @param str the string to word wrap + * @param maxWidth the maximum width a line may have + * @param lines the string list to which the text lines from str are appended * @return the maximal width of any of the lines added to lines */ int wordWrapText(const Common::String &str, int maxWidth, Common::Array &lines) const; }; - +/** + * A SCUMM style font. + */ class ScummFont : public Font { public: virtual int getFontHeight() const { return 8; } @@ -149,10 +185,10 @@ public: #define FORWARD_DECLARE_FONT(n) \ extern const NewFont *n; \ - extern void create_##n(); + extern void create_##n() #define INIT_FONT(n) \ - create_##n(); + create_##n() } // End of namespace Graphics diff --git a/graphics/fontman.cpp b/graphics/fontman.cpp index 5775a6aee41..21abc09052e 100644 --- a/graphics/fontman.cpp +++ b/graphics/fontman.cpp @@ -23,16 +23,15 @@ */ #include "graphics/fontman.h" -//#include "gui/consolefont.h" -DECLARE_SINGLETON(Graphics::FontManager) +DECLARE_SINGLETON(Graphics::FontManager); namespace Graphics { const ScummFont *g_scummfont = 0; -FORWARD_DECLARE_FONT(g_sysfont) -FORWARD_DECLARE_FONT(g_sysfont_big) -FORWARD_DECLARE_FONT(g_consolefont) +FORWARD_DECLARE_FONT(g_sysfont); +FORWARD_DECLARE_FONT(g_sysfont_big); +FORWARD_DECLARE_FONT(g_consolefont); FontManager::FontManager() { // This assert should *never* trigger, because @@ -41,9 +40,9 @@ FontManager::FontManager() { // reset to 0 in the desctructor of this class). assert(g_scummfont == 0); g_scummfont = new ScummFont; - INIT_FONT(g_sysfont) - INIT_FONT(g_sysfont_big) - INIT_FONT(g_consolefont) + INIT_FONT(g_sysfont); + INIT_FONT(g_sysfont_big); + INIT_FONT(g_consolefont); } FontManager::~FontManager() { diff --git a/graphics/imagedec.cpp b/graphics/imagedec.cpp index aa36016382f..dfe57d8f0f1 100644 --- a/graphics/imagedec.cpp +++ b/graphics/imagedec.cpp @@ -23,6 +23,7 @@ */ #include "graphics/imagedec.h" +#include "graphics/surface.h" #include "common/file.h" diff --git a/graphics/imagedec.h b/graphics/imagedec.h index e636c689793..09b7cfcdac3 100644 --- a/graphics/imagedec.h +++ b/graphics/imagedec.h @@ -27,13 +27,17 @@ #include "common/sys.h" #include "common/str.h" -#include "common/stream.h" -#include "graphics/surface.h" #include "graphics/pixelformat.h" +namespace Common{ +class SeekableReadStream; +} + namespace Graphics { +struct Surface; + class ImageDecoder { public: ImageDecoder() {} diff --git a/graphics/module.mk b/graphics/module.mk index bd77bad54c0..732ef49ee5d 100644 --- a/graphics/module.mk +++ b/graphics/module.mk @@ -8,6 +8,7 @@ MODULE_OBJS := \ fonts/newfont_big.o \ fonts/newfont.o \ fonts/scummfont.o \ + fonts/winfont.o \ imagedec.o \ primitives.o \ surface.o \ diff --git a/graphics/surface.h b/graphics/surface.h index 808aa36bdaa..23c6811e792 100644 --- a/graphics/surface.h +++ b/graphics/surface.h @@ -35,55 +35,160 @@ namespace Graphics { * operations, font rendering, etc. */ struct Surface { + /* + * IMPORTANT implementation specific detail: + * + * ARM code relies on the layout of the first 3 of these fields. Do not + * change them. + */ + /** - * ARM code relies on the layout of the first 3 of these fields. Do - * not change them. + * The width of the surface. */ uint16 w; - uint16 h; - uint16 pitch; - void *pixels; - uint8 bytesPerPixel; - Surface() : w(0), h(0), pitch(0), pixels(0), bytesPerPixel(0) {} + /** + * The height of the surface. + */ + uint16 h; + + /** + * The number of bytes a pixel line has. + * + * Note that this might not equal w * bytesPerPixel. + */ + uint16 pitch; + + /** + * The surface's pixel data. + */ + void *pixels; + + /** + * How many bytes a single pixel occupies. + */ + uint8 bytesPerPixel; + + /** + * Construct a simple Surface object. + */ + Surface() : w(0), h(0), pitch(0), pixels(0), bytesPerPixel(0) { + } + + /** + * Return a pointer to the pixel at the specified point. + * + * @param x The x coordinate of the pixel. + * @param y The y coordinate of the pixel. + * @return Pointer to the pixel. + */ inline const void *getBasePtr(int x, int y) const { return (const byte *)(pixels) + y * pitch + x * bytesPerPixel; } + /** + * Return a pointer to the pixel at the specified point. + * + * @param x The x coordinate of the pixel. + * @param y The y coordinate of the pixel. + * @return Pointer to the pixel. + */ inline void *getBasePtr(int x, int y) { return static_cast(pixels) + y * pitch + x * bytesPerPixel; } /** - * Allocate pixels memory for this surface and for the specified dimension. + * Allocate memory for the pixel data of the surface. + * + * Note that you are responsible for calling free yourself. + * @see free + * + * @param width Width of the surface object. + * @param height Height of the surface object. + * @param bytePP The number of bytes a single pixel uses. */ void create(uint16 width, uint16 height, uint8 bytesPP); /** * Release the memory used by the pixels memory of this surface. This is the * counterpart to create(). + * + * Note that you should only use this, when you created the Surface data via + * create! Otherwise this function has undefined behavior. + * @see create */ void free(); /** - * Copies data from another Surface, this calls *free* on the current surface, to assure - * it being clean. + * Copy the data from another Surface. + * + * Note that this calls free on the current surface, to assure it being + * clean. So be sure the current data was created via create, otherwise + * the results are undefined. + * @see create + * @see free + * + * @param surf Surface to copy from. */ void copyFrom(const Surface &surf); + /** + * Draw a line. + * + * @param x0 The x coordinate of the start point. + * @param y0 The y coordiante of the start point. + * @param x1 The x coordinate of the end point. + * @param y1 The y coordinate of the end point. + * @param color The color of the line. + */ void drawLine(int x0, int y0, int x1, int y1, uint32 color); + + /** + * Draw a horizontal line. + * + * @param x The start x coordinate of the line. + * @param y The y coordiante of the line. + * @param x2 The end x coordinate of the line. + * In case x > x2 the coordinates are swapped. + * @param color The color of the line. + */ void hLine(int x, int y, int x2, uint32 color); + + /** + * Draw a vertical line. + * + * @param x The x coordinate of the line. + * @param y The start y coordiante of the line. + * @param y2 The end y coordinate of the line. + * In case y > y2 the coordinates are swapped. + * @param color The color of the line. + */ void vLine(int x, int y, int y2, uint32 color); + + /** + * Fill a rect with a given color. + * + * @param r Rect to fill + * @param color The color of the rect's contents. + */ void fillRect(Common::Rect r, uint32 color); + + /** + * Draw a frame around a specified rect. + * + * @param r Rect to frame + * @param color The color of the frame. + */ void frameRect(const Common::Rect &r, uint32 color); + // See comment in graphics/surface.cpp about it void move(int dx, int dy, int height); }; /** - * For safe deletion of surface with SharedPtr. - * The deleter assures Surface::free is called on - * deletion. + * A deleter for Surface objects which can be used with SharedPtr. + * + * This deleter assures Surface::free is called on deletion. */ struct SharedPtrSurfaceDeleter { void operator()(Surface *ptr) { diff --git a/graphics/thumbnail.cpp b/graphics/thumbnail.cpp index 74e89555905..31495b1d635 100644 --- a/graphics/thumbnail.cpp +++ b/graphics/thumbnail.cpp @@ -27,6 +27,7 @@ #include "graphics/colormasks.h" #include "common/endian.h" #include "common/system.h" +#include "common/stream.h" namespace Graphics { @@ -48,7 +49,7 @@ bool loadHeader(Common::SeekableReadStream &in, ThumbnailHeader &header, bool ou // We also accept the bad 'BMHT' header here, for the sake of compatibility // with some older savegames which were written incorrectly due to a bug in // ScummVM which wrote the thumb header type incorrectly on LE systems. - if (header.type != MKID_BE('THMB') && header.type != MKID_BE('BMHT')) { + if (header.type != MKTAG('T','H','M','B') && header.type != MKTAG('B','M','H','T')) { if (outputWarnings) warning("couldn't find thumbnail header type"); return false; @@ -144,7 +145,7 @@ bool saveThumbnail(Common::WriteStream &out, const Graphics::Surface &thumb) { } ThumbnailHeader header; - header.type = MKID_BE('THMB'); + header.type = MKTAG('T','H','M','B'); header.size = ThumbnailHeaderSize + thumb.w*thumb.h*thumb.bytesPerPixel; header.version = THMB_VERSION; header.width = thumb.w; diff --git a/graphics/thumbnail.h b/graphics/thumbnail.h index 6f866ccf8de..8d1af2a9ebd 100644 --- a/graphics/thumbnail.h +++ b/graphics/thumbnail.h @@ -25,11 +25,17 @@ #ifndef GRAPHICS_THUMBNAIL_H #define GRAPHICS_THUMBNAIL_H -#include "common/stream.h" -#include "graphics/surface.h" +#include "common/sys.h" + +namespace Common{ +class SeekableReadStream; +class WriteStream; +} namespace Graphics { +struct Surface; + /** * Checks for presence of the thumbnail save header. * Seeks automatically back to start position after check. diff --git a/gui/Actions.cpp b/gui/Actions.cpp index f446b2d4378..8bc60e9d225 100644 --- a/gui/Actions.cpp +++ b/gui/Actions.cpp @@ -30,6 +30,7 @@ #ifdef _WIN32_WCE #include "backends/platform/wince/CEActionsPocket.h" #include "backends/platform/wince/CEActionsSmartphone.h" + #include "backends/platform/wince/CEDevice.h" #elif defined(__SYMBIAN32__) #include "backends/platform/symbian/src/SymbianActions.h" #endif @@ -41,8 +42,7 @@ Actions* Actions::Instance() { } Actions::Actions() : - _mapping_active(false), _initialized(false) -{ + _mapping_active(false), _initialized(false) { } @@ -94,7 +94,7 @@ bool Actions::mappingActive() { bool Actions::performMapped(unsigned int keyCode, bool pushed) { int i; - for (i=0; i kButtonHover + DrawData id; ///< The actual ID of the DrawData item. + const char *name; ///< The name of the DrawData item as it appears in the Theme Description files + bool buffer; ///< Sets whether this item is buffered on the backbuffer or drawn directly to the screen. + DrawData parent; ///< Parent DrawData item, for items that overlay. E.g. kButtonIdle -> kButtonHover }; /** * Default values for each DrawData item. */ static const DrawDataInfo kDrawDataDefaults[] = { - {kDDMainDialogBackground, "mainmenu_bg", true, kDDNone}, - {kDDSpecialColorBackground, "special_bg", true, kDDNone}, - {kDDPlainColorBackground, "plain_bg", true, kDDNone}, - {kDDTooltipBackground, "tooltip_bg", true, kDDNone}, - {kDDDefaultBackground, "default_bg", true, kDDNone}, - {kDDTextSelectionBackground, "text_selection", false, kDDNone}, - {kDDTextSelectionFocusBackground, "text_selection_focus", false, kDDNone}, + {kDDMainDialogBackground, "mainmenu_bg", true, kDDNone}, + {kDDSpecialColorBackground, "special_bg", true, kDDNone}, + {kDDPlainColorBackground, "plain_bg", true, kDDNone}, + {kDDTooltipBackground, "tooltip_bg", true, kDDNone}, + {kDDDefaultBackground, "default_bg", true, kDDNone}, + {kDDTextSelectionBackground, "text_selection", false, kDDNone}, + {kDDTextSelectionFocusBackground, "text_selection_focus", false, kDDNone}, - {kDDWidgetBackgroundDefault, "widget_default", true, kDDNone}, - {kDDWidgetBackgroundSmall, "widget_small", true, kDDNone}, - {kDDWidgetBackgroundEditText, "widget_textedit", true, kDDNone}, - {kDDWidgetBackgroundSlider, "widget_slider", true, kDDNone}, + {kDDWidgetBackgroundDefault, "widget_default", true, kDDNone}, + {kDDWidgetBackgroundSmall, "widget_small", true, kDDNone}, + {kDDWidgetBackgroundEditText, "widget_textedit", true, kDDNone}, + {kDDWidgetBackgroundSlider, "widget_slider", true, kDDNone}, - {kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider}, - {kDDButtonHover, "button_hover", false, kDDButtonIdle}, - {kDDButtonDisabled, "button_disabled", true, kDDNone}, + {kDDButtonIdle, "button_idle", true, kDDWidgetBackgroundSlider}, + {kDDButtonHover, "button_hover", false, kDDButtonIdle}, + {kDDButtonDisabled, "button_disabled", true, kDDNone}, - {kDDSliderFull, "slider_full", false, kDDNone}, - {kDDSliderHover, "slider_hover", false, kDDNone}, - {kDDSliderDisabled, "slider_disabled", false, kDDNone}, + {kDDSliderFull, "slider_full", false, kDDNone}, + {kDDSliderHover, "slider_hover", false, kDDNone}, + {kDDSliderDisabled, "slider_disabled", false, kDDNone}, - {kDDCheckboxDefault, "checkbox_default", true, kDDNone}, - {kDDCheckboxDisabled, "checkbox_disabled", true, kDDNone}, - {kDDCheckboxSelected, "checkbox_selected", false, kDDCheckboxDefault}, + {kDDCheckboxDefault, "checkbox_default", true, kDDNone}, + {kDDCheckboxDisabled, "checkbox_disabled", true, kDDNone}, + {kDDCheckboxSelected, "checkbox_selected", false, kDDCheckboxDefault}, - {kDDRadiobuttonDefault, "radiobutton_default", true, kDDNone}, - {kDDRadiobuttonDisabled, "radiobutton_disabled", true, kDDNone}, - {kDDRadiobuttonSelected, "radiobutton_selected", false, kDDRadiobuttonDefault}, + {kDDRadiobuttonDefault, "radiobutton_default", true, kDDNone}, + {kDDRadiobuttonDisabled, "radiobutton_disabled", true, kDDNone}, + {kDDRadiobuttonSelected, "radiobutton_selected", false, kDDRadiobuttonDefault}, - {kDDTabActive, "tab_active", false, kDDTabInactive}, - {kDDTabInactive, "tab_inactive", true, kDDNone}, - {kDDTabBackground, "tab_background", true, kDDNone}, + {kDDTabActive, "tab_active", false, kDDTabInactive}, + {kDDTabInactive, "tab_inactive", true, kDDNone}, + {kDDTabBackground, "tab_background", true, kDDNone}, - {kDDScrollbarBase, "scrollbar_base", true, kDDNone}, + {kDDScrollbarBase, "scrollbar_base", true, kDDNone}, - {kDDScrollbarButtonIdle, "scrollbar_button_idle", true, kDDNone}, - {kDDScrollbarButtonHover, "scrollbar_button_hover", false, kDDScrollbarButtonIdle}, + {kDDScrollbarButtonIdle, "scrollbar_button_idle", true, kDDNone}, + {kDDScrollbarButtonHover, "scrollbar_button_hover", false, kDDScrollbarButtonIdle}, - {kDDScrollbarHandleIdle, "scrollbar_handle_idle", false, kDDNone}, - {kDDScrollbarHandleHover, "scrollbar_handle_hover", false, kDDScrollbarBase}, + {kDDScrollbarHandleIdle, "scrollbar_handle_idle", false, kDDNone}, + {kDDScrollbarHandleHover, "scrollbar_handle_hover", false, kDDScrollbarBase}, - {kDDPopUpIdle, "popup_idle", true, kDDNone}, - {kDDPopUpHover, "popup_hover", false, kDDPopUpIdle}, - {kDDPopUpDisabled, "popup_disabled", true, kDDNone}, + {kDDPopUpIdle, "popup_idle", true, kDDNone}, + {kDDPopUpHover, "popup_hover", false, kDDPopUpIdle}, + {kDDPopUpDisabled, "popup_disabled", true, kDDNone}, - {kDDCaret, "caret", false, kDDNone}, - {kDDSeparator, "separator", true, kDDNone}, + {kDDCaret, "caret", false, kDDNone}, + {kDDSeparator, "separator", true, kDDNone}, }; /********************************************************** - * ThemeItem functions for drawing queues. + * ThemeItem functions for drawing queues. *********************************************************/ void ThemeItemDrawData::drawSelf(bool draw, bool restore) { @@ -259,7 +259,7 @@ void ThemeItemBitmap::drawSelf(bool draw, bool restore) { /********************************************************** - * ThemeEngine class + * ThemeEngine class *********************************************************/ ThemeEngine::ThemeEngine(Common::String id, GraphicsMode mode) : _system(0), _vectorRenderer(0), @@ -326,7 +326,7 @@ ThemeEngine::~ThemeEngine() { /********************************************************** - * Rendering mode management + * Rendering mode management *********************************************************/ const ThemeEngine::Renderer ThemeEngine::_rendererModes[] = { { _s("Disabled GFX"), _sc("Disabled GFX", "lowres"), "none", kGfxDisabled }, @@ -368,7 +368,7 @@ const char *ThemeEngine::findModeConfigName(GraphicsMode mode) { /********************************************************** - * Theme setup/initialization + * Theme setup/initialization *********************************************************/ bool ThemeEngine::init() { // reset everything and reload the graphics @@ -512,7 +512,7 @@ void ThemeEngine::setGraphicsMode(GraphicsMode mode) { void WidgetDrawData::calcBackgroundOffset() { uint maxShadow = 0; for (Common::List::const_iterator step = _steps.begin(); - step != _steps.end(); ++step) { + step != _steps.end(); ++step) { if ((step->autoWidth || step->autoHeight) && step->shadow > maxShadow) maxShadow = step->shadow; @@ -531,7 +531,7 @@ void ThemeEngine::restoreBackground(Common::Rect r) { /********************************************************** - * Theme elements management + * Theme elements management *********************************************************/ void ThemeEngine::addDrawStep(const Common::String &drawDataId, const Graphics::DrawStep &step) { DrawData id = parseDrawDataId(drawDataId); @@ -566,32 +566,34 @@ bool ThemeEngine::addFont(TextData textId, const Common::String &file) { if (file == "default") { _texts[textId]->_fontPtr = _font; } else { - Common::String localized = genLocalizedFontFilename(file.c_str()); + Common::String localized = genLocalizedFontFilename(file); // Try built-in fonts _texts[textId]->_fontPtr = FontMan.getFontByName(localized); if (!_texts[textId]->_fontPtr) { // First try to load localized font _texts[textId]->_fontPtr = loadFont(localized); - + if (_texts[textId]->_fontPtr) - FontMan.assignFontToName(file, _texts[textId]->_fontPtr); + FontMan.assignFontToName(localized, _texts[textId]->_fontPtr); // Fallback to non-localized font and default translation else { // Try built-in fonts _texts[textId]->_fontPtr = FontMan.getFontByName(file); - + // Try to load it if (!_texts[textId]->_fontPtr) { _texts[textId]->_fontPtr = loadFont(file); if (!_texts[textId]->_fontPtr) error("Couldn't load font '%s'", file.c_str()); - + FontMan.assignFontToName(file, _texts[textId]->_fontPtr); } +#ifdef USE_TRANSLATION TransMan.setLanguage("C"); +#endif warning("Failed to load localized font '%s'. Using non-localized font and default GUI language instead", file.c_str()); } } @@ -657,7 +659,7 @@ bool ThemeEngine::addDrawData(const Common::String &data, bool cached) { /********************************************************** - * Theme XML loading + * Theme XML loading *********************************************************/ void ThemeEngine::loadTheme(const Common::String &themeId) { unloadTheme(); @@ -715,12 +717,12 @@ bool ThemeEngine::loadDefaultXML() { #ifndef DISABLE_GUI_BUILTIN_THEME const char *defaultXML = #include "themes/default.inc" - ; + ; - if (!_parser->loadBuffer((const byte*)defaultXML, strlen(defaultXML))) + if (!_parser->loadBuffer((const byte *)defaultXML, strlen(defaultXML))) return false; - _themeName = "ScummVM Classic Theme (Builtin Version)"; + _themeName = "Residual Classic Theme (Builtin Version)"; _themeId = "builtin"; _themeFile.clear(); @@ -789,9 +791,8 @@ bool ThemeEngine::loadThemeXML(const Common::String &themeId) { } - /********************************************************** - * Drawing Queue management + * Drawing Queue management *********************************************************/ void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic, bool restore) { if (_widgets[type] == 0) @@ -818,7 +819,7 @@ void ThemeEngine::queueDD(DrawData type, const Common::Rect &r, uint32 dynamic, } void ThemeEngine::queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg, - bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) { + bool ellipsis, Graphics::TextAlign alignH, TextAlignVertical alignV, int deltax) { if (_texts[type] == 0) return; @@ -854,7 +855,7 @@ void ThemeEngine::queueBitmap(const Graphics::Surface *bitmap, const Common::Rec /********************************************************** - * Widget drawing functions + * Widget drawing functions *********************************************************/ void ThemeEngine::drawButton(const Common::Rect &r, const Common::String &str, WidgetStateInfo state, uint16 hints) { if (!ready()) @@ -1086,7 +1087,7 @@ void ThemeEngine::drawTab(const Common::Rect &r, int tabHeight, int tabWidth, co } if (active >= 0 && - (r.left + active * tabWidth < r.right) && (r.left + (active + 1) * tabWidth < r.right)) { + (r.left + active * tabWidth < r.right) && (r.left + (active + 1) * tabWidth < r.right)) { Common::Rect tabRect(r.left + active * tabWidth, r.top, r.left + (active + 1) * tabWidth, r.top + tabHeight); const uint16 tabLeft = active * tabWidth; const uint16 tabRight = MAX(r.right - tabRect.right, 0); @@ -1189,25 +1190,25 @@ void ThemeEngine::debugWidgetPosition(const char *name, const Common::Rect &r) { } /********************************************************** - * Screen/overlay management + * Screen/overlay management *********************************************************/ -void ThemeEngine::updateScreen() { +void ThemeEngine::updateScreen(bool render) { if (!_bufferQueue.empty()) { _vectorRenderer->setSurface(&_backBuffer); - for (Common::List::iterator q = _bufferQueue.begin(); q != _bufferQueue.end(); ++q) { + for (Common::List::iterator q = _bufferQueue.begin(); q != _bufferQueue.end(); ++q) { (*q)->drawSelf(true, false); delete *q; } _vectorRenderer->setSurface(&_screen); - memcpy(_screen.getBasePtr(0,0), _backBuffer.getBasePtr(0,0), _screen.pitch * _screen.h); + memcpy(_screen.getBasePtr(0, 0), _backBuffer.getBasePtr(0, 0), _screen.pitch * _screen.h); _bufferQueue.clear(); } if (!_screenQueue.empty()) { _vectorRenderer->disableShadows(); - for (Common::List::iterator q = _screenQueue.begin(); q != _screenQueue.end(); ++q) { + for (Common::List::iterator q = _screenQueue.begin(); q != _screenQueue.end(); ++q) { (*q)->drawSelf(true, false); delete *q; } @@ -1216,7 +1217,8 @@ void ThemeEngine::updateScreen() { _screenQueue.clear(); } - renderDirtyScreen(); + if (render) + renderDirtyScreen(); } void ThemeEngine::addDirtyRect(Common::Rect r) { @@ -1229,7 +1231,7 @@ void ThemeEngine::addDirtyRect(Common::Rect r) { // Check if the new rectangle is contained within another in the list Common::List::iterator it; - for (it = _dirtyScreen.begin(); it != _dirtyScreen.end(); ) { + for (it = _dirtyScreen.begin(); it != _dirtyScreen.end();) { // If we find a rectangle which fully contains the new one, // we can abort the search. if (it->contains(r)) @@ -1268,7 +1270,7 @@ void ThemeEngine::openDialog(bool doBuffer, ShadingStyle style) { addDirtyRect(Common::Rect(0, 0, _screen.w, _screen.h)); } - memcpy(_backBuffer.getBasePtr(0,0), _screen.getBasePtr(0,0), _screen.pitch * _screen.h); + memcpy(_backBuffer.getBasePtr(0, 0), _screen.getBasePtr(0, 0), _screen.pitch * _screen.h); _vectorRenderer->setSurface(&_screen); } @@ -1306,8 +1308,8 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int // Now, scan the bitmap. We have to convert it from 16 bit color mode // to 8 bit mode, and have to create a suitable palette on the fly. uint colorsFound = 0; - Common::HashMap colorToIndex; - const OverlayColor *src = (const OverlayColor*)cursor->pixels; + Common::HashMap colorToIndex; + const OverlayColor *src = (const OverlayColor *)cursor->pixels; for (uint y = 0; y < _cursorHeight; ++y) { for (uint x = 0; x < _cursorWidth; ++x) { byte r, g, b; @@ -1324,10 +1326,9 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int const int index = colorsFound++; colorToIndex[col] = index; - _cursorPal[index * 4 + 0] = r; - _cursorPal[index * 4 + 1] = g; - _cursorPal[index * 4 + 2] = b; - _cursorPal[index * 4 + 3] = 0xFF; + _cursorPal[index * 3 + 0] = r; + _cursorPal[index * 3 + 1] = g; + _cursorPal[index * 3 + 2] = b; if (colorsFound > MAX_CURS_COLORS) { warning("Cursor contains too many colors (%d, but only %d are allowed)", colorsFound, MAX_CURS_COLORS); @@ -1350,7 +1351,7 @@ bool ThemeEngine::createCursor(const Common::String &filename, int hotspotX, int /********************************************************** - * Legacy GUI::Theme support functions + * Legacy GUI::Theme support functions *********************************************************/ const Graphics::Font *ThemeEngine::getFont(FontStyle font) const { @@ -1386,7 +1387,7 @@ DrawData ThemeEngine::parseDrawDataId(const Common::String &name) const { } /********************************************************** - * External data loading + * External data loading *********************************************************/ const Graphics::Font *ThemeEngine::loadFontFromArchive(const Common::String &filename) { @@ -1419,7 +1420,7 @@ const Graphics::Font *ThemeEngine::loadCachedFontFromArchive(const Common::Strin const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename) { const Graphics::Font *font = 0; - Common::String cacheFilename = genCacheFilename(filename.c_str()); + Common::String cacheFilename = genCacheFilename(filename); Common::File fontFile; if (!cacheFilename.empty()) { @@ -1454,7 +1455,7 @@ const Graphics::Font *ThemeEngine::loadFont(const Common::String &filename) { return font; } -Common::String ThemeEngine::genCacheFilename(const char *filename) { +Common::String ThemeEngine::genCacheFilename(const Common::String &filename) const { Common::String cacheName(filename); for (int i = cacheName.size() - 1; i >= 0; --i) { if (cacheName[i] == '.') { @@ -1470,25 +1471,20 @@ Common::String ThemeEngine::genCacheFilename(const char *filename) { return Common::String(); } -Common::String ThemeEngine::genLocalizedFontFilename(const char *filename) { +Common::String ThemeEngine::genLocalizedFontFilename(const Common::String &filename) const { #ifndef USE_TRANSLATION - return Common::String(filename); + return filename; #else - Common::String result; bool pointPassed = false; - for (const char *p = filename; *p != 0; p++) { - if (!pointPassed) { - if (*p != '.') { - result += *p; - } else { - result += "-"; - result += TransMan.getCurrentCharset(); - result += *p; + for (const char *p = filename.c_str(); *p != 0; p++) { + if (!pointPassed && *p == '.') { + result += "-"; + result += TransMan.getCurrentCharset(); + result += *p; - pointPassed = true; - } + pointPassed = true; } else { result += *p; } @@ -1500,7 +1496,7 @@ Common::String ThemeEngine::genLocalizedFontFilename(const char *filename) { /********************************************************** - * Static Theme XML functions + * Static Theme XML functions *********************************************************/ bool ThemeEngine::themeConfigParseHeader(Common::String header, Common::String &themeName) { @@ -1586,7 +1582,9 @@ struct TDComparator { const Common::String _id; TDComparator(const Common::String &id) : _id(id) {} - bool operator()(const ThemeEngine::ThemeDescriptor &r) { return _id == r.id; } + bool operator()(const ThemeEngine::ThemeDescriptor &r) { + return _id == r.id; + } }; } // end of anonymous namespace @@ -1594,7 +1592,7 @@ struct TDComparator { void ThemeEngine::listUsableThemes(Common::List &list) { #ifndef DISABLE_GUI_BUILTIN_THEME ThemeDescriptor th; - th.name = "ScummVM Classic Theme (Builtin Version)"; + th.name = "Residual Classic Theme (Builtin Version)"; th.id = "builtin"; th.filename.clear(); list.push_back(th); @@ -1628,7 +1626,7 @@ void ThemeEngine::listUsableThemes(Common::Archive &archive, Common::ListgetName(); diff --git a/gui/ThemeEngine.h b/gui/ThemeEngine.h index 56b8c705a0f..e4781f42318 100644 --- a/gui/ThemeEngine.h +++ b/gui/ThemeEngine.h @@ -32,11 +32,11 @@ #include "graphics/surface.h" #include "graphics/font.h" -#define RESIDUAL_THEME_VERSION_STR "RESIDUAL_STX0.8" +#define RESIDUAL_THEME_VERSION_STR "RESIDUAL_STX0.8.3" namespace Graphics { - struct DrawStep; - class VectorRenderer; +struct DrawStep; +class VectorRenderer; } namespace GUI { @@ -53,9 +53,9 @@ class ThemeItem; class ThemeParser; /** - * DrawData sets enumeration. - * Each DD set corresponds to the actual looks - * of a widget in a given state. + * DrawData sets enumeration. + * Each DD set corresponds to the actual looks + * of a widget in a given state. */ enum DrawData { kDDMainDialogBackground, @@ -134,7 +134,7 @@ enum TextColor { class ThemeEngine { protected: - typedef Common::HashMap ImagesMap; + typedef Common::HashMap ImagesMap; friend class GUI::Dialog; friend class GUI::GuiObject; @@ -150,12 +150,12 @@ public: /// Widget background type enum WidgetBackground { - kWidgetBackgroundNo, ///< No background at all - kWidgetBackgroundPlain, ///< Simple background, this may not include borders - kWidgetBackgroundBorder, ///< Same as kWidgetBackgroundPlain just with a border - kWidgetBackgroundBorderSmall, ///< Same as kWidgetBackgroundPlain just with a small border - kWidgetBackgroundEditText, ///< Background used for edit text fields - kWidgetBackgroundSlider ///< Background used for sliders + kWidgetBackgroundNo, ///< No background at all + kWidgetBackgroundPlain, ///< Simple background, this may not include borders + kWidgetBackgroundBorder, ///< Same as kWidgetBackgroundPlain just with a border + kWidgetBackgroundBorderSmall, ///< Same as kWidgetBackgroundPlain just with a small border + kWidgetBackgroundEditText, ///< Background used for edit text fields + kWidgetBackgroundSlider ///< Background used for sliders }; /// Dialog background type @@ -169,18 +169,18 @@ public: /// State of the widget to be drawn enum State { - kStateDisabled, ///< Indicates that the widget is disabled, that does NOT include that it is invisible - kStateEnabled, ///< Indicates that the widget is enabled - kStateHighlight ///< Indicates that the widget is highlighted by the user + kStateDisabled, ///< Indicates that the widget is disabled, that does NOT include that it is invisible + kStateEnabled, ///< Indicates that the widget is enabled + kStateHighlight ///< Indicates that the widget is highlighted by the user }; typedef State WidgetStateInfo; /// Text inversion state of the text to be draw enum TextInversionState { - kTextInversionNone, ///< Indicates that the text should not be drawn inverted - kTextInversion, ///< Indicates that the text should be drawn inverted, but not focused - kTextInversionFocus ///< Indicates that the text should be drawn inverted, and focused + kTextInversionNone, ///< Indicates that the text should not be drawn inverted + kTextInversion, ///< Indicates that the text should be drawn inverted, but not focused + kTextInversionFocus ///< Indicates that the text should be drawn inverted, and focused }; enum ScrollbarState { @@ -193,34 +193,34 @@ public: /// Font style selector enum FontStyle { - kFontStyleBold = 0, ///< A bold font. This is also the default font. - kFontStyleNormal = 1, ///< A normal font. - kFontStyleItalic = 2, ///< Italic styled font. - kFontStyleFixedNormal = 3, ///< Fixed size font. - kFontStyleFixedBold = 4, ///< Fixed size bold font. - kFontStyleFixedItalic = 5, ///< Fixed size italic font. - kFontStyleTooltip = 6, ///< Tiny console font + kFontStyleBold = 0, ///< A bold font. This is also the default font. + kFontStyleNormal = 1, ///< A normal font. + kFontStyleItalic = 2, ///< Italic styled font. + kFontStyleFixedNormal = 3, ///< Fixed size font. + kFontStyleFixedBold = 4, ///< Fixed size bold font. + kFontStyleFixedItalic = 5, ///< Fixed size italic font. + kFontStyleTooltip = 6, ///< Tiny console font kFontStyleMax }; /// Font color selector enum FontColor { - kFontColorNormal = 0, ///< The default color of the theme - kFontColorAlternate = 1, ///< Alternative font color + kFontColorNormal = 0, ///< The default color of the theme + kFontColorAlternate = 1, ///< Alternative font color kFontColorMax }; /// Function used to process areas other than the current dialog enum ShadingStyle { - kShadingNone, ///< No special post processing - kShadingDim, ///< Dimming unused areas - kShadingLuminance ///< Converting colors to luminance for unused areas + kShadingNone, ///< No special post processing + kShadingDim, ///< Dimming unused areas + kShadingLuminance ///< Converting colors to luminance for unused areas }; // Special image ids for images used in the GUI - static const char * const kImageLogo; ///< ScummVM logo used in the launcher - static const char * const kImageLogoSmall; ///< ScummVM logo used in the GMM - static const char * const kImageSearch; ///< Search tool image used in the launcher + static const char *const kImageLogo; ///< ScummVM logo used in the launcher + static const char *const kImageLogoSmall; ///< ScummVM logo used in the GMM + static const char *const kImageSearch; ///< Search tool image used in the launcher /** * Graphics mode enumeration. @@ -228,9 +228,9 @@ public: * surface. */ enum GraphicsMode { - kGfxDisabled = 0, ///< No GFX - kGfxStandard16bit, ///< 2BPP with the standard (aliased) renderer. - kGfxAntialias16bit ///< 2BPP with the optimized AA renderer. + kGfxDisabled = 0, ///< No GFX + kGfxStandard16bit, ///< 2BPP with the standard (aliased) renderer. + kGfxAntialias16bit ///< 2BPP with the optimized AA renderer. }; /** Constant value to expand dirty rectangles, to make sure they are fully copied */ @@ -265,22 +265,22 @@ public: void disable(); /** - * Implementation of the GUI::Theme API. Called when a - * new dialog is opened. Note that the boolean parameter - * meaning has been changed. + * Implementation of the GUI::Theme API. Called when a + * new dialog is opened. Note that the boolean parameter + * meaning has been changed. * * @param enableBuffering If set to true, buffering is enabled for - * drawing this dialog, and will continue enabled - * until disabled. + * drawing this dialog, and will continue enabled + * until disabled. */ void openDialog(bool enableBuffering, ShadingStyle shading = kShadingNone); /** - * The updateScreen() method is called every frame. - * It processes all the drawing queues and then copies dirty rects - * in the current Screen surface to the overlay. + * The updateScreen() method is called every frame. + * It processes all the drawing queues and then copies dirty rects + * in the current Screen surface to the overlay. */ - void updateScreen(); + void updateScreen(bool render = true); /** @name FONT MANAGEMENT METHODS */ @@ -309,35 +309,35 @@ public: //@{ void drawWidgetBackground(const Common::Rect &r, uint16 hints, - WidgetBackground background = kWidgetBackgroundPlain, WidgetStateInfo state = kStateEnabled); + WidgetBackground background = kWidgetBackgroundPlain, WidgetStateInfo state = kStateEnabled); void drawButton(const Common::Rect &r, const Common::String &str, - WidgetStateInfo state = kStateEnabled, uint16 hints = 0); + WidgetStateInfo state = kStateEnabled, uint16 hints = 0); void drawSurface(const Common::Rect &r, const Graphics::Surface &surface, - WidgetStateInfo state = kStateEnabled, int alpha = 256, bool themeTrans = false); + WidgetStateInfo state = kStateEnabled, int alpha = 256, bool themeTrans = false); void drawSlider(const Common::Rect &r, int width, - WidgetStateInfo state = kStateEnabled); + WidgetStateInfo state = kStateEnabled); void drawCheckbox(const Common::Rect &r, const Common::String &str, - bool checked, WidgetStateInfo state = kStateEnabled); + bool checked, WidgetStateInfo state = kStateEnabled); void drawRadiobutton(const Common::Rect &r, const Common::String &str, - bool checked, WidgetStateInfo state = kStateEnabled); + bool checked, WidgetStateInfo state = kStateEnabled); void drawTab(const Common::Rect &r, int tabHeight, int tabWidth, - const Common::Array &tabs, int active, uint16 hints, - int titleVPad, WidgetStateInfo state = kStateEnabled); + const Common::Array &tabs, int active, uint16 hints, + int titleVPad, WidgetStateInfo state = kStateEnabled); void drawScrollbar(const Common::Rect &r, int sliderY, int sliderHeight, - ScrollbarState, WidgetStateInfo state = kStateEnabled); + ScrollbarState, WidgetStateInfo state = kStateEnabled); void drawPopUpWidget(const Common::Rect &r, const Common::String &sel, - int deltax, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignLeft); + int deltax, WidgetStateInfo state = kStateEnabled, Graphics::TextAlign align = Graphics::kTextAlignLeft); void drawCaret(const Common::Rect &r, bool erase, - WidgetStateInfo state = kStateEnabled); + WidgetStateInfo state = kStateEnabled); void drawLineSeparator(const Common::Rect &r, WidgetStateInfo state = kStateEnabled); @@ -362,13 +362,13 @@ public: /** - * Returns the DrawData enumeration value that represents the given string - * in the DrawDataDefaults enumeration. - * It's slow, but called sparsely. + * Returns the DrawData enumeration value that represents the given string + * in the DrawDataDefaults enumeration. + * It's slow, but called sparsely. * - * @returns The drawdata enum value, or -1 if not found. - * @param name The representing name, as found on Theme Description XML files. - * @see kDrawDataDefaults[] + * @returns The drawdata enum value, or -1 if not found. + * @param name The representing name, as found on Theme Description XML files. + * @see kDrawDataDefaults[] */ DrawData parseDrawDataId(const Common::String &name) const; @@ -377,34 +377,34 @@ public: /** - * Interface for ThemeParser class: Parsed DrawSteps are added via this function. - * There is no return type because DrawSteps can always be added, unless something - * goes horribly wrong. - * The specified step will be added to the Steps list of the given DrawData id. + * Interface for ThemeParser class: Parsed DrawSteps are added via this function. + * There is no return type because DrawSteps can always be added, unless something + * goes horribly wrong. + * The specified step will be added to the Steps list of the given DrawData id. * - * @param drawDataId The representing DrawData name, as found on Theme Description XML files. - * @param step The actual DrawStep struct to be added. + * @param drawDataId The representing DrawData name, as found on Theme Description XML files. + * @param step The actual DrawStep struct to be added. */ void addDrawStep(const Common::String &drawDataId, const Graphics::DrawStep &step); /** - * Interface for the ThemeParser class: Parsed DrawData sets are added via this function. - * The goal of the function is to initialize each DrawData set before their DrawSteps can - * be added, hence this must be called for each DD set before addDrawStep() can be called - * for that given set. + * Interface for the ThemeParser class: Parsed DrawData sets are added via this function. + * The goal of the function is to initialize each DrawData set before their DrawSteps can + * be added, hence this must be called for each DD set before addDrawStep() can be called + * for that given set. * - * @param data The representing DrawData name, as found on Theme Description XML files. - * @param cached Whether this DD set will be cached beforehand. + * @param data The representing DrawData name, as found on Theme Description XML files. + * @param cached Whether this DD set will be cached beforehand. */ bool addDrawData(const Common::String &data, bool cached); /** - * Interface for the ThemeParser class: Loads a font to use on the GUI from the given - * filename. + * Interface for the ThemeParser class: Loads a font to use on the GUI from the given + * filename. * - * @param fontName Identifier name for the font. - * @param file Name of the font file. + * @param fontName Identifier name for the font. + * @param file Name of the font file. */ bool addFont(TextData textId, const Common::String &file); @@ -418,25 +418,25 @@ public: /** - * Interface for the ThemeParser class: Loads a bitmap file to use on the GUI. - * The filename is also used as its identifier. + * Interface for the ThemeParser class: Loads a bitmap file to use on the GUI. + * The filename is also used as its identifier. * - * @param filename Name of the bitmap file. + * @param filename Name of the bitmap file. */ bool addBitmap(const Common::String &filename); /** - * Adds a new TextStep from the ThemeParser. This will be deprecated/removed once the - * new Font API is in place. FIXME: Is that so ??? + * Adds a new TextStep from the ThemeParser. This will be deprecated/removed once the + * new Font API is in place. FIXME: Is that so ??? */ bool addTextData(const Common::String &drawDataId, TextData textId, TextColor id, Graphics::TextAlign alignH, TextAlignVertical alignV); protected: /** - * Returns if the Theme is ready to draw stuff on screen. - * Must be called instead of just checking _initOk, because - * this checks if the renderer is initialized AND if the theme - * is loaded. + * Returns if the Theme is ready to draw stuff on screen. + * Must be called instead of just checking _initOk, because + * this checks if the renderer is initialized AND if the theme + * is loaded. */ bool ready() const { return _initOk && _themeOk; @@ -446,15 +446,15 @@ protected: void loadTheme(const Common::String &themeid); /** - * Changes the active graphics mode of the GUI; may be used to either - * initialize the GUI or to change the mode while the GUI is already running. + * Changes the active graphics mode of the GUI; may be used to either + * initialize the GUI or to change the mode while the GUI is already running. */ void setGraphicsMode(GraphicsMode mode); public: /** - * Finishes buffering: widgets from then on will be drawn straight on the screen - * without drawing queues. + * Finishes buffering: widgets from then on will be drawn straight on the screen + * without drawing queues. */ inline void finishBuffering() { _buffering = false; } inline void startBuffering() { _buffering = true; } @@ -474,21 +474,21 @@ public: } /** - * Interface for the Theme Parser: Creates a new cursor by loading the given - * bitmap and sets it as the active cursor. + * Interface for the Theme Parser: Creates a new cursor by loading the given + * bitmap and sets it as the active cursor. * - * @param filename File name of the bitmap to load. - * @param hotspotX X Coordinate of the bitmap which does the cursor click. - * @param hotspotY Y Coordinate of the bitmap which does the cursor click. - * @param scale Scale at which the bitmap is supposed to be used. + * @param filename File name of the bitmap to load. + * @param hotspotX X Coordinate of the bitmap which does the cursor click. + * @param hotspotY Y Coordinate of the bitmap which does the cursor click. + * @param scale Scale at which the bitmap is supposed to be used. */ bool createCursor(const Common::String &filename, int hotspotX, int hotspotY, int scale); /** - * Wrapper for restoring data from the Back Buffer to the screen. - * The actual processing is done in the VectorRenderer. + * Wrapper for restoring data from the Back Buffer to the screen. + * The actual processing is done in the VectorRenderer. * - * @param r Area to restore. + * @param r Area to restore. */ void restoreBackground(Common::Rect r); @@ -498,68 +498,68 @@ public: protected: /** - * Initializes the drawing screen surfaces, _screen and _backBuffer. - * If the surfaces already exist, they are cleared and re-initialized. + * Initializes the drawing screen surfaces, _screen and _backBuffer. + * If the surfaces already exist, they are cleared and re-initialized. * - * @param backBuffer Sets whether the _backBuffer surface should be initialized. - * @template PixelType C type which specifies the size of each pixel. - * Defaults to uint16 (2 BPP for the surfaces) + * @param backBuffer Sets whether the _backBuffer surface should be initialized. + * @template PixelType C type which specifies the size of each pixel. + * Defaults to uint16 (2 BPP for the surfaces) */ template void screenInit(bool backBuffer = true); /** - * Loads the given theme into the ThemeEngine. + * Loads the given theme into the ThemeEngine. * - * @param themeId Theme identifier. - * @returns true if the theme was successfully loaded. + * @param themeId Theme identifier. + * @returns true if the theme was successfully loaded. */ bool loadThemeXML(const Common::String &themeId); /** - * Loads the default theme file (the embedded XML file found - * in ThemeDefaultXML.cpp). - * Called only when no other themes are available. + * Loads the default theme file (the embedded XML file found + * in ThemeDefaultXML.cpp). + * Called only when no other themes are available. */ bool loadDefaultXML(); /** - * Unloads the currently loaded theme so another one can - * be loaded. + * Unloads the currently loaded theme so another one can + * be loaded. */ void unloadTheme(); const Graphics::Font *loadFont(const Common::String &filename); const Graphics::Font *loadFontFromArchive(const Common::String &filename); const Graphics::Font *loadCachedFontFromArchive(const Common::String &filename); - Common::String genCacheFilename(const char *filename); - Common::String genLocalizedFontFilename(const char *filename); + Common::String genCacheFilename(const Common::String &filename) const; + Common::String genLocalizedFontFilename(const Common::String &filename) const; /** - * Actual Dirty Screen handling function. - * Handles all the dirty squares in the list, merges and optimizes - * them when possible and draws them to the screen. - * Called from updateScreen() + * Actual Dirty Screen handling function. + * Handles all the dirty squares in the list, merges and optimizes + * them when possible and draws them to the screen. + * Called from updateScreen() */ void renderDirtyScreen(); /** - * Generates a DrawQueue item and enqueues it so it's drawn to the screen - * when the drawing queue is processed. + * Generates a DrawQueue item and enqueues it so it's drawn to the screen + * when the drawing queue is processed. * - * If Buffering is enabled, the DrawQueue item will be automatically placed - * on its corresponding queue. - * If Buffering is disabled, the DrawQueue item will be processed immediately - * and drawn to the screen. + * If Buffering is enabled, the DrawQueue item will be automatically placed + * on its corresponding queue. + * If Buffering is disabled, the DrawQueue item will be processed immediately + * and drawn to the screen. * - * This function is called from all the Widget Drawing methods. + * This function is called from all the Widget Drawing methods. */ void queueDD(DrawData type, const Common::Rect &r, uint32 dynamic = 0, bool restore = false); void queueDDText(TextData type, TextColor color, const Common::Rect &r, const Common::String &text, bool restoreBg, - bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0); + bool elipsis, Graphics::TextAlign alignH = Graphics::kTextAlignLeft, TextAlignVertical alignV = kTextAlignVTop, int deltax = 0); void queueBitmap(const Graphics::Surface *bitmap, const Common::Rect &r, bool alpha); /** - * DEBUG: Draws a white square and writes some text next to it. + * DEBUG: Draws a white square and writes some text next to it. */ void debugWidgetPosition(const char *name, const Common::Rect &r); @@ -603,7 +603,7 @@ protected: Graphics::Surface _backBuffer; /** Sets whether the current drawing is being buffered (stored for later - processing) or drawn directly to the screen. */ + processing) or drawn directly to the screen. */ bool _buffering; /** Bytes per pixel of the Active Drawing Surface (i.e. the screen) */ @@ -643,7 +643,7 @@ protected: /** Queue with all the drawing that must be done to the screen */ Common::List _screenQueue; - bool _initOk; ///< Class and renderer properly initialized + bool _initOk; ///< Class and renderer properly initialized bool _themeOk; ///< Theme data successfully loaded. bool _enabled; ///< Whether the Theme is currently shown on the overlay @@ -661,7 +661,7 @@ protected: byte *_cursor; bool _needPaletteUpdates; uint _cursorWidth, _cursorHeight; - byte _cursorPal[4*MAX_CURS_COLORS]; + byte _cursorPal[3 * MAX_CURS_COLORS]; byte _cursorPalSize; }; diff --git a/gui/ThemeParser.cpp b/gui/ThemeParser.cpp index d46ef60e877..2bca63956be 100644 --- a/gui/ThemeParser.cpp +++ b/gui/ThemeParser.cpp @@ -26,7 +26,7 @@ #include "gui/ThemeEngine.h" #include "gui/ThemeEval.h" #include "gui/ThemeParser.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "graphics/VectorRenderer.h" @@ -144,7 +144,7 @@ Graphics::DrawStep *ThemeParser::defaultDrawStep() { Graphics::DrawStep *ThemeParser::newDrawStep() { assert(_defaultStepGlobal); - Graphics::DrawStep *step = 0 ; //new DrawStep; + Graphics::DrawStep *step = 0; //new DrawStep; if (_defaultStepLocal) { step = new Graphics::DrawStep(*_defaultStepLocal); @@ -195,7 +195,7 @@ bool ThemeParser::parserCallback_text_color(ParserNode *node) { if (_palette.contains(node->values["color"])) getPaletteColor(node->values["color"], red, green, blue); - else if (!parseIntegerKey(node->values["color"].c_str(), 3, &red, &green, &blue)) + else if (!parseIntegerKey(node->values["color"], 3, &red, &green, &blue)) return parserError("Error parsing color value for text color definition."); if (!_theme->addTextColor(colorId, red, green, blue)) @@ -216,10 +216,10 @@ bool ThemeParser::parserCallback_cursor(ParserNode *node) { int spotx, spoty, scale; - if (!parseIntegerKey(node->values["hotspot"].c_str(), 2, &spotx, &spoty)) + if (!parseIntegerKey(node->values["hotspot"], 2, &spotx, &spoty)) return parserError("Error parsing cursor Hot Spot coordinates."); - if (!parseIntegerKey(node->values["scale"].c_str(), 1, &scale)) + if (!parseIntegerKey(node->values["scale"], 1, &scale)) return parserError("Error parsing cursor scale."); if (!_theme->createCursor(node->values["file"], spotx, spoty, scale)) @@ -286,7 +286,7 @@ bool ThemeParser::parserCallback_color(ParserNode *node) { int red, green, blue; - if (parseIntegerKey(node->values["rgb"].c_str(), 3, &red, &green, &blue) == false || + if (parseIntegerKey(node->values["rgb"], 3, &red, &green, &blue) == false || red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) return parserError("Error parsing RGB values for palette color '%s'", name.c_str());\ @@ -387,7 +387,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst */ #define __PARSER_ASSIGN_INT(struct_name, key_name, force) \ if (stepNode->values.contains(key_name)) { \ - if (!parseIntegerKey(stepNode->values[key_name].c_str(), 1, &x)) \ + if (!parseIntegerKey(stepNode->values[key_name], 1, &x)) \ return parserError("Error parsing key value for '%s'.", key_name); \ \ drawstep->struct_name = x; \ @@ -411,7 +411,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst red = _palette[val].r; \ green = _palette[val].g; \ blue = _palette[val].b; \ - } else if (parseIntegerKey(val.c_str(), 3, &red, &green, &blue) == false || \ + } else if (parseIntegerKey(val, 3, &red, &green, &blue) == false || \ red < 0 || red > 255 || green < 0 || green > 255 || blue < 0 || blue > 255) \ return parserError("Error parsing color struct '%s'", val.c_str());\ \ @@ -481,7 +481,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst drawstep->autoWidth = false; val = stepNode->values["width"]; - if (parseIntegerKey(val.c_str(), 1, &x)) + if (parseIntegerKey(val, 1, &x)) drawstep->w = x; else if (val == "height") drawstep->w = -1; @@ -490,7 +490,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst if (stepNode->values.contains("xpos")) { val = stepNode->values["xpos"]; - if (parseIntegerKey(val.c_str(), 1, &x)) + if (parseIntegerKey(val, 1, &x)) drawstep->x = x; else if (val == "center") drawstep->xAlign = Graphics::DrawStep::kVectorAlignCenter; @@ -509,7 +509,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst drawstep->autoHeight = false; val = stepNode->values["height"]; - if (parseIntegerKey(val.c_str(), 1, &x)) + if (parseIntegerKey(val, 1, &x)) drawstep->h = x; else if (val == "width") drawstep->h = -1; @@ -518,7 +518,7 @@ bool ThemeParser::parseDrawStep(ParserNode *stepNode, Graphics::DrawStep *drawst if (stepNode->values.contains("ypos")) { val = stepNode->values["ypos"]; - if (parseIntegerKey(val.c_str(), 1, &x)) + if (parseIntegerKey(val, 1, &x)) drawstep->y = x; else if (val == "center") drawstep->yAlign = Graphics::DrawStep::kVectorAlignCenter; @@ -569,7 +569,7 @@ bool ThemeParser::parserCallback_def(ParserNode *node) { if (_theme->getEvaluator()->hasVar(node->values["value"]) == true) value = _theme->getEvaluator()->getVar(node->values["value"]); - else if (!parseIntegerKey(node->values["value"].c_str(), 1, &value)) + else if (!parseIntegerKey(node->values["value"], 1, &value)) return parserError("Invalid definition for '%s'.", var.c_str()); _theme->getEvaluator()->setVar(var, value); @@ -608,7 +608,7 @@ bool ThemeParser::parserCallback_widget(ParserNode *node) { if (_theme->getEvaluator()->hasVar(node->values["width"]) == true) width = _theme->getEvaluator()->getVar(node->values["width"]); - else if (!parseIntegerKey(node->values["width"].c_str(), 1, &width)) + else if (!parseIntegerKey(node->values["width"], 1, &width)) return parserError("Corrupted width value in key for %s", var.c_str()); } @@ -616,7 +616,7 @@ bool ThemeParser::parserCallback_widget(ParserNode *node) { if (_theme->getEvaluator()->hasVar(node->values["height"]) == true) height = _theme->getEvaluator()->getVar(node->values["height"]); - else if (!parseIntegerKey(node->values["height"].c_str(), 1, &height)) + else if (!parseIntegerKey(node->values["height"], 1, &height)) return parserError("Corrupted height value in key for %s", var.c_str()); } @@ -651,7 +651,7 @@ bool ThemeParser::parserCallback_dialog(ParserNode *node) { } if (node->values.contains("inset")) { - if (!parseIntegerKey(node->values["inset"].c_str(), 1, &inset)) + if (!parseIntegerKey(node->values["inset"], 1, &inset)) return false; } @@ -682,7 +682,7 @@ bool ThemeParser::parserCallback_layout(ParserNode *node) { int spacing = -1; if (node->values.contains("spacing")) { - if (!parseIntegerKey(node->values["spacing"].c_str(), 1, &spacing)) + if (!parseIntegerKey(node->values["spacing"], 1, &spacing)) return false; } @@ -697,7 +697,7 @@ bool ThemeParser::parserCallback_layout(ParserNode *node) { if (node->values.contains("padding")) { int paddingL, paddingR, paddingT, paddingB; - if (!parseIntegerKey(node->values["padding"].c_str(), 4, &paddingL, &paddingR, &paddingT, &paddingB)) + if (!parseIntegerKey(node->values["padding"], 4, &paddingL, &paddingR, &paddingT, &paddingB)) return false; _theme->getEvaluator()->addPadding(paddingL, paddingR, paddingT, paddingB); @@ -713,7 +713,7 @@ bool ThemeParser::parserCallback_space(ParserNode *node) { if (_theme->getEvaluator()->hasVar(node->values["size"])) size = _theme->getEvaluator()->getVar(node->values["size"]); - else if (!parseIntegerKey(node->values["size"].c_str(), 1, &size)) + else if (!parseIntegerKey(node->values["size"], 1, &size)) return parserError("Invalid value for Spacing size."); } @@ -734,7 +734,7 @@ bool ThemeParser::parseCommonLayoutProps(ParserNode *node, const Common::String if (node->values.contains("size")) { int width, height; - if (!parseIntegerKey(node->values["size"].c_str(), 2, &width, &height)) { + if (!parseIntegerKey(node->values["size"], 2, &width, &height)) { Common::StringTokenizer tokenizer(node->values["size"], " ,"); Common::String wtoken, htoken; char *parseEnd; @@ -779,7 +779,7 @@ bool ThemeParser::parseCommonLayoutProps(ParserNode *node, const Common::String if (node->values.contains("pos")) { int x, y; - if (!parseIntegerKey(node->values["pos"].c_str(), 2, &x, &y)) { + if (!parseIntegerKey(node->values["pos"], 2, &x, &y)) { Common::StringTokenizer tokenizer(node->values["pos"], " ,"); Common::String xpos, ypos; char *parseEnd; @@ -835,7 +835,7 @@ bool ThemeParser::parseCommonLayoutProps(ParserNode *node, const Common::String if (node->values.contains("padding")) { int paddingL, paddingR, paddingT, paddingB; - if (!parseIntegerKey(node->values["padding"].c_str(), 4, &paddingL, &paddingR, &paddingT, &paddingB)) + if (!parseIntegerKey(node->values["padding"], 4, &paddingL, &paddingR, &paddingT, &paddingB)) return false; _theme->getEvaluator()->setVar(var + "Padding.Left", paddingL); @@ -861,30 +861,50 @@ bool ThemeParser::resolutionCheck(const Common::String &resolution) { return true; Common::StringTokenizer globTokenizer(resolution, ", "); - Common::String cur, w, h; - bool definedRes = false; + Common::String cur; while (!globTokenizer.empty()) { - bool ignore = false; cur = globTokenizer.nextToken(); - if (cur[0] == '-') { - ignore = true; - cur.deleteChar(0); - } else { - definedRes = true; + bool lt; + int val; + + if (cur.size() < 5) { + warning("Invalid theme 'resolution' token '%s'", resolution.c_str()); + return false; } - Common::StringTokenizer resTokenizer(cur, "x"); - w = resTokenizer.nextToken(); - h = resTokenizer.nextToken(); + if (cur[0] == 'x') { + val = g_system->getOverlayWidth(); + } else if (cur[0] == 'y') { + val = g_system->getOverlayHeight(); + } else { + warning("Error parsing theme 'resolution' token '%s'", resolution.c_str()); + return false; + } - if ((w == "X" || atoi(w.c_str()) == g_system->getOverlayWidth()) && - (h == "Y" || atoi(h.c_str()) == g_system->getOverlayHeight())) - return !ignore; + if (cur[1] == '<') { + lt = true; + } else if (cur[1] == '>') { + lt = false; + } else { + warning("Error parsing theme 'resolution' token '%s'", resolution.c_str()); + return false; + } + + int token = atoi(cur.c_str() + 2); + + // check inverse for unfulfilled requirements + if (lt) { + if (val >= token) + return false; + } else { + if (val <= token) + return false; + } } - return !definedRes; + return true; } } // End of namespace GUI diff --git a/gui/Tooltip.cpp b/gui/Tooltip.cpp index 5e6f9798812..00991e0a914 100644 --- a/gui/Tooltip.cpp +++ b/gui/Tooltip.cpp @@ -26,7 +26,7 @@ #include "graphics/fontman.h" #include "gui/widget.h" #include "gui/dialog.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/Tooltip.h" #include "gui/ThemeEval.h" @@ -34,47 +34,27 @@ namespace GUI { -Tooltip::Tooltip() : +Tooltip::Tooltip() : Dialog(-1, -1, -1, -1), _maxWidth(-1) { _backgroundType = GUI::ThemeEngine::kDialogBackgroundTooltip; } -void Tooltip::mustClose() { - if (isVisible()) - Dialog::close(); -} +void Tooltip::setup(Dialog *parent, Widget *widget, int x, int y) { + assert(widget->getTooltip()); -bool Tooltip::tooltipModal(int x, int y) { - Widget *wdg; - - if (!g_gui.getTopDialog()) - return false; - - wdg = g_gui.getTopDialog()->findWidget(x, y); - - if (!wdg || !wdg->getTooltip()) - return false; - - if (_maxWidth == -1) { - _maxWidth = g_gui.xmlEval()->getVar("Globals.Tooltip.MaxWidth", 100); - _xdelta = g_gui.xmlEval()->getVar("Globals.Tooltip.XDelta", 0); - _ydelta = g_gui.xmlEval()->getVar("Globals.Tooltip.YDelta", 0); - } + _maxWidth = g_gui.xmlEval()->getVar("Globals.Tooltip.MaxWidth", 100); + _xdelta = g_gui.xmlEval()->getVar("Globals.Tooltip.XDelta", 0); + _ydelta = g_gui.xmlEval()->getVar("Globals.Tooltip.YDelta", 0); const Graphics::Font *tooltipFont = g_gui.theme()->getFont(ThemeEngine::kFontStyleTooltip); _wrappedLines.clear(); - _w = tooltipFont->wordWrapText(wdg->getTooltip(), _maxWidth - 4, _wrappedLines); + _w = tooltipFont->wordWrapText(widget->getTooltip(), _maxWidth - 4, _wrappedLines); _h = (tooltipFont->getFontHeight() + 2) * _wrappedLines.size(); - _x = MIN(g_gui.getTopDialog()->_x + x + _xdelta, g_gui.getWidth() - _w - 3); - _y = MIN(g_gui.getTopDialog()->_y + y + _ydelta, g_gui.getHeight() - _h - 3); - - open(); - g_gui.runLoop(); - - return true; + _x = MIN(parent->_x + x + _xdelta, g_gui.getWidth() - _w - 3); + _y = MIN(parent->_y + y + _ydelta, g_gui.getHeight() - _h - 3); } void Tooltip::drawDialog() { @@ -85,14 +65,14 @@ void Tooltip::drawDialog() { for (Common::StringArray::const_iterator i = _wrappedLines.begin(); i != _wrappedLines.end(); ++i, ++num) { g_gui.theme()->drawText( - Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 +_w, _y + 1+ (num + 1) * h), *i, - ThemeEngine::kStateEnabled, - Graphics::kTextAlignLeft, - ThemeEngine::kTextInversionNone, + Common::Rect(_x + 1, _y + 1 + num * h, _x + 1 +_w, _y + 1+ (num + 1) * h), *i, + ThemeEngine::kStateEnabled, + Graphics::kTextAlignLeft, + ThemeEngine::kTextInversionNone, 0, - false, - ThemeEngine::kFontStyleTooltip, - ThemeEngine::kFontColorNormal, + false, + ThemeEngine::kFontStyleTooltip, + ThemeEngine::kFontColorNormal, false ); } diff --git a/gui/Tooltip.h b/gui/Tooltip.h index 9744c881721..e8221d74b9b 100644 --- a/gui/Tooltip.h +++ b/gui/Tooltip.h @@ -26,25 +26,31 @@ #define GUI_TOOLTIP_H #include "gui/dialog.h" +#include "gui/widget.h" namespace GUI { class Tooltip : public Dialog { public: Tooltip(); - ~Tooltip() {} - - void drawDialog(); - bool tooltipModal(int x, int y); - void mustClose(); + void setup(Dialog *parent, Widget *widget, int x, int y); + + void drawDialog(); protected: - Common::String _text; + virtual void handleMouseDown(int x, int y, int button, int clickCount) { close(); } + virtual void handleMouseUp(int x, int y, int button, int clickCount) { close(); } + virtual void handleMouseWheel(int x, int y, int direction) { close(); } + virtual void handleKeyDown(Common::KeyState state) { close(); } + virtual void handleKeyUp(Common::KeyState state) { close(); } + virtual void handleMouseMoved(int x, int y, int button) { close(); } + int _maxWidth; int _xdelta, _ydelta; Common::StringArray _wrappedLines; -}; -} +}; -#endif +} // End of namespace GUI + +#endif // GUI_TOOLTIP_H diff --git a/gui/about.cpp b/gui/about.cpp index b160becc085..3e59a0b99cc 100644 --- a/gui/about.cpp +++ b/gui/about.cpp @@ -30,7 +30,7 @@ #include "common/translation.h" #include "common/util.h" #include "gui/about.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/widget.h" #include "gui/ThemeEval.h" @@ -93,7 +93,7 @@ AboutDialog::AboutDialog() version += gResidualVersion; _lines.push_back(version); - Common::String date = Common::String::printf(_("(built on %s)"), gResidualBuildDate); + Common::String date = Common::String::format(_("(built on %s)"), gResidualBuildDate); _lines.push_back("C2" + date); for (i = 0; i < ARRAYSIZE(copyright_text); i++) diff --git a/gui/browser.cpp b/gui/browser.cpp index fb577a3d00c..35a499b79fe 100644 --- a/gui/browser.cpp +++ b/gui/browser.cpp @@ -23,8 +23,8 @@ */ #include "gui/browser.h" -#include "gui/GuiManager.h" -#include "gui/ListWidget.h" +#include "gui/gui-manager.h" +#include "gui/widgets/list.h" #include "common/config-manager.h" #include "common/system.h" diff --git a/gui/browser_osx.mm b/gui/browser_osx.mm index 9d258d8a74b..3a86efd7776 100644 --- a/gui/browser_osx.mm +++ b/gui/browser_osx.mm @@ -22,9 +22,10 @@ * $Id$ */ +// Disable symbol overrides so that we can use system headers +#define FORBIDDEN_SYMBOL_ALLOW_ALL + #include "gui/browser.h" -#include "gui/GuiManager.h" -#include "gui/ListWidget.h" #include "common/config-manager.h" #include "common/system.h" diff --git a/gui/chooser.cpp b/gui/chooser.cpp index e800c4264f1..de55d98fcb1 100644 --- a/gui/chooser.cpp +++ b/gui/chooser.cpp @@ -25,8 +25,8 @@ #include "common/system.h" #include "common/translation.h" #include "gui/chooser.h" -#include "gui/GuiManager.h" -#include "gui/ListWidget.h" +#include "gui/gui-manager.h" +#include "gui/widgets/list.h" namespace GUI { diff --git a/gui/console.cpp b/gui/console.cpp index a038b6c7f01..50f3cbd5ed8 100644 --- a/gui/console.cpp +++ b/gui/console.cpp @@ -23,8 +23,9 @@ */ #include "gui/console.h" -#include "gui/ScrollBarWidget.h" +#include "gui/widgets/scrollbar.h" #include "gui/ThemeEval.h" +#include "gui/gui-manager.h" #include "engines/engine.h" #include "base/version.h" @@ -487,7 +488,7 @@ void ConsoleDialog::defaultKeyDownHandler(Common::KeyState &state) { for (int i = _promptEndPos - 1; i >= _currentPos; i--) buffer(i + 1) = buffer(i); _promptEndPos++; - putchar((byte)state.ascii); + printChar((byte)state.ascii); scrollToCurrent(); } } @@ -498,7 +499,7 @@ void ConsoleDialog::insertIntoPrompt(const char* str) { buffer(i + l) = buffer(i); for (unsigned int j = 0; j < l; ++j) { _promptEndPos++; - putcharIntern(str[j]); + printCharIntern(str[j]); } } @@ -620,7 +621,7 @@ void ConsoleDialog::historyScroll(int direction) { else idx = _historyIndex; for (int i = 0; i < kLineBufferSize && _history[idx][i] != '\0'; i++) - putcharIntern(_history[idx][i]); + printCharIntern(_history[idx][i]); _promptEndPos = _currentPos; // Ensure once more the caret is visible (in case of very long history entries) @@ -659,38 +660,33 @@ void ConsoleDialog::updateScrollBuffer() { _scrollBar->recalc(); } -int ConsoleDialog::printf(const char *format, ...) { +int ConsoleDialog::printFormat(int dummy, const char *format, ...) { va_list argptr; va_start(argptr, format); - int count = this->vprintf(format, argptr); + int count = this->vprintFormat(dummy, format, argptr); va_end (argptr); return count; } -int ConsoleDialog::vprintf(const char *format, va_list argptr) { +int ConsoleDialog::vprintFormat(int dummy, const char *format, va_list argptr) { char buf[2048]; -#if defined(WIN32) - int count = _vsnprintf(buf, sizeof(buf), format, argptr); -#elif defined(__SYMBIAN32__) - int count = vsprintf(buf, format, argptr); -#else int count = vsnprintf(buf, sizeof(buf), format, argptr); -#endif + buf[sizeof(buf)-1] = 0; // ensure termination print(buf); return count; } -void ConsoleDialog::putchar(int c) { +void ConsoleDialog::printChar(int c) { if (_caretVisible) drawCaret(true); - putcharIntern(c); + printCharIntern(c); drawLine(pos2line(_currentPos)); } -void ConsoleDialog::putcharIntern(int c) { +void ConsoleDialog::printCharIntern(int c) { if (c == '\n') nextLine(); else { @@ -708,7 +704,7 @@ void ConsoleDialog::print(const char *str) { drawCaret(true); while (*str) - putcharIntern(*str++); + printCharIntern(*str++); draw(); } diff --git a/gui/console.h b/gui/console.h index 3754bf7e4f6..03c7aab8da9 100644 --- a/gui/console.h +++ b/gui/console.h @@ -26,7 +26,6 @@ #define CONSOLE_DIALOG_H #include "gui/dialog.h" -#include "gui/GuiManager.h" namespace GUI { @@ -143,10 +142,10 @@ public: void handleKeyDown(Common::KeyState state); void handleCommand(CommandSender *sender, uint32 cmd, uint32 data); - int printf(const char *format, ...) GCC_PRINTF(2, 3); - int vprintf(const char *format, va_list argptr); -#undef putchar - void putchar(int c); + int printFormat(int dummy, const char *format, ...) GCC_PRINTF(3, 4); + int vprintFormat(int dummy, const char *format, va_list argptr); + + void printChar(int c); void setInputCallback(InputCallbackProc proc, void *refCon) { _callbackProc = proc; @@ -172,7 +171,7 @@ protected: void drawLine(int line, bool restoreBg = true); void drawCaret(bool erase); - void putcharIntern(int c); + void printCharIntern(int c); void insertIntoPrompt(const char *str); void print(const char *str); void updateScrollBuffer(); diff --git a/gui/debugger.cpp b/gui/debugger.cpp index 3d415fccff8..31922775de3 100644 --- a/gui/debugger.cpp +++ b/gui/debugger.cpp @@ -23,10 +23,15 @@ * */ +// NB: This is really only necessary if USE_READLINE is defined +#define FORBIDDEN_SYMBOL_ALLOW_ALL + #include "common/debug.h" #include "common/debug-channels.h" #include "common/system.h" +#include "engines/engine.h" + #include "gui/debugger.h" #ifndef USE_TEXT_CONSOLE #include "gui/console.h" @@ -78,7 +83,7 @@ int Debugger::DebugPrintf(const char *format, ...) { va_start(argptr, format); int count; #ifndef USE_TEXT_CONSOLE - count = _debuggerDialog->vprintf(format, argptr); + count = _debuggerDialog->vprintFormat(1, format, argptr); #else count = ::vprintf(format, argptr); #endif @@ -86,6 +91,14 @@ int Debugger::DebugPrintf(const char *format, ...) { return count; } +void Debugger::preEnter() { + g_engine->pauseEngine(true); +} + +void Debugger::postEnter() { + g_engine->pauseEngine(false); +} + void Debugger::attach(const char *entry) { g_system->setFeatureState(OSystem::kFeatureVirtualKeyboard, true); diff --git a/gui/debugger.h b/gui/debugger.h index 64da4666f94..0352cfffebe 100644 --- a/gui/debugger.h +++ b/gui/debugger.h @@ -41,7 +41,7 @@ public: Debugger(); virtual ~Debugger(); - int DebugPrintf(const char *format, ...); + int DebugPrintf(const char *format, ...) GCC_PRINTF(2, 3); /** * The onFrame() method should be invoked by the engine at regular @@ -155,14 +155,18 @@ protected: /** * Hook for subclasses which is called just before enter() is run. * A typical usage example is pausing music and sound effects. + * + * The default implementation invokes Engine::pauseEngine(true). */ - virtual void preEnter() {} + virtual void preEnter(); /** * Hook for subclasses which is called just after enter() was run. * A typical usage example is resuming music and sound effects. + * + * The default implementation invokes Engine::pauseEngine(false). */ - virtual void postEnter() {} + virtual void postEnter(); /** * Subclasses should invoke the detach() method in their Cmd_FOO methods diff --git a/gui/dialog.cpp b/gui/dialog.cpp index 761fd5dde01..95ba0a7b022 100644 --- a/gui/dialog.cpp +++ b/gui/dialog.cpp @@ -24,10 +24,10 @@ #include "common/events.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/dialog.h" #include "gui/widget.h" -#include "gui/PopUpWidget.h" +#include "gui/widgets/popup.h" #include "common/system.h" diff --git a/gui/GuiManager.cpp b/gui/gui-manager.cpp similarity index 92% rename from gui/GuiManager.cpp rename to gui/gui-manager.cpp index 6903d4ff0bd..094d2ca8716 100644 --- a/gui/GuiManager.cpp +++ b/gui/gui-manager.cpp @@ -32,14 +32,15 @@ #include "backends/keymapper/keymapper.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/dialog.h" #include "gui/ThemeEngine.h" #include "gui/ThemeEval.h" +#include "gui/Tooltip.h" #include "graphics/cursorman.h" -DECLARE_SINGLETON(GUI::GuiManager) +DECLARE_SINGLETON(GUI::GuiManager); namespace GUI { @@ -50,8 +51,8 @@ enum { }; // Constructor -GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), _tooltipCheck(false), - _stateIsSaved(false), _cursorAnimateCounter(0), _cursorAnimateTimer(0) { +GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), _stateIsSaved(false), + _cursorAnimateCounter(0), _cursorAnimateTimer(0) { _theme = 0; _useStdCursor = false; @@ -62,9 +63,11 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), _tooltipCheck(false), // Clear the cursor memset(_cursor, 0xFF, sizeof(_cursor)); - + +#ifdef USE_TRANSLATION // Enable translation TransMan.setLanguage(ConfMan.get("gui_language").c_str()); +#endif // USE_TRANSLATION ConfMan.registerDefault("gui_theme", "modern"); Common::String themefile(ConfMan.get("gui_theme")); @@ -80,13 +83,10 @@ GuiManager::GuiManager() : _redrawStatus(kRedrawDisabled), _tooltipCheck(false), error("Failed to load any GUI theme, aborting"); } } - - _tooltip = 0; } GuiManager::~GuiManager() { delete _theme; - delete _tooltip; } #ifdef ENABLE_KEYMAPPER @@ -201,14 +201,15 @@ void GuiManager::redraw() { _theme->clearAll(); _theme->openDialog(true, ThemeEngine::kShadingNone); - for (i = 0; i < _dialogStack.size() - 1; i++) { + for (i = 0; i < _dialogStack.size() - 1; i++) _dialogStack[i]->drawDialog(); - } _theme->finishBuffering(); + // fall through + case kRedrawOpenDialog: - _theme->updateScreen(); + _theme->updateScreen(false); _theme->openDialog(true, shading); _dialogStack.top()->drawDialog(); _theme->finishBuffering(); @@ -229,7 +230,7 @@ Dialog *GuiManager::getTopDialog() const { } void GuiManager::runLoop() { - Dialog *activeDialog = getTopDialog(); + Dialog * const activeDialog = getTopDialog(); bool didSaveState = false; int button; uint32 time; @@ -269,6 +270,8 @@ void GuiManager::runLoop() { eventMan->getKeymapper()->pushKeymap("gui"); #endif + bool tooltipCheck = false; + while (!_dialogStack.empty() && activeDialog == getTopDialog()) { redraw(); @@ -290,9 +293,7 @@ void GuiManager::runLoop() { Common::Event event; - bool eventTookplace = false; while (eventMan->pollEvent(event)) { - // The top dialog can change during the event loop. In that case, flush all the // dialog-related events since they were probably generated while the old dialog // was still visible, and therefore not intended for the new one. @@ -304,20 +305,12 @@ void GuiManager::runLoop() { Common::Point mouse(event.mouse.x - activeDialog->_x, event.mouse.y - activeDialog->_y); - if (lastRedraw + waitTime < _system->getMillis()) { - _theme->updateScreen(); - _system->updateScreen(); - lastRedraw = _system->getMillis(); - } - switch (event.type) { case Common::EVENT_KEYDOWN: activeDialog->handleKeyDown(event.kbd); - eventTookplace = true; break; case Common::EVENT_KEYUP: activeDialog->handleKeyUp(event.kbd); - eventTookplace = true; break; case Common::EVENT_MOUSEMOVE: activeDialog->handleMouseMoved(mouse.x, mouse.y, 0); @@ -328,13 +321,11 @@ void GuiManager::runLoop() { _lastMousePosition.time = _system->getMillis(); } - _tooltipCheck = true; - eventTookplace = true; + tooltipCheck = true; break; // We don't distinguish between mousebuttons (for now at least) case Common::EVENT_LBUTTONDOWN: case Common::EVENT_RBUTTONDOWN: - eventTookplace = true; button = (event.type == Common::EVENT_LBUTTONDOWN ? 1 : 2); time = _system->getMillis(); if (_lastClick.count && (time < _lastClick.time + kDoubleClickDelay) @@ -351,39 +342,39 @@ void GuiManager::runLoop() { break; case Common::EVENT_LBUTTONUP: case Common::EVENT_RBUTTONUP: - eventTookplace = true; button = (event.type == Common::EVENT_LBUTTONUP ? 1 : 2); activeDialog->handleMouseUp(mouse.x, mouse.y, button, _lastClick.count); break; case Common::EVENT_WHEELUP: - eventTookplace = true; activeDialog->handleMouseWheel(mouse.x, mouse.y, -1); break; case Common::EVENT_WHEELDOWN: - eventTookplace = true; activeDialog->handleMouseWheel(mouse.x, mouse.y, 1); break; case Common::EVENT_QUIT: return; case Common::EVENT_SCREEN_CHANGED: - eventTookplace = true; screenChange(); break; default: break; } + + if (lastRedraw + waitTime < _system->getMillis()) { + _theme->updateScreen(); + _system->updateScreen(); + lastRedraw = _system->getMillis(); + } } - if (_tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { - if (_tooltip == 0) - _tooltip = new Tooltip(); - - _tooltipCheck = false; - _tooltip->tooltipModal(_lastMousePosition.x, _lastMousePosition.y); - } - - if (eventTookplace && _tooltip) { - _tooltip->mustClose(); + if (tooltipCheck && _lastMousePosition.time + kTooltipDelay < _system->getMillis()) { + Widget *wdg = activeDialog->findWidget(_lastMousePosition.x, _lastMousePosition.y); + if (wdg && wdg->getTooltip()) { + Tooltip *tooltip = new Tooltip(); + tooltip->setup(activeDialog, wdg, _lastMousePosition.x, _lastMousePosition.y); + tooltip->runModal(); + delete tooltip; + } } // Delay for a moment @@ -450,10 +441,10 @@ void GuiManager::closeTopDialog() { void GuiManager::setupCursor() { const byte palette[] = { - 255, 255, 255, 0, - 255, 255, 255, 0, - 171, 171, 171, 0, - 87, 87, 87, 0 + 255, 255, 255, + 255, 255, 255, + 171, 171, 171, + 87, 87, 87 }; CursorMan.pushCursorPalette(palette, 0, 4); diff --git a/gui/GuiManager.h b/gui/gui-manager.h similarity index 97% rename from gui/GuiManager.h rename to gui/gui-manager.h index d86d97a5b65..0c7f2035cb4 100644 --- a/gui/GuiManager.h +++ b/gui/gui-manager.h @@ -33,7 +33,6 @@ #include "graphics/font.h" #include "gui/widget.h" -#include "gui/Tooltip.h" #include "gui/ThemeEngine.h" class OSystem; @@ -61,7 +60,6 @@ typedef Common::FixedStack DialogStack; */ class GuiManager : public Common::Singleton { friend class Dialog; - friend class Tooltip; friend class Common::Singleton; GuiManager(); ~GuiManager(); @@ -117,9 +115,6 @@ protected: bool _useStdCursor; - Tooltip *_tooltip; - bool _tooltipCheck; - // position and time of last mouse click (used to detect double clicks) struct { int16 x, y; // Position of mouse when the click occurred diff --git a/gui/launcher.cpp b/gui/launcher.cpp index d73d357e086..227cc96e7df 100644 --- a/gui/launcher.cpp +++ b/gui/launcher.cpp @@ -38,18 +38,18 @@ #include "gui/launcher.h" #include "gui/massadd.h" #include "gui/message.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/options.h" #include "gui/saveload.h" -#include "gui/EditTextWidget.h" -#include "gui/ListWidget.h" -#include "gui/TabWidget.h" -#include "gui/PopUpWidget.h" +#include "gui/widgets/edittext.h" +#include "gui/widgets/list.h" +#include "gui/widgets/tab.h" +#include "gui/widgets/popup.h" #include "gui/ThemeEval.h" #include "graphics/cursorman.h" -#include "sound/mididrv.h" +#include "audio/mididrv.h" using Common::ConfigManager; @@ -188,8 +188,8 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc) // Language popup _langPopUpDesc = new StaticTextWidget(tab, "GameOptions_Game.LangPopupDesc", _("Language:"), _("Language of the game. This will not turn your Spanish game version into English")); _langPopUp = new PopUpWidget(tab, "GameOptions_Game.LangPopup", _("Language of the game. This will not turn your Spanish game version into English")); - _langPopUp->appendEntry(_(""), 0); - _langPopUp->appendEntry("", 0); + _langPopUp->appendEntry(_(""), (uint32)Common::UNK_LANG); + _langPopUp->appendEntry("", (uint32)Common::UNK_LANG); const Common::LanguageDescription *l = Common::g_languages; for (; l->code; ++l) { if (checkGameGUIOptionLanguage(l->id, _guioptionsString)) @@ -294,7 +294,7 @@ EditGameDialog::EditGameDialog(const String &domain, const String &desc) if (g_system->getOverlayWidth() > 320) new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _("Game Path:"), 0, kCmdGameBrowser); else - new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _c("Game Path:", "context"), 0, kCmdGameBrowser); + new ButtonWidget(tab, "GameOptions_Paths.Gamepath", _c("Game Path:", "lowres"), 0, kCmdGameBrowser); _gamePathWidget = new StaticTextWidget(tab, "GameOptions_Paths.GamepathText", gamePath); // GUI: Button + Label for the additional path @@ -341,7 +341,8 @@ void EditGameDialog::open() { e = ConfMan.hasKey("gfx_mode", _domain) || ConfMan.hasKey("render_mode", _domain) || ConfMan.hasKey("fullscreen", _domain) || - ConfMan.hasKey("aspect_ratio", _domain); + ConfMan.hasKey("aspect_ratio", _domain) || + ConfMan.hasKey("disable_dithering", _domain); _globalGraphicsOverride->setState(e); e = ConfMan.hasKey("music_driver", _domain) || @@ -371,6 +372,8 @@ void EditGameDialog::open() { if (ConfMan.hasKey("language", _domain)) { _langPopUp->setSelectedTag(lang); + } else { + _langPopUp->setSelectedTag((uint32)Common::UNK_LANG); } if (_langPopUp->numEntries() <= 3) { // If only one language is avaliable @@ -921,6 +924,7 @@ void LauncherDialog::loadGame(int item) { gameId = _domains[item]; const EnginePlugin *plugin = 0; + EngineMan.findGame(gameId, &plugin); String target = _domains[item]; @@ -929,7 +933,7 @@ void LauncherDialog::loadGame(int item) { if (plugin) { if ((*plugin)->hasFeature(MetaEngine::kSupportsListSaves) && (*plugin)->hasFeature(MetaEngine::kSupportsLoadingDuringStartup)) { - int slot = _loadDialog->runModal(plugin, target); + int slot = _loadDialog->runModalWithPluginAndTarget(plugin, target); if (slot >= 0) { ConfMan.setActiveDomain(_domains[item]); ConfMan.setInt("save_slot", slot, Common::ConfigManager::kTransientDomain); @@ -1053,7 +1057,7 @@ void LauncherDialog::updateButtons() { int modifiers = g_system->getEventManager()->getModifierState(); const bool massAdd = (modifiers & Common::KBD_SHIFT) != 0; const bool lowRes = g_system->getOverlayWidth() <= 320; - + const char *newAddButtonLabel = massAdd ? (lowRes ? _c("Mass Add...", "lowres") : _("Mass Add...")) : (lowRes ? _c("Add Game...", "lowres") : _("Add Game...")); diff --git a/gui/massadd.cpp b/gui/massadd.cpp index 7f95669b573..a39ac237668 100644 --- a/gui/massadd.cpp +++ b/gui/massadd.cpp @@ -31,9 +31,9 @@ #include "gui/launcher.h" // For addGameToConf() #include "gui/massadd.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/widget.h" -#include "gui/ListWidget.h" +#include "gui/widgets/list.h" namespace GUI { diff --git a/gui/message.cpp b/gui/message.cpp index 247d79c00d1..fbe9d91aaca 100644 --- a/gui/message.cpp +++ b/gui/message.cpp @@ -26,7 +26,7 @@ #include "common/str.h" #include "common/system.h" #include "gui/message.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/ThemeEval.h" #include "gui/widget.h" @@ -58,7 +58,11 @@ MessageDialog::MessageDialog(const Common::String &message, const char *defaultB int maxlineWidth = g_gui.getFont().wordWrapText(message, screenW - 2 * 20, lines); // Calculate the desired dialog size (maxing out at 300*180 for now) - _w = maxlineWidth + 20; + if (altButton) + _w = MAX(maxlineWidth, (2 * buttonWidth) + 10) + 20; + else + _w = MAX(maxlineWidth, buttonWidth) + 20; + lineCount = lines.size(); _h = 16; diff --git a/gui/module.mk b/gui/module.mk index 72b5fa18f38..df6b76172a7 100644 --- a/gui/module.mk +++ b/gui/module.mk @@ -6,27 +6,27 @@ MODULE_OBJS := \ console.o \ debugger.o \ dialog.o \ - editable.o \ error.o \ - EditTextWidget.o \ - GuiManager.o \ + gui-manager.o \ launcher.o \ - ListWidget.o \ massadd.o \ message.o \ object.o \ options.o \ - PopUpWidget.o \ saveload.o \ - ScrollBarWidget.o \ - TabWidget.o \ themebrowser.o \ ThemeEngine.o \ ThemeEval.o \ ThemeLayout.o \ ThemeParser.o \ Tooltip.o \ - widget.o + widget.o \ + widgets/editable.o \ + widgets/edittext.o \ + widgets/list.o \ + widgets/popup.o \ + widgets/scrollbar.o \ + widgets/tab.o ifdef MACOSX MODULE_OBJS += \ diff --git a/gui/object.cpp b/gui/object.cpp index 64aaf165445..a687fea7723 100644 --- a/gui/object.cpp +++ b/gui/object.cpp @@ -25,7 +25,7 @@ #include "common/system.h" #include "gui/object.h" #include "gui/widget.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/ThemeEval.h" namespace GUI { diff --git a/gui/options.cpp b/gui/options.cpp index 6403f025f56..ed26ec11ec7 100644 --- a/gui/options.cpp +++ b/gui/options.cpp @@ -26,11 +26,11 @@ #include "gui/themebrowser.h" #include "gui/chooser.h" #include "gui/message.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/ThemeEval.h" #include "gui/options.h" -#include "gui/PopUpWidget.h" -#include "gui/TabWidget.h" +#include "gui/widgets/popup.h" +#include "gui/widgets/tab.h" #include "common/fs.h" #include "common/config-manager.h" @@ -39,10 +39,10 @@ #include "graphics/scaler.h" -#include "sound/mididrv.h" -#include "sound/musicplugin.h" -#include "sound/mixer.h" -#include "sound/fmopl.h" +#include "audio/mididrv.h" +#include "audio/musicplugin.h" +#include "audio/mixer.h" +#include "audio/fmopl.h" namespace GUI { @@ -80,8 +80,6 @@ static const int savePeriodValues[] = { 0, 5 * 60, 10 * 60, 15 * 60, 30 * 60, -1 static const char *outputRateLabels[] = { _s(""), _s("8 kHz"), _s("11kHz"), _s("22 kHz"), _s("44 kHz"), _s("48 kHz"), 0 }; static const int outputRateValues[] = { 0, 8000, 11025, 22050, 44100, 48000, -1 }; - - OptionsDialog::OptionsDialog(const Common::String &domain, int x, int y, int w, int h) : Dialog(x, y, w, h), _domain(domain), _graphicsTabId(-1), _tabWidget(0) { init(); @@ -92,22 +90,40 @@ OptionsDialog::OptionsDialog(const Common::String &domain, const Common::String init(); } +OptionsDialog::~OptionsDialog() { + delete _subToggleGroup; +} + void OptionsDialog::init() { _enableGraphicSettings = false; _gfxPopUp = 0; + _gfxPopUpDesc = 0; _renderModePopUp = 0; + _renderModePopUpDesc = 0; _fullscreenCheckbox = 0; _aspectCheckbox = 0; + _disableDitheringCheckbox = 0; _enableAudioSettings = false; _midiPopUp = 0; + _midiPopUpDesc = 0; _oplPopUp = 0; + _oplPopUpDesc = 0; _outputRatePopUp = 0; + _outputRatePopUpDesc = 0; _enableMIDISettings = false; _gmDevicePopUp = 0; + _gmDevicePopUpDesc = 0; + _soundFont = 0; + _soundFontButton = 0; + _soundFontClearButton = 0; _multiMidiCheckbox = 0; + _midiGainDesc = 0; + _midiGainSlider = 0; + _midiGainLabel = 0; _enableMT32Settings = false; _mt32Checkbox = 0; _mt32DevicePopUp = 0; + _mt32DevicePopUpDesc = 0; _enableGSCheckbox = 0; _enableVolumeSettings = false; _musicVolumeDesc = 0; @@ -169,14 +185,8 @@ void OptionsDialog::open() { } if (_multiMidiCheckbox) { - if (!loadMusicDeviceSetting(_gmDevicePopUp, "gm_device")) { - if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { - if (!loadMusicDeviceSetting(_gmDevicePopUp, Common::String(), MT_GM)) - _gmDevicePopUp->setSelected(0); - } else { - _gmDevicePopUp->setSelected(0); - } - } + if (!loadMusicDeviceSetting(_gmDevicePopUp, "gm_device")) + _gmDevicePopUp->setSelected(0); // Multi midi setting _multiMidiCheckbox->setState(ConfMan.getBool("multi_midi", _domain)); @@ -200,14 +210,8 @@ void OptionsDialog::open() { // MT-32 options if (_mt32DevicePopUp) { - if (!loadMusicDeviceSetting(_mt32DevicePopUp, "mt32_device")) { - if (_domain.equals(Common::ConfigManager::kApplicationDomain)) { - if (!loadMusicDeviceSetting(_mt32DevicePopUp, Common::String(), MT_MT32)) - _mt32DevicePopUp->setSelected(0); - } else { - _mt32DevicePopUp->setSelected(0); - } - } + if (!loadMusicDeviceSetting(_mt32DevicePopUp, "mt32_device")) + _mt32DevicePopUp->setSelected(0); // Native mt32 setting _mt32Checkbox->setState(ConfMan.getBool("native_mt32", _domain)); @@ -484,7 +488,7 @@ void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &pref if (g_system->getOverlayWidth() > 320) _midiPopUpDesc = new StaticTextWidget(boss, prefix + "auMidiPopupDesc", _domain == Common::ConfigManager::kApplicationDomain ? _("Preferred Device:") : _("Music Device:"), _domain == Common::ConfigManager::kApplicationDomain ? _("Specifies preferred sound device or sound card emulator") : _("Specifies output sound device or sound card emulator")); else - _midiPopUpDesc = new StaticTextWidget(boss, prefix + "auMidiPopupDesc", _domain == Common::ConfigManager::kApplicationDomain ? _c("Preferred Device:", "lowres") : _c("Music Device:", "lowres"), _domain == Common::ConfigManager::kApplicationDomain ? _("Specifies preferred sound device or sound card emulator") : _("Specifies output sound device or sound card emulator")); + _midiPopUpDesc = new StaticTextWidget(boss, prefix + "auMidiPopupDesc", _domain == Common::ConfigManager::kApplicationDomain ? _c("Preferred Dev.:", "lowres") : _c("Music Device:", "lowres"), _domain == Common::ConfigManager::kApplicationDomain ? _("Specifies preferred sound device or sound card emulator") : _("Specifies output sound device or sound card emulator")); _midiPopUp = new PopUpWidget(boss, prefix + "auMidiPopup", _("Specifies output sound device or sound card emulator")); // Populate it @@ -497,7 +501,7 @@ void OptionsDialog::addAudioControls(GuiObject *boss, const Common::String &pref const uint32 deviceGuiOption = MidiDriver::musicType2GUIO(d->getMusicType()); if ((_domain == Common::ConfigManager::kApplicationDomain && d->getMusicType() != MT_TOWNS // global dialog - skip useless FM-Towns, C64, Amiga, AppleIIGS options there - && d->getMusicType() != MT_C64 && d->getMusicType() != MT_AMIGA && d->getMusicType() != MT_APPLEIIGS) + && d->getMusicType() != MT_C64 && d->getMusicType() != MT_AMIGA && d->getMusicType() != MT_APPLEIIGS && d->getMusicType() != MT_PC98) || (_domain != Common::ConfigManager::kApplicationDomain && !(_guioptions & allFlags)) // No flags are specified || (_guioptions & deviceGuiOption) // flag is present // HACK/FIXME: For now we have to show GM devices, even when the game only has GUIO_MIDIMT32 set, @@ -537,13 +541,25 @@ void OptionsDialog::addMIDIControls(GuiObject *boss, const Common::String &prefi // Populate const MusicPlugin::List p = MusicMan.getPlugins(); + // Make sure the null device is the first one in the list to avoid undesired + // auto detection for users who don't have a saved setting yet. for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { MusicDevices i = (**m)->getDevices(); for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { - if (d->getMusicType() >= MT_GM || d->getMusicDriverId() == "auto") { + if (d->getMusicDriverId() == "null") + _gmDevicePopUp->appendEntry(_("Don't use General MIDI music"), d->getHandle()); + } + } + // Now we add the other devices. + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getMusicType() >= MT_GM) { if (d->getMusicType() != MT_MT32) _gmDevicePopUp->appendEntry(d->getCompleteName(), d->getHandle()); - } + } else if (d->getMusicDriverId() == "auto") { + _gmDevicePopUp->appendEntry(_("Use first available device"), d->getHandle()); + } } } @@ -581,18 +597,29 @@ void OptionsDialog::addMT32Controls(GuiObject *boss, const Common::String &prefi if (g_system->getOverlayWidth() > 320) _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", _("True Roland MT-32 (disable GM emulation)"), _("Check if you want to use your real hardware Roland-compatible sound device connected to your computer")); else - _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", _c("True Roland MT-32 (disable GM emulation)", "lowres"), _("Check if you want to use your real hardware Roland-compatible sound device connected to your computer")); + _mt32Checkbox = new CheckboxWidget(boss, prefix + "mcMt32Checkbox", _c("True Roland MT-32 (no GM emulation)", "lowres"), _("Check if you want to use your real hardware Roland-compatible sound device connected to your computer")); // GS Extensions setting _enableGSCheckbox = new CheckboxWidget(boss, prefix + "mcGSCheckbox", _("Enable Roland GS Mode"), _("Turns off General MIDI mapping for games with Roland MT-32 soundtrack")); const MusicPlugin::List p = MusicMan.getPlugins(); + // Make sure the null device is the first one in the list to avoid undesired + // auto detection for users who don't have a saved setting yet. + for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { + MusicDevices i = (**m)->getDevices(); + for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { + if (d->getMusicDriverId() == "null") + _mt32DevicePopUp->appendEntry(_("Don't use Roland MT-32 music"), d->getHandle()); + } + } + // Now we add the other devices. for (MusicPlugin::List::const_iterator m = p.begin(); m != p.end(); ++m) { MusicDevices i = (**m)->getDevices(); for (MusicDevices::iterator d = i.begin(); d != i.end(); ++d) { - if (d->getMusicType() >= MT_GM || d->getMusicDriverId() == "auto") { + if (d->getMusicType() >= MT_GM) _mt32DevicePopUp->appendEntry(d->getCompleteName(), d->getHandle()); - } + else if (d->getMusicDriverId() == "auto") + _mt32DevicePopUp->appendEntry(_("Use first available device"), d->getHandle()); } } @@ -616,7 +643,7 @@ void OptionsDialog::addSubtitleControls(GuiObject *boss, const Common::String &p _subToggleSpeechOnly = new RadiobuttonWidget(boss, prefix + "subToggleSpeechOnly", _subToggleGroup, kSubtitlesSpeech, _("Speech")); _subToggleSubOnly = new RadiobuttonWidget(boss, prefix + "subToggleSubOnly", _subToggleGroup, kSubtitlesSubs, _("Subtitles")); _subToggleSubBoth = new RadiobuttonWidget(boss, prefix + "subToggleSubBoth", _subToggleGroup, kSubtitlesBoth, _("Both")); - + _subSpeedDesc = new StaticTextWidget(boss, prefix + "subSubtitleSpeedDesc", _("Subtitle speed:")); } else { _subToggleDesc = new StaticTextWidget(boss, prefix + "subToggleDesc", _c("Text and Speech:", "lowres")); @@ -626,7 +653,7 @@ void OptionsDialog::addSubtitleControls(GuiObject *boss, const Common::String &p _subToggleSpeechOnly = new RadiobuttonWidget(boss, prefix + "subToggleSpeechOnly", _subToggleGroup, kSubtitlesSpeech, _("Spch"), _("Speech")); _subToggleSubOnly = new RadiobuttonWidget(boss, prefix + "subToggleSubOnly", _subToggleGroup, kSubtitlesSubs, _("Subs"), _("Subtitles")); _subToggleSubBoth = new RadiobuttonWidget(boss, prefix + "subToggleSubBoth", _subToggleGroup, kSubtitlesBoth, _c("Both", "lowres"), _("Show subtitles and play speech")); - + _subSpeedDesc = new StaticTextWidget(boss, prefix + "subSubtitleSpeedDesc", _c("Subtitle speed:", "lowres")); } @@ -810,10 +837,10 @@ GlobalOptionsDialog::GlobalOptionsDialog() _themePath = new StaticTextWidget(tab, "GlobalOptions_Paths.ThemePath", _c("None", "path")); if (g_system->getOverlayWidth() > 320) - new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _("Extra Path:"), _("Specifies path to additional data used by all games or ScummVM"), kChooseExtraDirCmd); + new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _("Extra Path:"), _("Specifies path to additional data used by all games or Residual"), kChooseExtraDirCmd); else - new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _c("Extra Path:", "lowres"), _("Specifies path to additional data used by all games or ScummVM"), kChooseExtraDirCmd); - _extraPath = new StaticTextWidget(tab, "GlobalOptions_Paths.ExtraPath", _c("None", "path"), _("Specifies path to additional data used by all games or ScummVM")); + new ButtonWidget(tab, "GlobalOptions_Paths.ExtraButton", _c("Extra Path:", "lowres"), _("Specifies path to additional data used by all games or Residual"), kChooseExtraDirCmd); + _extraPath = new StaticTextWidget(tab, "GlobalOptions_Paths.ExtraPath", _c("None", "path"), _("Specifies path to additional data used by all games or Residual")); #ifdef DYNAMIC_MODULES if (g_system->getOverlayWidth() > 320) @@ -865,7 +892,7 @@ GlobalOptionsDialog::GlobalOptionsDialog() #ifdef USE_TRANSLATION - _guiLanguagePopUpDesc = new StaticTextWidget(tab, "GlobalOptions_Misc.GuiLanguagePopupDesc", _("GUI Language:"), _("Language of ScummVM GUI")); + _guiLanguagePopUpDesc = new StaticTextWidget(tab, "GlobalOptions_Misc.GuiLanguagePopupDesc", _("GUI Language:"), _("Language of Residual GUI")); _guiLanguagePopUp = new PopUpWidget(tab, "GlobalOptions_Misc.GuiLanguagePopup"); #ifdef USE_DETECTLANG _guiLanguagePopUp->appendEntry(_(""), Common::kTranslationAutodetectId); @@ -1014,7 +1041,7 @@ void GlobalOptionsDialog::close() { // only become active *after* the options dialog has closed. g_gui.loadNewTheme(g_gui.theme()->getThemeId(), ThemeEngine::kGfxDisabled, true); #else - MessageDialog error(_("You have to restart ScummVM to take the effect.")); + MessageDialog error(_("You have to restart Residual to take the effect.")); error.runModal(); #endif } @@ -1097,9 +1124,12 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 Common::String theme = browser.getSelected(); // FIXME: Actually, any changes (including the theme change) should // only become active *after* the options dialog has closed. +#ifdef USE_TRANSLATION Common::String lang = TransMan.getCurrentLanguage(); +#endif Common::String oldTheme = g_gui.theme()->getThemeId(); if (g_gui.loadNewTheme(theme)) { +#ifdef USE_TRANSLATION // If the charset has changed, it means the font were not found for the // new theme. Since for the moment we do not support change of translation // language without restarting, we let the user know about this. @@ -1109,9 +1139,12 @@ void GlobalOptionsDialog::handleCommand(CommandSender *sender, uint32 cmd, uint3 MessageDialog error(_("The theme you selected does not support your current language. If you want to use this theme you need to switch to another language first.")); error.runModal(); } else { +#endif _curTheme->setLabel(g_gui.theme()->getThemeName()); ConfMan.set("gui_theme", theme); +#ifdef USE_TRANSLATION } +#endif } draw(); } diff --git a/gui/options.h b/gui/options.h index 114f090f3d5..a9abae8fcb2 100644 --- a/gui/options.h +++ b/gui/options.h @@ -26,9 +26,8 @@ #define OPTIONS_DIALOG_H #include "gui/dialog.h" -#include "gui/TabWidget.h" #include "common/str.h" -#include "sound/musicplugin.h" +#include "audio/musicplugin.h" #ifdef SMALL_SCREEN_DEVICE #include "gui/KeysDialog.h" @@ -42,11 +41,13 @@ class PopUpWidget; class SliderWidget; class StaticTextWidget; class ListWidget; +class TabWidget; class OptionsDialog : public Dialog { public: OptionsDialog(const Common::String &domain, int x, int y, int w, int h); OptionsDialog(const Common::String &domain, const Common::String &name); + ~OptionsDialog(); void init(); @@ -96,6 +97,7 @@ private: PopUpWidget *_gfxPopUp; CheckboxWidget *_fullscreenCheckbox; CheckboxWidget *_aspectCheckbox; + CheckboxWidget *_disableDitheringCheckbox; StaticTextWidget *_renderModePopUpDesc; PopUpWidget *_renderModePopUp; @@ -115,8 +117,6 @@ private: StaticTextWidget *_gmDevicePopUpDesc; PopUpWidget *_gmDevicePopUp; - - // // MIDI controls // diff --git a/gui/saveload.cpp b/gui/saveload.cpp index d3269f47550..3abb056bf17 100644 --- a/gui/saveload.cpp +++ b/gui/saveload.cpp @@ -25,10 +25,11 @@ #include "common/config-manager.h" #include "common/translation.h" -#include "gui/ListWidget.h" +#include "gui/widgets/list.h" #include "gui/message.h" #include "gui/saveload.h" #include "gui/ThemeEval.h" +#include "gui/gui-manager.h" #include "graphics/scaler.h" @@ -78,7 +79,7 @@ SaveLoadChooser::SaveLoadChooser(const String &title, const String &buttonLabel) SaveLoadChooser::~SaveLoadChooser() { } -int SaveLoadChooser::runModal(const EnginePlugin *plugin, const String &target) { +int SaveLoadChooser::runModalWithPluginAndTarget(const EnginePlugin *plugin, const String &target) { if (_gfxWidget) _gfxWidget->setGfx(0); diff --git a/gui/saveload.h b/gui/saveload.h index 3ded7e5aff8..f2a4e7770f0 100644 --- a/gui/saveload.h +++ b/gui/saveload.h @@ -33,7 +33,7 @@ namespace GUI { class ListWidget; class GraphicsWidget; -class SaveLoadChooser : public GUI::Dialog { +class SaveLoadChooser : GUI::Dialog { typedef Common::String String; typedef Common::Array StringArray; protected: @@ -66,7 +66,7 @@ public: virtual void handleCommand(GUI::CommandSender *sender, uint32 cmd, uint32 data); void setList(const StringArray& list); - int runModal(const EnginePlugin *plugin, const String &target); + int runModalWithPluginAndTarget(const EnginePlugin *plugin, const String &target); void open(); const Common::String &getResultString() const; diff --git a/gui/themebrowser.cpp b/gui/themebrowser.cpp index 9ac55b9af59..34a32703c65 100644 --- a/gui/themebrowser.cpp +++ b/gui/themebrowser.cpp @@ -23,8 +23,9 @@ */ #include "gui/themebrowser.h" -#include "gui/ListWidget.h" +#include "gui/widgets/list.h" #include "gui/widget.h" +#include "gui/gui-manager.h" #include "common/translation.h" diff --git a/gui/themes/default.inc b/gui/themes/default.inc index 46ac4a1365b..2716e6ca723 100644 --- a/gui/themes/default.inc +++ b/gui/themes/default.inc @@ -1,5 +1,795 @@ "" -" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " +" " " " " " " " @@ -177,6 +967,9 @@ " " +" " " " " " " " @@ -787,793 +1580,6 @@ " " " " " " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " -" " " " " " " " -" " " " -" " " " -" " diff --git a/gui/themes/fonts/clR6x12-iso-8859-2.bdf b/gui/themes/fonts/clR6x12-iso-8859-2.bdf new file mode 100644 index 00000000000..0fb20258781 --- /dev/null +++ b/gui/themes/fonts/clR6x12-iso-8859-2.bdf @@ -0,0 +1,4291 @@ +STARTFONT 2.1 +COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT! +COMMENT Generated with 'ucs2any clR6x12.bdf /usr/share/fonts/X11/util/map-ISO8859-2 ISO8859-2' +COMMENT from an ISO10646-1 encoded source BDF font. +COMMENT ucs2any by Ben Collver , 2003, based on +COMMENT ucs2any.pl by Markus Kuhn , 2000. +COMMENT $XConsortium: clR6x12.bdf,v 1.2 94/04/11 12:08:30 gildea Exp $ +COMMENT +COMMENT Copyright 1989 Dale Schumacher, dal@syntel.mn.org +COMMENT 399 Beacon Ave. +COMMENT St. Paul, MN 55104-3527 +COMMENT +COMMENT Permission to use, copy, modify, and distribute this software and +COMMENT its documentation for any purpose and without fee is hereby +COMMENT granted, provided that the above copyright notice appear in all +COMMENT copies and that both that copyright notice and this permission +COMMENT notice appear in supporting documentation, and that the name of +COMMENT Dale Schumacher not be used in advertising or publicity pertaining to +COMMENT distribution of the software without specific, written prior +COMMENT permission. Dale Schumacher makes no representations about the +COMMENT suitability of this software for any purpose. It is provided "as +COMMENT is" without express or implied warranty. +COMMENT +COMMENT +COMMENT Modified by Robert Brady, +COMMENT +FONT -Schumacher-Clean-Medium-R-Normal--12-120-75-75-C-60-ISO8859-2 +SIZE 12 75 75 +FONTBOUNDINGBOX 6 12 0 -3 +STARTPROPERTIES 21 +FONTNAME_REGISTRY "" +FOUNDRY "Schumacher" +FAMILY_NAME "Clean" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 12 +POINT_SIZE 120 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "C" +AVERAGE_WIDTH 60 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "2" +FONT_ASCENT 9 +FONT_DESCENT 3 +DEFAULT_CHAR 0 +COPYRIGHT "Copyright 1989 Dale Schumacher, 1999 Robert Brady." +CAP_HEIGHT 8 +X_HEIGHT 5 +ENDPROPERTIES +CHARS 223 +STARTCHAR defaultchar +ENCODING 0 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +A8 +00 +88 +00 +88 +00 +A8 +00 +00 +00 +ENDCHAR +STARTCHAR uni25C6 +ENCODING 1 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +20 +70 +F8 +70 +20 +00 +00 +00 +ENDCHAR +STARTCHAR shade +ENCODING 2 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +A8 +54 +A8 +54 +A8 +54 +A8 +54 +A8 +54 +A8 +54 +ENDCHAR +STARTCHAR uni2409 +ENCODING 3 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +A0 +A0 +E0 +A0 +BC +08 +08 +08 +08 +00 +00 +ENDCHAR +STARTCHAR uni240C +ENCODING 4 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +E0 +80 +C0 +9C +90 +1C +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR uni240D +ENCODING 5 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +60 +80 +80 +98 +74 +18 +14 +14 +00 +00 +00 +ENDCHAR +STARTCHAR uni240A +ENCODING 6 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +80 +80 +9C +F0 +18 +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR degree +ENCODING 7 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +48 +48 +30 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plusminus +ENCODING 8 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +20 +F8 +20 +20 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR uni2424 +ENCODING 9 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +A0 +E0 +E0 +E0 +B0 +10 +10 +10 +1C +00 +00 +00 +ENDCHAR +STARTCHAR uni240B +ENCODING 10 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +A0 +A0 +A0 +5C +48 +08 +08 +08 +00 +00 +00 +ENDCHAR +STARTCHAR SF040000 +ENCODING 11 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +E0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF030000 +ENCODING 12 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF010000 +ENCODING 13 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +3F +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF020000 +ENCODING 14 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +3F +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF050000 +ENCODING 15 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +FF +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni23BA +ENCODING 16 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +FC +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BB +ENCODING 17 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +FC +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF100000 +ENCODING 18 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +FC +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BC +ENCODING 19 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +FC +00 +00 +00 +ENDCHAR +STARTCHAR uni23BD +ENCODING 20 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +FC +ENDCHAR +STARTCHAR SF080000 +ENCODING 21 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +3F +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF090000 +ENCODING 22 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF070000 +ENCODING 23 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +FF +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF060000 +ENCODING 24 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +FF +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF110000 +ENCODING 25 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR lessequal +ENCODING 26 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +18 +60 +80 +60 +18 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR greaterequal +ENCODING 27 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +C0 +30 +08 +30 +C0 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR pi +ENCODING 28 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F8 +88 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR notequal +ENCODING 29 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +10 +10 +F8 +20 +F8 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR sterling +ENCODING 30 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +48 +40 +E0 +40 +40 +48 +B0 +00 +00 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 31 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +30 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 32 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +20 +20 +20 +20 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +50 +50 +F8 +50 +F8 +50 +50 +00 +00 +00 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +78 +A0 +70 +28 +F0 +20 +00 +00 +00 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +C0 +C8 +10 +20 +40 +98 +18 +00 +00 +00 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +80 +80 +40 +A8 +90 +68 +00 +00 +00 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +20 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +08 +10 +10 +20 +20 +20 +20 +20 +10 +10 +08 +00 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +40 +20 +20 +10 +10 +10 +10 +10 +20 +20 +40 +00 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +20 +A8 +70 +A8 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +20 +20 +F8 +20 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +30 +30 +20 +40 +00 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +F8 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +30 +30 +00 +00 +00 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +08 +08 +10 +10 +20 +20 +40 +40 +80 +80 +00 +00 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +98 +A8 +C8 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +30 +10 +10 +10 +10 +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +08 +10 +20 +40 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +08 +30 +08 +08 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +30 +30 +50 +50 +F8 +10 +38 +00 +00 +00 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +F8 +80 +80 +F0 +08 +08 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +40 +80 +F0 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +F8 +88 +08 +08 +10 +10 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +88 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +88 +88 +78 +08 +10 +60 +00 +00 +00 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +30 +30 +00 +00 +30 +30 +00 +00 +00 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +30 +30 +00 +00 +30 +30 +20 +40 +00 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +0C +30 +C0 +30 +0C +00 +00 +00 +00 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F8 +00 +F8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +C0 +30 +0C +30 +C0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +08 +10 +20 +20 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +B8 +B8 +B0 +80 +70 +00 +00 +00 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +50 +88 +88 +F8 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F0 +88 +88 +F0 +88 +88 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +80 +80 +80 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +E0 +90 +88 +88 +88 +90 +E0 +00 +00 +00 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +80 +00 +00 +00 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +80 +98 +88 +88 +78 +00 +00 +00 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +38 +08 +08 +08 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +90 +A0 +C0 +A0 +90 +88 +00 +00 +00 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +80 +80 +80 +80 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +D8 +A8 +A8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +C8 +C8 +A8 +98 +98 +88 +00 +00 +00 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F0 +88 +88 +F0 +80 +80 +80 +00 +00 +00 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +70 +18 +00 +00 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F0 +88 +88 +F0 +A0 +90 +88 +00 +00 +00 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +80 +70 +08 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +50 +50 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +A8 +A8 +D8 +88 +00 +00 +00 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +50 +20 +50 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +50 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +08 +10 +20 +40 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +38 +20 +20 +20 +20 +20 +20 +20 +20 +20 +38 +00 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +80 +80 +40 +40 +20 +20 +10 +10 +08 +08 +00 +00 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +70 +10 +10 +10 +10 +10 +10 +10 +10 +10 +70 +00 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +50 +88 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +FC +00 +00 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +80 +80 +F0 +88 +88 +88 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +80 +80 +80 +78 +00 +00 +00 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +08 +08 +08 +78 +88 +88 +88 +78 +00 +00 +00 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +80 +70 +00 +00 +00 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +38 +40 +40 +F0 +40 +40 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +88 +88 +88 +78 +08 +08 +70 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +80 +80 +F0 +88 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +00 +60 +20 +20 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +08 +08 +00 +38 +08 +08 +08 +08 +08 +08 +70 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +40 +40 +40 +48 +50 +60 +50 +48 +00 +00 +00 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +60 +20 +20 +20 +20 +20 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +D0 +A8 +A8 +A8 +88 +00 +00 +00 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +B0 +C8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +F0 +80 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +88 +88 +88 +78 +08 +08 +08 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +58 +60 +40 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +80 +70 +08 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +20 +70 +20 +20 +20 +18 +00 +00 +00 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +D8 +50 +50 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +A8 +A8 +A8 +50 +00 +00 +00 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +50 +20 +50 +88 +00 +00 +00 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +78 +08 +08 +70 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F8 +10 +20 +40 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +08 +10 +10 +10 +10 +20 +10 +10 +10 +10 +08 +00 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +40 +20 +20 +20 +20 +10 +20 +20 +20 +20 +40 +00 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +40 +A8 +10 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 160 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Aogonek +ENCODING 161 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +50 +88 +88 +F8 +88 +88 +10 +18 +00 +ENDCHAR +STARTCHAR breve +ENCODING 162 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +48 +30 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Lslash +ENCODING 163 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +40 +40 +60 +C0 +40 +40 +7C +00 +00 +00 +ENDCHAR +STARTCHAR currency +ENCODING 164 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +70 +50 +70 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Lcaron +ENCODING 165 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +80 +80 +80 +80 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Sacute +ENCODING 166 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +70 +80 +70 +08 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +30 +48 +40 +30 +48 +48 +48 +30 +08 +48 +30 +00 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Scaron +ENCODING 169 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +70 +80 +70 +08 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Scedilla +ENCODING 170 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +80 +70 +08 +88 +70 +20 +60 +00 +ENDCHAR +STARTCHAR Tcaron +ENCODING 171 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +F8 +20 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR Zacute +ENCODING 172 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +F8 +10 +20 +40 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR hyphen +ENCODING 173 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +78 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Zcaron +ENCODING 174 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +F8 +10 +20 +40 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Zdotaccent +ENCODING 175 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +00 +F8 +10 +20 +40 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +48 +48 +30 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR aogonek +ENCODING 177 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +88 +88 +98 +68 +10 +08 +00 +ENDCHAR +STARTCHAR ogonek +ENCODING 178 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +40 +30 +ENDCHAR +STARTCHAR lslash +ENCODING 179 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +60 +20 +20 +30 +60 +20 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR lcaron +ENCODING 181 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +20 +20 +20 +20 +20 +10 +00 +00 +00 +ENDCHAR +STARTCHAR sacute +ENCODING 182 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +78 +80 +70 +08 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR caron +ENCODING 183 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR cedilla +ENCODING 184 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +10 +20 +00 +ENDCHAR +STARTCHAR scaron +ENCODING 185 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +20 +00 +78 +80 +70 +08 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR scedilla +ENCODING 186 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +80 +70 +08 +F0 +20 +60 +00 +ENDCHAR +STARTCHAR tcaron +ENCODING 187 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +20 +20 +F8 +20 +20 +18 +00 +00 +00 +ENDCHAR +STARTCHAR zacute +ENCODING 188 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +F8 +10 +20 +40 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR hungarumlaut +ENCODING 189 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +48 +90 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR zcaron +ENCODING 190 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +20 +00 +F8 +10 +20 +40 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR zdotaccent +ENCODING 191 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +00 +F8 +10 +20 +40 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Racute +ENCODING 192 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +F0 +88 +F0 +A0 +90 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +70 +88 +88 +F8 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +50 +00 +70 +88 +88 +F8 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Abreve +ENCODING 195 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +88 +70 +00 +70 +88 +88 +F8 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +00 +70 +88 +88 +F8 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Lacute +ENCODING 197 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +40 +00 +80 +80 +80 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Cacute +ENCODING 198 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +70 +88 +88 +80 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +80 +80 +80 +88 +70 +20 +40 +00 +ENDCHAR +STARTCHAR Ccaron +ENCODING 200 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +70 +88 +88 +80 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +F8 +80 +F0 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Eogonek +ENCODING 202 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +F8 +80 +F0 +80 +80 +F8 +20 +10 +00 +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +00 +F8 +80 +F0 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Ecaron +ENCODING 204 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +F8 +80 +F0 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +F8 +20 +20 +20 +20 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +50 +00 +F8 +20 +20 +20 +20 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Dcaron +ENCODING 207 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +E0 +90 +88 +88 +90 +E0 +00 +00 +00 +ENDCHAR +STARTCHAR Dcroat +ENCODING 208 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +48 +44 +E4 +44 +48 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Nacute +ENCODING 209 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +88 +C8 +A8 +98 +98 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Ncaron +ENCODING 210 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +88 +C8 +A8 +98 +98 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +70 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +50 +00 +70 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Ohungarumlaut +ENCODING 213 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +48 +90 +00 +70 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +00 +70 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +50 +20 +50 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Rcaron +ENCODING 216 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +00 +F0 +88 +F0 +A0 +90 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Uring +ENCODING 217 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +50 +20 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Uhungarumlaut +ENCODING 219 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +48 +90 +00 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +00 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Yacute +ENCODING 221 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +88 +50 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR Tcommaaccent +ENCODING 222 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +10 +30 +00 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +48 +48 +D0 +50 +48 +48 +50 +00 +00 +00 +ENDCHAR +STARTCHAR racute +ENCODING 224 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +58 +60 +40 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +78 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +50 +00 +78 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR abreve +ENCODING 227 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +88 +70 +00 +78 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +50 +00 +78 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR lacute +ENCODING 229 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +20 +20 +20 +20 +20 +10 +00 +00 +00 +ENDCHAR +STARTCHAR cacute +ENCODING 230 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +78 +80 +80 +80 +78 +00 +00 +00 +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +80 +80 +80 +78 +20 +40 +00 +ENDCHAR +STARTCHAR ccaron +ENCODING 232 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +20 +00 +78 +80 +80 +80 +78 +00 +00 +00 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +70 +88 +F8 +80 +70 +00 +00 +00 +ENDCHAR +STARTCHAR eogonek +ENCODING 234 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +80 +70 +40 +20 +00 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +50 +00 +70 +88 +F8 +80 +70 +00 +00 +00 +ENDCHAR +STARTCHAR ecaron +ENCODING 236 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +20 +00 +70 +88 +F8 +80 +70 +00 +00 +00 +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +40 +00 +60 +20 +20 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +50 +00 +60 +20 +20 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR dcaron +ENCODING 239 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +50 +20 +08 +08 +78 +88 +88 +88 +78 +00 +00 +00 +ENDCHAR +STARTCHAR dcroat +ENCODING 240 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +38 +10 +70 +90 +90 +90 +70 +00 +00 +00 +ENDCHAR +STARTCHAR nacute +ENCODING 241 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +B0 +C8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR ncaron +ENCODING 242 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +20 +00 +B0 +C8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +50 +00 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR ohungarumlaut +ENCODING 245 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +48 +90 +00 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +50 +00 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +20 +00 +F8 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR rcaron +ENCODING 248 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +28 +10 +00 +58 +60 +40 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR uring +ENCODING 249 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +50 +20 +88 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +88 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR uhungarumlaut +ENCODING 251 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +48 +90 +00 +88 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +50 +00 +88 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +00 +88 +88 +88 +88 +78 +08 +08 +70 +ENDCHAR +STARTCHAR tcommaaccent +ENCODING 254 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +20 +F8 +20 +20 +20 +18 +10 +30 +00 +ENDCHAR +STARTCHAR dotaccent +ENCODING 255 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +ENDFONT diff --git a/gui/themes/fonts/clR6x12-iso-8859-7.bdf b/gui/themes/fonts/clR6x12-iso-8859-7.bdf new file mode 100644 index 00000000000..cd389bd660f --- /dev/null +++ b/gui/themes/fonts/clR6x12-iso-8859-7.bdf @@ -0,0 +1,4234 @@ +STARTFONT 2.1 +COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT! +COMMENT Generated with 'ucs2any clR6x12.bdf /usr/share/fonts/X11/util/map-ISO8859-7 ISO8859-7' +COMMENT from an ISO10646-1 encoded source BDF font. +COMMENT ucs2any by Ben Collver , 2003, based on +COMMENT ucs2any.pl by Markus Kuhn , 2000. +COMMENT $XConsortium: clR6x12.bdf,v 1.2 94/04/11 12:08:30 gildea Exp $ +COMMENT +COMMENT Copyright 1989 Dale Schumacher, dal@syntel.mn.org +COMMENT 399 Beacon Ave. +COMMENT St. Paul, MN 55104-3527 +COMMENT +COMMENT Permission to use, copy, modify, and distribute this software and +COMMENT its documentation for any purpose and without fee is hereby +COMMENT granted, provided that the above copyright notice appear in all +COMMENT copies and that both that copyright notice and this permission +COMMENT notice appear in supporting documentation, and that the name of +COMMENT Dale Schumacher not be used in advertising or publicity pertaining to +COMMENT distribution of the software without specific, written prior +COMMENT permission. Dale Schumacher makes no representations about the +COMMENT suitability of this software for any purpose. It is provided "as +COMMENT is" without express or implied warranty. +COMMENT +COMMENT +COMMENT Modified by Robert Brady, +COMMENT +FONT -Schumacher-Clean-Medium-R-Normal--12-120-75-75-C-60-ISO8859-7 +SIZE 12 75 75 +FONTBOUNDINGBOX 6 12 0 -3 +STARTPROPERTIES 21 +FONTNAME_REGISTRY "" +FOUNDRY "Schumacher" +FAMILY_NAME "Clean" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 12 +POINT_SIZE 120 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "C" +AVERAGE_WIDTH 60 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "7" +FONT_ASCENT 9 +FONT_DESCENT 3 +DEFAULT_CHAR 0 +COPYRIGHT "Copyright 1989 Dale Schumacher, 1999 Robert Brady." +CAP_HEIGHT 8 +X_HEIGHT 5 +ENDPROPERTIES +CHARS 220 +STARTCHAR defaultchar +ENCODING 0 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +A8 +00 +88 +00 +88 +00 +A8 +00 +00 +00 +ENDCHAR +STARTCHAR uni25C6 +ENCODING 1 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +20 +70 +F8 +70 +20 +00 +00 +00 +ENDCHAR +STARTCHAR shade +ENCODING 2 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +A8 +54 +A8 +54 +A8 +54 +A8 +54 +A8 +54 +A8 +54 +ENDCHAR +STARTCHAR uni2409 +ENCODING 3 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +A0 +A0 +E0 +A0 +BC +08 +08 +08 +08 +00 +00 +ENDCHAR +STARTCHAR uni240C +ENCODING 4 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +E0 +80 +C0 +9C +90 +1C +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR uni240D +ENCODING 5 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +60 +80 +80 +98 +74 +18 +14 +14 +00 +00 +00 +ENDCHAR +STARTCHAR uni240A +ENCODING 6 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +80 +80 +9C +F0 +18 +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR degree +ENCODING 7 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +48 +48 +30 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plusminus +ENCODING 8 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +20 +F8 +20 +20 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR uni2424 +ENCODING 9 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +A0 +E0 +E0 +E0 +B0 +10 +10 +10 +1C +00 +00 +00 +ENDCHAR +STARTCHAR uni240B +ENCODING 10 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +A0 +A0 +A0 +5C +48 +08 +08 +08 +00 +00 +00 +ENDCHAR +STARTCHAR SF040000 +ENCODING 11 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +E0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF030000 +ENCODING 12 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF010000 +ENCODING 13 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +3F +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF020000 +ENCODING 14 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +3F +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF050000 +ENCODING 15 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +FF +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni23BA +ENCODING 16 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +FC +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BB +ENCODING 17 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +FC +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF100000 +ENCODING 18 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +FC +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BC +ENCODING 19 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +FC +00 +00 +00 +ENDCHAR +STARTCHAR uni23BD +ENCODING 20 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +FC +ENDCHAR +STARTCHAR SF080000 +ENCODING 21 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +3F +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF090000 +ENCODING 22 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +E0 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF070000 +ENCODING 23 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +FF +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF060000 +ENCODING 24 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +FF +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF110000 +ENCODING 25 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR lessequal +ENCODING 26 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +18 +60 +80 +60 +18 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR greaterequal +ENCODING 27 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +C0 +30 +08 +30 +C0 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR pi +ENCODING 28 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F8 +88 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR notequal +ENCODING 29 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +10 +10 +F8 +20 +F8 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR sterling +ENCODING 30 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +48 +40 +E0 +40 +40 +48 +B0 +00 +00 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 31 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +30 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 32 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +20 +20 +20 +20 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +50 +50 +F8 +50 +F8 +50 +50 +00 +00 +00 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +78 +A0 +70 +28 +F0 +20 +00 +00 +00 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +C0 +C8 +10 +20 +40 +98 +18 +00 +00 +00 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +80 +80 +40 +A8 +90 +68 +00 +00 +00 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +20 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +08 +10 +10 +20 +20 +20 +20 +20 +10 +10 +08 +00 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +40 +20 +20 +10 +10 +10 +10 +10 +20 +20 +40 +00 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +20 +A8 +70 +A8 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +20 +20 +F8 +20 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +30 +30 +20 +40 +00 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +F8 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +30 +30 +00 +00 +00 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +08 +08 +10 +10 +20 +20 +40 +40 +80 +80 +00 +00 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +98 +A8 +C8 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +30 +10 +10 +10 +10 +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +08 +10 +20 +40 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +08 +30 +08 +08 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +30 +30 +50 +50 +F8 +10 +38 +00 +00 +00 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +F8 +80 +80 +F0 +08 +08 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +40 +80 +F0 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +F8 +88 +08 +08 +10 +10 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +88 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +88 +88 +78 +08 +10 +60 +00 +00 +00 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +30 +30 +00 +00 +30 +30 +00 +00 +00 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +30 +30 +00 +00 +30 +30 +20 +40 +00 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +0C +30 +C0 +30 +0C +00 +00 +00 +00 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F8 +00 +F8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +C0 +30 +0C +30 +C0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +88 +08 +10 +20 +20 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +B8 +B8 +B0 +80 +70 +00 +00 +00 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +50 +88 +88 +F8 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F0 +88 +88 +F0 +88 +88 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +80 +80 +80 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +E0 +90 +88 +88 +88 +90 +E0 +00 +00 +00 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +80 +00 +00 +00 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +80 +98 +88 +88 +78 +00 +00 +00 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +38 +08 +08 +08 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +90 +A0 +C0 +A0 +90 +88 +00 +00 +00 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +80 +80 +80 +80 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +D8 +A8 +A8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +C8 +C8 +A8 +98 +98 +88 +00 +00 +00 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F0 +88 +88 +F0 +80 +80 +80 +00 +00 +00 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +70 +18 +00 +00 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F0 +88 +88 +F0 +A0 +90 +88 +00 +00 +00 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +80 +70 +08 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +50 +50 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +A8 +A8 +D8 +88 +00 +00 +00 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +50 +20 +50 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +50 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +08 +10 +20 +40 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +38 +20 +20 +20 +20 +20 +20 +20 +20 +20 +38 +00 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +80 +80 +40 +40 +20 +20 +10 +10 +08 +08 +00 +00 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +70 +10 +10 +10 +10 +10 +10 +10 +10 +10 +70 +00 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +50 +88 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +FC +00 +00 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +10 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +80 +80 +F0 +88 +88 +88 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +80 +80 +80 +78 +00 +00 +00 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +08 +08 +08 +78 +88 +88 +88 +78 +00 +00 +00 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +70 +88 +F8 +80 +70 +00 +00 +00 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +38 +40 +40 +F0 +40 +40 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +88 +88 +88 +78 +08 +08 +70 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +80 +80 +F0 +88 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +00 +60 +20 +20 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +08 +08 +00 +38 +08 +08 +08 +08 +08 +08 +70 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +40 +40 +40 +48 +50 +60 +50 +48 +00 +00 +00 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +60 +20 +20 +20 +20 +20 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +D0 +A8 +A8 +A8 +88 +00 +00 +00 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +B0 +C8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F0 +88 +88 +88 +F0 +80 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +88 +88 +88 +78 +08 +08 +08 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +58 +60 +40 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +80 +70 +08 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +20 +70 +20 +20 +20 +18 +00 +00 +00 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +88 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +D8 +50 +50 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +A8 +A8 +A8 +50 +00 +00 +00 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +50 +20 +50 +88 +00 +00 +00 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +88 +88 +88 +78 +08 +08 +70 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F8 +10 +20 +40 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +08 +10 +10 +10 +10 +20 +10 +10 +10 +10 +08 +00 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +40 +20 +20 +20 +20 +10 +20 +20 +20 +20 +40 +00 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +40 +A8 +10 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 160 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quoteleft +ENCODING 161 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +10 +20 +30 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quoteright +ENCODING 162 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +10 +20 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR sterling +ENCODING 163 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +48 +40 +E0 +40 +40 +48 +B0 +00 +00 +00 +ENDCHAR +STARTCHAR Euro +ENCODING 164 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +30 +48 +E0 +40 +E0 +48 +30 +00 +00 +00 +ENDCHAR +STARTCHAR uni20AF +ENCODING 165 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +40 +E0 +50 +48 +48 +48 +E8 +D0 +00 +00 +00 +ENDCHAR +STARTCHAR brokenbar +ENCODING 166 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +20 +20 +00 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +30 +48 +40 +30 +48 +48 +48 +30 +08 +48 +30 +00 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR copyright +ENCODING 169 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +78 +84 +B4 +A4 +A4 +B4 +84 +78 +00 +00 +00 +ENDCHAR +STARTCHAR uni037A +ENCODING 170 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +20 +30 +ENDCHAR +STARTCHAR guillemotleft +ENCODING 171 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +28 +50 +A0 +50 +28 +00 +00 +00 +00 +ENDCHAR +STARTCHAR logicalnot +ENCODING 172 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +78 +08 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR hyphen +ENCODING 173 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +78 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii00208 +ENCODING 175 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +FC +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +30 +48 +48 +30 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plusminus +ENCODING 177 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +20 +F8 +20 +20 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR twosuperior +ENCODING 178 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +60 +10 +20 +40 +70 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR threesuperior +ENCODING 179 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +60 +10 +20 +10 +60 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR tonos +ENCODING 180 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +00 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dieresistonos +ENCODING 181 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +50 +00 +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Alphatonos +ENCODING 182 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +90 +28 +44 +44 +7C +44 +44 +00 +00 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 183 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +00 +00 +30 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Epsilontonos +ENCODING 184 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +BC +20 +20 +38 +20 +20 +3C +00 +00 +00 +ENDCHAR +STARTCHAR Etatonos +ENCODING 185 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +A4 +24 +24 +3C +24 +24 +24 +00 +00 +00 +ENDCHAR +STARTCHAR Iotatonos +ENCODING 186 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +B8 +10 +10 +10 +10 +10 +38 +00 +00 +00 +ENDCHAR +STARTCHAR guillemotright +ENCODING 187 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +A0 +50 +28 +50 +A0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Omicrontonos +ENCODING 188 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +98 +24 +24 +24 +24 +24 +18 +00 +00 +00 +ENDCHAR +STARTCHAR onehalf +ENCODING 189 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +40 +40 +40 +70 +08 +10 +20 +38 +00 +00 +00 +ENDCHAR +STARTCHAR Upsilontonos +ENCODING 190 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +A8 +28 +10 +10 +10 +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR Omegatonos +ENCODING 191 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +90 +28 +44 +44 +44 +28 +6C +00 +00 +00 +ENDCHAR +STARTCHAR iotadieresistonos +ENCODING 192 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +10 +20 +00 +50 +00 +60 +20 +28 +10 +00 +00 +00 +ENDCHAR +STARTCHAR Alpha +ENCODING 193 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +50 +88 +88 +F8 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Beta +ENCODING 194 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F0 +88 +88 +F0 +88 +88 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR Gamma +ENCODING 195 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +78 +40 +40 +40 +40 +40 +40 +00 +00 +00 +ENDCHAR +STARTCHAR Delta +ENCODING 196 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +50 +50 +50 +88 +88 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Epsilon +ENCODING 197 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +80 +80 +F0 +80 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Zeta +ENCODING 198 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +08 +10 +20 +40 +80 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Eta +ENCODING 199 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +88 +F8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Theta +ENCODING 200 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +88 +A8 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Iota +ENCODING 201 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Kappa +ENCODING 202 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +90 +A0 +C0 +A0 +90 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Lambda +ENCODING 203 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +20 +20 +50 +50 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Mu +ENCODING 204 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +D8 +A8 +A8 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Nu +ENCODING 205 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +C8 +C8 +A8 +98 +98 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Xi +ENCODING 206 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +00 +00 +70 +00 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Omicron +ENCODING 207 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +88 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Pi +ENCODING 208 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +88 +88 +88 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Rho +ENCODING 209 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F0 +88 +88 +F0 +80 +80 +80 +00 +00 +00 +ENDCHAR +STARTCHAR Sigma +ENCODING 211 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +40 +20 +10 +20 +40 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Tau +ENCODING 212 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +F8 +20 +20 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR Upsilon +ENCODING 213 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +50 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR Phi +ENCODING 214 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +70 +20 +70 +A8 +A8 +70 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Chi +ENCODING 215 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +88 +88 +50 +20 +50 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR Psi +ENCODING 216 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +A8 +A8 +A8 +70 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR Omega +ENCODING 217 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +88 +88 +88 +50 +D8 +00 +00 +00 +ENDCHAR +STARTCHAR Iotadieresis +ENCODING 218 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +00 +F8 +20 +20 +20 +20 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR Upsilondieresis +ENCODING 219 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +00 +88 +50 +20 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR alphatonos +ENCODING 220 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +00 +68 +98 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR epsilontonos +ENCODING 221 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +00 +70 +88 +60 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR etatonos +ENCODING 222 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +00 +B0 +C8 +88 +88 +88 +08 +08 +00 +ENDCHAR +STARTCHAR iotatonos +ENCODING 223 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +00 +60 +20 +20 +28 +10 +00 +00 +00 +ENDCHAR +STARTCHAR upsilondieresistonos +ENCODING 224 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +88 +00 +90 +88 +88 +90 +60 +00 +00 +00 +ENDCHAR +STARTCHAR alpha +ENCODING 225 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +68 +98 +88 +98 +68 +00 +00 +00 +ENDCHAR +STARTCHAR beta +ENCODING 226 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +70 +88 +88 +F0 +88 +88 +C8 +B0 +80 +00 +ENDCHAR +STARTCHAR gamma +ENCODING 227 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +44 +A8 +28 +10 +10 +10 +10 +00 +00 +00 +ENDCHAR +STARTCHAR delta +ENCODING 228 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +30 +48 +20 +10 +30 +48 +48 +48 +30 +00 +00 +00 +ENDCHAR +STARTCHAR epsilon +ENCODING 229 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +70 +88 +60 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR zeta +ENCODING 230 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +40 +38 +20 +40 +40 +40 +40 +38 +08 +30 +00 +ENDCHAR +STARTCHAR eta +ENCODING 231 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +B0 +C8 +88 +88 +88 +08 +08 +00 +ENDCHAR +STARTCHAR theta +ENCODING 232 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +30 +48 +48 +78 +48 +48 +30 +00 +00 +00 +ENDCHAR +STARTCHAR iota +ENCODING 233 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +60 +20 +20 +28 +10 +00 +00 +00 +ENDCHAR +STARTCHAR kappa +ENCODING 234 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +48 +50 +60 +50 +48 +00 +00 +00 +ENDCHAR +STARTCHAR lambda +ENCODING 235 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +40 +A0 +20 +20 +50 +50 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR mu +ENCODING 236 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +88 +88 +98 +E8 +80 +80 +00 +ENDCHAR +STARTCHAR nu +ENCODING 237 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +D8 +50 +50 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR xi +ENCODING 238 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +80 +70 +80 +80 +70 +80 +80 +70 +08 +30 +00 +ENDCHAR +STARTCHAR omicron +ENCODING 239 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR pi +ENCODING 240 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +F8 +88 +88 +88 +88 +00 +00 +00 +ENDCHAR +STARTCHAR rho +ENCODING 241 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +70 +88 +88 +88 +B0 +80 +80 +80 +ENDCHAR +STARTCHAR sigma1 +ENCODING 242 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +80 +70 +08 +70 +00 +00 +00 +ENDCHAR +STARTCHAR sigma +ENCODING 243 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +90 +90 +90 +60 +00 +00 +00 +ENDCHAR +STARTCHAR tau +ENCODING 244 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +78 +20 +20 +28 +10 +00 +00 +00 +ENDCHAR +STARTCHAR upsilon +ENCODING 245 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +90 +88 +88 +88 +90 +60 +00 +00 +00 +ENDCHAR +STARTCHAR phi +ENCODING 246 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +30 +A8 +A8 +A8 +70 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR chi +ENCODING 247 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +88 +50 +20 +50 +88 +00 +00 +00 +ENDCHAR +STARTCHAR psi +ENCODING 248 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +A8 +A8 +70 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR omega +ENCODING 249 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +00 +00 +50 +88 +A8 +A8 +50 +00 +00 +00 +ENDCHAR +STARTCHAR iotadieresis +ENCODING 250 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +00 +50 +00 +60 +20 +20 +28 +10 +00 +00 +00 +ENDCHAR +STARTCHAR upsilondieresis +ENCODING 251 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +50 +00 +90 +88 +88 +88 +90 +60 +00 +00 +00 +ENDCHAR +STARTCHAR omicrontonos +ENCODING 252 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +00 +70 +88 +88 +88 +70 +00 +00 +00 +ENDCHAR +STARTCHAR upsilontonos +ENCODING 253 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +20 +20 +00 +90 +88 +88 +88 +90 +60 +00 +00 +00 +ENDCHAR +STARTCHAR omegatonos +ENCODING 254 +SWIDTH 480 0 +DWIDTH 6 0 +BBX 6 12 0 -3 +BITMAP +00 +20 +20 +00 +50 +88 +A8 +A8 +50 +00 +00 +00 +ENDCHAR +ENDFONT diff --git a/gui/themes/fonts/fixed5x8-iso-8859-2.bdf b/gui/themes/fonts/fixed5x8-iso-8859-2.bdf new file mode 100644 index 00000000000..d4d66d932e2 --- /dev/null +++ b/gui/themes/fonts/fixed5x8-iso-8859-2.bdf @@ -0,0 +1,3382 @@ +STARTFONT 2.1 +COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT! +COMMENT Generated with 'ucs2any fixed5x8.bdf /usr/share/fonts/X11/util/map-ISO8859-2 ISO8859-2' +COMMENT from an ISO10646-1 encoded source BDF font. +COMMENT ucs2any by Ben Collver , 2003, based on +COMMENT ucs2any.pl by Markus Kuhn , 2000. +COMMENT Derived from 5x8.bdf,v 1.32 2006-01-05 20:03:17+00 mgk25 Rel + +COMMENT Send bug reports to Markus Kuhn +FONT -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-2 +SIZE 11 75 75 +FONTBOUNDINGBOX 5 8 0 -1 +STARTPROPERTIES 21 +FONTNAME_REGISTRY "" +FOUNDRY "Misc" +FAMILY_NAME "Fixed" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 8 +POINT_SIZE 80 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "C" +AVERAGE_WIDTH 50 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "2" +FONT_DESCENT 1 +FONT_ASCENT 7 +COPYRIGHT "Public domain font. Share and enjoy." +DEFAULT_CHAR 0 +CAP_HEIGHT 6 +X_HEIGHT 4 +ENDPROPERTIES +CHARS 223 +STARTCHAR defaultchar +ENCODING 0 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +10 +80 +10 +80 +50 +00 +ENDCHAR +STARTCHAR uni25C6 +ENCODING 1 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +F8 +70 +20 +00 +ENDCHAR +STARTCHAR shade +ENCODING 2 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A8 +50 +A8 +50 +A8 +50 +A8 +ENDCHAR +STARTCHAR uni2409 +ENCODING 3 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +A0 +E0 +A0 +A0 +70 +20 +20 +ENDCHAR +STARTCHAR uni240C +ENCODING 4 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +80 +C0 +B8 +A0 +30 +20 +20 +ENDCHAR +STARTCHAR uni240D +ENCODING 5 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +80 +80 +60 +30 +28 +30 +28 +ENDCHAR +STARTCHAR uni240A +ENCODING 6 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +80 +E0 +38 +20 +30 +20 +ENDCHAR +STARTCHAR degree +ENCODING 7 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plusminus +ENCODING 8 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +20 +00 +70 +00 +ENDCHAR +STARTCHAR uni2424 +ENCODING 9 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +D0 +B0 +90 +20 +20 +20 +38 +ENDCHAR +STARTCHAR uni240B +ENCODING 10 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +A0 +A0 +40 +38 +10 +10 +10 +ENDCHAR +STARTCHAR SF040000 +ENCODING 11 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +E0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF030000 +ENCODING 12 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF010000 +ENCODING 13 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF020000 +ENCODING 14 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF050000 +ENCODING 15 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni23BA +ENCODING 16 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BB +ENCODING 17 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F8 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF100000 +ENCODING 18 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BC +ENCODING 19 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +ENDCHAR +STARTCHAR uni23BD +ENCODING 20 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F8 +ENDCHAR +STARTCHAR SF080000 +ENCODING 21 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF090000 +ENCODING 22 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +E0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF070000 +ENCODING 23 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF060000 +ENCODING 24 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF110000 +ENCODING 25 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR lessequal +ENCODING 26 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +40 +20 +10 +70 +00 +ENDCHAR +STARTCHAR greaterequal +ENCODING 27 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +10 +20 +40 +70 +00 +ENDCHAR +STARTCHAR pi +ENCODING 28 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +50 +50 +50 +00 +ENDCHAR +STARTCHAR notequal +ENCODING 29 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +F0 +60 +F0 +40 +00 +ENDCHAR +STARTCHAR sterling +ENCODING 30 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +E0 +40 +50 +A0 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 31 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 32 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +20 +00 +20 +00 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +F8 +50 +F8 +50 +50 +00 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +70 +A0 +70 +28 +70 +20 +00 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +50 +20 +50 +10 +00 +00 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +A0 +A0 +40 +A0 +A0 +50 +00 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +40 +40 +40 +20 +00 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +20 +20 +20 +40 +00 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +90 +60 +F0 +60 +90 +00 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +20 +F8 +20 +20 +00 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +30 +20 +40 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +20 +70 +20 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +20 +40 +80 +80 +00 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +50 +50 +50 +20 +00 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +60 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +10 +60 +80 +F0 +00 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +20 +60 +10 +90 +60 +00 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +60 +A0 +F0 +20 +20 +00 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +10 +90 +60 +00 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +80 +E0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +20 +20 +40 +40 +00 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +70 +10 +60 +00 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +60 +60 +00 +60 +60 +00 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +30 +30 +00 +30 +20 +40 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +40 +40 +20 +10 +00 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +00 +F0 +00 +00 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +10 +10 +20 +40 +00 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +10 +20 +00 +20 +00 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +48 +98 +A8 +A8 +90 +40 +30 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +80 +90 +60 +00 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +80 +00 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +B0 +90 +60 +00 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +A0 +40 +00 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A0 +C0 +A0 +A0 +90 +00 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +80 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +F0 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +D0 +F0 +B0 +B0 +90 +00 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +80 +80 +00 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +D0 +B0 +60 +10 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +40 +20 +90 +60 +00 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +90 +60 +60 +00 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +F0 +F0 +90 +00 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +60 +60 +90 +90 +00 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +40 +40 +40 +40 +70 +00 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +40 +20 +10 +10 +00 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +10 +10 +10 +10 +70 +00 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F0 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +40 +40 +30 +00 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +40 +E0 +40 +40 +00 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +70 +10 +60 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +10 +10 +50 +20 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +D0 +A8 +A8 +A8 +00 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +70 +10 +10 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +D0 +80 +80 +00 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +E0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +50 +20 +00 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +60 +60 +90 +00 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +40 +20 +C0 +20 +40 +30 +00 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +C0 +20 +40 +30 +40 +20 +C0 +00 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 160 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Aogonek +ENCODING 161 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +F0 +90 +90 +30 +ENDCHAR +STARTCHAR breve +ENCODING 162 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +88 +70 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Lslash +ENCODING 163 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +60 +C0 +40 +40 +78 +00 +ENDCHAR +STARTCHAR currency +ENCODING 164 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +88 +70 +50 +70 +88 +00 +ENDCHAR +STARTCHAR Lcaron +ENCODING 165 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +80 +80 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR Sacute +ENCODING 166 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +70 +80 +60 +10 +E0 +00 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +80 +E0 +90 +70 +10 +E0 +00 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Scaron +ENCODING 169 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +70 +80 +60 +10 +E0 +00 +ENDCHAR +STARTCHAR Scedilla +ENCODING 170 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +40 +20 +90 +60 +20 +ENDCHAR +STARTCHAR Tcaron +ENCODING 171 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +70 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Zacute +ENCODING 172 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +F0 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR hyphen +ENCODING 173 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +00 +00 +00 +ENDCHAR +STARTCHAR Zcaron +ENCODING 174 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +F0 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR Zdotaccent +ENCODING 175 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +00 +F0 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR aogonek +ENCODING 177 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +70 +20 +ENDCHAR +STARTCHAR ogonek +ENCODING 178 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +40 +60 +ENDCHAR +STARTCHAR lslash +ENCODING 179 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +20 +30 +60 +20 +70 +00 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR lcaron +ENCODING 181 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +60 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR sacute +ENCODING 182 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR caron +ENCODING 183 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR cedilla +ENCODING 184 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +20 +40 +ENDCHAR +STARTCHAR scaron +ENCODING 185 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR scedilla +ENCODING 186 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +60 +10 +60 +20 +ENDCHAR +STARTCHAR tcaron +ENCODING 187 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +40 +40 +E0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR zacute +ENCODING 188 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR hungarumlaut +ENCODING 189 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR zcaron +ENCODING 190 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR zdotaccent +ENCODING 191 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR Racute +ENCODING 192 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +E0 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Abreve +ENCODING 195 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Lacute +ENCODING 197 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +80 +80 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR Cacute +ENCODING 198 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +80 +90 +60 +00 +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +80 +90 +60 +40 +ENDCHAR +STARTCHAR Ccaron +ENCODING 200 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +60 +90 +80 +90 +60 +00 +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Eogonek +ENCODING 202 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +20 +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Ecaron +ENCODING 204 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Dcaron +ENCODING 207 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +E0 +90 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR Dcroat +ENCODING 208 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +48 +E8 +48 +48 +70 +00 +ENDCHAR +STARTCHAR Nacute +ENCODING 209 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +90 +D0 +B0 +90 +90 +00 +ENDCHAR +STARTCHAR Ncaron +ENCODING 210 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +90 +D0 +B0 +90 +90 +00 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Ohungarumlaut +ENCODING 213 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +30 +48 +48 +48 +30 +00 +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +50 +20 +50 +00 +ENDCHAR +STARTCHAR Rcaron +ENCODING 216 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +E0 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR Uring +ENCODING 217 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +20 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Uhungarumlaut +ENCODING 219 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +48 +48 +48 +30 +00 +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Yacute +ENCODING 221 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Tcommaaccent +ENCODING 222 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +40 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +A0 +A0 +90 +A0 +00 +ENDCHAR +STARTCHAR racute +ENCODING 224 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +A0 +D0 +80 +80 +00 +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR abreve +ENCODING 227 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR lacute +ENCODING 229 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +60 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR cacute +ENCODING 230 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +30 +40 +40 +30 +00 +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +40 +40 +30 +20 +ENDCHAR +STARTCHAR ccaron +ENCODING 232 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +80 +80 +60 +00 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR eogonek +ENCODING 234 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +B0 +C0 +60 +20 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR ecaron +ENCODING 236 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR dcaron +ENCODING 239 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +50 +10 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR dcroat +ENCODING 240 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +20 +60 +A0 +60 +00 +ENDCHAR +STARTCHAR nacute +ENCODING 241 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR ncaron +ENCODING 242 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR ohungarumlaut +ENCODING 245 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +30 +48 +48 +30 +00 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +00 +70 +00 +20 +00 +ENDCHAR +STARTCHAR rcaron +ENCODING 248 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +A0 +D0 +80 +80 +00 +ENDCHAR +STARTCHAR uring +ENCODING 249 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +20 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR uhungarumlaut +ENCODING 251 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +48 +48 +48 +38 +00 +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR tcommaaccent +ENCODING 254 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +E0 +40 +50 +20 +40 +ENDCHAR +STARTCHAR dotaccent +ENCODING 255 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +ENDFONT diff --git a/gui/themes/fonts/fixed5x8-iso-8859-5.bdf b/gui/themes/fonts/fixed5x8-iso-8859-5.bdf index cdd7d29da1d..7d0a93cb392 100644 --- a/gui/themes/fonts/fixed5x8-iso-8859-5.bdf +++ b/gui/themes/fonts/fixed5x8-iso-8859-5.bdf @@ -8,7 +8,7 @@ COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT! COMMENT Generated with 'ucs2any.pl 5x8.bdf ../xcyr-2.3/tryfont/KOI8-C.TXT KOI8-C' COMMENT from an ISO10646-1 encoded source BDF font. COMMENT ucs2any.pl by Markus Kuhn , 1999. -COMMENT $Id: fixed5x8-iso-8859-5.bdf 50436 2010-06-28 12:16:53Z sev $ +COMMENT $Id$ COMMENT Send bug reports to Markus Kuhn COMMENT Changes 1999 by Serge Winitzki. COMMENT $XFree86$ diff --git a/gui/themes/fonts/fixed5x8-iso-8859-7.bdf b/gui/themes/fonts/fixed5x8-iso-8859-7.bdf new file mode 100644 index 00000000000..da1374a465c --- /dev/null +++ b/gui/themes/fonts/fixed5x8-iso-8859-7.bdf @@ -0,0 +1,3337 @@ +STARTFONT 2.1 +COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT! +COMMENT Generated with 'ucs2any fixed5x8.bdf /usr/share/fonts/X11/util/map-ISO8859-7 ISO8859-7' +COMMENT from an ISO10646-1 encoded source BDF font. +COMMENT ucs2any by Ben Collver , 2003, based on +COMMENT ucs2any.pl by Markus Kuhn , 2000. +COMMENT Derived from 5x8.bdf,v 1.32 2006-01-05 20:03:17+00 mgk25 Rel + +COMMENT Send bug reports to Markus Kuhn +FONT -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO8859-7 +SIZE 11 75 75 +FONTBOUNDINGBOX 5 8 0 -1 +STARTPROPERTIES 21 +FONTNAME_REGISTRY "" +FOUNDRY "Misc" +FAMILY_NAME "Fixed" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 8 +POINT_SIZE 80 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "C" +AVERAGE_WIDTH 50 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "7" +FONT_DESCENT 1 +FONT_ASCENT 7 +COPYRIGHT "Public domain font. Share and enjoy." +DEFAULT_CHAR 0 +CAP_HEIGHT 6 +X_HEIGHT 4 +ENDPROPERTIES +CHARS 220 +STARTCHAR defaultchar +ENCODING 0 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +10 +80 +10 +80 +50 +00 +ENDCHAR +STARTCHAR uni25C6 +ENCODING 1 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +F8 +70 +20 +00 +ENDCHAR +STARTCHAR shade +ENCODING 2 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A8 +50 +A8 +50 +A8 +50 +A8 +ENDCHAR +STARTCHAR uni2409 +ENCODING 3 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +A0 +E0 +A0 +A0 +70 +20 +20 +ENDCHAR +STARTCHAR uni240C +ENCODING 4 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +80 +C0 +B8 +A0 +30 +20 +20 +ENDCHAR +STARTCHAR uni240D +ENCODING 5 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +80 +80 +60 +30 +28 +30 +28 +ENDCHAR +STARTCHAR uni240A +ENCODING 6 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +80 +E0 +38 +20 +30 +20 +ENDCHAR +STARTCHAR degree +ENCODING 7 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plusminus +ENCODING 8 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +20 +00 +70 +00 +ENDCHAR +STARTCHAR uni2424 +ENCODING 9 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +D0 +B0 +90 +20 +20 +20 +38 +ENDCHAR +STARTCHAR uni240B +ENCODING 10 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +A0 +A0 +40 +38 +10 +10 +10 +ENDCHAR +STARTCHAR SF040000 +ENCODING 11 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +E0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF030000 +ENCODING 12 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF010000 +ENCODING 13 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF020000 +ENCODING 14 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF050000 +ENCODING 15 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni23BA +ENCODING 16 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BB +ENCODING 17 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F8 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF100000 +ENCODING 18 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BC +ENCODING 19 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +ENDCHAR +STARTCHAR uni23BD +ENCODING 20 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F8 +ENDCHAR +STARTCHAR SF080000 +ENCODING 21 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF090000 +ENCODING 22 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +E0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF070000 +ENCODING 23 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF060000 +ENCODING 24 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR SF110000 +ENCODING 25 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR lessequal +ENCODING 26 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +40 +20 +10 +70 +00 +ENDCHAR +STARTCHAR greaterequal +ENCODING 27 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +10 +20 +40 +70 +00 +ENDCHAR +STARTCHAR pi +ENCODING 28 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +50 +50 +50 +00 +ENDCHAR +STARTCHAR notequal +ENCODING 29 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +F0 +60 +F0 +40 +00 +ENDCHAR +STARTCHAR sterling +ENCODING 30 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +E0 +40 +50 +A0 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 31 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 32 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +20 +00 +20 +00 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +F8 +50 +F8 +50 +50 +00 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +70 +A0 +70 +28 +70 +20 +00 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +50 +20 +50 +10 +00 +00 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +A0 +A0 +40 +A0 +A0 +50 +00 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +40 +40 +40 +20 +00 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +20 +20 +20 +40 +00 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +90 +60 +F0 +60 +90 +00 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +20 +F8 +20 +20 +00 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +30 +20 +40 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +20 +70 +20 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +20 +40 +80 +80 +00 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +50 +50 +50 +20 +00 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +60 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +10 +60 +80 +F0 +00 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +20 +60 +10 +90 +60 +00 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +60 +A0 +F0 +20 +20 +00 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +10 +90 +60 +00 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +80 +E0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +20 +20 +40 +40 +00 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +70 +10 +60 +00 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +60 +60 +00 +60 +60 +00 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +30 +30 +00 +30 +20 +40 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +40 +40 +20 +10 +00 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +00 +F0 +00 +00 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +10 +10 +20 +40 +00 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +10 +20 +00 +20 +00 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +48 +98 +A8 +A8 +90 +40 +30 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +80 +90 +60 +00 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +80 +00 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +B0 +90 +60 +00 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +A0 +40 +00 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A0 +C0 +A0 +A0 +90 +00 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +80 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +F0 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +D0 +F0 +B0 +B0 +90 +00 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +80 +80 +00 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +D0 +B0 +60 +10 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +40 +20 +90 +60 +00 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +90 +60 +60 +00 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +F0 +F0 +90 +00 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +60 +60 +90 +90 +00 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +40 +40 +40 +40 +70 +00 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +40 +20 +10 +10 +00 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +10 +10 +10 +10 +70 +00 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F0 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +40 +40 +30 +00 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +40 +E0 +40 +40 +00 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +70 +10 +60 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +10 +10 +50 +20 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +D0 +A8 +A8 +A8 +00 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +70 +10 +10 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +D0 +80 +80 +00 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +E0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +50 +20 +00 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +60 +60 +90 +00 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +40 +20 +C0 +20 +40 +30 +00 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +C0 +20 +40 +30 +40 +20 +C0 +00 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 160 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quoteleft +ENCODING 161 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quoteright +ENCODING 162 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +20 +40 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR sterling +ENCODING 163 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +E0 +40 +50 +A0 +00 +ENDCHAR +STARTCHAR Euro +ENCODING 164 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +40 +E0 +40 +E0 +40 +30 +00 +ENDCHAR +STARTCHAR uni20AF +ENCODING 165 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +E0 +50 +50 +50 +D0 +E0 +00 +ENDCHAR +STARTCHAR brokenbar +ENCODING 166 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +00 +20 +20 +20 +00 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +80 +E0 +90 +70 +10 +E0 +00 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR copyright +ENCODING 169 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +A8 +C8 +C8 +A8 +70 +00 +ENDCHAR +STARTCHAR uni037A +ENCODING 170 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +40 +60 +ENDCHAR +STARTCHAR guillemotleft +ENCODING 171 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +A0 +50 +00 +00 +ENDCHAR +STARTCHAR logicalnot +ENCODING 172 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +10 +10 +00 +ENDCHAR +STARTCHAR hyphen +ENCODING 173 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +00 +00 +00 +ENDCHAR +STARTCHAR afii00208 +ENCODING 175 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plusminus +ENCODING 177 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +20 +00 +70 +00 +ENDCHAR +STARTCHAR twosuperior +ENCODING 178 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +10 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR threesuperior +ENCODING 179 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +10 +60 +10 +60 +00 +00 +00 +ENDCHAR +STARTCHAR tonos +ENCODING 180 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dieresistonos +ENCODING 181 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +50 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Alphatonos +ENCODING 182 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 183 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR Epsilontonos +ENCODING 184 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Etatonos +ENCODING 185 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +90 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Iotatonos +ENCODING 186 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR guillemotright +ENCODING 187 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +50 +A0 +00 +00 +ENDCHAR +STARTCHAR Omicrontonos +ENCODING 188 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR onehalf +ENCODING 189 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +A0 +D0 +10 +20 +70 +00 +ENDCHAR +STARTCHAR Upsilontonos +ENCODING 190 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Omegatonos +ENCODING 191 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +70 +88 +88 +50 +D8 +00 +ENDCHAR +STARTCHAR iotadieresistonos +ENCODING 192 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +A0 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR Alpha +ENCODING 193 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Beta +ENCODING 194 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR Gamma +ENCODING 195 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +80 +80 +80 +80 +00 +ENDCHAR +STARTCHAR Delta +ENCODING 196 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +50 +50 +88 +F8 +00 +ENDCHAR +STARTCHAR Epsilon +ENCODING 197 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR Zeta +ENCODING 198 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR Eta +ENCODING 199 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Theta +ENCODING 200 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +F0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Iota +ENCODING 201 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Kappa +ENCODING 202 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A0 +C0 +A0 +A0 +90 +00 +ENDCHAR +STARTCHAR Lambda +ENCODING 203 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +60 +90 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Mu +ENCODING 204 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +F0 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Nu +ENCODING 205 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +D0 +F0 +B0 +B0 +90 +00 +ENDCHAR +STARTCHAR Xi +ENCODING 206 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +00 +60 +00 +00 +F0 +00 +ENDCHAR +STARTCHAR Omicron +ENCODING 207 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Pi +ENCODING 208 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +90 +90 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Rho +ENCODING 209 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +80 +80 +00 +ENDCHAR +STARTCHAR Sigma +ENCODING 211 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +40 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR Tau +ENCODING 212 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Upsilon +ENCODING 213 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Phi +ENCODING 214 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A8 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR Chi +ENCODING 215 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +60 +60 +90 +90 +00 +ENDCHAR +STARTCHAR Psi +ENCODING 216 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A8 +A8 +70 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Omega +ENCODING 217 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +88 +88 +88 +50 +D8 +00 +ENDCHAR +STARTCHAR Iotadieresis +ENCODING 218 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +00 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Upsilondieresis +ENCODING 219 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +00 +50 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR alphatonos +ENCODING 220 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR epsilontonos +ENCODING 221 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +70 +E0 +80 +70 +00 +ENDCHAR +STARTCHAR etatonos +ENCODING 222 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +A0 +D0 +90 +90 +10 +ENDCHAR +STARTCHAR iotatonos +ENCODING 223 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR upsilondieresistonos +ENCODING 224 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +D0 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR alpha +ENCODING 225 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR beta +ENCODING 226 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +E0 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR gamma +ENCODING 227 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +50 +20 +20 +ENDCHAR +STARTCHAR delta +ENCODING 228 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +80 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR epsilon +ENCODING 229 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +E0 +80 +70 +00 +ENDCHAR +STARTCHAR zeta +ENCODING 230 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F0 +40 +80 +60 +10 +20 +ENDCHAR +STARTCHAR eta +ENCODING 231 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +D0 +90 +90 +10 +ENDCHAR +STARTCHAR theta +ENCODING 232 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +F0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR iota +ENCODING 233 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR kappa +ENCODING 234 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +E0 +A0 +90 +00 +ENDCHAR +STARTCHAR lambda +ENCODING 235 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +10 +70 +90 +90 +90 +00 +ENDCHAR +STARTCHAR mu +ENCODING 236 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR nu +ENCODING 237 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +20 +20 +00 +ENDCHAR +STARTCHAR xi +ENCODING 238 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +40 +60 +80 +60 +10 +60 +ENDCHAR +STARTCHAR omicron +ENCODING 239 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR pi +ENCODING 240 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +50 +50 +50 +00 +ENDCHAR +STARTCHAR rho +ENCODING 241 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR sigma1 +ENCODING 242 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +80 +60 +10 +60 +ENDCHAR +STARTCHAR sigma +ENCODING 243 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +60 +00 +ENDCHAR +STARTCHAR tau +ENCODING 244 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR upsilon +ENCODING 245 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR phi +ENCODING 246 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +B0 +A8 +A8 +70 +20 +ENDCHAR +STARTCHAR chi +ENCODING 247 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +20 +50 +50 +ENDCHAR +STARTCHAR psi +ENCODING 248 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR omega +ENCODING 249 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR iotadieresis +ENCODING 250 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +00 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR upsilondieresis +ENCODING 251 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR omicrontonos +ENCODING 252 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR upsilontonos +ENCODING 253 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR omegatonos +ENCODING 254 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +ENDFONT diff --git a/gui/themes/fonts/fixed5x8.bdf b/gui/themes/fonts/fixed5x8.bdf new file mode 100644 index 00000000000..be26040a6f8 --- /dev/null +++ b/gui/themes/fonts/fixed5x8.bdf @@ -0,0 +1,21422 @@ +STARTFONT 2.1 +COMMENT $Id$ +COMMENT Send bug reports to Markus Kuhn +FONT -Misc-Fixed-Medium-R-Normal--8-80-75-75-C-50-ISO10646-1 +SIZE 11 75 75 +FONTBOUNDINGBOX 5 8 0 -1 +STARTPROPERTIES 22 +FONTNAME_REGISTRY "" +FOUNDRY "Misc" +FAMILY_NAME "Fixed" +WEIGHT_NAME "Medium" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 8 +POINT_SIZE 80 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "C" +AVERAGE_WIDTH 50 +CHARSET_REGISTRY "ISO10646" +CHARSET_ENCODING "1" +FONT_DESCENT 1 +FONT_ASCENT 7 +COPYRIGHT "Public domain font. Share and enjoy." +DEFAULT_CHAR 0 +_XMBDFED_INFO "Edited with xmbdfed 4.5." +CAP_HEIGHT 6 +X_HEIGHT 4 +ENDPROPERTIES +CHARS 1426 +STARTCHAR char0 +ENCODING 0 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +10 +80 +10 +80 +50 +00 +ENDCHAR +STARTCHAR space +ENCODING 32 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +20 +00 +20 +00 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +F8 +50 +F8 +50 +50 +00 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +70 +A0 +70 +28 +70 +20 +00 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +50 +20 +50 +10 +00 +00 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +A0 +A0 +40 +A0 +A0 +50 +00 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +40 +40 +40 +20 +00 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +20 +20 +20 +40 +00 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +90 +60 +F0 +60 +90 +00 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +20 +F8 +20 +20 +00 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +30 +20 +40 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +20 +70 +20 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +20 +40 +80 +80 +00 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +50 +50 +50 +20 +00 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +60 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +10 +60 +80 +F0 +00 +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +20 +60 +10 +90 +60 +00 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +60 +A0 +F0 +20 +20 +00 +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +10 +90 +60 +00 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +80 +E0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +20 +20 +40 +40 +00 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +70 +10 +60 +00 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +60 +60 +00 +60 +60 +00 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +30 +30 +00 +30 +20 +40 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +40 +40 +20 +10 +00 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +00 +F0 +00 +00 +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +10 +10 +20 +40 +00 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +10 +20 +00 +20 +00 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +48 +98 +A8 +A8 +90 +40 +30 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +80 +90 +60 +00 +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +80 +00 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +B0 +90 +60 +00 +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +A0 +40 +00 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A0 +C0 +A0 +A0 +90 +00 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +80 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +F0 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +D0 +F0 +B0 +B0 +90 +00 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +80 +80 +00 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +D0 +B0 +60 +10 +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +40 +20 +90 +60 +00 +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +90 +60 +60 +00 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +F0 +F0 +90 +00 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +60 +60 +90 +90 +00 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +40 +40 +40 +40 +70 +00 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +40 +20 +10 +10 +00 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +10 +10 +10 +10 +70 +00 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F0 +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +40 +40 +30 +00 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +40 +E0 +40 +40 +00 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +70 +10 +60 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +10 +10 +50 +20 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +D0 +A8 +A8 +A8 +00 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +70 +10 +10 +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +D0 +80 +80 +00 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +E0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +50 +20 +00 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +60 +60 +90 +00 +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +40 +20 +C0 +20 +40 +30 +00 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +C0 +20 +40 +30 +40 +20 +C0 +00 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR space +ENCODING 160 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR exclamdown +ENCODING 161 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR cent +ENCODING 162 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +A0 +A0 +70 +20 +ENDCHAR +STARTCHAR sterling +ENCODING 163 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +E0 +40 +50 +A0 +00 +ENDCHAR +STARTCHAR currency +ENCODING 164 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +88 +70 +50 +70 +88 +00 +ENDCHAR +STARTCHAR yen +ENCODING 165 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +50 +F8 +20 +F8 +20 +00 +ENDCHAR +STARTCHAR brokenbar +ENCODING 166 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +00 +20 +20 +20 +00 +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +80 +E0 +90 +70 +10 +E0 +00 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR copyright +ENCODING 169 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +A8 +C8 +C8 +A8 +70 +00 +ENDCHAR +STARTCHAR ordfeminine +ENCODING 170 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +50 +30 +00 +70 +00 +00 +00 +ENDCHAR +STARTCHAR guillemotleft +ENCODING 171 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +A0 +50 +00 +00 +ENDCHAR +STARTCHAR logicalnot +ENCODING 172 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +10 +10 +00 +ENDCHAR +STARTCHAR hyphen +ENCODING 173 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +00 +00 +00 +ENDCHAR +STARTCHAR registered +ENCODING 174 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +E8 +D8 +E8 +D8 +70 +00 +ENDCHAR +STARTCHAR macron +ENCODING 175 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR plusminus +ENCODING 177 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +20 +00 +70 +00 +ENDCHAR +STARTCHAR twosuperior +ENCODING 178 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +10 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR threesuperior +ENCODING 179 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +10 +60 +10 +60 +00 +00 +00 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR mu +ENCODING 181 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR paragraph +ENCODING 182 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +78 +E8 +E8 +68 +28 +28 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 183 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR cedilla +ENCODING 184 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +20 +40 +ENDCHAR +STARTCHAR onesuperior +ENCODING 185 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +60 +20 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR ordmasculine +ENCODING 186 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +20 +00 +70 +00 +00 +00 +ENDCHAR +STARTCHAR guillemotright +ENCODING 187 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +50 +A0 +00 +00 +ENDCHAR +STARTCHAR onequarter +ENCODING 188 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +80 +A0 +60 +F0 +20 +00 +ENDCHAR +STARTCHAR onehalf +ENCODING 189 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +A0 +D0 +10 +20 +70 +00 +ENDCHAR +STARTCHAR threequarters +ENCODING 190 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +40 +80 +60 +A0 +F0 +20 +00 +ENDCHAR +STARTCHAR questiondown +ENCODING 191 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +20 +40 +50 +20 +00 +ENDCHAR +STARTCHAR Agrave +ENCODING 192 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Atilde +ENCODING 195 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Aring +ENCODING 197 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR AE +ENCODING 198 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +A0 +A0 +F0 +A0 +B0 +00 +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +80 +90 +60 +40 +ENDCHAR +STARTCHAR Egrave +ENCODING 200 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Ecircumflex +ENCODING 202 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Igrave +ENCODING 204 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Idieresis +ENCODING 207 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +00 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Eth +ENCODING 208 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +48 +E8 +48 +48 +70 +00 +ENDCHAR +STARTCHAR Ntilde +ENCODING 209 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +90 +D0 +B0 +90 +90 +00 +ENDCHAR +STARTCHAR Ograve +ENCODING 210 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Otilde +ENCODING 213 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +50 +20 +50 +00 +ENDCHAR +STARTCHAR Oslash +ENCODING 216 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +B0 +B0 +D0 +D0 +E0 +00 +ENDCHAR +STARTCHAR Ugrave +ENCODING 217 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Ucircumflex +ENCODING 219 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Yacute +ENCODING 221 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Thorn +ENCODING 222 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +E0 +90 +90 +E0 +80 +00 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +A0 +A0 +90 +A0 +00 +ENDCHAR +STARTCHAR agrave +ENCODING 224 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR atilde +ENCODING 227 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR aring +ENCODING 229 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +60 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR ae +ENCODING 230 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +68 +B0 +78 +00 +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +40 +40 +30 +20 +ENDCHAR +STARTCHAR egrave +ENCODING 232 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR ecircumflex +ENCODING 234 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR igrave +ENCODING 236 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR idieresis +ENCODING 239 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR eth +ENCODING 240 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +40 +A0 +10 +70 +90 +60 +00 +ENDCHAR +STARTCHAR ntilde +ENCODING 241 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +00 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR ograve +ENCODING 242 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR otilde +ENCODING 245 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +00 +70 +00 +20 +00 +ENDCHAR +STARTCHAR oslash +ENCODING 248 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +B0 +D0 +E0 +00 +ENDCHAR +STARTCHAR ugrave +ENCODING 249 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR ucircumflex +ENCODING 251 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR thorn +ENCODING 254 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +E0 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR ydieresis +ENCODING 255 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +00 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR Amacron +ENCODING 256 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +00 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR amacron +ENCODING 257 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR Abreve +ENCODING 258 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR abreve +ENCODING 259 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR Aogonek +ENCODING 260 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +F0 +90 +90 +30 +ENDCHAR +STARTCHAR aogonek +ENCODING 261 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +70 +20 +ENDCHAR +STARTCHAR Cacute +ENCODING 262 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +80 +90 +60 +00 +ENDCHAR +STARTCHAR cacute +ENCODING 263 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +30 +40 +40 +30 +00 +ENDCHAR +STARTCHAR Ccircumflex +ENCODING 264 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +60 +90 +80 +90 +60 +00 +ENDCHAR +STARTCHAR ccircumflex +ENCODING 265 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +60 +80 +80 +60 +00 +ENDCHAR +STARTCHAR Cdotaccent +ENCODING 266 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +00 +60 +90 +80 +90 +60 +00 +ENDCHAR +STARTCHAR cdotaccent +ENCODING 267 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +30 +40 +40 +30 +00 +ENDCHAR +STARTCHAR Ccaron +ENCODING 268 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +60 +90 +80 +90 +60 +00 +ENDCHAR +STARTCHAR ccaron +ENCODING 269 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +80 +80 +60 +00 +ENDCHAR +STARTCHAR Dcaron +ENCODING 270 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +E0 +90 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR dcaron +ENCODING 271 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +50 +10 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR Dcroat +ENCODING 272 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +48 +E8 +48 +48 +70 +00 +ENDCHAR +STARTCHAR dcroat +ENCODING 273 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +20 +60 +A0 +60 +00 +ENDCHAR +STARTCHAR Emacron +ENCODING 274 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +00 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR emacron +ENCODING 275 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR Ebreve +ENCODING 276 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR ebreve +ENCODING 277 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR Edotaccent +ENCODING 278 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +00 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR edotaccent +ENCODING 279 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR Eogonek +ENCODING 280 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +20 +ENDCHAR +STARTCHAR eogonek +ENCODING 281 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +B0 +C0 +60 +20 +ENDCHAR +STARTCHAR Ecaron +ENCODING 282 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR ecaron +ENCODING 283 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR Gcircumflex +ENCODING 284 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +70 +80 +B0 +90 +60 +00 +ENDCHAR +STARTCHAR gcircumflex +ENCODING 285 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +60 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Gbreve +ENCODING 286 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +70 +80 +B0 +90 +60 +00 +ENDCHAR +STARTCHAR gbreve +ENCODING 287 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Gdotaccent +ENCODING 288 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +00 +70 +80 +B0 +90 +60 +00 +ENDCHAR +STARTCHAR gdotaccent +ENCODING 289 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +00 +60 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Gcommaaccent +ENCODING 290 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +B0 +90 +60 +20 +ENDCHAR +STARTCHAR gcommaaccent +ENCODING 291 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +40 +00 +60 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Hcircumflex +ENCODING 292 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR hcircumflex +ENCODING 293 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +80 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Hbar +ENCODING 294 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +F8 +50 +70 +50 +50 +00 +ENDCHAR +STARTCHAR hbar +ENCODING 295 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +F0 +40 +70 +48 +48 +00 +ENDCHAR +STARTCHAR Itilde +ENCODING 296 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +E0 +40 +40 +40 +E0 +00 +ENDCHAR +STARTCHAR itilde +ENCODING 297 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +00 +C0 +40 +40 +E0 +00 +ENDCHAR +STARTCHAR Imacron +ENCODING 298 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +00 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR imacron +ENCODING 299 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Ibreve +ENCODING 300 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR ibreve +ENCODING 301 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Iogonek +ENCODING 302 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +70 +10 +ENDCHAR +STARTCHAR iogonek +ENCODING 303 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +60 +20 +20 +70 +10 +ENDCHAR +STARTCHAR Idotaccent +ENCODING 304 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR dotlessi +ENCODING 305 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR IJ +ENCODING 306 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +B0 +90 +90 +90 +D0 +A0 +00 +ENDCHAR +STARTCHAR ij +ENCODING 307 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +50 +50 +50 +20 +ENDCHAR +STARTCHAR Jcircumflex +ENCODING 308 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +70 +20 +20 +A0 +40 +00 +ENDCHAR +STARTCHAR jcircumflex +ENCODING 309 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +20 +20 +20 +A0 +40 +ENDCHAR +STARTCHAR Kcommaaccent +ENCODING 310 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +48 +50 +60 +50 +50 +48 +80 +ENDCHAR +STARTCHAR kcommaaccent +ENCODING 311 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +48 +70 +48 +48 +80 +ENDCHAR +STARTCHAR kgreenlandic +ENCODING 312 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +60 +50 +50 +00 +ENDCHAR +STARTCHAR Lacute +ENCODING 313 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +80 +80 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR lacute +ENCODING 314 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +60 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Lcommaaccent +ENCODING 315 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +80 +80 +80 +F0 +20 +ENDCHAR +STARTCHAR lcommaaccent +ENCODING 316 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +20 +20 +20 +20 +70 +20 +ENDCHAR +STARTCHAR Lcaron +ENCODING 317 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +80 +80 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR lcaron +ENCODING 318 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +60 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Ldot +ENCODING 319 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +A0 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR ldot +ENCODING 320 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +C0 +40 +50 +40 +40 +E0 +00 +ENDCHAR +STARTCHAR Lslash +ENCODING 321 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +60 +C0 +40 +40 +78 +00 +ENDCHAR +STARTCHAR lslash +ENCODING 322 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +20 +30 +60 +20 +70 +00 +ENDCHAR +STARTCHAR Nacute +ENCODING 323 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +90 +D0 +B0 +90 +90 +00 +ENDCHAR +STARTCHAR nacute +ENCODING 324 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Ncommaaccent +ENCODING 325 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +D0 +F0 +B0 +B0 +90 +40 +ENDCHAR +STARTCHAR ncommaaccent +ENCODING 326 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +90 +90 +40 +ENDCHAR +STARTCHAR Ncaron +ENCODING 327 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +90 +D0 +B0 +90 +90 +00 +ENDCHAR +STARTCHAR ncaron +ENCODING 328 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR napostrophe +ENCODING 329 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +C0 +40 +80 +30 +28 +28 +28 +00 +ENDCHAR +STARTCHAR Eng +ENCODING 330 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +D0 +F0 +B0 +B0 +90 +20 +ENDCHAR +STARTCHAR eng +ENCODING 331 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +90 +90 +20 +ENDCHAR +STARTCHAR Omacron +ENCODING 332 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +00 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR omacron +ENCODING 333 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Obreve +ENCODING 334 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR obreve +ENCODING 335 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Ohungarumlaut +ENCODING 336 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +30 +48 +48 +48 +30 +00 +ENDCHAR +STARTCHAR ohungarumlaut +ENCODING 337 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +30 +48 +48 +30 +00 +ENDCHAR +STARTCHAR OE +ENCODING 338 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +A0 +B0 +A0 +A0 +70 +00 +ENDCHAR +STARTCHAR oe +ENCODING 339 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +A8 +B0 +78 +00 +ENDCHAR +STARTCHAR Racute +ENCODING 340 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +E0 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR racute +ENCODING 341 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +A0 +D0 +80 +80 +00 +ENDCHAR +STARTCHAR Rcommaaccent +ENCODING 342 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +90 +90 +20 +ENDCHAR +STARTCHAR rcommaaccent +ENCODING 343 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +68 +40 +40 +80 +ENDCHAR +STARTCHAR Rcaron +ENCODING 344 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +E0 +90 +E0 +90 +90 +00 +ENDCHAR +STARTCHAR rcaron +ENCODING 345 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +A0 +D0 +80 +80 +00 +ENDCHAR +STARTCHAR Sacute +ENCODING 346 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +70 +80 +60 +10 +E0 +00 +ENDCHAR +STARTCHAR sacute +ENCODING 347 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR Scircumflex +ENCODING 348 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +70 +80 +60 +10 +E0 +00 +ENDCHAR +STARTCHAR scircumflex +ENCODING 349 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR Scedilla +ENCODING 350 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +40 +20 +90 +60 +20 +ENDCHAR +STARTCHAR scedilla +ENCODING 351 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +60 +10 +60 +20 +ENDCHAR +STARTCHAR Scaron +ENCODING 352 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +70 +80 +60 +10 +E0 +00 +ENDCHAR +STARTCHAR scaron +ENCODING 353 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR Tcommaaccent +ENCODING 354 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +40 +ENDCHAR +STARTCHAR tcommaaccent +ENCODING 355 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +E0 +40 +50 +20 +40 +ENDCHAR +STARTCHAR Tcaron +ENCODING 356 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +70 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR tcaron +ENCODING 357 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +40 +40 +E0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR Tbar +ENCODING 358 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +70 +20 +20 +20 +00 +ENDCHAR +STARTCHAR tbar +ENCODING 359 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +E0 +40 +E0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR Utilde +ENCODING 360 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR utilde +ENCODING 361 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR Umacron +ENCODING 362 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +00 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR umacron +ENCODING 363 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR Ubreve +ENCODING 364 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR ubreve +ENCODING 365 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR Uring +ENCODING 366 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +20 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR uring +ENCODING 367 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +20 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR Uhungarumlaut +ENCODING 368 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +48 +48 +48 +30 +00 +ENDCHAR +STARTCHAR uhungarumlaut +ENCODING 369 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +48 +48 +48 +38 +00 +ENDCHAR +STARTCHAR Uogonek +ENCODING 370 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +90 +90 +60 +20 +ENDCHAR +STARTCHAR uogonek +ENCODING 371 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +70 +20 +ENDCHAR +STARTCHAR Wcircumflex +ENCODING 372 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +00 +90 +90 +F0 +F0 +90 +00 +ENDCHAR +STARTCHAR wcircumflex +ENCODING 373 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR Ycircumflex +ENCODING 374 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +50 +50 +20 +20 +00 +ENDCHAR +STARTCHAR ycircumflex +ENCODING 375 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR Ydieresis +ENCODING 376 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +00 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Zacute +ENCODING 377 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +F0 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR zacute +ENCODING 378 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR Zdotaccent +ENCODING 379 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +00 +F0 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR zdotaccent +ENCODING 380 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR Zcaron +ENCODING 381 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +F0 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR zcaron +ENCODING 382 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +F0 +20 +40 +F0 +00 +ENDCHAR +STARTCHAR longs +ENCODING 383 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +40 +C0 +40 +40 +00 +ENDCHAR +STARTCHAR uni018F +ENCODING 399 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +10 +F0 +90 +60 +00 +ENDCHAR +STARTCHAR florin +ENCODING 402 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +28 +20 +70 +20 +A0 +40 +ENDCHAR +STARTCHAR Ohorn +ENCODING 416 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +68 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR ohorn +ENCODING 417 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +68 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Uhorn +ENCODING 431 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A8 +B0 +A0 +A0 +A0 +40 +00 +ENDCHAR +STARTCHAR uhorn +ENCODING 432 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +B0 +A0 +60 +00 +ENDCHAR +STARTCHAR uni01B5 +ENCODING 437 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +F0 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR uni01B6 +ENCODING 438 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +F0 +40 +F0 +00 +ENDCHAR +STARTCHAR uni01D1 +ENCODING 465 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR uni01D2 +ENCODING 466 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Gcaron +ENCODING 486 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +70 +80 +B0 +90 +70 +00 +ENDCHAR +STARTCHAR gcaron +ENCODING 487 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +60 +90 +70 +10 +60 +ENDCHAR +STARTCHAR Aringacute +ENCODING 506 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +60 +90 +60 +90 +F0 +90 +00 +ENDCHAR +STARTCHAR aringacute +ENCODING 507 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +60 +90 +60 +70 +90 +70 +00 +ENDCHAR +STARTCHAR AEacute +ENCODING 508 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +70 +A0 +F0 +A0 +B0 +00 +ENDCHAR +STARTCHAR aeacute +ENCODING 509 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +F0 +68 +B0 +78 +00 +ENDCHAR +STARTCHAR Oslashacute +ENCODING 510 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +70 +B0 +D0 +D0 +E0 +00 +ENDCHAR +STARTCHAR oslashacute +ENCODING 511 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +70 +B0 +D0 +E0 +00 +ENDCHAR +STARTCHAR Scommaaccent +ENCODING 536 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +40 +20 +90 +60 +20 +ENDCHAR +STARTCHAR scommaaccent +ENCODING 537 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +60 +10 +60 +20 +ENDCHAR +STARTCHAR Tcommaaccent +ENCODING 538 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +40 +ENDCHAR +STARTCHAR tcommaaccent +ENCODING 539 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +E0 +40 +50 +20 +40 +ENDCHAR +STARTCHAR uni0259 +ENCODING 601 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +30 +D0 +60 +00 +ENDCHAR +STARTCHAR uni02BB +ENCODING 699 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +60 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii57929 +ENCODING 700 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +20 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii64937 +ENCODING 701 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +40 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni02BE +ENCODING 702 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni02BF +ENCODING 703 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR circumflex +ENCODING 710 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR caron +ENCODING 711 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR macron +ENCODING 713 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR breve +ENCODING 728 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +88 +70 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dotaccent +ENCODING 729 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ring +ENCODING 730 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +20 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR ogonek +ENCODING 731 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +40 +60 +ENDCHAR +STARTCHAR tilde +ENCODING 732 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A0 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR hungarumlaut +ENCODING 733 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR gravecomb +ENCODING 768 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR acutecomb +ENCODING 769 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0302 +ENCODING 770 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR tildecomb +ENCODING 771 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0304 +ENCODING 772 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0305 +ENCODING 773 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0306 +ENCODING 774 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0307 +ENCODING 775 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0308 +ENCODING 776 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR hookabovecomb +ENCODING 777 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030A +ENCODING 778 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +60 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030B +ENCODING 779 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030C +ENCODING 780 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030D +ENCODING 781 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030E +ENCODING 782 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni030F +ENCODING 783 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +48 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0310 +ENCODING 784 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A8 +70 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0311 +ENCODING 785 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +90 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0312 +ENCODING 786 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0313 +ENCODING 787 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +20 +40 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0314 +ENCODING 788 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +40 +20 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0315 +ENCODING 789 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +18 +08 +10 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dotbelowcomb +ENCODING 803 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +20 +ENDCHAR +STARTCHAR uni0324 +ENCODING 804 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni0331 +ENCODING 817 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F0 +ENDCHAR +STARTCHAR uni0332 +ENCODING 818 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F8 +ENDCHAR +STARTCHAR uni0338 +ENCODING 824 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +20 +40 +40 +80 +00 +ENDCHAR +STARTCHAR uni0340 +ENCODING 832 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0341 +ENCODING 833 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0374 +ENCODING 884 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni0375 +ENCODING 885 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +20 +40 +ENDCHAR +STARTCHAR uni037A +ENCODING 890 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +40 +60 +ENDCHAR +STARTCHAR uni037E +ENCODING 894 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +30 +30 +00 +30 +20 +40 +ENDCHAR +STARTCHAR tonos +ENCODING 900 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dieresistonos +ENCODING 901 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +50 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Alphatonos +ENCODING 902 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR anoteleia +ENCODING 903 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR Epsilontonos +ENCODING 904 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +F0 +80 +E0 +80 +F0 +00 +ENDCHAR +STARTCHAR Etatonos +ENCODING 905 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +90 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Iotatonos +ENCODING 906 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Omicrontonos +ENCODING 908 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Upsilontonos +ENCODING 910 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Omegatonos +ENCODING 911 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +70 +88 +88 +50 +D8 +00 +ENDCHAR +STARTCHAR iotadieresistonos +ENCODING 912 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +A0 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR Alpha +ENCODING 913 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR Beta +ENCODING 914 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR Gamma +ENCODING 915 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +80 +80 +80 +80 +00 +ENDCHAR +STARTCHAR Delta +ENCODING 916 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +50 +50 +88 +F8 +00 +ENDCHAR +STARTCHAR Epsilon +ENCODING 917 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR Zeta +ENCODING 918 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR Eta +ENCODING 919 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Theta +ENCODING 920 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +F0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Iota +ENCODING 921 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Kappa +ENCODING 922 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A0 +C0 +A0 +A0 +90 +00 +ENDCHAR +STARTCHAR Lambda +ENCODING 923 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +60 +90 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Mu +ENCODING 924 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +F0 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Nu +ENCODING 925 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +D0 +F0 +B0 +B0 +90 +00 +ENDCHAR +STARTCHAR Xi +ENCODING 926 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +00 +60 +00 +00 +F0 +00 +ENDCHAR +STARTCHAR Omicron +ENCODING 927 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR Pi +ENCODING 928 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +90 +90 +90 +90 +90 +00 +ENDCHAR +STARTCHAR Rho +ENCODING 929 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +80 +80 +00 +ENDCHAR +STARTCHAR Sigma +ENCODING 931 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +40 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR Tau +ENCODING 932 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Upsilon +ENCODING 933 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Phi +ENCODING 934 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A8 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR Chi +ENCODING 935 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +60 +60 +90 +90 +00 +ENDCHAR +STARTCHAR Psi +ENCODING 936 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A8 +A8 +70 +20 +20 +20 +00 +ENDCHAR +STARTCHAR Omega +ENCODING 937 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +88 +88 +88 +50 +D8 +00 +ENDCHAR +STARTCHAR Iotadieresis +ENCODING 938 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +00 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR Upsilondieresis +ENCODING 939 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +00 +50 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR alphatonos +ENCODING 940 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR epsilontonos +ENCODING 941 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +70 +E0 +80 +70 +00 +ENDCHAR +STARTCHAR etatonos +ENCODING 942 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +A0 +D0 +90 +90 +10 +ENDCHAR +STARTCHAR iotatonos +ENCODING 943 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR upsilondieresistonos +ENCODING 944 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +D0 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR alpha +ENCODING 945 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR beta +ENCODING 946 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +E0 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR gamma +ENCODING 947 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +50 +20 +20 +ENDCHAR +STARTCHAR delta +ENCODING 948 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +80 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR epsilon +ENCODING 949 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +E0 +80 +70 +00 +ENDCHAR +STARTCHAR zeta +ENCODING 950 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F0 +40 +80 +60 +10 +20 +ENDCHAR +STARTCHAR eta +ENCODING 951 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +D0 +90 +90 +10 +ENDCHAR +STARTCHAR theta +ENCODING 952 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +F0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR iota +ENCODING 953 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR kappa +ENCODING 954 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +E0 +A0 +90 +00 +ENDCHAR +STARTCHAR lambda +ENCODING 955 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +10 +70 +90 +90 +90 +00 +ENDCHAR +STARTCHAR mu +ENCODING 956 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR nu +ENCODING 957 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +20 +20 +00 +ENDCHAR +STARTCHAR xi +ENCODING 958 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +40 +60 +80 +60 +10 +60 +ENDCHAR +STARTCHAR omicron +ENCODING 959 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR pi +ENCODING 960 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +50 +50 +50 +00 +ENDCHAR +STARTCHAR rho +ENCODING 961 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR sigma1 +ENCODING 962 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +80 +60 +10 +60 +ENDCHAR +STARTCHAR sigma +ENCODING 963 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +60 +00 +ENDCHAR +STARTCHAR tau +ENCODING 964 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR upsilon +ENCODING 965 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR phi +ENCODING 966 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +B0 +A8 +A8 +70 +20 +ENDCHAR +STARTCHAR chi +ENCODING 967 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +20 +50 +50 +ENDCHAR +STARTCHAR psi +ENCODING 968 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +A8 +70 +20 +20 +ENDCHAR +STARTCHAR omega +ENCODING 969 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR iotadieresis +ENCODING 970 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +00 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR upsilondieresis +ENCODING 971 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR omicrontonos +ENCODING 972 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR upsilontonos +ENCODING 973 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR omegatonos +ENCODING 974 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR theta1 +ENCODING 977 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +78 +10 +90 +60 +00 +ENDCHAR +STARTCHAR Upsilon1 +ENCODING 978 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +68 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR uni03D3 +ENCODING 979 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +D0 +28 +A0 +A0 +20 +20 +00 +ENDCHAR +STARTCHAR uni03D4 +ENCODING 980 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +90 +68 +20 +20 +20 +00 +ENDCHAR +STARTCHAR phi1 +ENCODING 981 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A8 +A8 +A8 +70 +20 +ENDCHAR +STARTCHAR omega1 +ENCODING 982 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +88 +A8 +50 +00 +ENDCHAR +STARTCHAR uni03DE +ENCODING 990 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +90 +B0 +D0 +90 +10 +00 +ENDCHAR +STARTCHAR uni03DF +ENCODING 991 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +F0 +10 +20 +40 +00 +ENDCHAR +STARTCHAR uni03E9 +ENCODING 1001 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +60 +80 +70 +ENDCHAR +STARTCHAR uni03F0 +ENCODING 1008 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +50 +60 +90 +00 +ENDCHAR +STARTCHAR uni03F1 +ENCODING 1009 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +E0 +80 +70 +ENDCHAR +STARTCHAR uni03F2 +ENCODING 1010 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +80 +80 +70 +00 +ENDCHAR +STARTCHAR uni03F3 +ENCODING 1011 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +30 +10 +10 +90 +60 +ENDCHAR +STARTCHAR uni03F4 +ENCODING 1012 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +F0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR uni03F5 +ENCODING 1013 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +E0 +80 +70 +00 +ENDCHAR +STARTCHAR afii10023 +ENCODING 1025 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR afii10051 +ENCODING 1026 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +40 +60 +50 +50 +10 +20 +ENDCHAR +STARTCHAR afii10052 +ENCODING 1027 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +80 +80 +80 +80 +00 +ENDCHAR +STARTCHAR afii10053 +ENCODING 1028 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +C0 +80 +90 +60 +00 +ENDCHAR +STARTCHAR afii10054 +ENCODING 1029 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +40 +20 +90 +60 +00 +ENDCHAR +STARTCHAR afii10055 +ENCODING 1030 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR afii10056 +ENCODING 1031 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR afii10057 +ENCODING 1032 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +10 +10 +90 +60 +00 +ENDCHAR +STARTCHAR afii10058 +ENCODING 1033 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +A0 +B0 +A8 +A8 +B0 +00 +ENDCHAR +STARTCHAR afii10059 +ENCODING 1034 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +A0 +F0 +A8 +A8 +B0 +00 +ENDCHAR +STARTCHAR afii10060 +ENCODING 1035 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +40 +60 +50 +50 +50 +00 +ENDCHAR +STARTCHAR afii10061 +ENCODING 1036 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A0 +C0 +C0 +A0 +90 +00 +ENDCHAR +STARTCHAR uni040D +ENCODING 1037 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii10062 +ENCODING 1038 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +20 +20 +40 +00 +ENDCHAR +STARTCHAR afii10145 +ENCODING 1039 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +50 +50 +70 +20 +ENDCHAR +STARTCHAR afii10017 +ENCODING 1040 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR afii10018 +ENCODING 1041 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +80 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR afii10019 +ENCODING 1042 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR afii10020 +ENCODING 1043 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +90 +80 +80 +80 +80 +00 +ENDCHAR +STARTCHAR afii10021 +ENCODING 1044 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +A0 +A0 +A0 +A0 +F0 +90 +ENDCHAR +STARTCHAR afii10022 +ENCODING 1045 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +E0 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR afii10024 +ENCODING 1046 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A8 +A8 +70 +A8 +A8 +A8 +00 +ENDCHAR +STARTCHAR afii10025 +ENCODING 1047 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +20 +10 +90 +60 +00 +ENDCHAR +STARTCHAR afii10026 +ENCODING 1048 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +B0 +D0 +90 +90 +00 +ENDCHAR +STARTCHAR afii10027 +ENCODING 1049 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +60 +90 +B0 +D0 +90 +90 +00 +ENDCHAR +STARTCHAR afii10028 +ENCODING 1050 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A0 +C0 +A0 +90 +90 +00 +ENDCHAR +STARTCHAR afii10029 +ENCODING 1051 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +30 +50 +50 +50 +50 +90 +00 +ENDCHAR +STARTCHAR afii10030 +ENCODING 1052 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +F0 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR afii10031 +ENCODING 1053 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR afii10032 +ENCODING 1054 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR afii10033 +ENCODING 1055 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +90 +90 +90 +90 +90 +00 +ENDCHAR +STARTCHAR afii10034 +ENCODING 1056 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +90 +90 +E0 +80 +80 +00 +ENDCHAR +STARTCHAR afii10035 +ENCODING 1057 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +80 +80 +90 +60 +00 +ENDCHAR +STARTCHAR afii10036 +ENCODING 1058 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR afii10037 +ENCODING 1059 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +90 +70 +10 +E0 +00 +ENDCHAR +STARTCHAR afii10038 +ENCODING 1060 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A8 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR afii10039 +ENCODING 1061 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +20 +20 +50 +50 +00 +ENDCHAR +STARTCHAR afii10040 +ENCODING 1062 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +A0 +A0 +A0 +A0 +F0 +10 +ENDCHAR +STARTCHAR afii10041 +ENCODING 1063 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +30 +10 +10 +00 +ENDCHAR +STARTCHAR afii10042 +ENCODING 1064 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A8 +A8 +A8 +A8 +A8 +F8 +00 +ENDCHAR +STARTCHAR afii10043 +ENCODING 1065 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A8 +A8 +A8 +A8 +A8 +F8 +08 +ENDCHAR +STARTCHAR afii10044 +ENCODING 1066 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +20 +30 +28 +28 +30 +00 +ENDCHAR +STARTCHAR afii10045 +ENCODING 1067 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +88 +C8 +A8 +A8 +C8 +00 +ENDCHAR +STARTCHAR afii10046 +ENCODING 1068 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +60 +50 +50 +60 +00 +ENDCHAR +STARTCHAR afii10047 +ENCODING 1069 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +10 +70 +10 +10 +E0 +00 +ENDCHAR +STARTCHAR afii10048 +ENCODING 1070 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A8 +E8 +A8 +A8 +90 +00 +ENDCHAR +STARTCHAR afii10049 +ENCODING 1071 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +90 +90 +70 +90 +90 +00 +ENDCHAR +STARTCHAR afii10065 +ENCODING 1072 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR afii10066 +ENCODING 1073 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +80 +E0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR afii10067 +ENCODING 1074 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +E0 +90 +E0 +00 +ENDCHAR +STARTCHAR afii10068 +ENCODING 1075 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +40 +40 +40 +00 +ENDCHAR +STARTCHAR afii10069 +ENCODING 1076 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +50 +90 +F0 +90 +ENDCHAR +STARTCHAR afii10070 +ENCODING 1077 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR afii10072 +ENCODING 1078 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +70 +A8 +A8 +00 +ENDCHAR +STARTCHAR afii10073 +ENCODING 1079 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +30 +10 +60 +00 +ENDCHAR +STARTCHAR afii10074 +ENCODING 1080 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +B0 +D0 +90 +00 +ENDCHAR +STARTCHAR afii10075 +ENCODING 1081 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +60 +90 +B0 +D0 +90 +00 +ENDCHAR +STARTCHAR afii10076 +ENCODING 1082 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +E0 +A0 +90 +00 +ENDCHAR +STARTCHAR afii10077 +ENCODING 1083 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +50 +50 +90 +00 +ENDCHAR +STARTCHAR afii10078 +ENCODING 1084 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +88 +D8 +A8 +A8 +00 +ENDCHAR +STARTCHAR afii10079 +ENCODING 1085 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR afii10080 +ENCODING 1086 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR afii10081 +ENCODING 1087 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR afii10082 +ENCODING 1088 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +90 +90 +E0 +80 +ENDCHAR +STARTCHAR afii10083 +ENCODING 1089 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +40 +40 +30 +00 +ENDCHAR +STARTCHAR afii10084 +ENCODING 1090 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +20 +20 +20 +00 +ENDCHAR +STARTCHAR afii10085 +ENCODING 1091 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +50 +20 +40 +ENDCHAR +STARTCHAR afii10086 +ENCODING 1092 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +20 +20 +70 +50 +70 +20 +ENDCHAR +STARTCHAR afii10087 +ENCODING 1093 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +60 +60 +90 +00 +ENDCHAR +STARTCHAR afii10088 +ENCODING 1094 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +F0 +10 +ENDCHAR +STARTCHAR afii10089 +ENCODING 1095 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +70 +10 +00 +ENDCHAR +STARTCHAR afii10090 +ENCODING 1096 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +A8 +A8 +F8 +00 +ENDCHAR +STARTCHAR afii10091 +ENCODING 1097 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +A8 +A8 +F8 +08 +ENDCHAR +STARTCHAR afii10092 +ENCODING 1098 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +C0 +60 +50 +60 +00 +ENDCHAR +STARTCHAR afii10093 +ENCODING 1099 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +D0 +B0 +D0 +00 +ENDCHAR +STARTCHAR afii10094 +ENCODING 1100 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +80 +E0 +90 +E0 +00 +ENDCHAR +STARTCHAR afii10095 +ENCODING 1101 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +30 +10 +60 +00 +ENDCHAR +STARTCHAR afii10096 +ENCODING 1102 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +D0 +D0 +A0 +00 +ENDCHAR +STARTCHAR afii10097 +ENCODING 1103 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +50 +30 +50 +00 +ENDCHAR +STARTCHAR afii10071 +ENCODING 1105 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +00 +60 +B0 +C0 +60 +00 +ENDCHAR +STARTCHAR afii10099 +ENCODING 1106 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +E0 +40 +60 +50 +10 +20 +ENDCHAR +STARTCHAR afii10100 +ENCODING 1107 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +F0 +80 +80 +80 +00 +ENDCHAR +STARTCHAR afii10101 +ENCODING 1108 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +60 +40 +30 +00 +ENDCHAR +STARTCHAR afii10102 +ENCODING 1109 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +C0 +30 +E0 +00 +ENDCHAR +STARTCHAR afii10103 +ENCODING 1110 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR afii10104 +ENCODING 1111 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR afii10105 +ENCODING 1112 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +10 +10 +50 +20 +ENDCHAR +STARTCHAR afii10106 +ENCODING 1113 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +B8 +A8 +B0 +00 +ENDCHAR +STARTCHAR afii10107 +ENCODING 1114 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +F0 +A8 +B0 +00 +ENDCHAR +STARTCHAR afii10108 +ENCODING 1115 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +E0 +40 +60 +50 +50 +00 +ENDCHAR +STARTCHAR afii10109 +ENCODING 1116 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +40 +90 +E0 +A0 +90 +00 +ENDCHAR +STARTCHAR uni045D +ENCODING 1117 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii10110 +ENCODING 1118 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +60 +00 +90 +50 +20 +40 +ENDCHAR +STARTCHAR afii10193 +ENCODING 1119 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +50 +50 +70 +20 +ENDCHAR +STARTCHAR afii10050 +ENCODING 1168 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +F0 +80 +80 +80 +80 +00 +ENDCHAR +STARTCHAR afii10098 +ENCODING 1169 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +10 +F0 +80 +80 +80 +00 +ENDCHAR +STARTCHAR uni0492 +ENCODING 1170 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +40 +E0 +40 +40 +40 +00 +ENDCHAR +STARTCHAR uni0493 +ENCODING 1171 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +40 +E0 +40 +00 +ENDCHAR +STARTCHAR uni0496 +ENCODING 1174 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A8 +A8 +70 +A8 +A8 +A8 +08 +ENDCHAR +STARTCHAR uni0497 +ENCODING 1175 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +70 +A8 +A8 +08 +ENDCHAR +STARTCHAR uni049A +ENCODING 1178 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +A0 +C0 +A0 +90 +88 +08 +ENDCHAR +STARTCHAR uni049B +ENCODING 1179 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +E0 +A0 +90 +08 +ENDCHAR +STARTCHAR uni04AE +ENCODING 1198 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR uni04AF +ENCODING 1199 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +88 +50 +20 +20 +20 +ENDCHAR +STARTCHAR uni04B0 +ENCODING 1200 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +88 +88 +50 +F8 +20 +20 +00 +ENDCHAR +STARTCHAR uni04B1 +ENCODING 1201 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +88 +50 +F8 +20 +20 +ENDCHAR +STARTCHAR uni04B2 +ENCODING 1202 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +20 +20 +50 +50 +08 +ENDCHAR +STARTCHAR uni04B3 +ENCODING 1203 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +60 +60 +90 +08 +ENDCHAR +STARTCHAR uni04BA +ENCODING 1210 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +E0 +90 +90 +90 +00 +ENDCHAR +STARTCHAR uni04BB +ENCODING 1211 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +60 +50 +50 +50 +00 +ENDCHAR +STARTCHAR uni04D8 +ENCODING 1240 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +10 +F0 +90 +60 +00 +ENDCHAR +STARTCHAR afii10846 +ENCODING 1241 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +30 +D0 +60 +00 +ENDCHAR +STARTCHAR uni04E2 +ENCODING 1250 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +00 +70 +20 +20 +20 +70 +00 +ENDCHAR +STARTCHAR uni04E3 +ENCODING 1251 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +00 +60 +20 +20 +70 +00 +ENDCHAR +STARTCHAR uni04E8 +ENCODING 1256 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +F0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR uni04E9 +ENCODING 1257 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +F0 +90 +60 +00 +ENDCHAR +STARTCHAR uni04EE +ENCODING 1262 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +00 +90 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR uni04EF +ENCODING 1263 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +00 +90 +90 +90 +70 +00 +ENDCHAR +STARTCHAR afii57664 +ENCODING 1488 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +50 +A0 +90 +00 +ENDCHAR +STARTCHAR afii57665 +ENCODING 1489 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +20 +20 +F0 +00 +ENDCHAR +STARTCHAR afii57666 +ENCODING 1490 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +20 +20 +20 +D0 +00 +ENDCHAR +STARTCHAR afii57667 +ENCODING 1491 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +20 +20 +20 +00 +ENDCHAR +STARTCHAR afii57668 +ENCODING 1492 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +10 +90 +90 +00 +ENDCHAR +STARTCHAR afii57669 +ENCODING 1493 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR afii57670 +ENCODING 1494 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +20 +20 +20 +00 +ENDCHAR +STARTCHAR afii57671 +ENCODING 1495 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +50 +50 +50 +00 +ENDCHAR +STARTCHAR afii57672 +ENCODING 1496 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +F0 +00 +ENDCHAR +STARTCHAR afii57673 +ENCODING 1497 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR afii57674 +ENCODING 1498 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +10 +20 +20 +00 +ENDCHAR +STARTCHAR afii57675 +ENCODING 1499 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +70 +10 +10 +E0 +00 +ENDCHAR +STARTCHAR afii57676 +ENCODING 1500 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +70 +10 +20 +40 +00 +ENDCHAR +STARTCHAR afii57677 +ENCODING 1501 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +70 +90 +90 +F0 +00 +ENDCHAR +STARTCHAR afii57678 +ENCODING 1502 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +70 +90 +90 +B0 +00 +ENDCHAR +STARTCHAR afii57679 +ENCODING 1503 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +20 +40 +40 +40 +00 +ENDCHAR +STARTCHAR afii57680 +ENCODING 1504 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +20 +20 +20 +60 +00 +ENDCHAR +STARTCHAR afii57681 +ENCODING 1505 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +78 +48 +48 +30 +00 +ENDCHAR +STARTCHAR afii57682 +ENCODING 1506 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +50 +50 +F0 +00 +ENDCHAR +STARTCHAR afii57683 +ENCODING 1507 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +90 +10 +10 +00 +ENDCHAR +STARTCHAR afii57684 +ENCODING 1508 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +90 +10 +F0 +00 +ENDCHAR +STARTCHAR afii57685 +ENCODING 1509 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +60 +40 +40 +00 +ENDCHAR +STARTCHAR afii57686 +ENCODING 1510 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +60 +20 +F0 +00 +ENDCHAR +STARTCHAR afii57687 +ENCODING 1511 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +10 +A0 +80 +00 +ENDCHAR +STARTCHAR afii57688 +ENCODING 1512 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +10 +10 +10 +00 +ENDCHAR +STARTCHAR afii57689 +ENCODING 1513 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +C8 +88 +F0 +00 +ENDCHAR +STARTCHAR afii57690 +ENCODING 1514 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +50 +50 +D0 +00 +ENDCHAR +STARTCHAR uni1E02 +ENCODING 7682 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +E0 +90 +E0 +90 +E0 +00 +ENDCHAR +STARTCHAR uni1E03 +ENCODING 7683 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +80 +80 +E0 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR uni1E0A +ENCODING 7690 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +E0 +90 +90 +90 +E0 +00 +ENDCHAR +STARTCHAR uni1E0B +ENCODING 7691 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +10 +10 +70 +90 +90 +70 +00 +ENDCHAR +STARTCHAR uni1E1E +ENCODING 7710 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +F0 +80 +E0 +80 +80 +00 +ENDCHAR +STARTCHAR uni1E1F +ENCODING 7711 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +20 +50 +40 +E0 +40 +40 +00 +ENDCHAR +STARTCHAR uni1E40 +ENCODING 7744 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +90 +F0 +F0 +90 +90 +00 +ENDCHAR +STARTCHAR uni1E41 +ENCODING 7745 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +D0 +A8 +A8 +A8 +00 +ENDCHAR +STARTCHAR uni1E56 +ENCODING 7766 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +00 +E0 +90 +E0 +80 +80 +00 +ENDCHAR +STARTCHAR uni1E57 +ENCODING 7767 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +E0 +90 +E0 +80 +80 +ENDCHAR +STARTCHAR uni1E60 +ENCODING 7776 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +70 +80 +60 +10 +E0 +00 +ENDCHAR +STARTCHAR uni1E61 +ENCODING 7777 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +30 +60 +10 +60 +00 +ENDCHAR +STARTCHAR uni1E6A +ENCODING 7786 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +70 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR uni1E6B +ENCODING 7787 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +00 +40 +E0 +40 +50 +20 +00 +ENDCHAR +STARTCHAR Wgrave +ENCODING 7808 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +90 +90 +F0 +F0 +90 +00 +ENDCHAR +STARTCHAR wgrave +ENCODING 7809 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR Wacute +ENCODING 7810 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +90 +90 +F0 +F0 +90 +00 +ENDCHAR +STARTCHAR wacute +ENCODING 7811 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +20 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR Wdieresis +ENCODING 7812 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +00 +90 +90 +F0 +F0 +90 +00 +ENDCHAR +STARTCHAR wdieresis +ENCODING 7813 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +88 +A8 +A8 +50 +00 +ENDCHAR +STARTCHAR Ygrave +ENCODING 7922 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +88 +50 +20 +20 +20 +00 +ENDCHAR +STARTCHAR ygrave +ENCODING 7923 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +00 +90 +90 +70 +90 +60 +ENDCHAR +STARTCHAR uni2010 +ENCODING 8208 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +00 +00 +00 +ENDCHAR +STARTCHAR uni2011 +ENCODING 8209 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +00 +00 +00 +ENDCHAR +STARTCHAR figuredash +ENCODING 8210 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR endash +ENCODING 8211 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR emdash +ENCODING 8212 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR afii00208 +ENCODING 8213 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR uni2016 +ENCODING 8214 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +50 +50 +50 +00 +ENDCHAR +STARTCHAR underscoredbl +ENCODING 8215 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +F8 +00 +F8 +ENDCHAR +STARTCHAR quoteleft +ENCODING 8216 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +60 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quoteright +ENCODING 8217 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +20 +40 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quotesinglbase +ENCODING 8218 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +60 +20 +40 +ENDCHAR +STARTCHAR quotereversed +ENCODING 8219 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +40 +20 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quotedblleft +ENCODING 8220 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +48 +90 +D8 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quotedblright +ENCODING 8221 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +D8 +48 +90 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR quotedblbase +ENCODING 8222 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +D8 +48 +90 +ENDCHAR +STARTCHAR uni201F +ENCODING 8223 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +D8 +90 +48 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR dagger +ENCODING 8224 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR daggerdbl +ENCODING 8225 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +20 +70 +20 +20 +00 +ENDCHAR +STARTCHAR bullet +ENCODING 8226 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +F0 +F0 +60 +00 +ENDCHAR +STARTCHAR ellipsis +ENCODING 8230 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +A8 +00 +ENDCHAR +STARTCHAR perthousand +ENCODING 8240 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +A0 +40 +A8 +28 +00 +00 +ENDCHAR +STARTCHAR minute +ENCODING 8242 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR second +ENCODING 8243 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +A0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2034 +ENCODING 8244 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A8 +A8 +D0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2035 +ENCODING 8245 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2036 +ENCODING 8246 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +A0 +A0 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR guilsinglleft +ENCODING 8249 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +40 +20 +00 +00 +ENDCHAR +STARTCHAR guilsinglright +ENCODING 8250 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +20 +40 +00 +00 +ENDCHAR +STARTCHAR exclamdbl +ENCODING 8252 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +50 +00 +50 +00 +ENDCHAR +STARTCHAR uni203D +ENCODING 8253 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +30 +20 +00 +20 +00 +ENDCHAR +STARTCHAR uni203E +ENCODING 8254 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR fraction +ENCODING 8260 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +20 +40 +40 +80 +00 +ENDCHAR +STARTCHAR zerosuperior +ENCODING 8304 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +50 +50 +20 +00 +00 +00 +ENDCHAR +STARTCHAR uni2071 +ENCODING 8305 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +60 +20 +70 +00 +00 +00 +ENDCHAR +STARTCHAR foursuperior +ENCODING 8308 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +40 +60 +70 +20 +00 +00 +00 +ENDCHAR +STARTCHAR fivesuperior +ENCODING 8309 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +40 +60 +10 +60 +00 +00 +00 +ENDCHAR +STARTCHAR sixsuperior +ENCODING 8310 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +40 +60 +50 +20 +00 +00 +00 +ENDCHAR +STARTCHAR sevensuperior +ENCODING 8311 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +10 +20 +20 +20 +00 +00 +00 +ENDCHAR +STARTCHAR eightsuperior +ENCODING 8312 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +20 +50 +20 +00 +00 +00 +ENDCHAR +STARTCHAR ninesuperior +ENCODING 8313 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +30 +10 +60 +00 +00 +00 +ENDCHAR +STARTCHAR uni207A +ENCODING 8314 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni207B +ENCODING 8315 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni207C +ENCODING 8316 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +00 +70 +00 +00 +00 +00 +ENDCHAR +STARTCHAR parenleftsuperior +ENCODING 8317 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +40 +40 +40 +20 +00 +00 +00 +ENDCHAR +STARTCHAR parenrightsuperior +ENCODING 8318 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +20 +20 +40 +00 +00 +00 +ENDCHAR +STARTCHAR nsuperior +ENCODING 8319 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +60 +50 +50 +00 +00 +00 +ENDCHAR +STARTCHAR zeroinferior +ENCODING 8320 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +50 +50 +50 +20 +ENDCHAR +STARTCHAR oneinferior +ENCODING 8321 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +60 +20 +20 +70 +ENDCHAR +STARTCHAR twoinferior +ENCODING 8322 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +50 +10 +20 +70 +ENDCHAR +STARTCHAR threeinferior +ENCODING 8323 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +10 +60 +10 +60 +ENDCHAR +STARTCHAR fourinferior +ENCODING 8324 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +40 +60 +70 +20 +ENDCHAR +STARTCHAR fiveinferior +ENCODING 8325 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +40 +60 +10 +60 +ENDCHAR +STARTCHAR sixinferior +ENCODING 8326 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +40 +60 +50 +20 +ENDCHAR +STARTCHAR seveninferior +ENCODING 8327 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +10 +20 +20 +20 +ENDCHAR +STARTCHAR eightinferior +ENCODING 8328 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +50 +20 +50 +20 +ENDCHAR +STARTCHAR nineinferior +ENCODING 8329 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +50 +30 +10 +60 +ENDCHAR +STARTCHAR uni208A +ENCODING 8330 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +20 +70 +20 +00 +ENDCHAR +STARTCHAR uni208B +ENCODING 8331 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +70 +00 +00 +ENDCHAR +STARTCHAR uni208C +ENCODING 8332 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +00 +70 +00 +ENDCHAR +STARTCHAR parenleftinferior +ENCODING 8333 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +40 +40 +40 +20 +ENDCHAR +STARTCHAR parenrightinferior +ENCODING 8334 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +20 +20 +20 +40 +ENDCHAR +STARTCHAR franc +ENCODING 8355 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +80 +F0 +A0 +A0 +A0 +00 +ENDCHAR +STARTCHAR lira +ENCODING 8356 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +E0 +E0 +50 +A0 +00 +ENDCHAR +STARTCHAR peseta +ENCODING 8359 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +48 +F8 +70 +40 +40 +00 +ENDCHAR +STARTCHAR dong +ENCODING 8363 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +38 +70 +90 +90 +70 +F0 +ENDCHAR +STARTCHAR Euro +ENCODING 8364 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +40 +E0 +40 +E0 +40 +30 +00 +ENDCHAR +STARTCHAR uni20AF +ENCODING 8367 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +E0 +50 +50 +50 +D0 +E0 +00 +ENDCHAR +STARTCHAR uni20D0 +ENCODING 8400 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +F0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni20D1 +ENCODING 8401 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +F0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni20D2 +ENCODING 8402 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni20D3 +ENCODING 8403 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni20D4 +ENCODING 8404 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +D0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni20D5 +ENCODING 8405 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +B0 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni20D6 +ENCODING 8406 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +F0 +40 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni20D7 +ENCODING 8407 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +F0 +20 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2102 +ENCODING 8450 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +B0 +A0 +A0 +B0 +60 +00 +ENDCHAR +STARTCHAR afii61248 +ENCODING 8453 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +90 +A0 +70 +28 +68 +90 +00 +ENDCHAR +STARTCHAR afii61289 +ENCODING 8467 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +50 +60 +40 +B0 +00 +ENDCHAR +STARTCHAR uni2115 +ENCODING 8469 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +D0 +D0 +F0 +F0 +D0 +D0 +00 +ENDCHAR +STARTCHAR afii61352 +ENCODING 8470 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +C0 +B0 +A8 +B0 +A0 +B8 +00 +ENDCHAR +STARTCHAR uni211A +ENCODING 8474 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +D0 +D0 +D0 +F0 +60 +10 +ENDCHAR +STARTCHAR uni211D +ENCODING 8477 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +D0 +D0 +E0 +D0 +D0 +00 +ENDCHAR +STARTCHAR trademark +ENCODING 8482 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +20 +20 +00 +70 +70 +50 +00 +ENDCHAR +STARTCHAR uni2124 +ENCODING 8484 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +50 +50 +A0 +A0 +F0 +00 +ENDCHAR +STARTCHAR Omega +ENCODING 8486 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +88 +88 +88 +50 +D8 +00 +ENDCHAR +STARTCHAR estimated +ENCODING 8494 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +D0 +F0 +C0 +D0 +60 +00 +ENDCHAR +STARTCHAR oneeighth +ENCODING 8539 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +A0 +D0 +A0 +50 +20 +00 +ENDCHAR +STARTCHAR threeeighths +ENCODING 8540 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +40 +90 +68 +90 +28 +10 +00 +ENDCHAR +STARTCHAR fiveeighths +ENCODING 8541 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +C0 +80 +D0 +68 +90 +28 +10 +00 +ENDCHAR +STARTCHAR seveneighths +ENCODING 8542 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +C0 +40 +50 +A8 +90 +28 +10 +00 +ENDCHAR +STARTCHAR arrowleft +ENCODING 8592 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +40 +F8 +40 +20 +00 +ENDCHAR +STARTCHAR arrowup +ENCODING 8593 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A8 +20 +20 +20 +00 +ENDCHAR +STARTCHAR arrowright +ENCODING 8594 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +10 +F8 +10 +20 +00 +ENDCHAR +STARTCHAR arrowdown +ENCODING 8595 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR arrowboth +ENCODING 8596 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +F8 +50 +00 +00 +ENDCHAR +STARTCHAR arrowupdn +ENCODING 8597 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +20 +20 +70 +20 +00 +ENDCHAR +STARTCHAR uni2196 +ENCODING 8598 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +E0 +C0 +A0 +20 +10 +10 +00 +ENDCHAR +STARTCHAR uni2197 +ENCODING 8599 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +30 +50 +40 +80 +80 +00 +ENDCHAR +STARTCHAR uni2198 +ENCODING 8600 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +40 +50 +30 +70 +00 +ENDCHAR +STARTCHAR uni2199 +ENCODING 8601 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +20 +A0 +C0 +E0 +00 +ENDCHAR +STARTCHAR uni21A4 +ENCODING 8612 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +48 +F8 +48 +20 +00 +ENDCHAR +STARTCHAR uni21A5 +ENCODING 8613 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A8 +20 +20 +70 +00 +ENDCHAR +STARTCHAR uni21A6 +ENCODING 8614 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +90 +F8 +90 +20 +00 +ENDCHAR +STARTCHAR uni21A7 +ENCODING 8615 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +20 +20 +A8 +70 +20 +00 +ENDCHAR +STARTCHAR arrowupdnbse +ENCODING 8616 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +20 +20 +70 +20 +70 +ENDCHAR +STARTCHAR uni21B0 +ENCODING 8624 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +F0 +50 +10 +10 +10 +00 +ENDCHAR +STARTCHAR uni21B1 +ENCODING 8625 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +F0 +A0 +80 +80 +80 +00 +ENDCHAR +STARTCHAR uni21B2 +ENCODING 8626 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +10 +50 +F0 +40 +00 +ENDCHAR +STARTCHAR uni21B3 +ENCODING 8627 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +80 +80 +A0 +F0 +20 +00 +ENDCHAR +STARTCHAR uni21B4 +ENCODING 8628 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +E0 +20 +20 +70 +20 +00 +ENDCHAR +STARTCHAR carriagereturn +ENCODING 8629 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +10 +10 +50 +F0 +40 +00 +ENDCHAR +STARTCHAR uni21BC +ENCODING 8636 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +40 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR uni21BD +ENCODING 8637 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F8 +40 +20 +00 +ENDCHAR +STARTCHAR uni21BE +ENCODING 8638 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +30 +28 +20 +20 +20 +00 +ENDCHAR +STARTCHAR uni21BF +ENCODING 8639 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +60 +A0 +20 +20 +20 +00 +ENDCHAR +STARTCHAR uni21C0 +ENCODING 8640 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +10 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR uni21C1 +ENCODING 8641 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F8 +10 +20 +00 +ENDCHAR +STARTCHAR uni21C2 +ENCODING 8642 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +28 +30 +20 +00 +ENDCHAR +STARTCHAR uni21C3 +ENCODING 8643 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +A0 +60 +20 +00 +ENDCHAR +STARTCHAR uni21CB +ENCODING 8651 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +F0 +00 +F0 +20 +00 +ENDCHAR +STARTCHAR uni21CC +ENCODING 8652 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +F0 +00 +F0 +40 +00 +ENDCHAR +STARTCHAR arrowdblleft +ENCODING 8656 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +78 +80 +78 +20 +00 +00 +ENDCHAR +STARTCHAR arrowdblup +ENCODING 8657 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +D8 +50 +50 +50 +00 +ENDCHAR +STARTCHAR arrowdblright +ENCODING 8658 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +F0 +08 +F0 +20 +00 +00 +ENDCHAR +STARTCHAR arrowdbldown +ENCODING 8659 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +D8 +50 +20 +00 +ENDCHAR +STARTCHAR arrowdblboth +ENCODING 8660 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +88 +70 +20 +00 +00 +ENDCHAR +STARTCHAR uni21D5 +ENCODING 8661 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +D8 +50 +D8 +50 +20 +ENDCHAR +STARTCHAR uni21D6 +ENCODING 8662 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F0 +A0 +D0 +A8 +10 +00 +ENDCHAR +STARTCHAR uni21D7 +ENCODING 8663 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +78 +28 +58 +A8 +40 +00 +ENDCHAR +STARTCHAR uni21D8 +ENCODING 8664 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +A8 +58 +28 +78 +00 +ENDCHAR +STARTCHAR uni21D9 +ENCODING 8665 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +10 +A8 +D0 +A0 +F0 +00 +ENDCHAR +STARTCHAR uni21E0 +ENCODING 8672 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +40 +A8 +40 +20 +00 +ENDCHAR +STARTCHAR uni21E1 +ENCODING 8673 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +88 +20 +00 +20 +00 +ENDCHAR +STARTCHAR uni21E2 +ENCODING 8674 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +10 +A8 +10 +20 +00 +ENDCHAR +STARTCHAR uni21E3 +ENCODING 8675 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +20 +88 +70 +20 +00 +ENDCHAR +STARTCHAR uni21E4 +ENCODING 8676 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +A0 +C0 +F8 +C0 +A0 +00 +ENDCHAR +STARTCHAR uni21E5 +ENCODING 8677 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +28 +18 +F8 +18 +28 +00 +ENDCHAR +STARTCHAR uni21E6 +ENCODING 8678 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +78 +88 +78 +20 +00 +00 +ENDCHAR +STARTCHAR uni21E7 +ENCODING 8679 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +D8 +50 +50 +70 +00 +ENDCHAR +STARTCHAR uni21E8 +ENCODING 8680 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +F0 +88 +F0 +20 +00 +00 +ENDCHAR +STARTCHAR uni21E9 +ENCODING 8681 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +50 +50 +D8 +50 +20 +00 +ENDCHAR +STARTCHAR universal +ENCODING 8704 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +90 +F0 +90 +90 +60 +00 +ENDCHAR +STARTCHAR uni2201 +ENCODING 8705 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +40 +40 +50 +20 +00 +ENDCHAR +STARTCHAR partialdiff +ENCODING 8706 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +10 +50 +B0 +90 +60 +00 +ENDCHAR +STARTCHAR existential +ENCODING 8707 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F0 +10 +70 +10 +10 +F0 +00 +ENDCHAR +STARTCHAR uni2204 +ENCODING 8708 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +F0 +30 +70 +50 +50 +F0 +40 +ENDCHAR +STARTCHAR emptyset +ENCODING 8709 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +B0 +B0 +D0 +D0 +E0 +00 +ENDCHAR +STARTCHAR Delta +ENCODING 8710 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +50 +50 +88 +F8 +00 +ENDCHAR +STARTCHAR gradient +ENCODING 8711 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F8 +88 +50 +50 +20 +20 +00 +ENDCHAR +STARTCHAR element +ENCODING 8712 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +80 +E0 +80 +70 +00 +ENDCHAR +STARTCHAR notelement +ENCODING 8713 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A0 +E0 +C0 +70 +40 +ENDCHAR +STARTCHAR suchthat +ENCODING 8715 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +E0 +10 +70 +10 +E0 +00 +ENDCHAR +STARTCHAR uni220C +ENCODING 8716 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +E0 +30 +70 +50 +E0 +40 +ENDCHAR +STARTCHAR uni220E +ENCODING 8718 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +70 +70 +70 +00 +00 +ENDCHAR +STARTCHAR product +ENCODING 8719 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +50 +50 +50 +50 +50 +50 +D8 +ENDCHAR +STARTCHAR uni2210 +ENCODING 8720 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +D8 +50 +50 +50 +50 +50 +50 +F8 +ENDCHAR +STARTCHAR summation +ENCODING 8721 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +80 +40 +20 +20 +40 +80 +F8 +ENDCHAR +STARTCHAR minus +ENCODING 8722 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR uni2213 +ENCODING 8723 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +00 +20 +70 +20 +00 +ENDCHAR +STARTCHAR uni2214 +ENCODING 8724 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +00 +20 +70 +20 +00 +ENDCHAR +STARTCHAR fraction +ENCODING 8725 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +20 +40 +40 +80 +00 +ENDCHAR +STARTCHAR uni2216 +ENCODING 8726 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +40 +40 +20 +20 +10 +00 +ENDCHAR +STARTCHAR asteriskmath +ENCODING 8727 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +90 +60 +F0 +60 +90 +00 +ENDCHAR +STARTCHAR uni2218 +ENCODING 8728 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +50 +20 +00 +00 +ENDCHAR +STARTCHAR periodcentered +ENCODING 8729 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +70 +20 +00 +00 +ENDCHAR +STARTCHAR radical +ENCODING 8730 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +18 +10 +10 +10 +D0 +50 +20 +20 +ENDCHAR +STARTCHAR proportional +ENCODING 8733 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +50 +A0 +A0 +50 +00 +00 +ENDCHAR +STARTCHAR infinity +ENCODING 8734 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +50 +A8 +A8 +50 +00 +00 +ENDCHAR +STARTCHAR orthogonal +ENCODING 8735 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +80 +80 +80 +F0 +00 +ENDCHAR +STARTCHAR angle +ENCODING 8736 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +10 +20 +40 +80 +F0 +00 +ENDCHAR +STARTCHAR uni2221 +ENCODING 8737 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +10 +A0 +40 +A0 +F0 +20 +ENDCHAR +STARTCHAR uni2222 +ENCODING 8738 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +90 +60 +A0 +A0 +60 +90 +00 +ENDCHAR +STARTCHAR uni2223 +ENCODING 8739 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR uni2224 +ENCODING 8740 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +30 +60 +20 +20 +00 +ENDCHAR +STARTCHAR uni2225 +ENCODING 8741 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +50 +50 +50 +50 +50 +00 +ENDCHAR +STARTCHAR uni2226 +ENCODING 8742 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +58 +70 +D0 +50 +50 +00 +ENDCHAR +STARTCHAR logicaland +ENCODING 8743 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +60 +90 +90 +00 +ENDCHAR +STARTCHAR logicalor +ENCODING 8744 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +60 +60 +00 +ENDCHAR +STARTCHAR intersection +ENCODING 8745 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +90 +00 +ENDCHAR +STARTCHAR union +ENCODING 8746 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +90 +90 +90 +60 +00 +ENDCHAR +STARTCHAR integral +ENCODING 8747 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +28 +20 +20 +20 +20 +A0 +40 +ENDCHAR +STARTCHAR uni222E +ENCODING 8750 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +28 +20 +70 +70 +20 +A0 +40 +ENDCHAR +STARTCHAR therefore +ENCODING 8756 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2235 +ENCODING 8757 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +20 +00 +00 +ENDCHAR +STARTCHAR uni2236 +ENCODING 8758 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +00 +20 +00 +00 +ENDCHAR +STARTCHAR uni2237 +ENCODING 8759 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2238 +ENCODING 8760 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +60 +00 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR uni2239 +ENCODING 8761 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +C0 +10 +00 +00 +ENDCHAR +STARTCHAR uni223A +ENCODING 8762 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +90 +00 +F0 +00 +90 +00 +ENDCHAR +STARTCHAR uni223B +ENCODING 8763 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +00 +50 +A0 +00 +40 +00 +ENDCHAR +STARTCHAR similar +ENCODING 8764 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +A0 +00 +00 +00 +ENDCHAR +STARTCHAR uni223D +ENCODING 8765 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A0 +50 +00 +00 +00 +ENDCHAR +STARTCHAR uni2240 +ENCODING 8768 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +20 +40 +40 +20 +00 +ENDCHAR +STARTCHAR uni2242 +ENCODING 8770 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +00 +50 +A0 +00 +ENDCHAR +STARTCHAR uni2243 +ENCODING 8771 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +A0 +00 +F0 +00 +ENDCHAR +STARTCHAR congruent +ENCODING 8773 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A0 +00 +F0 +00 +F0 +00 +ENDCHAR +STARTCHAR approxequal +ENCODING 8776 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +A0 +50 +A0 +00 +ENDCHAR +STARTCHAR uni2249 +ENCODING 8777 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +A0 +50 +E0 +40 +ENDCHAR +STARTCHAR uni224A +ENCODING 8778 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A0 +50 +A0 +00 +F0 +00 +ENDCHAR +STARTCHAR uni224B +ENCODING 8779 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A0 +50 +A0 +50 +A0 +00 +ENDCHAR +STARTCHAR uni2258 +ENCODING 8792 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +00 +F0 +00 +F0 +00 +ENDCHAR +STARTCHAR uni2259 +ENCODING 8793 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +00 +F0 +00 +F0 +00 +ENDCHAR +STARTCHAR uni225A +ENCODING 8794 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +20 +00 +F0 +00 +F0 +00 +ENDCHAR +STARTCHAR uni225F +ENCODING 8799 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +20 +40 +00 +40 +F0 +00 +F0 +ENDCHAR +STARTCHAR notequal +ENCODING 8800 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +F0 +60 +F0 +40 +00 +ENDCHAR +STARTCHAR equivalence +ENCODING 8801 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F0 +00 +F0 +00 +F0 +00 +ENDCHAR +STARTCHAR uni2262 +ENCODING 8802 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +F0 +20 +F0 +40 +F0 +80 +ENDCHAR +STARTCHAR uni2263 +ENCODING 8803 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +00 +F0 +00 +F0 +00 +F0 +00 +ENDCHAR +STARTCHAR lessequal +ENCODING 8804 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +20 +40 +20 +10 +70 +00 +ENDCHAR +STARTCHAR greaterequal +ENCODING 8805 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +20 +10 +20 +40 +70 +00 +ENDCHAR +STARTCHAR uni226A +ENCODING 8810 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +28 +50 +A0 +50 +28 +00 +ENDCHAR +STARTCHAR uni226B +ENCODING 8811 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +A0 +50 +28 +50 +A0 +00 +ENDCHAR +STARTCHAR propersubset +ENCODING 8834 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +80 +70 +00 +00 +ENDCHAR +STARTCHAR propersuperset +ENCODING 8835 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +10 +E0 +00 +00 +ENDCHAR +STARTCHAR notsubset +ENCODING 8836 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +A0 +70 +20 +00 +ENDCHAR +STARTCHAR uni2285 +ENCODING 8837 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +E0 +50 +E0 +40 +00 +ENDCHAR +STARTCHAR reflexsubset +ENCODING 8838 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +80 +70 +00 +F0 +00 +ENDCHAR +STARTCHAR reflexsuperset +ENCODING 8839 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +E0 +10 +E0 +00 +F0 +00 +ENDCHAR +STARTCHAR uni2288 +ENCODING 8840 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A0 +70 +20 +F0 +20 +ENDCHAR +STARTCHAR uni2289 +ENCODING 8841 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +E0 +50 +E0 +40 +F0 +40 +ENDCHAR +STARTCHAR uni228A +ENCODING 8842 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +80 +70 +20 +F0 +40 +ENDCHAR +STARTCHAR uni228B +ENCODING 8843 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +E0 +10 +E0 +20 +F0 +40 +ENDCHAR +STARTCHAR circleplus +ENCODING 8853 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +A8 +F8 +A8 +70 +00 +ENDCHAR +STARTCHAR uni2296 +ENCODING 8854 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +88 +F8 +88 +70 +00 +ENDCHAR +STARTCHAR circlemultiply +ENCODING 8855 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +D8 +A8 +D8 +70 +00 +ENDCHAR +STARTCHAR uni2298 +ENCODING 8856 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +98 +A8 +C8 +70 +00 +ENDCHAR +STARTCHAR uni2299 +ENCODING 8857 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +88 +A8 +88 +70 +00 +ENDCHAR +STARTCHAR uni229E +ENCODING 8862 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F8 +A8 +F8 +A8 +F8 +00 +ENDCHAR +STARTCHAR uni229F +ENCODING 8863 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F8 +88 +F8 +88 +F8 +00 +ENDCHAR +STARTCHAR uni22A0 +ENCODING 8864 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F8 +D8 +A8 +D8 +F8 +00 +ENDCHAR +STARTCHAR uni22A1 +ENCODING 8865 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F8 +88 +A8 +88 +F8 +00 +ENDCHAR +STARTCHAR uni22A2 +ENCODING 8866 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +80 +F0 +80 +80 +00 +ENDCHAR +STARTCHAR uni22A3 +ENCODING 8867 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +10 +10 +F0 +10 +10 +00 +ENDCHAR +STARTCHAR uni22A4 +ENCODING 8868 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F8 +20 +20 +20 +20 +20 +00 +ENDCHAR +STARTCHAR perpendicular +ENCODING 8869 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +20 +20 +20 +F8 +00 +ENDCHAR +STARTCHAR uni22A6 +ENCODING 8870 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +40 +70 +40 +40 +00 +ENDCHAR +STARTCHAR uni22A7 +ENCODING 8871 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +70 +40 +70 +40 +00 +ENDCHAR +STARTCHAR uni22A8 +ENCODING 8872 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +F0 +80 +F0 +80 +00 +ENDCHAR +STARTCHAR uni22C0 +ENCODING 8896 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +50 +50 +50 +88 +88 +88 +ENDCHAR +STARTCHAR uni22C1 +ENCODING 8897 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +88 +88 +88 +50 +50 +50 +20 +20 +ENDCHAR +STARTCHAR uni22C2 +ENCODING 8898 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +88 +88 +88 +88 +88 +88 +ENDCHAR +STARTCHAR uni22C3 +ENCODING 8899 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +88 +88 +88 +88 +88 +88 +50 +20 +ENDCHAR +STARTCHAR dotmath +ENCODING 8901 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +20 +00 +00 +00 +ENDCHAR +STARTCHAR uni2300 +ENCODING 8960 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +A0 +50 +A0 +00 +ENDCHAR +STARTCHAR house +ENCODING 8962 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +60 +90 +90 +90 +90 +F0 +00 +ENDCHAR +STARTCHAR uni2308 +ENCODING 8968 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +40 +40 +40 +40 +40 +00 +ENDCHAR +STARTCHAR uni2309 +ENCODING 8969 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +10 +10 +10 +10 +10 +00 +ENDCHAR +STARTCHAR uni230A +ENCODING 8970 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +40 +40 +40 +70 +00 +ENDCHAR +STARTCHAR uni230B +ENCODING 8971 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +10 +10 +10 +70 +00 +ENDCHAR +STARTCHAR revlogicalnot +ENCODING 8976 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +40 +40 +00 +ENDCHAR +STARTCHAR uni2315 +ENCODING 8981 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +D0 +E0 +00 +ENDCHAR +STARTCHAR integraltp +ENCODING 8992 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +28 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR integralbt +ENCODING 8993 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +20 +20 +A0 +40 +00 +ENDCHAR +STARTCHAR uni23BA +ENCODING 9146 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BB +ENCODING 9147 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F8 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni23BC +ENCODING 9148 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +00 +ENDCHAR +STARTCHAR uni23BD +ENCODING 9149 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F8 +ENDCHAR +STARTCHAR uni2409 +ENCODING 9225 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +A0 +E0 +A0 +A0 +70 +20 +20 +ENDCHAR +STARTCHAR uni240A +ENCODING 9226 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +80 +E0 +38 +20 +30 +20 +ENDCHAR +STARTCHAR uni240B +ENCODING 9227 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A0 +A0 +A0 +40 +38 +10 +10 +10 +ENDCHAR +STARTCHAR uni240C +ENCODING 9228 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +80 +C0 +B8 +A0 +30 +20 +20 +ENDCHAR +STARTCHAR uni240D +ENCODING 9229 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +60 +80 +80 +60 +30 +28 +30 +28 +ENDCHAR +STARTCHAR uni2424 +ENCODING 9252 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +90 +D0 +B0 +90 +20 +20 +20 +38 +ENDCHAR +STARTCHAR SF100000 +ENCODING 9472 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2501 +ENCODING 9473 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR SF110000 +ENCODING 9474 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2503 +ENCODING 9475 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2504 +ENCODING 9476 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2505 +ENCODING 9477 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +A8 +00 +00 +00 +ENDCHAR +STARTCHAR uni2506 +ENCODING 9478 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +00 +20 +20 +00 +20 +20 +ENDCHAR +STARTCHAR uni2507 +ENCODING 9479 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +00 +30 +30 +00 +30 +30 +ENDCHAR +STARTCHAR uni2508 +ENCODING 9480 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2509 +ENCODING 9481 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +A8 +A8 +00 +00 +00 +ENDCHAR +STARTCHAR uni250A +ENCODING 9482 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +00 +20 +00 +20 +00 +20 +00 +ENDCHAR +STARTCHAR uni250B +ENCODING 9483 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +00 +30 +00 +30 +00 +30 +00 +ENDCHAR +STARTCHAR SF010000 +ENCODING 9484 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni250D +ENCODING 9485 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +38 +20 +20 +20 +ENDCHAR +STARTCHAR uni250E +ENCODING 9486 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni250F +ENCODING 9487 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +38 +30 +30 +30 +ENDCHAR +STARTCHAR SF030000 +ENCODING 9488 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2511 +ENCODING 9489 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +E0 +20 +20 +20 +ENDCHAR +STARTCHAR uni2512 +ENCODING 9490 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2513 +ENCODING 9491 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +F0 +30 +30 +30 +ENDCHAR +STARTCHAR SF020000 +ENCODING 9492 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2515 +ENCODING 9493 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +38 +00 +00 +00 +ENDCHAR +STARTCHAR uni2516 +ENCODING 9494 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +38 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2517 +ENCODING 9495 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +38 +38 +00 +00 +00 +ENDCHAR +STARTCHAR SF040000 +ENCODING 9496 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +E0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2519 +ENCODING 9497 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +E0 +E0 +00 +00 +00 +ENDCHAR +STARTCHAR uni251A +ENCODING 9498 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni251B +ENCODING 9499 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F0 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR SF080000 +ENCODING 9500 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni251D +ENCODING 9501 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +38 +20 +20 +20 +ENDCHAR +STARTCHAR uni251E +ENCODING 9502 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +38 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni251F +ENCODING 9503 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2520 +ENCODING 9504 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +38 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2521 +ENCODING 9505 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +38 +38 +20 +20 +20 +ENDCHAR +STARTCHAR uni2522 +ENCODING 9506 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +38 +38 +30 +30 +30 +ENDCHAR +STARTCHAR uni2523 +ENCODING 9507 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +38 +38 +30 +30 +30 +ENDCHAR +STARTCHAR SF090000 +ENCODING 9508 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +E0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2525 +ENCODING 9509 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +E0 +E0 +20 +20 +20 +ENDCHAR +STARTCHAR uni2526 +ENCODING 9510 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2527 +ENCODING 9511 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F0 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2528 +ENCODING 9512 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F0 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2529 +ENCODING 9513 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F0 +F0 +20 +20 +20 +ENDCHAR +STARTCHAR uni252A +ENCODING 9514 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F0 +F0 +30 +30 +30 +ENDCHAR +STARTCHAR uni252B +ENCODING 9515 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F0 +F0 +30 +30 +30 +ENDCHAR +STARTCHAR SF060000 +ENCODING 9516 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni252D +ENCODING 9517 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +E0 +20 +20 +20 +ENDCHAR +STARTCHAR uni252E +ENCODING 9518 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +38 +20 +20 +20 +ENDCHAR +STARTCHAR uni252F +ENCODING 9519 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +F8 +20 +20 +20 +ENDCHAR +STARTCHAR uni2530 +ENCODING 9520 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2531 +ENCODING 9521 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +F0 +30 +30 +30 +ENDCHAR +STARTCHAR uni2532 +ENCODING 9522 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +38 +30 +30 +30 +ENDCHAR +STARTCHAR uni2533 +ENCODING 9523 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +F8 +30 +30 +30 +ENDCHAR +STARTCHAR SF070000 +ENCODING 9524 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2535 +ENCODING 9525 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +E0 +00 +00 +00 +ENDCHAR +STARTCHAR uni2536 +ENCODING 9526 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +38 +00 +00 +00 +ENDCHAR +STARTCHAR uni2537 +ENCODING 9527 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR uni2538 +ENCODING 9528 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2539 +ENCODING 9529 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR uni253A +ENCODING 9530 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +38 +00 +00 +00 +ENDCHAR +STARTCHAR uni253B +ENCODING 9531 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR SF050000 +ENCODING 9532 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni253D +ENCODING 9533 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +E0 +20 +20 +20 +ENDCHAR +STARTCHAR uni253E +ENCODING 9534 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +38 +20 +20 +20 +ENDCHAR +STARTCHAR uni253F +ENCODING 9535 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +F8 +20 +20 +20 +ENDCHAR +STARTCHAR uni2540 +ENCODING 9536 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2541 +ENCODING 9537 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2542 +ENCODING 9538 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni2543 +ENCODING 9539 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +F0 +20 +20 +20 +ENDCHAR +STARTCHAR uni2544 +ENCODING 9540 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +38 +20 +20 +20 +ENDCHAR +STARTCHAR uni2545 +ENCODING 9541 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +F0 +30 +30 +30 +ENDCHAR +STARTCHAR uni2546 +ENCODING 9542 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +38 +30 +30 +30 +ENDCHAR +STARTCHAR uni2547 +ENCODING 9543 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +F8 +20 +20 +20 +ENDCHAR +STARTCHAR uni2548 +ENCODING 9544 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +F8 +F8 +30 +30 +30 +ENDCHAR +STARTCHAR uni2549 +ENCODING 9545 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +F0 +30 +30 +30 +ENDCHAR +STARTCHAR uni254A +ENCODING 9546 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +38 +30 +30 +30 +ENDCHAR +STARTCHAR uni254B +ENCODING 9547 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +F8 +F8 +30 +30 +30 +ENDCHAR +STARTCHAR uni254C +ENCODING 9548 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +B0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni254D +ENCODING 9549 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +B0 +B0 +00 +00 +00 +ENDCHAR +STARTCHAR uni254E +ENCODING 9550 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +00 +20 +20 +20 +00 +ENDCHAR +STARTCHAR uni254F +ENCODING 9551 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +00 +30 +30 +30 +00 +ENDCHAR +STARTCHAR SF430000 +ENCODING 9552 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F8 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR SF240000 +ENCODING 9553 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +50 +50 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF510000 +ENCODING 9554 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +38 +20 +38 +20 +20 +20 +ENDCHAR +STARTCHAR SF520000 +ENCODING 9555 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +78 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF390000 +ENCODING 9556 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +78 +40 +58 +50 +50 +50 +ENDCHAR +STARTCHAR SF220000 +ENCODING 9557 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +E0 +20 +E0 +20 +20 +20 +ENDCHAR +STARTCHAR SF210000 +ENCODING 9558 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF250000 +ENCODING 9559 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F0 +10 +D0 +50 +50 +50 +ENDCHAR +STARTCHAR SF500000 +ENCODING 9560 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +38 +20 +38 +00 +00 +00 +ENDCHAR +STARTCHAR SF490000 +ENCODING 9561 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +50 +78 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF380000 +ENCODING 9562 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +58 +40 +78 +00 +00 +00 +ENDCHAR +STARTCHAR SF280000 +ENCODING 9563 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +E0 +20 +E0 +00 +00 +00 +ENDCHAR +STARTCHAR SF270000 +ENCODING 9564 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +50 +F0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF260000 +ENCODING 9565 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +D0 +10 +F0 +00 +00 +00 +ENDCHAR +STARTCHAR SF360000 +ENCODING 9566 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +38 +20 +38 +20 +20 +20 +ENDCHAR +STARTCHAR SF370000 +ENCODING 9567 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +50 +58 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF420000 +ENCODING 9568 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +58 +40 +58 +50 +50 +50 +ENDCHAR +STARTCHAR SF190000 +ENCODING 9569 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +E0 +20 +E0 +20 +20 +20 +ENDCHAR +STARTCHAR SF200000 +ENCODING 9570 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +50 +D0 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF230000 +ENCODING 9571 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +D0 +10 +D0 +50 +50 +50 +ENDCHAR +STARTCHAR SF470000 +ENCODING 9572 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F8 +00 +F8 +20 +20 +20 +ENDCHAR +STARTCHAR SF480000 +ENCODING 9573 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF410000 +ENCODING 9574 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F8 +00 +D8 +50 +50 +50 +ENDCHAR +STARTCHAR SF450000 +ENCODING 9575 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +F8 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR SF460000 +ENCODING 9576 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +50 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR SF400000 +ENCODING 9577 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +D8 +00 +F8 +00 +00 +00 +ENDCHAR +STARTCHAR SF540000 +ENCODING 9578 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +F8 +20 +F8 +20 +20 +20 +ENDCHAR +STARTCHAR SF530000 +ENCODING 9579 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +50 +F8 +50 +50 +50 +50 +ENDCHAR +STARTCHAR SF440000 +ENCODING 9580 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +50 +D8 +00 +D8 +50 +50 +50 +ENDCHAR +STARTCHAR uni256D +ENCODING 9581 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +18 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni256E +ENCODING 9582 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +C0 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni256F +ENCODING 9583 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +C0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2570 +ENCODING 9584 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +18 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2571 +ENCODING 9585 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +08 +10 +10 +20 +20 +40 +40 +80 +ENDCHAR +STARTCHAR uni2572 +ENCODING 9586 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +40 +40 +20 +20 +10 +10 +08 +ENDCHAR +STARTCHAR uni2573 +ENCODING 9587 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +88 +50 +50 +20 +20 +50 +50 +88 +ENDCHAR +STARTCHAR uni2574 +ENCODING 9588 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2575 +ENCODING 9589 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +20 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2576 +ENCODING 9590 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2577 +ENCODING 9591 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +20 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2578 +ENCODING 9592 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +E0 +E0 +00 +00 +00 +ENDCHAR +STARTCHAR uni2579 +ENCODING 9593 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +30 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni257A +ENCODING 9594 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +38 +00 +00 +00 +ENDCHAR +STARTCHAR uni257B +ENCODING 9595 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni257C +ENCODING 9596 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +38 +00 +00 +00 +ENDCHAR +STARTCHAR uni257D +ENCODING 9597 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +20 +20 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR uni257E +ENCODING 9598 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +E0 +00 +00 +00 +ENDCHAR +STARTCHAR uni257F +ENCODING 9599 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +30 +30 +30 +30 +20 +20 +20 +ENDCHAR +STARTCHAR upblock +ENCODING 9600 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +F8 +F8 +F8 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2581 +ENCODING 9601 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +F8 +ENDCHAR +STARTCHAR uni2582 +ENCODING 9602 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +F8 +F8 +ENDCHAR +STARTCHAR uni2583 +ENCODING 9603 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +F8 +F8 +F8 +ENDCHAR +STARTCHAR dnblock +ENCODING 9604 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR uni2585 +ENCODING 9605 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR uni2586 +ENCODING 9606 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +F8 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR uni2587 +ENCODING 9607 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR block +ENCODING 9608 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +F8 +F8 +F8 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR uni2589 +ENCODING 9609 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +ENDCHAR +STARTCHAR uni258A +ENCODING 9610 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F0 +F0 +F0 +F0 +F0 +F0 +F0 +F0 +ENDCHAR +STARTCHAR uni258B +ENCODING 9611 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR lfblock +ENCODING 9612 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +E0 +E0 +E0 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni258D +ENCODING 9613 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR uni258E +ENCODING 9614 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR uni258F +ENCODING 9615 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +80 +80 +80 +80 +80 +80 +ENDCHAR +STARTCHAR rtblock +ENCODING 9616 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +18 +18 +18 +18 +18 +18 +18 +18 +ENDCHAR +STARTCHAR ltshade +ENCODING 9617 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +A8 +00 +50 +00 +A8 +00 +50 +00 +ENDCHAR +STARTCHAR shade +ENCODING 9618 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +A8 +50 +A8 +50 +A8 +50 +A8 +ENDCHAR +STARTCHAR dkshade +ENCODING 9619 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +50 +F8 +A8 +F8 +50 +F8 +A8 +F8 +ENDCHAR +STARTCHAR uni2594 +ENCODING 9620 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2595 +ENCODING 9621 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +08 +08 +08 +08 +08 +08 +08 +08 +ENDCHAR +STARTCHAR uni2596 +ENCODING 9622 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni2597 +ENCODING 9623 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +18 +18 +18 +18 +ENDCHAR +STARTCHAR uni2598 +ENCODING 9624 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +E0 +E0 +E0 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2599 +ENCODING 9625 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +E0 +E0 +E0 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR uni259A +ENCODING 9626 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +E0 +E0 +E0 +E0 +18 +18 +18 +18 +ENDCHAR +STARTCHAR uni259B +ENCODING 9627 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +F8 +F8 +F8 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni259C +ENCODING 9628 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +F8 +F8 +F8 +18 +18 +18 +18 +ENDCHAR +STARTCHAR uni259D +ENCODING 9629 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +18 +18 +18 +18 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni259E +ENCODING 9630 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +18 +18 +18 +18 +E0 +E0 +E0 +E0 +ENDCHAR +STARTCHAR uni259F +ENCODING 9631 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +18 +18 +18 +18 +F8 +F8 +F8 +F8 +ENDCHAR +STARTCHAR filledbox +ENCODING 9632 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +F0 +F0 +F0 +00 +ENDCHAR +STARTCHAR H22073 +ENCODING 9633 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +90 +90 +F0 +00 +ENDCHAR +STARTCHAR uni25A2 +ENCODING 9634 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR uni25A7 +ENCODING 9639 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +D0 +B0 +F0 +00 +ENDCHAR +STARTCHAR uni25A8 +ENCODING 9640 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +B0 +D0 +F0 +00 +ENDCHAR +STARTCHAR H18543 +ENCODING 9642 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +70 +70 +00 +00 +ENDCHAR +STARTCHAR H18551 +ENCODING 9643 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +70 +50 +70 +00 +00 +ENDCHAR +STARTCHAR filledrect +ENCODING 9644 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +F0 +F0 +00 +00 +ENDCHAR +STARTCHAR uni25AD +ENCODING 9645 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +90 +F0 +00 +00 +ENDCHAR +STARTCHAR uni25AE +ENCODING 9646 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +70 +70 +70 +70 +70 +00 +ENDCHAR +STARTCHAR uni25AF +ENCODING 9647 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +50 +50 +50 +50 +70 +00 +ENDCHAR +STARTCHAR uni25B0 +ENCODING 9648 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +70 +E0 +00 +00 +ENDCHAR +STARTCHAR uni25B1 +ENCODING 9649 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +38 +50 +E0 +00 +00 +ENDCHAR +STARTCHAR triagup +ENCODING 9650 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +70 +70 +F8 +F8 +00 +ENDCHAR +STARTCHAR uni25B3 +ENCODING 9651 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +50 +50 +88 +F8 +00 +ENDCHAR +STARTCHAR uni25B4 +ENCODING 9652 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +20 +70 +70 +00 +00 +ENDCHAR +STARTCHAR uni25B5 +ENCODING 9653 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +20 +50 +70 +00 +00 +ENDCHAR +STARTCHAR uni25B6 +ENCODING 9654 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +60 +70 +70 +60 +40 +00 +ENDCHAR +STARTCHAR uni25B7 +ENCODING 9655 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +60 +50 +50 +60 +40 +00 +ENDCHAR +STARTCHAR uni25B8 +ENCODING 9656 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +60 +70 +60 +40 +00 +ENDCHAR +STARTCHAR uni25B9 +ENCODING 9657 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +40 +60 +50 +60 +40 +00 +ENDCHAR +STARTCHAR triagrt +ENCODING 9658 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +E0 +F8 +E0 +80 +00 +ENDCHAR +STARTCHAR uni25BB +ENCODING 9659 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +80 +E0 +98 +E0 +80 +00 +ENDCHAR +STARTCHAR triagdn +ENCODING 9660 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F8 +F8 +70 +70 +20 +20 +00 +ENDCHAR +STARTCHAR uni25BD +ENCODING 9661 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +F8 +88 +50 +50 +20 +20 +00 +ENDCHAR +STARTCHAR uni25BE +ENCODING 9662 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +70 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni25BF +ENCODING 9663 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +50 +20 +20 +00 +00 +ENDCHAR +STARTCHAR uni25C0 +ENCODING 9664 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +30 +70 +70 +30 +10 +00 +ENDCHAR +STARTCHAR uni25C1 +ENCODING 9665 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +30 +50 +50 +30 +10 +00 +ENDCHAR +STARTCHAR uni25C2 +ENCODING 9666 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +10 +30 +70 +30 +10 +00 +ENDCHAR +STARTCHAR uni25C3 +ENCODING 9667 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +10 +30 +50 +30 +10 +00 +ENDCHAR +STARTCHAR triaglf +ENCODING 9668 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +08 +38 +F8 +38 +08 +00 +ENDCHAR +STARTCHAR uni25C5 +ENCODING 9669 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +08 +38 +C8 +38 +08 +00 +ENDCHAR +STARTCHAR uni25C6 +ENCODING 9670 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +70 +F8 +70 +20 +00 +ENDCHAR +STARTCHAR uni25C7 +ENCODING 9671 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +20 +50 +88 +50 +20 +00 +ENDCHAR +STARTCHAR lozenge +ENCODING 9674 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +50 +88 +50 +50 +20 +00 +ENDCHAR +STARTCHAR circle +ENCODING 9675 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +88 +88 +88 +70 +00 +ENDCHAR +STARTCHAR uni25CC +ENCODING 9676 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +50 +00 +88 +00 +50 +00 +ENDCHAR +STARTCHAR uni25CD +ENCODING 9677 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +A8 +A8 +A8 +70 +00 +ENDCHAR +STARTCHAR uni25CE +ENCODING 9678 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +A8 +D8 +A8 +70 +00 +ENDCHAR +STARTCHAR H18533 +ENCODING 9679 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +F8 +F8 +F8 +70 +00 +ENDCHAR +STARTCHAR uni25D0 +ENCODING 9680 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +E8 +E8 +E8 +70 +00 +ENDCHAR +STARTCHAR uni25D1 +ENCODING 9681 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +B8 +B8 +B8 +70 +00 +ENDCHAR +STARTCHAR uni25D2 +ENCODING 9682 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +88 +F8 +F8 +70 +00 +ENDCHAR +STARTCHAR uni25D3 +ENCODING 9683 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +F8 +F8 +88 +70 +00 +ENDCHAR +STARTCHAR uni25D4 +ENCODING 9684 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +B8 +B8 +88 +70 +00 +ENDCHAR +STARTCHAR uni25D5 +ENCODING 9685 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +98 +98 +F8 +70 +00 +ENDCHAR +STARTCHAR invbullet +ENCODING 9688 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +F8 +D8 +88 +88 +D8 +F8 +F8 +ENDCHAR +STARTCHAR invcircle +ENCODING 9689 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +D8 +A8 +70 +70 +A8 +D8 +F8 +ENDCHAR +STARTCHAR uni25DA +ENCODING 9690 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +F8 +D8 +A8 +70 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni25DB +ENCODING 9691 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +70 +A8 +D8 +F8 +ENDCHAR +STARTCHAR uni25E2 +ENCODING 9698 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +30 +70 +F0 +00 +ENDCHAR +STARTCHAR uni25E3 +ENCODING 9699 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +80 +C0 +E0 +F0 +00 +ENDCHAR +STARTCHAR uni25E4 +ENCODING 9700 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +E0 +C0 +80 +00 +ENDCHAR +STARTCHAR uni25E5 +ENCODING 9701 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +70 +30 +10 +00 +ENDCHAR +STARTCHAR openbullet +ENCODING 9702 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +60 +90 +90 +60 +00 +ENDCHAR +STARTCHAR uni25E7 +ENCODING 9703 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +D0 +D0 +F0 +00 +ENDCHAR +STARTCHAR uni25E8 +ENCODING 9704 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +B0 +B0 +F0 +00 +ENDCHAR +STARTCHAR uni25E9 +ENCODING 9705 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +F0 +D0 +F0 +00 +ENDCHAR +STARTCHAR uni25EA +ENCODING 9706 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +F0 +B0 +F0 +F0 +00 +ENDCHAR +STARTCHAR uni2625 +ENCODING 9765 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +50 +20 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2626 +ENCODING 9766 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +70 +20 +F8 +20 +30 +60 +20 +ENDCHAR +STARTCHAR uni2627 +ENCODING 9767 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +30 +28 +30 +20 +A8 +70 +A8 +00 +ENDCHAR +STARTCHAR uni2628 +ENCODING 9768 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +20 +70 +20 +F8 +20 +20 +20 +20 +ENDCHAR +STARTCHAR uni2629 +ENCODING 9769 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +20 +A8 +F8 +A8 +20 +70 +00 +ENDCHAR +STARTCHAR uni2630 +ENCODING 9776 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +00 +70 +00 +70 +00 +ENDCHAR +STARTCHAR uni2631 +ENCODING 9777 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +50 +00 +70 +00 +70 +00 +ENDCHAR +STARTCHAR uni2632 +ENCODING 9778 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +00 +50 +00 +70 +00 +ENDCHAR +STARTCHAR uni2633 +ENCODING 9779 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +50 +00 +50 +00 +70 +00 +ENDCHAR +STARTCHAR uni2634 +ENCODING 9780 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +00 +70 +00 +50 +00 +ENDCHAR +STARTCHAR uni2635 +ENCODING 9781 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +50 +00 +70 +00 +50 +00 +ENDCHAR +STARTCHAR uni2636 +ENCODING 9782 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +70 +00 +50 +00 +50 +00 +ENDCHAR +STARTCHAR uni2637 +ENCODING 9783 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +50 +00 +50 +00 +50 +00 +ENDCHAR +STARTCHAR uni2638 +ENCODING 9784 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +A8 +70 +50 +70 +A8 +20 +ENDCHAR +STARTCHAR smileface +ENCODING 9786 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +88 +D8 +88 +A8 +88 +70 +ENDCHAR +STARTCHAR invsmileface +ENCODING 9787 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +A8 +F8 +A8 +D8 +70 +00 +ENDCHAR +STARTCHAR sun +ENCODING 9788 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +88 +20 +50 +20 +88 +20 +ENDCHAR +STARTCHAR uni263D +ENCODING 9789 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +C8 +28 +28 +C8 +70 +00 +ENDCHAR +STARTCHAR uni263E +ENCODING 9790 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +98 +A0 +A0 +98 +70 +00 +ENDCHAR +STARTCHAR female +ENCODING 9792 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +70 +88 +88 +70 +20 +70 +20 +ENDCHAR +STARTCHAR uni2641 +ENCODING 9793 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +20 +70 +88 +88 +70 +ENDCHAR +STARTCHAR male +ENCODING 9794 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +38 +18 +68 +90 +90 +60 +ENDCHAR +STARTCHAR spade +ENCODING 9824 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +70 +F8 +20 +70 +00 +ENDCHAR +STARTCHAR uni2661 +ENCODING 9825 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A8 +88 +50 +20 +20 +00 +ENDCHAR +STARTCHAR uni2662 +ENCODING 9826 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +88 +50 +20 +00 +00 +ENDCHAR +STARTCHAR club +ENCODING 9827 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A8 +F8 +A8 +70 +00 +ENDCHAR +STARTCHAR uni2664 +ENCODING 9828 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +50 +F8 +20 +70 +00 +ENDCHAR +STARTCHAR heart +ENCODING 9829 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +F8 +F8 +70 +20 +20 +00 +ENDCHAR +STARTCHAR diamond +ENCODING 9830 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +F8 +70 +20 +00 +00 +ENDCHAR +STARTCHAR uni2667 +ENCODING 9831 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +70 +A8 +70 +20 +70 +00 +ENDCHAR +STARTCHAR uni2669 +ENCODING 9833 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +10 +10 +30 +70 +30 +00 +ENDCHAR +STARTCHAR musicalnote +ENCODING 9834 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +30 +28 +20 +60 +E0 +60 +00 +ENDCHAR +STARTCHAR musicalnotedbl +ENCODING 9835 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +60 +50 +D0 +D0 +30 +30 +00 +ENDCHAR +STARTCHAR uni266C +ENCODING 9836 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +40 +60 +50 +F0 +D0 +30 +30 +00 +ENDCHAR +STARTCHAR uni266D +ENCODING 9837 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +80 +A0 +D0 +90 +A0 +C0 +00 +ENDCHAR +STARTCHAR uni266E +ENCODING 9838 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +80 +80 +B0 +D0 +B0 +D0 +10 +10 +ENDCHAR +STARTCHAR uni266F +ENCODING 9839 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +10 +58 +70 +D0 +78 +D0 +40 +00 +ENDCHAR +STARTCHAR uni27E8 +ENCODING 10216 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +20 +40 +40 +20 +20 +00 +ENDCHAR +STARTCHAR uni27E9 +ENCODING 10217 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +40 +20 +20 +40 +40 +00 +ENDCHAR +STARTCHAR uni2800 +ENCODING 10240 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2801 +ENCODING 10241 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2802 +ENCODING 10242 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2803 +ENCODING 10243 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2804 +ENCODING 10244 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2805 +ENCODING 10245 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2806 +ENCODING 10246 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2807 +ENCODING 10247 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2808 +ENCODING 10248 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2809 +ENCODING 10249 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280A +ENCODING 10250 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280B +ENCODING 10251 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni280C +ENCODING 10252 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni280D +ENCODING 10253 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni280E +ENCODING 10254 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni280F +ENCODING 10255 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2810 +ENCODING 10256 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2811 +ENCODING 10257 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2812 +ENCODING 10258 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2813 +ENCODING 10259 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2814 +ENCODING 10260 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2815 +ENCODING 10261 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2816 +ENCODING 10262 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2817 +ENCODING 10263 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2818 +ENCODING 10264 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni2819 +ENCODING 10265 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281A +ENCODING 10266 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281B +ENCODING 10267 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +00 +00 +00 +ENDCHAR +STARTCHAR uni281C +ENCODING 10268 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni281D +ENCODING 10269 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni281E +ENCODING 10270 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni281F +ENCODING 10271 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +40 +00 +00 +ENDCHAR +STARTCHAR uni2820 +ENCODING 10272 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2821 +ENCODING 10273 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2822 +ENCODING 10274 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2823 +ENCODING 10275 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2824 +ENCODING 10276 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2825 +ENCODING 10277 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2826 +ENCODING 10278 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2827 +ENCODING 10279 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2828 +ENCODING 10280 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2829 +ENCODING 10281 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni282A +ENCODING 10282 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni282B +ENCODING 10283 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni282C +ENCODING 10284 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni282D +ENCODING 10285 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni282E +ENCODING 10286 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni282F +ENCODING 10287 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2830 +ENCODING 10288 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2831 +ENCODING 10289 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2832 +ENCODING 10290 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2833 +ENCODING 10291 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2834 +ENCODING 10292 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2835 +ENCODING 10293 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2836 +ENCODING 10294 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2837 +ENCODING 10295 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2838 +ENCODING 10296 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni2839 +ENCODING 10297 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni283A +ENCODING 10298 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni283B +ENCODING 10299 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +10 +00 +00 +ENDCHAR +STARTCHAR uni283C +ENCODING 10300 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni283D +ENCODING 10301 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni283E +ENCODING 10302 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni283F +ENCODING 10303 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +50 +00 +00 +ENDCHAR +STARTCHAR uni2840 +ENCODING 10304 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2841 +ENCODING 10305 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2842 +ENCODING 10306 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2843 +ENCODING 10307 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2844 +ENCODING 10308 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2845 +ENCODING 10309 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2846 +ENCODING 10310 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2847 +ENCODING 10311 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2848 +ENCODING 10312 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2849 +ENCODING 10313 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni284A +ENCODING 10314 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni284B +ENCODING 10315 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni284C +ENCODING 10316 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni284D +ENCODING 10317 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni284E +ENCODING 10318 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni284F +ENCODING 10319 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2850 +ENCODING 10320 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2851 +ENCODING 10321 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2852 +ENCODING 10322 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2853 +ENCODING 10323 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2854 +ENCODING 10324 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2855 +ENCODING 10325 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2856 +ENCODING 10326 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2857 +ENCODING 10327 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2858 +ENCODING 10328 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni2859 +ENCODING 10329 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni285A +ENCODING 10330 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni285B +ENCODING 10331 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +00 +00 +40 +ENDCHAR +STARTCHAR uni285C +ENCODING 10332 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni285D +ENCODING 10333 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni285E +ENCODING 10334 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni285F +ENCODING 10335 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +40 +00 +40 +ENDCHAR +STARTCHAR uni2860 +ENCODING 10336 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2861 +ENCODING 10337 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2862 +ENCODING 10338 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2863 +ENCODING 10339 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2864 +ENCODING 10340 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2865 +ENCODING 10341 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2866 +ENCODING 10342 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2867 +ENCODING 10343 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2868 +ENCODING 10344 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2869 +ENCODING 10345 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni286A +ENCODING 10346 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni286B +ENCODING 10347 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni286C +ENCODING 10348 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni286D +ENCODING 10349 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni286E +ENCODING 10350 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni286F +ENCODING 10351 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2870 +ENCODING 10352 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2871 +ENCODING 10353 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2872 +ENCODING 10354 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2873 +ENCODING 10355 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2874 +ENCODING 10356 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2875 +ENCODING 10357 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2876 +ENCODING 10358 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2877 +ENCODING 10359 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2878 +ENCODING 10360 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni2879 +ENCODING 10361 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni287A +ENCODING 10362 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni287B +ENCODING 10363 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +10 +00 +40 +ENDCHAR +STARTCHAR uni287C +ENCODING 10364 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni287D +ENCODING 10365 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni287E +ENCODING 10366 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni287F +ENCODING 10367 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +50 +00 +40 +ENDCHAR +STARTCHAR uni2880 +ENCODING 10368 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2881 +ENCODING 10369 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2882 +ENCODING 10370 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2883 +ENCODING 10371 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2884 +ENCODING 10372 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2885 +ENCODING 10373 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2886 +ENCODING 10374 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2887 +ENCODING 10375 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2888 +ENCODING 10376 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2889 +ENCODING 10377 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni288A +ENCODING 10378 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni288B +ENCODING 10379 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni288C +ENCODING 10380 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni288D +ENCODING 10381 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni288E +ENCODING 10382 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni288F +ENCODING 10383 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2890 +ENCODING 10384 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2891 +ENCODING 10385 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2892 +ENCODING 10386 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2893 +ENCODING 10387 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2894 +ENCODING 10388 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2895 +ENCODING 10389 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2896 +ENCODING 10390 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2897 +ENCODING 10391 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni2898 +ENCODING 10392 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni2899 +ENCODING 10393 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni289A +ENCODING 10394 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni289B +ENCODING 10395 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +00 +00 +10 +ENDCHAR +STARTCHAR uni289C +ENCODING 10396 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni289D +ENCODING 10397 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni289E +ENCODING 10398 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni289F +ENCODING 10399 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +40 +00 +10 +ENDCHAR +STARTCHAR uni28A0 +ENCODING 10400 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28A1 +ENCODING 10401 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28A2 +ENCODING 10402 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28A3 +ENCODING 10403 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28A4 +ENCODING 10404 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28A5 +ENCODING 10405 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28A6 +ENCODING 10406 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28A7 +ENCODING 10407 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28A8 +ENCODING 10408 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28A9 +ENCODING 10409 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28AA +ENCODING 10410 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28AB +ENCODING 10411 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28AC +ENCODING 10412 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28AD +ENCODING 10413 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28AE +ENCODING 10414 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28AF +ENCODING 10415 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28B0 +ENCODING 10416 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28B1 +ENCODING 10417 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28B2 +ENCODING 10418 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28B3 +ENCODING 10419 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28B4 +ENCODING 10420 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28B5 +ENCODING 10421 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28B6 +ENCODING 10422 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28B7 +ENCODING 10423 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28B8 +ENCODING 10424 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28B9 +ENCODING 10425 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28BA +ENCODING 10426 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28BB +ENCODING 10427 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +10 +00 +10 +ENDCHAR +STARTCHAR uni28BC +ENCODING 10428 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28BD +ENCODING 10429 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28BE +ENCODING 10430 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28BF +ENCODING 10431 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +50 +00 +10 +ENDCHAR +STARTCHAR uni28C0 +ENCODING 10432 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28C1 +ENCODING 10433 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28C2 +ENCODING 10434 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28C3 +ENCODING 10435 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28C4 +ENCODING 10436 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28C5 +ENCODING 10437 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28C6 +ENCODING 10438 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28C7 +ENCODING 10439 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28C8 +ENCODING 10440 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28C9 +ENCODING 10441 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28CA +ENCODING 10442 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28CB +ENCODING 10443 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28CC +ENCODING 10444 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28CD +ENCODING 10445 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28CE +ENCODING 10446 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28CF +ENCODING 10447 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28D0 +ENCODING 10448 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28D1 +ENCODING 10449 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28D2 +ENCODING 10450 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28D3 +ENCODING 10451 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28D4 +ENCODING 10452 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28D5 +ENCODING 10453 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28D6 +ENCODING 10454 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28D7 +ENCODING 10455 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28D8 +ENCODING 10456 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28D9 +ENCODING 10457 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28DA +ENCODING 10458 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28DB +ENCODING 10459 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +00 +00 +50 +ENDCHAR +STARTCHAR uni28DC +ENCODING 10460 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28DD +ENCODING 10461 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28DE +ENCODING 10462 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28DF +ENCODING 10463 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +40 +00 +50 +ENDCHAR +STARTCHAR uni28E0 +ENCODING 10464 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28E1 +ENCODING 10465 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28E2 +ENCODING 10466 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28E3 +ENCODING 10467 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28E4 +ENCODING 10468 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +00 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28E5 +ENCODING 10469 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +00 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28E6 +ENCODING 10470 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +40 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28E7 +ENCODING 10471 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +40 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28E8 +ENCODING 10472 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28E9 +ENCODING 10473 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28EA +ENCODING 10474 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28EB +ENCODING 10475 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28EC +ENCODING 10476 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +00 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28ED +ENCODING 10477 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +00 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28EE +ENCODING 10478 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +40 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28EF +ENCODING 10479 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +40 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28F0 +ENCODING 10480 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28F1 +ENCODING 10481 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28F2 +ENCODING 10482 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28F3 +ENCODING 10483 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28F4 +ENCODING 10484 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +10 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28F5 +ENCODING 10485 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +10 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28F6 +ENCODING 10486 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +00 +00 +50 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28F7 +ENCODING 10487 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +40 +00 +50 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28F8 +ENCODING 10488 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28F9 +ENCODING 10489 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28FA +ENCODING 10490 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28FB +ENCODING 10491 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +10 +00 +50 +ENDCHAR +STARTCHAR uni28FC +ENCODING 10492 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +10 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28FD +ENCODING 10493 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +10 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28FE +ENCODING 10494 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +10 +00 +50 +00 +50 +00 +50 +ENDCHAR +STARTCHAR uni28FF +ENCODING 10495 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +00 +50 +00 +50 +00 +50 +ENDCHAR +STARTCHAR ff +ENCODING 64256 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +50 +A8 +A0 +F0 +A0 +A0 +00 +ENDCHAR +STARTCHAR fi +ENCODING 64257 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +20 +50 +40 +F0 +50 +50 +00 +ENDCHAR +STARTCHAR fl +ENCODING 64258 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +00 +30 +50 +50 +F0 +50 +50 +00 +ENDCHAR +STARTCHAR uniFFFD +ENCODING 65533 +SWIDTH 436 0 +DWIDTH 5 0 +BBX 5 8 0 -1 +BITMAP +70 +D8 +A8 +E8 +D8 +F8 +D8 +70 +ENDCHAR +ENDFONT diff --git a/gui/themes/fonts/helvB12-iso-8859-2.bdf b/gui/themes/fonts/helvB12-iso-8859-2.bdf new file mode 100644 index 00000000000..6757e20c872 --- /dev/null +++ b/gui/themes/fonts/helvB12-iso-8859-2.bdf @@ -0,0 +1,3105 @@ +STARTFONT 2.1 +COMMENT AUTOMATICALLY GENERATED FILE. DO NOT EDIT! +COMMENT Generated with 'ucs2any helvB12.bdf /usr/share/fonts/X11/util/map-ISO8859-2 ISO8859-2' +COMMENT from an ISO10646-1 encoded source BDF font. +COMMENT ucs2any by Ben Collver , 2003, based on +COMMENT ucs2any.pl by Markus Kuhn , 2000. +FONT -Adobe-Helvetica-Bold-R-Normal--12-120-75-75-P-70-ISO8859-2 +SIZE 12 75 75 +FONTBOUNDINGBOX 12 16 -1 -3 +COMMENT $Xorg: $ +COMMENT ISO10646-1 extension by Markus Kuhn , 2001-03-20 +COMMENT +COMMENT + +COMMENT Copyright 1984-1989, 1994 Adobe Systems Incorporated. +COMMENT Copyright 1988, 1994 Digital Equipment Corporation. +COMMENT +COMMENT Adobe is a trademark of Adobe Systems Incorporated which may be +COMMENT registered in certain jurisdictions. +COMMENT Permission to use these trademarks is hereby granted only in +COMMENT association with the images described in this file. +COMMENT +COMMENT Permission to use, copy, modify, distribute and sell this software +COMMENT and its documentation for any purpose and without fee is hereby +COMMENT granted, provided that the above copyright notices appear in all +COMMENT copies and that both those copyright notices and this permission +COMMENT notice appear in supporting documentation, and that the names of +COMMENT Adobe Systems and Digital Equipment Corporation not be used in +COMMENT advertising or publicity pertaining to distribution of the software +COMMENT without specific, written prior permission. Adobe Systems and +COMMENT Digital Equipment Corporation make no representations about the +COMMENT suitability of this software for any purpose. It is provided "as +COMMENT is" without express or implied warranty. +COMMENT - +STARTPROPERTIES 26 +FOUNDRY "Adobe" +FAMILY_NAME "Helvetica" +WEIGHT_NAME "Bold" +SLANT "R" +SETWIDTH_NAME "Normal" +ADD_STYLE_NAME "" +PIXEL_SIZE 12 +POINT_SIZE 120 +RESOLUTION_X 75 +RESOLUTION_Y 75 +SPACING "P" +AVERAGE_WIDTH 70 +CHARSET_REGISTRY "ISO8859" +CHARSET_ENCODING "2" +CAP_HEIGHT 9 +X_HEIGHT 7 +FONT_ASCENT 11 +FONT_DESCENT 3 +FACE_NAME "Helvetica Bold" +COPYRIGHT "Copyright (c) 1984, 1987 Adobe Systems Incorporated. All Rights Reserved. Copyright (c) 1988, 1991 Digital Equipment Corporation. All Rights Reserved." +NOTICE "Helvetica is a trademark of Linotype-Hell AG and/or its subsidiaries. " +_DEC_DEVICE_FONTNAMES "PS=Helvetica-Bold" +DEFAULT_CHAR 0 +RELATIVE_SETWIDTH 50 +RELATIVE_WEIGHT 70 +FULL_NAME "Helvetica Bold" +ENDPROPERTIES +CHARS 192 +STARTCHAR defaultchar +ENCODING 0 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +AA +00 +82 +00 +82 +00 +82 +00 +AA +ENDCHAR +STARTCHAR space +ENCODING 32 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR exclam +ENCODING 33 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 2 9 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +80 +00 +C0 +C0 +ENDCHAR +STARTCHAR quotedbl +ENCODING 34 +SWIDTH 474 0 +DWIDTH 5 0 +BBX 3 3 1 6 +BITMAP +A0 +A0 +A0 +ENDCHAR +STARTCHAR numbersign +ENCODING 35 +SWIDTH 556 0 +DWIDTH 8 0 +BBX 7 8 0 0 +BITMAP +14 +14 +7E +28 +28 +FC +50 +50 +ENDCHAR +STARTCHAR dollar +ENCODING 36 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 11 0 -2 +BITMAP +10 +78 +D4 +D0 +78 +1C +94 +D4 +78 +10 +10 +ENDCHAR +STARTCHAR percent +ENCODING 37 +SWIDTH 889 0 +DWIDTH 12 0 +BBX 11 9 0 0 +BITMAP +7100 +DB00 +DA00 +7400 +0400 +09C0 +0B60 +1B60 +11C0 +ENDCHAR +STARTCHAR ampersand +ENCODING 38 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 9 9 0 0 +BITMAP +3800 +6C00 +6C00 +3800 +7900 +CF00 +C600 +CF00 +7980 +ENDCHAR +STARTCHAR quotesingle +ENCODING 39 +SWIDTH 238 0 +DWIDTH 3 0 +BBX 1 3 1 6 +BITMAP +80 +80 +80 +ENDCHAR +STARTCHAR parenleft +ENCODING 40 +SWIDTH 333 0 +DWIDTH 6 0 +BBX 4 12 1 -3 +BITMAP +30 +60 +60 +C0 +C0 +C0 +C0 +C0 +C0 +60 +60 +30 +ENDCHAR +STARTCHAR parenright +ENCODING 41 +SWIDTH 333 0 +DWIDTH 6 0 +BBX 4 12 1 -3 +BITMAP +C0 +60 +60 +30 +30 +30 +30 +30 +30 +60 +60 +C0 +ENDCHAR +STARTCHAR asterisk +ENCODING 42 +SWIDTH 389 0 +DWIDTH 6 0 +BBX 5 4 0 5 +BITMAP +20 +F8 +70 +50 +ENDCHAR +STARTCHAR plus +ENCODING 43 +SWIDTH 584 0 +DWIDTH 7 0 +BBX 6 5 0 1 +BITMAP +30 +30 +FC +30 +30 +ENDCHAR +STARTCHAR comma +ENCODING 44 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 2 4 1 -2 +BITMAP +C0 +C0 +40 +80 +ENDCHAR +STARTCHAR hyphen +ENCODING 45 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 4 1 0 3 +BITMAP +F0 +ENDCHAR +STARTCHAR period +ENCODING 46 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 2 2 1 0 +BITMAP +C0 +C0 +ENDCHAR +STARTCHAR slash +ENCODING 47 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 4 9 0 0 +BITMAP +30 +30 +20 +60 +60 +40 +40 +C0 +C0 +ENDCHAR +STARTCHAR zero +ENCODING 48 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +78 +CC +CC +CC +CC +CC +CC +CC +78 +ENDCHAR +STARTCHAR one +ENCODING 49 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 4 9 0 0 +BITMAP +30 +F0 +30 +30 +30 +30 +30 +30 +30 +ENDCHAR +STARTCHAR two +ENCODING 50 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +78 +CC +0C +18 +30 +60 +C0 +C0 +FC +ENDCHAR +STARTCHAR three +ENCODING 51 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +78 +CC +0C +38 +0C +0C +0C +CC +78 +ENDCHAR +STARTCHAR four +ENCODING 52 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 9 0 0 +BITMAP +0C +1C +2C +2C +4C +8C +FE +0C +0C +ENDCHAR +STARTCHAR five +ENCODING 53 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +7C +60 +C0 +F8 +0C +0C +CC +CC +78 +ENDCHAR +STARTCHAR six +ENCODING 54 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +78 +CC +C0 +C0 +F8 +CC +CC +CC +78 +ENDCHAR +STARTCHAR seven +ENCODING 55 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +FC +0C +18 +18 +30 +30 +30 +60 +60 +ENDCHAR +STARTCHAR eight +ENCODING 56 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +78 +CC +CC +78 +CC +CC +CC +CC +78 +ENDCHAR +STARTCHAR nine +ENCODING 57 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +78 +CC +CC +CC +7C +0C +0C +CC +78 +ENDCHAR +STARTCHAR colon +ENCODING 58 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 2 7 1 0 +BITMAP +C0 +C0 +00 +00 +00 +C0 +C0 +ENDCHAR +STARTCHAR semicolon +ENCODING 59 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 2 9 1 -2 +BITMAP +C0 +C0 +00 +00 +00 +C0 +C0 +40 +80 +ENDCHAR +STARTCHAR less +ENCODING 60 +SWIDTH 584 0 +DWIDTH 7 0 +BBX 5 5 1 1 +BITMAP +18 +70 +C0 +70 +18 +ENDCHAR +STARTCHAR equal +ENCODING 61 +SWIDTH 584 0 +DWIDTH 7 0 +BBX 6 3 0 2 +BITMAP +FC +00 +FC +ENDCHAR +STARTCHAR greater +ENCODING 62 +SWIDTH 584 0 +DWIDTH 7 0 +BBX 5 5 1 1 +BITMAP +C0 +70 +18 +70 +C0 +ENDCHAR +STARTCHAR question +ENCODING 63 +SWIDTH 611 0 +DWIDTH 8 0 +BBX 6 9 1 0 +BITMAP +78 +CC +CC +18 +30 +30 +00 +30 +30 +ENDCHAR +STARTCHAR at +ENCODING 64 +SWIDTH 975 0 +DWIDTH 12 0 +BBX 10 10 1 -1 +BITMAP +1F00 +6080 +4040 +8D40 +9240 +A240 +A680 +9B00 +4000 +3E00 +ENDCHAR +STARTCHAR A +ENCODING 65 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 8 9 0 0 +BITMAP +18 +3C +24 +66 +66 +7E +C3 +C3 +C3 +ENDCHAR +STARTCHAR B +ENCODING 66 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +FC +C6 +C6 +C6 +FC +C6 +C6 +C6 +FC +ENDCHAR +STARTCHAR C +ENCODING 67 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 7 9 1 0 +BITMAP +3C +66 +C0 +C0 +C0 +C0 +C0 +66 +3C +ENDCHAR +STARTCHAR D +ENCODING 68 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +F8 +CC +C6 +C6 +C6 +C6 +C6 +CC +F8 +ENDCHAR +STARTCHAR E +ENCODING 69 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 6 9 1 0 +BITMAP +FC +C0 +C0 +C0 +FC +C0 +C0 +C0 +FC +ENDCHAR +STARTCHAR F +ENCODING 70 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 9 1 0 +BITMAP +FC +C0 +C0 +C0 +F8 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR G +ENCODING 71 +SWIDTH 778 0 +DWIDTH 10 0 +BBX 8 9 1 0 +BITMAP +3E +63 +C0 +C0 +CF +C3 +C3 +63 +3D +ENDCHAR +STARTCHAR H +ENCODING 72 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +C6 +C6 +C6 +C6 +FE +C6 +C6 +C6 +C6 +ENDCHAR +STARTCHAR I +ENCODING 73 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 2 9 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR J +ENCODING 74 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +0C +0C +0C +0C +0C +0C +CC +CC +78 +ENDCHAR +STARTCHAR K +ENCODING 75 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 8 9 1 0 +BITMAP +C6 +CC +D8 +F0 +F0 +D8 +CC +C6 +C3 +ENDCHAR +STARTCHAR L +ENCODING 76 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 9 1 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +FC +ENDCHAR +STARTCHAR M +ENCODING 77 +SWIDTH 833 0 +DWIDTH 11 0 +BBX 9 9 1 0 +BITMAP +C180 +C180 +E380 +E380 +F780 +D580 +DD80 +C980 +C980 +ENDCHAR +STARTCHAR N +ENCODING 78 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +C6 +E6 +E6 +D6 +D6 +CE +CE +C6 +C6 +ENDCHAR +STARTCHAR O +ENCODING 79 +SWIDTH 778 0 +DWIDTH 10 0 +BBX 8 9 1 0 +BITMAP +3C +66 +C3 +C3 +C3 +C3 +C3 +66 +3C +ENDCHAR +STARTCHAR P +ENCODING 80 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 7 9 1 0 +BITMAP +FC +C6 +C6 +C6 +FC +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR Q +ENCODING 81 +SWIDTH 778 0 +DWIDTH 10 0 +BBX 8 9 1 0 +BITMAP +3C +66 +C3 +C3 +C3 +CB +CF +66 +3F +ENDCHAR +STARTCHAR R +ENCODING 82 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +FC +C6 +C6 +C6 +FC +CC +C6 +C6 +C6 +ENDCHAR +STARTCHAR S +ENCODING 83 +SWIDTH 667 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +7C +C6 +C6 +70 +1C +0E +C6 +C6 +7C +ENDCHAR +STARTCHAR T +ENCODING 84 +SWIDTH 611 0 +DWIDTH 8 0 +BBX 8 9 0 0 +BITMAP +FF +18 +18 +18 +18 +18 +18 +18 +18 +ENDCHAR +STARTCHAR U +ENCODING 85 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 9 1 0 +BITMAP +C6 +C6 +C6 +C6 +C6 +C6 +C6 +6C +7C +ENDCHAR +STARTCHAR V +ENCODING 86 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 8 9 0 0 +BITMAP +C3 +C3 +66 +66 +66 +24 +3C +18 +18 +ENDCHAR +STARTCHAR W +ENCODING 87 +SWIDTH 944 0 +DWIDTH 10 0 +BBX 10 9 0 0 +BITMAP +CCC0 +CCC0 +CCC0 +4C80 +6D80 +6D80 +3300 +3300 +3300 +ENDCHAR +STARTCHAR X +ENCODING 88 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 8 9 0 0 +BITMAP +C3 +C3 +66 +3C +18 +3C +66 +C3 +C3 +ENDCHAR +STARTCHAR Y +ENCODING 89 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 8 9 0 0 +BITMAP +C3 +C3 +66 +66 +3C +18 +18 +18 +18 +ENDCHAR +STARTCHAR Z +ENCODING 90 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 7 9 0 0 +BITMAP +FE +06 +0C +18 +30 +30 +60 +C0 +FE +ENDCHAR +STARTCHAR bracketleft +ENCODING 91 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 3 12 1 -3 +BITMAP +E0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +E0 +ENDCHAR +STARTCHAR backslash +ENCODING 92 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 4 9 0 0 +BITMAP +C0 +C0 +40 +60 +60 +20 +20 +30 +30 +ENDCHAR +STARTCHAR bracketright +ENCODING 93 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 3 12 0 -3 +BITMAP +E0 +60 +60 +60 +60 +60 +60 +60 +60 +60 +60 +E0 +ENDCHAR +STARTCHAR asciicircum +ENCODING 94 +SWIDTH 584 0 +DWIDTH 7 0 +BBX 7 4 0 5 +BITMAP +10 +38 +6C +C6 +ENDCHAR +STARTCHAR underscore +ENCODING 95 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 1 0 -3 +BITMAP +FE +ENDCHAR +STARTCHAR grave +ENCODING 96 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 3 2 0 8 +BITMAP +C0 +60 +ENDCHAR +STARTCHAR a +ENCODING 97 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 7 0 0 +BITMAP +78 +CC +0C +7C +CC +CC +76 +ENDCHAR +STARTCHAR b +ENCODING 98 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +C0 +C0 +D8 +EC +CC +CC +CC +EC +D8 +ENDCHAR +STARTCHAR c +ENCODING 99 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 7 0 0 +BITMAP +78 +CC +C0 +C0 +C0 +CC +78 +ENDCHAR +STARTCHAR d +ENCODING 100 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +0C +0C +6C +DC +CC +CC +CC +DC +6C +ENDCHAR +STARTCHAR e +ENCODING 101 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 7 0 0 +BITMAP +78 +CC +CC +FC +C0 +CC +78 +ENDCHAR +STARTCHAR f +ENCODING 102 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 5 9 0 0 +BITMAP +38 +60 +F0 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR g +ENCODING 103 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 -3 +BITMAP +6C +DC +CC +CC +CC +DC +6C +0C +CC +78 +ENDCHAR +STARTCHAR h +ENCODING 104 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +C0 +C0 +D8 +EC +CC +CC +CC +CC +CC +ENDCHAR +STARTCHAR i +ENCODING 105 +SWIDTH 278 0 +DWIDTH 3 0 +BBX 2 9 0 0 +BITMAP +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR j +ENCODING 106 +SWIDTH 278 0 +DWIDTH 3 0 +BBX 3 12 -1 -3 +BITMAP +60 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +C0 +ENDCHAR +STARTCHAR k +ENCODING 107 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 9 0 0 +BITMAP +C0 +C0 +CC +D8 +F0 +F0 +D8 +CC +C6 +ENDCHAR +STARTCHAR l +ENCODING 108 +SWIDTH 278 0 +DWIDTH 3 0 +BBX 2 9 0 0 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR m +ENCODING 109 +SWIDTH 889 0 +DWIDTH 11 0 +BBX 10 7 0 0 +BITMAP +BB80 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +CCC0 +ENDCHAR +STARTCHAR n +ENCODING 110 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 7 0 0 +BITMAP +D8 +EC +CC +CC +CC +CC +CC +ENDCHAR +STARTCHAR o +ENCODING 111 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 7 0 0 +BITMAP +78 +CC +CC +CC +CC +CC +78 +ENDCHAR +STARTCHAR p +ENCODING 112 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 -3 +BITMAP +D8 +EC +CC +CC +CC +EC +D8 +C0 +C0 +C0 +ENDCHAR +STARTCHAR q +ENCODING 113 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 -3 +BITMAP +74 +DC +CC +CC +CC +DC +6C +0C +0C +0C +ENDCHAR +STARTCHAR r +ENCODING 114 +SWIDTH 389 0 +DWIDTH 5 0 +BBX 5 7 0 0 +BITMAP +D8 +F8 +E0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR s +ENCODING 115 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 7 0 0 +BITMAP +78 +CC +E0 +38 +1C +CC +78 +ENDCHAR +STARTCHAR t +ENCODING 116 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 5 9 0 0 +BITMAP +60 +60 +F0 +60 +60 +60 +60 +68 +30 +ENDCHAR +STARTCHAR u +ENCODING 117 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 7 0 0 +BITMAP +CC +CC +CC +CC +CC +DC +6C +ENDCHAR +STARTCHAR v +ENCODING 118 +SWIDTH 556 0 +DWIDTH 8 0 +BBX 7 7 0 0 +BITMAP +C6 +C6 +6C +6C +38 +38 +10 +ENDCHAR +STARTCHAR w +ENCODING 119 +SWIDTH 778 0 +DWIDTH 11 0 +BBX 10 7 0 0 +BITMAP +CCC0 +CCC0 +6D80 +6D80 +6D80 +3300 +3300 +ENDCHAR +STARTCHAR x +ENCODING 120 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 7 0 0 +BITMAP +CC +CC +78 +30 +78 +CC +CC +ENDCHAR +STARTCHAR y +ENCODING 121 +SWIDTH 556 0 +DWIDTH 8 0 +BBX 7 10 0 -3 +BITMAP +C6 +C6 +6C +6C +38 +38 +18 +10 +30 +60 +ENDCHAR +STARTCHAR z +ENCODING 122 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 5 7 0 0 +BITMAP +F8 +18 +30 +20 +60 +C0 +F8 +ENDCHAR +STARTCHAR braceleft +ENCODING 123 +SWIDTH 389 0 +DWIDTH 5 0 +BBX 4 12 0 -3 +BITMAP +30 +60 +60 +60 +60 +C0 +60 +60 +60 +60 +60 +30 +ENDCHAR +STARTCHAR bar +ENCODING 124 +SWIDTH 280 0 +DWIDTH 4 0 +BBX 2 12 1 -3 +BITMAP +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR braceright +ENCODING 125 +SWIDTH 389 0 +DWIDTH 5 0 +BBX 4 12 0 -3 +BITMAP +C0 +60 +60 +60 +60 +30 +60 +60 +60 +60 +60 +C0 +ENDCHAR +STARTCHAR asciitilde +ENCODING 126 +SWIDTH 584 0 +DWIDTH 7 0 +BBX 7 2 0 3 +BITMAP +76 +DC +ENDCHAR +STARTCHAR space +ENCODING 160 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 1 1 0 0 +BITMAP +00 +ENDCHAR +STARTCHAR Aogonek +ENCODING 161 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 8 12 0 -3 +BITMAP +18 +3C +24 +66 +66 +7E +C3 +C3 +DB +30 +30 +1C +ENDCHAR +STARTCHAR breve +ENCODING 162 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 5 2 0 8 +BITMAP +88 +70 +ENDCHAR +STARTCHAR Lslash +ENCODING 163 +SWIDTH 611 0 +DWIDTH 8 0 +BBX 7 9 0 0 +BITMAP +60 +60 +78 +70 +E0 +60 +60 +60 +7E +ENDCHAR +STARTCHAR currency +ENCODING 164 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 6 0 1 +BITMAP +CC +78 +48 +48 +78 +CC +ENDCHAR +STARTCHAR Lcaron +ENCODING 165 +SWIDTH 858 0 +DWIDTH 11 0 +BBX 9 9 1 0 +BITMAP +C180 +C080 +C100 +C000 +C000 +C000 +C000 +C000 +FC00 +ENDCHAR +STARTCHAR Sacute +ENCODING 166 +SWIDTH 667 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +18 +30 +00 +7C +C6 +C6 +70 +1C +0E +C6 +C6 +7C +ENDCHAR +STARTCHAR section +ENCODING 167 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 12 0 -3 +BITMAP +78 +CC +E0 +70 +D8 +CC +CC +6C +38 +1C +CC +78 +ENDCHAR +STARTCHAR dieresis +ENCODING 168 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 5 1 0 8 +BITMAP +D8 +ENDCHAR +STARTCHAR Scaron +ENCODING 169 +SWIDTH 667 0 +DWIDTH 9 0 +BBX 7 10 1 0 +BITMAP +6C +38 +00 +78 +CC +E0 +78 +1C +CE +7C +ENDCHAR +STARTCHAR Scedilla +ENCODING 170 +SWIDTH 667 0 +DWIDTH 9 0 +BBX 7 12 1 -3 +BITMAP +7C +C6 +C6 +70 +1C +0E +C6 +C6 +7C +18 +18 +70 +ENDCHAR +STARTCHAR Tcaron +ENCODING 171 +SWIDTH 611 0 +DWIDTH 8 0 +BBX 8 12 0 0 +BITMAP +36 +1C +00 +FF +18 +18 +18 +18 +18 +18 +18 +18 +ENDCHAR +STARTCHAR Zacute +ENCODING 172 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 7 12 0 0 +BITMAP +0C +18 +00 +FE +06 +0C +18 +30 +30 +60 +C0 +FE +ENDCHAR +STARTCHAR hyphen +ENCODING 173 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 4 1 0 3 +BITMAP +F0 +ENDCHAR +STARTCHAR Zcaron +ENCODING 174 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 7 10 0 0 +BITMAP +6C +38 +00 +FC +18 +30 +30 +60 +C0 +FE +ENDCHAR +STARTCHAR Zdotaccent +ENCODING 175 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 7 11 0 0 +BITMAP +18 +00 +FE +06 +0C +18 +30 +30 +60 +C0 +FE +ENDCHAR +STARTCHAR degree +ENCODING 176 +SWIDTH 400 0 +DWIDTH 5 0 +BBX 4 4 0 4 +BITMAP +60 +90 +90 +60 +ENDCHAR +STARTCHAR aogonek +ENCODING 177 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 10 0 -3 +BITMAP +78 +CC +0C +7C +CC +CC +7E +30 +30 +1C +ENDCHAR +STARTCHAR ogonek +ENCODING 178 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 4 4 0 -3 +BITMAP +60 +C0 +C0 +70 +ENDCHAR +STARTCHAR lslash +ENCODING 179 +SWIDTH 278 0 +DWIDTH 3 0 +BBX 4 9 -1 0 +BITMAP +60 +60 +70 +60 +E0 +60 +60 +60 +60 +ENDCHAR +STARTCHAR acute +ENCODING 180 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 3 2 0 8 +BITMAP +60 +C0 +ENDCHAR +STARTCHAR lcaron +ENCODING 181 +SWIDTH 542 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +CC +C4 +C8 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR sacute +ENCODING 182 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +18 +30 +00 +78 +CC +E0 +38 +1C +CC +78 +ENDCHAR +STARTCHAR caron +ENCODING 183 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 5 2 0 8 +BITMAP +D8 +70 +ENDCHAR +STARTCHAR cedilla +ENCODING 184 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 4 4 0 -3 +BITMAP +60 +30 +30 +E0 +ENDCHAR +STARTCHAR scaron +ENCODING 185 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +D8 +70 +00 +78 +CC +E0 +38 +1C +CC +78 +ENDCHAR +STARTCHAR scedilla +ENCODING 186 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 -3 +BITMAP +78 +CC +E0 +38 +1C +CC +78 +18 +18 +70 +ENDCHAR +STARTCHAR tcaron +ENCODING 187 +SWIDTH 594 0 +DWIDTH 9 0 +BBX 8 9 0 0 +BITMAP +63 +61 +F2 +60 +60 +60 +60 +68 +30 +ENDCHAR +STARTCHAR zacute +ENCODING 188 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 5 10 0 0 +BITMAP +18 +30 +00 +F8 +18 +30 +20 +60 +C0 +F8 +ENDCHAR +STARTCHAR hungarumlaut +ENCODING 189 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 5 2 1 8 +BITMAP +68 +B0 +ENDCHAR +STARTCHAR zcaron +ENCODING 190 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 5 10 0 0 +BITMAP +D8 +70 +00 +F8 +18 +30 +20 +60 +C0 +F8 +ENDCHAR +STARTCHAR zdotaccent +ENCODING 191 +SWIDTH 500 0 +DWIDTH 6 0 +BBX 5 9 0 0 +BITMAP +30 +00 +F8 +18 +30 +20 +60 +C0 +F8 +ENDCHAR +STARTCHAR Racute +ENCODING 192 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +18 +30 +00 +FC +C6 +C6 +C6 +FC +CC +C6 +C6 +C6 +ENDCHAR +STARTCHAR Aacute +ENCODING 193 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 8 12 0 0 +BITMAP +0C +18 +00 +18 +18 +3C +24 +66 +7E +C3 +C3 +C3 +ENDCHAR +STARTCHAR Acircumflex +ENCODING 194 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 8 12 0 0 +BITMAP +1C +36 +00 +18 +18 +3C +24 +66 +7E +C3 +C3 +C3 +ENDCHAR +STARTCHAR Abreve +ENCODING 195 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 8 12 0 0 +BITMAP +22 +1C +00 +18 +3C +24 +66 +66 +7E +C3 +C3 +C3 +ENDCHAR +STARTCHAR Adieresis +ENCODING 196 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 8 11 0 0 +BITMAP +36 +00 +18 +18 +3C +24 +66 +7E +C3 +C3 +C3 +ENDCHAR +STARTCHAR Lacute +ENCODING 197 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 12 1 0 +BITMAP +30 +60 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +FC +ENDCHAR +STARTCHAR Cacute +ENCODING 198 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 7 12 1 0 +BITMAP +18 +30 +00 +3C +66 +C0 +C0 +C0 +C0 +C0 +66 +3C +ENDCHAR +STARTCHAR Ccedilla +ENCODING 199 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 7 12 1 -3 +BITMAP +3C +66 +C0 +C0 +C0 +C0 +C0 +66 +3C +18 +18 +70 +ENDCHAR +STARTCHAR Ccaron +ENCODING 200 +SWIDTH 722 0 +DWIDTH 8 0 +BBX 7 12 1 0 +BITMAP +6C +38 +00 +3C +66 +C0 +C0 +C0 +C0 +C0 +66 +3C +ENDCHAR +STARTCHAR Eacute +ENCODING 201 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 6 12 1 0 +BITMAP +18 +30 +00 +FC +C0 +C0 +C0 +FC +C0 +C0 +C0 +FC +ENDCHAR +STARTCHAR Eogonek +ENCODING 202 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 6 12 1 -3 +BITMAP +FC +C0 +C0 +C0 +FC +C0 +C0 +C0 +FC +60 +60 +38 +ENDCHAR +STARTCHAR Edieresis +ENCODING 203 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 6 11 1 0 +BITMAP +6C +00 +FC +C0 +C0 +C0 +FC +C0 +C0 +C0 +FC +ENDCHAR +STARTCHAR Ecaron +ENCODING 204 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 6 12 1 0 +BITMAP +D8 +70 +00 +FC +C0 +C0 +C0 +FC +C0 +C0 +C0 +FC +ENDCHAR +STARTCHAR Iacute +ENCODING 205 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 3 12 1 0 +BITMAP +60 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR Icircumflex +ENCODING 206 +SWIDTH 278 0 +DWIDTH 4 0 +BBX 5 12 0 0 +BITMAP +70 +D8 +00 +60 +60 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR Dcaron +ENCODING 207 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +6C +38 +00 +F8 +CC +C6 +C6 +C6 +C6 +C6 +CC +F8 +ENDCHAR +STARTCHAR Dcroat +ENCODING 208 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 8 9 0 0 +BITMAP +7C +66 +63 +63 +F3 +63 +63 +66 +7C +ENDCHAR +STARTCHAR Nacute +ENCODING 209 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +18 +30 +00 +C6 +E6 +E6 +D6 +D6 +CE +CE +C6 +C6 +ENDCHAR +STARTCHAR Ncaron +ENCODING 210 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +6C +38 +00 +C6 +E6 +E6 +D6 +D6 +CE +CE +C6 +C6 +ENDCHAR +STARTCHAR Oacute +ENCODING 211 +SWIDTH 778 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +0C +18 +00 +3C +66 +C3 +C3 +C3 +C3 +C3 +66 +3C +ENDCHAR +STARTCHAR Ocircumflex +ENCODING 212 +SWIDTH 778 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +1C +36 +00 +3C +66 +C3 +C3 +C3 +C3 +C3 +66 +3C +ENDCHAR +STARTCHAR Ohungarumlaut +ENCODING 213 +SWIDTH 778 0 +DWIDTH 10 0 +BBX 8 12 1 0 +BITMAP +1A +2C +00 +3C +66 +C3 +C3 +C3 +C3 +C3 +66 +3C +ENDCHAR +STARTCHAR Odieresis +ENCODING 214 +SWIDTH 778 0 +DWIDTH 10 0 +BBX 8 11 1 0 +BITMAP +66 +00 +3C +66 +C3 +C3 +C3 +C3 +C3 +66 +3C +ENDCHAR +STARTCHAR multiply +ENCODING 215 +SWIDTH 584 0 +DWIDTH 7 0 +BBX 6 5 0 1 +BITMAP +CC +78 +30 +78 +CC +ENDCHAR +STARTCHAR Rcaron +ENCODING 216 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +6C +38 +00 +FC +C6 +C6 +C6 +FC +CC +C6 +C6 +C6 +ENDCHAR +STARTCHAR Uring +ENCODING 217 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 13 1 0 +BITMAP +38 +6C +38 +00 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +6C +7C +ENDCHAR +STARTCHAR Uacute +ENCODING 218 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +0C +18 +00 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +6C +7C +ENDCHAR +STARTCHAR Uhungarumlaut +ENCODING 219 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 12 1 0 +BITMAP +34 +58 +00 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +6C +7C +ENDCHAR +STARTCHAR Udieresis +ENCODING 220 +SWIDTH 722 0 +DWIDTH 9 0 +BBX 7 11 1 0 +BITMAP +6C +00 +C6 +C6 +C6 +C6 +C6 +C6 +C6 +6C +7C +ENDCHAR +STARTCHAR Yacute +ENCODING 221 +SWIDTH 667 0 +DWIDTH 8 0 +BBX 8 12 0 0 +BITMAP +0C +18 +00 +C3 +C3 +66 +66 +24 +3C +18 +18 +18 +ENDCHAR +STARTCHAR Tcommaaccent +ENCODING 222 +SWIDTH 611 0 +DWIDTH 8 0 +BBX 8 12 0 -3 +BITMAP +FF +18 +18 +18 +18 +18 +18 +18 +18 +0C +0C +38 +ENDCHAR +STARTCHAR germandbls +ENCODING 223 +SWIDTH 611 0 +DWIDTH 8 0 +BBX 6 9 1 0 +BITMAP +78 +CC +CC +CC +D8 +CC +CC +CC +D8 +ENDCHAR +STARTCHAR racute +ENCODING 224 +SWIDTH 389 0 +DWIDTH 5 0 +BBX 5 10 0 0 +BITMAP +30 +60 +00 +D8 +F8 +E0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR aacute +ENCODING 225 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 10 0 0 +BITMAP +18 +30 +00 +78 +CC +0C +7C +CC +CC +76 +ENDCHAR +STARTCHAR acircumflex +ENCODING 226 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 10 0 0 +BITMAP +38 +6C +00 +78 +CC +0C +7C +CC +CC +76 +ENDCHAR +STARTCHAR abreve +ENCODING 227 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 10 0 0 +BITMAP +44 +38 +00 +78 +CC +0C +7C +CC +CC +76 +ENDCHAR +STARTCHAR adieresis +ENCODING 228 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 7 9 0 0 +BITMAP +6C +00 +78 +CC +0C +7C +CC +CC +76 +ENDCHAR +STARTCHAR lacute +ENCODING 229 +SWIDTH 278 0 +DWIDTH 3 0 +BBX 3 12 0 0 +BITMAP +60 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR cacute +ENCODING 230 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +18 +30 +00 +78 +CC +C0 +C0 +C0 +CC +78 +ENDCHAR +STARTCHAR ccedilla +ENCODING 231 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 -3 +BITMAP +78 +CC +C0 +C0 +C0 +CC +78 +10 +18 +70 +ENDCHAR +STARTCHAR ccaron +ENCODING 232 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +6C +38 +00 +78 +CC +C0 +C0 +C0 +CC +78 +ENDCHAR +STARTCHAR eacute +ENCODING 233 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +18 +30 +00 +78 +CC +CC +FC +C0 +CC +78 +ENDCHAR +STARTCHAR eogonek +ENCODING 234 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 -3 +BITMAP +78 +CC +CC +FC +C0 +CC +78 +60 +60 +38 +ENDCHAR +STARTCHAR edieresis +ENCODING 235 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +6C +00 +78 +CC +CC +FC +C0 +CC +78 +ENDCHAR +STARTCHAR ecaron +ENCODING 236 +SWIDTH 556 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +6C +38 +00 +78 +CC +CC +FC +C0 +CC +78 +ENDCHAR +STARTCHAR iacute +ENCODING 237 +SWIDTH 278 0 +DWIDTH 3 0 +BBX 3 10 0 0 +BITMAP +60 +C0 +00 +C0 +C0 +C0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR icircumflex +ENCODING 238 +SWIDTH 278 0 +DWIDTH 3 0 +BBX 5 10 -1 0 +BITMAP +70 +D8 +00 +60 +60 +60 +60 +60 +60 +60 +ENDCHAR +STARTCHAR dcaron +ENCODING 239 +SWIDTH 858 0 +DWIDTH 11 0 +BBX 10 9 0 0 +BITMAP +0CC0 +0C40 +6C80 +DC00 +CC00 +CC00 +CC00 +DC00 +6C00 +ENDCHAR +STARTCHAR dcroat +ENCODING 240 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 7 9 0 0 +BITMAP +0C +3E +6C +DC +CC +CC +CC +DC +6C +ENDCHAR +STARTCHAR nacute +ENCODING 241 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +18 +30 +00 +D8 +EC +CC +CC +CC +CC +CC +ENDCHAR +STARTCHAR ncaron +ENCODING 242 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +D8 +70 +00 +D8 +EC +CC +CC +CC +CC +CC +ENDCHAR +STARTCHAR oacute +ENCODING 243 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +18 +30 +00 +78 +CC +CC +CC +CC +CC +78 +ENDCHAR +STARTCHAR ocircumflex +ENCODING 244 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +38 +6C +00 +78 +CC +CC +CC +CC +CC +78 +ENDCHAR +STARTCHAR ohungarumlaut +ENCODING 245 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +34 +58 +00 +78 +CC +CC +CC +CC +CC +78 +ENDCHAR +STARTCHAR odieresis +ENCODING 246 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +6C +00 +78 +CC +CC +CC +CC +CC +78 +ENDCHAR +STARTCHAR divide +ENCODING 247 +SWIDTH 584 0 +DWIDTH 7 0 +BBX 6 5 0 1 +BITMAP +30 +00 +FC +00 +30 +ENDCHAR +STARTCHAR rcaron +ENCODING 248 +SWIDTH 389 0 +DWIDTH 5 0 +BBX 5 10 0 0 +BITMAP +D8 +70 +00 +D8 +F8 +E0 +C0 +C0 +C0 +C0 +ENDCHAR +STARTCHAR uring +ENCODING 249 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 11 0 0 +BITMAP +38 +6C +38 +00 +CC +CC +CC +CC +CC +DC +6C +ENDCHAR +STARTCHAR uacute +ENCODING 250 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +18 +30 +00 +CC +CC +CC +CC +CC +DC +6C +ENDCHAR +STARTCHAR uhungarumlaut +ENCODING 251 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 10 0 0 +BITMAP +34 +58 +00 +CC +CC +CC +CC +CC +DC +6C +ENDCHAR +STARTCHAR udieresis +ENCODING 252 +SWIDTH 611 0 +DWIDTH 7 0 +BBX 6 9 0 0 +BITMAP +6C +00 +CC +CC +CC +CC +CC +DC +6C +ENDCHAR +STARTCHAR yacute +ENCODING 253 +SWIDTH 556 0 +DWIDTH 8 0 +BBX 7 13 0 -3 +BITMAP +0C +18 +00 +C6 +C6 +6C +6C +38 +38 +18 +10 +30 +60 +ENDCHAR +STARTCHAR tcommaaccent +ENCODING 254 +SWIDTH 333 0 +DWIDTH 5 0 +BBX 5 12 0 -3 +BITMAP +60 +60 +F0 +60 +60 +60 +60 +68 +70 +30 +30 +E0 +ENDCHAR +STARTCHAR dotaccent +ENCODING 255 +SWIDTH 333 0 +DWIDTH 4 0 +BBX 2 1 1 8 +BITMAP +C0 +ENDCHAR +ENDFONT diff --git a/gui/themes/modern.zip b/gui/themes/modern.zip index 1847d2aa6a9..22cfb7a1ad3 100644 Binary files a/gui/themes/modern.zip and b/gui/themes/modern.zip differ diff --git a/gui/themes/modern/THEMERC b/gui/themes/modern/THEMERC index cc3589714a3..7dde6f4c42e 100644 --- a/gui/themes/modern/THEMERC +++ b/gui/themes/modern/THEMERC @@ -1 +1 @@ -[RESIDUAL_STX0.8:Residual Modern Theme:No Author] +[RESIDUAL_STX0.8.3:Residual Modern Theme:No Author] diff --git a/gui/themes/modern/clR6x12-iso-8859-2.fcc b/gui/themes/modern/clR6x12-iso-8859-2.fcc new file mode 100644 index 00000000000..042bc5b24d3 Binary files /dev/null and b/gui/themes/modern/clR6x12-iso-8859-2.fcc differ diff --git a/gui/themes/modern/fixed5x8-iso-8859-2.fcc b/gui/themes/modern/fixed5x8-iso-8859-2.fcc new file mode 100644 index 00000000000..73bb5fff2d4 Binary files /dev/null and b/gui/themes/modern/fixed5x8-iso-8859-2.fcc differ diff --git a/gui/themes/modern/helvb12-iso-8859-2.fcc b/gui/themes/modern/helvb12-iso-8859-2.fcc new file mode 100644 index 00000000000..2117b6b9e6f Binary files /dev/null and b/gui/themes/modern/helvb12-iso-8859-2.fcc differ diff --git a/gui/themes/modern/modern_gfx.stx b/gui/themes/modern/modern_gfx.stx index cbc5cc29418..f41bb4650ca 100644 --- a/gui/themes/modern/modern_gfx.stx +++ b/gui/themes/modern/modern_gfx.stx @@ -108,21 +108,21 @@ - - - @@ -178,7 +178,7 @@ - + diff --git a/gui/themes/modern/modern_layout.stx b/gui/themes/modern/modern_layout.stx index 665dacba611..4db1f539cff 100644 --- a/gui/themes/modern/modern_layout.stx +++ b/gui/themes/modern/modern_layout.stx @@ -23,7 +23,7 @@ - $Id$ - --> - + @@ -233,6 +233,9 @@ + @@ -344,7 +347,7 @@ - + - + @@ -214,6 +214,9 @@ + diff --git a/gui/themes/residualtheme.py b/gui/themes/residualtheme.py deleted file mode 100644 index a8c46818d4c..00000000000 --- a/gui/themes/residualtheme.py +++ /dev/null @@ -1,97 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 -import sys -import re -import os -import zipfile - -THEME_FILE_EXTENSIONS = ('.stx', '.bmp', '.fcc') - -def buildTheme(themeName): - if not os.path.isdir(themeName) or not os.path.isfile(os.path.join(themeName, "THEMERC")): - print ("Invalid theme name: " + themeName) - return - - zf = zipfile.ZipFile(themeName + ".zip", 'w') - - print ("Building '" + themeName + "' theme:") - os.chdir(themeName) - - zf.write('THEMERC', './THEMERC') - - for filename in os.listdir('.'): - if os.path.isfile(filename) and not filename[0] == '.' and filename.endswith(THEME_FILE_EXTENSIONS): - zf.write(filename, './' + filename) - print (" Adding file: " + filename) - - os.chdir('../') - - zf.close() - -def buildAllThemes(): - for f in os.listdir('.'): - if os.path.isdir(os.path.join('.', f)) and not f[0] == '.': - buildTheme(f) - -def parseSTX(theme_file, def_file): - comm = re.compile("", re.DOTALL) - head = re.compile("<\?(.*?)\?>") - - output = "" - for line in theme_file: - output += line.rstrip("\r\n\t ").lstrip() + " \n" - - output = re.sub(comm, "", output) - output = re.sub(head, "", output) - output = output.replace("\t", " ").replace(" ", " ").replace("\"", "'") - output = output.replace(" = ", "=").replace(", ", ",") - - for line in output.splitlines(): - if line and not line.isspace(): - def_file.write("\"" + line + "\"\n") - -def buildDefTheme(themeName): - def_file = open("default.inc", "w") - - if not os.path.isdir(themeName): - print ("Cannot open default theme dir.") - - def_file.write(""" ""\n""") - - for filename in os.listdir(themeName): - filename = os.path.join(themeName, filename) - if os.path.isfile(filename) and filename.endswith(".stx"): - theme_file = open(filename, "r") - parseSTX(theme_file, def_file) - theme_file.close() - - def_file.close() - -def printUsage(): - print ("===============================") - print ("Residual Theme Generation Script") - print ("===============================") - print ("Usage:") - print ("residualtheme.py makeall") - print (" Builds all the available themes.\n") - print ("residualtheme.py make [themename]") - print (" Builds the theme called 'themename'.\n") - print ("residualtheme.py default [themename]") - print (" Creates a 'default.inc' file to embed the given theme in the source code.\n") - -def main(): - - if len(sys.argv) == 2 and sys.argv[1] == "makeall": - buildAllThemes() - - elif len(sys.argv) == 3 and sys.argv[1] == "make": - buildTheme(sys.argv[2]) - - elif len(sys.argv) == 3 and sys.argv[1] == "default": - buildDefTheme(sys.argv[2]) - - else: - printUsage() - -if __name__ == "__main__": - sys.exit(main()) diff --git a/gui/widget.cpp b/gui/widget.cpp index b89d5c18bd3..3296c16ea71 100644 --- a/gui/widget.cpp +++ b/gui/widget.cpp @@ -26,7 +26,7 @@ #include "graphics/fontman.h" #include "gui/widget.h" #include "gui/dialog.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/ThemeEval.h" @@ -215,7 +215,7 @@ uint8 Widget::parseHotkey(const Common::String &label) { Common::String Widget::cleanupHotkey(const Common::String &label) { Common::String res; - for (uint i = 0; i < label.size() ; i++) + for (uint i = 0; i < label.size(); i++) if (label[i] != '~') res = res + label[i]; @@ -303,6 +303,58 @@ void ButtonWidget::drawWidget() { #pragma mark - +PicButtonWidget::PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip, uint32 cmd, uint8 hotkey) + : Widget(boss, x, y, w, h, tooltip), CommandSender(boss), + _cmd(cmd), _hotkey(hotkey), _gfx(), _alpha(256), _transparency(false) { + + setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG); + _type = kButtonWidget; +} + +PicButtonWidget::PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip, uint32 cmd, uint8 hotkey) + : Widget(boss, name, tooltip), CommandSender(boss), + _cmd(cmd), _gfx(), _alpha(256), _transparency(false) { + setFlags(WIDGET_ENABLED/* | WIDGET_BORDER*/ | WIDGET_CLEARBG); + _type = kButtonWidget; +} + +PicButtonWidget::~PicButtonWidget() { + _gfx.free(); +} + +void PicButtonWidget::handleMouseUp(int x, int y, int button, int clickCount) { + if (isEnabled() && x >= 0 && x < _w && y >= 0 && y < _h) + sendCommand(_cmd, 0); +} + +void PicButtonWidget::setGfx(const Graphics::Surface *gfx) { + _gfx.free(); + + if (!gfx || !gfx->pixels) + return; + + if (gfx->w > _w || gfx->h > _h) { + warning("PicButtonWidget has size %dx%d, but a surface with %dx%d is to be set", _w, _h, gfx->w, gfx->h); + return; + } + + // TODO: add conversion to OverlayColor + _gfx.copyFrom(*gfx); +} + +void PicButtonWidget::drawWidget() { + g_gui.theme()->drawButton(Common::Rect(_x, _y, _x+_w, _y+_h), "", _state, getFlags()); + + if (sizeof(OverlayColor) == _gfx.bytesPerPixel && _gfx.pixels) { + const int x = _x + (_w - _gfx.w) / 2; + const int y = _y + (_h - _gfx.h) / 2; + + g_gui.theme()->drawSurface(Common::Rect(x, y, x + _gfx.w, y + _gfx.h), _gfx, _state, _alpha, _transparency); + } +} + +#pragma mark - + CheckboxWidget::CheckboxWidget(GuiObject *boss, int x, int y, int w, int h, const Common::String &label, const char *tooltip, uint32 cmd, uint8 hotkey) : ButtonWidget(boss, x, y, w, h, label, tooltip, cmd, hotkey), _state(false) { setFlags(WIDGET_ENABLED); diff --git a/gui/widget.h b/gui/widget.h index 28fc6d94a79..4c07eb58365 100644 --- a/gui/widget.h +++ b/gui/widget.h @@ -198,6 +198,37 @@ protected: void drawWidget(); }; +/* PicButtonWidget */ +class PicButtonWidget : public Widget, public CommandSender { + friend class Dialog; // Needed for the hotkey handling +protected: + uint32 _cmd; + uint8 _hotkey; +public: + PicButtonWidget(GuiObject *boss, int x, int y, int w, int h, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0); + PicButtonWidget(GuiObject *boss, const Common::String &name, const char *tooltip = 0, uint32 cmd = 0, uint8 hotkey = 0); + ~PicButtonWidget(); + + void setCmd(uint32 cmd) { _cmd = cmd; } + uint32 getCmd() const { return _cmd; } + + void setGfx(const Graphics::Surface *gfx); + + void useAlpha(int alpha) { _alpha = alpha; } + void useThemeTransparency(bool enable) { _transparency = enable; } + + void handleMouseUp(int x, int y, int button, int clickCount); + void handleMouseEntered(int button) { setFlags(WIDGET_HILITED); draw(); } + void handleMouseLeft(int button) { clearFlags(WIDGET_HILITED); draw(); } + +protected: + void drawWidget(); + + Graphics::Surface _gfx; + int _alpha; + bool _transparency; +}; + /* CheckboxWidget */ class CheckboxWidget : public ButtonWidget { protected: diff --git a/gui/editable.cpp b/gui/widgets/editable.cpp similarity index 99% rename from gui/editable.cpp rename to gui/widgets/editable.cpp index 0707d946aa9..218328f8138 100644 --- a/gui/editable.cpp +++ b/gui/widgets/editable.cpp @@ -23,8 +23,8 @@ */ #include "common/events.h" -#include "gui/editable.h" -#include "gui/GuiManager.h" +#include "gui/widgets/editable.h" +#include "gui/gui-manager.h" namespace GUI { diff --git a/gui/editable.h b/gui/widgets/editable.h similarity index 97% rename from gui/editable.h rename to gui/widgets/editable.h index f2f05928e3e..8493aa45486 100644 --- a/gui/editable.h +++ b/gui/widgets/editable.h @@ -22,13 +22,12 @@ * $Id$ */ -#ifndef GUI_EDITABLE_H -#define GUI_EDITABLE_H +#ifndef GUI_WIDGETS_EDITABLE_H +#define GUI_WIDGETS_EDITABLE_H #include "common/str.h" #include "common/rect.h" #include "gui/widget.h" -#include "gui/GuiManager.h" namespace GUI { diff --git a/gui/EditTextWidget.cpp b/gui/widgets/edittext.cpp similarity index 98% rename from gui/EditTextWidget.cpp rename to gui/widgets/edittext.cpp index 6ece117a035..1acc40b34b1 100644 --- a/gui/EditTextWidget.cpp +++ b/gui/widgets/edittext.cpp @@ -22,9 +22,9 @@ * $Id$ */ -#include "gui/EditTextWidget.h" +#include "gui/widgets/edittext.h" #include "gui/dialog.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/ThemeEval.h" diff --git a/gui/EditTextWidget.h b/gui/widgets/edittext.h similarity index 95% rename from gui/EditTextWidget.h rename to gui/widgets/edittext.h index 49e0c0482d1..9d4587566b0 100644 --- a/gui/EditTextWidget.h +++ b/gui/widgets/edittext.h @@ -22,10 +22,10 @@ * $Id$ */ -#ifndef GUI_EDITTEXTWIDGET_H -#define GUI_EDITTEXTWIDGET_H +#ifndef GUI_WIDGETS_EDITTEXT_H +#define GUI_WIDGETS_EDITTEXT_H -#include "gui/editable.h" +#include "gui/widgets/editable.h" #include "common/str.h" namespace GUI { diff --git a/gui/ListWidget.cpp b/gui/widgets/list.cpp similarity index 99% rename from gui/ListWidget.cpp rename to gui/widgets/list.cpp index 3a8ce681b41..0bf518c989d 100644 --- a/gui/ListWidget.cpp +++ b/gui/widgets/list.cpp @@ -27,10 +27,10 @@ #include "common/frac.h" #include "common/tokenizer.h" -#include "gui/ListWidget.h" -#include "gui/ScrollBarWidget.h" +#include "gui/widgets/list.h" +#include "gui/widgets/scrollbar.h" #include "gui/dialog.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/ThemeEval.h" diff --git a/gui/ListWidget.h b/gui/widgets/list.h similarity index 98% rename from gui/ListWidget.h rename to gui/widgets/list.h index 313a1139c13..f3a348591d2 100644 --- a/gui/ListWidget.h +++ b/gui/widgets/list.h @@ -22,10 +22,10 @@ * $Id$ */ -#ifndef GUI_LISTWIDGET_H -#define GUI_LISTWIDGET_H +#ifndef GUI_WIDGETS_LIST_H +#define GUI_WIDGETS_LIST_H -#include "gui/editable.h" +#include "gui/widgets/editable.h" #include "common/str.h" #include "gui/ThemeEngine.h" diff --git a/gui/PopUpWidget.cpp b/gui/widgets/popup.cpp similarity index 99% rename from gui/PopUpWidget.cpp rename to gui/widgets/popup.cpp index 154b4dd47e6..284c35c67d4 100644 --- a/gui/PopUpWidget.cpp +++ b/gui/widgets/popup.cpp @@ -25,8 +25,8 @@ #include "common/system.h" #include "common/events.h" #include "gui/dialog.h" -#include "gui/GuiManager.h" -#include "gui/PopUpWidget.h" +#include "gui/gui-manager.h" +#include "gui/widgets/popup.h" #include "engines/engine.h" #include "gui/ThemeEval.h" diff --git a/gui/PopUpWidget.h b/gui/widgets/popup.h similarity index 98% rename from gui/PopUpWidget.h rename to gui/widgets/popup.h index e870677cc58..2c965ebb946 100644 --- a/gui/PopUpWidget.h +++ b/gui/widgets/popup.h @@ -22,8 +22,8 @@ * $Id$ */ -#ifndef POPUPWIDGET_H -#define POPUPWIDGET_H +#ifndef GUI_WIDGETS_POPUP_H +#define GUI_WIDGETS_POPUP_H #include "gui/widget.h" #include "common/str.h" diff --git a/gui/ScrollBarWidget.cpp b/gui/widgets/scrollbar.cpp similarity index 99% rename from gui/ScrollBarWidget.cpp rename to gui/widgets/scrollbar.cpp index f510fcfb2b3..798713faa01 100644 --- a/gui/ScrollBarWidget.cpp +++ b/gui/widgets/scrollbar.cpp @@ -22,9 +22,9 @@ * $Id$ */ -#include "ScrollBarWidget.h" +#include "gui/widgets/scrollbar.h" #include "gui/dialog.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "common/timer.h" diff --git a/gui/ScrollBarWidget.h b/gui/widgets/scrollbar.h similarity index 97% rename from gui/ScrollBarWidget.h rename to gui/widgets/scrollbar.h index 96761089ada..05a81bbc1aa 100644 --- a/gui/ScrollBarWidget.h +++ b/gui/widgets/scrollbar.h @@ -22,8 +22,8 @@ * $Id$ */ -#ifndef SCROLLBARWIDGET_H -#define SCROLLBARWIDGET_H +#ifndef GUI_WIDGETS_SCROLLBAR_H +#define GUI_WIDGETS_SCROLLBAR_H #include "gui/widget.h" diff --git a/gui/TabWidget.cpp b/gui/widgets/tab.cpp similarity index 99% rename from gui/TabWidget.cpp rename to gui/widgets/tab.cpp index 6bc38336fb3..60c4e340eb8 100644 --- a/gui/TabWidget.cpp +++ b/gui/widgets/tab.cpp @@ -23,9 +23,9 @@ */ #include "common/util.h" -#include "gui/TabWidget.h" +#include "gui/widgets/tab.h" #include "gui/dialog.h" -#include "gui/GuiManager.h" +#include "gui/gui-manager.h" #include "gui/ThemeEval.h" diff --git a/gui/TabWidget.h b/gui/widgets/tab.h similarity index 97% rename from gui/TabWidget.h rename to gui/widgets/tab.h index febc52448a5..0369a8bde5b 100644 --- a/gui/TabWidget.h +++ b/gui/widgets/tab.h @@ -22,10 +22,10 @@ * $Id$ */ -#ifndef TABWIDGET_H -#define TABWIDGET_H +#ifndef GUI_WIDGETS_TAB_H +#define GUI_WIDGETS_TAB_H -#include "widget.h" +#include "gui/widget.h" #include "common/str.h" #include "common/array.h" diff --git a/po/POTFILES b/po/POTFILES index 4ef46c40b45..d0e7e628d39 100644 --- a/po/POTFILES +++ b/po/POTFILES @@ -4,7 +4,7 @@ gui/about.cpp gui/browser.cpp gui/chooser.cpp gui/error.cpp -gui/GuiManager.cpp +gui/gui-manager.cpp gui/KeysDialog.h gui/KeysDialog.cpp gui/launcher.cpp @@ -21,16 +21,16 @@ common/util.cpp engines/dialogs.cpp -sound/fmopl.cpp -sound/musicplugin.cpp -sound/null.h -sound/null.cpp -sound/softsynth/adlib.cpp -sound/softsynth/appleiigs.cpp -sound/softsynth/sid.cpp -sound/softsynth/mt32.cpp -sound/softsynth/pcspk.cpp -sound/softsynth/ym2612.cpp +audio/fmopl.cpp +audio/musicplugin.cpp +audio/null.h +audio/null.cpp +audio/softsynth/adlib.cpp +audio/softsynth/appleiigs.cpp +audio/softsynth/sid.cpp +audio/softsynth/mt32.cpp +audio/softsynth/pcspk.cpp +audio/softsynth/ym2612.cpp backends/keymapper/remap-dialog.cpp backends/midi/windows.cpp diff --git a/po/module.mk b/po/module.mk index 1a4982e3fd1..cf4aa6d6f3c 100644 --- a/po/module.mk +++ b/po/module.mk @@ -2,9 +2,9 @@ POTFILE := $(srcdir)/po/residual.pot POFILES := $(wildcard $(srcdir)/po/*.po) updatepot: - xgettext -f $(srcdir)/po/POTFILES -D $(srcdir) -d residual --c++ -k_ -k_t -k_s -o $(POTFILE) \ + xgettext -f $(srcdir)/po/POTFILES -D $(srcdir) -d residual --c++ -k_ -k_s -k_c:1,2c -k_sc:1,2c \ -kDECLARE_TRANSLATION_ADDITIONAL_CONTEXT:1,2c -o $(POTFILE) \ - "--copyright-holder=Residual Team" --package-name=Residual \ + --copyright-holder="Residual Team" --package-name=Residual \ --package-version=$(VERSION) --msgid-bugs-address=residual-devel@lists.sf.net -o $(POTFILE)_ sed -e 's/SOME DESCRIPTIVE TITLE/LANGUAGE translation for Residual/' \ @@ -33,13 +33,10 @@ updatepot: mv -f $@.new $@; \ fi; -#$(srcdir)/common/messages.cpp: $(POFILES) -# perl $(srcdir)/tools/po2c $^ > $(srcdir)/common/messages.cpp - -translations-dat: tools/create_translations - tools/create_translations/create_translations $(POFILES) +translations-dat: devtools/create_translations + devtools/create_translations/create_translations $(POFILES) mv translations.dat $(srcdir)/gui/themes/ - + update-translations: updatepot $(POFILES) translations-dat update-translations: updatepot $(POFILES) diff --git a/ports.mk b/ports.mk index a09e8af5b1b..0c5075e41f7 100644 --- a/ports.mk +++ b/ports.mk @@ -8,7 +8,7 @@ # # UNIX specific # -install: all +install: $(INSTALL) -d "$(DESTDIR)$(bindir)" $(INSTALL) -c -s -m 755 "./$(EXECUTABLE)" "$(DESTDIR)$(bindir)/$(EXECUTABLE)" #$(INSTALL) -d "$(DESTDIR)$(mandir)/man6/" @@ -73,7 +73,7 @@ endif chmod 755 residual cp residual $(bundle_name)/Residual cp $(srcdir)/dists/iphone/icon.png $(bundle_name)/ - cp $(srcdir)/dists/iphone/icon-72.png $(bundle_name)/ + cp $(srcdir)/dists/iphone/icon-72.png $(bundle_name)/ cp $(srcdir)/dists/iphone/Default.png $(bundle_name)/ # Location of static libs for the iPhone @@ -105,6 +105,14 @@ ifdef USE_MPEG2 OSX_STATIC_LIBS += $(STATICLIBPATH)/lib/libmpeg2.a endif +ifdef USE_PNG +OSX_STATIC_LIBS += $(STATICLIBPATH)/lib/libpng.a +endif + +ifdef USE_THEORADEC +OSX_STATIC_LIBS += $(STATICLIBPATH)/lib/libtheoradec.a +endif + ifdef USE_ZLIB OSX_ZLIB ?= -lz endif @@ -211,11 +219,7 @@ aos4dist: $(EXECUTABLE) ifdef DIST_FILES_ENGINEDATA cp $(DIST_FILES_ENGINEDATA) $(AOS4PATH)/extras/ endif - cp $(srcdir)/AUTHORS $(AOS4PATH)/AUTHORS.txt - cp $(srcdir)/COPYING $(AOS4PATH)/COPYING.txt - cp $(srcdir)/COPYING.LGPL $(AOS4PATH)/COPYING.LGPL.txt - cp $(srcdir)/NEWS $(AOS4PATH)/NEWS.txt - cp $(srcdir)/README $(AOS4PATH)/README.txt + cp $(DIST_FILES_DOCS) $(AOS4PATH) # Mark special targets as phony .PHONY: deb bundle osxsnap win32dist install uninstall diff --git a/rules.mk b/rules.mk index fde462fc0b2..c531d49a293 100644 --- a/rules.mk +++ b/rules.mk @@ -28,12 +28,12 @@ $(TOOL-$(MODULE)): $(MODULE_OBJS-$(MODULE)) # Reset TOOL_EXECUTABLE var TOOL_EXECUTABLE:= -# Add to "tools" target -tools: $(TOOL-$(MODULE)) +# Add to "devtools" target +devtools: $(TOOL-$(MODULE)) -# Pseudo target for comfort, allows for "make tools/skycpt", etc. +# Pseudo target for comfort, allows for "make devtools/skycpt", etc. $(MODULE): $(TOOL-$(MODULE)) -clean-tools: clean-$(MODULE) +clean-devtools: clean-$(MODULE) else ifdef PLUGIN diff --git a/sound/audiocd.h b/sound/audiocd.h deleted file mode 100644 index ab16dc23326..00000000000 --- a/sound/audiocd.h +++ /dev/null @@ -1,96 +0,0 @@ -/* Residual - A 3D game interpreter - * - * 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 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 SOUND_AUDIOCD_H -#define SOUND_AUDIOCD_H - -#include "common/sys.h" -#include "common/singleton.h" -#include "sound/mixer.h" - - -namespace Audio { - - -class AudioCDManager : public Common::Singleton { -public: - struct Status { - bool playing; - int track; - int start; - int duration; - int numLoops; - int volume; - int balance; - }; - - /** - * Start playback of the specified "CD" track. This method mimics - * the interface of OSystem::playCD (which it in fact may call, if an Audio CD is - * present), but also can play digital audio tracks in various formats. - * - * @param track the track to play. - * @param num_loops how often playback should be repeated (-1 = infinitely often). - * @param start_frame the frame at which playback should start (75 frames = 1 second). - * @param duration the number of frames to play (0: play until end) - * @param only_emulate if true, don't try to play from a real CD - */ - void play(int track, int numLoops, int startFrame, int duration, bool only_emulate = false); - void stop(); - bool isPlaying() const; - - void setVolume(byte volume); - void setBalance(int8 balance); - - void updateCD(); - - Status getStatus() const; - -private: - friend class Common::Singleton; - AudioCDManager(); - - // FIXME: It might make sense to stop CD playback, when the AudioCDManager singleton - // is destroyed. Currently we can not do this, since in worst case the OSystem and - // along with it the Mixer will be destroyed before the AudioCDManager, thus - // leading to invalid memory access. If we can fix up the code to destroy the - // AudioCDManager before OSystem in *all* cases, that is including calling - // OSystem::quit, we might be able to implement it via a simple "stop()" - // call in a custom destructor of AudioCDManager. - - /* used for emulated CD music */ - SoundHandle _handle; - bool _emulating; - - Status _cd; - Mixer *_mixer; -}; - -/** Shortcut for accessing the audio CD manager. */ -#define AudioCD Audio::AudioCDManager::instance() - -} // End of namespace Audio - -#endif diff --git a/sound/softsynth/mt32/mt32_file.cpp b/sound/softsynth/mt32/mt32_file.cpp deleted file mode 100644 index f4eba73d331..00000000000 --- a/sound/softsynth/mt32/mt32_file.cpp +++ /dev/null @@ -1,108 +0,0 @@ -/* Copyright (c) 2003-2005 Various contributors - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to - * deal in the Software without restriction, including without limitation the - * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or - * sell copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#include - -#include "mt32emu.h" - -namespace MT32Emu { - - bool ANSIFile::open(const char *filename, OpenMode mode) { - const char *fmode; - if (mode == OpenMode_read) { - fmode = "rb"; - } else { - fmode = "wb"; - } - fp = fopen(filename, fmode); - return (fp != NULL); - } - - void ANSIFile::close() { - fclose(fp); - } - - size_t ANSIFile::read(void *in, size_t size) { - return fread(in, 1, size, fp); - } - - bool ANSIFile::readBit8u(Bit8u *in) { - int c = fgetc(fp); - if (c == EOF) - return false; - *in = (Bit8u)c; - return true; - } - - bool File::readBit16u(Bit16u *in) { - Bit8u b[2]; - if (read(&b[0], 2) != 2) - return false; - *in = ((b[0] << 8) | b[1]); - return true; - } - - bool File::readBit32u(Bit32u *in) { - Bit8u b[4]; - if (read(&b[0], 4) != 4) - return false; - *in = ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]); - return true; - } - - size_t ANSIFile::write(const void *out, size_t size) { - return fwrite(out, 1, size, fp); - } - - bool ANSIFile::writeBit8u(Bit8u out) { - return fputc(out, fp) != EOF; - } - - bool File::writeBit16u(Bit16u out) { - if (!writeBit8u((Bit8u)((out & 0xFF00) >> 8))) { - return false; - } - if (!writeBit8u((Bit8u)(out & 0x00FF))) { - return false; - } - return true; - } - - bool File::writeBit32u(Bit32u out) { - if (!writeBit8u((Bit8u)((out & 0xFF000000) >> 24))) { - return false; - } - if (!writeBit8u((Bit8u)((out & 0x00FF0000) >> 16))) { - return false; - } - if (!writeBit8u((Bit8u)((out & 0x0000FF00) >> 8))) { - return false; - } - if (!writeBit8u((Bit8u)(out & 0x000000FF))) { - return false; - } - return true; - } - - bool ANSIFile::isEOF() { - return feof(fp) != 0; - } -} diff --git a/tools/themeparser.py b/tools/themeparser.py deleted file mode 100644 index 6dd9b58f7b1..00000000000 --- a/tools/themeparser.py +++ /dev/null @@ -1,621 +0,0 @@ -#!/usr/bin/env python -# encoding: utf-8 - -""" - " Residual - A 3D game interpreter - " - " 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 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$ -""" - -from __future__ import with_statement -import os -import xml.dom.minidom as DOM -import struct - -FILTER=''.join([(len(repr(chr(x)))==3) and chr(x) or '.' for x in range(256)]) - -# adapted from Activestate Snippet Cookbook -def printBinaryDump(src, length=16): - N=0; result='' - while src: - s,src = src[:length],src[length:] - hexa = ' '.join(["%02X"%ord(x) for x in s]) - s = s.translate(FILTER) - result += "%04X %-*s %s\n" % (N, length*3, hexa, s) - N+=length - print (result) - -def pbin(data): - return str(map(lambda c: hex(ord(c)), data)) -# return " ".join(["%0.2X" % ord(c) for c in data]) - -class STXBinaryFile(object): - class InvalidRGBColor(Exception): - pass - - class InvalidResolution(Exception): - pass - - class InvalidFontIdentifier(Exception): - pass - - class InvalidBitmapName(Exception): - pass - - class InvalidDialogOverlay(Exception): - pass - - class DrawStepData(object): - def __init__(self, isDefault, packFormat, function): - self.isDefault = isDefault - self.packFormat = packFormat - self.parse = function - - BYTEORDER = '>' # big-endian format by default, platform independent - - TRUTH_VALUES = {"" : 0, "true" : 1, "false" : 0, "True" : 1, "False" : 0} - - BLOCK_HEADERS = { - "bitmaps" : 0x0100000A, - "fonts" : 0x0100000B, - "cursor" : 0x0100000C, - "drawdata" : 0x0100000D, - - "globals" : 0x0200000A, - "dialog" : 0x0200000B, - } - - DIALOG_shading = {"none" : 0x0, "dim" : 0x1, "luminance" : 0x2} - - DS_triangleOrientations = {"top" : 0x1, "bottom" : 0x2, "left" : 0x3, "right" : 0x4} - DS_fillModes = {"none" : 0x0, "foreground" : 0x1, "background" : 0x2, "gradient" : 0x3} - DS_vectorAlign = {"left" : 0x1, "right" : 0x2, "bottom" : 0x3, "top" : 0x4, "center" : 0x5} - - DS_functions = { - "void" : 0x0, "circle" : 0x1, "square" : 0x2, "roundedsq" : 0x3, "bevelsq" : 0x4, - "line" : 0x5, "triangle" : 0x6, "fill" : 0x7, "tab" : 0x8, "bitmap" : 0x9, "cross" : 0xA - } - - DS_fonts = { - "text_default" : 0x0, "text_hover" : 0x1, "text_disabled" : 0x2, - "text_inverted" : 0x3, "text_button" : 0x4, "text_button_hover" : 0x5, "text_normal" : 0x6 - } - - DS_text_alignV = {"bottom" : 0x0, "center" : 0x1, "top" : 0x2} - DS_text_alignH = {"left" : 0x0, "center" : 0x1, "right" : 0x2} - - DS_list = [ - "func", "fill", "stroke", "gradient_factor", - "width", "height", "xpos", "ypos", - "radius", "bevel", "shadow", "orientation", "file", - "fg_color", "bg_color", "gradient_start", "gradient_end", "bevel_color" - ] - - def __init__(self, themeName, autoLoad = True, verbose = False): - self._themeName = themeName - self._stxFiles = [] - self._verbose = verbose - - self.DS_data = { - # attribute name isDefault pack parse function - "func" : self.DrawStepData(False, "B", lambda f: self.DS_functions[f]), - "fill" : self.DrawStepData(True, "B", lambda f: self.DS_fillModes[f]), - "stroke" : self.DrawStepData(True, "B", int), - "gradient_factor" : self.DrawStepData(True, "B", int), - "width" : self.DrawStepData(False, "i", lambda w: -1 if w == 'height' else 0 if w == 'auto' else int(w)), - "height" : self.DrawStepData(False, "i", lambda h: -1 if h == 'width' else 0 if h == 'auto' else int(h)), - "xpos" : self.DrawStepData(False, "i", lambda pos: self.DS_vectorAlign[pos] if pos in self.DS_vectorAlign else int(pos)), - "ypos" : self.DrawStepData(False, "i", lambda pos: self.DS_vectorAlign[pos] if pos in self.DS_vectorAlign else int(pos)), - "radius" : self.DrawStepData(False, "i", lambda r: 0xFF if r == 'auto' else int(r)), - "bevel" : self.DrawStepData(True, "B", int), - "shadow" : self.DrawStepData(True, "B", int), - "orientation" : self.DrawStepData(False, "B", lambda o: self.DS_triangleOrientations[o]), - "file" : self.DrawStepData(False, "B", self.__getBitmap), - "fg_color" : self.DrawStepData(True, "4s", self.__parseColor), - "bg_color" : self.DrawStepData(True, "4s", self.__parseColor), - "gradient_start" : self.DrawStepData(True, "4s", self.__parseColor), - "gradient_end" : self.DrawStepData(True, "4s", self.__parseColor), - "bevel_color" : self.DrawStepData(True, "4s", self.__parseColor) - } - - if autoLoad: - if not os.path.isdir(themeName) or not os.path.isfile(os.path.join(themeName, "THEMERC")): - raise IOError - - for filename in os.listdir(themeName): - filename = os.path.join(themeName, filename) - if os.path.isfile(filename) and filename.endswith('.stx'): - self._stxFiles.append(filename) - - def debug(self, text): - if self._verbose: print (text) - - def debugBinary(self, data): - if self._verbose: - print ("BINARY OUTPUT (%d bytes): %s" % (len(data), " ".join(["%0.2X" % ord(c) for c in data]))) - - def addSTXFile(self, filename): - if not os.path.isfile(filename): - raise IOError - else: - self._stxFiles.append(filename) - - def parse(self): - if not self._stxFiles: - self.debug("No files have been loaded for parsing on the theme.") - raise IOError - - for f in self._stxFiles: - self.debug("Parsing %s." % f) - with open(f) as stxFile: - self.__parseFile(stxFile) - - def __parseFile(self, xmlFile): - stxDom = DOM.parse(xmlFile) - - for layout in stxDom.getElementsByTagName("layout_info"): - self.__parseLayout(layout) - - for render in stxDom.getElementsByTagName("render_info"): - self.__parseRender(render) - - stxDom.unlink() - - def __getBitmap(self, bmp): - bmp = str(bmp) - - if bmp == "": - return 0x0 - if bmp not in self._bitmaps: - raise self.InvalidBitmapName - - return self._bitmaps[bmp] - - def __parseDrawStep(self, drawstepDom, localDefaults = {}): - - dstable = {} - - if drawstepDom.tagName == "defaults": - isGlobal = drawstepDom.parentNode.tagName == "render_info" - - for ds in self.DS_list: - if self.DS_data[ds].isDefault and drawstepDom.hasAttribute(ds): - dstable[ds] = self.DS_data[ds].parse(drawstepDom.getAttribute(ds)) - - elif isGlobal: - dstable[ds] = None - - else: - for ds in self.DS_data: - if drawstepDom.hasAttribute(ds): - dstable[ds] = self.DS_data[ds].parse(drawstepDom.getAttribute(ds)) - elif self.DS_data[ds].isDefault: - dstable[ds] = localDefaults[ds] if ds in localDefaults else self._globalDefaults[ds] - else: - dstable[ds] = None - - return dstable - - - def __parseDrawStepToBin(self, stepDict): - """ - /BBBBiiiiiBBB4s4s4s4s4sB/ == - function (byte) - fill (byte) - stroke (byte) - gradient_factor (byte) - width (int32) - height (int32) - xpos (int32) - ypos (int32) - radius (int32) - bevel (byte) - shadow (byte) - orientation (byte) - file (byte) - fg_color (4 byte) - bg_color (4 byte) - gradient_start (4 byte) - gradient_end (4 byte) - bevel_color (4 byte) - """ - - packLayout = "" - packData = [] - - for ds in self.DS_list: - layout = self.DS_data[ds].packFormat - data = stepDict[ds] - - if not data: - size = struct.calcsize(layout) - packLayout += "B" * size - - for d in range(size): - packData.append(0) - else: - packLayout += layout - packData.append(data) - - - stepBin = struct.pack(self.BYTEORDER + packLayout, *tuple(packData)) - return stepBin - - - def __parseResolutionToBin(self, resString): - """ - /B bHH bHH bHH/ == 1 byte + x * 9 bytes - number of resolution sections (byte) - exclude resolution (byte) - resolution X (half) - resolution Y (half) - """ - - if resString == "": - return struct.pack(self.BYTEORDER + "BbHH", 1, 0, 0, 0) - - resolutions = resString.split(", ") - packFormat = "B" + "bHH" * len(resolutions) - packData = [len(resolutions)] - - for res in resolutions: - exclude = 0 - if res[0] == '-': - exclude = 1 - res = res[1:] - - try: - x, y = res.split('x') - x = 0 if x == 'X' else int(x) - y = 0 if y == 'Y' else int(y) - except ValueError: - raise InvalidResolution - - packData.append(exclude) - packData.append(x) - packData.append(y) - - buff = struct.pack(self.BYTEORDER + packFormat, *tuple(packData)) - return buff - - def __parseRGBToBin(self, color): - """ - /xBBB/ == 32 bits - padding (byte) - red color (byte) - green color (byte) - blue color (byte) - """ - - try: - rgb = tuple(map(int, color.split(", "))) - except ValueError: - raise self.InvalidRGBColor - - if len(rgb) != 3: - raise self.InvalidRGBColor - - for c in rgb: - if c < 0 or c > 255: - raise self.InvalidRGBColor - - rgb = struct.pack(self.BYTEORDER + "xBBB", *tuple(rgb)) - -# self.debugBinary(rgb) - return rgb - - def __parseColor(self, color): - try: - color = self.__parseRGBToBin(color) - except self.InvalidRGBColor: - if color not in self._colors: - raise self.InvalidRGBColor - color = self._colors[color] - - return color - - - def __parsePalette(self, paletteDom): - self._colors = {} - - for color in paletteDom.getElementsByTagName("color"): - color_name = color.getAttribute('name') - color_rgb = self.__parseRGBToBin(color.getAttribute('rgb')) - - self._colors[color_name] = color_rgb -# self.debug("COLOR: %s" % (color_name)) - - - def __parseBitmaps(self, bitmapsDom): - self._bitmaps = {} - idCount = 0xA0 - packLayout = "" - packData = [] - - for bitmap in bitmapsDom.getElementsByTagName("bitmap"): - bmpName = str(bitmap.getAttribute("filename")) - self._bitmaps[bmpName] = idCount - - packLayout += "B%ds" % (len(bmpName) + 1) - packData.append(idCount) - packData.append(bmpName) - idCount += 1 - - - bitmapBinary = struct.pack( - self.BYTEORDER + "IB" + packLayout, - self.BLOCK_HEADERS['bitmaps'], - len(bitmapsDom.getElementsByTagName("bitmap")), - *tuple(packData) - ) - -# self.debug("BITMAPS:\n%s\n\n" % pbin(bitmapBinary)) - return bitmapBinary - - def __parseFonts(self, fontsDom): - """ - /IB Bs4ss .../ - section header (uint32) - number of font definitions (byte) - - id for font definition (byte) - resolution for font (byte array) - color for font (4 bytes) - font filename (byte array, null terminated) - """ - - packLayout = "" - packData = [] - - for font in fontsDom.getElementsByTagName("font"): - ident = font.getAttribute("id") - - if ident not in self.DS_fonts: - raise self.InvalidFontIdentifier - - color = self.__parseColor(font.getAttribute("color")) - filename = str(font.getAttribute("file")) - - if filename == 'default': - filename = '' - - resolution = self.__parseResolutionToBin(font.getAttribute("resolution")) - - packLayout += "B%ds4s%ds" % (len(resolution), len(filename) + 1) - packData.append(self.DS_fonts[ident]) - packData.append(resolution) - packData.append(color) - packData.append(filename) - - fontsBinary = struct.pack(self.BYTEORDER + \ - "IB" + packLayout, - self.BLOCK_HEADERS['fonts'], - len(fontsDom.getElementsByTagName("font")), - *tuple(packData) - ) - - -# self.debug("FONTS DATA:\n%s\n\n" % pbin(fontsBinary)) - return fontsBinary - - def __parseTextToBin(self, textDom): - """ - /BBBx/ - font identifier (byte) - vertical alignment (byte) - horizontal alignment (byte) - padding until word (byte) - """ - - font = textDom.getAttribute("font") - if font not in self.DS_fonts: - raise self.InvalidFontIdentifier - - textBin = struct.pack(self.BYTEORDER + "BBBx", - self.DS_fonts[font], - self.DS_text_alignV[textDom.getAttribute("vertical_align")], - self.DS_text_alignH[textDom.getAttribute("horizontal_align")] - ) - - return textBin - - def __parseDrawData(self, ddDom): - """ - /IsIBBHss/ - Section Header (uint32) - Resolution (byte array, word-aligned) - DrawData id hash (uint32) - Cached (byte) - has text section? (byte) - number of DD sections (uint16) - ** text segment (4 bytes) - drawstep segments (byte array) - """ - - - localDefaults = ddDom.getElementsByTagName("defaults") - localDefaults = localDefaults[0] if localDefaults else {} - - stepList = [] - - for ds in ddDom.getElementsByTagName("drawstep"): - dstable = self.__parseDrawStep(ds, localDefaults) - dsbinary = self.__parseDrawStepToBin(dstable) - - stepList.append(dsbinary) - - stepByteArray = "".join(stepList) - - resolution = self.__parseResolutionToBin(ddDom.getAttribute("resolution")) - - text = ddDom.getElementsByTagName("text") - text = self.__parseTextToBin(text[0]) if text else "" - - id_hash = str.__hash__(str(ddDom.getAttribute("id"))) & 0xFFFFFFFF - cached = self.TRUTH_VALUES[ddDom.getAttribute("cached")] - - ddBinary = struct.pack(self.BYTEORDER + \ - "I%dsIBBH4s%ds" % (len(resolution), len(stepByteArray)), - - self.BLOCK_HEADERS['drawdata'], # Section Header (uint32) - resolution, # Resolution (byte array, word-aligned) - id_hash, # DrawData id hash (uint32) - cached, # Cached (byte) - 0x1 if text else 0x0, # has text section? (byte) - len(stepList), # number of DD sections (uint16) - text, # ** text segment (byte array) - stepByteArray # drawstep segments (byte array) - ) - -# self.debug("DRAW DATA %s (%X): \n" % (ddDom.getAttribute("id"), id_hash) + pbin(ddBinary) + "\n\n") - return ddBinary - - def __parseCursor(self, cursorDom): - """ - /IsBBhh/ - section header (uint32) - resolution string (byte array) - bitmap id (byte) - scale (byte) - hotspot X (half) - hotspot Y (half) - """ - - resolution = self.__parseResolutionToBin(cursorDom.getAttribute("resolution")) - scale = int(cursorDom.getAttribute("scale")) - hsX, hsY = cursorDom.getAttribute("hotspot").split(", ") - - cursorBin = struct.pack(self.BYTEORDER + "I%dsBBhh" % len(resolution), - self.BLOCK_HEADERS['cursor'], - resolution, - self.__getBitmap(cursorDom.getAttribute("file")), - scale, - int(hsX), - int(hsY) - ) - -# self.debug("CURSOR:\n%s\n\n" % pbin(cursorBin)) - return cursorBin - - def __parseDialog(self, dialogDom): - - dialog_id = str(dialogDom.getAttribute("name")) - resolution = self.__parseResolutionToBin(dialogDom.getAttribute("resolution")) - - overlays = str(dialogDom.getAttribute("overlays")) - overlay_type = 0x0 - overlay_parent = "" - - if overlays == "screen": - overlay_type = 0x1 - elif overlays == "screen_center": - overlay_type = 0x2 - else: - overlay_type = 0x3 - overlay_parent = str(overlays) - - dialog_enabled = 0x1 - if dialogDom.hasAttribute("enabled"): - dialog_enabled = self.TRUTH_VALUES[dialogDom.getAttribute("enabled")] - - dialog_shading = 0x0 - if dialogDom.hasAttribute("shading"): - dialog_shading = self.DIALOG_shading[dialogDom.getAttribute("shading")] - - dialog_inset = 0 - if dialogDom.hasAttribute("inset"): - dialog_inset = int(dialogDom.getAttribute("inset")) - - dialogBin = struct.pack(self.BYTEORDER + \ - "I%ds%dsBBBB%ds" % (len(resolution), len(dialog_id) + 1, len(overlay_parent) + 1), - self.BLOCK_HEADERS['dialog'], - resolution, - dialog_id, - dialog_enabled, - dialog_shading, - dialog_inset, - overlay_type, - overlay_parent, - ) - - return dialogBin - - def __parseLayout(self, layoutDom): - self.debug("GLOBAL SECTION: LAYOUT INFO.") - - dialogBIN = "" - - for dialog in layoutDom.getElementsByTagName("dialog"): - dialogBIN += self.__parseDialog(dialog) - - - printBinaryDump(dialogBIN) - - return dialogBIN - - def __parseRender(self, renderDom): - self.debug("GLOBAL SECTION: RENDER INFO.") - - bitmapBIN = "" - fontsBIN = "" - cursorBIN = "" - drawdataBIN = "" - - # parse color palettes - paletteDom = renderDom.getElementsByTagName("palette") - if paletteDom: - self.__parsePalette(paletteDom[0]) - - # parse bitmaps - bitmapsDom = renderDom.getElementsByTagName("bitmaps") - if bitmapsDom: - bitmapBIN = self.__parseBitmaps(bitmapsDom[0]) - - # parse fonts - fontsDom = renderDom.getElementsByTagName("fonts")[0] - fontsBIN = self.__parseFonts(fontsDom) - - # parse defaults - defaultsDom = renderDom.getElementsByTagName("defaults") - if defaultsDom: - self._globalDefaults = self.__parseDrawStep(defaultsDom[0]) - else: - self._globalDefaults = {} - - # parse cursors - for cur in renderDom.getElementsByTagName("cursor"): - cursorBIN += self.__parseCursor(cur) - - # parse drawdata sets - for dd in renderDom.getElementsByTagName("drawdata"): - drawdataBIN += self.__parseDrawData(dd) - - - renderInfoBIN = bitmapBIN + fontsBIN + cursorBIN + drawdataBIN - printBinaryDump(renderInfoBIN) - - return renderInfoBIN - -if __name__ == '__main__': - bin = STXBinaryFile('../gui/themes/scummclassic', True, True) - bin.parse() -