aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEugene Sandulenko2014-10-06 14:50:05 +0200
committerEugene Sandulenko2015-12-15 00:05:02 +0100
commit8ca14d1d642fce2617513fdc0c3223af2ab4e7e7 (patch)
tree191bf0157fbb79df4721e6094141db206dc41ffa
parent64f9c902ddf0c8294fd9e5f66cf96661eb12040b (diff)
downloadscummvm-rg350-8ca14d1d642fce2617513fdc0c3223af2ab4e7e7.tar.gz
scummvm-rg350-8ca14d1d642fce2617513fdc0c3223af2ab4e7e7.tar.bz2
scummvm-rg350-8ca14d1d642fce2617513fdc0c3223af2ab4e7e7.zip
LAB: Initial code
-rw-r--r--engines/lab/allocroom.cpp221
-rw-r--r--engines/lab/audioi.cpp461
-rw-r--r--engines/lab/configure.engine3
-rw-r--r--engines/lab/detection.cpp104
-rw-r--r--engines/lab/diff.h102
-rw-r--r--engines/lab/engine.cpp1834
-rw-r--r--engines/lab/graphics.cpp902
-rw-r--r--engines/lab/interface.cpp234
-rw-r--r--engines/lab/interface.h143
-rw-r--r--engines/lab/intro.cpp470
-rw-r--r--engines/lab/lab.cpp68
-rw-r--r--engines/lab/lab.h52
-rw-r--r--engines/lab/labfile.cpp549
-rw-r--r--engines/lab/labfun.h393
-rw-r--r--engines/lab/labmusic.cpp543
-rw-r--r--engines/lab/labsets.cpp94
-rw-r--r--engines/lab/labtext.cpp168
-rw-r--r--engines/lab/machine.cpp372
-rw-r--r--engines/lab/map.cpp955
-rw-r--r--engines/lab/modernsavegame.cpp127
-rw-r--r--engines/lab/modernsavegame.h55
-rw-r--r--engines/lab/module.mk40
-rw-r--r--engines/lab/mouse.cpp569
-rw-r--r--engines/lab/mouse.h62
-rw-r--r--engines/lab/parsefun.h101
-rw-r--r--engines/lab/parsetypes.h237
-rw-r--r--engines/lab/processroom.cpp1056
-rw-r--r--engines/lab/readdiff.cpp673
-rw-r--r--engines/lab/readparse.cpp514
-rw-r--r--engines/lab/savegame.cpp323
-rw-r--r--engines/lab/savegamepalmap.cpp3316
-rw-r--r--engines/lab/special.cpp2219
-rw-r--r--engines/lab/stddefines.h105
-rw-r--r--engines/lab/storage.cpp89
-rw-r--r--engines/lab/storage.h48
-rw-r--r--engines/lab/text.cpp293
-rw-r--r--engines/lab/text.h69
-rw-r--r--engines/lab/timing.cpp147
-rw-r--r--engines/lab/timing.h47
-rw-r--r--engines/lab/undiff.cpp498
-rw-r--r--engines/lab/vga.cpp1082
-rw-r--r--engines/lab/vga.h100
42 files changed, 19438 insertions, 0 deletions
diff --git a/engines/lab/allocroom.cpp b/engines/lab/allocroom.cpp
new file mode 100644
index 0000000000..208d7ce8c3
--- /dev/null
+++ b/engines/lab/allocroom.cpp
@@ -0,0 +1,221 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/storage.h"
+#include "lab/parsetypes.h"
+#include "lab/stddefines.h"
+
+namespace Lab {
+
+/* Have to make sure that ROOMBUFFERSIZE is bigger than the biggest piece of memory
+ that we need */
+#define ROOMBUFFERSIZE (2 * 20480L)
+#define EMPTYROOM ((uint16) -1)
+#define MAXMARKERS 10
+
+extern RoomData *Rooms;
+extern uint16 ManyRooms;
+
+
+typedef struct {
+ uint16 RoomNum;
+ void *Start0, *End0, *Start1, *End1;
+} RoomMarker;
+
+
+
+static RoomMarker RoomMarkers[MAXMARKERS];
+static void *RoomBuffer = NULL;
+static uint16 CurMarker = 0;
+static void *MemPlace = NULL, *NextMemPlace = NULL;
+static int32 MemLeftInBuffer = 0L;
+
+/*****************************************************************************/
+/* Allocates the memory for the room buffers. */
+/*****************************************************************************/
+bool initRoomBuffer(void) {
+ uint16 counter;
+
+ CurMarker = 0;
+
+ if (allocate((void **)&RoomBuffer, ROOMBUFFERSIZE)) {
+ MemPlace = RoomBuffer;
+ MemLeftInBuffer = ROOMBUFFERSIZE;
+
+ for (counter = 0; counter < MAXMARKERS; counter++)
+ RoomMarkers[counter].RoomNum = EMPTYROOM;
+
+ return true;
+ } else
+ return false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Frees the memory for the room buffers. */
+/*****************************************************************************/
+void freeRoomBuffer(void) {
+ if (RoomBuffer)
+ deallocate(RoomBuffer, ROOMBUFFERSIZE);
+}
+
+
+/*****************************************************************************/
+/* Frees a room's resources. */
+/*****************************************************************************/
+static void freeRoom(uint16 RMarker) {
+ uint16 RoomNum;
+
+ RoomNum = RoomMarkers[RMarker].RoomNum;
+
+ if (RoomNum != EMPTYROOM) {
+ Rooms[RoomNum].NorthView = NULL;
+ Rooms[RoomNum].SouthView = NULL;
+ Rooms[RoomNum].EastView = NULL;
+ Rooms[RoomNum].WestView = NULL;
+ Rooms[RoomNum].RuleList = NULL;
+ Rooms[RoomNum].RoomMsg = NULL;
+ }
+
+ RoomMarkers[RMarker].RoomNum = EMPTYROOM;
+ RoomMarkers[RMarker].Start0 = NULL;
+ RoomMarkers[RMarker].End0 = NULL;
+ RoomMarkers[RMarker].Start1 = NULL;
+ RoomMarkers[RMarker].End1 = NULL;
+}
+
+/*****************************************************************************/
+/* Gets a chunk of memory from the buffer. */
+/*****************************************************************************/
+static void *getCurMem(uint16 Size) {
+ uint16 counter;
+ void *Ptr, *Start0, *Start1, *End0, *End1;
+
+ if (((int32) Size) > MemLeftInBuffer) {
+ MemPlace = RoomBuffer;
+ MemLeftInBuffer = ROOMBUFFERSIZE;
+ NextMemPlace = NULL;
+ }
+
+ Ptr = MemPlace;
+ MemPlace = (char *)MemPlace + Size;
+ MemLeftInBuffer -= Size;
+
+ if (MemPlace > NextMemPlace) {
+ NextMemPlace = NULL;
+
+ for (counter = 0; counter < MAXMARKERS; counter++) {
+ if (RoomMarkers[counter].RoomNum != EMPTYROOM) {
+ Start0 = RoomMarkers[counter].Start0;
+ Start1 = RoomMarkers[counter].Start1;
+ End0 = RoomMarkers[counter].End0;
+ End1 = RoomMarkers[counter].End1;
+
+ if (((Start0 >= Ptr) && (Start0 < MemPlace)) ||
+ ((End0 >= Ptr) && (End0 < MemPlace)) ||
+ ((Ptr >= Start0) && (Ptr <= End0)) ||
+
+ ((Start1 >= Ptr) && (Start1 < MemPlace)) ||
+ ((End1 >= Ptr) && (End1 < MemPlace)) ||
+ ((Ptr >= Start1) && (Ptr <= End1))) {
+ freeRoom(counter);
+ } else {
+ if (Start0 >= MemPlace)
+ if ((NextMemPlace == NULL) || (Start0 < NextMemPlace))
+ NextMemPlace = Start0;
+
+ if (Start1 >= MemPlace)
+ if ((NextMemPlace == NULL) || (Start1 < NextMemPlace))
+ NextMemPlace = Start1;
+ }
+ }
+ }
+
+ if (NextMemPlace == NULL) {
+ NextMemPlace = RoomBuffer;
+ NextMemPlace = (char *)NextMemPlace + ROOMBUFFERSIZE;
+ }
+ }
+
+ return Ptr;
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Grabs a chunk of memory from the room buffer, and manages it for a */
+/* particular room. */
+/*****************************************************************************/
+void allocRoom(void **Ptr, uint16 Size, uint16 RoomNum) {
+ uint16 RMarker;
+ bool doit = true;
+
+ if (1 & Size) /* Memory is required to be even aligned */
+ Size++;
+
+ RMarker = 0;
+
+ while ((RMarker < MAXMARKERS) && doit) {
+ if (RoomMarkers[RMarker].RoomNum == RoomNum)
+ doit = false;
+ else
+ RMarker++;
+ }
+
+ if (RMarker >= MAXMARKERS) {
+ RMarker = CurMarker;
+ CurMarker++;
+
+ if (CurMarker >= MAXMARKERS)
+ CurMarker = 0;
+
+ freeRoom(RMarker);
+ RoomMarkers[RMarker].RoomNum = RoomNum;
+ }
+
+ *Ptr = getCurMem(Size);
+
+ if (RoomMarkers[RMarker].Start0 == NULL) {
+ RoomMarkers[RMarker].Start0 = *Ptr;
+ RoomMarkers[RMarker].End0 = (void *)(((char *)(*Ptr)) + Size - 1);
+ } else if (*Ptr < RoomMarkers[RMarker].Start0) {
+ if (RoomMarkers[RMarker].Start1 == NULL)
+ RoomMarkers[RMarker].Start1 = *Ptr;
+
+ RoomMarkers[RMarker].End1 = (void *)(((char *)(*Ptr)) + Size - 1);
+ } else
+ RoomMarkers[RMarker].End0 = (void *)(((char *)(*Ptr)) + Size - 1);
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/audioi.cpp b/engines/lab/audioi.cpp
new file mode 100644
index 0000000000..44ba56e6c5
--- /dev/null
+++ b/engines/lab/audioi.cpp
@@ -0,0 +1,461 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+
+#include "lab/labfun.h"
+
+namespace Lab {
+
+#define PLAYBUFSIZE 65536L
+
+#if defined(DOSCODE)
+const char VERSION[] = "1.01";
+
+char *AudioI_DriverName = "a32sbdg.dll";
+#endif
+
+extern bool MusicOn;
+
+#if defined(DOSCODE)
+static HTIMER server;
+static HDRIVER hdriver;
+static char *drvr;
+static char *dll;
+static drvr_desc *desc;
+#endif
+//static sound_buff firstblock, tempblock;
+static int bufnum;
+#if defined(DOSCODE)
+static unsigned seg1;
+static unsigned seg2;
+static union REGS inregs, outregs;
+#endif
+
+
+bool EffectPlaying = false, ContMusic = false, DoMusic = false;
+static char *CurMusic, *startMusic;
+static uint32 StartMusicLen;
+
+
+#if defined(DOSCODE)
+static uint16 *mem, *head, *tail, counter;
+
+#pragma off (check_stack)
+void cdecl timer_callback(void) {
+
+ head = (uint16 *)(0x41A);
+ tail = (uint16 *)(0x41C);
+ mem = (uint16 *)(0x400 + *head);
+
+ if (*tail > *head)
+ counter = (*tail - *head) >> 1;
+ else
+ counter = (*head - *tail) >> 1;
+
+ if (counter > 16)
+ counter = 16;
+
+ while (counter) {
+ if ((*mem == 0x2e03) || (*mem == 0x300) || (*mem == 0x0003)) {
+ *tail = *head;
+ return;
+ }
+
+ mem++;
+ counter--;
+ }
+}
+#endif
+
+void freeAudio(void) {
+ if (!DoMusic)
+ return;
+
+#if defined(DOSCODE)
+ AIL_release_timer_handle(server);
+
+ AIL_shutdown(NULL);
+#else
+ //SDLWrapAudio();
+#endif
+}
+
+
+
+bool initAudio(void) {
+ if (!DoMusic)
+ return true;
+
+#if 0
+#if defined(DOSCODE)
+
+ AudioI_DriverName = "a32sbdg.dll";
+
+ //
+ // Allocate two 16K buffers from real-mode (lower 1MB) memory
+ //
+ // *buf1, *buf2 -> protected-mode pointers to buffers (sel:0000)
+ // *seg1, *seg2 -> real-mode (physical) pointers to buffers (seg:0000)
+ //
+ // Note: DPMI calculations assume flat model near pointer offset 0 =
+ // segment 0, offset 0 (Rational DOS4GW). The reason -- our simple
+ // file loader function can't use the far pointer formed by the selector
+ // returned by the DPMI call.
+
+ // Note that these examples do not implement out-of-memory error
+ // checking
+ //
+
+ inregs.x.eax = 0x100;
+ inregs.x.ebx = (16384 / 16);
+ int386(0x31, &inregs, &outregs);
+
+ seg1 = outregs.x.eax << 16;
+ buf1 = (char *)(outregs.x.eax * 16);
+
+ if (buf1 == NULL)
+ return false;
+
+ inregs.x.eax = 0x100;
+ inregs.x.ebx = (16384 / 16);
+ int386(0x31, &inregs, &outregs);
+
+ seg2 = outregs.x.eax << 16;
+ buf2 = (char *)(outregs.x.eax * 16);
+
+ if (buf2 == NULL)
+ return false;
+
+ //
+ // Load driver file
+ //
+
+ dll = FILE_read(AudioI_DriverName, NULL);
+
+ if (dll == NULL) {
+ return false;
+ }
+
+ drvr = DLL_load(dll, DLLMEM_ALLOC | DLLSRC_MEM, NULL);
+
+ if (drvr == NULL) {
+ return false;
+ }
+
+ free(dll);
+
+ //
+ // Initialize API before calling any Library functions
+ //
+
+ AIL_startup();
+
+ hdriver = AIL_register_driver(drvr);
+
+ if (hdriver == -1) {
+ AIL_shutdown(NULL);
+ return false;
+ }
+
+ //
+ // Get driver type and factory default I/O parameters; exit if
+ // driver is not capable of interpreting PCM sound data
+ //
+
+ desc = AIL_describe_driver(hdriver);
+
+ if (desc->drvr_type != DSP_DRVR) {
+ AIL_shutdown(NULL);
+ return false;
+ }
+
+ if (!AIL_detect_device(hdriver, desc->default_IO, desc->default_IRQ, desc->default_DMA, desc->default_DRQ)) {
+ desc->default_IRQ = 5;
+
+ if (!AIL_detect_device(hdriver, desc->default_IO, desc->default_IRQ, desc->default_DMA, desc->default_DRQ)) {
+ AIL_shutdown(NULL);
+ return false;
+ }
+ }
+
+ AIL_init_driver(hdriver, desc->default_IO, desc->default_IRQ, desc->default_DMA, desc->default_DRQ);
+
+ //
+ // Register a timer function; set up for 10-millisecond (100 Hz.)
+ // callback intervals
+ //
+
+ server = AIL_register_timer(timer_callback);
+
+ if (server != -1) {
+ AIL_set_timer_period(server, 20000L);
+ AIL_start_timer(server);
+ }
+
+#else
+ // we allocate extra mempory for 16-bit samples
+ buf1 = malloc(PLAYBUFSIZE);
+
+ if (buf1 == NULL)
+ return false;
+
+ buf2 = malloc(PLAYBUFSIZE);
+
+ if (buf2 == NULL)
+ return false;
+
+ if (!SDLInitAudio())
+ return false;
+
+#endif
+#endif
+
+ return true;
+}
+
+
+void initSampleRate(uint16 SampleSpeed) {
+ flushAudio();
+
+ if (SampleSpeed < 4000)
+ SampleSpeed = 4000;
+
+#if defined(DOSCODE)
+ firstblock.sample_rate = 256 - (1000000L / SampleSpeed);
+ firstblock.pack_type = 0 | 0x80; // 8-bit mono sample
+#else
+ //firstblock.sample_rate = SampleSpeed;
+ //firstblock.pack_type = AUDIO_S16; // SOUND_MONO | SOUND_16BIT; // 16-bit mono sample
+#endif
+}
+
+
+
+
+bool musicBufferEmpty(uint16 i) {
+#if defined(NEWCODE)
+ return (AIL_sound_buffer_status(hdriver, i) == DAC_DONE);
+#else
+ //return (SDLSoundBufferStatus(i) == DAC_DONE);
+ return true;
+#endif
+}
+
+
+
+void playMusicBlock(void *Ptr, uint32 Size, uint16 BufferNum, uint16 SampleSpeed) {
+#if defined(DOSCODE)
+ uint32 TempPtr;
+ uint32 seg;
+ char *buf;
+
+ TempPtr = ((uint32) Ptr) / 16L;
+
+ seg = TempPtr << 16;
+ buf = (char *)(TempPtr * 16);
+
+ if (SampleSpeed < 4000)
+ SampleSpeed = 4000;
+
+ firstblock.sample_rate = 256 - (1000000L / SampleSpeed);
+ firstblock.pack_type = 0 | 0x80; // 8-bit mono sample
+
+ tempblock = firstblock;
+ tempblock.sel_data = buf;
+ tempblock.seg_data = seg;
+ tempblock.len = Size;
+
+ AIL_register_sound_buffer(hdriver, BufferNum, &tempblock);
+ AIL_format_sound_buffer(hdriver, &tempblock);
+
+ AIL_start_digital_playback(hdriver);
+ AIL_set_digital_playback_volume(hdriver, 127);
+#else
+#if 0
+
+ if (SampleSpeed < 4000)
+ SampleSpeed = 4000;
+
+ firstblock.sample_rate = SampleSpeed;
+ firstblock.pack_type = SOUND_MONO | SOUND_16BIT; // 16-bit mono sample
+
+ tempblock = firstblock;
+ tempblock.sel_data = Ptr;
+ tempblock.len = Size;
+
+ SDLPlayBuffer(BufferNum, &tempblock);
+#endif
+#endif
+}
+
+
+void updateSoundBuffers(void) {
+ if (!DoMusic)
+ return;
+
+ if (!EffectPlaying)
+ return;
+
+#if defined(DOSCODE)
+
+ for (int i = 0; i < 2; i++) {
+ if ((AIL_sound_buffer_status(hdriver, i) == DAC_DONE) && firstblock.len) {
+ tempblock.len = min(16384L, firstblock.len);
+ firstblock.len -= tempblock.len;
+
+ if (!(bufnum ^= 1)) {
+ memcpy(buf1, CurMusic, (unsigned) tempblock.len);
+ tempblock.sel_data = buf1;
+ tempblock.seg_data = seg1;
+ } else {
+ memcpy(buf2, CurMusic, (unsigned) tempblock.len);
+ tempblock.sel_data = buf2;
+ tempblock.seg_data = seg2;
+ }
+
+ CurMusic += tempblock.len;
+
+ AIL_register_sound_buffer(hdriver, i, &tempblock);
+ AIL_format_sound_buffer(hdriver, &tempblock);
+
+ AIL_start_digital_playback(hdriver);
+ AIL_set_digital_playback_volume(hdriver, 127);
+ }
+ }
+
+ //
+ // Playback ends when no bytes are left in the source data and
+ // the status of both buffers equals DAC_DONE
+ //
+
+ if (!firstblock.len) {
+ if (ContMusic) {
+ CurMusic = startMusic;
+ firstblock.len = StartMusicLen;
+ } else if ((AIL_sound_buffer_status(hdriver, 0) == DAC_DONE) &&
+ (AIL_sound_buffer_status(hdriver, 1) == DAC_DONE)) {
+ flushAudio();
+ EffectPlaying = false;
+ }
+ }
+
+#else
+#if 0
+
+ for (int i = 0; i < 2; i++) {
+ if ((SDLSoundBufferStatus(i) == DAC_DONE) && firstblock.len) {
+ // use extra memory for 16-bit samples
+ tempblock.len = min(PLAYBUFSIZE, firstblock.len);
+ firstblock.len -= tempblock.len;
+
+ if (!(bufnum ^= 1)) {
+ memcpy(buf1, CurMusic, (unsigned) tempblock.len);
+ tempblock.sel_data = buf1;
+ } else {
+ memcpy(buf2, CurMusic, (unsigned) tempblock.len);
+ tempblock.sel_data = buf2;
+ }
+
+ CurMusic += tempblock.len;
+
+ SDLPlayBuffer(i, &tempblock);
+ }
+ }
+
+ //
+ // Playback ends when no bytes are left in the source data and
+ // the status of both buffers equals DAC_DONE
+ //
+
+ if (!firstblock.len) {
+ if (ContMusic) {
+ CurMusic = startMusic;
+ firstblock.len = StartMusicLen;
+ } else if ((SDLSoundBufferStatus(0) == DAC_DONE) &&
+ (SDLSoundBufferStatus(1) == DAC_DONE)) {
+ flushAudio();
+ EffectPlaying = false;
+ }
+ }
+
+#endif
+#endif
+}
+
+
+
+void flushAudio(void) {
+ if (!DoMusic)
+ return;
+
+#if defined(DOSCODE)
+ AIL_stop_digital_playback(hdriver);
+#else
+ //SDLStopPlayback();
+#endif
+ EffectPlaying = false;
+}
+
+
+
+
+void playMusic(uint16 SampleSpeed, uint16 Volume, uint32 Length, bool flush, void *Data) {
+ if (!DoMusic)
+ return;
+
+ g_music->pauseBackMusic();
+
+ if (flush)
+ flushAudio();
+
+ if (SampleSpeed < 4000)
+ SampleSpeed = 4000;
+
+#if defined(DOSCODE)
+ firstblock.sample_rate = 256 - (1000000L / SampleSpeed);
+ firstblock.pack_type = 0 | 0x80; // 8-bit mono sample
+#else
+ //firstblock.sample_rate = SampleSpeed;
+ //firstblock.pack_type = SOUND_MONO | SOUND_16BIT; // 16-bit mono sample
+#endif
+ //firstblock.len = Length;
+ bufnum = 0;
+
+ //tempblock = firstblock;
+ EffectPlaying = true;
+ CurMusic = (char *)Data;
+ startMusic = CurMusic;
+ StartMusicLen = Length;
+
+ updateSoundBuffers();
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/configure.engine b/engines/lab/configure.engine
new file mode 100644
index 0000000000..df154b4d8e
--- /dev/null
+++ b/engines/lab/configure.engine
@@ -0,0 +1,3 @@
+# This file is included from the main "configure" script
+# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps]
+add_engine lab "Labirynth of Time" no
diff --git a/engines/lab/detection.cpp b/engines/lab/detection.cpp
new file mode 100644
index 0000000000..f7632c76be
--- /dev/null
+++ b/engines/lab/detection.cpp
@@ -0,0 +1,104 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+ /*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "engines/advancedDetector.h"
+#include "common/system.h"
+
+#include "base/plugins.h"
+
+#include "lab/lab.h"
+
+static const PlainGameDescriptor lab_setting[] = {
+ { "lab", "Labyrith of Time Engine game" },
+ { 0, 0 }
+};
+
+static const ADGameDescription labDescriptions[] = {
+ {
+ "lab",
+ "",
+ {
+ { "doors", 0, "d77536010e7e5ae17ee066323ceb9585", 2537 },
+ { "notes11", 0, "63e873f659f8f46f9809d16a2bf653c7", 3562 },
+ { NULL, 0, NULL, 0 }
+ },
+ Common::EN_ANY,
+ Common::kPlatformDOS,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ {
+ "lab",
+ "",
+ AD_ENTRY1s("doors", "7bf458df6ec30cc8ef4665e4d7c77f59", 2537),
+ Common::EN_ANY,
+ Common::kPlatformAmiga,
+ ADGF_NO_FLAGS,
+ GUIO0()
+ },
+ AD_TABLE_END_MARKER
+};
+
+static const char *const directoryGlobs[] = {
+ "fonts",
+ "game",
+ 0
+};
+
+class LabMetaEngine : public AdvancedMetaEngine {
+public:
+ LabMetaEngine() : AdvancedMetaEngine(labDescriptions, sizeof(ADGameDescription), lab_setting) {
+ _singleid = "lab";
+
+ _maxScanDepth = 2;
+ _directoryGlobs = directoryGlobs;
+ }
+
+ virtual const char *getName() const {
+ return "Lab";
+ }
+
+ virtual const char *getOriginalCopyright() const {
+ return "Labytinth of Time (c) 2004 The Wyrmkeep Entertainment Co.";
+ }
+
+ virtual bool createInstance(OSystem *syst, Engine **engine, const ADGameDescription * /* desc */) const {
+ // Instantiate Engine even if the game data is not found.
+ *engine = new Lab::LabEngine(syst);
+ return true;
+ }
+
+};
+
+#if PLUGIN_ENABLED_DYNAMIC(LAB)
+ REGISTER_PLUGIN_DYNAMIC(LAB, PLUGIN_TYPE_ENGINE, LabMetaEngine);
+#else
+ REGISTER_PLUGIN_STATIC(LAB, PLUGIN_TYPE_ENGINE, LabMetaEngine);
+#endif
diff --git a/engines/lab/diff.h b/engines/lab/diff.h
new file mode 100644
index 0000000000..e46e320a13
--- /dev/null
+++ b/engines/lab/diff.h
@@ -0,0 +1,102 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#ifndef LAB_DIFF_H
+#define LAB_DIFF_H
+
+#include "lab/stddefines.h"
+
+namespace Lab {
+
+
+struct DIFFHeader {
+ uint16 Version, x, y;
+ char depth, fps;
+ uint32 BufferSize;
+ uint16 Machine;
+ uint32 Flags;
+};
+
+struct BitMap {
+ uint16 BytesPerRow, Rows;
+ byte Flags, Depth;
+ byte *Planes[16];
+};
+
+#if !defined(DOSCODE)
+#define BITMAPF_VIDEO (1<<7)
+#endif
+
+/* unDiff.c */
+
+void initOffsets(uint16 bytesperrow);
+
+bool unDIFFMemory(byte *Dest, /* Where to Un-DIFF */
+ byte *diff, /* The DIFFed code. */
+ uint16 HeaderSize, /* Size of header (1, 2 or 4 bytes)
+ (only supports 1 currently */
+ uint16 CopySize); /* Size of minimum copy or skip.
+ (1, 2 or 4 bytes) */
+
+bool VUnDIFFMemory(byte *Dest, byte *diff, uint16 HeaderSize, uint16 CopySize, uint16 bytesperrow);
+
+void runLengthDecode(byte *Dest, byte *Source);
+
+void VRunLengthDecode(byte *Dest, byte *Source, uint16 bytesperrow);
+
+/* readDiff.c */
+
+void blackScreen();
+
+void blackAllScreen();
+
+void whiteScreen(void);
+
+bool readDiff(bool playonce);
+
+void diffNextFrame(void);
+
+void playCntMusic(void);
+
+void readSound(void);
+
+void stopDiff(void);
+
+void stopDiffEnd(void);
+
+void stopSound(void);
+
+void diffSetMusic(void);
+
+} // End of namespace Lab
+
+#endif /* LAB_DIFF_H */
+
+
diff --git a/engines/lab/engine.cpp b/engines/lab/engine.cpp
new file mode 100644
index 0000000000..b0b8614d74
--- /dev/null
+++ b/engines/lab/engine.cpp
@@ -0,0 +1,1834 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/labfun.h"
+#include "lab/diff.h"
+#include "lab/vga.h"
+#include "lab/timing.h"
+#include "lab/text.h"
+#include "lab/storage.h"
+#include "lab/parsefun.h"
+#include "lab/interface.h"
+#include "lab/mouse.h"
+
+namespace Lab {
+
+const char *CurFileName = " ";
+
+bool LongWinInFront = false;
+
+struct TextFont *MsgFont;
+
+extern bool DoBlack, waiteffect, EffectPlaying, stopsound, DoNotDrawMessage, IsHiRes, nopalchange, DoMusic;
+
+/* Global parser data */
+
+extern RoomData *Rooms;
+extern InventoryData *Inventory;
+extern uint16 NumInv, RoomNum, ManyRooms, HighestCondition, Direction;
+extern LargeSet Conditions, RoomsFound;
+CloseDataPtr CPtr;
+
+#if !defined(DOSCODE)
+CrumbData BreadCrumbs[MAX_CRUMBS];
+uint16 NumCrumbs;
+bool DroppingCrumbs;
+bool FollowingCrumbs;
+bool FollowCrumbsFast;
+bool IsCrumbTurning;
+uint32 CrumbSecs, CrumbMicros;
+bool IsCrumbWaiting;
+
+int followCrumbs();
+void mayShowCrumbIndicator();
+void mayShowCrumbIndicatorOff();
+#endif
+
+bool Alternate = false, ispal = false, noupdatediff = false, MainDisplay = true, QuitLab = false, DoNotReset = false;
+
+extern char *NewFileName; /* When ProcessRoom.c decides to change the filename
+ of the current picture. */
+
+extern char *LAMPONMSG, *TURNLEFT, *TURNRIGHT;
+extern char *GOFORWARDDIR, *NOPATH, *TAKEITEM, *USEONWHAT, *TAKEWHAT, *MOVEWHAT, *OPENWHAT, *CLOSEWHAT, *LOOKWHAT, *NOTHING, *USEMAP, *USEJOURNAL, *TURNLAMPON, *TURNLAMPOFF, *USEWHISKEY, *USEPITH, *USEHELMET;
+
+
+#define BIGBUFFERSIZE 850000L
+#define SMALLBUFFERSIZE 250000L
+
+static uint32 BUFFERSIZE = BIGBUFFERSIZE;
+
+
+/* LAB: Labyrinth specific code for the special puzzles */
+#define SPECIALLOCK 100
+#define SPECIALBRICK 101
+#define SPECIALBRICKNOMOUSE 102
+
+#define MAPNUM 28
+#define JOURNALNUM 9
+#define WESTPAPERNUM 18
+#define NOTESNUM 12
+#define WHISKEYNUM 25
+#define PITHHELMETNUM 7
+#define HELMETNUM 1
+
+#define LAMPNUM 27
+#define LAMPON 151
+
+#define BELTNUM 3
+#define BELTGLOW 70
+
+#define USEDHELMET 184
+
+#define QUARTERNUM 30
+
+
+#define MUSEUMMONITOR 71
+#define GRAMAPHONEMONITOR 72
+#define UNICYCLEMONITOR 73
+#define STATUEMONITOR 74
+#define TALISMANMONITOR 75
+#define LUTEMONITOR 76
+#define CLOCKMONITOR 77
+#define WINDOWMONITOR 78
+#define BELTMONITOR 79
+#define LIBRARYMONITOR 80
+#define TERMINALMONITOR 81
+#define LEVERSMONITOR 82
+
+
+#define CLOWNROOM 123
+#define DIMROOM 80
+
+
+
+static byte *MovePanelBuffer, *InvPanelBuffer;
+static uint32 MovePanelBufferSize, InvPanelBufferSize;
+static struct Image *MoveImages[20],
+#if defined(DOSCODE)
+ *InvImages[6];
+#else
+ *InvImages[10];
+#endif
+static struct Gadget *MoveGadgetList, *InvGadgetList;
+
+
+static char initcolors[] = { '\x00', '\x00', '\x00', '\x30',
+ '\x30', '\x30', '\x10', '\x10',
+ '\x10', '\x14', '\x14', '\x14',
+ '\x20', '\x20', '\x20', '\x24',
+ '\x24', '\x24', '\x2c', '\x2c',
+ '\x2c', '\x08', '\x08', '\x08'};
+
+
+
+
+/******************************************************************************/
+/* Draws the control panel display. */
+/******************************************************************************/
+void drawPanel(void) {
+ mouseHide();
+
+ setAPen(3); /* Clear Area */
+ rectFill(0, VGAScaleY(149) + SVGACord(2), VGAScaleX(319), VGAScaleY(199));
+
+ setAPen(0); /* First Line */
+ drawHLine(0, VGAScaleY(149) + SVGACord(2), VGAScaleX(319));
+ setAPen(5); /* Second Line */
+ drawHLine(0, VGAScaleY(149) + 1 + SVGACord(2), VGAScaleX(319));
+
+ /* Gadget Seperators */
+ setAPen(0);
+ drawHLine(0, VGAScaleY(170), VGAScaleX(319)); /* First black line to seperate buttons */
+
+ if (!Alternate) {
+ setAPen(4);
+ drawHLine(0, VGAScaleY(170) + 1, VGAScaleX(319)); /* The horizontal lines under the black one */
+ drawGadgetList(MoveGadgetList);
+ } else {
+#if defined(DOSCODE)
+ drawVLine(VGAScaleX(124), VGAScaleY(170) + 1, VGAScaleY(199)); /* Vertical Black lines */
+ drawVLine(VGAScaleX(194), VGAScaleY(170) + 1, VGAScaleY(199));
+#else
+ drawVLine(VGAScaleX(90), VGAScaleY(170) + 1, VGAScaleY(199)); /* Vertical Black lines */
+ drawVLine(VGAScaleX(160), VGAScaleY(170) + 1, VGAScaleY(199));
+ drawVLine(VGAScaleX(230), VGAScaleY(170) + 1, VGAScaleY(199));
+#endif
+
+ setAPen(4);
+ drawHLine(0, VGAScaleY(170) + 1, VGAScaleX(122)); /* The horizontal lines under the black one */
+ drawHLine(VGAScaleX(126), VGAScaleY(170) + 1, VGAScaleX(192));
+ drawHLine(VGAScaleX(196), VGAScaleY(170) + 1, VGAScaleX(319));
+
+ drawVLine(VGAScaleX(1), VGAScaleY(170) + 2, VGAScaleY(198)); /* The vertical high light lines */
+#if defined(DOSCODE)
+ drawVLine(VGAScaleX(126), VGAScaleY(170) + 2, VGAScaleY(198));
+ drawVLine(VGAScaleX(196), VGAScaleY(170) + 2, VGAScaleY(198));
+#else
+ drawVLine(VGAScaleX(92), VGAScaleY(170) + 2, VGAScaleY(198));
+ drawVLine(VGAScaleX(162), VGAScaleY(170) + 2, VGAScaleY(198));
+ drawVLine(VGAScaleX(232), VGAScaleY(170) + 2, VGAScaleY(198));
+#endif
+
+ drawGadgetList(InvGadgetList);
+ }
+
+ mouseShow();
+}
+
+
+extern bool LastMessageLong;
+
+static bool LastTooLong = false;
+
+
+
+
+/******************************************************************************/
+/* Draws the message for the room. */
+/******************************************************************************/
+static void drawRoomMessage(uint16 CurInv, CloseDataPtr cptr) {
+ char text[250], ManyText[8], *ManyPtr;
+
+ if (LastTooLong) {
+ LastTooLong = false;
+ return;
+ }
+
+ if (Alternate) {
+ if ((CurInv <= NumInv) && In(Conditions, CurInv) && Inventory[CurInv].BInvName) {
+ if ((CurInv == LAMPNUM) && In(Conditions, LAMPON)) /* LAB: Labyrith specific */
+ drawMessage(LAMPONMSG);
+ else if (Inventory[CurInv].Many > 1) {
+ ManyPtr = numtostr(ManyText, Inventory[CurInv].Many);
+ strcpy(text, Inventory[CurInv].name);
+ strcat(text, " (");
+ strcat(text, ManyPtr);
+ strcat(text, ")");
+ drawMessage(text);
+ } else
+ drawMessage(Inventory[CurInv].name);
+ }
+ } else
+ drawDirection(cptr);
+
+ LastTooLong = LastMessageLong;
+}
+
+
+static uint16 OldMode;
+
+/******************************************************************************/
+/* Sets up the Labyrinth screens, and opens up the initial windows. */
+/******************************************************************************/
+bool setUpScreens(void) {
+ uint16 counter;
+ byte *bufferstorage, **buffer = &bufferstorage;
+ struct Gadget *curgad;
+ uint16 y;
+
+ if (!createScreen(IsHiRes))
+ return false;
+
+ /* Loads in the graphics for the movement control panel */
+ MovePanelBufferSize = sizeOfFile("P:Control");
+
+ if (MovePanelBufferSize == 0L)
+ return false;
+
+ if (!allocate((void **) &MovePanelBuffer, MovePanelBufferSize))
+ return false;
+
+ Common::File *file = openPartial("P:Control");
+
+ if (!file)
+ return false;
+
+ file->read(MovePanelBuffer, MovePanelBufferSize);
+ file->close();
+
+ *buffer = MovePanelBuffer;
+
+ for (counter = 0; counter < 20; counter++)
+ readImage(buffer, &(MoveImages[counter]));
+
+ /* Creates the gadgets for the movement control panel */
+ y = VGAScaleY(173) - SVGACord(2);
+#if !defined(DOSCODE)
+ MoveGadgetList = createButton(VGAScaleX(1), y, 0, 't', MoveImages[0], MoveImages[1]);
+ curgad = MoveGadgetList;
+ curgad->NextGadget = createButton(VGAScaleX(33), y, 1, 'm', MoveImages[2], MoveImages[3]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(65), y, 2, 'o', MoveImages[4], MoveImages[5]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(97), y, 3, 'c', MoveImages[6], MoveImages[7]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(129), y, 4, 'l', MoveImages[8], MoveImages[9]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(161), y, 5, 'i', MoveImages[12], MoveImages[13]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(193), y, 6, VKEY_LTARROW, MoveImages[14], MoveImages[15]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(225), y, 7, VKEY_UPARROW, MoveImages[16], MoveImages[17]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(257), y, 8, VKEY_RTARROW, MoveImages[18], MoveImages[19]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(289), y, 9, 'p', MoveImages[10], MoveImages[11]);
+#else
+ MoveGadgetList = createButton(VGAScaleX(1), y, 0, MoveImages[0], MoveImages[1]);
+ curgad = MoveGadgetList;
+ curgad->NextGadget = createButton(VGAScaleX(33), y, 1, MoveImages[2], MoveImages[3]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(65), y, 2, MoveImages[4], MoveImages[5]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(97), y, 3, MoveImages[6], MoveImages[7]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(129), y, 4, MoveImages[8], MoveImages[9]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(161), y, 5, MoveImages[12], MoveImages[13]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(193), y, 6, MoveImages[14], MoveImages[15]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(225), y, 7, MoveImages[16], MoveImages[17]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(257), y, 8, MoveImages[18], MoveImages[19]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(289), y, 9, MoveImages[10], MoveImages[11]);
+#endif
+
+ InvPanelBufferSize = sizeOfFile("P:Inv");
+
+ if (InvPanelBufferSize == 0L)
+ return false;
+
+ if (!allocate((void **) &InvPanelBuffer, InvPanelBufferSize))
+ return false;
+
+ file = openPartial("P:Inv");
+
+ if (!file)
+ return false;
+
+ file->read(InvPanelBuffer, InvPanelBufferSize);
+ file->close();
+
+ *buffer = InvPanelBuffer;
+#if !defined(DOSCODE)
+
+ for (counter = 0; counter < 10; counter++)
+ readImage(buffer, &(InvImages[counter]));
+
+ InvGadgetList = createButton(VGAScaleX(24), y, 0, 'm', InvImages[0], InvImages[1]);
+ curgad = InvGadgetList;
+ curgad->NextGadget = createButton(VGAScaleX(56), y, 1, 'g', InvImages[2], InvImages[3]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(94), y, 2, 'u', InvImages[4], InvImages[5]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(126), y, 3, 'l', MoveImages[8], MoveImages[9]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(164), y, 4, VKEY_LTARROW, MoveImages[14], MoveImages[15]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(196), y, 5, VKEY_RTARROW, MoveImages[18], MoveImages[19]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(234), y, 6, 'b', InvImages[6], InvImages[7]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(266), y, 7, 'f', InvImages[8], InvImages[9]);
+ curgad = curgad->NextGadget;
+#else
+
+ for (counter = 0; counter < 6; counter++)
+ readImage(buffer, &(InvImages[counter]));
+
+ InvGadgetList = createButton(VGAScaleX(58), y, 0, InvImages[0], InvImages[1]);
+ curgad = InvGadgetList;
+ curgad->NextGadget = createButton(VGAScaleX(90), y, 1, InvImages[2], InvImages[3]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(128), y, 2, InvImages[4], InvImages[5]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(160), y, 3, MoveImages[8], MoveImages[9]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(198), y, 4, MoveImages[14], MoveImages[15]);
+ curgad = curgad->NextGadget;
+ curgad->NextGadget = createButton(VGAScaleX(230), y, 5, MoveImages[18], MoveImages[19]);
+ curgad = curgad->NextGadget;
+#endif
+
+ return true;
+}
+
+
+
+
+
+uint16 curmousex = 0, curmousey = 0;
+
+
+
+/******************************************************************************/
+/* Permanently flips the imagry of a gadget. */
+/******************************************************************************/
+static void perFlipGadget(uint16 GadID) {
+ struct Image *Temp;
+ struct Gadget *TopGad;
+
+ TopGad = MoveGadgetList;
+
+ while (TopGad) {
+ if (TopGad->GadgetID == GadID) {
+ Temp = TopGad->Im;
+ TopGad->Im = TopGad->ImAlt;
+ TopGad->ImAlt = Temp;
+
+ if (!Alternate) {
+ mouseHide();
+ drawImage(TopGad->Im, TopGad->x, TopGad->y);
+ mouseShow();
+ }
+
+ return;
+ } else
+ TopGad = TopGad->NextGadget;
+ }
+}
+
+
+
+/******************************************************************************/
+/* Eats all the available messages. */
+/******************************************************************************/
+void eatMessages(void) {
+ struct IntuiMessage *Msg;
+
+ do {
+ Msg = getMsg();
+
+ if (Msg) {
+ replyMsg((void *) Msg);
+ }
+ } while (Msg);
+
+ return;
+}
+
+
+
+
+
+static uint16 lastmusicroom = 1;
+
+
+/******************************************************************************/
+/* Checks the music that should be playing in a particular room. */
+/******************************************************************************/
+static void checkRoomMusic(void) {
+ if ((lastmusicroom == RoomNum) || !g_music->_musicOn)
+ return;
+
+ if (RoomNum == CLOWNROOM)
+ g_music->changeMusic("Music:Laugh");
+ else if (RoomNum == DIMROOM)
+ g_music->changeMusic("Music:Rm81");
+ else if (!DoNotReset)
+ g_music->resetMusic();
+
+ lastmusicroom = RoomNum;
+}
+
+
+
+#if defined(DOSCODE)
+#define MONLTMARGIN 0
+#define MONRTMARGIN 319
+#define MONTOPMARGIN 0
+#define LUTERTMARGIN 124
+#else
+#define MONLTMARGIN 2
+#define MONRTMARGIN 317
+#define MONTOPMARGIN 2
+#define LUTERTMARGIN 128
+#endif
+
+/******************************************************************************/
+/* Checks whether the close up is one of the special case closeups. */
+/******************************************************************************/
+static bool doCloseUp(CloseDataPtr cptr) {
+ if (cptr == NULL)
+ return false;
+
+ if ((cptr->CloseUpType == MUSEUMMONITOR) || (cptr->CloseUpType == LIBRARYMONITOR) ||
+ (cptr->CloseUpType == WINDOWMONITOR))
+ doMonitor(cptr->GraphicName, cptr->Message, false, MONLTMARGIN, MONTOPMARGIN, MONRTMARGIN, 165);
+ else if (cptr->CloseUpType == GRAMAPHONEMONITOR)
+ doMonitor(cptr->GraphicName, cptr->Message, false, MONLTMARGIN, MONTOPMARGIN, 171, 165);
+ else if (cptr->CloseUpType == UNICYCLEMONITOR)
+ doMonitor(cptr->GraphicName, cptr->Message, false, 100, MONTOPMARGIN, MONRTMARGIN, 165);
+ else if (cptr->CloseUpType == STATUEMONITOR)
+ doMonitor(cptr->GraphicName, cptr->Message, false, 117, MONTOPMARGIN, MONRTMARGIN, 165);
+ else if (cptr->CloseUpType == TALISMANMONITOR)
+ doMonitor(cptr->GraphicName, cptr->Message, false, MONLTMARGIN, MONTOPMARGIN, 184, 165);
+ else if (cptr->CloseUpType == LUTEMONITOR)
+ doMonitor(cptr->GraphicName, cptr->Message, false, MONLTMARGIN, MONTOPMARGIN, LUTERTMARGIN, 165);
+ else if (cptr->CloseUpType == CLOCKMONITOR)
+ doMonitor(cptr->GraphicName, cptr->Message, false, MONLTMARGIN, MONTOPMARGIN, 206, 165);
+ else if (cptr->CloseUpType == TERMINALMONITOR)
+ doMonitor(cptr->GraphicName, cptr->Message, true, MONLTMARGIN, MONTOPMARGIN, MONRTMARGIN, 165);
+ else
+ return false;
+
+ CurFileName = " ";
+ drawPanel();
+
+ return true;
+}
+
+
+
+
+/******************************************************************************/
+/* Gets the current inventory name. */
+/******************************************************************************/
+static const char *getInvName(uint16 CurInv) {
+ if (MainDisplay)
+ return Inventory[CurInv].BInvName;
+
+ if ((CurInv == LAMPNUM) && In(Conditions, LAMPON))
+ return "P:Mines/120";
+
+ else if ((CurInv == BELTNUM) && In(Conditions, BELTGLOW))
+ return "P:Future/BeltGlow";
+
+ else if (CurInv == WESTPAPERNUM) {
+ CurFileName = Inventory[CurInv].BInvName;
+ nopalchange = true;
+ readPict(CurFileName, false);
+ nopalchange = false;
+ doWestPaper();
+ }
+
+ else if (CurInv == NOTESNUM) {
+ CurFileName = Inventory[CurInv].BInvName;
+ nopalchange = true;
+ readPict(CurFileName, false);
+ nopalchange = false;
+ doNotes();
+ }
+
+ return Inventory[CurInv].BInvName;
+}
+
+
+
+
+static bool interfaceisoff = false;
+
+
+/******************************************************************************/
+/* Turns the interface off. */
+/******************************************************************************/
+static void interfaceOff(void) {
+ if (!interfaceisoff) {
+ attachGadgetList(NULL);
+ mouseHide();
+ interfaceisoff = true;
+ }
+}
+
+
+
+
+/******************************************************************************/
+/* Turns the interface on. */
+/******************************************************************************/
+static void interfaceOn(void) {
+ if (interfaceisoff) {
+ interfaceisoff = false;
+
+ mouseShow();
+ }
+
+ if (LongWinInFront)
+ attachGadgetList(NULL);
+ else if (Alternate)
+ attachGadgetList(InvGadgetList);
+ else
+ attachGadgetList(MoveGadgetList);
+}
+
+
+
+static const char *Test;
+
+
+/******************************************************************************/
+/* If the user hits the "Use" gadget; things that can get used on themselves. */
+/******************************************************************************/
+static bool doUse(uint16 CurInv) {
+
+ if (CurInv == MAPNUM) { /* LAB: Labyrinth specific */
+ drawMessage(USEMAP);
+ interfaceOff();
+ stopDiff();
+ CurFileName = " ";
+ CPtr = NULL;
+ doMap(RoomsFound, RoomNum);
+ VGASetPal(initcolors, 8);
+ drawMessage(NULL);
+ drawPanel();
+ }
+
+ else if (CurInv == JOURNALNUM) { /* LAB: Labyrinth specific */
+ drawMessage(USEJOURNAL);
+ interfaceOff();
+ stopDiff();
+ CurFileName = " ";
+ CPtr = NULL;
+ doJournal(Conditions);
+ drawPanel();
+ drawMessage(NULL);
+ }
+
+ else if (CurInv == LAMPNUM) { /* LAB: Labyrinth specific */
+ interfaceOff();
+
+ if (In(Conditions, LAMPON)) {
+ drawMessage(TURNLAMPOFF);
+ exclElement(Conditions, LAMPON);
+ } else {
+ drawMessage(TURNLAMPON);
+ inclElement(Conditions, LAMPON);
+ }
+
+ DoBlack = false;
+ waiteffect = true;
+ readPict("Music:Click", true);
+ waiteffect = false;
+
+ DoBlack = false;
+ Test = getInvName(CurInv);
+ }
+
+ else if (CurInv == BELTNUM) { /* LAB: Labyrinth specific */
+ if (!In(Conditions, BELTGLOW))
+ inclElement(Conditions, BELTGLOW);
+
+ DoBlack = false;
+ Test = getInvName(CurInv);
+ }
+
+ else if (CurInv == WHISKEYNUM) { /* LAB: Labyrinth specific */
+ inclElement(Conditions, USEDHELMET);
+ drawMessage(USEWHISKEY);
+ }
+
+ else if (CurInv == PITHHELMETNUM) { /* LAB: Labyrinth specific */
+ inclElement(Conditions, USEDHELMET);
+ drawMessage(USEPITH);
+ }
+
+ else if (CurInv == HELMETNUM) { /* LAB: Labyrinth specific */
+ inclElement(Conditions, USEDHELMET);
+ drawMessage(USEHELMET);
+ }
+
+ else
+ return false;
+
+ return true;
+}
+
+
+
+
+/******************************************************************************/
+/* Decrements the current inventory number. */
+/******************************************************************************/
+static void decIncInv(uint16 *CurInv, bool dec) {
+ interfaceOff();
+
+ if (dec)
+ (*CurInv)--;
+ else
+ (*CurInv)++;
+
+ while (*CurInv && (*CurInv <= NumInv)) {
+ if (In(Conditions, *CurInv) && Inventory[*CurInv].BInvName) {
+ Test = getInvName(*CurInv);
+ break;
+ }
+
+ if (dec)
+ (*CurInv)--;
+ else
+ (*CurInv)++;
+ }
+
+ if ((*CurInv == 0) || (*CurInv > NumInv)) {
+ if (dec)
+ *CurInv = NumInv;
+ else
+ *CurInv = 1;
+
+ while (*CurInv && (*CurInv <= NumInv)) {
+ if (In(Conditions, *CurInv) && Inventory[*CurInv].BInvName) {
+ Test = getInvName(*CurInv);
+ break;
+ }
+
+ if (dec)
+ (*CurInv)--;
+ else
+ (*CurInv)++;
+ }
+ }
+}
+
+
+#if defined(DOSCODE)
+static bool nosvgamem = false;
+static bool didintro = false;
+#else
+int didintro = false; // change to int do labw.c can access
+#endif
+static bool novesa = false, noaudio = false;
+
+
+void processEvents() {
+ warning("STUB: processEvents()");
+}
+
+/******************************************************************************/
+/* Processes user input events. */
+/******************************************************************************/
+static void process(void) {
+ struct IntuiMessage *Msg;
+ uint32 Class;
+
+ uint16 Code, Qualifier, MouseX, MouseY, ActionMode = 4, CurInv = MAPNUM, /* Lab: Labyrinth specific initialization */
+ LastInv = MAPNUM, /* Lab: Labyrinth specific initialization */
+ Old;
+
+ bool ForceDraw = false, doit, GotMessage = true;
+
+ uint16 OldRoomNum,
+#if !defined(DOSCODE)
+ OldDirection,
+#endif
+ GadID, NewDir;
+
+ CloseDataPtr OldCPtr, TempCPtr, HCPtr = NULL;
+ ViewDataPtr VPtr;
+
+ VGASetPal(initcolors, 8);
+
+ CPtr = NULL;
+ RoomNum = 1;
+ Direction = NORTH;
+
+ readRoomData("LAB:Doors");
+ readInventory("LAB:Inventor");
+
+ if (!createSet(&Conditions, HighestCondition + 1))
+ return;
+
+ if (!createSet(&RoomsFound, ManyRooms + 1))
+ return;
+
+ readInitialConditions(Conditions, "LAB:Conditio");
+
+ LongWinInFront = false;
+ drawPanel();
+
+ perFlipGadget(ActionMode);
+
+ /* Set up initial picture. */
+
+ while (1) {
+ processEvents();
+
+ if (GotMessage) {
+ if (QuitLab) {
+ stopDiff();
+ break;
+ }
+
+ g_music->restartBackMusic();
+
+ /* Sees what kind of close up we're in and does the appropriate stuff, if any. */
+ if (doCloseUp(CPtr)) {
+ CPtr = NULL;
+#if !defined(DOSCODE)
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ }
+
+ /* Sets the current picture properly on the screen */
+ if (MainDisplay)
+ Test = getPictName(&CPtr);
+
+ if (noupdatediff) {
+ inclElement(RoomsFound, RoomNum); /* Potentially entered another room */
+ ForceDraw = (strcmp(Test, CurFileName) != 0) || ForceDraw;
+
+ noupdatediff = false;
+ CurFileName = Test;
+ }
+
+ else if (strcmp(Test, CurFileName) != 0) {
+ interfaceOff();
+ inclElement(RoomsFound, RoomNum); /* Potentially entered another room */
+ CurFileName = Test;
+
+ if (CPtr) {
+ if ((CPtr->CloseUpType == SPECIALLOCK) && MainDisplay) /* LAB: Labyrinth specific code */
+ showCombination(CurFileName);
+ else if (((CPtr->CloseUpType == SPECIALBRICK) ||
+ (CPtr->CloseUpType == SPECIALBRICKNOMOUSE)) &&
+ MainDisplay) /* LAB: Labyrinth specific code */
+ showTile(CurFileName, (bool)(CPtr->CloseUpType == SPECIALBRICKNOMOUSE));
+ else
+ readPict(CurFileName, false);
+ } else
+ readPict(CurFileName, false);
+
+ drawRoomMessage(CurInv, CPtr);
+ ForceDraw = false;
+
+#if !defined(DOSCODE)
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+
+ if (!FollowingCrumbs)
+ eatMessages();
+
+#else
+ eatMessages();
+#endif
+ }
+
+ if (ForceDraw) {
+ drawRoomMessage(CurInv, CPtr);
+ ForceDraw = false;
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+ }
+
+ g_music->checkMusic(); /* Make sure we check the music at least after every message */
+ interfaceOn();
+ Msg = getMsg();
+
+ if (Msg == NULL) { /* Does music load and next animation frame when you've run out of messages */
+ GotMessage = false;
+ checkRoomMusic();
+ g_music->newCheckMusic();
+ diffNextFrame();
+#if !defined(DOSCODE)
+
+ if (FollowingCrumbs) {
+ int result = followCrumbs();
+
+ if (result != 0) {
+ int x = 0, y = 0;
+
+ warning("STUB: getMousePos()");
+ //SDL_GetMousePos(&x, &y);
+
+ Class = GADGETUP;
+ Qualifier = 0;
+ MouseX = x;
+ MouseY = y;
+
+ if (result == VKEY_UPARROW) {
+ Code = GadID = 7;
+ } else if (result == VKEY_LTARROW) {
+ Code = GadID = 6;
+ } else if (result == VKEY_RTARROW) {
+ Code = GadID = 8;
+ }
+
+ GotMessage = true;
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+ goto from_crumbs;
+ }
+ }
+
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ } else {
+ GotMessage = true;
+
+ Class = Msg->Class;
+ Code = Msg->Code;
+ Qualifier = Msg->Qualifier;
+ MouseX = Msg->MouseX;
+ MouseY = Msg->MouseY;
+ GadID = Msg->GadgetID;
+
+ replyMsg((void *) Msg);
+
+#if !defined(DOSCODE)
+ FollowingCrumbs = false;
+
+from_crumbs:
+#endif
+ DoBlack = false;
+
+ if ((Class == RAWKEY) && (!LongWinInFront)) {
+ if (Code == 13) { /* The return key */
+ Class = MOUSEBUTTONS;
+ Qualifier = IEQUALIFIER_LEFTBUTTON;
+ mouseXY(&MouseX, &MouseY);
+ }
+
+#if !defined(DOSCODE)
+ else if (Code == 'b' || Code == 'B') { /* Start bread crumbs */
+ BreadCrumbs[0].RoomNum = 0;
+ NumCrumbs = 0;
+ DroppingCrumbs = true;
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+ }
+
+ else if (Code == 'f' || Code == 'F' ||
+ Code == 'r' || Code == 'R') { /* Follow bread crumbs */
+ if (DroppingCrumbs) {
+ if (NumCrumbs > 0) {
+ FollowingCrumbs = true;
+ FollowCrumbsFast = (Code == 'r' || Code == 'R');
+ IsCrumbTurning = false;
+ IsCrumbWaiting = false;
+ getTime(&CrumbSecs, &CrumbMicros);
+
+ if (Alternate) {
+ eatMessages();
+ Alternate = false;
+ DoBlack = true;
+ DoNotDrawMessage = false;
+
+ MainDisplay = true;
+ interfaceOn(); /* Sets the correct gadget list */
+ drawPanel();
+ drawRoomMessage(CurInv, CPtr);
+ g_system->updateScreen();
+ }
+ } else {
+ BreadCrumbs[0].RoomNum = 0;
+ DroppingCrumbs = false;
+
+ // Need to hide indicator!!!!
+ mayShowCrumbIndicatorOff();
+ g_system->updateScreen();
+ }
+ }
+ }
+
+#endif
+
+ else if ((Code == 315) || (Code == 'x') || (Code == 'X')
+ || (Code == 'q') || (Code == 'Q')) { /* Quit? */
+ DoNotDrawMessage = false;
+ drawMessage("Do you want to quit? (Y/N)");
+ doit = false;
+ eatMessages();
+ interfaceOff();
+
+ while (1) {
+ g_music->checkMusic(); /* Make sure we check the music at least after every message */
+ Msg = getMsg();
+
+ if (Msg == NULL) { /* Does music load and next animation frame when you've run out of messages */
+ g_music->newCheckMusic();
+ diffNextFrame();
+ } else {
+ replyMsg((void *) Msg); /* Can't do this in non-IBM versions */
+
+ if (Msg->Class == RAWKEY) {
+#if defined(DOSCODE)
+
+ if ((Msg->Code == 'Y') || (Msg->Code == 'y'))
+#else
+ if ((Msg->Code == 'Y') || (Msg->Code == 'y') || (Msg->Code == 'Q') || (Msg->Code == 'q'))
+#endif
+ {
+ doit = true;
+ break;
+ } else if (Msg->Code < 128) {
+ break;
+ }
+ } else if (Msg->Class == MOUSEBUTTONS) {
+ break;
+ }
+ }
+ }
+
+ if (doit) {
+ stopDiff();
+ break;
+ } else {
+ ForceDraw = true;
+ interfaceOn();
+ }
+ }
+
+#ifdef undef
+ else if (Code == 324) {
+ if (BUFFERSIZE >= BIGBUFFERSIZE) { /* F10 key to switch resolutions */
+ blackAllScreen();
+ setMode((char) OldMode);
+
+ Alternate = false;
+ MainDisplay = true;
+ attachGadgetList(NULL);
+ fillUpMusic(true);
+ g_system->delayMillis(750);
+
+ IsHiRes = !IsHiRes;
+
+ deallocate(MovePanelBuffer, MovePanelBufferSize);
+ deallocate(InvPanelBuffer, InvPanelBufferSize);
+ freeButtonList(MoveGadgetList);
+ freeButtonList(InvGadgetList);
+ MoveGadgetList = NULL;
+ InvGadgetList = NULL;
+
+ if (!setUpScreens()) {
+ IsHiRes = false;
+ setUpScreens();
+ }
+
+ blackAllScreen();
+ resetBuffer();
+ CPtr = NULL;
+ DoBlack = true;
+ CurFileName = " ";
+ closeFont(MsgFont);
+ openFont("P:AvanteG.12", &MsgFont);
+ /*
+ mouseReset();
+ */
+ initMouse();
+ drawPanel();
+ perFlipGadget(ActionMode);
+ } else
+ drawMessage("Not enough memory to change resolutions.");
+ }
+
+#endif
+
+ else if (Code == 9) { /* TAB key */
+ Class = DELTAMOVE;
+ }
+
+ else if (Code == 27) { /* ESC key */
+ CPtr = NULL;
+ }
+
+ eatMessages();
+ }
+
+ if (LongWinInFront) {
+ if ((Class == RAWKEY) ||
+ ((Class == MOUSEBUTTONS) &&
+ ((IEQUALIFIER_LEFTBUTTON & Qualifier) ||
+ (IEQUALIFIER_RBUTTON & Qualifier)))) {
+ LongWinInFront = false;
+ DoNotDrawMessage = false;
+ drawPanel();
+ drawRoomMessage(CurInv, CPtr);
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+ }
+
+ else if ((Class == GADGETUP) && !Alternate) {
+ if (GadID <= 5) {
+ if ((ActionMode == 4) && (GadID == 4) && (CPtr != NULL)) {
+ doMainView(&CPtr);
+
+ DoBlack = true;
+ HCPtr = NULL;
+ CPtr = NULL;
+#if !defined(DOSCODE)
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ }
+
+ else if (GadID == 5) {
+ eatMessages();
+
+ Alternate = true;
+ DoBlack = true;
+ DoNotDrawMessage = false;
+ interfaceOn(); /* Sets the correct gadget list */
+
+ MainDisplay = false;
+
+ if (LastInv && In(Conditions, LastInv)) {
+ CurInv = LastInv;
+ Test = getInvName(CurInv);
+ } else
+ decIncInv(&CurInv, false);
+
+ drawPanel();
+ drawRoomMessage(CurInv, CPtr);
+#if !defined(DOSCODE)
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ } else {
+ Old = ActionMode;
+ ActionMode = GadID;
+
+ if (Old < 5)
+ perFlipGadget(Old);
+
+ perFlipGadget(ActionMode);
+
+ if (GadID == 0)
+ drawMessage(TAKEWHAT);
+ else if (GadID == 1)
+ drawMessage(MOVEWHAT);
+ else if (GadID == 2)
+ drawMessage(OPENWHAT);
+ else if (GadID == 3)
+ drawMessage(CLOSEWHAT);
+ else if (GadID == 4)
+ drawMessage(LOOKWHAT);
+
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+ }
+
+ else if (GadID == 9) {
+ doUse(MAPNUM);
+#if !defined(DOSCODE)
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ }
+
+ else if (GadID >= 6) { /* Arrow Gadgets */
+ CPtr = NULL;
+ HCPtr = NULL;
+
+ if ((GadID == 6) || (GadID == 8)) {
+ if (GadID == 6)
+ drawMessage(TURNLEFT);
+ else
+ drawMessage(TURNRIGHT);
+
+ CurFileName = " ";
+#if !defined(DOSCODE)
+ OldDirection = Direction;
+#endif
+ NewDir = Direction;
+ processArrow(&NewDir, GadID - 6);
+ doTurn(Direction, NewDir, &CPtr);
+ DoBlack = true;
+ Direction = NewDir;
+ ForceDraw = true;
+#if !defined(DOSCODE)
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ } else if (GadID == 7) {
+ OldRoomNum = RoomNum;
+
+ if (doGoForward(&CPtr)) {
+ if (OldRoomNum == RoomNum)
+ DoBlack = true;
+ } else {
+ DoBlack = true;
+ processArrow(&Direction, GadID - 6);
+
+ if (OldRoomNum != RoomNum) {
+ drawMessage(GOFORWARDDIR);
+ inclElement(RoomsFound, RoomNum); /* Potentially entered a new room */
+ CurFileName = " ";
+ ForceDraw = true;
+ } else {
+ DoBlack = true;
+ drawMessage(NOPATH);
+ }
+ }
+
+#if defined(DEMODATA)
+ {
+ void writeDemoData();
+ writeDemoData();
+ }
+#endif
+
+#if !defined(DOSCODE)
+
+ if (FollowingCrumbs) {
+ if (IsCrumbTurning) {
+ if (Direction == OldDirection) {
+ FollowingCrumbs = false;
+ }
+ } else {
+ if (RoomNum == OldRoomNum) { // didn't get there?
+ FollowingCrumbs = false;
+ }
+ }
+ } else if (DroppingCrumbs && OldRoomNum != RoomNum) {
+ // If in surreal maze, turn off DroppingCrumbs.
+ // Note: These numbers were generated by parsing the
+ // "Maps" file, which is why they are hard-coded. Bleh!
+ if (RoomNum >= 245 && RoomNum <= 280) {
+ FollowingCrumbs = false;
+ DroppingCrumbs = false;
+ NumCrumbs = 0;
+ BreadCrumbs[0].RoomNum = 0;
+ } else {
+ bool intersect = false;
+ int i;
+
+ for (i = 0; i < NumCrumbs; i++) {
+ if (BreadCrumbs[i].RoomNum == RoomNum) {
+ NumCrumbs = i + 1;
+ BreadCrumbs[NumCrumbs].RoomNum = 0;
+ intersect = true;
+ }
+ }
+
+ if (!intersect) {
+ if (NumCrumbs == MAX_CRUMBS) {
+ NumCrumbs = MAX_CRUMBS - 1;
+ memcpy(&BreadCrumbs[0], &BreadCrumbs[1], NumCrumbs * sizeof BreadCrumbs[0]);
+ }
+
+ BreadCrumbs[NumCrumbs].RoomNum = RoomNum;
+ BreadCrumbs[NumCrumbs++].Direction = Direction;
+ }
+ }
+ }
+
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ }
+ }
+ }
+
+ else if ((Class == GADGETUP) && Alternate) {
+ DoBlack = true;
+
+ if (GadID == 0) {
+ eatMessages();
+ Alternate = false;
+ DoBlack = true;
+ DoNotDrawMessage = false;
+
+ MainDisplay = true;
+ interfaceOn(); /* Sets the correct gadget list */
+ drawPanel();
+ drawRoomMessage(CurInv, CPtr);
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+
+ GadID--;
+
+ if (GadID == 0) {
+ interfaceOff();
+ stopDiff();
+ CurFileName = " ";
+
+ doit = !saveRestoreGame();
+ CPtr = NULL;
+
+ MainDisplay = true;
+
+ CurInv = MAPNUM;
+ LastInv = MAPNUM;
+
+ Test = getInvName(CurInv);
+
+ drawPanel();
+
+ if (doit) {
+ drawMessage("Disk operation failed.");
+ VGASetPal(initcolors, 8);
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ g_system->delayMillis(1000);
+ }
+
+#if !defined(DOSCODE)
+ else {
+ g_system->updateScreen();
+ }
+
+#endif
+ }
+
+ else if (GadID == 1) {
+ if (!doUse(CurInv)) {
+ Old = ActionMode;
+ ActionMode = 5; /* Use button */
+
+ if (Old < 5)
+ perFlipGadget(Old);
+
+ drawMessage(USEONWHAT);
+ MainDisplay = true;
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+ }
+
+ else if (GadID == 2) {
+ MainDisplay = !MainDisplay;
+
+ if ((CurInv == 0) || (CurInv > NumInv)) {
+ CurInv = 1;
+
+ while ((CurInv <= NumInv) && (!In(Conditions, CurInv)))
+ CurInv++;
+ }
+
+ if ((CurInv <= NumInv) && In(Conditions, CurInv) &&
+ Inventory[CurInv].BInvName)
+ Test = getInvName(CurInv);
+
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+
+ else if (GadID == 3) { /* Left gadget */
+ decIncInv(&CurInv, true);
+ LastInv = CurInv;
+ DoNotDrawMessage = false;
+ drawRoomMessage(CurInv, CPtr);
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+
+ else if (GadID == 4) { /* Right gadget */
+ decIncInv(&CurInv, false);
+ LastInv = CurInv;
+ DoNotDrawMessage = false;
+ drawRoomMessage(CurInv, CPtr);
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+
+#if !defined(DOSCODE)
+ else if (GadID == 5) { /* bread crumbs */
+ BreadCrumbs[0].RoomNum = 0;
+ NumCrumbs = 0;
+ DroppingCrumbs = true;
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+ }
+
+ else if (GadID == 6) { /* follow crumbs */
+ if (DroppingCrumbs) {
+ if (NumCrumbs > 0) {
+ FollowingCrumbs = true;
+ FollowCrumbsFast = false;
+ IsCrumbTurning = false;
+ IsCrumbWaiting = false;
+ getTime(&CrumbSecs, &CrumbMicros);
+
+ eatMessages();
+ Alternate = false;
+ DoBlack = true;
+ DoNotDrawMessage = false;
+
+ MainDisplay = true;
+ interfaceOn(); /* Sets the correct gadget list */
+ drawPanel();
+ drawRoomMessage(CurInv, CPtr);
+ g_system->updateScreen();
+ } else {
+ BreadCrumbs[0].RoomNum = 0;
+ DroppingCrumbs = false;
+
+ // Need to hide indicator!!!!
+ mayShowCrumbIndicatorOff();
+ g_system->updateScreen();
+ }
+ }
+ }
+ }
+
+#endif
+
+ else if ((Class == MOUSEBUTTONS) && (IEQUALIFIER_LEFTBUTTON & Qualifier) && MainDisplay) {
+ interfaceOff();
+ MainDisplay = true;
+
+ doit = false;
+
+ if (CPtr) {
+ if ((CPtr->CloseUpType == SPECIALLOCK) && MainDisplay) /* LAB: Labrinth specific code */
+ mouseCombination(Conditions, MouseX, MouseY);
+ else if ((CPtr->CloseUpType == SPECIALBRICK) && MainDisplay)
+ mouseTile(Conditions, MouseX, MouseY);
+ else
+ doit = true;
+ } else
+ doit = true;
+
+
+ if (doit) {
+ HCPtr = NULL;
+ eatMessages();
+
+ if (ActionMode == 0) { /* Take something. */
+ if (doActionRule(MouseX, MouseY, ActionMode, RoomNum, &CPtr))
+ CurFileName = NewFileName;
+ else if (takeItem(MouseX, MouseY, &CPtr))
+ drawMessage(TAKEITEM);
+ else if (doActionRule(MouseX, MouseY, TAKEDEF - 1, RoomNum, &CPtr))
+ CurFileName = NewFileName;
+ else if (doActionRule(MouseX, MouseY, TAKE - 1, 0, &CPtr))
+ CurFileName = NewFileName;
+ else if (MouseY < (VGAScaleY(149) + SVGACord(2)))
+ drawMessage(NOTHING);
+ }
+
+ else if ((ActionMode == 1) /* Manipulate an object */ ||
+ (ActionMode == 2) /* Open up a "door" */ ||
+ (ActionMode == 3)) { /* Close a "door" */
+ if (doActionRule(MouseX, MouseY, ActionMode, RoomNum, &CPtr))
+ CurFileName = NewFileName;
+ else if (!doActionRule(MouseX, MouseY, ActionMode, 0, &CPtr)) {
+ if (MouseY < (VGAScaleY(149) + SVGACord(2)))
+ drawMessage(NOTHING);
+ }
+ }
+
+ else if (ActionMode == 4) { /* Look at closeups */
+ TempCPtr = CPtr;
+ setCurClose(MouseX, MouseY, &TempCPtr);
+
+ if (CPtr == TempCPtr) {
+ if (MouseY < (VGAScaleY(149) + SVGACord(2)))
+ drawMessage(NOTHING);
+ } else if (TempCPtr->GraphicName) {
+ if (*(TempCPtr->GraphicName)) {
+ DoBlack = true;
+ CPtr = TempCPtr;
+ } else if (MouseY < (VGAScaleY(149) + SVGACord(2)))
+ drawMessage(NOTHING);
+ } else if (MouseY < (VGAScaleY(149) + SVGACord(2)))
+ drawMessage(NOTHING);
+ }
+
+ else if ((ActionMode == 5) &&
+ In(Conditions, CurInv)) { /* Use an item on something else */
+ if (doOperateRule(MouseX, MouseY, CurInv, &CPtr)) {
+ CurFileName = NewFileName;
+
+ if (!In(Conditions, CurInv))
+ decIncInv(&CurInv, false);
+ } else if (MouseY < (VGAScaleY(149) + SVGACord(2)))
+ drawMessage(NOTHING);
+ }
+ }
+
+#if !defined(DOSCODE)
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ }
+
+ else if (Class == DELTAMOVE) {
+ VPtr = getViewData(RoomNum, Direction);
+ OldCPtr = VPtr->closeUps;
+
+ if (HCPtr == NULL) {
+ TempCPtr = CPtr;
+ setCurClose(MouseX, MouseY, &TempCPtr);
+
+ if ((TempCPtr == NULL) || (TempCPtr == CPtr)) {
+ if (CPtr == NULL)
+ HCPtr = OldCPtr;
+ else
+ HCPtr = CPtr->SubCloseUps;
+ } else
+ HCPtr = TempCPtr->NextCloseUp;
+ } else
+ HCPtr = HCPtr->NextCloseUp;
+
+
+ if (HCPtr == NULL) {
+ if (CPtr == NULL)
+ HCPtr = OldCPtr;
+ else
+ HCPtr = CPtr->SubCloseUps;
+ }
+
+ if (HCPtr)
+ mouseMove(scaleX((HCPtr->x1 + HCPtr->x2) / 2), scaleY((HCPtr->y1 + HCPtr->y2) / 2));
+ }
+
+ else if ((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) {
+ eatMessages();
+ Alternate = !Alternate;
+ DoBlack = true;
+ DoNotDrawMessage = false;
+ MainDisplay = true;
+ interfaceOn(); /* Sets the correct gadget list */
+
+ if (Alternate) {
+ if (LastInv && In(Conditions, LastInv))
+ CurInv = LastInv;
+ else
+ decIncInv(&CurInv, false);
+ }
+
+ drawPanel();
+ drawRoomMessage(CurInv, CPtr);
+#if !defined(DOSCODE)
+ mayShowCrumbIndicator();
+ g_system->updateScreen();
+#endif
+ }
+ }
+ }
+
+ if (Conditions)
+ deleteSet(Conditions);
+
+ if (RoomsFound)
+ deleteSet(RoomsFound);
+
+ if (Rooms)
+ deallocate(Rooms, (ManyRooms + 1) * sizeof(RoomData));
+
+ if (Inventory) {
+ for (Code = 1; Code <= NumInv; Code++) {
+ if (Inventory[Code].name)
+ deallocate(Inventory[Code].name, strlen(Inventory[Code].name) + 1);
+
+ if (Inventory[Code].BInvName)
+ deallocate(Inventory[Code].BInvName, strlen(Inventory[Code].BInvName) + 1);
+ }
+
+ deallocate(Inventory, (NumInv + 1) * sizeof(InventoryData));
+ }
+}
+
+
+/*
+ void mySignalHandler(int sig)
+ {
+ signal(sig, mySignalHandler);
+ }
+ */
+
+
+
+#if defined(DOSCODE)
+void (__interrupt __far *oldctrlc)(), (__interrupt __far *oldctrlcb)();
+
+uint16 iretdummy;
+void __interrupt __far myiret() {
+ iretdummy++;
+}
+#endif
+
+
+void inner_main() {
+ bool mem, dointro = false;
+ uint16 counter;
+
+ getMode(&OldMode);
+
+ IsHiRes = true;
+ DoMusic = true;
+ g_music->_turnMusicOn = true;
+ dointro = true;
+
+#if 0
+ for (counter = 1; counter < argc; counter++) {
+#if defined(DOSCODE)
+
+ if (((argv[counter])[0] == 'v') || ((argv[counter])[0] == 'V')) {
+ IsHiRes = false;
+ } else
+#endif
+ if (((argv[counter])[0] == 'q') || ((argv[counter])[0] == 'Q')) {
+ DoMusic = false;
+ g_music->_turnMusicOn = false;
+ }
+
+#ifdef _DEBUG
+ else if (((argv[counter])[0] == 'i') || ((argv[counter])[0] == 'I')) {
+ dointro = false;
+ }
+
+#endif
+ else if (((argv[counter])[0] == '/') && ((argv[counter])[1] == '?')) {
+ debug("\n\nPlayer Version 1.0. Copyright (c) 1993 Terra Nova Development\n");
+ debug("Player v q\n");
+#ifdef _DEBUG
+ debug(" i : Skip intro (debug only).\n");
+#endif
+#if defined(DOSCODE)
+ debug(" v : Open up on a low res VGA display.\n");
+#endif
+ debug(" q : Start in quiet mode; no sound output.\n\n");
+ return;
+ }
+ }
+#endif
+
+ if (initBuffer(BUFFERSIZE, true)) {
+ mem = true;
+ } else {
+#if defined(DOSCODE)
+ BUFFERSIZE = SMALLBUFFERSIZE;
+ mem = initBuffer(BUFFERSIZE, true);
+ IsHiRes = false;
+ nosvgamem = true;
+#else
+ // unacceptable !!!!
+ warning("initBuffer() failed");
+ return;
+#endif
+ }
+
+ if (!initAudio()) {
+ noaudio = true;
+ DoMusic = false;
+ g_music->_turnMusicOn = false;
+ debug("Could not open Audio.");
+ g_system->delayMillis(500);
+ }
+
+ if (!setUpScreens()) {
+ IsHiRes = false;
+ novesa = true;
+ mem = mem && setUpScreens();
+ }
+
+ if (!initMouse()) {
+ setMode((char) OldMode);
+#if defined(DOSCODE)
+ _dos_setvect(0x23, oldctrlc);
+ _dos_setvect(0x1B, oldctrlcb);
+#endif
+ debug("\n\nMouse or mouse driver not installed!\n\n");
+ return;
+ }
+
+ mem = mem && initRoomBuffer() &&
+ initLabText();
+
+ doDisks();
+
+ if (!dointro)
+ g_music->initMusic();
+
+ openFont("P:AvanteG.12", &MsgFont);
+
+ if (dointro && mem) {
+#if defined(DOSCODE)
+ didintro = true;
+#endif
+ introSequence();
+#if !defined(DOSCODE)
+ didintro = true;
+#endif
+ } else
+ DoBlack = true;
+
+ if (mem) {
+ mouseShow();
+ process();
+ } else
+ debug("\n\nNot enough memory to start game.\n\n");
+
+ if (QuitLab) { /* Won the game */
+ blackAllScreen();
+ readPict("P:End/L2In.1", true);
+
+ for (counter = 0; counter < 120; counter++) {
+ g_music->newCheckMusic();
+ waitTOF();
+ }
+
+ readPict("P:End/L2In.9", true);
+ readPict("P:End/Lost", true);
+
+#if defined(DOSCODE)
+ counter = 600;
+
+ while (counter) {
+ newCheckMusic();
+ diffNextFrame();
+ waitTOF();
+ counter--;
+ }
+
+#else
+
+ warning("STUB: waitForPress");
+ while (!1) { // 1 means ignore SDL_ProcessInput calls
+ g_music->newCheckMusic();
+ diffNextFrame();
+ waitTOF();
+ }
+
+ // If we weren't exiting, a call to a mythical SDL_StopWaitForPress() would be in order.
+#endif
+ }
+
+ closeFont(MsgFont);
+
+ freeLabText();
+ freeRoomBuffer();
+ freeBuffer();
+
+ g_music->freeMusic();
+ freeAudio();
+
+ mouseReset();
+ setMode((char) OldMode);
+
+#if defined(DOSCODE)
+ _dos_setvect(0x23, oldctrlc);
+ _dos_setvect(0x1B, oldctrlcb);
+#endif
+}
+
+#if !defined(DOSCODE)
+/*****************************************************************************/
+/* New code to allow quick(er) return navigation in game. */
+/*****************************************************************************/
+int followCrumbs() {
+ // NORTH, SOUTH, EAST, WEST
+ static int movement[4][4] = {
+ { VKEY_UPARROW, VKEY_RTARROW, VKEY_RTARROW, VKEY_LTARROW }, { VKEY_RTARROW, VKEY_UPARROW, VKEY_LTARROW, VKEY_RTARROW }, { VKEY_LTARROW, VKEY_RTARROW, VKEY_UPARROW, VKEY_RTARROW }, { VKEY_RTARROW, VKEY_LTARROW, VKEY_RTARROW, VKEY_UPARROW }
+#if 0
+ { -1, EAST, EAST, WEST }, { WEST, -1, EAST, WEST }, { NORTH, SOUTH, -1, SOUTH }, { NORTH, SOUTH, NORTH, -1 }
+#endif
+ };
+
+ int ExitDir;
+ int MoveDir;
+
+ if (IsCrumbWaiting) {
+ uint32 Secs;
+ uint32 Micros;
+
+ timeDiff(CrumbSecs, CrumbMicros, &Secs, &Micros);
+
+ if (Secs != 0 || Micros != 0)
+ return 0;
+
+ IsCrumbWaiting = false;
+ }
+
+ if (!IsCrumbTurning)
+ BreadCrumbs[NumCrumbs--].RoomNum = 0;
+
+ // Is the current crumb this room? If not, logic error.
+ if (RoomNum != BreadCrumbs[NumCrumbs].RoomNum) {
+ NumCrumbs = 0;
+ BreadCrumbs[0].RoomNum = 0;
+ DroppingCrumbs = false;
+ FollowingCrumbs = false;
+ return 0;
+ }
+
+ // which direction is last crumb
+ if (BreadCrumbs[NumCrumbs].Direction == EAST)
+ ExitDir = WEST;
+ else if (BreadCrumbs[NumCrumbs].Direction == WEST)
+ ExitDir = EAST;
+ else if (BreadCrumbs[NumCrumbs].Direction == NORTH)
+ ExitDir = SOUTH;
+ else
+ ExitDir = NORTH;
+
+ MoveDir = movement[Direction][ExitDir];
+
+ if (NumCrumbs == 0) {
+ IsCrumbTurning = false;
+ BreadCrumbs[0].RoomNum = 0;
+ DroppingCrumbs = false;
+ FollowingCrumbs = false;
+ } else {
+ int theDelay = (FollowCrumbsFast ? ONESECOND / 4 : ONESECOND);
+
+ IsCrumbTurning = (MoveDir != VKEY_UPARROW);
+ IsCrumbWaiting = true;
+
+ addCurTime(theDelay / ONESECOND, theDelay % ONESECOND, &CrumbSecs, &CrumbMicros);
+ }
+
+ return MoveDir;
+}
+
+byte dropCrumbs[] = { 0x00 };
+byte dropCrumbsOff[] = { 0x00 };
+
+struct Image DropCrumbsImage = { 24, 24, dropCrumbs };
+struct Image DropCrumbsOffImage = { 24, 24, dropCrumbsOff };
+
+void mayShowCrumbIndicator() {
+ if (DroppingCrumbs && MainDisplay) {
+ mouseHide();
+ drawMaskImage(&DropCrumbsImage, 612, 4);
+ mouseShow();
+ }
+}
+
+void mayShowCrumbIndicatorOff() {
+ if (MainDisplay) {
+ mouseHide();
+ drawMaskImage(&DropCrumbsOffImage, 612, 4);
+ mouseShow();
+ }
+}
+#endif
+
+} // End of namespace Lab
diff --git a/engines/lab/graphics.cpp b/engines/lab/graphics.cpp
new file mode 100644
index 0000000000..bcaed9ceab
--- /dev/null
+++ b/engines/lab/graphics.cpp
@@ -0,0 +1,902 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/diff.h"
+#include "lab/parsetypes.h"
+#include "lab/labfun.h"
+#include "lab/parsefun.h"
+#include "lab/mouse.h"
+#include "lab/vga.h"
+#include "lab/text.h"
+
+namespace Lab {
+
+struct BitMap bit1, bit2, *DispBitMap = &bit1, *DrawBitMap = &bit1;
+
+
+extern struct BitMap RawDiffBM;
+extern char diffcmap[256 * 3], lastcmap[256 * 3];
+extern bool IsBM, NoFlip, nopalchange, ContMusic;
+
+extern int32 ReadSoFar;
+extern bool ReadIsDone, ReadIsError;
+extern bool DoBlack, EffectPlaying, stopsound;
+extern bool IsHiRes;
+extern struct TextFont *MsgFont;
+extern const char *CurFileName;
+
+
+
+
+
+/*---------------------------------------------------------------------------*/
+/*------ From readPict.c. Reads in pictures and animations from disk. ------*/
+/*---------------------------------------------------------------------------*/
+
+
+extern uint32 VGAScreenWidth, VGAScreenHeight, VGAPages, VGABytesPerPage;
+
+/*****************************************************************************/
+/* Reads in a picture into the dest bitmap. */
+/*****************************************************************************/
+bool readPict(const char *filename, bool PlayOnce) {
+ byte **file = NULL;
+#if defined(DOSCODE)
+ uint16 counter;
+#endif
+
+ stopDiff();
+
+ ReadSoFar = 0L;
+ ReadIsDone = false;
+ ReadIsError = false;
+
+ file = g_music->newOpen(filename);
+
+ if (file == NULL) {
+ if ((filename[0] == 'p') || (filename[0] == 'P'))
+ blackScreen();
+
+ return false;
+ }
+
+ DispBitMap->BytesPerRow = VGAScreenWidth;
+ DispBitMap->Rows = VGAScreenHeight;
+#if defined(DOSCODE)
+ DispBitMap->Flags = 0;
+#else
+ DispBitMap->Flags = BITMAPF_VIDEO;
+#endif
+ DispBitMap->Depth = VGAPages;
+#if defined(DOSCODE)
+
+ for (counter = 0; counter < VGAPages; counter++)
+ DispBitMap->Planes[counter] = getVGABaseAddr();
+
+#else
+ // playDiff deals with resetting planes for the "video" display.
+#endif
+
+ readDiff(PlayOnce);
+
+#if !defined(DOSCODE)
+ ungetVGABaseAddr();
+#endif
+
+ return true;
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads in a music file. Ignores any graphics. */
+/*****************************************************************************/
+bool readMusic(const char *filename) {
+ byte **file = NULL;
+
+ file = g_music->newOpen(filename);
+
+ if (file == NULL) {
+ return false;
+ }
+
+ DoBlack = false;
+ readSound();
+
+ return true;
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads in a picture into buffer memory. */
+/*****************************************************************************/
+byte *readPictToMem(const char *filename, uint16 x, uint16 y) {
+ byte **file = NULL;
+ byte *Mem, *CurMem;
+#if defined(DOSCODE)
+ uint16 counter;
+#endif
+
+ stopDiff();
+
+ ReadSoFar = 0L;
+ ReadIsDone = false;
+ ReadIsError = false;
+
+ allocFile((void **)&Mem, (int32) x * (int32) y, "Bitmap");
+ CurMem = Mem;
+
+ file = g_music->newOpen(filename);
+
+ if (file == NULL)
+ return NULL;
+
+ DispBitMap->BytesPerRow = x;
+ DispBitMap->Rows = y;
+ DispBitMap->Flags = 0;
+ DispBitMap->Depth = VGAPages;
+#if defined(DOSCODE)
+
+ for (counter = 0; counter < VGAPages; counter++) {
+ DispBitMap->Planes[counter] = CurMem;
+ CurMem += VGABytesPerPage;
+ }
+
+#else
+ DispBitMap->Planes[0] = CurMem;
+ DispBitMap->Planes[1] = DispBitMap->Planes[0] + 0x10000;
+ DispBitMap->Planes[2] = DispBitMap->Planes[1] + 0x10000;
+ DispBitMap->Planes[3] = DispBitMap->Planes[2] + 0x10000;
+ DispBitMap->Planes[4] = DispBitMap->Planes[3] + 0x10000;
+#endif
+
+ readDiff(true);
+
+ return Mem;
+}
+
+
+
+
+/*---------------------------------------------------------------------------*/
+/*------------ Does all the text rendering to the message boxes. ------------*/
+/*---------------------------------------------------------------------------*/
+
+
+bool DoNotDrawMessage = false;
+
+extern bool LongWinInFront, Alternate;
+
+
+/*----- The flowText routines -----*/
+
+
+
+
+/******************************************************************************/
+/* Extracts the first word from a string. */
+/******************************************************************************/
+static void getWord(char *WordBuffer, const char *MainBuffer, uint16 *WordWidth) {
+ uint16 width = 0;
+
+ while ((MainBuffer[width] != ' ') && MainBuffer[width] &&
+ (MainBuffer[width] != '\n')) {
+ WordBuffer[width] = MainBuffer[width];
+ width++;
+ }
+
+ WordBuffer[width] = 0;
+
+ *WordWidth = width;
+}
+
+
+
+
+
+/******************************************************************************/
+/* Gets a line of text for flowText; makes sure that its length is less than */
+/* or equal to the maximum width. */
+/******************************************************************************/
+static void getLine(struct TextFont *tf, char *LineBuffer, const char **MainBuffer, uint16 LineWidth) {
+ uint16 CurWidth = 0, WordWidth;
+ char WordBuffer[100];
+ bool doit = true;
+
+ LineWidth += textLength(tf, " ", 1);
+
+ LineBuffer[0] = 0;
+
+ while ((*MainBuffer)[0] && doit) {
+ getWord(WordBuffer, *MainBuffer, &WordWidth);
+ strcat(WordBuffer, " ");
+
+ if ((CurWidth + textLength(tf, WordBuffer, WordWidth + 1)) <= LineWidth) {
+ strcat(LineBuffer, WordBuffer);
+ (*MainBuffer) += WordWidth;
+
+ if ((*MainBuffer)[0] == '\n')
+ doit = false;
+
+ if ((*MainBuffer)[0])
+ (*MainBuffer)++;
+
+ CurWidth = textLength(tf, LineBuffer, strlen(LineBuffer));
+ } else
+ doit = false;
+ }
+
+ /* NYI: Would add code here to break up words in case they were longer than a line */
+}
+
+
+
+
+/******************************************************************************/
+/* Dumps a chunk of text to an arbitrary box; flows it within that box and */
+/* optionally centers it. Returns the number of characters that were */
+/* processed. */
+/* */
+/* Note: Every individual word MUST be int16 enough to fit on a line, and */
+/* each line less than 255 characters. */
+/******************************************************************************/
+uint32 flowText(void *font, /* the TextAttr pointer */
+ uint16 spacing, /* How much vertical spacing between the lines */
+ uint16 pencolor, /* pen number to use for text */
+ uint16 backpen, /* the background color */
+ bool fillback, /* Whether to fill the background */
+ bool centerh, /* Whether to center the text horizontally */
+ bool centerv, /* Whether to center the text vertically */
+ bool output, /* Whether to output any text */
+ uint16 x1, /* Cords */
+ uint16 y1, uint16 x2, uint16 y2, const char *str) { /* The text itself */
+ struct TextFont *msgfont = (TextFont *)font;
+ char linebuffer[256];
+ const char *temp;
+ uint16 numlines, actlines, fontheight, width;
+ uint16 x, y;
+
+ if (fillback) {
+ setAPen(backpen);
+ rectFill(x1, y1, x2, y2);
+ }
+
+ if (str == NULL)
+ return 0L;
+
+ setAPen(pencolor);
+
+ fontheight = textHeight(msgfont) + spacing;
+ numlines = (y2 - y1 + 1) / fontheight;
+ width = x2 - x1 + 1;
+ y = y1;
+
+ if (centerv && output) {
+ temp = str;
+ actlines = 0;
+
+ while (temp[0]) {
+ getLine(msgfont, linebuffer, &temp, width);
+ actlines++;
+ }
+
+ if (actlines <= numlines)
+ y += ((y2 - y1 + 1) - (actlines * fontheight)) / 2;
+ }
+
+ temp = str;
+
+ while (numlines && str[0]) {
+ getLine(msgfont, linebuffer, &str, width);
+
+ x = x1;
+
+ if (centerh)
+ x += (width - textLength(msgfont, linebuffer, strlen(linebuffer))) / 2;
+
+ if (output)
+ text(msgfont, x, y, pencolor, linebuffer, strlen(linebuffer));
+
+ numlines--;
+ y += fontheight;
+ }
+
+ return (str - temp);
+}
+
+
+extern uint32 VGABASEADDRESS, VGABytesPerPage;
+
+
+/******************************************************************************/
+/* Calls flowText, but flows it to memory. Same restrictions as flowText. */
+/******************************************************************************/
+uint32 flowTextToMem(struct Image *DestIm, void *font, /* the TextAttr pointer */
+ uint16 spacing, /* How much vertical spacing between the lines */
+ uint16 pencolor, /* pen number to use for text */
+ uint16 backpen, /* the background color */
+ bool fillback, /* Whether to fill the background */
+ bool centerh, /* Whether to center the text horizontally */
+ bool centerv, /* Whether to center the text vertically */
+ bool output, /* Whether to output any text */
+ uint16 x1, /* Cords */
+ uint16 y1, uint16 x2, uint16 y2, const char *str) { /* The text itself */
+ uint32 res, vgabyte = VGABytesPerPage;
+
+ //VGABASEADDRESS = (uint32)(DestIm->ImageData);
+ VGABytesPerPage = (uint32) DestIm->Width * (int32) DestIm->Height;
+
+ res = flowText(font, spacing, pencolor, backpen, fillback, centerh, centerv, output, x1, y1, x2, y2, str);
+
+ VGABytesPerPage = vgabyte;
+
+ return res;
+}
+
+
+
+
+/*----- The control panel stuff -----*/
+
+
+
+void createBox(uint16 y2) {
+ setAPen(7); /* Message box area */
+ rectFill(VGAScaleX(4), VGAScaleY(154), VGAScaleX(315), VGAScaleY(y2 - 2));
+
+ setAPen(0); /* Box around message area */
+ drawHLine(VGAScaleX(2), VGAScaleY(152), VGAScaleX(317));
+ drawVLine(VGAScaleX(317), VGAScaleY(152), VGAScaleY(y2));
+ drawHLine(VGAScaleX(2), VGAScaleY(y2), VGAScaleX(317));
+ drawVLine(VGAScaleX(2), VGAScaleY(152), VGAScaleY(y2));
+}
+
+
+
+
+int32 longcharsdrawn = 0L;
+bool LastMessageLong = false;
+
+void longDrawMessage(const char *str) {
+ char NewText[512];
+
+ if (str == NULL)
+ return;
+
+ attachGadgetList(NULL);
+ mouseHide();
+ strcpy(NewText, str);
+
+ if (!LongWinInFront) {
+ LongWinInFront = true;
+ setAPen(3); /* Clear Area */
+ rectFill(0, VGAScaleY(149) + SVGACord(2), VGAScaleX(319), VGAScaleY(199));
+ }
+
+ createBox(198);
+ longcharsdrawn = flowText(MsgFont, 0, 1, 7, false, true, true, true, VGAScaleX(6), VGAScaleY(155), VGAScaleX(313), VGAScaleY(195), str);
+ mouseShow();
+}
+
+
+
+
+/******************************************************************************/
+/* Draws a message to the message box. */
+/******************************************************************************/
+void drawMessage(const char *str) {
+ if (DoNotDrawMessage) {
+ DoNotDrawMessage = false;
+ return;
+ }
+
+ if (str) {
+ if ((textLength(MsgFont, str, strlen(str)) > VGAScaleX(306))) {
+ longDrawMessage(str);
+ LastMessageLong = true;
+ } else {
+ if (LongWinInFront) {
+ LongWinInFront = false;
+ drawPanel();
+ }
+
+ mouseHide();
+ createBox(168);
+ text(MsgFont, VGAScaleX(7), VGAScaleY(155) + SVGACord(2), 1, str, strlen(str));
+ mouseShow();
+ LastMessageLong = false;
+ }
+ }
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*--------------------------- All the wipe stuff. ---------------------------*/
+/*---------------------------------------------------------------------------*/
+
+
+
+#define TRANSWIPE 1
+#define SCROLLWIPE 2
+#define SCROLLBLACK 3
+#define SCROLLBOUNCE 4
+#define TRANSPORTER 5
+#define READFIRSTFRAME 6
+#define READNEXTFRAME 7
+
+
+
+
+/*****************************************************************************/
+/* Copies memory from one location to another 64 bytes at a time. */
+/*****************************************************************************/
+void copyLong64(uint32 *Dest, uint32 *Source, uint32 Many64) {
+ while (Many64) {
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+ Dest++;
+ Source++;
+
+ Many64--;
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Scrolls the display to black. */
+/*****************************************************************************/
+static void doScrollBlack(void) {
+ byte *mem, *tempmem;
+ struct Image Im;
+ uint16 width, height, by, nheight, CurPage;
+ uint32 size, copysize;
+ uint32 *BaseAddr;
+
+ mouseHide();
+ width = VGAScaleX(320);
+ height = VGAScaleY(149) + SVGACord(2);
+
+ /*
+ while (EffectPlaying)
+ {
+ g_music->updateMusic();
+ waitTOF();
+ }
+ */
+
+ allocFile((void **) &mem, (int32) width * (int32) height, "Temp Mem");
+ /*
+ mem = stealBufMem((int32) width * (int32) height);
+ */
+ Im.Width = width;
+ Im.Height = height;
+ Im.ImageData = mem;
+ g_music->fillUpMusic(true);
+ readScreenImage(&Im, 0, 0);
+ g_music->fillUpMusic(true);
+
+ BaseAddr = (uint32 *) getVGABaseAddr();
+
+ by = VGAScaleX(4);
+ nheight = height;
+
+ while (nheight) {
+ g_music->newCheckMusic();
+
+ if (!IsHiRes)
+ waitTOF();
+
+#if !defined(DOSCODE)
+ BaseAddr = (uint32 *) getVGABaseAddr();
+#endif
+
+ if (by > nheight)
+ by = nheight;
+
+ mem += by * width;
+ nheight -= by;
+ size = (int32) nheight * (int32) width;
+ CurPage = 0;
+ tempmem = mem;
+
+ while (size) {
+ if (size > VGABytesPerPage)
+ copysize = VGABytesPerPage;
+ else
+ copysize = size;
+
+ size -= copysize;
+
+ setPage(CurPage);
+ copyLong64(BaseAddr, (uint32 *) tempmem, copysize >> 6);
+ tempmem += copysize;
+ CurPage++;
+ }
+
+ setAPen(0);
+ rectFill(0, nheight, width - 1, nheight + by - 1);
+
+ g_system->updateScreen();
+
+ if (!IsHiRes) {
+ if (nheight <= (height / 8))
+ by = 1;
+ else if (nheight <= (height / 4))
+ by = 2;
+ else if (nheight <= (height / 2))
+ by = 3;
+ }
+ }
+
+ freeAllStolenMem();
+ mouseShow();
+
+#if !defined(DOSCODE)
+ ungetVGABaseAddr();
+#endif
+}
+
+
+
+
+extern struct BitMap RawDiffBM;
+extern DIFFHeader headerdata;
+
+
+
+
+static void copyPage(uint16 width, uint16 height, uint16 nheight, uint16 startline, byte *mem) {
+ uint32 size, OffSet, copysize;
+ uint16 CurPage;
+ uint32 *BaseAddr;
+
+ BaseAddr = (uint32 *) getVGABaseAddr();
+
+ size = (int32)(height - nheight) * (int32) width;
+ mem += startline * width;
+ CurPage = ((int32) nheight * (int32) width) / VGABytesPerPage;
+ OffSet = ((int32) nheight * (int32) width) - (CurPage * VGABytesPerPage);
+
+ while (size) {
+ if (size > (VGABytesPerPage - OffSet))
+ copysize = VGABytesPerPage - OffSet;
+ else
+ copysize = size;
+
+ size -= copysize;
+
+ setPage(CurPage);
+ copyLong64(BaseAddr + (OffSet >> 2), (uint32 *) mem, copysize >> 6);
+ mem += copysize;
+ CurPage++;
+ OffSet = 0;
+ }
+
+#if !defined(DOSCODE)
+ ungetVGABaseAddr();
+#endif
+}
+
+
+/*****************************************************************************/
+/* Scrolls the display to a new picture from a black screen. */
+/*****************************************************************************/
+static void doScrollWipe(char *filename) {
+ byte *mem;
+ uint16 width, height, by, nheight, startline = 0, onrow = 0;
+
+ mouseHide();
+ width = VGAScaleX(320);
+ height = VGAScaleY(149) + SVGACord(2);
+
+ while (EffectPlaying) {
+ g_music->newCheckMusic();
+ waitTOF();
+ }
+
+ IsBM = true;
+ readPict(filename, true);
+ VGASetPal(diffcmap, 256);
+ IsBM = false;
+ mem = RawDiffBM.Planes[0];
+
+ g_music->fillUpMusic(true);
+ by = VGAScaleX(3);
+ nheight = height;
+
+ while (onrow < headerdata.y) {
+ g_music->newCheckMusic();
+
+ if ((by > nheight) && nheight)
+ by = nheight;
+
+ if ((startline + by) > (headerdata.y - height - 1))
+ break;
+
+ if (nheight)
+ nheight -= by;
+
+ copyPage(width, height, nheight, startline, mem);
+
+ g_system->updateScreen();
+
+ if (!nheight)
+ startline += by;
+
+ onrow += by;
+
+ if (nheight <= (height / 4))
+ by = VGAScaleX(5);
+ else if (nheight <= (height / 3))
+ by = VGAScaleX(4);
+ else if (nheight <= (height / 2))
+ by = VGAScaleX(3);
+ }
+
+ mouseShow();
+}
+
+
+
+
+/*****************************************************************************/
+/* Does the scroll bounce. Assumes bitmap already in memory. */
+/*****************************************************************************/
+static void doScrollBounce(void) {
+ byte *mem;
+ uint16 width, height, startline, counter,
+#if defined(DOSCODE)
+ newby[5] = {5, 4, 3, 2, 1}, newby1[8] = {3, 3, 2, 2, 2, 1, 1, 1};
+#else
+ newby[5] = {10, 8, 6, 4, 2}, newby1[8] = {6, 6, 4, 4, 4, 2, 2, 2};
+#endif
+
+ mouseHide();
+ width = VGAScaleX(320);
+ height = VGAScaleY(149) + SVGACord(2);
+ mem = RawDiffBM.Planes[0];
+
+ g_music->fillUpMusic(true);
+ startline = headerdata.y - height - 1;
+
+ for (counter = 0; counter < 5; counter++) {
+ g_music->newCheckMusic();
+ startline -= newby[counter];
+ copyPage(width, height, 0, startline, mem);
+
+ g_system->updateScreen();
+ waitTOF();
+ }
+
+ for (counter = 8; counter > 0; counter--) {
+ g_music->newCheckMusic();
+ startline += newby1[counter - 1];
+ copyPage(width, height, 0, startline, mem);
+
+ g_system->updateScreen();
+ waitTOF();
+
+ }
+
+ mouseShow();
+}
+
+
+
+/*****************************************************************************/
+/* Does the transporter wipe. */
+/*****************************************************************************/
+static void doTransWipe(CloseDataPtr *CPtr, char *filename) {
+ uint16 LastY, CurY, counter, linesdone = 0, lineslast;
+ struct Image ImSource, ImDest;
+
+ if (IsHiRes) {
+ lineslast = 3;
+ LastY = 358;
+ } else {
+ lineslast = 1;
+ LastY = 148;
+ }
+
+ for (counter = 0; counter < 2; counter++) {
+ CurY = counter * 2;
+
+ while (CurY < LastY) {
+ if (linesdone >= lineslast) {
+ g_music->updateMusic();
+ waitTOF();
+ linesdone = 0;
+ }
+
+ ghoastRect(0, 0, CurY, VGAScreenWidth - 1, CurY + 1);
+ CurY += 4;
+ linesdone++;
+ }
+ }
+
+ setAPen(0);
+
+ for (counter = 0; counter < 2; counter++) {
+ CurY = counter * 2;
+
+ while (CurY <= LastY) {
+ if (linesdone >= lineslast) {
+ g_music->updateMusic();
+ waitTOF();
+ linesdone = 0;
+ }
+
+ rectFill(0, CurY, VGAScreenWidth - 1, CurY + 1);
+ CurY += 4;
+ linesdone++;
+ }
+ }
+
+ if (filename == NULL)
+ CurFileName = getPictName(CPtr);
+ else if (filename[0] > ' ')
+ CurFileName = filename;
+ else
+ CurFileName = getPictName(CPtr);
+
+ byte *BitMapMem = readPictToMem(CurFileName, VGAScreenWidth, LastY + 5);
+ VGASetPal(diffcmap, 256);
+
+ if (BitMapMem) {
+ ImSource.Width = VGAScreenWidth;
+ ImSource.Height = LastY;
+ ImSource.ImageData = BitMapMem;
+
+ ImDest.Width = VGAScreenWidth;
+ ImDest.Height = VGAScreenHeight;
+ ImDest.ImageData = getVGABaseAddr();
+
+ for (counter = 0; counter < 2; counter++) {
+ CurY = counter * 2;
+
+ while (CurY < LastY) {
+ if (linesdone >= lineslast) {
+ g_music->updateMusic();
+ waitTOF();
+ linesdone = 0;
+ }
+
+#if !defined(DOSCODE)
+ ImDest.ImageData = getVGABaseAddr();
+#endif
+
+ bltBitMap(&ImSource, 0, CurY, &ImDest, 0, CurY, VGAScreenWidth, 2);
+ ghoastRect(0, 0, CurY, VGAScreenWidth - 1, CurY + 1);
+ CurY += 4;
+ linesdone++;
+ }
+ }
+
+ for (counter = 0; counter < 2; counter++) {
+ CurY = counter * 2;
+
+ while (CurY <= LastY) {
+ if (linesdone >= lineslast) {
+ g_music->updateMusic();
+ waitTOF();
+ linesdone = 0;
+ }
+
+#if !defined(DOSCODE)
+ ImDest.ImageData = getVGABaseAddr();
+#endif
+
+ if (CurY == LastY)
+ bltBitMap(&ImSource, 0, CurY, &ImDest, 0, CurY, VGAScreenWidth, 1);
+ else
+ bltBitMap(&ImSource, 0, CurY, &ImDest, 0, CurY, VGAScreenWidth, 2);
+
+ CurY += 4;
+ linesdone++;
+ }
+ }
+ }
+
+#if !defined(DOSCODE)
+ ungetVGABaseAddr();
+#endif
+}
+
+
+
+/*****************************************************************************/
+/* Does a certain number of pre-programmed wipes. */
+/*****************************************************************************/
+void doWipe(uint16 WipeType, CloseDataPtr *CPtr, char *filename) {
+ if ((WipeType == TRANSWIPE) || (WipeType == TRANSPORTER))
+ doTransWipe(CPtr, filename);
+ else if (WipeType == SCROLLWIPE)
+ doScrollWipe(filename);
+ else if (WipeType == SCROLLBLACK)
+ doScrollBlack();
+ else if (WipeType == SCROLLBOUNCE)
+ doScrollBounce();
+ else if (WipeType == READFIRSTFRAME)
+ readPict(filename, false);
+ else if (WipeType == READNEXTFRAME)
+ diffNextFrame();
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/interface.cpp b/engines/lab/interface.cpp
new file mode 100644
index 0000000000..91111ae949
--- /dev/null
+++ b/engines/lab/interface.cpp
@@ -0,0 +1,234 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/interface.h"
+#include "lab/storage.h"
+#include "lab/timing.h"
+#include "lab/mouse.h"
+#include "lab/vga.h"
+#include "common/util.h"
+
+namespace Lab {
+
+extern bool IsHiRes;
+
+Common::KeyState _keyPressed;
+
+struct Gadget *createButton(uint16 x, uint16 y, uint16 id, uint16 key, Image *im, Image *imalt) {
+ Gadget *gptr;
+
+ if (allocate((void **)&gptr, sizeof(struct Gadget))) {
+ gptr->x = x;
+ gptr->y = y;
+ gptr->GadgetID = id;
+#if !defined(DOSCODE)
+ gptr->KeyEquiv = key;
+#endif
+ gptr->Im = im;
+ gptr->ImAlt = imalt;
+ gptr->NextGadget = NULL;
+
+ return gptr;
+ } else
+ return NULL;
+}
+
+
+
+
+void freeButtonList(Gadget *gptrlist) {
+ struct Gadget *gptr, *next = gptrlist;
+
+ while (next) {
+ gptr = next;
+ next = next->NextGadget;
+
+ deallocate(gptr, sizeof(struct Gadget));
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Draws a gadget list to the screen. */
+/*****************************************************************************/
+void drawGadgetList(struct Gadget *gadlist) {
+ while (gadlist) {
+ drawImage(gadlist->Im, gadlist->x, gadlist->y);
+
+ if (GADGETOFF & gadlist->GadgetFlags)
+ ghoastGadget(gadlist, 1);
+
+ gadlist = gadlist->NextGadget;
+ }
+}
+
+
+/*****************************************************************************/
+/* Ghoasts a gadget, and makes it unavailable for using. */
+/*****************************************************************************/
+void ghoastGadget(struct Gadget *curgad, uint16 pencolor) {
+ ghoastRect(pencolor, curgad->x, curgad->y, curgad->x + curgad->Im->Width - 1, curgad->y + curgad->Im->Height - 1);
+ curgad->GadgetFlags |= GADGETOFF;
+}
+
+
+
+/*****************************************************************************/
+/* Unghoasts a gadget, and makes it available again. */
+/*****************************************************************************/
+void unGhoastGadget(struct Gadget *curgad) {
+ drawImage(curgad->Im, curgad->x, curgad->y);
+ curgad->GadgetFlags &= !(GADGETOFF);
+}
+
+
+/*****************************************************************************/
+/* Make a key press have the right case for a gadget KeyEquiv value. */
+/*****************************************************************************/
+#if !defined(DOSCODE)
+uint16 makeGadgetKeyEquiv(uint16 key) {
+ if (Common::isAlnum(key))
+ key = tolower(key);
+
+ return key;
+}
+#endif
+
+/*****************************************************************************/
+/* Checks whether or not the cords fall within one of the gadgets in a list */
+/* of gadgets. */
+/*****************************************************************************/
+static struct Gadget *checkNumGadgetHit(struct Gadget *gadlist, uint16 key) {
+#if !defined(DOSCODE)
+ uint16 gkey = key - '0';
+#else
+ key = key - '0';
+#endif
+
+ while (gadlist != NULL) {
+#if !defined(DOSCODE)
+
+ if ((gkey - 1 == gadlist->GadgetID || (gkey == 0 && gadlist->GadgetID == 9) ||
+ (gadlist->KeyEquiv != 0 && makeGadgetKeyEquiv(key) == gadlist->KeyEquiv))
+ && !(GADGETOFF & gadlist->GadgetFlags))
+#else
+ if ((((key - 1) == gadlist->GadgetID) || ((key == 0) && (gadlist->GadgetID == 9))) &&
+ !(GADGETOFF & gadlist->GadgetFlags))
+#endif
+ {
+ mouseHide();
+ drawImage(gadlist->ImAlt, gadlist->x, gadlist->y);
+ mouseShow();
+ g_system->delayMillis(80);
+ mouseHide();
+ drawImage(gadlist->Im, gadlist->x, gadlist->y);
+ mouseShow();
+
+ return gadlist;
+ } else {
+ gadlist = gadlist->NextGadget;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+/*****************************************************************************/
+/* Checks whether or not a key has been pressed. */
+/*****************************************************************************/
+static bool keyPress(uint16 *KeyCode) {
+ if (_keyPressed.keycode) {
+ *KeyCode = _keyPressed.keycode;
+ return true;
+ }
+
+ return false;
+}
+
+
+struct IntuiMessage IMessage;
+extern struct Gadget *ScreenGadgetList;
+
+struct IntuiMessage *getMsg(void) {
+ struct Gadget *curgad;
+ int Qualifiers;
+
+ updateMouse();
+#if !defined(DOSCODE)
+ Qualifiers = _keyPressed.flags;
+#endif
+
+ if ((curgad = mouseGadget()) != NULL) {
+ updateMouse();
+ IMessage.Class = GADGETUP;
+ IMessage.Code = curgad->GadgetID;
+ IMessage.GadgetID = curgad->GadgetID;
+ IMessage.Qualifier = Qualifiers;
+ return &IMessage;
+ }
+
+ else if (mouseButton(&IMessage.MouseX, &IMessage.MouseY, true)) { /* Left Button */
+ IMessage.Qualifier = IEQUALIFIER_LEFTBUTTON | Qualifiers;
+ IMessage.Class = MOUSEBUTTONS;
+ return &IMessage;
+ }
+
+ else if (mouseButton(&IMessage.MouseX, &IMessage.MouseY, false)) { /* Right Button */
+ IMessage.Qualifier = IEQUALIFIER_RBUTTON | Qualifiers;
+ IMessage.Class = MOUSEBUTTONS;
+ return &IMessage;
+ }
+
+ else if (keyPress(&IMessage.Code)) { /* Keyboard key */
+ curgad = checkNumGadgetHit(ScreenGadgetList, IMessage.Code);
+
+ if (curgad) {
+ IMessage.Class = GADGETUP;
+ IMessage.Code = curgad->GadgetID;
+ IMessage.GadgetID = curgad->GadgetID;
+ } else
+ IMessage.Class = RAWKEY;
+
+ IMessage.Qualifier = Qualifiers;
+ return &IMessage;
+ } else
+ return NULL;
+}
+
+void replyMsg(void *Msg) {
+ return;
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/interface.h b/engines/lab/interface.h
new file mode 100644
index 0000000000..cb0115daf9
--- /dev/null
+++ b/engines/lab/interface.h
@@ -0,0 +1,143 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/vga.h"
+#include "common/keyboard.h"
+
+#ifndef LAB_INTEFACE_H
+#define LAB_INTEFACE_H
+
+namespace Lab {
+
+struct IntuiMessage {
+ uint32 Class;
+ uint16 Code, Qualifier, MouseX, MouseY, GadgetID;
+ uint32 Seconds, Micros;
+};
+
+
+struct Gadget {
+ uint16 x, y, GadgetID;
+#if !defined(DOSCODE)
+ uint16 KeyEquiv; // if not zero, a key that activates gadget
+#endif
+ uint32 GadgetFlags;
+ struct Image *Im, *ImAlt;
+ struct Gadget *NextGadget;
+};
+
+extern Common::KeyState _keyPressed;
+
+/* Defines for the GadgetFlags portion */
+
+#define GADGETOFF 0x01
+
+
+
+/* Defines for the Class variable in IntuiMessage */
+#define SIZEVERIFY 0x00000001
+#define NEWSIZE 0x00000002
+#define REFRESHWINDOW 0x00000004
+#define MOUSEBUTTONS 0x00000008
+#define MOUSEMOVE 0x00000010
+#define GADGETDOWN 0x00000020
+#define GADGETUP 0x00000040
+#define REQSET 0x00000080
+#define MENUPICK 0x00000100
+#define CLOSEWINDOW 0x00000200
+#define RAWKEY 0x00000400
+#define REQVERIFY 0x00000800
+#define REQCLEAR 0x00001000
+#define MENUVERIFY 0x00002000
+#define NEWPREFS 0x00004000
+#define DISKINSERTED 0x00008000
+#define DISKREMOVED 0x00010000
+#define WBENCHMESSAGE 0x00020000 /* System use only */
+#define ACTIVEWINDOW 0x00040000
+#define INACTIVEWINDOW 0x00080000
+#define DELTAMOVE 0x00100000
+#define VANULLLAKEY 0x00200000
+
+
+/* Defines for the Qualifier variable in IntuiMessage */
+#define IEQUALIFIER_LSHIFT 0x0001
+#define IEQUALIFIER_RSHIFT 0x0002
+#define IEQUALIFIER_CAPSLOCK 0x0004
+#define IEQUALIFIER_CONTROL 0x0008
+#define IEQUALIFIER_LALT 0x0010
+#define IEQUALIFIER_RALT 0x0020
+#define IEQUALIFIER_LCOMMAND 0x0040
+#define IEQUALIFIER_RCOMMAND 0x0080
+#define IEQUALIFIER_NUMERICPAD 0x0100
+#define IEQUALIFIER_REPEAT 0x0200
+#define IEQUALIFIER_INTERRUPT 0x0400
+#define IEQUALIFIER_MULTIBROADCAST 0x0800
+#define IEQUALIFIER_MIDBUTTON 0x1000
+#define IEQUALIFIER_RBUTTON 0x2000
+#define IEQUALIFIER_LEFTBUTTON 0x4000
+
+#if !defined(DOSCODE)
+// these values come from the SDL virtual key table
+#define VKEY_UPARROW 273
+#define VKEY_DNARROW 274
+#define VKEY_RTARROW 275
+#define VKEY_LTARROW 276
+#endif
+
+
+/*---------------------------------------------------------------------------*/
+/*--------------------------- Function Prototypes ---------------------------*/
+/*---------------------------------------------------------------------------*/
+
+
+
+
+struct Gadget *createButton(uint16 x, uint16 y, uint16 id,
+#if !defined(DOSCODE)
+ uint16 key,
+#endif
+ struct Image *im, struct Image *imalt);
+
+void freeButtonList(void *gptrlist);
+
+void drawGadgetList(struct Gadget *gadlist);
+
+void ghoastGadget(struct Gadget *curgad, uint16 pencolor);
+
+void unGhoastGadget(struct Gadget *curgad);
+
+struct IntuiMessage *getMsg(void);
+
+void replyMsg(void *Msg);
+
+} // End of namespace Lab
+
+#endif /* LAB_INTEFACE_H */
+
diff --git a/engines/lab/intro.cpp b/engines/lab/intro.cpp
new file mode 100644
index 0000000000..ae822cb72c
--- /dev/null
+++ b/engines/lab/intro.cpp
@@ -0,0 +1,470 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/labfun.h"
+#include "lab/timing.h"
+#include "lab/diff.h"
+#include "lab/text.h"
+#include "lab/interface.h"
+
+namespace Lab {
+
+static struct TextFont filler, *msgfont = &filler;
+
+extern bool nopalchange, noscreenchange, hidemouse, DoBlack, NoFlip, IsHiRes;
+
+extern char diffcmap[256 * 3];
+
+extern uint32 VGAScreenWidth, VGAScreenHeight;
+
+
+extern uint16 *FadePalette;
+
+static uint16 Palette[16] = {
+ 0x0000, 0x0855, 0x0FF9, 0x0EE7, 0x0ED5, 0x0DB4, 0x0CA2, 0x0C91, 0x0B80, 0x0B80, 0x0B91, 0x0CA2, 0x0CB3, 0x0DC4, 0x0DD6, 0x0EE7
+};
+
+
+static bool QuitIntro = false, IntroDoBlack;
+extern int32 longcharsdrawn;
+
+
+
+/******************************************************************************/
+/* Goes thru, and responds to all the intuition messages currently in the */
+/* the message port. */
+/******************************************************************************/
+void introEatMessages(void) {
+ struct IntuiMessage *Msg;
+
+ while (1) {
+ Msg = getMsg();
+
+ if (Msg == NULL)
+ return;
+ else {
+ if (((Msg->Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Msg->Qualifier)) ||
+ ((Msg->Class == RAWKEY) && (Msg->Code == 27)))
+ QuitIntro = true;
+
+ replyMsg(Msg);
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads in a picture. */
+/*****************************************************************************/
+static void doPictText(const char *Filename, bool isscreen) {
+ uint32 lastsecs = 0L, lastmicros = 0L, secs = 0L, micros = 0L;
+ struct IntuiMessage *Msg;
+ char filename[50] = "Lab:rooms/Intro/";
+ byte *curplace, **tfile;
+ bool DrawNextText = true, End = false, Begin = true;
+
+ int32 Class, Code, Drawn;
+ int16 Qualifier;
+ uint timedelay;
+
+ strcat(filename, Filename);
+
+ if (isscreen) {
+ g_music->fillUpMusic(true);
+ timedelay = 35;
+ } else {
+ g_music->newCheckMusic();
+ timedelay = 7;
+ }
+
+ if (QuitIntro)
+ return;
+
+ while (1) {
+ if (DrawNextText) {
+ if (Begin) {
+ Begin = false;
+
+ tfile = g_music->newOpen(filename);
+
+ if (!tfile)
+ return;
+
+ curplace = *tfile;
+ } else if (isscreen)
+ fade(false, 0);
+
+ if (isscreen) {
+ setAPen(7L);
+ rectFill(VGAScaleX(10), VGAScaleY(10), VGAScaleX(310), VGAScaleY(190));
+
+ Drawn = flowText(msgfont, (!IsHiRes) * -1, 5, 7, false, false, true, true, VGAScaleX(14), VGAScaleY(11), VGAScaleX(306), VGAScaleY(189), (char *)curplace);
+ fade(true, 0);
+ } else {
+ longDrawMessage((char *)curplace);
+ Drawn = longcharsdrawn;
+ }
+
+ curplace += Drawn;
+
+ End = (*curplace == 0);
+
+ DrawNextText = false;
+ introEatMessages();
+
+ if (QuitIntro) {
+ if (isscreen)
+ fade(false, 0);
+
+ return;
+ }
+
+ getTime(&lastsecs, &lastmicros);
+ }
+
+ Msg = getMsg();
+
+ if (Msg == NULL) {
+ g_music->newCheckMusic();
+ diffNextFrame();
+
+ getTime(&secs, &micros);
+ anyTimeDiff(lastsecs, lastmicros, secs, micros, &secs, &micros);
+
+ if (secs > timedelay) {
+ if (End) {
+ if (isscreen)
+ fade(false, 0);
+
+ return;
+ } else {
+ DrawNextText = true;
+ }
+ }
+
+ waitTOF();
+ } else {
+ Class = Msg->Class;
+ Qualifier = Msg->Qualifier;
+ Code = Msg->Code;
+ replyMsg(Msg);
+
+ if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
+ ((Class == RAWKEY) && (Code == 27))) {
+ QuitIntro = true;
+
+ if (isscreen)
+ fade(false, 0);
+
+ return;
+ }
+
+ else if (Class == MOUSEBUTTONS) {
+ if (IEQUALIFIER_LEFTBUTTON & Qualifier) {
+ if (End) {
+ if (isscreen)
+ fade(false, 0);
+
+ return;
+ } else
+ DrawNextText = true;
+ }
+
+ introEatMessages();
+
+ if (QuitIntro) {
+ if (isscreen)
+ fade(false, 0);
+
+ return;
+ }
+ }
+
+ if (End) {
+ if (isscreen)
+ fade(false, 0);
+
+ return;
+ } else
+ DrawNextText = true;
+ }
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Does a one second delay, but checks the music while doing it. */
+/*****************************************************************************/
+void musicDelay(void) {
+ int16 counter;
+
+ g_music->newCheckMusic();
+
+ if (QuitIntro)
+ return;
+
+ for (counter = 0; counter < 20; counter++) {
+ g_music->newCheckMusic();
+ waitTOF();
+ waitTOF();
+ waitTOF();
+ }
+}
+
+
+
+static void NReadPict(const char *Filename, bool PlayOnce) {
+ char filename[20] = "P:Intro/";
+
+ g_music->newCheckMusic();
+
+ if (QuitIntro)
+ return;
+
+ strcat(filename, Filename);
+
+ DoBlack = IntroDoBlack;
+ stopDiffEnd();
+ readPict(filename, PlayOnce);
+}
+
+
+//#define ALL_LOGOS
+
+/*****************************************************************************/
+/* Does the introduction sequence for Labyrinth. */
+/*****************************************************************************/
+void introSequence(void) {
+ uint16 counter, counter1;
+
+ DoBlack = true;
+
+#if defined(DOSCODE)
+ readPict("p:Intro/EA0", true);
+ readPict("p:Intro/EA1", true);
+ readPict("p:Intro/EA2", true);
+ readPict("p:Intro/EA3", true);
+#elif defined(ALL_LOGOS) || defined(NDEBUG)
+ readPict("p:Intro/WYRMKEEP", true);
+ microDelay(4, 0, NULL);
+#endif
+ blackAllScreen();
+
+ g_music->initMusic();
+
+ nopalchange = true;
+ noscreenchange = true;
+ readPict("p:Intro/TNDcycle2.pic", true);
+ nopalchange = false;
+ noscreenchange = false;
+
+ FadePalette = Palette;
+#if defined(ALL_LOGOS) || defined(NDEBUG)
+
+ for (counter = 0; counter < 16; counter++) {
+ Palette[counter] = ((diffcmap[counter * 3] >> 2) << 8) +
+ ((diffcmap[counter * 3 + 1] >> 2) << 4) +
+ (diffcmap[counter * 3 + 2] >> 2);
+ }
+
+ newCheckMusic();
+ fade(true, 0);
+
+ for (int times = 0; times < 150; times++) {
+ newCheckMusic();
+ uint16 temp = Palette[2];
+
+ for (counter = 2; counter < 15; counter++)
+ Palette[counter] = Palette[counter + 1];
+
+ Palette[15] = temp;
+
+ setAmigaPal(Palette, 16);
+ waitTOF();
+ }
+
+ fade(false, 0);
+ blackAllScreen();
+#endif
+ g_music->newCheckMusic();
+
+ readPict("p:Intro/Title.A", true);
+ readPict("p:Intro/AB", true);
+ musicDelay();
+ readPict("p:Intro/BA", true);
+ readPict("p:Intro/AC", true);
+ musicDelay();
+#if !defined(DOSCODE)
+ musicDelay(); // more credits on this page now
+#endif
+ readPict("p:Intro/CA", true);
+ readPict("p:Intro/AD", true);
+ musicDelay();
+#if !defined(DOSCODE)
+ musicDelay(); // more credits on this page now
+#endif
+ readPict("p:Intro/DA", true);
+ musicDelay();
+
+ g_music->newOpen("p:Intro/Intro.1"); /* load the picture into the buffer */
+
+ g_music->newCheckMusic();
+ blackAllScreen();
+ g_music->fillUpMusic(true);
+
+ getFont("P:Map.font", msgfont);
+
+ nopalchange = true;
+ noscreenchange = true;
+ readPict("p:Intro/Intro.1", true);
+ noscreenchange = false;
+ nopalchange = false;
+
+ for (counter = 0; counter < 16; counter++) {
+ Palette[counter] = ((diffcmap[counter * 3] >> 2) << 8) +
+ ((diffcmap[counter * 3 + 1] >> 2) << 4) +
+ (diffcmap[counter * 3 + 2] >> 2);
+ }
+
+ doPictText("i.1", true);
+ doPictText("i.2A", true);
+ doPictText("i.2B", true);
+
+ freeAllStolenMem();
+
+ blackAllScreen();
+ g_music->fillUpMusic(true);
+
+ IntroDoBlack = true;
+ NReadPict("Station1", true);
+ doPictText("i.3", false);
+
+ NReadPict("Station2", true);
+ doPictText("i.4", false);
+
+ NReadPict("Stiles4", true);
+ doPictText("i.5", false);
+
+ NReadPict("Stiles3", true);
+ doPictText("i.6", false);
+
+ NReadPict("Platform2", true);
+ doPictText("i.7", false);
+
+ NReadPict("Subway.1", true);
+ doPictText("i.8", false);
+
+ NReadPict("Subway.2", true);
+
+ doPictText("i.9", false);
+ doPictText("i.10", false);
+ doPictText("i.11", false);
+
+ if (!QuitIntro)
+ for (counter = 0; counter < 50; counter++) {
+ for (counter1 = (8 * 3); counter1 < (255 * 3); counter1++)
+ diffcmap[counter1] = 255 - diffcmap[counter1];
+
+ g_music->newCheckMusic();
+ waitTOF();
+ VGASetPal(diffcmap, 256);
+ waitTOF();
+ waitTOF();
+ }
+
+ doPictText("i.12", false);
+ doPictText("i.13", false);
+
+ IntroDoBlack = false;
+ NReadPict("Daed0", true);
+ doPictText("i.14", false);
+
+ NReadPict("Daed1", true);
+ doPictText("i.15", false);
+
+ NReadPict("Daed2", true);
+ doPictText("i.16", false);
+ doPictText("i.17", false);
+ doPictText("i.18", false);
+
+ NReadPict("Daed3", true);
+ doPictText("i.19", false);
+ doPictText("i.20", false);
+
+ NReadPict("Daed4", true);
+ doPictText("i.21", false);
+
+ NReadPict("Daed5", true);
+ doPictText("i.22", false);
+ doPictText("i.23", false);
+ doPictText("i.24", false);
+
+ NReadPict("Daed6", true);
+ doPictText("i.25", false);
+ doPictText("i.26", false);
+
+ NReadPict("Daed7", false);
+ doPictText("i.27", false);
+ doPictText("i.28", false);
+ stopDiffEnd();
+
+ NReadPict("Daed8", true);
+ doPictText("i.29", false);
+ doPictText("i.30", false);
+
+ NReadPict("Daed9", true);
+ doPictText("i.31", false);
+ doPictText("i.32", false);
+ doPictText("i.33", false);
+
+ NReadPict("Daed9a", true);
+ NReadPict("Daed10", true);
+ doPictText("i.34", false);
+ doPictText("i.35", false);
+ doPictText("i.36", false);
+
+ NReadPict("SubX", true);
+
+ if (QuitIntro) {
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, VGAScreenHeight - 1);
+ DoBlack = true;
+ }
+
+ hidemouse = false;
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/lab.cpp b/engines/lab/lab.cpp
new file mode 100644
index 0000000000..edde50bb5d
--- /dev/null
+++ b/engines/lab/lab.cpp
@@ -0,0 +1,68 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+ /*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "common/debug-channels.h"
+#include "common/scummsys.h"
+#include "common/error.h"
+#include "common/fs.h"
+#include "common/rect.h"
+
+#include "engines/util.h"
+
+#include "lab/lab.h"
+#include "lab/labfun.h"
+
+namespace Lab {
+
+bool LabEngine::hasFeature(EngineFeature f) const {
+ return (f == kSupportsRTL) ? true : false;
+}
+
+LabEngine::LabEngine(OSystem *syst)
+ : Engine(syst) {
+}
+
+LabEngine::~LabEngine() {
+ // Remove all of our debug levels here
+ DebugMan.clearAllDebugChannels();
+}
+
+Common::Error LabEngine::run() {
+ // Initialize graphics using following:
+ initGraphics(320, 200, false);
+
+ g_music = new Music();
+
+ inner_main();
+
+ return Common::kNoError;
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/lab.h b/engines/lab/lab.h
new file mode 100644
index 0000000000..3b1e411e7c
--- /dev/null
+++ b/engines/lab/lab.h
@@ -0,0 +1,52 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+ /*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#ifndef LAB_H
+#define LAB_H
+
+#include "common/array.h"
+
+#include "engines/engine.h"
+
+namespace Lab {
+
+class LabEngine : public Engine {
+public:
+ LabEngine(OSystem *syst);
+ ~LabEngine();
+
+ virtual Common::Error run();
+
+ bool hasFeature(EngineFeature f) const;
+};
+
+} // End of namespace Lab
+
+#endif // LAB_H
diff --git a/engines/lab/labfile.cpp b/engines/lab/labfile.cpp
new file mode 100644
index 0000000000..90db66fcbb
--- /dev/null
+++ b/engines/lab/labfile.cpp
@@ -0,0 +1,549 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/labfun.h"
+#include "lab/mouse.h"
+#include "lab/storage.h"
+#include "common/file.h"
+
+namespace Lab {
+
+#define MAXREADSIZE 30720L
+#define DMABUGSIZE 0 /* The number of bytes the DMA driver might screw */
+/* NOTE: set to 0 for non-CDTV machines. */
+
+
+
+static byte *buffer = NULL, *realbufferstart = NULL, *startoffilestorage = NULL;
+
+byte **startoffile = &startoffilestorage;
+static uint32 buffersize, realbuffersize;
+
+uint32 ReadSoFar;
+bool ReadIsError, ReadIsDone;
+
+
+#if defined(WIN32)
+#define stat _stat
+#endif
+
+/*****************************************************************************/
+/* Returns the size of a file. */
+/*****************************************************************************/
+uint32 sizeOfFile(const char *name) {
+ Common::File file;
+
+ file.open(translateFileName(name));
+ if (!file.isOpen()) {
+ warning("Cannot open file %s", translateFileName(name));
+
+ return 0;
+ }
+ uint32 size = file.size();
+ file.close();
+
+ return size;
+}
+
+
+
+
+/*-------------------- Routines that buffer a whole file --------------------*/
+
+
+
+/*----- divides up and manages the buffer -----*/
+
+
+
+#define MAXMARKERS 15
+
+
+
+typedef struct {
+ char name[32];
+ void *Start, *End;
+} FileMarker;
+
+
+
+static FileMarker FileMarkers[MAXMARKERS];
+static uint16 CurMarker = 0;
+static void *MemPlace = NULL;
+
+
+
+
+
+/*****************************************************************************/
+/* Frees a File's resources. */
+/*****************************************************************************/
+static void freeFile(uint16 RMarker) {
+ FileMarkers[RMarker].name[0] = 0;
+ FileMarkers[RMarker].Start = NULL;
+ FileMarkers[RMarker].End = NULL;
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Gets a chunk of memory from the buffer. */
+/*****************************************************************************/
+static void *getCurMem(uint32 size) {
+ void *ptr = 0;
+
+ warning ("STUB: getCurMem(%d)", size);
+
+#if 0
+ if ((((char *) MemPlace) + size - 1) >=
+ (((char *) buffer) + buffersize))
+ MemPlace = buffer;
+
+ ptr = MemPlace;
+ ((char *)MemPlace) += size;
+
+ for (int counter = 0; counter < MAXMARKERS; counter++) {
+ if (FileMarkers[counter].name[0]) {
+ if (((FileMarkers[counter].Start >= ptr) &&
+ (FileMarkers[counter].Start < MemPlace)) ||
+ ((FileMarkers[counter].End >= ptr) &&
+ (FileMarkers[counter].End < MemPlace)) ||
+ ((ptr >= FileMarkers[counter].Start) &&
+ (ptr <= FileMarkers[counter].End)))
+
+ freeFile(counter);
+ }
+ }
+#endif
+ return ptr;
+}
+
+
+
+
+/*****************************************************************************/
+/* Checks if a file is already buffered. */
+/*****************************************************************************/
+byte **isBuffered(const char *fileName) {
+ uint16 RMarker;
+
+ if (fileName == NULL)
+ return NULL;
+
+ RMarker = 0;
+
+ while (RMarker < MAXMARKERS) {
+ if (strcmp(FileMarkers[RMarker].name, fileName) == 0) {
+ *startoffile = (byte *) FileMarkers[RMarker].Start;
+ return startoffile;
+ } else
+ RMarker++;
+ }
+
+ return NULL;
+}
+
+
+
+
+/*****************************************************************************/
+/* Grabs a chunk of memory from the room buffer, and manages it for a */
+/* particular room. If it returns true, then the file is already in memory. */
+/*****************************************************************************/
+bool allocFile(void **Ptr, uint32 Size, const char *fileName) {
+ uint16 RMarker;
+ byte **temp;
+
+ Size += DMABUGSIZE;
+
+ if (1 & Size) /* Memory is required to be even aligned */
+ Size++;
+
+ temp = isBuffered(fileName);
+
+ if (temp) {
+ *Ptr = *temp;
+ return true;
+ }
+
+ RMarker = CurMarker;
+ CurMarker++;
+
+ if (CurMarker >= MAXMARKERS)
+ CurMarker = 0;
+
+ freeFile(RMarker);
+ strcpy(FileMarkers[RMarker].name, fileName);
+
+ *Ptr = getCurMem(Size);
+ FileMarkers[RMarker].Start = *Ptr;
+ FileMarkers[RMarker].End = (void *)(((char *)(*Ptr)) + Size - 1);
+
+ return false;
+}
+
+
+
+
+
+/*----- Main routines -----*/
+
+
+/*****************************************************************************/
+/* Reads a file into memory. */
+/*****************************************************************************/
+byte **openFile(const char *name) {
+ warning("STUB: openFile");
+
+ return NULL;
+#if 0
+ char *tempbuffer, *Buffer;
+ int32 Size, Left;
+ int FPtr, ReadSize, myread;
+
+ ReadSoFar = 0L;
+ ReadIsError = false;
+ ReadIsDone = false;
+
+ if ((buffer == NULL) || (name == NULL)) {
+ ReadIsError = true;
+ ReadIsDone = true;
+ return NULL;
+ }
+
+ Size = sizeOfFile(name);
+
+ if (!Size || (Size > ((int32) buffersize))) {
+ ReadIsError = true;
+ ReadIsDone = true;
+ return NULL;
+ }
+
+ if (allocFile((void **) &Buffer, Size, name)) { /* Get place in Buffer */
+ *startoffile = Buffer; /* If the file is buffered */
+
+ ReadSoFar = Size;
+ ReadIsError = false;
+ ReadIsDone = true;
+
+ return startoffile;
+ }
+
+#if defined(WIN32)
+#if defined(DEMODATA)
+ {
+ FILE *fh = fopen("c:\\depot\\labyrinth\\demodata.log", "a+w");
+ fprintf(fh, "%s\n", name);
+ fclose(fh);
+ }
+#endif
+
+ FPtr = open(translateFileName(name), O_RDONLY | O_BINARY);
+#else
+ FPtr = open(translateFileName(name), O_RDONLY);
+#endif
+
+ if (FPtr != -1) {
+ Left = Size;
+ tempbuffer = Buffer;
+ *startoffile = Buffer;
+
+ while (Left) {
+ fileCheckMusic(Left);
+
+ if (Left > MAXREADSIZE)
+ ReadSize = MAXREADSIZE;
+ else
+ ReadSize = (int) Left;
+
+ if (!(myread = read(FPtr, tempbuffer, ReadSize + DMABUGSIZE))) {
+ ReadIsError = false;
+ ReadIsDone = true;
+
+ close(FPtr);
+ return NULL;
+ }
+
+ /* Not necessary for IBM version
+ if ((ReadSize == MAXREADSIZE) && DMABUGSIZE)
+ Seek(FPtr, -DMABUGSIZE, (int32) OFFSET_CURRENT);
+ */
+
+ ReadSoFar += ReadSize;
+ tempbuffer += ReadSize;
+ Left -= ReadSize;
+ }
+
+ ReadIsDone = true;
+ close(FPtr);
+ return startoffile;
+ } else {
+ ReadIsError = false;
+ ReadIsDone = true;
+
+ return NULL;
+ }
+#endif
+}
+
+
+
+/*****************************************************************************/
+/* Reads a block of memory. */
+/*****************************************************************************/
+void readBlock(void *Buffer, uint32 Size, byte **File) {
+ memcpy(Buffer, *File, (size_t) Size);
+ (*File) += Size;
+}
+
+
+
+/*****************************************************************************/
+/* Reads on character. */
+/*****************************************************************************/
+char readChar(char **File) {
+ char c = **File;
+
+ (*File)++;
+ return c;
+}
+
+
+
+
+/*****************************************************************************/
+/* Skips a chunk of memory. */
+/*****************************************************************************/
+void skip(byte **File, uint32 skip) {
+ (*File) += skip;
+}
+
+
+
+/*****************************************************************************/
+/* Resets the internal buffers to empty. */
+/*****************************************************************************/
+void resetBuffer(void) {
+ uint16 RMarker;
+
+ CurMarker = 0;
+ RMarker = 0;
+ MemPlace = buffer;
+
+ while (RMarker < MAXMARKERS) {
+ freeFile(RMarker);
+ RMarker++;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Initializes the buffer. */
+/*****************************************************************************/
+bool initBuffer(uint32 BufSize, bool IsGraphicsMem) {
+ if (!allocate((void **) &buffer, BufSize))
+ buffer = NULL;
+
+ buffersize = BufSize;
+ realbuffersize = buffersize;
+ realbufferstart = buffer;
+
+ resetBuffer();
+
+ return (buffer != NULL);
+}
+
+
+
+
+/*****************************************************************************/
+/* Frees the buffer. */
+/*****************************************************************************/
+void freeBuffer(void) {
+ freeAllStolenMem();
+
+ if (buffer)
+ deallocate(buffer, buffersize);
+}
+
+
+
+
+/*------------------------------------------------------------------------*/
+/* The following routines allow stealing of memory from the buffer (which */
+/* later may or may not be given back). */
+/*------------------------------------------------------------------------*/
+
+
+
+
+/*****************************************************************************/
+/* Clears all the buffers. */
+/*****************************************************************************/
+static void flushBuffers(void) {
+ uint16 RMarker;
+
+ RMarker = 0;
+
+ while (RMarker < MAXMARKERS) {
+ freeFile(RMarker);
+ RMarker++;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Steal some memory from the buffer */
+/*****************************************************************************/
+void *stealBufMem(int32 Size) {
+ void *Mem;
+
+ Size += DMABUGSIZE;
+
+ flushBuffers();
+ Mem = buffer;
+
+ buffer += Size;
+ buffersize -= Size;
+ MemPlace = buffer;
+
+ return Mem;
+}
+
+
+Common::File *openPartial(const char *name) {
+ Common::File *f;
+
+ f = new Common::File();
+ f->open(translateFileName(name));
+
+ if (!f->isOpen()) {
+ delete f;
+ return 0;
+ }
+
+ return f;
+}
+
+
+/*****************************************************************************/
+/* Frees all the memory stolen from the buffer. */
+/*****************************************************************************/
+void freeAllStolenMem(void) {
+ flushBuffers();
+
+ buffer = realbufferstart;
+ buffersize = realbuffersize;
+ MemPlace = buffer;
+}
+
+
+
+
+/*--------------- Routines that read partial chunks of a file ---------------*/
+
+
+
+/*****************************************************************************/
+/* Reads Size amount of bytes into buffer. */
+/*****************************************************************************/
+uint32 readPartial(int32 File, void *buf, uint32 Size) {
+ uint32 haveread = 0;
+
+ warning("STUB: readPartial");
+
+#if 0
+ uint32 nsize;
+
+ while (Size) {
+ if (Size > MAXREADSIZE)
+ nsize = MAXREADSIZE;
+ else
+ nsize = Size;
+
+ haveread += (uint32)(read((int) File, buf, (int) nsize));
+ Size -= nsize;
+ ((char *) buf) += nsize;
+ updateMouse();
+ }
+#endif
+ return haveread;
+}
+
+
+
+/*****************************************************************************/
+/* Reads Size amount of bytes into buffer. Use this one if the data must */
+/* absolutely be correct (compressed data for example). Otherwise, because */
+/* of the DMA bug, last two bytes may be screwed. */
+/*****************************************************************************/
+uint32 newReadPartial(int32 File, void *buf, uint32 Size) {
+ return readPartial((int) File, buf, Size);
+}
+
+
+
+/*****************************************************************************/
+/* Reads Size amount of bytes into buffer. Use this one if the data must */
+/* absolutely be correct (compressed data for example). Otherwise, because */
+/* of the DMA bug, last two bytes may be screwed. This one will work if the */
+/* data is not padded the extra two bytes. */
+/*****************************************************************************/
+uint32 bufferedReadPartial(int32 File, void *buf, uint32 Size) {
+ return readPartial(File, buf, Size);
+}
+
+
+
+/*****************************************************************************/
+/* Sets the current position in the file relative to the beginning of the */
+/* file. */
+/*****************************************************************************/
+void setPos(int32 File, uint32 Place) {
+ warning("STUB: setPos");
+ //lseek((int) File, (int32) Place, SEEK_SET);
+}
+
+
+
+/*****************************************************************************/
+/* Skips a certain number of bytes either forward or backwards. */
+/*****************************************************************************/
+void skipPartial(int32 File, int32 Skip) {
+ warning("STUB: skipPartial");
+
+ //lseek((int) File, Skip, SEEK_CUR);
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/labfun.h b/engines/lab/labfun.h
new file mode 100644
index 0000000000..08130f3e0b
--- /dev/null
+++ b/engines/lab/labfun.h
@@ -0,0 +1,393 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#ifndef LAB_LABFUN_H
+#define LAB_LABFUN_H
+
+#include "lab/stddefines.h"
+#include "lab/parsetypes.h"
+#include "common/file.h"
+
+namespace Lab {
+
+/* Direction defines */
+#define NORTH 0
+#define SOUTH 1
+#define EAST 2
+#define WEST 3
+
+
+
+/* Generic co-ordinate define. */
+typedef struct {
+ uint16 x1, y1;
+} Cords;
+
+struct Image;
+struct TextFont;
+
+/*----------------------------*/
+/*------ From Audioi.c -------*/
+/*----------------------------*/
+
+bool initAudio(void);
+
+void freeAudio(void);
+
+void initSampleRate(uint16 SampleSpeed);
+
+bool musicBufferEmpty(uint16 i);
+
+void playMusicBlock(void *Ptr, uint32 Size, uint16 BufferNum, uint16 SampleSpeed);
+
+void updateSoundBuffers(void);
+
+void flushAudio(void);
+
+void playMusic(uint16 SampleSpeed, uint16 Volume, uint32 Length, bool flush, void *Data);
+
+
+
+
+/*----------------------------*/
+/*----- From graphics.c ------*/
+/*----------------------------*/
+
+/* Reads in pictures */
+
+bool readPict(const char *filename, bool PlayOnce);
+
+bool readMusic(const char *filename);
+
+byte *readPictToMem(const char *filename, uint16 x, uint16 y);
+
+/* Window text stuff */
+
+uint32 flowText(void *font, /* the TextAttr pointer */
+ uint16 spacing, /* How much vertical spacing between the lines */
+ uint16 pencolor, /* pen number to use for text */
+ uint16 backpen, /* the background color */
+ bool fillback, /* Whether to fill the background */
+ bool centerh, /* Whether to center the text horizontally */
+ bool centerv, /* Whether to center the text vertically */
+ bool output, /* Whether to output any text */
+ uint16 x1, /* Cords */
+ uint16 y1, uint16 x2, uint16 y2, const char *text); /* The text itself */
+
+uint32 flowTextToMem(struct Image *DestIm, void *font, /* the TextAttr pointer */
+ uint16 spacing, /* How much vertical spacing between the lines */
+ uint16 pencolor, /* pen number to use for text */
+ uint16 backpen, /* the background color */
+ bool fillback, /* Whether to fill the background */
+ bool centerh, /* Whether to center the text horizontally */
+ bool centerv, /* Whether to center the text vertically */
+ bool output, /* Whether to output any text */
+ uint16 x1, /* Cords */
+ uint16 y1, uint16 x2, uint16 y2, const char *text); /* The text itself */
+
+void drawMessage(const char *text);
+
+void longDrawMessage(const char *text);
+
+bool readFont(char *filename, void *font, void *data);
+
+/* The Wipes */
+
+void doWipe(uint16 WipeType, CloseDataPtr *CPtr, char *filename);
+
+
+/* Double Buffer stuff */
+
+void newFlipViews(void *scrPtr, uint16 *newpal, uint16 numcolors);
+
+void flipViews(void *scrPtr);
+
+
+
+
+/*----------------------------*/
+/*----- From Interface.c -----*/
+/*----------------------------*/
+
+struct Gadget *addGadButton(uint16 x, uint16 y, void *UpImage, void *DownImage, uint16 id);
+
+void gadgetsOnOff(void *gptr, void *win, int32 num, bool on);
+
+/*----------------------*/
+/*---- From Intro.c ----*/
+/*----------------------*/
+
+void introSequence(void);
+
+
+
+/*----------------------*/
+/*----- From Lab.c -----*/
+/*----------------------*/
+
+void eatMessages(void);
+
+bool setUpScreens(void);
+
+void drawPanel(void);
+
+bool quitPlaying(void);
+
+
+
+/*---------------------------*/
+/*------ From LabFile.c -----*/
+/*---------------------------*/
+
+uint32 sizeOfFile(const char *name);
+
+/* Buffer a whole file */
+
+byte **isBuffered(const char *fileName);
+
+byte **openFile(const char *name);
+
+void readBlock(void *Buffer, uint32 Size, byte **File);
+
+char readChar(char **File);
+
+void skip(byte **File, uint32 skip);
+
+void resetBuffer(void);
+
+bool initBuffer(uint32 BufSize, bool IsGraphicsMem);
+
+void freeBuffer(void);
+
+
+/* Functions that borrow memory from the buffer */
+
+bool allocFile(void **Ptr, uint32 Size, const char *fileName);
+
+void *stealBufMem(int32 Size);
+
+void freeAllStolenMem(void);
+
+
+/* Read chunks of a file */
+
+
+Common::File *openPartial(const char *name);
+
+void closePartial(int32 File);
+
+uint32 readPartial(int32 File, void *buffer, uint32 Size);
+
+uint32 newReadPartial(int32 File, void *buffer, uint32 Size);
+
+uint32 bufferedReadPartial(int32 File, void *buffer, uint32 Size);
+
+
+void setPos(int32 File, uint32 Place);
+
+void skipPartial(int32 File, int32 Skip);
+
+
+
+/*---------------------------*/
+/*------ From LabText.c -----*/
+/*---------------------------*/
+
+bool initLabText(void);
+
+void freeLabText(void);
+
+void decrypt(byte *text);
+
+
+
+/*---------------------------*/
+/*----- From LabMusic.c -----*/
+/*---------------------------*/
+
+#define MANYBUFFERS 5L
+#define MAXBUFFERS 5L
+#define MINBUFFERS 2L
+
+class Music {
+public:
+ Music();
+
+ byte **newOpen(const char *name);
+ bool initMusic(void);
+ void freeMusic(void);
+ void fillUpMusic(bool doit);
+ void updateMusic(void);
+ void checkMusic(void);
+ void newCheckMusic(void);
+ void closeMusic(void);
+ void setMusic(bool on);
+ void restartBackMusic(void);
+ void pauseBackMusic(void);
+ void changeMusic(const char *newmusic);
+ void resetMusic(void);
+ void fileCheckMusic(uint32 filelength);
+
+ bool _winmusic, _doNotFileFlushAudio;
+ bool _turnMusicOn;
+ bool _musicOn;
+
+private:
+ void fillbuffer(uint16 unit);
+ uint16 getManyBuffersLeft(void);
+ void startMusic(bool startatbegin);
+
+ Common::File *_file;
+ Common::File *_tFile;
+ bool _musicPaused;
+
+ bool _tMusicOn;
+ uint32 _tFileLength;
+ uint32 _tLeftInFile;
+
+ uint16 _manyBuffers;
+
+ void *_musicBuffer[MAXBUFFERS];
+ uint16 _musicFilledTo, _musicPlaying, _musicOnBuffer;
+
+ uint32 _filelength, _leftinfile;
+};
+
+
+extern Music *g_music;
+
+/*---------------------------*/
+/*----- From LabSets.c ------*/
+/*---------------------------*/
+
+typedef struct {
+ uint16 lastElement, array[1];
+} LargeSetRecord;
+
+typedef LargeSetRecord *LargeSet;
+
+
+
+bool createSet(LargeSet *set, uint16 last);
+
+void deleteSet(LargeSet set);
+
+bool In(LargeSet set, uint16 element);
+
+void inclElement(LargeSet set, uint16 element);
+
+void exclElement(LargeSet set, uint16 element);
+
+
+
+
+/*---------------------------*/
+/*----- From Machine.c ------*/
+/*---------------------------*/
+
+uint16 scaleX(uint16 x);
+
+uint16 scaleY(uint16 y);
+
+uint16 VGAScaleX(uint16 x);
+
+uint16 VGAScaleY(uint16 y);
+
+int16 VGAScaleXs(int16 x);
+
+int16 VGAScaleYs(int16 y);
+
+uint16 SVGACord(uint16 cord);
+
+uint16 VGAUnScaleX(uint16 x);
+
+uint16 VGAUnScaleY(uint16 y);
+
+char *translateFileName(const char *filename);
+
+
+
+/*---------------------------*/
+/*-------- From Map.c -------*/
+/*---------------------------*/
+
+void fade(bool fadein, uint16 res);
+
+void setAmigaPal(uint16 *pal, uint16 numcolors);
+
+char *getText(const char *filename);
+
+bool getFont(const char *filename, TextFont *textfont);
+
+void readImage(byte **buffer, Image **im);
+
+void doMap(LargeSet RoomsFound, uint16 CurRoom);
+
+void doJournal(LargeSet Conditions);
+
+void doNotes(void);
+
+void doWestPaper(void);
+
+void doMonitor(char *background, char *textfile, bool isinteractive, uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+
+uint16 doDisks(void);
+
+bool saveRestoreGame(void);
+
+
+
+/*--------------------------*/
+/*----- From saveGame.c ----*/
+/*--------------------------*/
+
+bool saveFloppy(char *path, uint16 RoomNum, uint16 Direction, uint16 NumQuarters, LargeSet Conditions, LargeSet Rooms, uint16 filenum, uint16 type);
+
+bool readFloppy(char *path, uint16 *RoomNum, uint16 *Direction, uint16 *NumQuarters, LargeSet Conditions, LargeSet Rooms, uint16 filenum, uint16 type);
+
+
+
+/*--------------------------*/
+/*----- From Special.c -----*/
+/*--------------------------*/
+
+void showCombination(const char *filename);
+
+void mouseCombination(LargeSet Conditions, uint16 x, uint16 y);
+
+void showTile(const char *filename, bool showsolution);
+
+void mouseTile(LargeSet Conditions, uint16 x, uint16 y);
+
+void inner_main();
+
+} // End of namespace Lab
+
+#endif /* LAB_LABFUN_H */
diff --git a/engines/lab/labmusic.cpp b/engines/lab/labmusic.cpp
new file mode 100644
index 0000000000..e15dfa70f4
--- /dev/null
+++ b/engines/lab/labmusic.cpp
@@ -0,0 +1,543 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/storage.h"
+#include "lab/labfun.h"
+#include "lab/timing.h"
+#include "lab/mouse.h"
+
+namespace Lab {
+
+#define MUSICBUFSIZE (2 * 65536L)
+
+#define SAMPLESPEED 15000L
+
+extern bool EffectPlaying;
+Music *g_music;
+
+Music::Music() {
+ _file = 0;
+ _tFile = 0;
+ _musicPaused = false;
+
+ _tMusicOn = false;
+ _tFileLength = 0;
+ _tLeftInFile = 0;
+
+ _manyBuffers = MANYBUFFERS;
+
+ _musicFilledTo = 0;
+ _musicPlaying = 0;
+ _musicOnBuffer = 0;
+
+ _filelength = 0;
+ _leftinfile = 0;
+
+ _musicOn = false;
+ _turnMusicOn = false;
+ _winmusic = false;
+ _doNotFileFlushAudio = false;
+}
+
+/*****************************************************************************/
+/* Figures out which buffer is currently playing based on messages sent to */
+/* it from the Audio device. */
+/*****************************************************************************/
+void Music::updateMusic(void) {
+ uint16 i;
+
+#if !defined(DOSCODE)
+ //SDL_ProcessInput(0);
+#endif
+ updateMouse();
+
+ if (EffectPlaying)
+ updateSoundBuffers();
+ else if (_musicOn) {
+ for (i = 0; i < 2; i++) {
+ if (musicBufferEmpty(i)) {
+ playMusicBlock(_musicBuffer[_musicPlaying], MUSICBUFSIZE, i, SAMPLESPEED);
+
+ if (_musicPlaying)
+ _musicOnBuffer = _musicPlaying - 1;
+ else
+ _musicOnBuffer = _manyBuffers - 1;
+
+ _musicPlaying++;
+
+ if (_musicPlaying >= _manyBuffers)
+ _musicPlaying = 0;
+ }
+ }
+ }
+}
+
+
+void Music::fillbuffer(uint16 unit) {
+ uint32 Size = MUSICBUFSIZE;
+ void *ptr = _musicBuffer[unit];
+#if defined(DOSCODE)
+ char *endptr;
+#endif
+
+ if (Size < _leftinfile) {
+ _file->read(ptr, Size);
+ _leftinfile -= Size;
+ } else {
+ _file->read(ptr, _leftinfile);
+
+#if defined(DOSCODE)
+ endptr = ptr;
+ endptr += _leftinfile - 2;
+
+ memset((void *)(((uint32) ptr) + _leftinfile), *endptr, Size - _leftinfile);
+#else
+ memset((char *)ptr + _leftinfile, 0, Size - _leftinfile);
+#endif
+
+ _file->seek(0);
+ _leftinfile = _filelength;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Figures out how many *complete* buffers of music left to play. */
+/*****************************************************************************/
+uint16 Music::getManyBuffersLeft(void) {
+ uint16 mp = _musicOnBuffer;
+
+ if (mp == _musicFilledTo) /* Already filled */
+ return _manyBuffers;
+ else if (mp > _musicFilledTo)
+ return _manyBuffers - (mp - _musicFilledTo);
+ else
+ return _musicFilledTo - mp;
+}
+
+
+
+/*****************************************************************************/
+/* Fills up the buffers that have already been played if necessary; if doit */
+/* is set to TRUE then it will fill up all empty buffers. Otherwise, it */
+/* Check if there are MINBUFFERS or less buffers that are playing. */
+/*****************************************************************************/
+void Music::fillUpMusic(bool doit) {
+ int16 ManyLeft, ManyFill;
+
+ updateMusic();
+
+ if (!_musicOn)
+ return;
+
+ ManyLeft = getManyBuffersLeft();
+
+ if (ManyLeft < MINBUFFERS)
+ doit = true;
+ else if (ManyLeft == _manyBuffers) /* All the buffers are already full */
+ doit = false;
+
+ if (doit && (ManyLeft < _manyBuffers) && ManyLeft) {
+ ManyFill = _manyBuffers - ManyLeft - 1;
+
+ while (ManyFill > 0) {
+ _musicFilledTo++;
+
+ if (_musicFilledTo >= _manyBuffers)
+ _musicFilledTo = 0;
+
+ fillbuffer(_musicFilledTo);
+ updateMusic();
+
+ ManyFill--;
+ }
+
+ updateMusic();
+
+ ManyLeft = getManyBuffersLeft();
+
+ if (ManyLeft < _manyBuffers) {
+ ManyFill = _manyBuffers - ManyLeft - 1;
+
+ while (ManyFill > 0) {
+ _musicFilledTo++;
+
+ if (_musicFilledTo >= _manyBuffers)
+ _musicFilledTo = 0;
+
+ fillbuffer(_musicFilledTo);
+ updateMusic();
+
+ ManyFill--;
+ }
+ }
+ }
+
+ updateMusic();
+
+ /* NYI: A check for dirty cds; for instance, if lots of buffers already
+ played */
+}
+
+
+
+
+/*****************************************************************************/
+/* Starts up the music initially. */
+/*****************************************************************************/
+void Music::startMusic(bool startatbegin) {
+ uint16 counter;
+
+ if (!_musicOn)
+ return;
+
+ flushAudio();
+
+ if (startatbegin) {
+ _file->seek(0);
+ _leftinfile = _filelength;
+ }
+
+ initSampleRate(SAMPLESPEED);
+
+ _musicPlaying = 0;
+ _musicOnBuffer = 0;
+ _musicFilledTo = _manyBuffers - 1;
+
+ _musicOn = false;
+
+ for (counter = 0; counter < _manyBuffers; counter++)
+ fillbuffer(counter);
+
+ _musicOn = true;
+ updateMusic();
+}
+
+
+
+
+
+
+/*****************************************************************************/
+/* Initializes the music buffers. */
+/*****************************************************************************/
+bool Music::initMusic(void) {
+ uint16 counter;
+ bool mem;
+
+ if (!_turnMusicOn)
+ return true;
+
+ _musicOn = true;
+ _musicPaused = false;
+
+ const char *filename;
+
+ if (_winmusic)
+ filename = "Music:WinGame";
+ else
+ filename = "Music:BackGrou";
+
+ mem = true;
+
+ if (_musicBuffer[0] == NULL) {
+ for (counter = 0; counter < _manyBuffers; counter++)
+ mem = mem && allocatedos((void **) & (_musicBuffer[counter]), MUSICBUFSIZE);
+ }
+
+ if (mem) {
+ _filelength = sizeOfFile(filename);
+ _file = openPartial(filename);
+
+ if (_file) {
+ startMusic(true);
+ return true;
+ }
+ }
+
+ _musicOn = false;
+ return false;
+}
+
+
+
+/*****************************************************************************/
+/* Frees up the music buffers and closes the file. */
+/*****************************************************************************/
+void Music::freeMusic(void) {
+ _musicOn = false;
+
+ if (_file->isOpen())
+ _file->close();
+
+ _file = 0;
+}
+
+
+/*****************************************************************************/
+/* Pauses the background music. */
+/*****************************************************************************/
+void Music::pauseBackMusic(void) {
+ if (!_musicPaused && _musicOn) {
+ updateMusic();
+ _musicOn = false;
+ flushAudio();
+
+ if (_musicPlaying)
+ _musicPlaying--;
+ else
+ _musicPlaying = _manyBuffers - 1;
+
+ _musicPaused = true;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Restarts the paused background music. */
+/*****************************************************************************/
+void Music::restartBackMusic(void) {
+ if (_musicPaused) {
+ flushAudio();
+ _musicOn = true;
+ updateMusic();
+ _musicPaused = false;
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Checks to see if need to fill buffers fill of music. */
+/*****************************************************************************/
+void Music::checkMusic(void) {
+ updateMusic();
+
+ if (!_musicOn)
+ return;
+
+ fillUpMusic(false);
+}
+
+
+
+/*****************************************************************************/
+/* Checks to see if need to fill buffers fill of music. */
+/*****************************************************************************/
+void Music::newCheckMusic(void) {
+ checkMusic();
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Turns the music on and off. */
+/*****************************************************************************/
+void Music::setMusic(bool on) {
+ flushAudio();
+
+ if (on && !_musicOn) {
+ _musicOn = true;
+ startMusic(true);
+ } else if (!on && _musicOn) {
+ _musicOn = false;
+ updateMusic();
+ } else
+ _musicOn = on;
+}
+
+/*****************************************************************************/
+/* Changes the background music to something else. */
+/*****************************************************************************/
+void Music::changeMusic(const char *newmusic) {
+ if (!_tFile) {
+ _tFile = _file;
+ _tMusicOn = _musicOn;
+ _tFileLength = _filelength;
+#if defined(DOSCODE)
+ _tLeftInFile = _leftinfile;
+#else
+ _tLeftInFile = _leftinfile + 65536L;
+
+ if (_tLeftInFile > _tFileLength)
+ _tLeftInFile = _leftinfile;
+
+#endif
+ }
+
+ _file = openPartial(newmusic);
+
+ if (_file) {
+ _musicOn = true; /* turn it off */
+ setMusic(false);
+
+ _filelength = sizeOfFile(newmusic);
+
+ _musicOn = false; /* turn it back on */
+ setMusic(true);
+ } else {
+ _file = _tFile;
+ _tFile = 0;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Changes the background music to the original piece playing. */
+/*****************************************************************************/
+void Music::resetMusic(void) {
+ if (!_tFile)
+ return;
+
+ if (_file->isOpen())
+ _file->close();
+
+ _file = _tFile;
+ _filelength = _tFileLength;
+ _leftinfile = _tLeftInFile;
+
+ _file->seek(_filelength - _leftinfile);
+
+ _musicOn = true;
+ setMusic(false);
+ updateMusic();
+
+ if (!_tMusicOn) {
+ _tFile = 0;
+ return;
+ }
+
+ _musicOn = _tMusicOn;
+ startMusic(false);
+
+ _tFile = 0;
+}
+
+
+
+
+
+#define FUDGEFACTOR 5L
+#define READSPEED (2 * 130000L)
+
+
+
+/*****************************************************************************/
+/* Checks whether or note enough memory in music buffer before loading any */
+/* files. Fills it if not. Does not take into account the current buffer */
+/* playing; a built in fudge factor. We've also got another FUDGEFACTOR */
+/* defined above in case things go wrong. */
+/* */
+/* Here, the seconds are multipled by 10. */
+/*****************************************************************************/
+byte **Music::newOpen(const char *name) {
+ uint32 filelength, LeftSecs, Time;
+
+ byte **file;
+
+ if (name == NULL) {
+ return NULL;
+ }
+
+ if ((strcmp(name, "") == 0) || (strcmp(name, " ") == 0)) {
+ return NULL;
+ }
+
+ if ((file = isBuffered(name))) {
+ return file;
+ }
+
+ if (_musicOn) {
+ updateMusic();
+
+#if defined(DOSCODE)
+ LeftSecs = (getManyBuffersLeft() * MUSICBUFSIZE * 10) / SAMPLESPEED;
+#else
+ LeftSecs = (getManyBuffersLeft() * MUSICBUFSIZE * 10) / (2 * SAMPLESPEED);
+#endif
+
+ filelength = sizeOfFile(name) * 10;
+ Time = 10 + /* Seek time for the music and the file */
+ (filelength / READSPEED) + /* Read time for the file */
+ FUDGEFACTOR;
+
+ if (Time >= LeftSecs)
+ fillUpMusic(true);
+ }
+
+ if (!_doNotFileFlushAudio && EffectPlaying)
+ flushAudio();
+
+ file = openFile(name);
+ checkMusic();
+ return file;
+}
+
+
+
+/*****************************************************************************/
+/* Checks whether or note enough memory in music buffer to continue loading */
+/* in a file. Fills the music buffer if not. Does not take into account */
+/* the current buffer playing; a built in fudge factor. We've also got */
+/* another FUDGEFACTOR defined above in case things go wrong. */
+/* */
+/* Here, the seconds are multipled by 10. */
+/*****************************************************************************/
+void Music::fileCheckMusic(uint32 filelength) {
+ uint32 LeftSecs, Time;
+
+ if (_musicOn) {
+ updateMusic();
+
+#if defined(DOSCODE)
+ LeftSecs = (getManyBuffersLeft() * MUSICBUFSIZE * 10) / SAMPLESPEED;
+#else
+ LeftSecs = (getManyBuffersLeft() * MUSICBUFSIZE * 10) / (2 * SAMPLESPEED);
+#endif
+
+ filelength *= 10;
+ Time = 5 + /* Seek time for the music */
+ (filelength / READSPEED) + /* Read time for the file */
+ FUDGEFACTOR;
+
+ if (Time >= LeftSecs)
+ fillUpMusic(true);
+ }
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/labsets.cpp b/engines/lab/labsets.cpp
new file mode 100644
index 0000000000..5faf1cce8a
--- /dev/null
+++ b/engines/lab/labsets.cpp
@@ -0,0 +1,94 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/labfun.h"
+#include "lab/storage.h"
+
+namespace Lab {
+
+const uint32 LargeSetSIZE = sizeof(LargeSetRecord) - 2;
+
+
+
+/*****************************************************************************/
+/* Creates a large set. */
+/*****************************************************************************/
+bool createSet(LargeSet *set, uint16 last) {
+ last = (((last + 15) >> 4) << 4);
+
+ if (allocate((void **) set, (last >> 3) + LargeSetSIZE)) {
+ (*set)->lastElement = last;
+ return true;
+ } else /* Not Enough Memory! */
+ return false;
+
+}
+
+
+
+
+/*****************************************************************************/
+/* Deletes a large set. */
+/*****************************************************************************/
+void deleteSet(LargeSet set) {
+ if (set != NULL)
+ deallocate(set, (set->lastElement >> 3) + LargeSetSIZE);
+}
+
+
+
+
+/*****************************************************************************/
+/* Tests if an element is in the set. */
+/*****************************************************************************/
+bool In(LargeSet set, uint16 element) {
+ return ((1 << ((element - 1) % 16)) & (set->array[(element - 1) >> 4])) > 0;
+}
+
+
+
+/*****************************************************************************/
+/* Sets an element in the Large set. */
+/*****************************************************************************/
+void inclElement(LargeSet set, uint16 element) {
+ INCL((set->array[(element - 1) >> 4]), (1 << ((element - 1) % 16)));
+}
+
+
+
+/*****************************************************************************/
+/* Removes an element in the Large set. */
+/*****************************************************************************/
+void exclElement(LargeSet set, uint16 element) {
+ EXCL((set->array[(element - 1) >> 4]), (1 << ((element - 1) % 16)));
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/labtext.cpp b/engines/lab/labtext.cpp
new file mode 100644
index 0000000000..d90929fc8e
--- /dev/null
+++ b/engines/lab/labtext.cpp
@@ -0,0 +1,168 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/storage.h"
+#include "lab/labfun.h"
+
+namespace Lab {
+
+static uint32 SizeOfMemChunk;
+static char *BeginOfMemChunk, *CurPlace;
+
+
+char *LOWERFLOORS, *MIDDLEFLOORS, *UPPERFLOORS, *MEDMAZEFLOORS, *HEDGEMAZEFLOORS, *SURMAZEFLOORS, *CARNIVALFLOOR, *SURMAZEMSG, *FACINGNORTH, *FACINGEAST, *FACINGSOUTH, *FACINGWEST, *LAMPONMSG, *TURNLEFT, *TURNRIGHT, *GOFORWARDDIR, *NOPATH, *TAKEITEM, *SAVETEXT, *LOADTEXT, *BOOKMARKTEXT, *PERSONALTEXT, *DISKTEXT, *SAVEBOOK, *RESTOREBOOK, *SAVEFLASH, *RESTOREFLASH, *SAVEDISK, *RESTOREDISK, *NODISKINDRIVE, *WRITEPROTECTED, *SELECTDISK, *FORMATFLOPPY, *FORMATTING, *NOTHING, *USEONWHAT, *TAKEWHAT, *MOVEWHAT, *OPENWHAT, *CLOSEWHAT, *LOOKWHAT, *USEMAP, *USEJOURNAL, *TURNLAMPON, *TURNLAMPOFF, *USEWHISKEY, *USEPITH, *USEHELMET;
+
+
+#define LABTEXTFILE "Lab:Rooms/LabText"
+
+
+
+
+/*****************************************************************************/
+/* Gets the next string from the list, and changes the end of string marker */
+/* from an end of line to a null character. */
+/*****************************************************************************/
+static void setString(char **string) {
+ *string = CurPlace;
+
+ while (*CurPlace != '\n')
+ CurPlace++;
+
+ *CurPlace = 0;
+ CurPlace++;
+}
+
+
+
+/*****************************************************************************/
+/* Initializes everything for the Labyrinth text stuff */
+/*****************************************************************************/
+bool initLabText(void) {
+ if ((SizeOfMemChunk = sizeOfFile(LABTEXTFILE)))
+ if (allocate((void **) &BeginOfMemChunk, SizeOfMemChunk)) {
+ Common::File *file = openPartial(LABTEXTFILE);
+
+ if (file) {
+ file->read(BeginOfMemChunk, SizeOfMemChunk);
+ file->close();
+
+ CurPlace = BeginOfMemChunk;
+
+ setString(&LOWERFLOORS);
+ setString(&MIDDLEFLOORS);
+ setString(&UPPERFLOORS);
+ setString(&MEDMAZEFLOORS);
+ setString(&HEDGEMAZEFLOORS);
+ setString(&SURMAZEFLOORS);
+ setString(&CARNIVALFLOOR);
+ setString(&SURMAZEMSG);
+
+ setString(&FACINGNORTH);
+ setString(&FACINGEAST);
+ setString(&FACINGSOUTH);
+ setString(&FACINGWEST);
+
+ setString(&LAMPONMSG);
+
+ setString(&TURNLEFT);
+ setString(&TURNRIGHT);
+ setString(&GOFORWARDDIR);
+ setString(&NOPATH);
+ setString(&TAKEITEM);
+
+ setString(&SAVETEXT);
+ setString(&LOADTEXT);
+ setString(&BOOKMARKTEXT);
+ setString(&PERSONALTEXT);
+ setString(&DISKTEXT);
+
+ setString(&SAVEBOOK);
+ setString(&RESTOREBOOK);
+ setString(&SAVEFLASH);
+ setString(&RESTOREFLASH);
+ setString(&SAVEDISK);
+ setString(&RESTOREDISK);
+ setString(&NODISKINDRIVE);
+ setString(&WRITEPROTECTED);
+ setString(&SELECTDISK);
+
+ setString(&FORMATFLOPPY);
+ setString(&FORMATTING);
+
+ setString(&NOTHING);
+ setString(&USEONWHAT);
+ setString(&TAKEWHAT);
+ setString(&MOVEWHAT);
+ setString(&OPENWHAT);
+ setString(&CLOSEWHAT);
+ setString(&LOOKWHAT);
+
+ setString(&USEMAP);
+ setString(&USEJOURNAL);
+ setString(&TURNLAMPON);
+ setString(&TURNLAMPOFF);
+ setString(&USEWHISKEY);
+ setString(&USEPITH);
+ setString(&USEHELMET);
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/*****************************************************************************/
+/* Frees the memory from the Labyrinth text stuff. */
+/*****************************************************************************/
+void freeLabText(void) {
+ if (SizeOfMemChunk && BeginOfMemChunk)
+ deallocate(BeginOfMemChunk, SizeOfMemChunk);
+}
+
+
+
+
+/*****************************************************************************/
+/* Decrypts a chunk of text. */
+/*****************************************************************************/
+void decrypt(byte *text) {
+ if (text == NULL)
+ return;
+
+ while (*text != '\0') {
+ (*text) -= (byte) 95;
+ text++;
+ }
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/machine.cpp b/engines/lab/machine.cpp
new file mode 100644
index 0000000000..ab46ce600e
--- /dev/null
+++ b/engines/lab/machine.cpp
@@ -0,0 +1,372 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+
+namespace Lab {
+
+bool IsHiRes = false;
+
+/*****************************************************************************/
+/* Scales the x co-ordinates to that of the new display. In the room parser */
+/* file, co-ordinates are set up on a 360x336 display. */
+/*****************************************************************************/
+uint16 scaleX(uint16 x) {
+ if (IsHiRes)
+ return (uint16)((x * 16) / 9);
+ else
+ return (uint16)((x * 8) / 9);
+}
+
+
+
+
+/*****************************************************************************/
+/* Scales the y co-ordinates to that of the new display. In the room parser */
+/* file, co-ordinates are set up on a 368x336 display. */
+/*****************************************************************************/
+uint16 scaleY(uint16 y) {
+ if (IsHiRes)
+ return (y + (y / 14));
+ else
+ return ((y * 10) / 24);
+}
+
+
+
+
+/*****************************************************************************/
+/* Scales the VGA cords to SVGA if necessary; otherwise, returns VGA cords. */
+/*****************************************************************************/
+uint16 VGAScaleX(uint16 x) {
+ if (IsHiRes)
+ return (x * 2);
+ else
+ return x;
+}
+
+
+
+
+/*****************************************************************************/
+/* Scales the VGA cords to SVGA if necessary; otherwise, returns VGA cords. */
+/*****************************************************************************/
+uint16 VGAScaleY(uint16 y) {
+ if (IsHiRes)
+ return ((y * 12) / 5);
+ else
+ return y;
+}
+
+
+
+/*****************************************************************************/
+/* Scales the VGA cords to SVGA if necessary; otherwise, returns VGA cords. */
+/*****************************************************************************/
+int16 VGAScaleXs(int16 x) {
+ if (IsHiRes)
+ return (x * 2);
+ else
+ return x;
+}
+
+
+
+
+/*****************************************************************************/
+/* Scales the VGA cords to SVGA if necessary; otherwise, returns VGA cords. */
+/*****************************************************************************/
+int16 VGAScaleYs(int16 y) {
+ if (IsHiRes)
+ return ((y * 12) / 5);
+ else
+ return y;
+}
+
+
+
+
+uint16 SVGACord(uint16 cord) {
+ if (IsHiRes)
+ return cord;
+ else
+ return 0;
+}
+
+
+
+
+/*****************************************************************************/
+/* Converts SVGA cords to VGA if necessary, otherwise returns VGA cords. */
+/*****************************************************************************/
+uint16 VGAUnScaleX(uint16 x) {
+ if (IsHiRes)
+ return (x / 2);
+ else
+ return x;
+}
+
+
+
+
+/*****************************************************************************/
+/* Converts SVGA cords to VGA if necessary, otherwise returns VGA cords. */
+/*****************************************************************************/
+uint16 VGAUnScaleY(uint16 y) {
+ if (IsHiRes)
+ return ((y * 5) / 12);
+ else
+ return y;
+}
+
+
+
+
+#if defined(WIN32)
+/*****************************************************************************/
+/* Replaces all occurences of a character in a string with a new one. */
+/*****************************************************************************/
+static void strrplc(char *text, char orig, char replace) {
+ uint16 counter;
+
+ counter = 0;
+
+ while (text[counter]) {
+ if (text[counter] == orig)
+ text[counter] = replace;
+
+ counter++;
+ }
+}
+#endif
+
+
+/*****************************************************************************/
+/* Checks to see if all the characters in the second string are at the start */
+/* of the first. */
+/*****************************************************************************/
+static bool strstart(const char **Source, const char *Start) {
+ uint16 len1, len2, counter;
+
+ len1 = strlen(*Source);
+ len2 = strlen(Start);
+
+ if (len1 < len2)
+ return false;
+
+ for (counter = 0; counter < len2; counter++)
+ if ((*Source)[counter] != Start[counter])
+ return false;
+
+ (*Source) += len2;
+ return true;
+}
+
+
+static char NewFileName[255];
+
+/*****************************************************************************/
+/* Modifes the filename so that paths and stuff are correct. Should mostly */
+/* deal with assigns and the '/' instead of '\' on IBM systems. */
+/* */
+/* NOTE: Make a *copy* of the string, and modify that. It would be a real */
+/* *bad* idea to modify the original. Since Labyrinth only focuses its */
+/* attention to one file at a time, it would be fine to have one variable */
+/* not on the stack which is used to store the new filename. */
+/*****************************************************************************/
+static void mystrupr(char *s) {
+ char c;
+
+ while ((c = *s) != 0)
+ *s++ = toupper(c);
+}
+
+char *translateFileName(const char *filename) {
+ char tempfilename[255];
+ char *dot;
+
+ strcpy(tempfilename, filename);
+ mystrupr(tempfilename);
+
+ *NewFileName = 0;
+ filename = tempfilename;
+
+ if (strstart(&filename, "P:")) {
+ if (IsHiRes)
+ strcat(NewFileName, "GAME/SPICT/");
+ else
+ strcat(NewFileName, "GAME/PICT/");
+ } else if (strstart(&filename, "LAB:"))
+ strcat(NewFileName, "GAME/");
+ else if (strstart(&filename, "MUSIC:"))
+ strcat(NewFileName, "GAME/MUSIC/");
+
+ strcat(NewFileName, filename);
+
+ dot = strrchr(NewFileName, '.');
+
+ if (dot != NewFileName && dot != NULL && dot[4] != '/') { // Linux may start with '.'
+ dot[4] = 0; // Back to the days of 8.3, even if your OS was never DOSish!!
+ }
+
+ return NewFileName;
+}
+
+#if defined(USE_SWAP)
+
+uint16 swapUShort(uint16 value) {
+ char *b = (char *)&value;
+ char t = b[0];
+ b[0] = b[1];
+ b[1] = t;
+ return value;
+}
+uint16 *swapUShortPtr(uint16 *ptr, int count) {
+ while (count-- > 0) {
+ char *b = (char *)ptr++;
+ char t = b[0];
+ b[0] = b[1];
+ b[1] = t;
+ }
+
+ return ptr;
+}
+int16 swapShort(int16 value) {
+ char *b = (char *)&value;
+ char t = b[0];
+ b[0] = b[1];
+ b[1] = t;
+ return value;
+}
+int16 *swapShortPtr(int16 *ptr, int count) {
+ while (count-- > 0) {
+ char *b = (char *)ptr++;
+ char t = b[0];
+ b[0] = b[1];
+ b[1] = t;
+ }
+
+ return ptr;
+}
+unsigned int swapUInt(unsigned int value) {
+ char *b = (char *)&value;
+ char t = b[0];
+ b[0] = b[3];
+ b[3] = t;
+ t = b[1];
+ b[1] = b[2];
+ b[2] = t;
+ return value;
+}
+unsigned int *swapUIntPtr(unsigned int *ptr, int count) {
+ while (count-- > 0) {
+ char *b = (char *)ptr++;
+ char t = b[0];
+ b[0] = b[3];
+ b[3] = t;
+ t = b[1];
+ b[1] = b[2];
+ b[2] = t;
+ }
+
+ return ptr;
+}
+int swapInt(int value) {
+ char *b = (char *)&value;
+ char t = b[0];
+ b[0] = b[3];
+ b[3] = t;
+ t = b[1];
+ b[1] = b[2];
+ b[2] = t;
+ return value;
+}
+int *swapIntPtr(int *ptr, int count) {
+ while (count-- > 0) {
+ char *b = (char *)ptr++;
+ char t = b[0];
+ b[0] = b[3];
+ b[3] = t;
+ t = b[1];
+ b[1] = b[2];
+ b[2] = t;
+ }
+
+ return ptr;
+}
+uint32 swapULong(uint32 value) {
+ char *b = (char *)&value;
+ char t = b[0];
+ b[0] = b[3];
+ b[3] = t;
+ t = b[1];
+ b[1] = b[2];
+ b[2] = t;
+ return value;
+}
+uint32 *swapULongPtr(uint32 *ptr, int count) {
+ while (count-- > 0) {
+ char *b = (char *)ptr++;
+ char t = b[0];
+ b[0] = b[3];
+ b[3] = t;
+ t = b[1];
+ b[1] = b[2];
+ b[2] = t;
+ }
+
+ return ptr;
+}
+int32 swapLong(int32 value) {
+ char *b = (char *)&value;
+ char t = b[0];
+ b[0] = b[3];
+ b[3] = t;
+ t = b[1];
+ b[1] = b[2];
+ b[2] = t;
+ return value;
+}
+int32 *swapLongPtr(int32 *ptr, int count) {
+ while (count-- > 0) {
+ char *b = (char *)ptr++;
+ char t = b[0];
+ b[0] = b[3];
+ b[3] = t;
+ t = b[1];
+ b[1] = b[2];
+ b[2] = t;
+ }
+
+ return ptr;
+}
+#endif
+
+} // End of namespace Lab
diff --git a/engines/lab/map.cpp b/engines/lab/map.cpp
new file mode 100644
index 0000000000..f6e94990b5
--- /dev/null
+++ b/engines/lab/map.cpp
@@ -0,0 +1,955 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/storage.h"
+#include "lab/labfun.h"
+#include "lab/diff.h"
+#include "lab/vga.h"
+#include "lab/text.h"
+#include "lab/mouse.h"
+#include "lab/parsefun.h"
+#include "lab/parsetypes.h"
+#include "lab/interface.h"
+#include "lab/text.h"
+#include "lab/stddefines.h"
+
+namespace Lab {
+
+static struct TextFont *BigMsgFont;
+static struct TextFont bmf;
+
+
+extern uint16 Direction;
+extern bool IsHiRes;
+extern uint32 VGAScreenWidth, VGAScreenHeight;
+
+#if !defined(DOSCODE)
+extern CloseDataPtr CPtr;
+extern uint16 RoomNum;
+#endif
+
+/*****************************************************************************/
+/* Converts an Amiga palette (up to 16 colors) to a VGA palette, then sets */
+/* the VGA palette. */
+/*****************************************************************************/
+void setAmigaPal(uint16 *pal, uint16 numcolors) {
+ char vgapal[16 * 3];
+ uint16 counter, vgacount;
+
+ if (numcolors > 16)
+ numcolors = 16;
+
+ vgacount = 0;
+
+ for (counter = 0; counter < numcolors; counter++) {
+ vgapal[vgacount] = (char)(((pal[counter] & 0xf00) >> 8) << 2);
+ vgacount++;
+ vgapal[vgacount] = (char)(((pal[counter] & 0x0f0) >> 4) << 2);
+ vgacount++;
+ vgapal[vgacount] = (char)(((pal[counter] & 0x00f)) << 2);
+ vgacount++;
+ }
+
+ writeColorRegsSmooth(vgapal, 0, 16);
+}
+
+
+/*****************************************************************************/
+/* Gets a font from disk and puts it into temporary memory. */
+/*****************************************************************************/
+bool getFont(const char *filename, TextFont *textfont) {
+ byte *fontbuffer;
+
+ fontbuffer = (byte *)stealBufMem(sizeOfFile(filename) -
+ (sizeof(struct TextFont) + 4));
+ g_music->checkMusic();
+
+ if (fontbuffer == NULL)
+ return false;
+
+ return openFontMem(filename, textfont, fontbuffer);
+}
+
+
+
+
+/*****************************************************************************/
+/* Gets a chunk of text and puts it into the graphics memory. */
+/*****************************************************************************/
+char *getText(const char *filename) {
+ bool dodecrypt;
+ byte **tfile;
+
+ g_music->checkMusic();
+ dodecrypt = (isBuffered(filename) == NULL);
+ tfile = g_music->newOpen(filename);
+
+ if (!tfile)
+ return NULL;
+
+ if (dodecrypt)
+ decrypt(*tfile);
+
+ return (char *)*tfile;
+}
+
+
+
+/*****************************************************************************/
+/* Reads in an image from disk. */
+/*****************************************************************************/
+void readImage(byte **buffer, Image **im) {
+ uint32 size;
+
+ (*im) = (Image *)(*buffer);
+
+ (*im)->Width = READ_LE_UINT16(*buffer);
+ (*im)->Height = READ_LE_UINT16(*buffer + 2);
+
+ *buffer += 8; /* sizeof(struct Image); */
+
+ size = (*im)->Width * (*im)->Height;
+
+ if (1L & size)
+ size++;
+
+ (*im)->ImageData = (byte *)(*buffer);
+ (*buffer) += size;
+}
+
+
+
+
+
+
+/*---------------------------------------------------------------------------*/
+/*------------------------------ The Map stuff ------------------------------*/
+/*---------------------------------------------------------------------------*/
+
+
+
+extern RoomData *Rooms;
+extern char *ViewPath;
+
+static Image *Map, *Room, *UpArrowRoom, *DownArrowRoom, *Bridge,
+ *HRoom, *VRoom, *Maze, *HugeMaze, *Path, *MapNorth,
+ *MapEast, *MapSouth, *MapWest, *XMark, *Back, *BackAlt,
+ *Down, *DownAlt, *Up, *UpAlt;
+
+static uint16 MaxRooms;
+static MapData *Maps;
+
+extern char *LOWERFLOORS, *MIDDLEFLOORS, *UPPERFLOORS, *MEDMAZEFLOORS, *HEDGEMAZEFLOORS, *SURMAZEFLOORS, *CARNIVALFLOOR, *SURMAZEMSG;
+
+extern TextFont *MsgFont;
+
+uint16 *FadePalette;
+
+static uint16 MapGadX[3] = {101, 55, 8}, MapGadY[3] = {105, 105, 105};
+#if !defined(DOSCODE)
+static Gadget downgadget = { 101, 105, 2, VKEY_DNARROW, 0L, NULL, NULL, NULL },
+ upgadget = { 55, 105, 1, VKEY_UPARROW, 0L, NULL, NULL, &downgadget },
+ backgadget = { 8, 105, 0, 0, 0L, NULL, NULL, &upgadget },
+#else
+static Gadget downgadget = { 101, 105, 2, 0L, NULL, NULL, NULL },
+ upgadget = { 55, 105, 1, 0L, NULL, NULL, &downgadget },
+ backgadget = { 8, 105, 0, 0L, NULL, NULL, &upgadget },
+#endif
+*MapGadgetList = &backgadget;
+
+static uint16 AmigaMapPalette[] = {
+ 0x0BA8, 0x0C11, 0x0A74, 0x0076,
+ 0x0A96, 0x0DCB, 0x0CCA, 0x0222,
+ 0x0444, 0x0555, 0x0777, 0x0999,
+ 0x0AAA, 0x0ED0, 0x0EEE, 0x0694
+};
+
+
+#define LOWERFLOOR 1
+#define MIDDLEFLOOR 2
+#define UPPERFLOOR 3
+#define MEDMAZEFLOOR 4
+#define HEDGEMAZEFLOOR 5
+#define SURMAZEFLOOR 6
+#define CARNIVAL 7
+
+
+
+static uint16 mapScaleX(uint16 x) {
+ if (IsHiRes)
+ return (x - 45);
+ else
+ return ((x - 45) >> 1);
+}
+
+
+
+static uint16 mapScaleY(uint16 y) {
+ if (IsHiRes)
+ return y;
+ else
+ return ((y - 35) >> 1) - (y >> 6);
+}
+
+
+
+
+/*****************************************************************************/
+/* Loads in the map data. */
+/*****************************************************************************/
+static bool loadMapData(void) {
+ byte **buffer, Temp[5];
+ int32 Size;
+ struct Gadget *gptr;
+ uint16 counter;
+
+ BigMsgFont = &bmf;
+
+ if (!getFont("P:Map.fon", BigMsgFont))
+ BigMsgFont = MsgFont;
+
+ Size = sizeOfFile("P:MapImage");
+ resetBuffer(); /* Make images load into start of buffer */
+ buffer = g_music->newOpen("P:MapImage");
+
+ if (!buffer)
+ return false;
+
+ stealBufMem(Size); /* Now freeze that buffer from further use */
+
+ readImage(buffer, &Map);
+
+ readImage(buffer, &Room);
+ readImage(buffer, &UpArrowRoom);
+ readImage(buffer, &DownArrowRoom);
+ readImage(buffer, &HRoom);
+ readImage(buffer, &VRoom);
+ readImage(buffer, &Maze);
+ readImage(buffer, &HugeMaze);
+
+ readImage(buffer, &MapNorth);
+ readImage(buffer, &MapEast);
+ readImage(buffer, &MapSouth);
+ readImage(buffer, &MapWest);
+
+ readImage(buffer, &Path);
+ readImage(buffer, &Bridge);
+
+ readImage(buffer, &Back);
+ readImage(buffer, &BackAlt);
+ readImage(buffer, &Up);
+ readImage(buffer, &UpAlt);
+ readImage(buffer, &Down);
+ readImage(buffer, &DownAlt);
+
+ backgadget.Im = Back;
+ backgadget.ImAlt = BackAlt;
+ upgadget.Im = Up;
+ upgadget.ImAlt = UpAlt;
+ downgadget.Im = Down;
+ downgadget.ImAlt = DownAlt;
+
+ counter = 0;
+ gptr = MapGadgetList;
+
+ while (gptr) {
+ gptr->x = VGAScaleX(MapGadX[counter]);
+ gptr->y = VGAScaleY(MapGadY[counter]);
+ gptr = gptr->NextGadget;
+ counter++;
+ }
+
+ buffer = g_music->newOpen("Lab:Maps");
+ stealBufMem(sizeOfFile("Lab:Maps")); /* Freeze the memory for the maps */
+ readBlock(Temp, 4L, buffer);
+ Temp[4] = 0;
+
+ if (strcmp((char *)Temp, "MAP0") == 0) {
+ readBlock(&MaxRooms, 2L, buffer);
+#if !defined(DOSCODE)
+ swapUShortPtr(&MaxRooms, 1);
+#endif
+ Maps = (MapData *)(*buffer);
+#if !defined(DOSCODE)
+
+ for (counter = 1; counter <= MaxRooms; counter++) {
+ swapUShortPtr(&Maps[counter].x, 4);
+ swapULongPtr(&Maps[counter].MapFlags, 1);
+ }
+
+#endif
+ } else
+ return false;
+
+ return true;
+}
+
+
+
+
+static uint16 fadeNumIn(uint16 num, uint16 res, uint16 counter) {
+ return (num - ((((int32)(15 - counter)) * ((int32)(num - res))) / 15));
+}
+
+
+static uint16 fadeNumOut(uint16 num, uint16 res, uint16 counter) {
+ return (num - ((((int32) counter) * ((int32)(num - res))) / 15));
+}
+
+
+
+/*****************************************************************************/
+/* Does the fading of the Palette on the screen. */
+/*****************************************************************************/
+void fade(bool fadein, uint16 res) {
+ uint16 pennum, counter, newpal[16];
+
+ for (counter = 0; counter < 16; counter++) {
+ for (pennum = 0; pennum < 16; pennum++) {
+ if (fadein)
+ newpal[pennum] = (0x00F & fadeNumIn(0x00F & FadePalette[pennum], 0x00F & res, counter)) +
+ (0x0F0 & fadeNumIn(0x0F0 & FadePalette[pennum], 0x0F0 & res, counter)) +
+ (0xF00 & fadeNumIn(0xF00 & FadePalette[pennum], 0xF00 & res, counter));
+ else
+ newpal[pennum] = (0x00F & fadeNumOut(0x00F & FadePalette[pennum], 0x00F & res, counter)) +
+ (0x0F0 & fadeNumOut(0x0F0 & FadePalette[pennum], 0x0F0 & res, counter)) +
+ (0xF00 & fadeNumOut(0xF00 & FadePalette[pennum], 0xF00 & res, counter));
+ }
+
+ setAmigaPal(newpal, 16);
+ waitTOF();
+ g_music->updateMusic();
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Figures out what a room's coordinates should be. */
+/*****************************************************************************/
+static void roomCords(uint16 CurRoom, uint16 *x1, uint16 *y1, uint16 *x2, uint16 *y2) {
+ *x1 = mapScaleX(Maps[CurRoom].x);
+ *y1 = mapScaleY(Maps[CurRoom].y);
+ *x2 = *x1;
+ *y2 = *y1;
+
+ switch (Maps[CurRoom].SpecialID) {
+ case NORMAL:
+ case UPARROWROOM:
+ case DOWNARROWROOM:
+ (*x2) += Room->Width;
+ (*y2) += Room->Height;
+ break;
+
+ case BRIDGEROOM:
+ (*x2) += Bridge->Width;
+ (*y2) += Bridge->Height;
+ break;
+
+ case VCORRIDOR:
+ (*x2) += VRoom->Width;
+ (*y2) += VRoom->Height;
+ break;
+
+ case HCORRIDOR:
+ (*x2) += HRoom->Width;
+ (*y2) += HRoom->Height;
+ break;
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Draws a room to the bitmap. */
+/*****************************************************************************/
+static void drawRoom(uint16 CurRoom, bool drawx) {
+ uint16 x, y, xx, xy, offset;
+ uint32 flags;
+
+ x = mapScaleX(Maps[CurRoom].x);
+ y = mapScaleY(Maps[CurRoom].y);
+ flags = Maps[CurRoom].MapFlags;
+
+ switch (Maps[CurRoom].SpecialID) {
+ case NORMAL:
+ case UPARROWROOM:
+ case DOWNARROWROOM:
+ if (Maps[CurRoom].SpecialID == NORMAL)
+ drawImage(Room, x, y);
+ else if (Maps[CurRoom].SpecialID == DOWNARROWROOM)
+ drawImage(DownArrowRoom, x, y);
+ else
+ drawImage(UpArrowRoom, x, y);
+
+ offset = (Room->Width - Path->Width) / 2;
+
+ if ((NORTHDOOR & flags) && (y >= Path->Height))
+ drawImage(Path, x + offset, y - Path->Height);
+
+ if (SOUTHDOOR & flags)
+ drawImage(Path, x + offset, y + Room->Height);
+
+ offset = (Room->Height - Path->Height) / 2;
+
+ if (EASTDOOR & flags)
+ drawImage(Path, x + Room->Width, y + offset);
+
+ if (WESTDOOR & flags)
+ drawImage(Path, x - Path->Width, y + offset);
+
+ xx = x + (Room->Width - XMark->Width) / 2;
+ xy = y + (Room->Height - XMark->Height) / 2;
+
+ break;
+
+ case BRIDGEROOM:
+ drawImage(Bridge, x, y);
+
+ xx = x + (Bridge->Width - XMark->Width) / 2;
+ xy = y + (Bridge->Height - XMark->Height) / 2;
+
+ break;
+
+ case VCORRIDOR:
+ drawImage(VRoom, x, y);
+
+ offset = (VRoom->Width - Path->Width) / 2;
+
+ if (NORTHDOOR & flags)
+ drawImage(Path, x + offset, y - Path->Height);
+
+ if (SOUTHDOOR & flags)
+ drawImage(Path, x + offset, y + VRoom->Height);
+
+ offset = (Room->Height - Path->Height) / 2;
+
+ if (EASTDOOR & flags)
+ drawImage(Path, x + VRoom->Width, y + offset);
+
+ if (WESTDOOR & flags)
+ drawImage(Path, x - Path->Width, y + offset);
+
+ if (EASTBDOOR & flags)
+ drawImage(Path, x + VRoom->Width, y - offset - Path->Height + VRoom->Height);
+
+ if (WESTBDOOR & flags)
+ drawImage(Path, x - Path->Width, y - offset - Path->Height + VRoom->Height);
+
+ offset = (VRoom->Height - Path->Height) / 2;
+
+ if (EASTMDOOR & flags)
+ drawImage(Path, x + VRoom->Width, y - offset - Path->Height + VRoom->Height);
+
+ if (WESTMDOOR & flags)
+ drawImage(Path, x - Path->Width, y - offset - Path->Height + VRoom->Height);
+
+ xx = x + (VRoom->Width - XMark->Width) / 2;
+ xy = y + (VRoom->Height - XMark->Height) / 2;
+
+ break;
+
+ case HCORRIDOR:
+ drawImage(HRoom, x, y);
+
+ offset = (Room->Width - Path->Width) / 2;
+
+ if (NORTHDOOR & flags)
+ drawImage(Path, x + offset, y - Path->Height);
+
+ if (SOUTHDOOR & flags)
+ drawImage(Path, x + offset, y + Room->Height);
+
+ if (NORTHRDOOR & flags)
+ drawImage(Path, x - offset - Path->Width + HRoom->Width, y - Path->Height);
+
+ if (SOUTHRDOOR & flags)
+ drawImage(Path, x - offset - Path->Width + HRoom->Width, y + Room->Height);
+
+ offset = (HRoom->Width - Path->Width) / 2;
+
+ if (NORTHMDOOR & flags)
+ drawImage(Path, x - offset - Path->Width + HRoom->Width, y - Path->Height);
+
+ if (SOUTHMDOOR & flags)
+ drawImage(Path, x - offset - Path->Width + HRoom->Width, y + Room->Height);
+
+ offset = (Room->Height - Path->Height) / 2;
+
+ if (EASTDOOR & flags)
+ drawImage(Path, x + HRoom->Width, y + offset);
+
+ if (WESTDOOR & flags)
+ drawImage(Path, x - Path->Width, y + offset);
+
+ xx = x + (HRoom->Width - XMark->Width) / 2;
+ xy = y + (HRoom->Height - XMark->Height) / 2;
+
+ break;
+
+ default:
+ return;
+ }
+
+ if (drawx)
+ drawImage(XMark, xx, xy);
+}
+
+
+
+/*****************************************************************************/
+/* Checks if a floor has been visitted. */
+/*****************************************************************************/
+static bool onFloor(LargeSet RoomsFound, uint16 Floor) {
+ uint16 drawroom;
+
+ for (drawroom = 1; drawroom <= MaxRooms; drawroom++) {
+ if ((Maps[drawroom].PageNumber == Floor)
+ && In(RoomsFound, drawroom)
+ && Maps[drawroom].x) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Figures out which floor, if any, should be gone to if the up arrow is hit */
+/*****************************************************************************/
+static void getUpFloor(LargeSet RoomsFound, uint16 *Floor, bool *isfloor) {
+ do {
+ *isfloor = true;
+
+ if (*Floor < UPPERFLOOR)
+ (*Floor)++;
+ else {
+ *Floor = CARNIVAL + 1;
+ *isfloor = false;
+ return;
+ }
+ } while ((!onFloor(RoomsFound, *Floor)) && (*Floor <= CARNIVAL));
+}
+
+
+
+
+/*****************************************************************************/
+/* Figures out which floor, if any, should be gone to if the down arrow is */
+/* hit. */
+/*****************************************************************************/
+static void getDownFloor(LargeSet RoomsFound, uint16 *Floor, bool *isfloor) {
+ do {
+ *isfloor = true;
+
+ if ((*Floor == LOWERFLOOR) || (*Floor == 0)) {
+ *Floor = 0;
+ *isfloor = false;
+ return;
+ } else if (*Floor > UPPERFLOOR) {
+ /* LAB: Labyrinth specific code */
+ if (*Floor == HEDGEMAZEFLOOR)
+ *Floor = UPPERFLOOR;
+ else if ((*Floor == CARNIVAL) || (*Floor == MEDMAZEFLOOR))
+ *Floor = MIDDLEFLOOR;
+ else if (*Floor == SURMAZEFLOOR)
+ *Floor = LOWERFLOOR;
+ else {
+ *Floor = 0;
+ *isfloor = false;
+ return;
+ }
+ } else
+ (*Floor)--;
+
+ } while ((!onFloor(RoomsFound, *Floor)) && *Floor);
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Draws the map */
+/*****************************************************************************/
+static void drawMap(LargeSet RoomsFound, uint16 CurRoom, uint16 CurMsg, uint16 Floor, bool fadeout, bool fadein) {
+ uint16 drawroom;
+ char *sptr;
+
+ uint16 tempfloor;
+ bool noghoast;
+
+ mouseHide();
+
+ if (fadeout)
+ fade(false, 0);
+
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, VGAScreenHeight - 1);
+
+ drawImage(Map, 0, 0);
+ drawGadgetList(MapGadgetList);
+
+ for (drawroom = 1; drawroom <= MaxRooms; drawroom++) {
+ if ((Maps[drawroom].PageNumber == Floor)
+ && In(RoomsFound, drawroom)
+ && Maps[drawroom].x) {
+ drawRoom(drawroom, (bool)(drawroom == CurRoom));
+ g_music->checkMusic();
+ }
+ }
+
+ if ((Maps[CurRoom].PageNumber == Floor) /* Makes sure the X is drawn in corridors */
+ && In(RoomsFound, CurRoom) /* NOTE: this here on purpose just in case there's some wierd condition, like the surreal maze where there are no rooms */
+ && Maps[CurRoom].x)
+ drawRoom(CurRoom, true);
+
+ tempfloor = Floor;
+ getUpFloor(RoomsFound, &tempfloor, &noghoast);
+
+ if (noghoast)
+ unGhoastGadget(&upgadget);
+ else
+ ghoastGadget(&upgadget, 12);
+
+ tempfloor = Floor;
+ getDownFloor(RoomsFound, &tempfloor, &noghoast);
+
+ if (noghoast)
+ unGhoastGadget(&downgadget);
+ else
+ ghoastGadget(&downgadget, 12);
+
+ /* LAB: Labyrinth specific code */
+ if (Floor == LOWERFLOOR) {
+ if (onFloor(RoomsFound, SURMAZEFLOOR))
+ drawImage(Maze, mapScaleX(538), mapScaleY(277));
+ }
+
+ else if (Floor == MIDDLEFLOOR) {
+ if (onFloor(RoomsFound, CARNIVAL))
+ drawImage(Maze, mapScaleX(358), mapScaleY(72));
+
+ if (onFloor(RoomsFound, MEDMAZEFLOOR))
+ drawImage(Maze, mapScaleX(557), mapScaleY(325));
+ }
+
+ else if (Floor == UPPERFLOOR) {
+ if (onFloor(RoomsFound, HEDGEMAZEFLOOR))
+ drawImage(HugeMaze, mapScaleX(524), mapScaleY(97));
+ }
+
+ else if (Floor == SURMAZEFLOOR) {
+ flowText(MsgFont, 0, 7, 0, true, true, true, true, mapScaleX(360), 0, mapScaleX(660), mapScaleY(450), SURMAZEMSG);
+ }
+
+
+ /* LAB: Labyrinth specific code */
+ sptr = NULL;
+
+ switch (Floor) {
+ case LOWERFLOOR:
+ sptr = LOWERFLOORS;
+ break;
+
+ case MIDDLEFLOOR:
+ sptr = MIDDLEFLOORS;
+ break;
+
+ case UPPERFLOOR:
+ sptr = UPPERFLOORS;
+ break;
+
+ case MEDMAZEFLOOR:
+ sptr = MEDMAZEFLOORS;
+ break;
+
+ case HEDGEMAZEFLOOR:
+ sptr = HEDGEMAZEFLOORS;
+ break;
+
+ case SURMAZEFLOOR:
+ sptr = SURMAZEFLOORS;
+ break;
+
+ case CARNIVAL:
+ sptr = CARNIVALFLOOR;
+ break;
+
+ default:
+ sptr = NULL;
+ break;
+ }
+
+ if (sptr)
+ flowText(MsgFont, 0, 5, 3, true, true, true, true, VGAScaleX(14), VGAScaleY(75), VGAScaleX(134), VGAScaleY(97), sptr);
+
+ if ((sptr = Rooms[CurMsg].RoomMsg))
+ flowText(MsgFont, 0, 5, 3, true, true, true, true, VGAScaleX(14), VGAScaleY(148), VGAScaleX(134), VGAScaleY(186), sptr);
+
+ if (fadein)
+ fade(true, 0);
+
+ mouseShow();
+}
+
+
+
+/*****************************************************************************/
+/* Processes the map. */
+/*****************************************************************************/
+void processMap(uint16 CurRoom, LargeSet RoomsFound) {
+ uint32 Class, place = 1;
+ uint16 Code, Qualifier, MouseX, MouseY, GadgetID, CurFloor, OldFloor, OldMsg, CurMsg, drawroom, x1, y1, x2, y2;
+ char *sptr, newcolor[3];
+ bool drawmap;
+ struct IntuiMessage *Msg;
+
+ CurMsg = CurRoom;
+ CurFloor = Maps[CurRoom].PageNumber;
+
+ while (1) {
+ g_music->checkMusic(); /* Make sure we check the music at least after every message */
+ Msg = getMsg();
+
+ if (Msg == NULL) {
+ g_music->newCheckMusic();
+
+ if (place <= 14) {
+ newcolor[0] = 14 << 2;
+ newcolor[1] = place << 2;
+ newcolor[2] = newcolor[1];
+ } else {
+ newcolor[0] = 14 << 2;
+ newcolor[1] = (28 - place) << 2;
+ newcolor[2] = newcolor[1];
+ }
+
+ waitTOF();
+ writeColorReg(newcolor, 1);
+ updateMouse();
+ waitTOF();
+ updateMouse();
+ waitTOF();
+ updateMouse();
+ waitTOF();
+ updateMouse();
+
+ place++;
+
+ if (place >= 28)
+ place = 1;
+
+ } else {
+ Class = Msg->Class;
+ Code = Msg->Code;
+ GadgetID = Msg->GadgetID;
+ Qualifier = Msg->Qualifier;
+ MouseX = Msg->MouseX;
+ MouseY = Msg->MouseY;
+
+ if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
+ ((Class == RAWKEY) && (Code == 27)))
+ return;
+
+ if (Class == GADGETUP) {
+ if (GadgetID == 0) { /* Quit menu button */
+ return;
+ } else if (GadgetID == 1) { /* Up arrow */
+ OldFloor = CurFloor;
+ getUpFloor(RoomsFound, &CurFloor, &drawmap);
+
+ if (drawmap) {
+ fade(false, 0);
+ drawMap(RoomsFound, CurRoom, CurMsg, CurFloor, false, false);
+ fade(true, 0);
+ } else
+ CurFloor = OldFloor;
+ } else if (GadgetID == 2) { /* Down arrow */
+ OldFloor = CurFloor;
+ getDownFloor(RoomsFound, &CurFloor, &drawmap);
+
+ if (drawmap) {
+ fade(false, 0);
+ drawMap(RoomsFound, CurRoom, CurMsg, CurFloor, false, false);
+ fade(true, 0);
+ } else
+ CurFloor = OldFloor;
+ }
+ }
+
+ else if ((Class == MOUSEBUTTONS) && (IEQUALIFIER_LEFTBUTTON & Qualifier)) {
+ if ((CurFloor == LOWERFLOOR) && (MouseX >= mapScaleX(538)) && (MouseY >= mapScaleY(277))
+ && (MouseX <= mapScaleX(633)) && (MouseY <= mapScaleY(352))
+ && onFloor(RoomsFound, SURMAZEFLOOR)) {
+ CurFloor = SURMAZEFLOOR;
+
+ fade(false, 0);
+ drawMap(RoomsFound, CurRoom, CurMsg, CurFloor, false, false);
+ fade(true, 0);
+ }
+
+ else if ((CurFloor == MIDDLEFLOOR) && (MouseX >= mapScaleX(358)) && (MouseY >= mapScaleY(71))
+ && (MouseX <= mapScaleX(452)) && (MouseY <= mapScaleY(147))
+ && onFloor(RoomsFound, CARNIVAL)) {
+ CurFloor = CARNIVAL;
+
+ fade(false, 0);
+ drawMap(RoomsFound, CurRoom, CurMsg, CurFloor, false, false);
+ fade(true, 0);
+ }
+
+ else if ((CurFloor == MIDDLEFLOOR) && (MouseX >= mapScaleX(557)) && (MouseY >= mapScaleY(325))
+ && (MouseX <= mapScaleX(653)) && (MouseY <= mapScaleY(401))
+ && onFloor(RoomsFound, MEDMAZEFLOOR)) {
+ CurFloor = MEDMAZEFLOOR;
+
+ fade(false, 0);
+ drawMap(RoomsFound, CurRoom, CurMsg, CurFloor, false, false);
+ fade(true, 0);
+ }
+
+ else if ((CurFloor == UPPERFLOOR) && (MouseX >= mapScaleX(524)) && (MouseY >= mapScaleY(97))
+ && (MouseX <= mapScaleX(645)) && (MouseY <= mapScaleY(207))
+ && onFloor(RoomsFound, HEDGEMAZEFLOOR)) {
+ CurFloor = HEDGEMAZEFLOOR;
+
+ fade(false, 0);
+ drawMap(RoomsFound, CurRoom, CurMsg, CurFloor, false, false);
+ fade(true, 0);
+ }
+
+ else if (MouseX > mapScaleX(314)) {
+ OldMsg = CurMsg;
+
+ for (drawroom = 1; drawroom <= MaxRooms; drawroom++) {
+ roomCords(drawroom, &x1, &y1, &x2, &y2);
+
+ if ((Maps[drawroom].PageNumber == CurFloor)
+ && In(RoomsFound, drawroom)
+ && (MouseX >= x1) && (MouseX <= x2)
+ && (MouseY >= y1) && (MouseY <= y2)) {
+ CurMsg = drawroom;
+ }
+ }
+
+ if (OldMsg != CurMsg) {
+ if (Rooms[CurMsg].RoomMsg == NULL)
+ readViews(CurMsg, ViewPath);
+
+ if ((sptr = Rooms[CurMsg].RoomMsg)) {
+ mouseHide();
+ setAPen(3);
+ rectFill(VGAScaleX(13), VGAScaleY(148), VGAScaleX(135), VGAScaleY(186));
+ flowText(MsgFont, 0, 5, 3, true, true, true, true, VGAScaleX(14), VGAScaleY(148), VGAScaleX(134), VGAScaleY(186), sptr);
+
+ if (Maps[OldMsg].PageNumber == CurFloor)
+ drawRoom(OldMsg, (bool)(OldMsg == CurRoom));
+
+ roomCords(CurMsg, &x1, &y1, &x2, &y2);
+ x1 = (x1 + x2) / 2;
+ y1 = (y1 + y2) / 2;
+
+ if ((CurMsg != CurRoom) && (Maps[CurMsg].PageNumber == CurFloor)) {
+ setAPen(1);
+ rectFill(x1 - 1, y1, x1, y1);
+ }
+
+ mouseShow();
+ }
+ }
+ }
+ }
+
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ }
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Cleans up behind itself. */
+/*****************************************************************************/
+void mapCleanUp(void) {
+ freeAllStolenMem();
+}
+
+
+
+
+/*****************************************************************************/
+/* Does the map processing. */
+/*****************************************************************************/
+void doMap(LargeSet RoomsFound, uint16 CurRoom) {
+ FadePalette = AmigaMapPalette;
+
+ g_music->checkMusic();
+ loadMapData();
+ blackAllScreen();
+
+ if (Direction == NORTH)
+ XMark = MapNorth;
+ else if (Direction == SOUTH)
+ XMark = MapSouth;
+ else if (Direction == EAST)
+ XMark = MapEast;
+ else if (Direction == WEST)
+ XMark = MapWest;
+
+ drawMap(RoomsFound, CurRoom, CurRoom, Maps[CurRoom].PageNumber, false, true);
+ mouseShow();
+ attachGadgetList(MapGadgetList);
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ processMap(CurRoom, RoomsFound);
+ attachGadgetList(NULL);
+ fade(false, 0);
+ blackAllScreen();
+ mouseHide();
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, VGAScreenHeight - 1);
+ mapCleanUp();
+ blackAllScreen();
+ mouseShow();
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/modernsavegame.cpp b/engines/lab/modernsavegame.cpp
new file mode 100644
index 0000000000..2ea5c22911
--- /dev/null
+++ b/engines/lab/modernsavegame.cpp
@@ -0,0 +1,127 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/labfun.h"
+#include "lab/modernsavegame.h"
+
+namespace Lab {
+
+byte g_SaveGameImage[SAVED_IMAGE_SIZE]; // 640 x 358
+
+char g_SaveGamePath[512];
+char g_PathSeperator[4];
+
+extern LargeSet Conditions,
+ RoomsFound;
+
+#define SAVEVERSION "LBS3"
+
+int getSaveGameList(struct SaveGameInfo *info, int maxNum) {
+ warning("STUB: getSaveGameList");
+
+ return 0;
+
+#if 0
+ char path[512];
+ struct stat statb;
+ int total = 0;
+ int i;
+
+ for (i = 0; i < maxNum; i++) {
+ checkMusic();
+
+ sprintf(path, "%s%s%d", g_SaveGamePath, g_PathSeperator, i);
+ statb.st_size = 0;
+ stat(path, &statb);
+
+ if (statb.st_size > 0) {
+ struct tm *create_date;
+ FILE *fh;
+
+ create_date = localtime(&statb.st_ctime);
+ strcpy(info->SaveGameDate, asctime(create_date));
+
+ fh = fopen(path, "rb");
+
+ if (fh != NULL) {
+ char temp[5];
+ unsigned short t;
+ int toSeek;
+
+ info->Index = i;
+
+ fread(temp, 1, 4, fh);
+ temp[4] = 0;
+
+ fread(&t, 1, 2, fh);
+ info->RoomNumber = swapUShort(t);
+ fread(&t, 1, 2, fh);
+ info->Direction = swapUShort(t);
+
+ toSeek = 2 + Conditions->lastElement / 8 + RoomsFound->lastElement / 8 + 6 + 2 * 16;
+ fseek(fh, toSeek, SEEK_CUR);
+
+ info->SaveGameImage = NULL;
+
+ if (strcmp(temp, SAVEVERSION) == 0) {
+ info->SaveGameImage = malloc(SAVED_IMAGE_SIZE);
+
+ if (info->SaveGameImage != NULL)
+ fread(info->SaveGameImage, 1, SAVED_IMAGE_SIZE, fh);
+ } else {
+ info->SaveGameImage = malloc(SAVED_IMAGE_SIZE);
+
+ if (info->SaveGameImage != NULL)
+ memset(info->SaveGameImage, 0, SAVED_IMAGE_SIZE);
+ }
+
+ fclose(fh);
+
+ info++;
+ total++;
+ }
+ }
+ }
+
+ return total;
+#endif
+}
+
+void freeSaveGameList(struct SaveGameInfo *info, int count) {
+ int i;
+
+ for (i = 0; i < count; i++) {
+ free(info->SaveGameImage);
+ ++info;
+ }
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/modernsavegame.h b/engines/lab/modernsavegame.h
new file mode 100644
index 0000000000..160f3f9619
--- /dev/null
+++ b/engines/lab/modernsavegame.h
@@ -0,0 +1,55 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#ifndef LAB_MODERNGAMESAVE_H
+#define LAB_MODERNGAMESAVE_H
+
+namespace Lab {
+
+#define MAX_SAVED_GAMES 15
+#define SAVED_IMAGE_SIZE (128 * 72)
+
+extern byte g_SaveGameImage[SAVED_IMAGE_SIZE]; // 640 x 358
+
+struct SaveGameInfo {
+ unsigned short Index;
+ unsigned short RoomNumber;
+ unsigned short Direction;
+ byte *SaveGameImage;
+ char SaveGameDate[128];
+};
+
+int getSaveGameList(struct SaveGameInfo *info, int maxNum);
+void freeSaveGameList(struct SaveGameInfo *info, int count);
+
+} // End of namespace Lab
+
+#endif /* LAB_MODERNGAMESAVE_H */
+
diff --git a/engines/lab/module.mk b/engines/lab/module.mk
new file mode 100644
index 0000000000..5edaa78fd9
--- /dev/null
+++ b/engines/lab/module.mk
@@ -0,0 +1,40 @@
+MODULE := engines/lab
+
+MODULE_OBJS := \
+ allocroom.o \
+ audioi.o \
+ detection.o \
+ engine.o \
+ graphics.o \
+ interface.o \
+ intro.o \
+ lab.o \
+ labfile.o \
+ labmusic.o \
+ labsets.o \
+ labtext.o \
+ machine.o \
+ map.o \
+ modernsavegame.o \
+ mouse.o \
+ processroom.o \
+ readdiff.o \
+ readparse.o \
+ savegame.o \
+ savegamepalmap.o \
+ special.o \
+ storage.o \
+ text.o \
+ timing.o \
+ undiff.o \
+ vga.o
+
+
+# This module can be built as a plugin
+ifeq ($(ENABLE_LAB), DYNAMIC_PLUGIN)
+PLUGIN := 1
+endif
+
+# Include common rules
+include $(srcdir)/rules.mk
+
diff --git a/engines/lab/mouse.cpp b/engines/lab/mouse.cpp
new file mode 100644
index 0000000000..857a39726e
--- /dev/null
+++ b/engines/lab/mouse.cpp
@@ -0,0 +1,569 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/mouse.h"
+#include "lab/vga.h"
+#include "lab/stddefines.h"
+#include "lab/timing.h"
+#include "lab/interface.h"
+
+namespace Lab {
+
+extern bool IsHiRes;
+extern uint32 VGAScreenWidth, VGAScreenHeight;
+
+void mouseHideXY(void);
+
+#if defined(DOSCODE)
+/*****************************************************************************/
+/* Standard mouse calling template. */
+/*****************************************************************************/
+static void mouse(int16 *m1, int16 *m2, int16 *m3, int16 *m4) {
+ union REGS reg;
+
+ reg.w.ax = *m1;
+ reg.w.bx = *m2;
+ reg.w.cx = *m3;
+ reg.w.dx = *m4;
+
+ int386(0x33, &reg, &reg);
+
+ *m1 = reg.w.ax;
+ *m2 = reg.w.bx;
+ *m3 = reg.w.cx;
+ *m4 = reg.w.dx;
+}
+#endif
+
+
+static bool LeftClick = false;
+static uint16 leftx = 0, lefty = 0;
+static bool RightClick = false;
+static uint16 rightx = 0, righty = 0;
+
+static bool MouseHidden = true, QuitMouseHandler = false;
+static int32 NumHidden = 1;
+static uint16 CurMouseX, CurMouseY;
+static uint16 MouseImageWidth = 10, MouseImageHeight = 15;
+static struct Gadget *LastGadgetHit = NULL;
+struct Gadget *ScreenGadgetList = NULL;
+static byte MouseData[] = {1, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+ 1, 7, 1, 0, 0, 0, 0, 0, 0, 0,
+ 1, 7, 7, 1, 0, 0, 0, 0, 0, 0,
+ 1, 7, 7, 7, 1, 0, 0, 0, 0, 0,
+ 1, 7, 7, 7, 7, 1, 0, 0, 0, 0,
+ 1, 7, 7, 7, 7, 7, 1, 0, 0, 0,
+ 1, 7, 7, 7, 7, 7, 7, 1, 0, 0,
+ 1, 7, 7, 7, 7, 7, 7, 7, 1, 0,
+ 1, 7, 7, 7, 7, 7, 1, 1, 1, 1,
+ 1, 7, 7, 1, 7, 7, 1, 0, 0, 0,
+ 1, 7, 1, 0, 1, 7, 7, 1, 0, 0,
+ 1, 1, 0, 0, 1, 7, 7, 1, 0, 0,
+ 0, 0, 0, 0, 0, 1, 7, 7, 1, 0,
+ 0, 0, 0, 0, 0, 1, 7, 7, 1, 0,
+ 0, 0, 0, 0, 0, 0, 1, 1, 0, 0};
+
+
+static struct Image MouseImage, BackImage;
+static byte BackImageBuffer[256];
+static uint16 backx, backy;
+
+static bool drawmouse = false, gadhit = false;
+static struct Gadget *hitgad = NULL;
+
+void mouseShowXY(uint16 CurMouseX, uint16 CurMouseY);
+
+/*****************************************************************************/
+/* Checks whether or not the cords fall within one of the gadgets in a list */
+/* of gadgets. */
+/*****************************************************************************/
+static Gadget *checkGadgetHit(struct Gadget *gadlist, uint16 x, uint16 y) {
+ uint16 counter;
+
+ while (gadlist != NULL) {
+ if ((x >= gadlist->x) && (y >= gadlist->y) &&
+ (x <= (gadlist->x + gadlist->Im->Width)) &&
+ (y <= (gadlist->y + gadlist->Im->Height)) &&
+ !(GADGETOFF & gadlist->GadgetFlags)) {
+ if (IsHiRes) {
+ gadhit = true;
+ hitgad = gadlist;
+ } else {
+ QuitMouseHandler = true;
+ VGAStorePage();
+ mouseHideXY();
+ drawImage(gadlist->ImAlt, gadlist->x, gadlist->y);
+ mouseShowXY(x, y);
+
+ for (counter = 0; counter < 3; counter++)
+ waitTOF();
+
+ mouseHideXY();
+ drawImage(gadlist->Im, gadlist->x, gadlist->y);
+ mouseShowXY(x, y);
+ VGARestorePage();
+ QuitMouseHandler = false;
+ }
+
+ return gadlist;
+ } else {
+ gadlist = gadlist->NextGadget;
+ }
+ }
+
+ return NULL;
+}
+
+
+
+void attachGadgetList(struct Gadget *GadList) {
+ if (ScreenGadgetList != GadList)
+ LastGadgetHit = NULL;
+
+ ScreenGadgetList = GadList;
+}
+
+
+
+
+static void drawMouse(void) {
+ if (BackImage.ImageData) {
+#if !defined(DOSCODE)
+
+ if (backx <= 640 - BackImage.Width && backy <= 480 - BackImage.Height)
+#endif
+ drawMaskImage(&MouseImage, backx, backy);
+ } else {
+#if !defined(DOSCODE)
+
+ if (CurMouseX <= 640 - MouseImage.Width && CurMouseY <= 480 - MouseImage.Height)
+#endif
+ drawMaskImage(&MouseImage, CurMouseX, CurMouseY);
+ }
+}
+
+
+
+static void getBackMouse(void) {
+ BackImage.Width = MouseImage.Width;
+ BackImage.Height = MouseImage.Height;
+ BackImage.ImageData = BackImageBuffer;
+
+ backx = CurMouseX;
+ backy = CurMouseY;
+
+#if !defined(DOSCODE)
+
+ if (/* backx >= 0 && backy >= 0 && */ backx <= 640 - BackImage.Width && backy <= 480 - BackImage.Height)
+#endif
+ readScreenImage(&BackImage, backx, backy);
+}
+
+static void restoreBackMouse(void) {
+ if (BackImage.ImageData) {
+#if !defined(DOSCODE)
+
+ if (/* backx >= 0 && backy >= 0 && */ backx <= 640 - BackImage.Width && backy <= 480 - BackImage.Height)
+#endif
+ drawImage(&BackImage, backx, backy);
+
+ BackImage.ImageData = NULL;
+ }
+}
+
+
+static struct Gadget *TempGad;
+
+
+#if defined(DOSCODE)
+#pragma off (check_stack)
+void _loadds far mouse_handler(int32 max, int32 mcx, int32 mdx) {
+#pragma aux mouse_handler parm [EAX] [ECX] [EDX]
+#else
+void mouse_handler(int32 max, int32 mcx, int32 mdx) {
+#endif
+
+ if (!IsHiRes)
+ mcx /= 2;
+
+ if (max & 0x01) { /* mouse Move */
+ if ((CurMouseX != mcx) || (CurMouseY != mdx)) {
+ CurMouseX = mcx;
+ CurMouseY = mdx;
+
+ if (IsHiRes && !QuitMouseHandler) {
+ drawmouse = true;
+ } else if (!MouseHidden && !QuitMouseHandler) {
+ VGAStorePage();
+ restoreBackMouse();
+ getBackMouse();
+ drawMouse();
+ VGARestorePage();
+ }
+ }
+ }
+
+ if ((max & 0x02) && (NumHidden < 2)) { /* Left mouse button click */
+ if (ScreenGadgetList)
+ TempGad = checkGadgetHit(ScreenGadgetList, mcx, mdx);
+ else
+ TempGad = NULL;
+
+ if (TempGad) {
+ LastGadgetHit = TempGad;
+ } else {
+ LeftClick = true;
+ leftx = mcx;
+ lefty = mdx;
+ }
+ }
+
+ if ((max & 0x08) && (NumHidden < 2)) { /* Right mouse button click */
+ RightClick = true;
+ rightx = mcx;
+ righty = mdx;
+ }
+}
+
+
+
+
+void updateMouse(void) {
+ uint16 counter;
+#if !defined(DOSCODE)
+ bool doUpdateDisplay = false;
+#endif
+
+ if (drawmouse && !MouseHidden) {
+ QuitMouseHandler = true;
+ drawmouse = false;
+ restoreBackMouse();
+ getBackMouse();
+ drawMouse();
+ QuitMouseHandler = false;
+#if !defined(DOSCODE)
+ doUpdateDisplay = true;
+#endif
+ }
+
+ if (gadhit) {
+ gadhit = false;
+ QuitMouseHandler = true;
+ mouseHide();
+ drawImage(hitgad->ImAlt, hitgad->x, hitgad->y);
+ mouseShow();
+
+ for (counter = 0; counter < 3; counter++)
+ waitTOF();
+
+ mouseHide();
+ drawImage(hitgad->Im, hitgad->x, hitgad->y);
+ mouseShow();
+#if !defined(DOSCODE)
+ doUpdateDisplay = true;
+#endif
+ QuitMouseHandler = false;
+ }
+
+#if !defined(DOSCODE)
+
+ if (doUpdateDisplay)
+ g_system->updateScreen();
+
+#endif
+}
+
+
+
+
+/*****************************************************************************/
+/* Initializes the mouse. */
+/*****************************************************************************/
+bool initMouse(void) {
+#if defined(DOSCODE)
+ void (interrupt far * int_handler)();
+ int32 vector;
+ byte firstbyte;
+ struct SREGS sregs;
+ union REGS inregs, outregs;
+ int (far * function_ptr)();
+ int16 m1, m2, m3, m4;
+
+ segread(&sregs);
+
+ /* Determine mouse-driver interrupt address */
+ int_handler = _dos_getvect(0x33); /* Get interrupt vector */
+ firstbyte = *(byte far *) int_handler; /* Get first instruction of interrupt */
+ vector = (int32) int_handler;
+
+ if ((vector == 0L) || (firstbyte == 0xcf)) { /* Vector should not be zero */
+ /* First instruction should not be iret */
+ return false;
+ }
+
+ m1 = 0;
+ mouse(&m1, &m2, &m3, &m4);
+
+ if (m1 != -1)
+ return false;
+
+ m1 = 0x0f;
+ m3 = 3;
+ m4 = 10;
+ mouse(&m1, &m2, &m3, &m4);
+
+ m1 = 0x07;
+ m3 = 0;
+ m4 = VGAScreenWidth - MouseImageWidth;
+
+ if (!IsHiRes) m4 *= 2;
+
+ mouse(&m1, &m2, &m3, &m4);
+
+ m1 = 0x08;
+ m3 = 0;
+ m4 = VGAScreenHeight - MouseImageHeight;
+ mouse(&m1, &m2, &m3, &m4);
+#endif
+
+ BackImage.ImageData = NULL;
+ MouseImage.ImageData = MouseData;
+ MouseImage.Width = MouseImageWidth;
+ MouseImage.Height = MouseImageHeight;
+
+ mouseMove(0, 0);
+
+#if defined(DOSCODE)
+
+ if (IsHiRes) {
+ m1 = 0x0f;
+ m3 = 0x03;
+ m4 = 0x04;
+ mouse(&m1, &m2, &m3, &m4);
+ }
+
+ inregs.w.ax = 0xc;
+ inregs.w.cx = 0x01 + 0x02 + 0x08; /* mouse move, left and right mouse clicks */
+ function_ptr = mouse_handler;
+ inregs.x.edx = FP_OFF(function_ptr);
+ sregs.es = FP_SEG(function_ptr);
+ int386x(0x33, &inregs, &outregs, &sregs);
+
+ /* mouse reset and status */
+ return mouseReset();
+#endif
+
+ return true;
+}
+
+
+
+/*****************************************************************************/
+/* Resets the mouse. */
+/*****************************************************************************/
+bool mouseReset(void) {
+#if defined(DOSCODE)
+ int16 m1 = 0, dum;
+
+ mouse(&m1, &dum, &dum, &dum);
+ return (m1 == -1);
+#else
+ return true;
+#endif
+}
+
+
+
+/*****************************************************************************/
+/* Shows the mouse. */
+/*****************************************************************************/
+void mouseShow(void) {
+ QuitMouseHandler = true;
+ VGAStorePage();
+ mouseShowXY(CurMouseX, CurMouseY);
+ VGARestorePage();
+ QuitMouseHandler = false;
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Shows the mouse. */
+/*****************************************************************************/
+void mouseShowXY(uint16 MouseX, uint16 MouseY) {
+ QuitMouseHandler = true;
+
+ if (NumHidden)
+ NumHidden--;
+
+ if ((NumHidden == 0) && MouseHidden) {
+ CurMouseX = MouseX;
+ CurMouseY = MouseY;
+ getBackMouse();
+ drawMouse();
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ MouseHidden = false;
+ }
+
+ QuitMouseHandler = false;
+}
+
+
+
+/*****************************************************************************/
+/* Hides the mouse. */
+/*****************************************************************************/
+void mouseHide(void) {
+ QuitMouseHandler = true;
+
+ NumHidden++;
+
+ if (NumHidden && !MouseHidden) {
+ MouseHidden = true;
+ VGAStorePage();
+ restoreBackMouse();
+ VGARestorePage();
+ }
+
+ QuitMouseHandler = false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Hides the mouse. */
+/*****************************************************************************/
+void mouseHideXY(void) {
+ QuitMouseHandler = true;
+
+ NumHidden++;
+
+ if (NumHidden && !MouseHidden) {
+ MouseHidden = true;
+ restoreBackMouse();
+ }
+
+ QuitMouseHandler = false;
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Gets the current mouse co-ordinates. NOTE: On IBM version, will scale */
+/* from virtual to screen co-ordinates automatically. */
+/*****************************************************************************/
+void mouseXY(uint16 *x, uint16 *y) {
+ int xx = 0, yy = 0;
+ //SDL_GetMousePos(&xx, &yy);
+ warning("STUB: mouseXY");
+ *x = (uint16)xx;
+ *y = (uint16)yy;
+
+ if (!IsHiRes)
+ (*x) /= 2;
+}
+
+
+
+
+/*****************************************************************************/
+/* Moves the mouse to new co-ordinates. */
+/*****************************************************************************/
+void mouseMove(uint16 x, uint16 y) {
+#if defined(DOSCODE)
+ int16 m1 = 4, dum;
+#endif
+
+ if (!IsHiRes)
+ x *= 2;
+
+ g_system->warpMouse(x, y);
+
+ if (!MouseHidden) {
+ QuitMouseHandler = true;
+ mouseXY(&CurMouseX, &CurMouseY);
+ VGAStorePage();
+ restoreBackMouse();
+ getBackMouse();
+ drawMouse();
+ VGARestorePage();
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+ QuitMouseHandler = false;
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Checks whether or not the mouse buttons have been pressed, and the last */
+/* co-ordinates of the button press. leftbutton tells whether to check the */
+/* left or right button. */
+/*****************************************************************************/
+bool mouseButton(uint16 *x, uint16 *y, bool leftbutton) {
+ if (leftbutton) {
+ if (LeftClick) {
+ *x = leftx;
+ *y = lefty;
+ LeftClick = false;
+ return true;
+ }
+ } else {
+ if (RightClick) {
+ *x = rightx;
+ *y = righty;
+ RightClick = false;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+
+
+Gadget *mouseGadget(void) {
+ Gadget *Temp = LastGadgetHit;
+
+ LastGadgetHit = NULL;
+ return Temp;
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/mouse.h b/engines/lab/mouse.h
new file mode 100644
index 0000000000..e8bc7bfb7c
--- /dev/null
+++ b/engines/lab/mouse.h
@@ -0,0 +1,62 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+
+#ifndef LAB_MOUSE_H
+#define LAB_MOUSE_H
+
+namespace Lab {
+
+struct Gadget;
+
+bool initMouse(void);
+
+bool mouseReset(void);
+
+void updateMouse(void);
+
+void mouseShow(void);
+
+void mouseHide(void);
+
+void mouseXY(uint16 *x, uint16 *y);
+
+void mouseMove(uint16 x, uint16 y);
+
+bool mouseButton(uint16 *x, uint16 *y, bool leftbutton);
+
+Gadget *mouseGadget(void);
+
+void attachGadgetList(struct Gadget *GadList);
+
+} // End of namespace Lab
+
+#endif /* LAB_MOUSE_H */
diff --git a/engines/lab/parsefun.h b/engines/lab/parsefun.h
new file mode 100644
index 0000000000..4e1dc5de7e
--- /dev/null
+++ b/engines/lab/parsefun.h
@@ -0,0 +1,101 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#ifndef LAB_PARSEFUN_H
+#define LAB_PARSEFUN_H
+
+#include "lab/stddefines.h"
+#include "lab/labfun.h"
+#include "lab/parsetypes.h"
+
+namespace Lab {
+
+/* From Parser.c */
+
+bool parse(const char *InputFile);
+
+
+/* From allocRoom.c */
+
+bool initRoomBuffer(void);
+
+void freeRoomBuffer(void);
+
+void allocRoom(void **Ptr, uint16 Size, uint16 RoomNum);
+
+/* From ReadParse.c */
+
+bool readRoomData(const char *fileName);
+
+bool readInventory(const char *fileName);
+
+char *numtostr(char *text, uint16 Num);
+
+bool readViews(uint16 RoomNum, const char *Path);
+
+bool readInitialConditions(LargeSet Conditions, const char *fileName);
+
+
+
+/* From ProcessRoom.c */
+
+ViewDataPtr getViewData(uint16 RoomNum, uint16 Direction);
+
+char *getPictName(CloseDataPtr *LCPtr);
+
+void drawDirection(CloseDataPtr LCPtr);
+
+bool processArrow(uint16 *Direction, uint16 Arrow);
+
+void setCurCloseAbs(uint16 x, uint16 y, CloseDataPtr *cptr);
+
+void setCurClose(uint16 x, uint16 y, CloseDataPtr *cptr);
+
+bool takeItem(uint16 x, uint16 y, CloseDataPtr *cptr);
+
+bool doActionRule(int16 x, int16 y, int16 Action, int16 RoomNum, CloseDataPtr *LCPtr);
+
+bool doOperateRule(int16 x, int16 y, int16 ItemNum, CloseDataPtr *LCPtr);
+
+bool doGoForward(CloseDataPtr *LCPtr);
+
+bool doTurn(uint16 from, uint16 to, CloseDataPtr *LCPtr);
+
+bool doMainView(CloseDataPtr *LCPtr);
+
+/*
+ bool doConditions(int16 x,
+ int16 y,
+ CloseDataPtr *LCPtr);
+ */
+
+} // End of namespace Lab
+
+#endif /* LAB_PARSEFUN_H */
diff --git a/engines/lab/parsetypes.h b/engines/lab/parsetypes.h
new file mode 100644
index 0000000000..defe9afddf
--- /dev/null
+++ b/engines/lab/parsetypes.h
@@ -0,0 +1,237 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#ifndef LAB_PARSETYPES_H
+#define LAB_PARSETYPES_H
+
+namespace Lab {
+
+#define MAXFILELEN 31
+
+
+
+/*------------------------------- Action types ------------------------------*/
+#define PLAYSOUND 1
+#define PLAYSOUNDCONT 2
+#define SHOWDIFF 3
+#define SHOWDIFFCONT 4
+#define LOADDIFF 5
+#define LOADBM 6
+#define SHOWBM 7
+#define WIPECMD 8
+#define NOUPDATE 9
+#define FORCEUPDATE 10
+#define SHOWCURPICT 11
+#define SETELEMENT 12
+#define UNSETELEMENT 13
+#define SHOWMESSAGE 14
+#define SHOWMESSAGES 15
+#define SETPOSITION 16
+#define SETCLOSEUP 17
+#define MAINVIEW 18
+#define SUBINV 19
+#define ADDINV 20
+#define SHOWDIR 21
+#define WAITSECS 22
+#define STOPMUSIC 23
+#define STARTMUSIC 24
+#define CHANGEMUSIC 25
+#define RESETMUSIC 26
+#define FILLMUSIC 27
+#define WAITSOUND 28
+#define CLEARSOUND 29
+#define WINMUSIC 30
+#define WINGAME 31
+#define LOSTGAME 32
+#define RESETBUFFER 33
+#define SPECIALCMD 34
+#define CSHOWMESSAGE 35
+#define PLAYSOUNDB 36
+
+
+
+/* Rule Types */
+#define ACTION 1
+#define OPERATE 2
+#define GOFORWARD 3
+#define CONDITIONS 4
+#define TURN 5
+#define GOMAINVIEW 6
+#define TURNFROMTO 7
+
+
+
+/*----------------------------- Rule Type Action ----------------------------*/
+#define TAKE 1
+#define MOVE 2
+#define OPENDOOR 3
+#define CLOSEDOOR 4
+#define TAKEDEF 5
+
+#if defined(WIN32)
+#pragma pack(push, 1)
+#endif
+
+typedef struct closeData {
+ uint16 x1, y1, x2, y2;
+ int16 CloseUpType; /* if > 0, an object. If < 0,
+ an item */
+ uint16 depth; /* Level of the closeup. */
+ char *GraphicName, *Message;
+ struct closeData *NextCloseUp, *SubCloseUps;
+} CloseData;
+
+typedef CloseData *CloseDataPtr;
+
+
+
+typedef struct viewData {
+ int16 *Condition;
+ char *GraphicName;
+ struct viewData *NextCondition;
+ CloseDataPtr closeUps;
+
+} viewData;
+
+typedef viewData *ViewDataPtr;
+
+
+struct Action {
+ int16 ActionType, Param1, Param2, Param3;
+ byte *Data; /* Message, or a pointer to array
+ of messages. */
+ Action *NextAction;
+
+};
+
+typedef Action *ActionPtr;
+
+
+
+typedef struct rule {
+ int16 RuleType, Param1, Param2, *Condition;
+
+ ActionPtr ActionList;
+ struct rule *NextRule;
+
+} Rule;
+
+typedef Rule *RulePtr;
+
+
+
+typedef struct {
+ uint16 NorthDoor, SouthDoor, EastDoor, WestDoor;
+
+ byte WipeType;
+
+ ViewDataPtr NorthView, SouthView, EastView, WestView;
+ RulePtr RuleList;
+ char *RoomMsg;
+
+} RoomData;
+
+
+
+typedef struct inventoryData {
+ /* New inventory stuff */
+ /*
+ int16 *Condition;
+ char *GraphicName,
+ * InvName;
+ struct inventoryData *NextInventory;
+ CloseDataPtr closeUps;
+ RulePtr RuleList;
+ */
+
+ /* Old inventory stuff */
+ uint16 Many;
+ char *name, *BInvName;
+} InventoryData;
+
+
+
+/* Map Flags */
+
+/* Where the doors are; in a corridor, assumed to be left doors */
+#define NORTHDOOR 1L
+#define EASTDOOR 2L
+#define SOUTHDOOR 4L
+#define WESTDOOR 8L
+
+/* Where the doors are in corridors; M means middle, R means right, B means bottom */
+#define NORTHMDOOR 16L
+#define NORTHRDOOR 32L
+#define SOUTHMDOOR 64L
+#define SOUTHRDOOR 128L
+
+#define EASTMDOOR 16L
+#define EASTBDOOR 32L
+#define WESTMDOOR 64L
+#define WESTBDOOR 128L
+
+/* Special Map ID's */
+#define NORMAL 0
+#define UPARROWROOM 1
+#define DOWNARROWROOM 2
+#define BRIDGEROOM 3
+#define VCORRIDOR 4
+#define HCORRIDOR 5
+#define MEDMAZE 6
+#define HEDGEMAZE 7
+#define SURMAZE 8
+#define MULTIMAZEF1 9
+#define MULTIMAZEF2 10
+#define MULTIMAZEF3 11
+
+
+
+typedef struct {
+ uint16 x, y, PageNumber, SpecialID;
+ uint32 MapFlags;
+
+} MapData;
+
+#if defined(WIN32)
+#pragma pack(pop)
+#endif
+
+#if !defined(DOSCODE)
+typedef struct {
+ uint16 RoomNum;
+ uint16 Direction;
+} CrumbData;
+
+#define MAX_CRUMBS 128
+#endif
+
+} // End of namespace Lab
+
+#endif /* LAB_PARSETYPES_H */
diff --git a/engines/lab/processroom.cpp b/engines/lab/processroom.cpp
new file mode 100644
index 0000000000..2af9fa05d9
--- /dev/null
+++ b/engines/lab/processroom.cpp
@@ -0,0 +1,1056 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/labfun.h"
+#include "lab/parsetypes.h"
+#include "lab/parsefun.h"
+#include "lab/timing.h"
+#include "lab/diff.h"
+#include "lab/vga.h"
+#if !defined(DOSCODE)
+#include "lab/interface.h"
+#endif
+
+namespace Lab {
+
+#ifdef GAME_TRIAL
+extern int g_IsRegistered;
+#endif
+
+
+/* Global parser data */
+
+RoomData *Rooms;
+InventoryData *Inventory;
+uint16 NumInv, RoomNum, ManyRooms, HighestCondition, Direction;
+LargeSet Conditions, RoomsFound;
+
+
+extern char *FACINGNORTH, *FACINGEAST, *FACINGSOUTH, *FACINGWEST;
+extern bool LongWinInFront;
+
+
+#define NOFILE "no file"
+
+
+
+extern const char *CurFileName;
+
+const char *ViewPath = "LAB:Rooms/";
+
+
+const char *NewFileName;
+
+
+extern bool DoNotDrawMessage;
+extern bool NoFlip, IsBM, noupdatediff, waiteffect, mwaiteffect, QuitLab, EffectPlaying, soundplaying, MusicOn, DoBlack, ContMusic, DoNotReset;
+extern char diffcmap[256 * 3];
+
+extern CloseDataPtr CPtr;
+
+
+
+/*****************************************************************************/
+/* Generates a random number. */
+/*****************************************************************************/
+uint16 getRandom(uint16 max) {
+ uint32 secs, micros;
+
+ getTime(&secs, &micros);
+ return ((micros + secs) % max);
+}
+
+
+
+
+/*****************************************************************************/
+/* Checks whether all the conditions in a condition list are met. */
+/*****************************************************************************/
+static bool checkConditions(int16 *Condition) {
+ int16 Counter;
+ bool res;
+
+ if (Condition == NULL)
+ return true;
+
+ if (Condition[0] == 0)
+ return true;
+
+ Counter = 1;
+ res = In(Conditions, Condition[0]);
+
+ while (Condition[Counter] && res) {
+ res = In(Conditions, Condition[Counter]);
+ Counter++;
+ }
+
+ return res;
+}
+
+
+
+
+/*****************************************************************************/
+/* Gets the current ViewDataPointer. */
+/*****************************************************************************/
+ViewDataPtr getViewData(uint16 roomNum, uint16 direction) {
+ ViewDataPtr *VPtr = NULL, ViewPtr;
+ bool doit = true;
+
+ if (direction == NORTH)
+ VPtr = &Rooms[roomNum].NorthView;
+ else if (direction == SOUTH)
+ VPtr = &Rooms[roomNum].SouthView;
+ else if (direction == EAST)
+ VPtr = &Rooms[roomNum].EastView;
+ else if (direction == WEST)
+ VPtr = &Rooms[roomNum].WestView;
+
+ if (*VPtr == NULL)
+ readViews(roomNum, ViewPath);
+
+ ViewPtr = *VPtr;
+
+ do {
+ if (checkConditions(ViewPtr->Condition))
+ doit = false;
+ else
+ ViewPtr = ViewPtr->NextCondition;
+
+ } while (doit);
+
+ return ViewPtr;
+}
+
+
+
+/*****************************************************************************/
+/* Gets an object, if any, from the user's click on the screen. */
+/*****************************************************************************/
+static CloseData *getObject(uint16 x, uint16 y, CloseDataPtr LCPtr) {
+ ViewDataPtr VPtr;
+
+ if (LCPtr == NULL) {
+ VPtr = getViewData(RoomNum, Direction);
+ LCPtr = VPtr->closeUps;
+ }
+
+ else
+ LCPtr = LCPtr->SubCloseUps;
+
+
+ while (LCPtr != NULL) {
+ if ((x >= scaleX(LCPtr->x1)) && (y >= scaleY(LCPtr->y1)) &&
+ (x <= scaleX(LCPtr->x2)) && (y <= scaleY(LCPtr->y2)))
+ return LCPtr;
+
+ LCPtr = LCPtr->NextCloseUp;
+ }
+
+ return NULL;
+}
+
+
+
+
+/*****************************************************************************/
+/* Goes through the list of closeups to find a match. */
+/* NYI: Known bug here. If there are two objects that have closeups, and */
+/* some of the closeups have the same hit boxes, then this returns the */
+/* first occurence of the object with the same hit box. */
+/*****************************************************************************/
+static CloseDataPtr findCPtrMatch(CloseDataPtr Main, CloseDataPtr List) {
+ CloseDataPtr cptr;
+
+ while (List) {
+ if ((Main->x1 == List->x1) && (Main->x2 == List->x2) &&
+ (Main->y1 == List->y1) && (Main->y2 == List->y2) &&
+ (Main->depth == List->depth))
+ return List;
+
+ cptr = findCPtrMatch(Main, List->SubCloseUps);
+
+ if (cptr)
+ return cptr;
+ else
+ List = List->NextCloseUp;
+ }
+
+ return NULL;
+}
+
+
+
+
+
+
+/*****************************************************************************/
+/* Returns the current picture name. */
+/*****************************************************************************/
+char *getPictName(CloseDataPtr *LCPtr) {
+ ViewDataPtr ViewPtr;
+
+ ViewPtr = getViewData(RoomNum, Direction);
+
+ if (*LCPtr != NULL) {
+ *LCPtr = findCPtrMatch(*LCPtr, ViewPtr->closeUps);
+
+ if (*LCPtr)
+ return (*LCPtr)->GraphicName;
+ }
+
+ return ViewPtr->GraphicName;
+}
+
+
+/*****************************************************************************/
+/* Draws the current direction to the screen. */
+/*****************************************************************************/
+void drawDirection(CloseDataPtr LCPtr) {
+ char Message[250];
+ /*
+ char test[15];
+ */
+
+ if (LCPtr != NULL) {
+ if (LCPtr->Message) {
+ drawMessage(LCPtr->Message);
+ return;
+ }
+ }
+
+
+ Message[0] = '\0';
+
+ if (Rooms[RoomNum].RoomMsg) {
+ strcpy(Message, Rooms[RoomNum].RoomMsg);
+ strcat(Message, ", ");
+ }
+
+ if (Direction == NORTH)
+ strcat(Message, FACINGNORTH);
+ else if (Direction == EAST)
+ strcat(Message, FACINGEAST);
+ else if (Direction == SOUTH)
+ strcat(Message, FACINGSOUTH);
+ else if (Direction == WEST)
+ strcat(Message, FACINGWEST);
+
+ /*
+ numtostr(test, RoomNum);
+ strcat(Message, ", ");
+ strcat(Message, test);
+ */
+
+ drawMessage(Message);
+}
+
+#if !defined(DOSCODE)
+void getRoomMessage(int MyRoomNum, int MyDirection, char *msg) {
+ getViewData(MyRoomNum, MyDirection);
+
+ msg[0] = '\0';
+
+ if (Rooms[MyRoomNum].RoomMsg) {
+ strcpy(msg, Rooms[MyRoomNum].RoomMsg);
+ strcat(msg, ", ");
+ }
+
+ if (MyDirection == NORTH)
+ strcat(msg, FACINGNORTH);
+ else if (MyDirection == EAST)
+ strcat(msg, FACINGEAST);
+ else if (MyDirection == SOUTH)
+ strcat(msg, FACINGSOUTH);
+ else if (MyDirection == WEST)
+ strcat(msg, FACINGWEST);
+}
+#endif
+
+
+
+
+
+/*****************************************************************************/
+/* process a arrow gadget movement. */
+/*****************************************************************************/
+bool processArrow(uint16 *direction, uint16 Arrow) {
+ uint16 room = 1;
+
+ if (Arrow == 1) { /* Forward */
+ if (*direction == NORTH)
+ room = Rooms[RoomNum].NorthDoor;
+ else if (*direction == SOUTH)
+ room = Rooms[RoomNum].SouthDoor;
+ else if (*direction == EAST)
+ room = Rooms[RoomNum].EastDoor;
+ else if (*direction == WEST)
+ room = Rooms[RoomNum].WestDoor;
+
+ if (room == 0)
+ return false;
+ else
+ RoomNum = room;
+ } else if (Arrow == 0) { /* Left */
+ if (*direction == NORTH)
+ *direction = WEST;
+ else if (*direction == WEST)
+ *direction = SOUTH;
+ else if (*direction == SOUTH)
+ *direction = EAST;
+ else
+ *direction = NORTH;
+ } else if (Arrow == 2) { /* Right */
+ if (*direction == NORTH)
+ *direction = EAST;
+ else if (*direction == EAST)
+ *direction = SOUTH;
+ else if (*direction == SOUTH)
+ *direction = WEST;
+ else
+ *direction = NORTH;
+ }
+
+ return true;
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Sets the current close up data, but uses absolute cords. */
+/*****************************************************************************/
+void setCurCloseAbs(uint16 x, uint16 y, CloseDataPtr *cptr) {
+ ViewDataPtr VPtr;
+ CloseDataPtr LCPtr;
+
+ if (*cptr == NULL) {
+ VPtr = getViewData(RoomNum, Direction);
+ LCPtr = VPtr->closeUps;
+ } else
+ LCPtr = (*cptr)->SubCloseUps;
+
+
+ while (LCPtr != NULL) {
+ if ((x >= LCPtr->x1) && (y >= LCPtr->y1) &&
+ (x <= LCPtr->x2) && (y <= LCPtr->y2) &&
+ (LCPtr->GraphicName)) {
+ *cptr = LCPtr;
+ return;
+ }
+
+ LCPtr = LCPtr->NextCloseUp;
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Sets the current close up data. */
+/*****************************************************************************/
+void setCurClose(uint16 x, uint16 y, CloseDataPtr *cptr) {
+ ViewDataPtr VPtr;
+ CloseDataPtr LCPtr;
+
+ if (*cptr == NULL) {
+ VPtr = getViewData(RoomNum, Direction);
+ LCPtr = VPtr->closeUps;
+ } else
+ LCPtr = (*cptr)->SubCloseUps;
+
+
+ while (LCPtr != NULL) {
+ if ((x >= scaleX(LCPtr->x1)) && (y >= scaleY(LCPtr->y1)) &&
+ (x <= scaleX(LCPtr->x2)) && (y <= scaleY(LCPtr->y2)) &&
+ (LCPtr->GraphicName)) {
+ *cptr = LCPtr;
+ return;
+ }
+
+ LCPtr = LCPtr->NextCloseUp;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Takes the currently selected item. */
+/*****************************************************************************/
+bool takeItem(uint16 x, uint16 y, CloseDataPtr *cptr) {
+ ViewDataPtr VPtr;
+ CloseDataPtr LCPtr;
+
+ if (*cptr == NULL) {
+ VPtr = getViewData(RoomNum, Direction);
+ LCPtr = VPtr->closeUps;
+ } else if ((*cptr)->CloseUpType < 0) {
+ inclElement(Conditions, abs((*cptr)->CloseUpType));
+ return true;
+ } else
+ LCPtr = (*cptr)->SubCloseUps;
+
+
+ while (LCPtr != NULL) {
+ if ((x >= scaleX(LCPtr->x1)) && (y >= scaleY(LCPtr->y1)) &&
+ (x <= scaleX(LCPtr->x2)) && (y <= scaleY(LCPtr->y2)) &&
+ (LCPtr->CloseUpType < 0)) {
+ inclElement(Conditions, abs(LCPtr->CloseUpType));
+ return true;
+ }
+
+ LCPtr = LCPtr->NextCloseUp;
+ }
+
+ return false;
+}
+
+
+
+/*****************************************************************************/
+/* Processes the action list. */
+/*****************************************************************************/
+static void doActions(ActionPtr APtr, CloseDataPtr *LCPtr) {
+ CloseDataPtr TLCPtr;
+ bool FirstLoaded = true;
+ char **str, *Test;
+ uint16 counter;
+ uint32 StartSecs, StartMicros, CurSecs, CurMicros;
+
+ while (APtr) {
+ g_music->newCheckMusic();
+
+ switch (APtr->ActionType) {
+ case PLAYSOUND:
+ mwaiteffect = true; /* Plays a sound, but waits for it to be done before continuing */
+ ContMusic = false;
+ readMusic((char *)APtr->Data);
+ mwaiteffect = false;
+ break;
+
+ case PLAYSOUNDB:
+ mwaiteffect = false; /* Plays a sound in the background. */
+ ContMusic = false;
+ readMusic((char *)APtr->Data);
+ break;
+
+ case PLAYSOUNDCONT:
+ g_music->_doNotFileFlushAudio = true;
+ ContMusic = true;
+ readMusic((char *)APtr->Data);
+ break;
+
+ case SHOWDIFF:
+ readPict((char *)APtr->Data, true);
+ break;
+
+ case SHOWDIFFCONT:
+ readPict((char *)APtr->Data, false);
+ break;
+
+ case LOADDIFF:
+ if (FirstLoaded) {
+ resetBuffer();
+ FirstLoaded = false;
+ }
+
+ if (APtr->Data)
+ g_music->newOpen((char *)APtr->Data); /* Puts a file into memory */
+
+ break;
+
+ case WIPECMD:
+ doWipe(APtr->Param1, LCPtr, (char *)APtr->Data);
+ break;
+
+ case NOUPDATE:
+ noupdatediff = true;
+ DoBlack = false;
+ break;
+
+ case FORCEUPDATE:
+ CurFileName = " ";
+ break;
+
+ case SHOWCURPICT:
+ Test = getPictName(LCPtr);
+
+ if (strcmp(Test, CurFileName) != 0) {
+ CurFileName = Test;
+ readPict(CurFileName, true);
+ }
+
+ break;
+
+ case SETELEMENT:
+ inclElement(Conditions, APtr->Param1);
+ break;
+
+ case UNSETELEMENT:
+ exclElement(Conditions, APtr->Param1);
+ break;
+
+ case SHOWMESSAGE:
+ DoNotDrawMessage = false;
+
+ if (LongWinInFront)
+ longDrawMessage((char *)APtr->Data);
+ else
+ drawMessage((char *)APtr->Data);
+
+ DoNotDrawMessage = true;
+ break;
+
+ case CSHOWMESSAGE:
+ if (*LCPtr == NULL) {
+ DoNotDrawMessage = false;
+ drawMessage((char *)APtr->Data);
+ DoNotDrawMessage = true;
+ }
+
+ break;
+
+ case SHOWMESSAGES:
+ str = (char **)APtr->Data;
+ DoNotDrawMessage = false;
+ drawMessage(str[getRandom(APtr->Param1)]);
+ DoNotDrawMessage = true;
+ break;
+
+ case SETPOSITION:
+#if defined(LABDEMO)
+
+ // if teleporting to room 45 or 49
+ if (APtr->Param1 == 45 || APtr->Param1 == 49) {
+ extern void doTrialBlock();
+
+ // Time to pay up!
+ doTrialBlock();
+
+ CurFileName = getPictName(LCPtr);
+ readPict(CurFileName, true);
+
+ APtr = NULL;
+ continue;
+ }
+
+#endif
+#if defined(GAME_TRIAL)
+
+ if (APtr->Param1 & 0x8000) { // check registration if high-bit set
+ if (!g_IsRegistered) {
+ extern int trialCheckInGame();
+ int result;
+
+ // Time to pay up!
+ result = trialCheckInGame();
+
+ CurFileName = getPictName(LCPtr);
+ readPict(CurFileName, true);
+
+ if (!g_IsRegistered) {
+ APtr = NULL;
+ continue;
+ }
+ }
+
+ // fix-up data
+ APtr->Param1 &= 0x7fff; // clear high-bit
+ }
+
+#endif
+ RoomNum = APtr->Param1;
+ Direction = APtr->Param2 - 1;
+ *LCPtr = NULL;
+ DoBlack = true;
+ break;
+
+ case SETCLOSEUP:
+ TLCPtr = getObject(scaleX(APtr->Param1), scaleY(APtr->Param2), *LCPtr);
+
+ if (TLCPtr)
+ *LCPtr = TLCPtr;
+
+ break;
+
+ case MAINVIEW:
+ *LCPtr = NULL;
+ break;
+
+ case SUBINV:
+ if (Inventory[APtr->Param1].Many)
+ (Inventory[APtr->Param1].Many)--;
+
+ if (Inventory[APtr->Param1].Many == 0)
+ exclElement(Conditions, APtr->Param1);
+
+ break;
+
+ case ADDINV:
+ (Inventory[APtr->Param1].Many) += APtr->Param2;
+ inclElement(Conditions, APtr->Param1);
+ break;
+
+ case SHOWDIR:
+ DoNotDrawMessage = false;
+ break;
+
+ case WAITSECS:
+ addCurTime(APtr->Param1, 0, &StartSecs, &StartMicros);
+
+#if !defined(DOSCODE)
+ g_system->updateScreen();
+#endif
+
+ while (1) {
+ g_music->newCheckMusic();
+ diffNextFrame();
+ getTime(&CurSecs, &CurMicros);
+
+ if ((CurSecs > StartSecs) || ((CurSecs == StartSecs) &&
+ (CurMicros >= StartMicros)))
+ break;
+ }
+
+ break;
+
+ case STOPMUSIC:
+ g_music->setMusic(false);
+ break;
+
+ case STARTMUSIC:
+ g_music->setMusic(true);
+ break;
+
+ case CHANGEMUSIC:
+ if (g_music->_turnMusicOn) {
+ g_music->changeMusic((const char *)APtr->Data);
+ DoNotReset = true;
+ }
+
+ break;
+
+ case RESETMUSIC:
+ if (g_music->_turnMusicOn) {
+ g_music->resetMusic();
+ DoNotReset = false;
+ }
+
+ break;
+
+ case FILLMUSIC:
+ g_music->fillUpMusic(true);
+ break;
+
+ case WAITSOUND:
+ while (EffectPlaying) {
+ g_music->updateMusic();
+ diffNextFrame();
+ waitTOF();
+ }
+
+ break;
+
+ case CLEARSOUND:
+ if (ContMusic) {
+ ContMusic = false;
+ flushAudio();
+ } else if (EffectPlaying)
+ flushAudio();
+
+ break;
+
+ case WINMUSIC:
+ if (g_music->_turnMusicOn) {
+ g_music->_winmusic = true;
+ g_music->freeMusic();
+ g_music->initMusic();
+ }
+
+ break;
+
+ case WINGAME:
+ QuitLab = true;
+ break;
+
+ case LOSTGAME:
+ QuitLab = true;
+ break;
+
+ case RESETBUFFER:
+ resetBuffer();
+ break;
+
+ case SPECIALCMD:
+ if (APtr->Param1 == 0)
+ DoBlack = true;
+ else if (APtr->Param1 == 1)
+ DoBlack = (CPtr == NULL);
+ else if (APtr->Param1 == 2)
+ DoBlack = (CPtr != NULL);
+ else if (APtr->Param1 == 5) { /* inverse the palette */
+ for (counter = (8 * 3); counter < (255 * 3); counter++)
+ diffcmap[counter] = 255 - diffcmap[counter];
+
+ waitTOF();
+ VGASetPal(diffcmap, 256);
+ waitTOF();
+ waitTOF();
+ } else if (APtr->Param1 == 4) { /* white the palette */
+ whiteScreen();
+ waitTOF();
+ waitTOF();
+ } else if (APtr->Param1 == 6) { /* Restore the palette */
+ waitTOF();
+ VGASetPal(diffcmap, 256);
+ waitTOF();
+ waitTOF();
+ } else if (APtr->Param1 == 7) { /* Quick pause */
+ waitTOF();
+ waitTOF();
+ waitTOF();
+ }
+
+ break;
+ }
+
+ APtr = APtr->NextAction;
+ }
+
+ if (ContMusic) {
+ ContMusic = false;
+ flushAudio();
+ } else {
+ while (EffectPlaying) {
+ g_music->updateMusic();
+ diffNextFrame();
+ waitTOF();
+ }
+ }
+
+ g_music->_doNotFileFlushAudio = false;
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Does the work for doActionRule. */
+/*****************************************************************************/
+static bool doActionRuleSub(int16 Action, int16 roomNum, CloseDataPtr LCPtr, CloseDataPtr *Set, bool AllowDefaults) {
+ RulePtr RPtr;
+
+ Action++;
+
+ if (LCPtr) {
+ RPtr = Rooms[roomNum].RuleList;
+
+ if ((RPtr == NULL) && (roomNum == 0)) {
+ readViews(roomNum, ViewPath);
+ RPtr = Rooms[roomNum].RuleList;
+ }
+
+
+ while (RPtr) {
+ if ((RPtr->RuleType == ACTION) &&
+ ((RPtr->Param1 == Action) || ((RPtr->Param1 == 0) && AllowDefaults))) {
+ if (((RPtr->Param2 == LCPtr->CloseUpType) ||
+ ((RPtr->Param2 == 0) && AllowDefaults))
+ ||
+ ((Action == 1) && (RPtr->Param2 == (-LCPtr->CloseUpType)))) {
+ if (checkConditions(RPtr->Condition)) {
+ doActions(RPtr->ActionList, Set);
+ return true;
+ }
+ }
+ }
+
+ RPtr = RPtr->NextRule;
+ }
+ }
+
+ return false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Goes through the rules if an action is taken. */
+/*****************************************************************************/
+bool doActionRule(int16 x, int16 y, int16 Action, int16 roomNum, CloseDataPtr *LCPtr) {
+ CloseDataPtr TLCPtr;
+
+ if (roomNum)
+ NewFileName = NOFILE;
+ else
+ NewFileName = CurFileName;
+
+ TLCPtr = getObject(x, y, *LCPtr);
+
+ if (doActionRuleSub(Action, roomNum, TLCPtr, LCPtr, false))
+ return true;
+ else if (doActionRuleSub(Action, roomNum, *LCPtr, LCPtr, false))
+ return true;
+ else if (doActionRuleSub(Action, roomNum, TLCPtr, LCPtr, true))
+ return true;
+ else if (doActionRuleSub(Action, roomNum, *LCPtr, LCPtr, true))
+ return true;
+
+ return false;
+}
+
+
+
+/*****************************************************************************/
+/* Does the work for doActionRule. */
+/*****************************************************************************/
+static bool doOperateRuleSub(int16 ItemNum, int16 roomNum, CloseDataPtr LCPtr, CloseDataPtr *Set, bool AllowDefaults) {
+ RulePtr RPtr;
+
+ if (LCPtr)
+ if (LCPtr->CloseUpType > 0) {
+ RPtr = Rooms[roomNum].RuleList;
+
+ if ((RPtr == NULL) && (roomNum == 0)) {
+ readViews(roomNum, ViewPath);
+ RPtr = Rooms[roomNum].RuleList;
+ }
+
+ while (RPtr) {
+ if ((RPtr->RuleType == OPERATE) &&
+ ((RPtr->Param1 == ItemNum) || ((RPtr->Param1 == 0) && AllowDefaults)) &&
+ ((RPtr->Param2 == LCPtr->CloseUpType) || ((RPtr->Param2 == 0) && AllowDefaults))) {
+ if (checkConditions(RPtr->Condition)) {
+ doActions(RPtr->ActionList, Set);
+ return true;
+ }
+ }
+
+ RPtr = RPtr->NextRule;
+ }
+ }
+
+ return false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Goes thru the rules if the user tries to operate an item on an object. */
+/*****************************************************************************/
+bool doOperateRule(int16 x, int16 y, int16 ItemNum, CloseDataPtr *LCPtr) {
+ CloseDataPtr TLCPtr;
+
+ NewFileName = NOFILE;
+
+ TLCPtr = getObject(x, y, *LCPtr);
+
+ if (doOperateRuleSub(ItemNum, RoomNum, TLCPtr, LCPtr, false))
+ return true;
+ else if (doOperateRuleSub(ItemNum, RoomNum, *LCPtr, LCPtr, false))
+ return true;
+ else if (doOperateRuleSub(ItemNum, RoomNum, TLCPtr, LCPtr, true))
+ return true;
+ else if (doOperateRuleSub(ItemNum, RoomNum, *LCPtr, LCPtr, true))
+ return true;
+
+ else {
+ NewFileName = CurFileName;
+
+ if (doOperateRuleSub(ItemNum, 0, TLCPtr, LCPtr, false))
+ return true;
+ else if (doOperateRuleSub(ItemNum, 0, *LCPtr, LCPtr, false))
+ return true;
+ else if (doOperateRuleSub(ItemNum, 0, TLCPtr, LCPtr, true))
+ return true;
+ else if (doOperateRuleSub(ItemNum, 0, *LCPtr, LCPtr, true))
+ return true;
+ }
+
+ return false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Goes thru the rules if the user tries to go forward. */
+/*****************************************************************************/
+bool doGoForward(CloseDataPtr *LCPtr) {
+ RulePtr RPtr;
+
+ RPtr = Rooms[RoomNum].RuleList;
+
+ while (RPtr) {
+ if ((RPtr->RuleType == GOFORWARD) && (RPtr->Param1 == (Direction + 1))) {
+ if (checkConditions(RPtr->Condition)) {
+ doActions(RPtr->ActionList, LCPtr);
+ return true;
+ }
+ }
+
+ RPtr = RPtr->NextRule;
+ }
+
+ return false;
+}
+
+
+
+/*****************************************************************************/
+/* Goes thru the rules if the user tries to turn. */
+/*****************************************************************************/
+bool doTurn(uint16 from, uint16 to, CloseDataPtr *LCPtr) {
+ RulePtr RPtr;
+
+ from++;
+ to++;
+
+ RPtr = Rooms[RoomNum].RuleList;
+
+ while (RPtr) {
+ if ((RPtr->RuleType == TURN) ||
+
+ ((RPtr->RuleType == TURNFROMTO) &&
+ (RPtr->Param1 == from) && (RPtr->Param2 == to))) {
+ if (checkConditions(RPtr->Condition)) {
+ doActions(RPtr->ActionList, LCPtr);
+ return true;
+ }
+ }
+
+ RPtr = RPtr->NextRule;
+ }
+
+ return false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Goes thru the rules if the user tries to go to the main view */
+/*****************************************************************************/
+bool doMainView(CloseDataPtr *LCPtr) {
+ RulePtr RPtr;
+
+ RPtr = Rooms[RoomNum].RuleList;
+
+ while (RPtr) {
+ if (RPtr->RuleType == GOMAINVIEW) {
+ if (checkConditions(RPtr->Condition)) {
+ doActions(RPtr->ActionList, LCPtr);
+ return true;
+ }
+ }
+
+ RPtr = RPtr->NextRule;
+ }
+
+ return false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Goes thru the rules whenever (probably after an action or something), and */
+/* sets the conditions. */
+/*****************************************************************************/
+/*
+ bool doConditions(int16 x,
+ int16 y,
+ CloseDataPtr *LCPtr)
+ {
+ RulePtr RPtr;
+
+ NewFileName = NOFILE;
+
+ RPtr = Rooms[RoomNum].RuleList;
+
+ while (RPtr)
+ {
+ if (RPtr->RuleType == CONDITIONS)
+ {
+ if (checkConditions(RPtr->Condition))
+ {
+ doActions(RPtr->ActionList, LCPtr);
+ return true;
+ }
+ }
+
+ RPtr = RPtr->NextRule;
+ }
+ return false;
+ }
+ */
+
+#if defined(DEMODATA)
+#include <stdio.h>
+
+static void WriteDemoData_CloseUps(FILE *fh, CloseDataPtr cd) {
+ while (cd != NULL) {
+ if (*cd->GraphicName)
+ fprintf(fh, "%s\n", cd->GraphicName);
+
+ WriteDemoData_CloseUps(fh, cd->SubCloseUps);
+ cd = cd->NextCloseUp;
+ }
+}
+
+static void WriteDemoData_ViewData(FILE *fh, ViewDataPtr vd) {
+ if (vd == NULL)
+ return;
+
+ if (*vd->GraphicName != 0)
+ fprintf(fh, "%s\n", vd->GraphicName);
+
+ WriteDemoData_CloseUps(fh, vd->closeUps);
+}
+
+void writeDemoData() {
+ FILE *fh = fopen("c:\\depot\\labyrinth\\demodata.log", "a+w");
+
+ WriteDemoData_ViewData(fh, getViewData(RoomNum, NORTH));
+ WriteDemoData_ViewData(fh, getViewData(RoomNum, SOUTH));
+ WriteDemoData_ViewData(fh, getViewData(RoomNum, EAST));
+ WriteDemoData_ViewData(fh, getViewData(RoomNum, WEST));
+
+ fclose(fh);
+}
+#endif
+
+} // End of namespace Lab
diff --git a/engines/lab/readdiff.cpp b/engines/lab/readdiff.cpp
new file mode 100644
index 0000000000..2af49e9f43
--- /dev/null
+++ b/engines/lab/readdiff.cpp
@@ -0,0 +1,673 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/timing.h"
+#include "lab/diff.h"
+#include "lab/labfun.h"
+#include "lab/vga.h"
+#include "lab/mouse.h"
+
+namespace Lab {
+
+extern struct BitMap *DispBitMap, *DrawBitMap;
+extern uint32 VGABytesPerPage;
+
+/*
+ extern int32 ReadSoFar;
+ extern bool ReadIsDone,
+ ReadIsError;
+ */
+extern byte **startoffile;
+
+static bool PlayOnce = false, changedscreen;
+
+bool NoFlip = false, /* Don't flip the new picture to front */
+ DoBlack = false, /* Black the screen before new picture */
+ nopalchange = false, /* Don't change the palette. */
+ noscreenchange = false, /* Don't change the screen type. */
+ IsBM = false, /* Just fill in the RawDIFFBM structure */
+ hidemouse = false, /* Don't set the mouse colors */
+ stopsound = false,
+ soundplaying = false,
+ screenbuffer = false,
+ waiteffect = false, /* Wait for each sound effect to finish
+ before coninuing. */
+ mwaiteffect = false;
+
+uint16 DataBytesPerRow;
+
+extern bool EffectPlaying;
+
+
+#define CONTINUOUS 0xFFFF
+
+DIFFHeader headerdata;
+
+
+
+/*------ Stuff for the animation task. -----*/
+
+static byte *start;
+
+static uint32 diffwidth, diffheight;
+
+static bool continuous,
+ IsPlaying = false,
+ StopPlaying = false,
+ StopPlayingEnd = false,
+ IsAnim = false,
+ IsPal = false;
+
+char diffcmap[256 * 3], lastcmap[256 * 3];
+
+struct BitMap RawDiffBM;
+
+
+
+
+/*****************************************************************************/
+/* Does the undiffing between the bitmaps. */
+/*****************************************************************************/
+void unDiff(byte *NewBuf, byte *OldBuf, byte *DiffData, uint16 bytesperrow, bool IsV) {
+ byte buftype;
+
+ DiffData++;
+ buftype = *DiffData;
+ DiffData++;
+
+ if (IsV)
+ VUnDIFFMemory(NewBuf, DiffData, 1, buftype + 1, bytesperrow);
+ else
+ unDIFFMemory(NewBuf, DiffData, 1, buftype + 1);
+}
+
+
+static char blackbuffer[256 * 3];
+
+/*****************************************************************************/
+/* Changes the front screen to black. */
+/*****************************************************************************/
+void blackScreen() {
+ memset(blackbuffer, 0, 248 * 3);
+ writeColorRegs(blackbuffer, 8, 248);
+
+ g_system->delayMillis(32);
+}
+
+/*****************************************************************************/
+/* Changes the front screen to white. */
+/*****************************************************************************/
+void whiteScreen(void) {
+ memset(blackbuffer, 255, 248 * 3);
+ writeColorRegs(blackbuffer, 8, 248);
+}
+
+/*****************************************************************************/
+/* Changes the entire screen to black. */
+/*****************************************************************************/
+void blackAllScreen() {
+ memset(blackbuffer, 0, 256 * 3);
+ writeColorRegs(blackbuffer, 0, 256);
+
+ g_system->delayMillis(32);
+}
+
+
+
+/* For Play Diff */
+static uint32 header, size, processed = 0L, WaitSec = 0L, WaitMicros = 0L, DelayMicros = 0L;
+static uint16 CurBit = 0, framenumber = 0, samplespeed, numchunks = 1;
+static byte *Buffer, temp[5];
+static bool FirstThru = true, donepal = false;
+static byte *storagefordifffile, * *difffile = &storagefordifffile;
+
+void diffNextFrame(void) {
+ if (header == 65535) /* Already done. */
+ return;
+
+#if !defined(DOSCODE)
+
+ if (DispBitMap->Flags & BITMAPF_VIDEO) {
+ DispBitMap->Planes[0] = getVGABaseAddr();
+ DispBitMap->Planes[1] = DispBitMap->Planes[0] + 0x10000;
+ DispBitMap->Planes[2] = DispBitMap->Planes[1] + 0x10000;
+ DispBitMap->Planes[3] = DispBitMap->Planes[2] + 0x10000;
+ DispBitMap->Planes[4] = DispBitMap->Planes[3] + 0x10000;
+ }
+
+#endif
+
+ mouseHide();
+
+ while (1) {
+ /* NYI: Don't need.
+ if (ReadIsError)
+ {
+ IsPlaying = false;
+ mouseShow();
+ return;
+ }
+ */
+
+ if (CurBit >= numchunks) {
+ mouseShow();
+
+#ifdef undef /* NYI: Don't need. */
+
+ while (!ReadIsDone && !ReadIsError) /* Wait for the file to load */
+ waitTOF();
+
+#endif
+
+ if (!NoFlip && !IsBM) {
+ if (headerdata.fps) {
+ waitForTime(WaitSec, WaitMicros);
+ addCurTime(0L, DelayMicros, &WaitSec, &WaitMicros);
+ }
+
+ if (IsPal && !nopalchange) {
+ VGASetPal(diffcmap, 256);
+ IsPal = false;
+ }
+
+ donepal = true;
+ FirstThru = false;
+ }
+
+ if (IsPal && !nopalchange && !IsBM && !donepal) {
+ VGASetPal(diffcmap, 256);
+ IsPal = false;
+ }
+
+ donepal = false;
+
+ framenumber++;
+
+ if ((framenumber == 1) && (continuous || (!PlayOnce)))
+ Buffer = *difffile;
+
+ IsAnim = (framenumber >= 3) && (!PlayOnce);
+ CurBit = 0;
+
+#if !defined(DOSCODE)
+
+ if (DispBitMap->Flags & BITMAPF_VIDEO)
+ g_system->updateScreen();
+
+#endif
+
+ return; /* done with the next frame. */
+ }
+
+ g_music->updateMusic();
+ readBlock(&header, 4L, difffile);
+#if !defined(DOSCODE)
+ swapULongPtr(&header, 1);
+#endif
+ readBlock(&size, 4L, difffile);
+#if !defined(DOSCODE)
+ swapULongPtr(&size, 1);
+#endif
+
+ processed += 8L;
+
+ processed += size;
+
+ switch (header) {
+ case 8L:
+ memcpy(lastcmap, diffcmap, 256 * 3);
+
+ readBlock(diffcmap, size, difffile);
+ IsPal = true;
+ break;
+
+ case 10L:
+ RawDiffBM.Planes[CurBit] = *difffile;
+
+ if (IsBM)
+ skip(difffile, size);
+ else {
+#if defined(DOSCODE)
+ setPage(CurBit);
+#endif
+ readBlock(DrawBitMap->Planes[CurBit], size, difffile);
+ }
+
+ CurBit++;
+ break;
+
+ case 11L:
+#if defined(DOSCODE)
+ setPage(CurBit);
+#endif
+ skip(difffile, 4L);
+ runLengthDecode(DrawBitMap->Planes[CurBit], *difffile);
+ CurBit++;
+ skip(difffile, size - 4);
+ break;
+
+ case 12L:
+#if defined(DOSCODE)
+ setPage(CurBit);
+#endif
+ skip(difffile, 4L);
+ VRunLengthDecode(DrawBitMap->Planes[CurBit], *difffile, DrawBitMap->BytesPerRow);
+ CurBit++;
+ skip(difffile, size - 4);
+ break;
+
+ case 20L:
+#if defined(DOSCODE)
+ setPage(CurBit);
+#endif
+ unDiff(DrawBitMap->Planes[CurBit], DispBitMap->Planes[CurBit], *difffile, DrawBitMap->BytesPerRow, false);
+ CurBit++;
+ skip(difffile, size);
+ break;
+
+ case 21L:
+#if defined(DOSCODE)
+ setPage(CurBit);
+#endif
+ unDiff(DrawBitMap->Planes[CurBit], DispBitMap->Planes[CurBit], *difffile, DrawBitMap->BytesPerRow, true);
+ CurBit++;
+ skip(difffile, size);
+ break;
+
+ case 25L:
+ CurBit++;
+ break;
+
+ case 26L:
+ /* NYI: This don't work no more
+ memcpy((void *) DrawBitMap->Planes[CurBit],
+ (void *) DispBitMap->Planes[CurBit], (uint16) (diffheight*diffwidth));
+ */
+ CurBit++;
+ break;
+
+ case 30L:
+ case 31L: {
+ if (waiteffect) {
+ while (EffectPlaying) {
+ g_music->updateMusic();
+ waitTOF();
+ }
+ }
+
+ size -= 8L;
+
+ skip(difffile, 4L);
+ readBlock(&samplespeed, 2L, difffile);
+#if !defined(DOSCODE)
+ swapUShortPtr(&samplespeed, 1);
+#endif
+ skip(difffile, 2L);
+
+ byte *music = *difffile;
+ uint32 musicsize = size;
+ skip(difffile, size);
+
+ playMusic(samplespeed, 64, musicsize, true, music);
+ break;
+ }
+ case 65535L:
+ if ((framenumber == 1) || PlayOnce || StopPlayingEnd) {
+#if !defined(DOSCODE)
+ int didTOF = 0;
+#endif
+
+ if (waiteffect) {
+ while (EffectPlaying) {
+ g_music->updateMusic();
+ waitTOF();
+#if !defined(DOSCODE)
+
+ if (DispBitMap->Flags & BITMAPF_VIDEO)
+ didTOF = 1;
+
+#endif
+ }
+ }
+
+ IsPlaying = false;
+ mouseShow();
+#if !defined(DOSCODE)
+
+ if (DispBitMap->Flags & BITMAPF_VIDEO)
+ ungetVGABaseAddr();
+
+ if (!didTOF)
+ g_system->updateScreen();
+
+#endif
+ return;
+ }
+
+ framenumber = 4; /* Random frame number so it never gets back to 2 */
+ *difffile = Buffer;
+ break;
+
+ default:
+ skip(difffile, size);
+ break;
+ }
+ }
+
+#if !defined(DOSCODE)
+
+ if (DispBitMap->Flags & BITMAPF_VIDEO)
+ ungetVGABaseAddr();
+
+#endif
+}
+
+
+
+/*****************************************************************************/
+/* A separate task launched by readDiff. Plays the DIFF. */
+/*****************************************************************************/
+void playDiff(void) {
+ processed = 0L;
+ WaitSec = 0L;
+ WaitMicros = 0L;
+ DelayMicros = 0L;
+ header = 0;
+ CurBit = 0;
+ framenumber = 0;
+ numchunks = 1;
+ FirstThru = true;
+ donepal = false;
+ difffile = &storagefordifffile;
+
+ IsPlaying = true;
+ StopPlaying = false;
+ StopPlayingEnd = false;
+
+ changedscreen = false;
+
+ if (DoBlack) {
+ DoBlack = false;
+ blackScreen();
+ }
+
+
+ start = *startoffile; /* Make a copy of the pointer to the start of the file */
+ *difffile = start; /* Now can modify the file without modifying the original */
+
+
+ if (start == NULL) {
+ IsPlaying = false;
+ return;
+ }
+
+ continuous = false;
+ readBlock(temp, 4L, difffile);
+ temp[4] = '\0';
+ readBlock(&header, 4L, difffile);
+#if !defined(DOSCODE)
+ swapULongPtr(&header, 1);
+#endif
+ processed += 8L;
+
+ if (!((strcmp((char *)temp, "DIFF") == 0) && (header == 1219009121L))) {
+ IsPlaying = false;
+ return;
+ }
+
+ readBlock(&header, 4L, difffile);
+#if !defined(DOSCODE)
+ swapULongPtr(&header, 1);
+#endif
+ readBlock(&size, 4L, difffile);
+#if !defined(DOSCODE)
+ swapULongPtr(&size, 1);
+#endif
+
+ if (header == 0) {
+#if defined(IS_MACOSX)
+ // sizeof(headerdata) != 18, but the padding might be at the end
+ readBlock(&headerdata.Version, 2, difffile);
+ readBlock(&headerdata.x, 2, difffile);
+ readBlock(&headerdata.y, 2, difffile);
+ readBlock(&headerdata.depth, 1, difffile);
+ readBlock(&headerdata.fps, 1, difffile);
+ readBlock(&headerdata.BufferSize, 4, difffile);
+ readBlock(&headerdata.Machine, 2, difffile);
+ readBlock(&headerdata.Flags, 4, difffile);
+#else
+ readBlock(&headerdata, 18, difffile);
+#endif
+ skip(difffile, size - 18);
+
+#if !defined(DOSCODE)
+ swapUShortPtr(&headerdata.Version, 3);
+ swapULongPtr(&headerdata.BufferSize, 1);
+ swapUShortPtr(&headerdata.Machine, 1);
+ swapULongPtr(&headerdata.Flags, 1);
+#endif
+
+ continuous = CONTINUOUS & headerdata.Flags;
+ diffwidth = headerdata.x;
+ diffheight = headerdata.y;
+ DataBytesPerRow = diffwidth;
+
+#if defined(DOSCODE)
+ numchunks = (((int32) diffwidth) * diffheight) / VGABytesPerPage;
+
+ if ((numchunks * VGABytesPerPage) < (((int32) diffwidth) * diffheight))
+ numchunks++;
+
+#else
+ numchunks = (((int32) diffwidth) * diffheight) / 0x10000;
+
+ if ((uint32)(numchunks * 0x10000) < (uint32)(((int32) diffwidth) * diffheight))
+ numchunks++;
+
+#endif
+ } else {
+ return;
+ }
+
+ processed += 8L + size;
+
+ for (header = 0; header < 8; header++)
+ RawDiffBM.Planes[header] = NULL;
+
+ if (headerdata.fps)
+ DelayMicros = ONESECOND / headerdata.fps;
+
+ if (PlayOnce) {
+ while (header != 65535)
+ diffNextFrame();
+ } else
+ diffNextFrame();
+}
+
+
+
+/*****************************************************************************/
+/* Stops an animation from running. */
+/*****************************************************************************/
+void stopDiff(void) {
+ if (IsPlaying) {
+ StopPlaying = true;
+
+ /* NYI:
+ while (IsPlaying)
+ waitTOF();
+ */
+
+ if (IsAnim)
+ blackScreen();
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Stops an animation from running. */
+/*****************************************************************************/
+void stopDiffEnd(void) {
+ if (IsPlaying) {
+ StopPlayingEnd = true;
+
+ while (IsPlaying) {
+ g_music->newCheckMusic();
+ diffNextFrame();
+ }
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Stops the continuous sound from playing. */
+/*****************************************************************************/
+void stopSound(void) {
+ stopsound = true;
+}
+
+
+
+/*****************************************************************************/
+/* Checks the music while a diff is playing. */
+/*****************************************************************************/
+void diffSetMusic(void) {
+ return;
+
+ while (IsPlaying) {
+ waitTOF();
+ g_music->newCheckMusic();
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Reads in a DIFF file. */
+/*****************************************************************************/
+bool readDiff(bool playonce) {
+ PlayOnce = playonce;
+ playDiff();
+ return true;
+}
+
+
+
+static byte *mstart;
+
+
+void readSound(void) {
+ uint32 header_ = 0, size_;
+ uint16 samplespeed_;
+// uint16 numchunks = 1;
+ char temp_[5];
+// bool FirstThru = true;
+ byte *storagefordifffile_, **difffile_ = &storagefordifffile_;
+
+ mstart = *startoffile; /* Make a copy of the pointer to the start of the file */
+ *difffile_ = mstart; /* Now can modify the file without modifying the original */
+
+ if (mstart == NULL)
+ return;
+
+ readBlock(temp_, 4L, difffile_);
+ temp_[4] = '\0';
+ readBlock(&header_, 4L, difffile_);
+#if !defined(DOSCODE)
+ swapULongPtr(&header_, 1);
+#endif
+ processed += 8L;
+
+ if (!((strcmp(temp_, "DIFF") == 0) && (header_ == 1219009121L)))
+ return;
+
+ readBlock(&header_, 4L, difffile_);
+#if !defined(DOSCODE)
+ swapULongPtr(&header_, 1);
+#endif
+ readBlock(&size_, 4L, difffile_);
+#if !defined(DOSCODE)
+ swapULongPtr(&size_, 1);
+#endif
+
+ if (header_ == 0)
+ skip(difffile_, size_);
+ else
+ return;
+
+ while (header_ != 65535) {
+ g_music->updateMusic();
+ readBlock(&header_, 4L, difffile_);
+#if !defined(DOSCODE)
+ swapULongPtr(&header_, 1);
+#endif
+ readBlock(&size_, 4L, difffile_);
+#if !defined(DOSCODE)
+ swapULongPtr(&size_, 1);
+#endif
+
+ if ((header_ == 30) || (header_ == 31)) {
+ if (mwaiteffect) {
+ while (EffectPlaying) {
+ g_music->updateMusic();
+ waitTOF();
+ }
+ }
+
+ size_ -= 8L;
+
+ skip(difffile_, 4L);
+ readBlock(&samplespeed_, 2L, difffile_);
+#if !defined(DOSCODE)
+ swapUShortPtr(&samplespeed_, 1);
+#endif
+ skip(difffile_, 2L);
+
+ byte *music = *difffile_;
+ uint32 musicsize = size_;
+ skip(difffile_, size_);
+
+ playMusic(samplespeed_, 64, musicsize, true, music);
+ } else if (header_ == 65535L) {
+ if (mwaiteffect) {
+ while (EffectPlaying) {
+ g_music->updateMusic();
+ waitTOF();
+ }
+ }
+ } else
+ skip(difffile_, size_);
+ }
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/readparse.cpp b/engines/lab/readparse.cpp
new file mode 100644
index 0000000000..e970942a41
--- /dev/null
+++ b/engines/lab/readparse.cpp
@@ -0,0 +1,514 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/labfun.h"
+#include "lab/parsetypes.h"
+#include "lab/parsefun.h"
+#include "lab/storage.h"
+#include "lab/stddefines.h"
+
+namespace Lab {
+
+#define MAXSTRINGLENGTH 250
+
+static bool UseMemory = false;
+
+
+
+/* Global parser data */
+
+extern RoomData *Rooms;
+extern InventoryData *Inventory;
+extern uint16 NumInv, ManyRooms, HighestCondition, Direction;
+extern LargeSet Conditions, RoomsFound;
+
+
+
+static uint16 allocroom;
+
+
+static bool rallocate(void **Ptr, uint32 Size) {
+ if (UseMemory)
+ return allocate(Ptr, Size);
+ else {
+ allocRoom(Ptr, (uint16) Size, allocroom);
+ return true;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Reads in the RoomData. */
+/*****************************************************************************/
+bool readRoomData(const char *fileName) {
+ byte **file;
+ uint16 Counter;
+ char Temp[5];
+
+ if ((file = g_music->newOpen(fileName)) != NULL) {
+ readBlock(Temp, 4L, file);
+ Temp[4] = '\0';
+
+ if (strcmp(Temp, "DOR1") != 0)
+ return false;
+
+ readBlock(&ManyRooms, 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&ManyRooms, 1);
+#endif
+ readBlock(&HighestCondition, 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&HighestCondition, 1);
+#endif
+
+ if (allocate((void **) &Rooms, (ManyRooms + 1) * sizeof(RoomData))) {
+ for (Counter = 1; Counter <= ManyRooms; Counter++) {
+ readBlock(&(Rooms[Counter].NorthDoor), 2L, file);
+ readBlock(&(Rooms[Counter].SouthDoor), 2L, file);
+ readBlock(&(Rooms[Counter].EastDoor), 2L, file);
+ readBlock(&(Rooms[Counter].WestDoor), 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&(Rooms[Counter].NorthDoor), 1);
+ swapUShortPtr(&(Rooms[Counter].SouthDoor), 1);
+ swapUShortPtr(&(Rooms[Counter].EastDoor), 1);
+ swapUShortPtr(&(Rooms[Counter].WestDoor), 1);
+#endif
+
+ readBlock(&(Rooms[Counter].WipeType), 1L, file);
+ }
+ } else
+ return false;
+ } else
+ return false;
+
+ return true;
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads in a NULL terminated string, and allocates memory for it. */
+/*****************************************************************************/
+static bool readString(char **string, byte **file) {
+ char len;
+ uint32 counter = 0L;
+
+
+ readBlock(&len, 1L, file);
+
+ if (len) {
+ counter = len;
+
+ if (rallocate((void **) string, counter)) {
+ readBlock(*string, counter, file);
+ (*string)[counter - 1] = 0; /* Sanity modification */
+ decrypt((byte *)*string);
+ return true;
+ }
+ } else {
+ *string = NULL;
+ return true;
+ }
+
+ return false;
+}
+
+
+
+/*****************************************************************************/
+/* Reads in the Inventory data. */
+/*****************************************************************************/
+bool readInventory(const char *fileName) {
+ byte **file;
+ uint16 Counter;
+ char Temp[5];
+
+ if ((file = g_music->newOpen(fileName)) != NULL) {
+ readBlock(Temp, 4L, file);
+ Temp[4] = '\0';
+
+ if (strcmp(Temp, "INV1") != 0)
+ return false;
+
+ readBlock(&NumInv, 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&NumInv, 1);
+#endif
+ UseMemory = true;
+
+ if (rallocate((void **) &Inventory, (NumInv + 1) * sizeof(InventoryData))) {
+ for (Counter = 1; Counter <= NumInv; Counter++) {
+ readBlock(&(Inventory[Counter].Many), 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&(Inventory[Counter].Many), 1);
+#endif
+
+ if (!readString(&(Inventory[Counter].name), file)) {
+ UseMemory = false;
+ return false;
+ }
+
+ if (!readString(&(Inventory[Counter].BInvName), file)) {
+ UseMemory = false;
+ return false;
+ }
+ }
+ } else {
+ UseMemory = false;
+ return false;
+ }
+ } else
+ return false;
+
+ UseMemory = false;
+ return true;
+}
+
+
+
+
+
+
+/*****************************************************************************/
+/* Converts a number to a string. */
+/*****************************************************************************/
+char *numtostr(char *text, uint16 Num) {
+ uint16 Counter = 0;
+
+ if (Num == 0) {
+ text[0] = '0';
+ text[1] = 0;
+ return text;
+ }
+
+ strcpy(text, "00000");
+
+ if (Num >= 10000) {
+ text[0] = (Num / 10000) + '0';
+ Num -= (Num / 10000) * 10000;
+ }
+
+ if (Num >= 1000) {
+ text[1] = (Num / 1000) + '0';
+ Num -= (Num / 1000) * 1000;
+ }
+
+ if (Num >= 100) {
+ text[2] = (Num / 100) + '0';
+ Num -= (Num / 100) * 100;
+ }
+
+ if (Num >= 10) {
+ text[3] = (Num / 10) + '0';
+ Num -= (Num / 10) * 10;
+ }
+
+ text[4] = Num + '0';
+ text[5] = 0;
+
+ while (text[Counter] == '0')
+ Counter++;
+
+ return (&text[Counter]);
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Reads in a list of conditions. */
+/*****************************************************************************/
+static int16 *readConditions(byte **file) {
+ int16 Counter = 0, last, list[25], *ptr;
+
+ do {
+ readBlock(&last, 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr((uint16 *)&last, 1);
+#endif
+
+ if (Counter < 25) {
+ list[Counter] = last;
+ Counter++;
+ } else
+ list[Counter] = 0;
+ } while (last);
+
+ if (!rallocate((void **) & (ptr), Counter * 2L))
+ return NULL;
+
+ memcpy(ptr, list, (size_t)(Counter * 2L));
+
+ return ptr;
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads in some CloseUp data. */
+/*****************************************************************************/
+static bool readCloseUps(CloseDataPtr *CPtr, uint16 depth, byte **file) {
+ char c;
+
+ while (1) {
+ *CPtr = NULL;
+
+ readBlock(&c, 1L, file);
+
+ if (c != '\0') {
+ if (rallocate((void **) CPtr, sizeof(CloseData))) {
+ (*CPtr)->SubCloseUps = NULL;
+ (*CPtr)->NextCloseUp = NULL;
+ (*CPtr)->depth = depth;
+
+ readBlock(*CPtr, 10L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr((uint16 *)*CPtr, 5);
+#endif
+
+ if (!readString(&((*CPtr)->GraphicName), file))
+ return false;
+
+ if (!readString(&((*CPtr)->Message), file))
+ return false;
+
+ if (!readCloseUps(&((*CPtr)->SubCloseUps), depth + 1, file))
+ return false;
+
+ CPtr = &((*CPtr)->NextCloseUp);
+ } else
+ return false;
+ } else
+ return true;
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads in a View. */
+/*****************************************************************************/
+static bool readView(ViewDataPtr *VPtr, byte **file) {
+ char c;
+
+ while (1) {
+ *VPtr = NULL;
+
+ readBlock(&c, 1L, file);
+
+ if (c == 1) {
+ if (rallocate((void **) VPtr, sizeof(viewData))) {
+ (*VPtr)->closeUps = NULL;
+ (*VPtr)->NextCondition = NULL;
+
+ (*VPtr)->Condition = readConditions(file);
+
+ if (!(*VPtr)->Condition)
+ return false;
+
+ if (!readString(&((*VPtr)->GraphicName), file))
+ return false;
+
+ readCloseUps(&((*VPtr)->closeUps), 0, file);
+
+ VPtr = &((*VPtr)->NextCondition);
+ } else
+ return false;
+ } else
+ return true;
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads in an Action. */
+/*****************************************************************************/
+static bool readAction(ActionPtr *APtr, byte **file) {
+ char c;
+ byte **ptrarray;
+ uint16 counter;
+
+ while (1) {
+ *APtr = NULL;
+
+ readBlock(&c, 1L, file);
+
+ if (c == 1) {
+ if (rallocate((void **) APtr, sizeof(Action))) {
+ readBlock(*APtr, 8L, file);
+#if !defined(DOSCODE)
+ swapShortPtr((int16 *)*APtr, 4);
+#endif
+
+ if ((*APtr)->ActionType == SHOWMESSAGES) {
+ if (!rallocate((void **) &ptrarray, 4L * (*APtr)->Param1))
+ return false;
+
+ for (counter = 0; counter < (*APtr)->Param1; counter++)
+ readString((char **) & (ptrarray[counter]), file);
+
+ (*APtr)->Data = (byte *)ptrarray;
+ } else
+ readString((char **) & ((*APtr)->Data), file);
+
+ APtr = &((*APtr)->NextAction);
+ } else
+ return false;
+ } else
+ return true;
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Reads in a rule. */
+/*****************************************************************************/
+static bool readRule(RulePtr *RPtr, byte **file) {
+ char c;
+
+ while (1) {
+ *RPtr = NULL;
+ readBlock(&c, 1L, file);
+
+ if (c == 1) {
+ if (rallocate((void **) RPtr, sizeof(Rule))) {
+ readBlock(*RPtr, 6L, file);
+#if !defined(DOSCODE)
+ swapShortPtr((int16 *)*RPtr, 3);
+#endif
+ (*RPtr)->Condition = readConditions(file);
+
+ if (!(*RPtr)->Condition)
+ return false;
+
+ readAction(&((*RPtr)->ActionList), file);
+ } else
+ return false;
+
+ RPtr = &((*RPtr)->NextRule);
+ } else
+ return true;
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Reads in the views of a room. */
+/*****************************************************************************/
+bool readViews(uint16 RoomNum, const char *Path) {
+ char Temp[10], *RoomString, fileName[250];
+ byte **file;
+
+ allocroom = RoomNum;
+
+ RoomString = numtostr(Temp, RoomNum);
+ strcpy(fileName, Path);
+ strcat(fileName, RoomString);
+
+ if ((file = g_music->newOpen(fileName)) != NULL) {
+ readBlock(Temp, 4L, file);
+ Temp[4] = '\0';
+
+ if (strcmp(Temp, "ROM4") != 0)
+ return false;
+
+ readString(&(Rooms[RoomNum].RoomMsg), file);
+
+ readView(&Rooms[RoomNum].NorthView, file);
+ g_music->checkMusic();
+
+ readView(&Rooms[RoomNum].SouthView, file);
+ g_music->checkMusic();
+
+ readView(&Rooms[RoomNum].EastView, file);
+ g_music->checkMusic();
+
+ readView(&Rooms[RoomNum].WestView, file);
+ g_music->checkMusic();
+
+ readRule(&Rooms[RoomNum].RuleList, file);
+
+ return true;
+ } else
+ return false;
+
+ return false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads the initial conditions and sets the LargeSet accordingly. */
+/*****************************************************************************/
+bool readInitialConditions(LargeSet conditions, const char *fileName) {
+ byte **file;
+ uint16 many, set;
+ char temp[5];
+
+ if ((file = g_music->newOpen(fileName)) != NULL) {
+ readBlock(temp, 4L, file);
+ temp[4] = '\0';
+
+ if (strcmp(temp, "CON0") != 0)
+ return false;
+
+ readBlock(&many, 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&many, 1);
+#endif
+
+ for (int counter = 0; counter < many; counter++) {
+ readBlock(&set, 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&set, 1);
+#endif
+ inclElement(conditions, set);
+ }
+ } else
+ return false;
+
+ return true;
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/savegame.cpp b/engines/lab/savegame.cpp
new file mode 100644
index 0000000000..ed25c38ef2
--- /dev/null
+++ b/engines/lab/savegame.cpp
@@ -0,0 +1,323 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/labfun.h"
+#include "lab/modernsavegame.h"
+
+namespace Lab {
+
+/* The version string */
+#if defined(DOSCODE)
+#define SAVEVERSION "LBS2"
+#else
+#define SAVEVERSION "LBS3"
+#define SAVEVERSION_COMPAT "LBS2"
+#endif
+
+#define BOOKMARK 0
+#define CARDMARK 1
+#define FLOPPY 2
+
+typedef void *LABFH;
+#define INVALID_LABFH NULL
+
+uint16 FileType, FileNum;
+
+
+
+/*----- The Amiga specific area of saveGame.c -----*/
+
+
+/*****************************************************************************/
+/* Opens a file to write to from disk. */
+/*****************************************************************************/
+static LABFH saveGameOpen(char *filename, bool iswrite) {
+ warning("STUB: saveGameOpen");
+ return 0;
+
+#if 0
+ if (iswrite) {
+ unlink(filename);
+ return fopen(filename, "wb");
+ } else
+ return fopen(filename, "rb");
+#endif
+}
+
+
+
+
+/*****************************************************************************/
+/* Closes a file. */
+/*****************************************************************************/
+static void saveGameClose(LABFH file, bool iswrite) {
+ warning("STUB: saveGameClose");
+ return;
+
+#if 0
+ if (file != INVALID_LABFH)
+ fclose(file);
+#endif
+}
+
+
+
+
+/*****************************************************************************/
+/* Writes a block of memory to whatever it is that we're writing to. */
+/*****************************************************************************/
+static void saveGameWriteBlock(LABFH file, void *data, uint32 size) {
+ warning("STUB: saveGameWriteBlock");
+ return;
+
+ //fwrite(data, 1, size, file);
+}
+
+
+
+/*****************************************************************************/
+/* Writes a block of memory to whatever it is that we're writing to. */
+/*****************************************************************************/
+static void saveGameReadBlock(LABFH file, void *data, uint32 size) {
+ warning("STUB: saveGameReadBlock");
+ return;
+
+ //fread(data, 1, size, file);
+}
+
+
+
+
+/*----- The machine independent section of saveGame.c -----*/
+
+
+/* Lab: Labyrinth specific */
+extern uint16 combination[6];
+extern uint16 CurTile[4] [4];
+
+#if !defined(DOSCODE)
+extern CrumbData BreadCrumbs[MAX_CRUMBS];
+extern uint16 NumCrumbs;
+extern bool DroppingCrumbs;
+extern bool FollowingCrumbs;
+#endif
+
+/*****************************************************************************/
+/* Writes the game out to disk. */
+/* Assumes that the file has already been openned and is there. */
+/*****************************************************************************/
+static bool saveGame(uint16 RoomNum, uint16 Direction, uint16 Quarters, LargeSet set1, LargeSet set2, LABFH file) {
+#if !defined(DOSCODE)
+ uint16 temp;
+ CrumbData crumbs[sizeof(BreadCrumbs) / sizeof(CrumbData)];
+#endif
+ uint16 last, counter, counter1;
+ char c;
+
+ saveGameWriteBlock(file, (void *)SAVEVERSION, 4L);
+#if defined(DOSCODE)
+ saveGameWriteBlock(file, &RoomNum, 2L);
+ saveGameWriteBlock(file, &Direction, 2L);
+ saveGameWriteBlock(file, &Quarters, 2L);
+#else
+ temp = swapUShort(RoomNum);
+ saveGameWriteBlock(file, &temp, 2L);
+ temp = swapUShort(Direction);
+ saveGameWriteBlock(file, &temp, 2L);
+ temp = swapUShort(Quarters);
+ saveGameWriteBlock(file, &temp, 2L);
+#endif
+
+ last = set1->lastElement / 8;
+ saveGameWriteBlock(file, &(set1->array[0]), (uint32) last);
+
+ last = set2->lastElement / 8;
+ saveGameWriteBlock(file, &(set2->array[0]), (uint32) last);
+
+ /* LAB: the combination lock and tile stuff */
+ for (counter = 0; counter < 6; counter++) {
+ c = (char)combination[counter];
+ saveGameWriteBlock(file, &c, 1L);
+ }
+
+ for (counter = 0; counter < 4; counter++)
+ for (counter1 = 0; counter1 < 4; counter1++)
+#if defined(DOSCODE)
+ saveGameWriteBlock(file, &(CurTile[counter] [counter1]), 2L);
+
+#else
+ {
+ temp = swapUShort(CurTile[counter] [counter1]);
+ saveGameWriteBlock(file, &temp, 2L);
+ }
+#endif
+
+#if !defined(DOSCODE)
+ saveGameWriteBlock(file, g_SaveGameImage, SAVED_IMAGE_SIZE);
+ memcpy(crumbs, BreadCrumbs, sizeof BreadCrumbs);
+ swapUShortPtr(&crumbs[0].RoomNum, sizeof(BreadCrumbs) / sizeof(uint16));
+ saveGameWriteBlock(file, crumbs, sizeof BreadCrumbs);
+#endif
+
+ saveGameClose(file, true);
+
+ return true;
+}
+
+
+
+/*****************************************************************************/
+/* Reads the game from disk. */
+/* Assumes that the file has already been openned and is there. */
+/*****************************************************************************/
+static bool loadGame(uint16 *RoomNum, uint16 *Direction, uint16 *Quarters, LargeSet set1, LargeSet set2, LABFH file) {
+#if !defined(DOSCODE)
+ uint16 t;
+ CrumbData crumbs[sizeof(BreadCrumbs) / sizeof(CrumbData)];
+#endif
+ char temp[5], c;
+ uint16 last, counter, counter1;
+
+ saveGameReadBlock(file, temp, 4L);
+ temp[4] = 0;
+
+ /*
+ if (strcmp(temp, SAVEVERSION) != 0)
+ {
+ saveGameClose(file, false);
+ return false;
+ }
+ */
+
+#if defined(DOSCODE)
+ saveGameReadBlock(file, RoomNum, 2L);
+ saveGameReadBlock(file, Direction, 2L);
+ saveGameReadBlock(file, Quarters, 2L);
+#else
+ saveGameReadBlock(file, &t, 2L);
+ *RoomNum = swapUShort(t);
+ saveGameReadBlock(file, &t, 2L);
+ *Direction = swapUShort(t);
+ saveGameReadBlock(file, &t, 2L);
+ *Quarters = swapUShort(t);
+#endif
+
+ last = set1->lastElement / 8;
+ saveGameReadBlock(file, &(set1->array[0]), (uint32) last);
+
+ last = set2->lastElement / 8;
+ saveGameReadBlock(file, &(set2->array[0]), (uint32) last);
+
+ /* LAB: the combination lock and tile stuff */
+ for (counter = 0; counter < 6; counter++) {
+ saveGameReadBlock(file, &c, 1L);
+ combination[counter] = c;
+ }
+
+ for (counter = 0; counter < 4; counter++)
+ for (counter1 = 0; counter1 < 4; counter1++)
+#if defined(DOSCODE)
+ saveGameReadBlock(file, &(CurTile[counter] [counter1]), 2L);
+
+#else
+ {
+ saveGameReadBlock(file, &t, 2L);
+ CurTile[counter] [counter1] = swapUShort(t);
+ }
+#endif
+
+ if (strcmp(temp, SAVEVERSION) == 0) {
+ saveGameReadBlock(file, g_SaveGameImage, SAVED_IMAGE_SIZE);
+
+ memset(crumbs, 0, sizeof BreadCrumbs);
+ saveGameReadBlock(file, crumbs, sizeof BreadCrumbs);
+ swapUShortPtr(&crumbs[0].RoomNum, sizeof(BreadCrumbs) / sizeof(uint16));
+ memcpy(BreadCrumbs, crumbs, sizeof BreadCrumbs);
+ DroppingCrumbs = (BreadCrumbs[0].RoomNum != 0);
+ FollowingCrumbs = false;
+
+ for (counter = 0; counter < MAX_CRUMBS; counter++)
+ if (BreadCrumbs[counter].RoomNum == 0) break;
+
+ NumCrumbs = counter;
+ }
+
+ saveGameClose(file, false);
+
+ return true;
+}
+
+
+
+
+/*****************************************************************************/
+/* Saves the game to the floppy disk. */
+/*****************************************************************************/
+bool saveFloppy(char *path, uint16 RoomNum, uint16 Direction, uint16 NumQuarters, LargeSet Conditions, LargeSet Rooms, uint16 filenum, uint16 type) {
+ LABFH FPtr;
+
+ g_music->checkMusic();
+
+ FileType = type;
+ FileNum = filenum;
+
+ if ((FPtr = saveGameOpen(path, true)) != INVALID_LABFH)
+ saveGame(RoomNum, Direction, NumQuarters, Conditions, Rooms, FPtr);
+ else
+ return false;
+
+ return true;
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads the game from the floppy disk. */
+/*****************************************************************************/
+bool readFloppy(char *path, uint16 *RoomNum, uint16 *Direction, uint16 *NumQuarters, LargeSet Conditions, LargeSet Rooms, uint16 filenum, uint16 type) {
+ LABFH FPtr;
+
+ g_music->checkMusic();
+
+ FileType = type;
+ FileNum = filenum;
+
+ if ((FPtr = saveGameOpen(path, false)) != INVALID_LABFH) {
+ if (!loadGame(RoomNum, Direction, NumQuarters, Conditions, Rooms, FPtr))
+ return false;
+ } else
+ return false;
+
+ return true;
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/savegamepalmap.cpp b/engines/lab/savegamepalmap.cpp
new file mode 100644
index 0000000000..786a5571e6
--- /dev/null
+++ b/engines/lab/savegamepalmap.cpp
@@ -0,0 +1,3316 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+ /*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/lab.h"
+
+ namespace Lab {
+
+ const byte ThePalMap[] = {
+ 0x73, 0x73, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68,
+ 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x1E, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1,
+ 0xE1, 0xE1, 0x73, 0x2F, 0x68, 0x68, 0x68, 0x68, 0x68, 0x68,
+ 0x68, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE1, 0xE1, 0xE1, 0x67, 0x67, 0x2F, 0x68, 0x68, 0x68,
+ 0x37, 0x37, 0x37, 0x20, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE2, 0xF7, 0xF7, 0xF7, 0xF7, 0x67, 0x67, 0x67, 0x72,
+ 0x72, 0x37, 0x37, 0x37, 0x37, 0x23, 0x23, 0x23, 0x23, 0x23,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2,
+ 0xE2, 0xE2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x67, 0x67,
+ 0x67, 0x72, 0x37, 0x37, 0x37, 0x37, 0x71, 0x23, 0x23, 0x23,
+ 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x67, 0x67, 0x67, 0x37, 0x37, 0x37, 0x37, 0x71, 0x23, 0x23,
+ 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x67, 0x67, 0x67, 0x37, 0x37, 0x37, 0x71, 0x71,
+ 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x67, 0x67, 0x37, 0x37, 0x71, 0x71,
+ 0x71, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x67, 0x67, 0x37, 0x71,
+ 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xF3, 0xF3, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x67, 0x67,
+ 0x71, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x60, 0x60, 0x71, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x71, 0x71, 0x23, 0x5F, 0x5F,
+ 0x5F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x71, 0x5F, 0x5F,
+ 0x5F, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x1E, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xEA, 0xEA,
+ 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8,
+ 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
+ 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5,
+ 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5,
+ 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE5, 0xE5, 0xE5, 0x73, 0x2F, 0x68, 0x68, 0x68, 0x68,
+ 0x68, 0x68, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x1E,
+ 0x1E, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x2F, 0x2F, 0x2F, 0x2E,
+ 0x68, 0x68, 0x37, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x67, 0x2F,
+ 0x72, 0x72, 0x72, 0x37, 0x37, 0x20, 0x20, 0x20, 0x23, 0x23,
+ 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1,
+ 0x67, 0x24, 0x72, 0x72, 0x37, 0x37, 0x37, 0x20, 0x20, 0x23,
+ 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x67, 0x67, 0x72, 0x37, 0x37, 0x37, 0x37, 0x71,
+ 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x67, 0x67, 0x37, 0x37, 0x37, 0x37,
+ 0x71, 0x23, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x67, 0x67, 0x37, 0x37,
+ 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x67, 0x37,
+ 0x37, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x60, 0x60, 0x71, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0x23,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x60, 0x60, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23,
+ 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D,
+ 0x3D, 0xF3, 0xF3, 0xF3, 0xF3, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x71, 0x71, 0x23,
+ 0x23, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D,
+ 0x3D, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x71,
+ 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D,
+ 0x3D, 0x3D, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60,
+ 0x60, 0x60, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x1E, 0x1E, 0x3D,
+ 0x3D, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE5, 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA,
+ 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8,
+ 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6,
+ 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5, 0x66, 0x22,
+ 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x23, 0x23, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1,
+ 0x22, 0x22, 0x2E, 0x2E, 0x2E, 0x37, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1,
+ 0xE1, 0xE1, 0x24, 0x24, 0x72, 0x72, 0x37, 0x37, 0x20, 0x20,
+ 0x20, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE1, 0xE1, 0xE1, 0x24, 0x24, 0x72, 0x37, 0x37, 0x37,
+ 0x20, 0x20, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE2, 0xF7, 0xF7, 0xF7, 0xF7, 0x24, 0x24, 0x37, 0x37,
+ 0x37, 0x37, 0x71, 0x23, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE,
+ 0xDE, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x24, 0x24,
+ 0x37, 0x37, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0x23, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x24, 0x37, 0x37, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23, 0x23,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x60, 0x60, 0x71, 0x71, 0x71, 0x71, 0x23, 0x23,
+ 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x71, 0x71, 0x71, 0x23,
+ 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x3D, 0xDF, 0xDF, 0xDF, 0xDF, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x71,
+ 0x71, 0x23, 0x23, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x3D, 0x3D, 0x29, 0xF3, 0xF3, 0xF3, 0xF3, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60,
+ 0x60, 0x71, 0x23, 0x5F, 0x5F, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x29, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x60, 0x60, 0x60, 0x60, 0x5F, 0x5F, 0x5F, 0x5F, 0x5F, 0x1E,
+ 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x3D, 0x29, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x60, 0x5F, 0x5F, 0x5F, 0x5F,
+ 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x3D, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0x3D, 0x3D, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xEA, 0xEA, 0xEA, 0xEA,
+ 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8,
+ 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6,
+ 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5, 0xEA, 0xEA,
+ 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8,
+ 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
+ 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5,
+ 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5,
+ 0xE5, 0xE5, 0x66, 0x22, 0x2E, 0x2E, 0x2E, 0x2E, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x1E, 0xE4, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE1, 0xE1, 0xE1, 0x22, 0x22, 0x2E, 0x2E, 0x2E, 0x20,
+ 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x24, 0x24, 0x01, 0x01,
+ 0x37, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x24, 0x24,
+ 0x01, 0x37, 0x37, 0x20, 0x20, 0x20, 0x23, 0x23, 0x23, 0x23,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1,
+ 0x24, 0x24, 0x37, 0x37, 0x71, 0x71, 0x71, 0x23, 0x23, 0x23,
+ 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x24, 0x37, 0x37, 0x71, 0x71, 0x71, 0x23, 0x23,
+ 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x71, 0x71, 0x71, 0x71,
+ 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x71, 0x71,
+ 0x71, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE,
+ 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60,
+ 0x60, 0x71, 0x71, 0x23, 0x23, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x3D, 0x3D, 0xDF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x60, 0x60, 0x60, 0x71, 0x23, 0x5F, 0x5F, 0x5F, 0x5F, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x29, 0x29, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x60, 0x5F, 0x5F, 0x5F, 0x5F,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x3D, 0x29, 0x29,
+ 0x29, 0xF3, 0xF3, 0xF3, 0xF3, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x60, 0x5F, 0x5F,
+ 0x5F, 0x5F, 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x29,
+ 0x29, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x60,
+ 0x5F, 0x5F, 0x5F, 0x5F, 0x70, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0x70, 0x3D, 0x3D, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB,
+ 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5,
+ 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE5, 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5, 0x65, 0x65, 0x2E, 0x2E,
+ 0x2E, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23, 0x1E,
+ 0xE4, 0xE4, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x65, 0x65,
+ 0x01, 0x01, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23,
+ 0x1E, 0x1E, 0x1E, 0xE4, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1,
+ 0x24, 0x01, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20, 0x23, 0x23,
+ 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1,
+ 0xE1, 0xE1, 0x24, 0x00, 0x00, 0x00, 0x20, 0x20, 0x20, 0x23,
+ 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE1, 0xE1, 0xE1, 0x00, 0x00, 0x00, 0x00, 0x71, 0x71,
+ 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE,
+ 0xDE, 0xDE, 0xDE, 0xDD, 0xDD, 0xDD, 0x60, 0x12, 0x12, 0x71,
+ 0x71, 0x71, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE,
+ 0xDE, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60,
+ 0x12, 0x71, 0x71, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x60, 0x60, 0x60, 0x71, 0x71, 0x23, 0x23, 0x5F, 0x5F, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x71, 0x23, 0x5F, 0x5F, 0x5F,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x29,
+ 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x60, 0x5F, 0x5F,
+ 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x3D,
+ 0x29, 0x29, 0x29, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x60,
+ 0x5F, 0x5F, 0x5F, 0x5F, 0x1E, 0x1E, 0x3D, 0x3D, 0x3D, 0x3D,
+ 0x3D, 0x29, 0x29, 0x29, 0x29, 0xDC, 0xDC, 0xDC, 0xDC, 0xDB,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60,
+ 0x60, 0x60, 0x5F, 0x5F, 0x5F, 0x5F, 0x70, 0x3D, 0x3D, 0x3D,
+ 0x3D, 0x3D, 0x29, 0x29, 0x29, 0x29, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x60, 0x60, 0x60, 0x60, 0x5F, 0x5F, 0x5F, 0x70, 0x70, 0x3D,
+ 0x3D, 0x3D, 0x3D, 0x3D, 0x29, 0x29, 0x29, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0x70,
+ 0x70, 0x3D, 0x3D, 0x3D, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEB, 0xEB, 0xEB, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA,
+ 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8,
+ 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6,
+ 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5, 0xEA, 0xEA,
+ 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8,
+ 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
+ 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5,
+ 0x65, 0x65, 0x65, 0x00, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
+ 0x23, 0x23, 0xE4, 0xE4, 0xE4, 0xE4, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1,
+ 0xE1, 0xE1, 0x65, 0x65, 0x00, 0x00, 0x20, 0x20, 0x20, 0x20,
+ 0x20, 0x23, 0x23, 0x1C, 0x1E, 0x1E, 0xE4, 0xE4, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE1, 0xE1, 0xE1, 0x65, 0x00, 0x00, 0x00, 0x20, 0x20,
+ 0x20, 0x20, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E, 0xE4,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x00, 0x00, 0x00, 0x00,
+ 0x20, 0x20, 0x09, 0x23, 0x23, 0x23, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x60, 0x12,
+ 0x12, 0x12, 0x09, 0x09, 0x23, 0x23, 0x23, 0x23, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDD, 0xDD, 0xDD,
+ 0x60, 0x60, 0x12, 0x12, 0x09, 0x23, 0x23, 0x23, 0x23, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDD,
+ 0xDD, 0xDD, 0x60, 0x60, 0x12, 0x12, 0x71, 0x23, 0x23, 0x5F,
+ 0x1A, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x3A, 0x23, 0x5F,
+ 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D,
+ 0x10, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE,
+ 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x3A,
+ 0x3A, 0x5F, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x3D,
+ 0x3D, 0x3D, 0x29, 0x29, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE,
+ 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60,
+ 0x60, 0x3A, 0x5F, 0x5F, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x3D,
+ 0x3D, 0x3D, 0x3D, 0x29, 0x29, 0x29, 0xDF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x60, 0x60, 0x60, 0x3A, 0x5F, 0x5F, 0x5F, 0x5F, 0x1E, 0x3D,
+ 0x3D, 0x3D, 0x3D, 0x3D, 0x29, 0x29, 0x29, 0x29, 0xDC, 0xDC,
+ 0xDC, 0xDC, 0xDC, 0xDB, 0xDB, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x3A, 0x5F, 0x5F, 0x5F, 0x70,
+ 0x70, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x29, 0x29, 0x29, 0x29,
+ 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDB, 0xDB, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x60, 0x5F, 0x5F,
+ 0x70, 0x70, 0x70, 0x3D, 0x3D, 0x3D, 0x3D, 0x29, 0x29, 0x29,
+ 0x29, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0x70, 0x70, 0x70, 0x70, 0x3D, 0x3D, 0x29, 0x29,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xEA, 0xEA,
+ 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8,
+ 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7,
+ 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5,
+ 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5,
+ 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE5, 0xE5, 0xE5, 0x61, 0x61, 0x61, 0x61, 0x20, 0x20,
+ 0x20, 0x20, 0x20, 0x1C, 0x1C, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x61, 0x61, 0x61, 0x00,
+ 0x20, 0x20, 0x20, 0x20, 0x1C, 0x1C, 0x1C, 0x1E, 0xE4, 0xE4,
+ 0xE4, 0xE4, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x61, 0x61,
+ 0x00, 0x00, 0x20, 0x20, 0x20, 0x1C, 0x1C, 0x1C, 0x1C, 0x1E,
+ 0x1E, 0x1E, 0xE4, 0xE4, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1,
+ 0x00, 0x12, 0x12, 0x12, 0x17, 0x17, 0x1C, 0x1C, 0x1C, 0x1C,
+ 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1,
+ 0xE1, 0xE1, 0x60, 0x12, 0x12, 0x12, 0x17, 0x17, 0x1C, 0x1C,
+ 0x1C, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0xDF, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
+ 0xDE, 0xDD, 0xDD, 0xDD, 0x60, 0x60, 0x12, 0x12, 0x17, 0x1C,
+ 0x1C, 0x1C, 0x1A, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE,
+ 0xDE, 0xDE, 0xDE, 0xDD, 0xDD, 0xDD, 0x60, 0x60, 0x60, 0x17,
+ 0x3A, 0x1C, 0x5F, 0x1A, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x10, 0x10, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE,
+ 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDD, 0xDD, 0xDD, 0x60, 0x60,
+ 0x60, 0x3A, 0x3A, 0x5F, 0x5F, 0x5F, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x3D, 0x3D, 0x10, 0x29, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0x60, 0x60, 0x60, 0x3A, 0x3A, 0x5F, 0x5F, 0x5F, 0x1E, 0x1E,
+ 0x1E, 0x3D, 0x3D, 0x3D, 0x10, 0x29, 0x29, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x3A, 0x3A, 0x5F, 0x5F, 0x5F,
+ 0x1E, 0x3D, 0x3D, 0x3D, 0x3D, 0x3D, 0x29, 0x29, 0x29, 0x29,
+ 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x3A, 0x3A, 0x5F,
+ 0x5F, 0x70, 0x70, 0x3D, 0x3D, 0x3D, 0x3D, 0x29, 0x29, 0x29,
+ 0x29, 0x29, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDB, 0xDB, 0xDB,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x3A,
+ 0x3A, 0x5F, 0x70, 0x70, 0x70, 0x3D, 0x3D, 0x3D, 0x3D, 0x29,
+ 0x29, 0x29, 0x29, 0x29, 0xDC, 0xDC, 0xDC, 0xDC, 0xDC, 0xDB,
+ 0xDB, 0xDB, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60,
+ 0x60, 0x3A, 0x3A, 0x70, 0x70, 0x70, 0x70, 0x70, 0x3D, 0x3D,
+ 0x29, 0x29, 0x29, 0x29, 0x29, 0x29, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0xDC, 0xDB, 0xDB, 0xDB, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0x70, 0x70, 0x70, 0x70, 0x70,
+ 0x6F, 0x6F, 0x29, 0x29, 0x29, 0x29, 0x29, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7,
+ 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0x6F, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF7,
+ 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF7, 0xF7, 0xF7, 0xF7, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1,
+ 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6, 0xF5, 0xF5,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2, 0xF2, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6, 0xF6, 0xF6,
+ 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF2,
+ 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1, 0xF6, 0xF6,
+ 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF4, 0xF4,
+ 0xF4, 0xF4, 0xF4, 0xF4, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3, 0xF3,
+ 0xF3, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF2, 0xF1, 0xF1, 0xF1,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0, 0xF0, 0xF0,
+ 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED, 0xEC,
+ 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB, 0xF0, 0xF0,
+ 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEE, 0xEE,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB, 0xEB, 0xEB,
+ 0xF0, 0xF0, 0xF0, 0xF0, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF, 0xEF,
+ 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xEE, 0xED, 0xED, 0xED, 0xED,
+ 0xED, 0xED, 0xED, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEC, 0xEB,
+ 0xEB, 0xEB, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE7, 0xE7,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE5, 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA, 0xE9, 0xE9,
+ 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8, 0xE8,
+ 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6, 0xE6, 0xE6,
+ 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5, 0xEA, 0xEA, 0xEA, 0xEA,
+ 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8,
+ 0xE8, 0xE8, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE7, 0xE6,
+ 0xE6, 0xE6, 0xE6, 0xE6, 0xE6, 0xE5, 0xE5, 0xE5, 0x61, 0x61,
+ 0x61, 0x61, 0x61, 0x20, 0x20, 0x20, 0x1C, 0x1C, 0xE4, 0xE4,
+ 0xE4, 0xE4, 0xE4, 0xE4, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1,
+ 0x61, 0x61, 0x61, 0x0B, 0x31, 0x17, 0x17, 0x1C, 0x1C, 0x1C,
+ 0x1C, 0xE4, 0xE4, 0xE4, 0xE4, 0xE4, 0xE3, 0xE3, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2, 0xE1,
+ 0xE1, 0xE1, 0x61, 0x61, 0x0B, 0x12, 0x17, 0x17, 0x17, 0x1C,
+ 0x1C, 0x1C, 0x1E, 0x1E, 0x1E, 0xE4, 0xE4, 0xE4, 0xE3, 0xE3,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE1, 0xE1, 0xE1, 0x0B, 0x12, 0x12, 0x17, 0x17, 0x17,
+ 0x1C, 0x1C, 0x1C, 0x1C, 0x1E, 0x1E, 0x1E, 0x1E, 0xE4, 0xE4,
+ 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE3, 0xE2, 0xE2, 0xE2,
+ 0xE2, 0xE2, 0xE2, 0xE1, 0xE1, 0xE1, 0x60, 0x12, 0x12, 0x17,
+ 0x17, 0x17, 0x1C, 0x1C, 0x1C, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0xE0, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE,
+ 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDD, 0xDD, 0xDD, 0x60, 0x60,
+ 0x12, 0x17, 0x17, 0x17, 0x1C, 0x1A, 0x1A, 0x1E, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0xE0, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDD, 0xDD, 0xDD,
+ 0x60, 0x60, 0x60, 0x3A, 0x3A, 0x3A, 0x5F, 0x1A, 0x1E, 0x1E,
+ 0x1E, 0x1E, 0x1E, 0x3D, 0x10, 0x10, 0xDF, 0xDF, 0xDF, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE, 0xDD,
+ 0xDD, 0xDD, 0x60, 0x60, 0x60, 0x3A, 0x3A, 0x3A, 0x5F, 0x1A,
+ 0x1E, 0x1E, 0x1E, 0x3D, 0x3D, 0x10, 0x10, 0x10, 0x29, 0xDF,
+ 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE, 0xDE, 0xDE,
+ 0xDE, 0xDD, 0xDD, 0xDD, 0x60, 0x60, 0x60, 0x3A, 0x3A, 0x3A,
+ 0x5F, 0x5F, 0x1E, 0x3D, 0x3D, 0x3D, 0x3D, 0x10, 0x10, 0x29,
+ 0x29, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE, 0xDE, 0xDE,
+ 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60, 0x60, 0x3A,
+ 0x3A, 0x3A, 0x5F, 0x70, 0x70, 0x3D, 0x3D, 0x3D, 0x10, 0x10,
+ 0x29, 0x29, 0x29, 0x29, 0xDF, 0xDF, 0xDF, 0xDF, 0xDF, 0xDE,
+ 0xDE, 0xDE, 0xDE, 0xF7, 0xF7, 0xF7, 0xF7, 0xF7, 0x60, 0x60,
+ 0x60, 0x3A, 0x3A, 0x5F, 0x70, 0x70, 0x70, 0x3D, 0x3D, 0x3D,
+ 0x10, 0x29, 0x29, 0x29, 0x29, 0x29, 0xDC, 0xDC, 0xDC, 0xDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7, 0XF7, 0XF7, 0XF7, 0XF7,
+ 0X60, 0X60, 0X60, 0X3A, 0X3A, 0X70, 0X70, 0X70, 0X70, 0X70,
+ 0X3D, 0X3D, 0X29, 0X29, 0X29, 0X29, 0X29, 0X29, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7, 0XF7, 0XF7,
+ 0XF7, 0XF7, 0X60, 0X60, 0X60, 0X3A, 0X70, 0X70, 0X70, 0X70,
+ 0X70, 0X70, 0X6F, 0X6F, 0X29, 0X29, 0X29, 0X29, 0X29, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7,
+ 0XF7, 0XF7, 0XF7, 0XF7, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X70,
+ 0X70, 0X70, 0X70, 0X6F, 0X6F, 0X6F, 0X29, 0X29, 0X29, 0X29,
+ 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XF7, 0XF7, 0XF7, 0XF7, 0XF7, 0XF6, 0XF6, 0XF6, 0XF6,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0X6F, 0X6F, 0X6F, 0X29, 0X29,
+ 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF7, 0XF7, 0XF7, 0XF7, 0XF7, 0XF6, 0XF6,
+ 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF7, 0XF7, 0XF7, 0XF7,
+ 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1,
+ 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2,
+ 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6,
+ 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1,
+ 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1,
+ 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2,
+ 0XF2, 0XF1, 0XF1, 0XF1, 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF,
+ 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE,
+ 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC,
+ 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0,
+ 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE,
+ 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC,
+ 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0,
+ 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE,
+ 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED,
+ 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB,
+ 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF,
+ 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED,
+ 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB,
+ 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF,
+ 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED,
+ 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC,
+ 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF,
+ 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE,
+ 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC,
+ 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB, 0XEA, 0XEA, 0XEA, 0XEA,
+ 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE8, 0XE8, 0XE8, 0XE8,
+ 0XE8, 0XE8, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE6,
+ 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE5, 0XE5, 0XE5, 0XEA, 0XEA,
+ 0XEA, 0XEA, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE8, 0XE8,
+ 0XE8, 0XE8, 0XE8, 0XE8, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7,
+ 0XE7, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE5, 0XE5, 0XE5,
+ 0XEA, 0XEA, 0XEA, 0XEA, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9,
+ 0XE8, 0XE8, 0XE8, 0XE8, 0XE8, 0XE8, 0XE7, 0XE7, 0XE7, 0XE7,
+ 0XE7, 0XE7, 0XE7, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE5,
+ 0XE5, 0XE5, 0X64, 0X64, 0X64, 0X0B, 0X31, 0X31, 0X31, 0X5D,
+ 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE1, 0XE1, 0XE1, 0X64, 0X64, 0X0B, 0X0B, 0X31, 0X31,
+ 0X31, 0X1C, 0X1C, 0X1C, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X0B, 0X0B, 0X0B, 0X31,
+ 0X31, 0X31, 0X17, 0X1C, 0X1C, 0X1C, 0X1E, 0XE4, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X0B, 0X0B,
+ 0X31, 0X31, 0X31, 0X17, 0X17, 0X1C, 0X1C, 0X1E, 0X1E, 0X1E,
+ 0X1E, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1,
+ 0X0B, 0X0B, 0X31, 0X31, 0X17, 0X17, 0X1C, 0X1C, 0X1A, 0X1E,
+ 0X1E, 0X1E, 0X1E, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X60, 0X0F, 0X0F, 0X17, 0X3A, 0X3A, 0X1C, 0X1A,
+ 0X1A, 0X1E, 0X1E, 0X1E, 0X1E, 0X10, 0XE0, 0XE0, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X60, 0X60, 0X0F, 0X3A, 0X3A, 0X3A,
+ 0X1A, 0X1A, 0X1E, 0X1E, 0X1E, 0X1E, 0X10, 0X10, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X60, 0X60, 0X60, 0X3A,
+ 0X3A, 0X3A, 0X1A, 0X1F, 0X1F, 0X1F, 0X3D, 0X3D, 0X10, 0X10,
+ 0X10, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X60, 0X60,
+ 0X60, 0X3A, 0X3A, 0X3A, 0X5F, 0X70, 0X70, 0X3D, 0X3D, 0X10,
+ 0X10, 0X10, 0X29, 0X29, 0X29, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X60, 0X60, 0X60, 0X3A, 0X3A, 0X3A, 0X70, 0X70, 0X70, 0X3D,
+ 0X3D, 0X10, 0X10, 0X29, 0X29, 0X29, 0X29, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XF7, 0XF7,
+ 0XF7, 0XF7, 0X60, 0X60, 0X60, 0X3A, 0X3A, 0X70, 0X70, 0X70,
+ 0X70, 0X70, 0X3D, 0X10, 0X29, 0X29, 0X29, 0X29, 0X29, 0X29,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XF7, 0XF7, 0XF7, 0XF7, 0X60, 0X60, 0X60, 0X3A, 0X3A, 0X70,
+ 0X70, 0X70, 0X70, 0X70, 0X6F, 0X6F, 0X29, 0X29, 0X29, 0X29,
+ 0X29, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XF7, 0XF7, 0XF7, 0XF7, 0X5A, 0X5A, 0X5A, 0X5A,
+ 0X59, 0X70, 0X70, 0X70, 0X70, 0X6F, 0X6F, 0X6F, 0X29, 0X29,
+ 0X29, 0X29, 0X29, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XF7, 0XF7, 0XF7, 0XF7, 0X5A, 0X5A,
+ 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X70, 0X6F, 0X6F, 0X6F, 0X6F,
+ 0X29, 0X29, 0X29, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7, 0XF7, 0XF7, 0XF7,
+ 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X6F, 0X6F,
+ 0X6F, 0X6F, 0X29, 0X29, 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7, 0XF7,
+ 0XF7, 0XF7, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0X6F, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2,
+ 0XF7, 0XF7, 0XF7, 0XF7, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6,
+ 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1,
+ 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1,
+ 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2,
+ 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1, 0XF0, 0XF0,
+ 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE,
+ 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED,
+ 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB,
+ 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF,
+ 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED,
+ 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB,
+ 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF,
+ 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED,
+ 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC,
+ 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF,
+ 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE,
+ 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC,
+ 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0,
+ 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE,
+ 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC,
+ 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0,
+ 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE,
+ 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED,
+ 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB,
+ 0XEA, 0XEA, 0XEA, 0XEA, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9,
+ 0XE8, 0XE8, 0XE8, 0XE8, 0XE8, 0XE8, 0XE7, 0XE7, 0XE7, 0XE7,
+ 0XE7, 0XE7, 0XE7, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE5,
+ 0XE5, 0XE5, 0XEA, 0XEA, 0XEA, 0XEA, 0XE9, 0XE9, 0XE9, 0XE9,
+ 0XE9, 0XE9, 0XE8, 0XE8, 0XE8, 0XE8, 0XE8, 0XE8, 0XE7, 0XE7,
+ 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6,
+ 0XE6, 0XE5, 0XE5, 0XE5, 0XEA, 0XEA, 0XEA, 0XEA, 0XE9, 0XE9,
+ 0XE9, 0XE9, 0XE9, 0XE9, 0XE8, 0XE8, 0XE8, 0XE8, 0XE8, 0XE8,
+ 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE6, 0XE6, 0XE6,
+ 0XE6, 0XE6, 0XE6, 0XE5, 0XE5, 0XE5, 0X64, 0X64, 0X64, 0X0B,
+ 0X31, 0X31, 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X64, 0X0B,
+ 0X0B, 0X0B, 0X31, 0X31, 0X31, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1,
+ 0X0B, 0X0B, 0X0B, 0X31, 0X31, 0X31, 0X31, 0X16, 0X5D, 0X5D,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1,
+ 0XE1, 0XE1, 0X0B, 0X0B, 0X31, 0X31, 0X31, 0X31, 0X16, 0X16,
+ 0X16, 0X1F, 0X1F, 0X1F, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE1, 0XE1, 0XE1, 0X0B, 0X0F, 0X0F, 0X31, 0X16, 0X16,
+ 0X16, 0X16, 0X1F, 0X1F, 0X1F, 0X1F, 0XE0, 0XE0, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X0F, 0X0F, 0X0F, 0X0F,
+ 0X16, 0X16, 0X16, 0X16, 0X1F, 0X1F, 0X1F, 0X1F, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X60, 0X0F,
+ 0X0F, 0X0F, 0X16, 0X16, 0X16, 0X1F, 0X1F, 0X1F, 0X1F, 0X10,
+ 0X10, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X60, 0X0F, 0X0F, 0X0F, 0X3A, 0X3A, 0X1F, 0X1F, 0X1F, 0X1F,
+ 0X10, 0X10, 0X10, 0X10, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X60, 0X60, 0X0F, 0X3A, 0X3A, 0X3A, 0X1F, 0X1F,
+ 0X70, 0X3D, 0X10, 0X10, 0X10, 0X10, 0X29, 0X29, 0X29, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X60, 0X60, 0X3A, 0X3A, 0X3A, 0X3A,
+ 0X70, 0X70, 0X70, 0X70, 0X10, 0X10, 0X10, 0X29, 0X29, 0X29,
+ 0X29, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X60, 0X07, 0X07, 0X07,
+ 0X3A, 0X70, 0X70, 0X70, 0X70, 0X70, 0X10, 0X10, 0X29, 0X29,
+ 0X29, 0X29, 0X29, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7, 0XF7, 0XF7, 0X5A, 0X5A,
+ 0X5A, 0X07, 0X59, 0X70, 0X70, 0X70, 0X70, 0X6F, 0X6F, 0X6F,
+ 0X29, 0X29, 0X29, 0X29, 0X29, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7, 0XF7, 0XF7,
+ 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X70, 0X6F, 0X6F,
+ 0X6F, 0X6F, 0X29, 0X29, 0X29, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7,
+ 0XF7, 0XF7, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59,
+ 0X6F, 0X6F, 0X6F, 0X6F, 0X29, 0X29, 0X3E, 0X3E, 0X3E, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XF7, 0XF7, 0XF7, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59,
+ 0X59, 0X59, 0X59, 0X6F, 0X6F, 0X6F, 0X3E, 0X3E, 0X3E, 0X3E,
+ 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XF7, 0XF7, 0XF7, 0X5A, 0X5A, 0X5A, 0X5A,
+ 0X59, 0X59, 0X59, 0X59, 0X59, 0X6F, 0X6F, 0X6F, 0X3E, 0X3E,
+ 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XF7, 0XF7, 0XF7, 0XF6, 0XF6,
+ 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1,
+ 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1,
+ 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2,
+ 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4,
+ 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6, 0XF6, 0XF6,
+ 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF2,
+ 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1, 0XF6, 0XF6,
+ 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF4, 0XF4,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1, 0XF1, 0XF1,
+ 0XF6, 0XF6, 0XF6, 0XF6, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5, 0XF5,
+ 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF4, 0XF3, 0XF3, 0XF3, 0XF3,
+ 0XF3, 0XF3, 0XF3, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF2, 0XF1,
+ 0XF1, 0XF1, 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF,
+ 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED,
+ 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC,
+ 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF,
+ 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE,
+ 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC,
+ 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0,
+ 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE,
+ 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC,
+ 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB, 0XF0, 0XF0,
+ 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEE, 0XEE,
+ 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED, 0XED, 0XED,
+ 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB, 0XEB, 0XEB,
+ 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF, 0XEF,
+ 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED, 0XED, 0XED,
+ 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC, 0XEB,
+ 0XEB, 0XEB, 0XF0, 0XF0, 0XF0, 0XF0, 0XEF, 0XEF, 0XEF, 0XEF,
+ 0XEF, 0XEF, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XEE, 0XED, 0XED,
+ 0XED, 0XED, 0XED, 0XED, 0XED, 0XEC, 0XEC, 0XEC, 0XEC, 0XEC,
+ 0XEC, 0XEB, 0XEB, 0XEB, 0XEA, 0XEA, 0XEA, 0XEA, 0XE9, 0XE9,
+ 0XE9, 0XE9, 0XE9, 0XE9, 0XE8, 0XE8, 0XE8, 0XE8, 0XE8, 0XE8,
+ 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE6, 0XE6, 0XE6,
+ 0XE6, 0XE6, 0XE6, 0XE5, 0XE5, 0XE5, 0XEA, 0XEA, 0XEA, 0XEA,
+ 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE8, 0XE8, 0XE8, 0XE8,
+ 0XE8, 0XE8, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE6,
+ 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE5, 0XE5, 0XE5, 0XEA, 0XEA,
+ 0XEA, 0XEA, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE9, 0XE8, 0XE8,
+ 0XE8, 0XE8, 0XE8, 0XE8, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7, 0XE7,
+ 0XE7, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE6, 0XE5, 0XE5, 0XE5,
+ 0X63, 0X63, 0X63, 0X0B, 0X31, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1,
+ 0XE1, 0XE1, 0X63, 0X0B, 0X0B, 0X0B, 0X31, 0X31, 0X5D, 0X5D,
+ 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE1, 0XE1, 0XE1, 0X0B, 0X0B, 0X0B, 0X31, 0X31, 0X31,
+ 0X31, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X0B, 0X0B, 0X31, 0X31,
+ 0X31, 0X31, 0X16, 0X16, 0X16, 0X1F, 0X1F, 0XE4, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X0B, 0X0F,
+ 0X0F, 0X31, 0X16, 0X16, 0X16, 0X16, 0X1F, 0X1F, 0X1F, 0XE0,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X0F, 0X0F, 0X0F, 0X0F, 0X16, 0X16, 0X16, 0X16, 0X1F, 0X1F,
+ 0X1F, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X0F, 0X0F, 0X0F, 0X0F, 0X16, 0X16, 0X16, 0X1F,
+ 0X1F, 0X1F, 0X1F, 0X10, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X0F, 0X0F, 0X0F, 0X16, 0X16,
+ 0X16, 0X1F, 0X1F, 0X1F, 0X10, 0X10, 0X10, 0XE0, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X0F, 0X0F, 0X0F,
+ 0X16, 0X14, 0X1F, 0X1F, 0X1F, 0X10, 0X10, 0X10, 0X10, 0X29,
+ 0X29, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X07,
+ 0X07, 0X07, 0X07, 0X14, 0X70, 0X70, 0X70, 0X10, 0X10, 0X10,
+ 0X29, 0X29, 0X29, 0X29, 0X29, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X5A, 0X07, 0X07, 0X07, 0X07, 0X70, 0X70, 0X70, 0X70, 0X10,
+ 0X6F, 0X6F, 0X29, 0X29, 0X29, 0X29, 0X29, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA,
+ 0XDA, 0XDA, 0X5A, 0X5A, 0X07, 0X07, 0X07, 0X59, 0X59, 0X70,
+ 0X6F, 0X6F, 0X6F, 0X6F, 0X29, 0X29, 0X29, 0X29, 0X3E, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59,
+ 0X59, 0X59, 0X6F, 0X6F, 0X6F, 0X6F, 0X29, 0X29, 0X3E, 0X3E,
+ 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A,
+ 0X59, 0X59, 0X59, 0X59, 0X59, 0X6F, 0X6F, 0X6F, 0X29, 0X3E,
+ 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A,
+ 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X6F, 0X6F, 0X6F,
+ 0X3E, 0X3E, 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA,
+ 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X59,
+ 0X6F, 0X58, 0X58, 0X3E, 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA,
+ 0XDA, 0XDA, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0X3E, 0X6E, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9,
+ 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4,
+ 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4,
+ 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD3, 0XD3, 0XD3, 0XD3,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3,
+ 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE,
+ 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE,
+ 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XCD, 0XCD,
+ 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB,
+ 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA,
+ 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8,
+ 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC,
+ 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA,
+ 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8,
+ 0XC8, 0XC8, 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC,
+ 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA,
+ 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9,
+ 0XC9, 0XC8, 0XC8, 0XC8, 0X63, 0X63, 0X63, 0X0B, 0X5D, 0X5D,
+ 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X63, 0X63, 0X0B, 0X0B,
+ 0X31, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X0B, 0X0B,
+ 0X0B, 0X31, 0X31, 0X35, 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1,
+ 0X0B, 0X0B, 0X31, 0X31, 0X31, 0X35, 0X16, 0X16, 0X5D, 0X5D,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1,
+ 0XE1, 0XE1, 0X0F, 0X0F, 0X0F, 0X0F, 0X16, 0X16, 0X16, 0X16,
+ 0X5B, 0X1F, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X0F, 0X0F, 0X0F, 0X16, 0X16,
+ 0X16, 0X5B, 0X5B, 0X1F, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X0F, 0X0F, 0X0F,
+ 0X16, 0X14, 0X14, 0X5B, 0X5B, 0X1F, 0X10, 0XE0, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X5C,
+ 0X0F, 0X0F, 0X14, 0X14, 0X14, 0X5B, 0X1F, 0X1F, 0X10, 0X10,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X5C, 0X5C, 0X07, 0X07, 0X14, 0X14, 0X14, 0X5B, 0X1F, 0X10,
+ 0X10, 0X10, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X5C, 0X07, 0X07, 0X07, 0X07, 0X14, 0X14, 0X11,
+ 0X11, 0X10, 0X10, 0X6F, 0X29, 0X29, 0X29, 0X29, 0X29, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X5A, 0X07, 0X07, 0X07, 0X07, 0X07,
+ 0X59, 0X11, 0X11, 0X6F, 0X6F, 0X6F, 0X29, 0X29, 0X29, 0X29,
+ 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X07, 0X07,
+ 0X07, 0X59, 0X59, 0X59, 0X6F, 0X6F, 0X6F, 0X6F, 0X29, 0X29,
+ 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A,
+ 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X6F, 0X6F, 0X6F,
+ 0X29, 0X3E, 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA,
+ 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X6F,
+ 0X6F, 0X6F, 0X3E, 0X3E, 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA,
+ 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59,
+ 0X59, 0X59, 0X6F, 0X58, 0X58, 0X3E, 0X3E, 0X3E, 0X3E, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59,
+ 0X59, 0X59, 0X59, 0X59, 0X58, 0X58, 0X58, 0X58, 0X3E, 0X3E,
+ 0X6E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0XD9, 0XD9, 0XD9, 0XD9,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD7, 0X6E, 0X6E, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9,
+ 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4,
+ 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4,
+ 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9,
+ 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4,
+ 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE,
+ 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3,
+ 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE,
+ 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE,
+ 0XCE, 0XCE, 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC,
+ 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA,
+ 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9,
+ 0XC9, 0XC8, 0XC8, 0XC8, 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC,
+ 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB,
+ 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9,
+ 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8, 0XCD, 0XCD, 0XCD, 0XCD,
+ 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB,
+ 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9,
+ 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8, 0X5E, 0X5E,
+ 0X5E, 0X5E, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1,
+ 0X5E, 0X5E, 0X5E, 0X35, 0X35, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1,
+ 0XE1, 0XE1, 0X5E, 0X5E, 0X35, 0X35, 0X35, 0X35, 0X5D, 0X5D,
+ 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE1, 0XE1, 0XE1, 0X0B, 0X35, 0X35, 0X35, 0X35, 0X35,
+ 0X35, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X5C, 0X35, 0X35, 0X35,
+ 0X35, 0X35, 0X14, 0X5B, 0X5B, 0X5B, 0XE0, 0XE0, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X5C,
+ 0X0F, 0X35, 0X14, 0X14, 0X14, 0X5B, 0X5B, 0X5B, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X5C, 0X5C, 0X5C, 0X0F, 0X14, 0X14, 0X14, 0X5B, 0X5B, 0X5B,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X5C, 0X5C, 0X5C, 0X07, 0X14, 0X14, 0X14, 0X5B,
+ 0X5B, 0X11, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X5C, 0X07, 0X07, 0X07, 0X14,
+ 0X14, 0X5B, 0X11, 0X11, 0X11, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X07, 0X07, 0X07,
+ 0X07, 0X14, 0X14, 0X11, 0X11, 0X11, 0X11, 0X6F, 0X29, 0X29,
+ 0X29, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5A, 0X07,
+ 0X07, 0X07, 0X07, 0X07, 0X59, 0X11, 0X11, 0X11, 0X6F, 0X6F,
+ 0X29, 0X29, 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA,
+ 0X5A, 0X5A, 0X07, 0X07, 0X07, 0X59, 0X59, 0X59, 0X11, 0X11,
+ 0X6F, 0X32, 0X32, 0X3E, 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA,
+ 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59,
+ 0X59, 0X6F, 0X6F, 0X32, 0X32, 0X3E, 0X3E, 0X3E, 0X3E, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59,
+ 0X59, 0X59, 0X59, 0X59, 0X32, 0X58, 0X58, 0X3E, 0X3E, 0X3E,
+ 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A,
+ 0X59, 0X59, 0X59, 0X59, 0X59, 0X59, 0X58, 0X58, 0X58, 0X58,
+ 0X3E, 0X3E, 0X6E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A,
+ 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X59, 0X58, 0X58,
+ 0X58, 0X58, 0X58, 0X6E, 0X6E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA,
+ 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0X6E, 0X6E, 0X6E, 0X6E, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4,
+ 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0X6E, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9,
+ 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4,
+ 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4,
+ 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3,
+ 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE,
+ 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE,
+ 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XCD, 0XCD, 0XCD, 0XCD,
+ 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB,
+ 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9,
+ 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8, 0XCD, 0XCD,
+ 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB,
+ 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA,
+ 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8,
+ 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC,
+ 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA,
+ 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8,
+ 0XC8, 0XC8, 0X5E, 0X5E, 0X5E, 0X1B, 0X5D, 0X5D, 0X5D, 0X5D,
+ 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE1, 0XE1, 0XE1, 0X5E, 0X5E, 0X1B, 0X1B, 0X35, 0X5D,
+ 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X5E, 0X1B, 0X1B, 0X35,
+ 0X35, 0X35, 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X1B, 0X1B,
+ 0X1B, 0X35, 0X35, 0X35, 0X35, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1,
+ 0X5C, 0X1B, 0X21, 0X21, 0X35, 0X35, 0X5B, 0X5B, 0X5B, 0X5B,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X5C, 0X5C, 0X21, 0X21, 0X21, 0X14, 0X5B, 0X5B,
+ 0X5B, 0X5B, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X5C, 0X5C, 0X21, 0X14, 0X14,
+ 0X5B, 0X5B, 0X5B, 0X5B, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X5C, 0X07, 0X07,
+ 0X14, 0X14, 0X5B, 0X5B, 0X5B, 0X11, 0X11, 0XE0, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X07,
+ 0X07, 0X07, 0X07, 0X14, 0X5B, 0X5B, 0X11, 0X11, 0X11, 0XE0,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X07, 0X07, 0X07, 0X07, 0X07, 0X07, 0X11, 0X11, 0X11, 0X11,
+ 0X11, 0X11, 0X32, 0X32, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X07, 0X07, 0X07, 0X07, 0X07, 0X07, 0X11, 0X11,
+ 0X11, 0X11, 0X11, 0X32, 0X32, 0X32, 0X32, 0X3E, 0X3E, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X07, 0X07, 0X07, 0X59,
+ 0X59, 0X59, 0X11, 0X11, 0X2B, 0X32, 0X32, 0X32, 0X3E, 0X3E,
+ 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X07,
+ 0X59, 0X59, 0X59, 0X59, 0X59, 0X2B, 0X2B, 0X32, 0X32, 0X58,
+ 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A,
+ 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X59, 0X2B, 0X2B,
+ 0X58, 0X58, 0X58, 0X3E, 0X6E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA,
+ 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X59,
+ 0X2B, 0X58, 0X58, 0X58, 0X15, 0X6E, 0X6E, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA,
+ 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59,
+ 0X59, 0X59, 0X2B, 0X58, 0X58, 0X15, 0X6E, 0X6E, 0X6E, 0X6E,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDA, 0XDA, 0XDA, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0X15, 0X15, 0X6E, 0X6E,
+ 0X6E, 0X3B, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD7, 0X6E, 0X3B, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9,
+ 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4,
+ 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4,
+ 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD3, 0XD3,
+ 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE,
+ 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE,
+ 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3,
+ 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE,
+ 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC,
+ 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA,
+ 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8,
+ 0XC8, 0XC8, 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC,
+ 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA,
+ 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9,
+ 0XC9, 0XC8, 0XC8, 0XC8, 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC,
+ 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB,
+ 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9,
+ 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8, 0X5E, 0X5E, 0X5E, 0X1B,
+ 0X5D, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X5E, 0X5E,
+ 0X1B, 0X1B, 0X1B, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1,
+ 0X1B, 0X1B, 0X1B, 0X1B, 0X1B, 0X35, 0X5D, 0X5D, 0X5D, 0X5D,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1,
+ 0XE1, 0XE1, 0X1B, 0X1B, 0X1B, 0X1B, 0X21, 0X35, 0X35, 0X5D,
+ 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE1, 0XE1, 0XE1, 0X1B, 0X1B, 0X21, 0X21, 0X21, 0X21,
+ 0X5B, 0X5B, 0X5B, 0X5B, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X5C, 0X21, 0X21,
+ 0X21, 0X21, 0X5B, 0X5B, 0X5B, 0X5B, 0XE0, 0XE0, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X5C,
+ 0X21, 0X21, 0X21, 0X14, 0X5B, 0X5B, 0X5B, 0X5B, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X5C, 0X5C, 0X07, 0X07, 0X14, 0X14, 0X5B, 0X5B, 0X5B, 0X11,
+ 0X11, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X5C, 0X07, 0X07, 0X07, 0X07, 0X14, 0X5B, 0X5B,
+ 0X11, 0X11, 0X11, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X07, 0X07, 0X07, 0X07, 0X07, 0X07,
+ 0X11, 0X11, 0X11, 0X11, 0X11, 0X11, 0X32, 0X32, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X07, 0X07, 0X07, 0X07,
+ 0X07, 0X07, 0X11, 0X11, 0X11, 0X11, 0X11, 0X2B, 0X32, 0X32,
+ 0X32, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A,
+ 0X07, 0X07, 0X07, 0X59, 0X59, 0X59, 0X11, 0X11, 0X2B, 0X2B,
+ 0X2B, 0X32, 0X3E, 0X3E, 0X3E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA,
+ 0X5A, 0X5A, 0X5A, 0X07, 0X59, 0X59, 0X59, 0X59, 0X59, 0X2B,
+ 0X2B, 0X2B, 0X2B, 0X58, 0X58, 0X15, 0X15, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA,
+ 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59,
+ 0X59, 0X2B, 0X2B, 0X2B, 0X2B, 0X15, 0X15, 0X15, 0X6E, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59,
+ 0X59, 0X59, 0X59, 0X2B, 0X2B, 0X2B, 0X15, 0X15, 0X15, 0X6E,
+ 0X6E, 0X6E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A,
+ 0X59, 0X59, 0X59, 0X59, 0X59, 0X59, 0X2B, 0X15, 0X15, 0X15,
+ 0X6E, 0X6E, 0X6E, 0X3B, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0XD9, 0XD9,
+ 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0X15, 0X15,
+ 0X15, 0X6E, 0X6E, 0X6E, 0X3B, 0X3B, 0X2A, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4,
+ 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0X39, 0X39, 0X39, 0X2A, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4,
+ 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0X39, 0X39, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0X39, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9,
+ 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4,
+ 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD6, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4,
+ 0XD4, 0XD4, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3,
+ 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE,
+ 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE,
+ 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCE, 0XCE, 0XCE, 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC,
+ 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB,
+ 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9,
+ 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8, 0XCD, 0XCD, 0XCD, 0XCD,
+ 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB,
+ 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9,
+ 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8, 0XCD, 0XCD,
+ 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB,
+ 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA,
+ 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8,
+ 0X62, 0X62, 0X1B, 0X1B, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D, 0X5D,
+ 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1,
+ 0XE1, 0XE1, 0X62, 0X1B, 0X1B, 0X1B, 0X1B, 0X5D, 0X5D, 0X5D,
+ 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE3, 0XE3,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE1, 0XE1, 0XE1, 0X1B, 0X1B, 0X1B, 0X1B, 0X1B, 0X1B,
+ 0X5D, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2, 0XE2, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X1B, 0X1B, 0X1B, 0X1B,
+ 0X21, 0X21, 0X21, 0X5D, 0X5D, 0X5D, 0XE4, 0XE4, 0XE4, 0XE4,
+ 0XE4, 0XE4, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE3, 0XE2,
+ 0XE2, 0XE2, 0XE2, 0XE2, 0XE2, 0XE1, 0XE1, 0XE1, 0X1B, 0X1B,
+ 0X1B, 0X21, 0X21, 0X21, 0X21, 0X5B, 0X5B, 0X5B, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X5C, 0X21, 0X21, 0X21, 0X21, 0X21, 0X5B, 0X5B, 0X5B, 0X5B,
+ 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD,
+ 0XDD, 0XDD, 0X5C, 0X5C, 0X21, 0X21, 0X21, 0X5B, 0X5B, 0X5B,
+ 0X5B, 0X5B, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0, 0XDF, 0XDF,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X5C, 0X07, 0X07, 0X14, 0X5B,
+ 0X5B, 0X5B, 0X5B, 0X11, 0X11, 0XE0, 0XE0, 0XE0, 0XE0, 0XE0,
+ 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE, 0XDE, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X5C, 0X07, 0X07, 0X07,
+ 0X07, 0X5B, 0X5B, 0X11, 0X11, 0X11, 0X11, 0XE0, 0XE0, 0XE0,
+ 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDE,
+ 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD, 0X07, 0X07,
+ 0X07, 0X07, 0X07, 0X07, 0X11, 0X11, 0X11, 0X11, 0X11, 0X2B,
+ 0X2B, 0X32, 0XE0, 0XE0, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF, 0XDF,
+ 0XDF, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDE, 0XDD, 0XDD, 0XDD,
+ 0X07, 0X07, 0X07, 0X07, 0X07, 0X07, 0X11, 0X11, 0X11, 0X11,
+ 0X11, 0X2B, 0X2B, 0X2B, 0X32, 0X32, 0X15, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA,
+ 0XDA, 0XDA, 0X5A, 0X5A, 0X07, 0X07, 0X07, 0X59, 0X59, 0X59,
+ 0X11, 0X11, 0X2B, 0X2B, 0X2B, 0X2B, 0X15, 0X15, 0X15, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X07, 0X59, 0X59,
+ 0X59, 0X59, 0X59, 0X2B, 0X2B, 0X2B, 0X2B, 0X15, 0X15, 0X15,
+ 0X15, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A, 0X5A, 0X5A,
+ 0X59, 0X59, 0X59, 0X59, 0X59, 0X2B, 0X2B, 0X2B, 0X2B, 0X15,
+ 0X15, 0X15, 0X6E, 0X6E, 0XDC, 0XDC, 0XDC, 0XDC, 0XDC, 0XDB,
+ 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA, 0X5A, 0X5A,
+ 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X2B, 0X2B, 0X2B,
+ 0X15, 0X15, 0X15, 0X6E, 0X6E, 0X3B, 0XDC, 0XDC, 0XDC, 0XDC,
+ 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA, 0XDA, 0XDA,
+ 0X5A, 0X5A, 0X5A, 0X5A, 0X59, 0X59, 0X59, 0X59, 0X59, 0X2B,
+ 0X2B, 0X15, 0X15, 0X15, 0X6E, 0X6E, 0X3B, 0X3B, 0X3B, 0XDC,
+ 0XDC, 0XDC, 0XDC, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDB, 0XDA,
+ 0XDA, 0XDA, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0X15, 0X15, 0X15, 0X6E, 0X6E, 0X3B, 0X3B, 0X3B,
+ 0X2A, 0X2A, 0X2A, 0X2A, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0X39, 0X39, 0X39,
+ 0X39, 0X2A, 0X2A, 0X2A, 0X2A, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0X39, 0X39, 0X39, 0X2A, 0X2A, 0X2A, 0XD6, 0XD6, 0XD6, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9,
+ 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7,
+ 0XD7, 0XD7, 0XD7, 0X39, 0X2A, 0X2A, 0X2A, 0XD6, 0XD6, 0XD6,
+ 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4,
+ 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0X2A, 0X2A, 0XD6, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5, 0XD4,
+ 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0X2A, 0XD6,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD4, 0XD4, 0XD4, 0XD9, 0XD9, 0XD9, 0XD9, 0XD8, 0XD8,
+ 0XD8, 0XD8, 0XD8, 0XD8, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7, 0XD7,
+ 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD6, 0XD5, 0XD5, 0XD5,
+ 0XD5, 0XD5, 0XD5, 0XD4, 0XD4, 0XD4, 0XD3, 0XD3, 0XD3, 0XD3,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3,
+ 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE,
+ 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE,
+ 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD0, 0XD0,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3, 0XD2, 0XD2,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF, 0XCF, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XD3, 0XD3, 0XD3, 0XD3,
+ 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD2, 0XD1, 0XD1, 0XD1, 0XD1,
+ 0XD1, 0XD1, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XD0, 0XCF,
+ 0XCF, 0XCF, 0XCF, 0XCF, 0XCF, 0XCE, 0XCE, 0XCE, 0XCD, 0XCD,
+ 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCB, 0XCB,
+ 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XCA,
+ 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8, 0XC8, 0XC8,
+ 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC, 0XCC,
+ 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA, 0XCA, 0XCA,
+ 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9, 0XC8,
+ 0XC8, 0XC8, 0XCD, 0XCD, 0XCD, 0XCD, 0XCC, 0XCC, 0XCC, 0XCC,
+ 0XCC, 0XCC, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCB, 0XCA, 0XCA,
+ 0XCA, 0XCA, 0XCA, 0XCA, 0XCA, 0XC9, 0XC9, 0XC9, 0XC9, 0XC9,
+ 0XC9, 0XC8, 0XC8, 0XC8, 0X62, 0X62, 0X62, 0X62, 0X1B, 0X57,
+ 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0X62, 0X62, 0X62, 0X1B,
+ 0X1B, 0X57, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0X62, 0X1B,
+ 0X1B, 0X1B, 0X1B, 0X0A, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3,
+ 0X1B, 0X1B, 0X1B, 0X1B, 0X0A, 0X0A, 0X0A, 0X0A, 0X57, 0X57,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3,
+ 0XC3, 0XC3, 0X1B, 0X1B, 0X1B, 0X0A, 0X0A, 0X0A, 0X0A, 0X0A,
+ 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X21, 0X0A, 0X0A, 0X0A, 0X0A,
+ 0X0A, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X0A, 0X0A,
+ 0X0A, 0X0A, 0X55, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56,
+ 0X0A, 0X0A, 0X0A, 0X0A, 0X3C, 0X3C, 0X3C, 0X11, 0X11, 0XC2,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF,
+ 0X56, 0X07, 0X07, 0X07, 0X07, 0X3C, 0X3C, 0X3C, 0X11, 0X11,
+ 0X11, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF,
+ 0XBF, 0XBF, 0X07, 0X07, 0X07, 0X07, 0X07, 0X3C, 0X3C, 0X11,
+ 0X11, 0X11, 0X11, 0X2B, 0X2B, 0X2B, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X07, 0X07, 0X07, 0X07, 0X07, 0X0C,
+ 0X11, 0X11, 0X11, 0X11, 0X2B, 0X2B, 0X2B, 0X2B, 0X2B, 0X15,
+ 0X15, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X07, 0X0C,
+ 0X0C, 0X0C, 0X53, 0X53, 0X11, 0X2B, 0X2B, 0X2B, 0X2B, 0X2B,
+ 0X15, 0X15, 0X15, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54,
+ 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X2B, 0X2B, 0X2B,
+ 0X08, 0X08, 0X15, 0X15, 0X6E, 0X3B, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X2B,
+ 0X2B, 0X08, 0X08, 0X15, 0X15, 0X15, 0X3B, 0X3B, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC,
+ 0XBC, 0XBC, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53,
+ 0X53, 0X2B, 0X08, 0X08, 0X15, 0X15, 0X15, 0X3B, 0X3B, 0X3B,
+ 0X3B, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X0C,
+ 0X53, 0X53, 0X53, 0X08, 0X08, 0X08, 0X15, 0X15, 0X3B, 0X3B,
+ 0X3B, 0X3B, 0X6D, 0X2A, 0X2A, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0XBB, 0XBB, 0XBB, 0X0C,
+ 0X0C, 0X51, 0X51, 0X51, 0X51, 0X08, 0X08, 0X15, 0X15, 0X39,
+ 0X39, 0X39, 0X39, 0X6D, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA,
+ 0X39, 0X39, 0X39, 0X39, 0X39, 0X2A, 0X2A, 0X2A, 0X2A, 0X2A,
+ 0X50, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51,
+ 0XBA, 0XBA, 0XBA, 0X39, 0X39, 0X39, 0X2A, 0X2A, 0X2A, 0X2A,
+ 0X2A, 0X50, 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51,
+ 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0X39, 0X39, 0X2A, 0X2A,
+ 0X2A, 0X2A, 0X50, 0X02, 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51,
+ 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X2A,
+ 0X2A, 0X2A, 0X2A, 0X50, 0X02, 0X02, 0X02, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB,
+ 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0X2A, 0X2A, 0X50, 0X02, 0X02, 0X02, 0X02, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0X2A, 0X50, 0X02, 0X02, 0X02, 0X02,
+ 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3,
+ 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7,
+ 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3,
+ 0XB3, 0XB3, 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1,
+ 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF,
+ 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE,
+ 0XAE, 0XAD, 0XAD, 0XAD, 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE,
+ 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD, 0XB2, 0XB2, 0XB2, 0XB2,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE,
+ 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD, 0X62, 0X62,
+ 0X62, 0X62, 0X57, 0X57, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3,
+ 0X62, 0X62, 0X62, 0X62, 0X57, 0X57, 0X57, 0X57, 0X57, 0X57,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3,
+ 0XC3, 0XC3, 0X62, 0X62, 0X62, 0X0A, 0X0A, 0X0A, 0X57, 0X57,
+ 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC3, 0XC3, 0XC3, 0X62, 0X0A, 0X0A, 0X0A, 0X0A, 0X0A,
+ 0X0A, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0X56, 0X0A, 0X0A, 0X0A,
+ 0X0A, 0X0A, 0X0A, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56,
+ 0X0A, 0X0A, 0X0A, 0X0A, 0X0A, 0X55, 0X55, 0X55, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF,
+ 0X56, 0X56, 0X0A, 0X0A, 0X0A, 0X0A, 0X55, 0X55, 0X55, 0X55,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF,
+ 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X0A, 0X0A, 0X55, 0X3C, 0X3C,
+ 0X3C, 0X3C, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X0A, 0X3C, 0X3C,
+ 0X3C, 0X3C, 0X3C, 0X3C, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X07, 0X0C,
+ 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0X11, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X54, 0X54,
+ 0X0C, 0X0C, 0X0C, 0X0C, 0X3C, 0X3C, 0X3C, 0X11, 0X08, 0X08,
+ 0X08, 0X08, 0X08, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X08,
+ 0X08, 0X08, 0X08, 0X08, 0X08, 0X52, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC,
+ 0XBC, 0XBC, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53,
+ 0X53, 0X08, 0X08, 0X08, 0X08, 0X08, 0X08, 0X52, 0X3B, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C,
+ 0X53, 0X53, 0X53, 0X08, 0X08, 0X08, 0X08, 0X08, 0X08, 0X3B,
+ 0X3B, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C,
+ 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X08, 0X08, 0X08, 0X08, 0X08,
+ 0X3B, 0X3B, 0X3B, 0X3B, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54,
+ 0X54, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53, 0X08, 0X08, 0X08,
+ 0X08, 0X08, 0X3B, 0X3B, 0X3B, 0X6D, 0X6D, 0X6D, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0XBB, 0XBB, 0XBB, 0X0C, 0X0C, 0X51, 0X51, 0X51, 0X51, 0X08,
+ 0X08, 0X08, 0X39, 0X39, 0X39, 0X39, 0X6D, 0X6D, 0X6D, 0X2A,
+ 0X2A, 0X2A, 0X50, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51,
+ 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0X39, 0X39, 0X39, 0X6D, 0X6D,
+ 0X2A, 0X2A, 0X2A, 0X50, 0X50, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51,
+ 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0X39, 0X39,
+ 0X6D, 0X2A, 0X2A, 0X2A, 0X50, 0X50, 0X02, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB,
+ 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0XBA, 0X6D, 0X2A, 0X2A, 0X2A, 0X50, 0X50, 0X02, 0X02, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0X2A, 0X2A, 0X50, 0X50, 0X02, 0X02,
+ 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X2A, 0X50, 0X50, 0X02,
+ 0X02, 0X02, 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51,
+ 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X50, 0X50,
+ 0X02, 0X02, 0X02, 0X02, 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7,
+ 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3,
+ 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB2, 0XB2, 0XB2, 0XB2,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE,
+ 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD, 0XB2, 0XB2,
+ 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF,
+ 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD,
+ 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1,
+ 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF,
+ 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD,
+ 0XAD, 0XAD, 0X62, 0X62, 0X62, 0X62, 0X57, 0X57, 0X57, 0X57,
+ 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC3, 0XC3, 0XC3, 0X62, 0X62, 0X62, 0X62, 0X57, 0X57,
+ 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0X62, 0X62, 0X0A, 0X0A,
+ 0X0A, 0X57, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0X62, 0X0A,
+ 0X0A, 0X0A, 0X0A, 0X0A, 0X0A, 0X57, 0X57, 0X57, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3,
+ 0X56, 0X0A, 0X0A, 0X0A, 0X0A, 0X0A, 0X0A, 0X55, 0X55, 0X55,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF,
+ 0XBF, 0XBF, 0X56, 0X56, 0X0A, 0X0A, 0X0A, 0X0A, 0X55, 0X55,
+ 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X0A, 0X0A, 0X0A, 0X55,
+ 0X55, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X0A,
+ 0X0A, 0X55, 0X3C, 0X3C, 0X3C, 0X3C, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56,
+ 0X56, 0X0A, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF,
+ 0X56, 0X56, 0X56, 0X0C, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C,
+ 0X3C, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF,
+ 0XBF, 0XBF, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C, 0X3C, 0X3C,
+ 0X3C, 0X3C, 0X08, 0X08, 0X08, 0X08, 0X52, 0X52, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C,
+ 0X53, 0X53, 0X53, 0X53, 0X08, 0X08, 0X08, 0X08, 0X52, 0X52,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X0C, 0X0C,
+ 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53, 0X08, 0X08, 0X08, 0X08,
+ 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54,
+ 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53, 0X08, 0X08,
+ 0X08, 0X08, 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53,
+ 0X08, 0X08, 0X08, 0X08, 0X52, 0X34, 0X34, 0X34, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC,
+ 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X53, 0X53, 0X53,
+ 0X53, 0X53, 0X08, 0X08, 0X08, 0X08, 0X34, 0X34, 0X34, 0X34,
+ 0X6D, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBC, 0XBC, 0XBC, 0XBB, 0XBB, 0XBB, 0X0C, 0X26, 0X51,
+ 0X51, 0X51, 0X51, 0X51, 0X08, 0X08, 0X08, 0X39, 0X34, 0X34,
+ 0X34, 0X34, 0X6D, 0X6D, 0X6D, 0X50, 0X50, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB,
+ 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0X34, 0X34, 0X34, 0X6D, 0X6D, 0X6D, 0X50, 0X50, 0X50, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0XBA, 0X34, 0X6D, 0X6D, 0X6D, 0X50, 0X50, 0X50,
+ 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X6D, 0X6D, 0X50, 0X50,
+ 0X50, 0X02, 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51,
+ 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X6D, 0X50,
+ 0X50, 0X50, 0X02, 0X02, 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51,
+ 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0X50, 0X50, 0X50, 0X02, 0X02, 0X02, 0X02, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB,
+ 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0X50, 0X50, 0X02, 0X02, 0X02, 0X02, 0X02, 0X2C,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XB7, 0XB7,
+ 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0X6C, 0X2C, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3,
+ 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7,
+ 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3,
+ 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1,
+ 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF,
+ 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD,
+ 0XAD, 0XAD, 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1,
+ 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF,
+ 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE,
+ 0XAE, 0XAD, 0XAD, 0XAD, 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE,
+ 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD, 0XC7, 0XC7, 0XC7, 0XC7,
+ 0X57, 0X57, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0XC7, 0XC7,
+ 0XC7, 0XC7, 0X57, 0X57, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3,
+ 0XC7, 0XC7, 0XC7, 0X0A, 0X0A, 0X57, 0X57, 0X57, 0X57, 0X57,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3,
+ 0XC3, 0XC3, 0XC7, 0XC7, 0X0A, 0X0A, 0X0A, 0X0A, 0X57, 0X57,
+ 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC3, 0XC3, 0XC3, 0X56, 0X56, 0X0A, 0X0A, 0X0A, 0X0A,
+ 0X55, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X0A, 0X0A,
+ 0X0A, 0X0A, 0X55, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56,
+ 0X56, 0X0A, 0X0A, 0X55, 0X55, 0X55, 0X55, 0X55, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF,
+ 0X56, 0X56, 0X56, 0X0A, 0X55, 0X55, 0X55, 0X3C, 0X3C, 0X3C,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF,
+ 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X56, 0X3C, 0X3C, 0X3C, 0X3C,
+ 0X3C, 0X3C, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X0C, 0X3C, 0X3C,
+ 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X54, 0X54, 0X0C, 0X0C,
+ 0X0C, 0X0C, 0X3C, 0X3C, 0X3C, 0X3C, 0X08, 0X08, 0X52, 0X52,
+ 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54,
+ 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53, 0X08, 0X08,
+ 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53,
+ 0X08, 0X08, 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC,
+ 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X53, 0X53,
+ 0X53, 0X53, 0X08, 0X08, 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X53,
+ 0X53, 0X53, 0X53, 0X53, 0X08, 0X08, 0X52, 0X52, 0X52, 0X34,
+ 0X34, 0X34, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C,
+ 0X0C, 0X53, 0X53, 0X53, 0X53, 0X53, 0X08, 0X08, 0X52, 0X52,
+ 0X34, 0X34, 0X34, 0X34, 0X34, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0XBB, 0XBB,
+ 0XBB, 0X26, 0X26, 0X26, 0X26, 0X51, 0X51, 0X51, 0X08, 0X08,
+ 0XBA, 0X34, 0X34, 0X34, 0X34, 0X34, 0X34, 0X6D, 0X50, 0X50,
+ 0X50, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XBB, 0XBB, 0XBB, 0X26, 0X26, 0X51, 0X51, 0X51, 0X51, 0X51,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0X34, 0X34, 0X34, 0X34, 0X34, 0X50,
+ 0X50, 0X50, 0X50, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51,
+ 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X34, 0X34, 0X34,
+ 0X50, 0X50, 0X50, 0X50, 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51,
+ 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0X34, 0X50, 0X50, 0X50, 0X50, 0X02, 0X02, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB,
+ 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0X50, 0X50, 0X50, 0X50, 0X02, 0X02, 0X02, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0X50, 0X50, 0X50, 0X02, 0X02, 0X02,
+ 0X6C, 0X6C, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X50, 0X50, 0X02, 0X02,
+ 0X02, 0X6C, 0X6C, 0X2C, 0X2C, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0X6C, 0X2C, 0X2C, 0X2C, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X2C, 0X2C, 0X4F, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7,
+ 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3,
+ 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0XB3, 0XB3, 0XB3, 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE,
+ 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD, 0XB2, 0XB2, 0XB2, 0XB2,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE,
+ 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD, 0XB2, 0XB2,
+ 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF,
+ 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD,
+ 0XC7, 0XC7, 0XC7, 0XC7, 0X57, 0X57, 0X57, 0X57, 0X57, 0X57,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3,
+ 0XC3, 0XC3, 0XC7, 0XC7, 0XC7, 0XC7, 0X57, 0X57, 0X57, 0X57,
+ 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC3, 0XC3, 0XC3, 0XC7, 0XC7, 0XC7, 0X0A, 0X57, 0X57,
+ 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0XC7, 0XC7, 0X0A, 0X0A,
+ 0X0A, 0X0A, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0X56, 0X56,
+ 0X0A, 0X0A, 0X0A, 0X0A, 0X55, 0X55, 0X55, 0X55, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF,
+ 0X56, 0X56, 0X56, 0X0A, 0X0A, 0X55, 0X55, 0X55, 0X55, 0X55,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF,
+ 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X0A, 0X55, 0X55, 0X55, 0X55,
+ 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X56, 0X55, 0X55,
+ 0X55, 0X3C, 0X3C, 0X3C, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X56,
+ 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56,
+ 0X56, 0X0C, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0X3C, 0XC2,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF,
+ 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C, 0X3C, 0X3C, 0X3C, 0X3C,
+ 0X52, 0X52, 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC,
+ 0XBC, 0XBC, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X0C, 0X53, 0X53,
+ 0X53, 0X53, 0X52, 0X52, 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X0C,
+ 0X53, 0X53, 0X53, 0X53, 0X52, 0X52, 0X52, 0X52, 0X52, 0X52,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C,
+ 0X0C, 0X53, 0X53, 0X53, 0X53, 0X53, 0X52, 0X52, 0X52, 0X52,
+ 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54,
+ 0X54, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53, 0X53, 0X52, 0X52,
+ 0X52, 0X52, 0X52, 0X34, 0X34, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0X54, 0X54, 0X54, 0X26, 0X26, 0X26, 0X26, 0X53, 0X53, 0X53,
+ 0X52, 0X52, 0X52, 0X52, 0X34, 0X34, 0X34, 0X34, 0X34, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC,
+ 0XBC, 0XBC, 0XBB, 0XBB, 0X26, 0X26, 0X26, 0X26, 0X26, 0X26,
+ 0X26, 0X51, 0XBA, 0XBA, 0XBA, 0X34, 0X34, 0X34, 0X34, 0X34,
+ 0X34, 0X34, 0X50, 0X50, 0X50, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0X26, 0X26, 0X26,
+ 0X26, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0X34, 0X34,
+ 0X34, 0X34, 0X34, 0X50, 0X50, 0X50, 0X02, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0X26,
+ 0X26, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0XBA, 0X34, 0X34, 0X34, 0X50, 0X50, 0X50, 0X02, 0X02, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0X34, 0X50, 0X50, 0X50, 0X02, 0X02,
+ 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X50, 0X50, 0X50, 0X02,
+ 0X02, 0X02, 0X6C, 0X6C, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51,
+ 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X50, 0X50,
+ 0X02, 0X02, 0X02, 0X6C, 0X6C, 0X6C, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51,
+ 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0X50, 0X02, 0X02, 0X02, 0X6C, 0X6C, 0X6C, 0X2C, 0X2C, 0X2C,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XB7, 0XB7, 0XB7, 0XB7,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0X6C, 0X6C, 0X2C, 0X2C,
+ 0X2C, 0X36, 0X36, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7,
+ 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0X2C, 0X2C, 0X36, 0X36, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0X2C, 0X36, 0X36, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3,
+ 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X36, 0X4F, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F, 0X4F, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X4F,
+ 0X4F, 0X4F, 0X4F, 0X4F, 0X4F, 0XB3, 0XB3, 0XB3, 0XB2, 0XB2,
+ 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF,
+ 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD,
+ 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1,
+ 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF,
+ 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD,
+ 0XAD, 0XAD, 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1,
+ 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF,
+ 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE,
+ 0XAE, 0XAD, 0XAD, 0XAD, 0XC7, 0XC7, 0XC7, 0XC7, 0X57, 0X57,
+ 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0XC7, 0XC7, 0XC7, 0XC7,
+ 0X57, 0X57, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0XC7, 0XC7,
+ 0XC7, 0XC7, 0X57, 0X57, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3,
+ 0XC7, 0XC7, 0X0A, 0X0A, 0X0A, 0X57, 0X57, 0X57, 0X57, 0X57,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3,
+ 0XC3, 0XC3, 0X56, 0X56, 0X56, 0X0A, 0X0A, 0X55, 0X55, 0X55,
+ 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X0A, 0X3F, 0X55,
+ 0X55, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X3F,
+ 0X3F, 0X3F, 0X55, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56,
+ 0X56, 0X3F, 0X3F, 0X3F, 0X3F, 0X55, 0X3C, 0X3C, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF,
+ 0X56, 0X56, 0X56, 0X3F, 0X3F, 0X3F, 0X3F, 0X3C, 0X3C, 0X3C,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF,
+ 0XBF, 0XBF, 0X56, 0X56, 0X56, 0X3F, 0X3F, 0X3F, 0X3F, 0X3C,
+ 0X3C, 0X3C, 0X3C, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X54, 0X54, 0X0C, 0X0C, 0X0C, 0X3F,
+ 0X3F, 0X3C, 0X3C, 0X3C, 0X52, 0X52, 0X52, 0X52, 0X52, 0X52,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C,
+ 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53, 0X52, 0X52, 0X52, 0X52,
+ 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54,
+ 0X54, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53, 0X53, 0X52, 0X52,
+ 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X53, 0X53, 0X53, 0X53, 0X53,
+ 0X52, 0X52, 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC,
+ 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X26, 0X26, 0X26, 0X53, 0X53,
+ 0X53, 0X53, 0X52, 0X52, 0X52, 0X52, 0X52, 0X52, 0X34, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X26, 0X26, 0X26, 0X26,
+ 0X26, 0X26, 0X26, 0X53, 0X52, 0X52, 0X52, 0X52, 0X34, 0X34,
+ 0X34, 0X34, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0XBB, 0XBB, 0X26, 0X26,
+ 0X26, 0X26, 0X26, 0X26, 0X26, 0X19, 0X19, 0XBA, 0XBA, 0XBA,
+ 0X34, 0X34, 0X34, 0X34, 0X34, 0X50, 0X50, 0X50, 0X50, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0X26, 0X26, 0X26, 0X26, 0X26, 0X26, 0X26, 0X19, 0X19, 0XBA,
+ 0XBA, 0XBA, 0X34, 0X34, 0X34, 0X34, 0X34, 0X50, 0X50, 0X50,
+ 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XBB, 0XBB, 0XBB, 0X26, 0X26, 0X26, 0X26, 0X51, 0X51, 0X19,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X34, 0X34, 0X34, 0X50, 0X50,
+ 0X50, 0X02, 0X02, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51,
+ 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0X34, 0X50,
+ 0X50, 0X50, 0X02, 0X02, 0X6C, 0X6C, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51,
+ 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0X50, 0X50, 0X50, 0X02, 0X02, 0X6C, 0X6C, 0X6C, 0XB9, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB,
+ 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0X50, 0X50, 0X02, 0X02, 0X6C, 0X6C, 0X6C, 0X6C,
+ 0X2C, 0X2C, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X51, 0XBA, 0XBA,
+ 0XBA, 0XBA, 0XBA, 0XBA, 0X50, 0X02, 0X02, 0X6C, 0X6C, 0X6C,
+ 0X6C, 0X2C, 0X2C, 0X2C, 0X2C, 0X36, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0X6C,
+ 0X6C, 0X6C, 0X2C, 0X2C, 0X2C, 0X36, 0X36, 0X36, 0X36, 0XB3,
+ 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0X2C, 0X2C, 0X2C, 0X36, 0X36, 0X36, 0X36,
+ 0X18, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X2C, 0X36, 0X36, 0X36,
+ 0X36, 0X36, 0X18, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X36, 0X36,
+ 0X36, 0X36, 0X36, 0X18, 0X18, 0XB3, 0XB3, 0XB3, 0XB7, 0XB7,
+ 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0X36, 0X36, 0X36, 0X36, 0X4F, 0X18, 0X18, 0XB3, 0XB3, 0XB3,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0X36, 0X36, 0X4F, 0X4F, 0X18, 0X18, 0X38,
+ 0XB3, 0XB3, 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1,
+ 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF,
+ 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE,
+ 0X38, 0X38, 0XAD, 0XAD, 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE,
+ 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD, 0XB2, 0XB2, 0XB2, 0XB2,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAE,
+ 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0XAD, 0XAD, 0XAD, 0XC7, 0XC7,
+ 0XC7, 0XC7, 0X57, 0X57, 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3,
+ 0XC7, 0XC7, 0XC7, 0XC7, 0X57, 0X57, 0X57, 0X57, 0X57, 0X57,
+ 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4, 0XC3,
+ 0XC3, 0XC3, 0XC7, 0XC7, 0XC7, 0XC7, 0X57, 0X57, 0X57, 0X57,
+ 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC5, 0XC5,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC3, 0XC3, 0XC3, 0XC7, 0XC7, 0XC7, 0X0A, 0X0A, 0X57,
+ 0X57, 0X57, 0X57, 0X57, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6, 0XC6,
+ 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC5, 0XC4, 0XC4, 0XC4,
+ 0XC4, 0XC4, 0XC4, 0XC3, 0XC3, 0XC3, 0X56, 0X56, 0X56, 0X3F,
+ 0X3F, 0X3F, 0X3F, 0X55, 0X55, 0X55, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56,
+ 0X56, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X55, 0X55, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF,
+ 0X56, 0X56, 0X56, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X55,
+ 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF,
+ 0XBF, 0XBF, 0X56, 0X56, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F,
+ 0X3F, 0X3F, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC1, 0XC1,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X3F, 0X3F, 0X3F, 0X3F,
+ 0X3F, 0X3F, 0X3F, 0X3F, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2, 0XC2,
+ 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0, 0XC0, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X56, 0X56, 0X3F, 0X3F,
+ 0X3F, 0X3F, 0X3F, 0X3F, 0X27, 0X27, 0X27, 0XC2, 0XC2, 0XC2,
+ 0XC2, 0XC2, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC1, 0XC0,
+ 0XC0, 0XC0, 0XC0, 0XC0, 0XC0, 0XBF, 0XBF, 0XBF, 0X54, 0X54,
+ 0X3F, 0X3F, 0X3F, 0X3F, 0X27, 0X27, 0X27, 0X27, 0X27, 0X52,
+ 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X27, 0X27, 0X27, 0X27, 0X27,
+ 0X27, 0X52, 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC,
+ 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C, 0X0C, 0X53, 0X53, 0X53,
+ 0X27, 0X27, 0X52, 0X52, 0X52, 0X52, 0X52, 0X52, 0XBE, 0XBE,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X54, 0X0C, 0X26, 0X26,
+ 0X53, 0X53, 0X53, 0X53, 0X52, 0X52, 0X52, 0X52, 0X52, 0X52,
+ 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD, 0XBD, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54, 0X26, 0X26,
+ 0X26, 0X26, 0X26, 0X26, 0X53, 0X53, 0X52, 0X52, 0X52, 0X52,
+ 0X52, 0X52, 0X34, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBE, 0XBD,
+ 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC, 0X54, 0X54,
+ 0X26, 0X26, 0X26, 0X26, 0X26, 0X26, 0X26, 0X19, 0X19, 0X52,
+ 0X52, 0X52, 0X52, 0X34, 0X34, 0X34, 0XBE, 0XBE, 0XBE, 0XBE,
+ 0XBE, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBD, 0XBC, 0XBC, 0XBC,
+ 0XBB, 0X26, 0X26, 0X26, 0X26, 0X26, 0X26, 0X26, 0X19, 0X19,
+ 0X19, 0X03, 0X03, 0X03, 0X34, 0X34, 0X34, 0X34, 0X34, 0X50,
+ 0X50, 0X50, 0X50, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0X26, 0X26, 0X26, 0X26, 0X26, 0X26,
+ 0X19, 0X19, 0X19, 0X03, 0X03, 0X03, 0X03, 0X34, 0X34, 0X34,
+ 0X50, 0X50, 0X50, 0X50, 0X6C, 0XB9, 0XB9, 0XB9, 0XB9, 0XB9,
+ 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0X26, 0X26, 0X26, 0X26,
+ 0X26, 0X19, 0X19, 0X19, 0X19, 0X03, 0X03, 0X03, 0X03, 0X03,
+ 0X34, 0X34, 0X50, 0X50, 0X50, 0X6C, 0X6C, 0X6C, 0XB9, 0XB9,
+ 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0X26,
+ 0X26, 0X26, 0X51, 0X19, 0X19, 0X19, 0X03, 0X03, 0X03, 0X03,
+ 0X03, 0X03, 0X03, 0X50, 0X50, 0X50, 0X6C, 0X6C, 0X6C, 0X6C,
+ 0XB9, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8, 0XBB, 0XBB,
+ 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X19, 0X19, 0X03, 0X03,
+ 0X03, 0X03, 0X03, 0X03, 0X03, 0X50, 0X50, 0X6C, 0X6C, 0X6C,
+ 0X6C, 0X6C, 0X2C, 0XB9, 0XB9, 0XB9, 0XB9, 0XB8, 0XB8, 0XB8,
+ 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51, 0X51, 0X19,
+ 0X03, 0X03, 0X03, 0X03, 0X03, 0X03, 0X04, 0X50, 0X6C, 0X6C,
+ 0X6C, 0X6C, 0X6C, 0X6C, 0X2C, 0X2C, 0X2C, 0XB9, 0XB9, 0XB8,
+ 0XB8, 0XB8, 0XBB, 0XBB, 0XBB, 0XBB, 0X51, 0X51, 0X51, 0X51,
+ 0X51, 0X03, 0X03, 0X03, 0X03, 0X03, 0X03, 0X04, 0X04, 0X6C,
+ 0X6C, 0X6C, 0X6C, 0X6C, 0X6C, 0X2C, 0X2C, 0X2C, 0X2C, 0X36,
+ 0X18, 0X18, 0XB8, 0XB8, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0X03, 0X03, 0XB5, 0XB5, 0XB5, 0X04,
+ 0X04, 0XB4, 0X6C, 0X6C, 0X6C, 0X6C, 0X2C, 0X2C, 0X2C, 0X2C,
+ 0X36, 0X18, 0X18, 0X18, 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0X6C, 0X2C, 0X2C, 0X2C,
+ 0X36, 0X36, 0X36, 0X18, 0X18, 0X18, 0XB3, 0XB3, 0XB7, 0XB7,
+ 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X2C,
+ 0X2C, 0X36, 0X36, 0X36, 0X18, 0X18, 0X18, 0X18, 0XB3, 0XB3,
+ 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0X36, 0X36, 0X36, 0X36, 0X18, 0X18, 0X18, 0X18,
+ 0XB3, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB4, 0XB4,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0X36, 0X36, 0X36, 0X18, 0X18, 0X18,
+ 0X18, 0X38, 0X38, 0XB3, 0XB7, 0XB7, 0XB7, 0XB7, 0XB6, 0XB6,
+ 0XB6, 0XB6, 0XB6, 0XB6, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5, 0XB5,
+ 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0XB4, 0X36, 0X36, 0X36, 0X18,
+ 0X18, 0X18, 0X38, 0X38, 0X38, 0XB3, 0XB2, 0XB2, 0XB2, 0XB2,
+ 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0X36,
+ 0X18, 0X18, 0X38, 0X38, 0X38, 0X38, 0X38, 0X38, 0XB2, 0XB2,
+ 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB0, 0XB0,
+ 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF, 0XAF,
+ 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0X38, 0X38, 0X38, 0X38, 0XAD,
+ 0XB2, 0XB2, 0XB2, 0XB2, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1, 0XB1,
+ 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XB0, 0XAF, 0XAF, 0XAF, 0XAF,
+ 0XAF, 0XAF, 0XAF, 0XAE, 0XAE, 0XAE, 0XAE, 0XAE, 0X38, 0X38,
+ 0XAD, 0XAD, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC,
+ 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7,
+ 0XA6, 0XA6, 0XA6, 0X3F, 0X3F, 0X3F, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2,
+ 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0X3F, 0X3F, 0X3F, 0X3F, 0X4E,
+ 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0X3F, 0X3F, 0X3F,
+ 0X3F, 0X3F, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0X3F,
+ 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6,
+ 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X27, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2,
+ 0XA6, 0XA6, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F, 0X27, 0X27, 0X27,
+ 0X27, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2,
+ 0XA2, 0XA2, 0XA1, 0XA1, 0X3F, 0X3F, 0X3F, 0X27, 0X27, 0X27,
+ 0X27, 0X27, 0X27, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0X27, 0X27, 0X27,
+ 0X27, 0X27, 0X27, 0X27, 0X27, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1,
+ 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0X4C, 0X4C, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1,
+ 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E,
+ 0XA1, 0XA1, 0XA1, 0X26, 0X26, 0X26, 0X26, 0X4D, 0X4D, 0X4D,
+ 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E,
+ 0X9E, 0X9E, 0XA1, 0XA1, 0X26, 0X26, 0X26, 0X26, 0X26, 0X26,
+ 0X19, 0X19, 0X19, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0X34, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9E, 0X9E, 0X9E, 0X9D, 0X9D, 0X26, 0X26, 0X26, 0X26,
+ 0X26, 0X19, 0X19, 0X19, 0X19, 0X03, 0X03, 0X03, 0X03, 0X34,
+ 0X34, 0X34, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X26, 0X26,
+ 0X26, 0X26, 0X26, 0X19, 0X19, 0X19, 0X19, 0X03, 0X03, 0X03,
+ 0X03, 0X03, 0X34, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D,
+ 0X9D, 0X26, 0X26, 0X26, 0X19, 0X19, 0X19, 0X19, 0X19, 0X03,
+ 0X03, 0X03, 0X03, 0X03, 0X03, 0X49, 0X49, 0X49, 0X49, 0X49,
+ 0X6C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B,
+ 0X9D, 0X9D, 0X9D, 0X26, 0X26, 0X4B, 0X19, 0X19, 0X19, 0X19,
+ 0X03, 0X03, 0X03, 0X03, 0X03, 0X03, 0X04, 0X49, 0X49, 0X49,
+ 0X49, 0X6C, 0X6C, 0X6C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B,
+ 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X19,
+ 0X19, 0X19, 0X03, 0X03, 0X03, 0X03, 0X03, 0X03, 0X04, 0X49,
+ 0X49, 0X49, 0X6C, 0X6C, 0X6C, 0X6C, 0X9C, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X19, 0X19, 0X03, 0X03, 0X03, 0X03, 0X03, 0X04,
+ 0X04, 0X04, 0X49, 0X6C, 0X6C, 0X6C, 0X6C, 0X2C, 0X2C, 0X6B,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X03, 0X03, 0X03, 0X03, 0X03,
+ 0X04, 0X04, 0X04, 0X05, 0X6C, 0X6C, 0X6C, 0X6C, 0X6B, 0X6B,
+ 0X6B, 0X6B, 0X6B, 0X18, 0X18, 0X18, 0X9B, 0X9B, 0XF8, 0XF8,
+ 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9, 0XF9, 0XF9, 0XFA, 0XFA,
+ 0XFA, 0XFA, 0X04, 0X04, 0X04, 0XFB, 0XFB, 0X6C, 0X6C, 0X6B,
+ 0X6B, 0X6B, 0X6B, 0X6B, 0X18, 0X18, 0X18, 0X18, 0XFD, 0XFD,
+ 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9, 0XF9, 0XF9,
+ 0XFA, 0XFA, 0XFA, 0XFA, 0XFA, 0XFA, 0XFB, 0XFB, 0XFB, 0XFB,
+ 0XFB, 0X6B, 0X6B, 0X6B, 0X6B, 0X36, 0X18, 0X18, 0X18, 0X18,
+ 0XFD, 0XFD, 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9,
+ 0XF9, 0XF9, 0XFA, 0XFA, 0XFA, 0XFA, 0XFA, 0XFA, 0XFB, 0XFB,
+ 0XFB, 0XFB, 0XFB, 0X6B, 0X6B, 0X6B, 0X36, 0X18, 0X18, 0X18,
+ 0X18, 0X18, 0XFD, 0XFD, 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9,
+ 0XF9, 0XF9, 0XF9, 0X99, 0XFA, 0XFA, 0XFA, 0XFA, 0XFA, 0X48,
+ 0XFB, 0XFB, 0XFB, 0XFB, 0XFB, 0X47, 0X6B, 0X36, 0X36, 0X18,
+ 0X18, 0X18, 0X18, 0X18, 0XFD, 0XFD, 0XF8, 0XF8, 0XF8, 0XF8,
+ 0XF9, 0XF9, 0XF9, 0XF9, 0X99, 0X99, 0XFA, 0XFA, 0XFA, 0XFA,
+ 0X48, 0X48, 0XFB, 0XFB, 0XFB, 0XFB, 0X47, 0X47, 0X36, 0X36,
+ 0X18, 0X18, 0X18, 0X18, 0X38, 0X38, 0X38, 0XFD, 0X9A, 0X9A,
+ 0X9A, 0X9A, 0XF9, 0XF9, 0XF9, 0X99, 0X99, 0X99, 0XFA, 0XFA,
+ 0XFA, 0X48, 0X48, 0X48, 0XFB, 0XFB, 0XFB, 0X47, 0X47, 0X47,
+ 0X36, 0X36, 0X18, 0X18, 0X18, 0X38, 0X38, 0X38, 0X38, 0X38,
+ 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0X95, 0X95, 0X95, 0X95, 0X95, 0X95, 0X94, 0X94, 0X94, 0X94,
+ 0X94, 0X94, 0X94, 0X93, 0X93, 0X18, 0X38, 0X38, 0X38, 0X38,
+ 0X38, 0X38, 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0XFF, 0XFF, 0X95, 0X95, 0X95, 0X95, 0X95, 0X95, 0X94, 0X94,
+ 0X94, 0X94, 0X94, 0X94, 0X94, 0X93, 0X93, 0X93, 0X93, 0X38,
+ 0X38, 0X38, 0X38, 0X92, 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF,
+ 0XFF, 0XFF, 0XFF, 0XFF, 0X95, 0X95, 0X95, 0X95, 0X95, 0X95,
+ 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X93, 0X93, 0X93,
+ 0X93, 0X93, 0X38, 0X38, 0X92, 0X92, 0XAC, 0XAC, 0XAC, 0XAC,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC,
+ 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7,
+ 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7,
+ 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA7, 0XA7, 0XA7, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0X3F,
+ 0X3F, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6,
+ 0XA6, 0X3F, 0X3F, 0X3F, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2,
+ 0XA6, 0XA6, 0XA6, 0X3F, 0X3F, 0X3F, 0X3F, 0X4E, 0X4E, 0X4E,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2,
+ 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0X3F, 0X3F, 0X3F, 0X3F, 0X3F,
+ 0X27, 0X27, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0X3F, 0X3F, 0X27,
+ 0X27, 0X27, 0X27, 0X27, 0X27, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA1, 0XA1, 0XA1, 0X27,
+ 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0X4C, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1,
+ 0XA1, 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E,
+ 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D,
+ 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E,
+ 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D,
+ 0X4D, 0X4D, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D,
+ 0X4D, 0X4D, 0X4D, 0X4D, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0X26,
+ 0X26, 0X26, 0X4D, 0X4D, 0X19, 0X19, 0X19, 0X4C, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0X9D, 0X9D,
+ 0X26, 0X26, 0X26, 0X26, 0X19, 0X19, 0X19, 0X19, 0X19, 0X19,
+ 0X4A, 0X4A, 0X4A, 0X4A, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49,
+ 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B,
+ 0X9D, 0X9D, 0X9D, 0X26, 0X26, 0X26, 0X19, 0X19, 0X19, 0X19,
+ 0X19, 0X03, 0X03, 0X03, 0X4A, 0X4A, 0X49, 0X49, 0X49, 0X49,
+ 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B,
+ 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X19, 0X19,
+ 0X19, 0X19, 0X19, 0X03, 0X03, 0X03, 0X03, 0X4A, 0X04, 0X49,
+ 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B,
+ 0X4B, 0X19, 0X19, 0X19, 0X03, 0X03, 0X03, 0X03, 0X03, 0X04,
+ 0X04, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X19, 0X19, 0X03, 0X03, 0X03, 0X03,
+ 0X04, 0X04, 0X04, 0X49, 0X49, 0X49, 0X49, 0X49, 0X6C, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D,
+ 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X19, 0X03, 0X03,
+ 0X03, 0X03, 0X04, 0X04, 0X04, 0X05, 0X49, 0X49, 0X49, 0X6C,
+ 0X6B, 0X6B, 0X6B, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B,
+ 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B,
+ 0X03, 0X03, 0X03, 0X04, 0X04, 0X04, 0X04, 0X05, 0X05, 0X49,
+ 0X6C, 0X6B, 0X6B, 0X6B, 0X6B, 0X6B, 0X6B, 0X9C, 0X18, 0X9B,
+ 0X9B, 0X9B, 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9,
+ 0XF9, 0XF9, 0XFA, 0XFA, 0XFA, 0XFA, 0X04, 0X04, 0X05, 0X05,
+ 0XFB, 0XFB, 0XFB, 0X6B, 0X6B, 0X6B, 0X6B, 0X6B, 0X18, 0X18,
+ 0X18, 0XFD, 0XFD, 0XFD, 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9,
+ 0XF9, 0XF9, 0XF9, 0XF9, 0XFA, 0XFA, 0XFA, 0XFA, 0XFA, 0XFA,
+ 0X05, 0XFB, 0XFB, 0XFB, 0XFB, 0X6B, 0X6B, 0X6B, 0X6B, 0X6B,
+ 0X18, 0X18, 0X18, 0X18, 0XFD, 0XFD, 0XF8, 0XF8, 0XF8, 0XF8,
+ 0XF9, 0XF9, 0XF9, 0XF9, 0XF9, 0X99, 0XFA, 0XFA, 0XFA, 0XFA,
+ 0XFA, 0X48, 0XFB, 0XFB, 0XFB, 0XFB, 0XFB, 0X47, 0X6B, 0X6B,
+ 0X6B, 0XFC, 0X18, 0X18, 0X18, 0X06, 0XFD, 0XFD, 0XF8, 0XF8,
+ 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9, 0X99, 0X99, 0XFA, 0XFA,
+ 0XFA, 0XFA, 0X48, 0X48, 0XFB, 0XFB, 0XFB, 0XFB, 0X47, 0X47,
+ 0X6B, 0X6B, 0XFC, 0X18, 0X18, 0X18, 0X06, 0X38, 0XFD, 0XFD,
+ 0X9A, 0X9A, 0X9A, 0X9A, 0XF9, 0XF9, 0XF9, 0X99, 0X99, 0X99,
+ 0XFA, 0XFA, 0XFA, 0X48, 0X48, 0X48, 0XFB, 0XFB, 0XFB, 0X47,
+ 0X47, 0X47, 0X47, 0XFC, 0XFC, 0X18, 0X18, 0X06, 0X38, 0X38,
+ 0X38, 0XFD, 0X9A, 0X9A, 0X9A, 0X9A, 0XF9, 0XF9, 0X99, 0X99,
+ 0X99, 0X99, 0XFA, 0XFA, 0X48, 0X48, 0X48, 0X48, 0XFB, 0XFB,
+ 0X47, 0X47, 0X47, 0X47, 0X47, 0XFC, 0XFC, 0X18, 0X38, 0X38,
+ 0X38, 0X38, 0X38, 0X38, 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF,
+ 0XFF, 0XFF, 0XFF, 0XFF, 0X95, 0X95, 0X95, 0X95, 0X95, 0X95,
+ 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X93, 0X93, 0X93,
+ 0X38, 0X38, 0X38, 0X38, 0X38, 0X38, 0XFE, 0XFE, 0XFE, 0XFE,
+ 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X95, 0X95, 0X95, 0X95,
+ 0X95, 0X95, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X93,
+ 0X93, 0X93, 0X93, 0X38, 0X38, 0X38, 0X38, 0X92, 0XFE, 0XFE,
+ 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X96, 0X95, 0X95,
+ 0X95, 0X95, 0X95, 0X95, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94,
+ 0X94, 0X93, 0X93, 0X93, 0X93, 0X93, 0X38, 0X38, 0X92, 0X92,
+ 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7,
+ 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XA6, 0XA6,
+ 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2,
+ 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2,
+ 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0X3F,
+ 0X3F, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6,
+ 0XA6, 0X3F, 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0XA5,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2,
+ 0XA1, 0XA1, 0XA1, 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0X27,
+ 0X27, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E,
+ 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X27, 0X27, 0X27, 0X27,
+ 0X27, 0X27, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D,
+ 0X4D, 0X4D, 0X4D, 0X4D, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1,
+ 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4C, 0X4C, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1,
+ 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E,
+ 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X19,
+ 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E,
+ 0X9E, 0X9E, 0X9D, 0X9D, 0X9D, 0X26, 0X26, 0X19, 0X19, 0X19,
+ 0X19, 0X19, 0X19, 0X4A, 0X4A, 0X4A, 0X4A, 0X4A, 0X49, 0X49,
+ 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B,
+ 0X19, 0X19, 0X19, 0X19, 0X19, 0X4A, 0X4A, 0X4A, 0X4A, 0X4A,
+ 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D,
+ 0X4B, 0X4B, 0X4B, 0X19, 0X19, 0X19, 0X19, 0X4A, 0X4A, 0X4A,
+ 0X4A, 0X4A, 0X04, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D,
+ 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X19, 0X19, 0X19, 0X4A,
+ 0X4A, 0X4A, 0X4A, 0X04, 0X04, 0X49, 0X49, 0X49, 0X49, 0X49,
+ 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B,
+ 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X19,
+ 0X03, 0X4A, 0X4A, 0X4A, 0X04, 0X04, 0X04, 0X49, 0X49, 0X49,
+ 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B,
+ 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X03, 0X03, 0X4A, 0X04, 0X04, 0X04, 0X04, 0X05,
+ 0X49, 0X49, 0X49, 0X49, 0X6B, 0X6B, 0X9C, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X03, 0X03, 0X04, 0X04, 0X04, 0X04,
+ 0X05, 0X05, 0X05, 0X49, 0X49, 0X6B, 0X6B, 0X6B, 0X6B, 0X6B,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0XF8, 0XF8, 0XF8, 0XF8,
+ 0XF9, 0XF9, 0XF9, 0XF9, 0XF9, 0XF9, 0XFA, 0XFA, 0XFA, 0XFA,
+ 0X04, 0X04, 0X05, 0X05, 0XFB, 0XFB, 0XFB, 0X6B, 0X6B, 0X6B,
+ 0X6B, 0X6B, 0XFC, 0XFC, 0X06, 0XFD, 0XFD, 0XFD, 0XF8, 0XF8,
+ 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9, 0XF9, 0X99, 0XFA, 0XFA,
+ 0XFA, 0XFA, 0XFA, 0X48, 0X05, 0XFB, 0XFB, 0XFB, 0XFB, 0X47,
+ 0X6B, 0X6B, 0X6B, 0XFC, 0XFC, 0XFC, 0X06, 0XFD, 0XFD, 0XFD,
+ 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9, 0X99, 0X99,
+ 0XFA, 0XFA, 0XFA, 0XFA, 0X48, 0X48, 0XFB, 0XFB, 0XFB, 0XFB,
+ 0X47, 0X47, 0X6B, 0X6B, 0XFC, 0XFC, 0XFC, 0X06, 0X06, 0X06,
+ 0XFD, 0XFD, 0X9A, 0X9A, 0X9A, 0X9A, 0XF9, 0XF9, 0XF9, 0X99,
+ 0X99, 0X99, 0XFA, 0XFA, 0XFA, 0X48, 0X48, 0X48, 0XFB, 0XFB,
+ 0XFB, 0X47, 0X47, 0X47, 0X47, 0XFC, 0XFC, 0XFC, 0X46, 0X06,
+ 0X06, 0X06, 0XFD, 0XFD, 0X9A, 0X9A, 0X9A, 0X9A, 0XF9, 0XF9,
+ 0X99, 0X99, 0X99, 0X99, 0XFA, 0XFA, 0X48, 0X48, 0X48, 0X48,
+ 0XFB, 0XFB, 0X47, 0X47, 0X47, 0X47, 0X47, 0XFC, 0XFC, 0X46,
+ 0X06, 0X06, 0X38, 0X38, 0X25, 0X98, 0X9A, 0X9A, 0X9A, 0X9A,
+ 0XF9, 0X99, 0X99, 0X99, 0X99, 0X99, 0XFA, 0X48, 0X48, 0X48,
+ 0X48, 0X48, 0XFB, 0X47, 0X47, 0X47, 0X47, 0X47, 0X47, 0XFC,
+ 0X46, 0X46, 0X06, 0X38, 0X38, 0X38, 0X38, 0X98, 0XFE, 0XFE,
+ 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X95, 0X95,
+ 0X95, 0X95, 0X95, 0X95, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94,
+ 0X94, 0X93, 0X93, 0X93, 0X38, 0X38, 0X38, 0X38, 0X38, 0X1D,
+ 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0X96,
+ 0X95, 0X95, 0X95, 0X95, 0X95, 0X95, 0X94, 0X94, 0X94, 0X94,
+ 0X94, 0X94, 0X94, 0X93, 0X93, 0X93, 0X93, 0X38, 0X38, 0X38,
+ 0X1D, 0X92, 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0X96, 0X96, 0X95, 0X95, 0X95, 0X95, 0X95, 0X95, 0X94, 0X94,
+ 0X94, 0X94, 0X94, 0X94, 0X94, 0X93, 0X93, 0X93, 0X93, 0X93,
+ 0X38, 0X38, 0X92, 0X92, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC,
+ 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7,
+ 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7,
+ 0XA7, 0XA7, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6,
+ 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6,
+ 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2,
+ 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2,
+ 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6, 0X27, 0X27, 0X27, 0X27,
+ 0X27, 0X27, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA2, 0XA2, 0XA2, 0XA1, 0XA1, 0XA1, 0X27, 0X27, 0X27,
+ 0X27, 0X27, 0X27, 0X27, 0X27, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1,
+ 0X4D, 0X4D, 0X4D, 0X27, 0X27, 0X27, 0X4C, 0X4C, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1,
+ 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E,
+ 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D,
+ 0X13, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E,
+ 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D,
+ 0X4D, 0X4D, 0X13, 0X13, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D,
+ 0X4D, 0X4D, 0X4D, 0X4D, 0X13, 0X13, 0X13, 0X4C, 0X4C, 0X4C,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0X9D, 0X9D, 0X9D, 0X9D,
+ 0X4B, 0X4B, 0X19, 0X19, 0X19, 0X19, 0X13, 0X13, 0X13, 0X13,
+ 0X4A, 0X4A, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D,
+ 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X19, 0X19, 0X19, 0X19, 0X4A,
+ 0X4A, 0X4A, 0X4A, 0X4A, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49,
+ 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B,
+ 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X19, 0X19,
+ 0X19, 0X4A, 0X4A, 0X4A, 0X4A, 0X4A, 0X49, 0X49, 0X49, 0X49,
+ 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B,
+ 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B,
+ 0X4B, 0X19, 0X4A, 0X4A, 0X4A, 0X4A, 0X4A, 0X04, 0X04, 0X49,
+ 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X4A, 0X4A, 0X4A, 0X4A, 0X04, 0X04,
+ 0X05, 0X05, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4A, 0X4A, 0X4A, 0X04,
+ 0X04, 0X04, 0X05, 0X05, 0X05, 0X49, 0X49, 0X49, 0X30, 0X30,
+ 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D,
+ 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4A, 0X4A,
+ 0X04, 0X04, 0X04, 0X05, 0X05, 0X05, 0X05, 0X05, 0X49, 0X30,
+ 0X30, 0X30, 0X30, 0X30, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B,
+ 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9, 0XF9, 0X99,
+ 0XFA, 0XFA, 0XFA, 0XFA, 0X04, 0X05, 0X05, 0X05, 0X05, 0XFB,
+ 0XFB, 0X30, 0X30, 0X30, 0X30, 0X30, 0XFC, 0XFC, 0X06, 0XFD,
+ 0XFD, 0XFD, 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9, 0XF9, 0XF9,
+ 0X99, 0X99, 0XFA, 0XFA, 0XFA, 0XFA, 0X48, 0X05, 0X05, 0X05,
+ 0XFB, 0XFB, 0X47, 0X47, 0X30, 0X30, 0X30, 0XFC, 0XFC, 0X46,
+ 0X06, 0X06, 0XFD, 0XFD, 0X9A, 0X9A, 0X9A, 0X9A, 0XF9, 0XF9,
+ 0XF9, 0X99, 0X99, 0X99, 0XFA, 0XFA, 0XFA, 0X48, 0X48, 0X48,
+ 0XFB, 0XFB, 0XFB, 0X47, 0X47, 0X47, 0X30, 0X30, 0XFC, 0XFC,
+ 0X46, 0X06, 0X06, 0X06, 0XFD, 0XFD, 0X9A, 0X9A, 0X9A, 0X9A,
+ 0XF9, 0XF9, 0X99, 0X99, 0X99, 0X99, 0XFA, 0XFA, 0X48, 0X48,
+ 0X48, 0X48, 0XFB, 0XFB, 0X47, 0X47, 0X47, 0X47, 0X47, 0XFC,
+ 0XFC, 0X46, 0X46, 0X06, 0X06, 0X25, 0XFD, 0X98, 0X9A, 0X9A,
+ 0X9A, 0X9A, 0XF9, 0X99, 0X99, 0X99, 0X99, 0X99, 0XFA, 0X48,
+ 0X48, 0X48, 0X48, 0X48, 0XFB, 0X47, 0X47, 0X47, 0X47, 0X47,
+ 0X47, 0XFC, 0X46, 0X46, 0X06, 0X06, 0X25, 0X25, 0X25, 0X98,
+ 0X9A, 0X9A, 0X9A, 0X9A, 0X99, 0X99, 0X99, 0X99, 0X99, 0X99,
+ 0X48, 0X48, 0X48, 0X48, 0X48, 0X48, 0X47, 0X47, 0X47, 0X47,
+ 0X47, 0X47, 0X47, 0X46, 0X46, 0X06, 0X06, 0X38, 0X25, 0X25,
+ 0X25, 0X1D, 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0XFF,
+ 0XFF, 0X96, 0X95, 0X95, 0X95, 0X95, 0X95, 0X95, 0X94, 0X94,
+ 0X94, 0X94, 0X94, 0X94, 0X94, 0X93, 0X93, 0X93, 0X38, 0X38,
+ 0X38, 0X25, 0X1D, 0X1D, 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF,
+ 0XFF, 0XFF, 0X96, 0X96, 0X95, 0X95, 0X95, 0X95, 0X95, 0X95,
+ 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X93, 0X93, 0X93,
+ 0X93, 0X38, 0X38, 0X1D, 0X1D, 0X1D, 0XFE, 0XFE, 0XFE, 0XFE,
+ 0XFF, 0XFF, 0XFF, 0X96, 0X96, 0X96, 0X95, 0X95, 0X95, 0X95,
+ 0X95, 0X95, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X93,
+ 0X93, 0X93, 0X93, 0X93, 0X93, 0X1D, 0X1D, 0X92, 0XAC, 0XAC,
+ 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7,
+ 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7,
+ 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XA6, 0XA6, 0XA6, 0XA6,
+ 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6,
+ 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2,
+ 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2,
+ 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6,
+ 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA1, 0XA1,
+ 0XA1, 0XA1, 0X27, 0X27, 0X27, 0X27, 0X27, 0X27, 0X4C, 0X4C,
+ 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E,
+ 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D,
+ 0X13, 0X4C, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E,
+ 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D,
+ 0X4D, 0X4D, 0X13, 0X13, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D,
+ 0X4D, 0X4D, 0X4D, 0X4D, 0X13, 0X13, 0X13, 0X4C, 0X4C, 0X4C,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1,
+ 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X13, 0X13, 0X13, 0X13, 0X13,
+ 0X13, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1,
+ 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X13, 0X13, 0X13,
+ 0X13, 0X13, 0X13, 0X13, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E,
+ 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X19, 0X19, 0X19,
+ 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X49, 0X49, 0X49, 0X49,
+ 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B,
+ 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B,
+ 0X19, 0X19, 0X19, 0X4A, 0X4A, 0X4A, 0X4A, 0X4A, 0X49, 0X49,
+ 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X4B, 0X19, 0X4A, 0X4A, 0X4A, 0X4A, 0X4A, 0X4A,
+ 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4A, 0X4A, 0X4A, 0X4A,
+ 0X4A, 0X04, 0X05, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D,
+ 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4A, 0X4A,
+ 0X4A, 0X4A, 0X04, 0X04, 0X05, 0X05, 0X49, 0X49, 0X49, 0X49,
+ 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B,
+ 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B,
+ 0X4A, 0X4A, 0X4A, 0X04, 0X04, 0X05, 0X05, 0X05, 0X05, 0X49,
+ 0X49, 0X49, 0X30, 0X30, 0X30, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B,
+ 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X4A, 0X4A, 0X04, 0X04, 0X04, 0X05, 0X05, 0X05,
+ 0X05, 0X05, 0X49, 0X30, 0X30, 0X30, 0X30, 0X30, 0X30, 0X9C,
+ 0X9C, 0X9B, 0X9B, 0X9B, 0XF8, 0XF8, 0XF8, 0XF8, 0XF9, 0XF9,
+ 0XF9, 0XF9, 0X99, 0X99, 0XFA, 0XFA, 0XFA, 0XFA, 0X05, 0X05,
+ 0X05, 0X05, 0X05, 0X0E, 0X0E, 0X30, 0X30, 0X30, 0X30, 0X30,
+ 0X30, 0X46, 0X06, 0XFD, 0XFD, 0XFD, 0X9A, 0X9A, 0X9A, 0X9A,
+ 0XF9, 0XF9, 0XF9, 0X99, 0X99, 0X99, 0XFA, 0XFA, 0XFA, 0X48,
+ 0X48, 0X05, 0X05, 0X05, 0X0E, 0X0E, 0X47, 0X30, 0X30, 0X30,
+ 0X30, 0X30, 0X46, 0X46, 0X06, 0X06, 0XFD, 0XFD, 0X9A, 0X9A,
+ 0X9A, 0X9A, 0XF9, 0XF9, 0X99, 0X99, 0X99, 0X99, 0XFA, 0XFA,
+ 0X48, 0X48, 0X48, 0X48, 0X05, 0XFB, 0X47, 0X47, 0X47, 0X47,
+ 0X30, 0X30, 0X30, 0X46, 0X46, 0X06, 0X06, 0X25, 0XFD, 0X98,
+ 0X9A, 0X9A, 0X9A, 0X9A, 0XF9, 0X99, 0X99, 0X99, 0X99, 0X99,
+ 0XFA, 0X48, 0X48, 0X48, 0X48, 0X48, 0XFB, 0X47, 0X47, 0X47,
+ 0X47, 0X47, 0X30, 0X30, 0X46, 0X46, 0X06, 0X06, 0X25, 0X25,
+ 0X25, 0X98, 0X9A, 0X9A, 0X9A, 0X9A, 0X99, 0X99, 0X99, 0X99,
+ 0X99, 0X99, 0X48, 0X48, 0X48, 0X48, 0X48, 0X48, 0X47, 0X47,
+ 0X47, 0X47, 0X47, 0X47, 0X47, 0X46, 0X46, 0X46, 0X06, 0X6A,
+ 0X25, 0X25, 0X25, 0X98, 0X9A, 0X9A, 0X9A, 0X9A, 0X99, 0X99,
+ 0X99, 0X99, 0X99, 0X99, 0X48, 0X48, 0X48, 0X48, 0X48, 0X48,
+ 0X47, 0X47, 0X47, 0X47, 0X47, 0X47, 0X47, 0X46, 0X46, 0X6A,
+ 0X6A, 0X6A, 0X25, 0X25, 0X25, 0X1D, 0XFE, 0XFE, 0XFE, 0XFE,
+ 0XFF, 0XFF, 0XFF, 0XFF, 0X96, 0X96, 0X95, 0X95, 0X95, 0X95,
+ 0X95, 0X95, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X93,
+ 0X93, 0X6A, 0X6A, 0X6A, 0X25, 0X1D, 0X1D, 0X1D, 0XFE, 0XFE,
+ 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0X96, 0X96, 0X96, 0X95, 0X95,
+ 0X95, 0X95, 0X95, 0X95, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94,
+ 0X94, 0X93, 0X93, 0X93, 0X93, 0X6A, 0X1D, 0X1D, 0X1D, 0X1D,
+ 0X97, 0X97, 0X97, 0X97, 0XFF, 0XFF, 0X96, 0X96, 0X96, 0X96,
+ 0X95, 0X95, 0X95, 0X95, 0X95, 0X95, 0X94, 0X94, 0X94, 0X94,
+ 0X94, 0X94, 0X94, 0X93, 0X93, 0X93, 0X93, 0X93, 0X1D, 0X1D,
+ 0X1D, 0X1D, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC, 0XAB, 0XAB,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8, 0XA8, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC, 0XAC, 0XAC,
+ 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA8,
+ 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7, 0XAC, 0XAC,
+ 0XAC, 0XAC, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAB, 0XAA, 0XAA,
+ 0XAA, 0XAA, 0XAA, 0XAA, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9, 0XA9,
+ 0XA9, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA8, 0XA7, 0XA7, 0XA7,
+ 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2,
+ 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E,
+ 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6, 0XA6, 0XA6,
+ 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA3,
+ 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2, 0XA6, 0XA6,
+ 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0XA5, 0XA5,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2, 0XA2, 0XA2,
+ 0XA6, 0XA6, 0XA6, 0XA6, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E, 0X4E,
+ 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA5, 0XA4, 0XA4, 0XA4, 0XA4,
+ 0XA4, 0XA4, 0XA4, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA3, 0XA2,
+ 0XA2, 0XA2, 0XA1, 0XA1, 0XA1, 0XA1, 0X27, 0X27, 0X27, 0X27,
+ 0X27, 0X27, 0X13, 0X13, 0X4C, 0X4C, 0X4C, 0X4C, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D,
+ 0X4D, 0X4D, 0X4D, 0X4D, 0X13, 0X13, 0X13, 0X4C, 0X4C, 0X4C,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1,
+ 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X13, 0X13, 0X13, 0X13, 0X13,
+ 0X13, 0X4C, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F,
+ 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E, 0XA1, 0XA1,
+ 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X13, 0X13, 0X13,
+ 0X13, 0X13, 0X13, 0X13, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E, 0X9E, 0X9E,
+ 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D, 0X4D, 0X13,
+ 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0XA0, 0XA0, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F, 0X9E,
+ 0X9E, 0X9E, 0XA1, 0XA1, 0XA1, 0XA1, 0X4D, 0X4D, 0X4D, 0X4D,
+ 0X4D, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0XA0,
+ 0XA0, 0XA0, 0XA0, 0XA0, 0XA0, 0X9F, 0X9F, 0X9F, 0X9F, 0X9F,
+ 0X9F, 0X9E, 0X9E, 0X9E, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X19, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13,
+ 0X13, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X19, 0X13, 0X13, 0X13, 0X4A,
+ 0X4A, 0X4A, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X49, 0X9C,
+ 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D,
+ 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4A, 0X4A,
+ 0X4A, 0X4A, 0X4A, 0X4A, 0X05, 0X49, 0X49, 0X49, 0X49, 0X49,
+ 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B,
+ 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B,
+ 0X4A, 0X4A, 0X4A, 0X4A, 0X4A, 0X04, 0X05, 0X05, 0X49, 0X49,
+ 0X49, 0X49, 0X49, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9C, 0X9B,
+ 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X4A, 0X4A, 0X4A, 0X4A, 0X04, 0X05, 0X05, 0X05,
+ 0X05, 0X49, 0X49, 0X49, 0X30, 0X30, 0X9C, 0X9C, 0X9C, 0X9C,
+ 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D, 0X4B, 0X4B,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X4A, 0X4A, 0X4A, 0X04, 0X04, 0X05,
+ 0X05, 0X05, 0X05, 0X05, 0X49, 0X30, 0X30, 0X30, 0X30, 0X30,
+ 0X9C, 0X9C, 0X9C, 0X9B, 0X9B, 0X9B, 0X9D, 0X9D, 0X9D, 0X9D,
+ 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4B, 0X4A, 0X4A, 0X04, 0X04,
+ 0X05, 0X05, 0X05, 0X05, 0X05, 0X05, 0X0E, 0X30, 0X30, 0X30,
+ 0X30, 0X30, 0X30, 0X30, 0X9C, 0X9B, 0X9B, 0X9B, 0X9A, 0X9A,
+ 0X9A, 0X9A, 0XF9, 0XF9, 0XF9, 0X99, 0X99, 0X99, 0XFA, 0XFA,
+ 0XFA, 0X48, 0X05, 0X05, 0X05, 0X05, 0X0E, 0X0E, 0X0E, 0X30,
+ 0X30, 0X30, 0X30, 0X30, 0X30, 0X30, 0X06, 0XFD, 0XFD, 0XFD,
+ 0X9A, 0X9A, 0X9A, 0X9A, 0XF9, 0XF9, 0X99, 0X99, 0X99, 0X99,
+ 0XFA, 0XFA, 0X48, 0X48, 0X48, 0X05, 0X05, 0X0E, 0X0E, 0X0E,
+ 0X0E, 0X0E, 0X30, 0X30, 0X30, 0X30, 0X30, 0X06, 0X06, 0X25,
+ 0XFD, 0X98, 0X9A, 0X9A, 0X9A, 0X9A, 0XF9, 0X99, 0X99, 0X99,
+ 0X99, 0X99, 0XFA, 0X48, 0X48, 0X48, 0X48, 0X48, 0X0E, 0X0E,
+ 0X0E, 0X0E, 0X0E, 0X0E, 0X30, 0X30, 0X30, 0X30, 0X46, 0X06,
+ 0X6A, 0X25, 0X98, 0X98, 0X9A, 0X9A, 0X9A, 0X9A, 0X99, 0X99,
+ 0X99, 0X99, 0X99, 0X99, 0X48, 0X48, 0X48, 0X48, 0X48, 0X48,
+ 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X30, 0X30, 0X28, 0X46,
+ 0X6A, 0X6A, 0X6A, 0X25, 0X25, 0X98, 0X9A, 0X9A, 0X9A, 0X9A,
+ 0X99, 0X99, 0X99, 0X99, 0X99, 0X99, 0X48, 0X48, 0X48, 0X48,
+ 0X48, 0X48, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X28, 0X28,
+ 0X28, 0X28, 0X6A, 0X6A, 0X6A, 0X25, 0X33, 0X33, 0X9A, 0X9A,
+ 0X9A, 0X9A, 0X99, 0X99, 0X99, 0X99, 0X99, 0X99, 0X48, 0X48,
+ 0X48, 0X48, 0X48, 0X48, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E,
+ 0X28, 0X28, 0X28, 0X6A, 0X6A, 0X6A, 0X6A, 0X33, 0X33, 0X1D,
+ 0XFE, 0XFE, 0XFE, 0XFE, 0XFF, 0XFF, 0XFF, 0X96, 0X96, 0X96,
+ 0X95, 0X95, 0X95, 0X95, 0X95, 0X95, 0X94, 0X94, 0X94, 0X94,
+ 0X94, 0X94, 0X28, 0X28, 0X28, 0X6A, 0X6A, 0X6A, 0X6A, 0X33,
+ 0X1D, 0X1D, 0X97, 0X97, 0X97, 0X97, 0XFF, 0XFF, 0X96, 0X96,
+ 0X96, 0X96, 0X95, 0X95, 0X95, 0X95, 0X95, 0X95, 0X94, 0X94,
+ 0X94, 0X94, 0X94, 0X94, 0X94, 0X93, 0X93, 0X93, 0X6A, 0X6A,
+ 0X33, 0X1D, 0X1D, 0X1D, 0X97, 0X97, 0X97, 0X97, 0XFF, 0X96,
+ 0X96, 0X96, 0X96, 0X96, 0X95, 0X95, 0X95, 0X95, 0X95, 0X95,
+ 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X94, 0X93, 0X93, 0X93,
+ 0X93, 0X93, 0X1D, 0X1D, 0X1D, 0X1D, 0X91, 0X91, 0X91, 0X91,
+ 0X90, 0X90, 0X90, 0X90, 0X90, 0X90, 0X8F, 0X8F, 0X8F, 0X8F,
+ 0X8F, 0X8F, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8D,
+ 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8C, 0X8C, 0X8C, 0X91, 0X91,
+ 0X91, 0X91, 0X90, 0X90, 0X90, 0X90, 0X90, 0X90, 0X8F, 0X8F,
+ 0X8F, 0X8F, 0X8F, 0X8F, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E,
+ 0X8E, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8C, 0X8C, 0X8C,
+ 0X91, 0X91, 0X91, 0X91, 0X90, 0X90, 0X90, 0X90, 0X90, 0X90,
+ 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8E, 0X8E, 0X8E, 0X8E,
+ 0X8E, 0X8E, 0X8E, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8C,
+ 0X8C, 0X8C, 0X91, 0X91, 0X91, 0X91, 0X90, 0X90, 0X90, 0X90,
+ 0X90, 0X90, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8E, 0X8E,
+ 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D,
+ 0X8D, 0X8C, 0X8C, 0X8C, 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A,
+ 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89, 0X89, 0X89,
+ 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X87, 0X87, 0X87,
+ 0X87, 0X87, 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B,
+ 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89,
+ 0X89, 0X89, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X87,
+ 0X87, 0X87, 0X87, 0X87, 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B,
+ 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89,
+ 0X89, 0X89, 0X89, 0X89, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88,
+ 0X88, 0X87, 0X87, 0X87, 0X87, 0X87, 0X87, 0X86, 0X86, 0X86,
+ 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A,
+ 0X89, 0X89, 0X89, 0X89, 0X89, 0X89, 0X88, 0X88, 0X88, 0X88,
+ 0X88, 0X88, 0X88, 0X87, 0X87, 0X87, 0X87, 0X87, 0X87, 0X86,
+ 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A,
+ 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89, 0X89, 0X89, 0X88, 0X88,
+ 0X88, 0X88, 0X88, 0X88, 0X88, 0X87, 0X87, 0X87, 0X87, 0X87,
+ 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A,
+ 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89, 0X89, 0X89,
+ 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X87, 0X87, 0X87,
+ 0X87, 0X87, 0X87, 0X86, 0X86, 0X86, 0X85, 0X85, 0X85, 0X85,
+ 0X84, 0X84, 0X84, 0X84, 0X84, 0X84, 0X13, 0X13, 0X13, 0X83,
+ 0X83, 0X83, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X81,
+ 0X81, 0X81, 0X81, 0X81, 0X81, 0X80, 0X80, 0X80, 0X85, 0X85,
+ 0X85, 0X85, 0X84, 0X84, 0X84, 0X84, 0X84, 0X13, 0X13, 0X13,
+ 0X13, 0X13, 0X83, 0X83, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82,
+ 0X82, 0X81, 0X81, 0X81, 0X81, 0X81, 0X81, 0X80, 0X80, 0X80,
+ 0X85, 0X85, 0X85, 0X85, 0X84, 0X84, 0X84, 0X84, 0X84, 0X13,
+ 0X13, 0X13, 0X13, 0X13, 0X13, 0X83, 0X82, 0X82, 0X82, 0X82,
+ 0X82, 0X82, 0X82, 0X81, 0X81, 0X81, 0X81, 0X81, 0X81, 0X80,
+ 0X80, 0X80, 0X85, 0X85, 0X85, 0X85, 0X84, 0X84, 0X84, 0X84,
+ 0X84, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X82, 0X82,
+ 0X82, 0X82, 0X82, 0X82, 0X82, 0X81, 0X81, 0X81, 0X81, 0X81,
+ 0X81, 0X80, 0X80, 0X80, 0X85, 0X85, 0X85, 0X85, 0X84, 0X84,
+ 0X84, 0X84, 0X84, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13,
+ 0X13, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X81, 0X81, 0X81,
+ 0X81, 0X81, 0X81, 0X80, 0X80, 0X80, 0X85, 0X85, 0X85, 0X85,
+ 0X84, 0X84, 0X84, 0X84, 0X84, 0X13, 0X13, 0X13, 0X13, 0X13,
+ 0X13, 0X13, 0X13, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X81,
+ 0X81, 0X81, 0X81, 0X81, 0X81, 0X80, 0X80, 0X80, 0X7F, 0X7F,
+ 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X13, 0X13, 0X13,
+ 0X13, 0X13, 0X13, 0X13, 0X13, 0X44, 0X44, 0X44, 0X44, 0X44,
+ 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C,
+ 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X13,
+ 0X13, 0X13, 0X13, 0X13, 0X45, 0X45, 0X44, 0X44, 0X44, 0X44,
+ 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C,
+ 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E,
+ 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45, 0X45, 0X45, 0X44, 0X44,
+ 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D,
+ 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E,
+ 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45, 0X45, 0X45,
+ 0X05, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D,
+ 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F,
+ 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45,
+ 0X45, 0X05, 0X05, 0X05, 0X44, 0X44, 0X44, 0X44, 0X30, 0X30,
+ 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F,
+ 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45,
+ 0X45, 0X45, 0X05, 0X05, 0X05, 0X05, 0X05, 0X44, 0X44, 0X30,
+ 0X30, 0X30, 0X30, 0X30, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C,
+ 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E,
+ 0X45, 0X45, 0X45, 0X04, 0X05, 0X05, 0X05, 0X05, 0X05, 0X0E,
+ 0X0E, 0X30, 0X30, 0X30, 0X30, 0X30, 0X30, 0X30, 0X7D, 0X7C,
+ 0X7C, 0X7C, 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A,
+ 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79, 0X05, 0X05, 0X05, 0X05,
+ 0X0E, 0X0E, 0X0E, 0X0E, 0X30, 0X30, 0X30, 0X30, 0X30, 0X30,
+ 0X42, 0X78, 0X78, 0X78, 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A,
+ 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79, 0X79, 0X05,
+ 0X05, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X30, 0X30, 0X30, 0X30,
+ 0X30, 0X42, 0X6A, 0X6A, 0X78, 0X78, 0X7B, 0X7B, 0X7B, 0X7B,
+ 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79,
+ 0X79, 0X79, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X30, 0X30,
+ 0X30, 0X28, 0X28, 0X6A, 0X6A, 0X6A, 0X78, 0X78, 0X7B, 0X7B,
+ 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79,
+ 0X79, 0X79, 0X79, 0X79, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E,
+ 0X28, 0X28, 0X28, 0X28, 0X28, 0X6A, 0X6A, 0X33, 0X33, 0X78,
+ 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A,
+ 0X79, 0X79, 0X79, 0X79, 0X79, 0X79, 0X0E, 0X0E, 0X0E, 0X0E,
+ 0X0E, 0X0E, 0X28, 0X28, 0X28, 0X28, 0X6A, 0X6A, 0X6A, 0X33,
+ 0X33, 0X33, 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A,
+ 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79, 0X79, 0X79, 0X0E, 0X0E,
+ 0X0E, 0X0E, 0X0E, 0X0E, 0X28, 0X28, 0X28, 0X28, 0X6A, 0X6A,
+ 0X33, 0X33, 0X33, 0X33, 0X77, 0X77, 0X77, 0X77, 0X76, 0X76,
+ 0X76, 0X76, 0X76, 0X76, 0X75, 0X75, 0X75, 0X75, 0X75, 0X75,
+ 0X0E, 0X0E, 0X74, 0X74, 0X74, 0X28, 0X28, 0X28, 0X28, 0X28,
+ 0X2D, 0X6A, 0X33, 0X33, 0X33, 0X69, 0X77, 0X77, 0X77, 0X77,
+ 0X76, 0X76, 0X76, 0X76, 0X76, 0X76, 0X75, 0X75, 0X75, 0X75,
+ 0X75, 0X75, 0X74, 0X74, 0X74, 0X74, 0X74, 0X74, 0X28, 0X28,
+ 0X28, 0X2D, 0X2D, 0X2D, 0X69, 0X69, 0X69, 0X69, 0X77, 0X77,
+ 0X77, 0X77, 0X76, 0X76, 0X76, 0X76, 0X76, 0X76, 0X75, 0X75,
+ 0X75, 0X75, 0X75, 0X75, 0X74, 0X74, 0X74, 0X74, 0X74, 0X74,
+ 0X74, 0X41, 0X41, 0X41, 0X41, 0X2D, 0X69, 0X69, 0X69, 0X69,
+ 0X91, 0X91, 0X91, 0X91, 0X90, 0X90, 0X90, 0X90, 0X90, 0X90,
+ 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8E, 0X8E, 0X8E, 0X8E,
+ 0X8E, 0X8E, 0X8E, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8C,
+ 0X8C, 0X8C, 0X91, 0X91, 0X91, 0X91, 0X90, 0X90, 0X90, 0X90,
+ 0X90, 0X90, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8E, 0X8E,
+ 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D,
+ 0X8D, 0X8C, 0X8C, 0X8C, 0X91, 0X91, 0X91, 0X91, 0X90, 0X90,
+ 0X90, 0X90, 0X90, 0X90, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F,
+ 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8D, 0X8D, 0X8D,
+ 0X8D, 0X8D, 0X8D, 0X8C, 0X8C, 0X8C, 0X91, 0X91, 0X91, 0X91,
+ 0X90, 0X90, 0X90, 0X90, 0X90, 0X90, 0X8F, 0X8F, 0X8F, 0X8F,
+ 0X8F, 0X8F, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8D,
+ 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8C, 0X8C, 0X8C, 0X8B, 0X8B,
+ 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89,
+ 0X89, 0X89, 0X89, 0X89, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88,
+ 0X88, 0X87, 0X87, 0X87, 0X87, 0X87, 0X87, 0X86, 0X86, 0X86,
+ 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A,
+ 0X89, 0X89, 0X89, 0X89, 0X89, 0X89, 0X88, 0X88, 0X88, 0X88,
+ 0X88, 0X88, 0X88, 0X87, 0X87, 0X87, 0X87, 0X87, 0X87, 0X86,
+ 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A,
+ 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89, 0X89, 0X89, 0X88, 0X88,
+ 0X88, 0X88, 0X88, 0X88, 0X88, 0X87, 0X87, 0X87, 0X87, 0X87,
+ 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A,
+ 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89, 0X89, 0X89,
+ 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X87, 0X87, 0X87,
+ 0X87, 0X87, 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B,
+ 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89,
+ 0X89, 0X89, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X87,
+ 0X87, 0X87, 0X87, 0X87, 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B,
+ 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89,
+ 0X89, 0X89, 0X89, 0X89, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88,
+ 0X88, 0X87, 0X87, 0X87, 0X87, 0X87, 0X87, 0X86, 0X86, 0X86,
+ 0X85, 0X85, 0X85, 0X85, 0X84, 0X84, 0X84, 0X84, 0X84, 0X84,
+ 0X83, 0X83, 0X83, 0X83, 0X83, 0X83, 0X82, 0X82, 0X82, 0X82,
+ 0X82, 0X82, 0X82, 0X81, 0X81, 0X81, 0X81, 0X81, 0X81, 0X80,
+ 0X80, 0X80, 0X85, 0X85, 0X85, 0X85, 0X84, 0X84, 0X84, 0X84,
+ 0X84, 0X84, 0X83, 0X83, 0X83, 0X83, 0X83, 0X83, 0X82, 0X82,
+ 0X82, 0X82, 0X82, 0X82, 0X82, 0X81, 0X81, 0X81, 0X81, 0X81,
+ 0X81, 0X80, 0X80, 0X80, 0X85, 0X85, 0X85, 0X85, 0X84, 0X84,
+ 0X84, 0X84, 0X84, 0X84, 0X13, 0X83, 0X83, 0X83, 0X83, 0X83,
+ 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X81, 0X81, 0X81,
+ 0X81, 0X81, 0X81, 0X80, 0X80, 0X80, 0X85, 0X85, 0X85, 0X85,
+ 0X84, 0X84, 0X84, 0X84, 0X84, 0X84, 0X13, 0X13, 0X83, 0X83,
+ 0X83, 0X83, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X81,
+ 0X81, 0X81, 0X81, 0X81, 0X81, 0X80, 0X80, 0X80, 0X85, 0X85,
+ 0X85, 0X85, 0X84, 0X84, 0X84, 0X84, 0X84, 0X84, 0X13, 0X13,
+ 0X13, 0X83, 0X83, 0X83, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82,
+ 0X82, 0X81, 0X81, 0X81, 0X81, 0X81, 0X81, 0X80, 0X80, 0X80,
+ 0X85, 0X85, 0X85, 0X85, 0X84, 0X84, 0X84, 0X84, 0X84, 0X13,
+ 0X13, 0X13, 0X13, 0X13, 0X83, 0X83, 0X82, 0X82, 0X82, 0X82,
+ 0X82, 0X82, 0X82, 0X81, 0X81, 0X81, 0X81, 0X81, 0X81, 0X80,
+ 0X80, 0X80, 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E,
+ 0X7E, 0X13, 0X13, 0X13, 0X13, 0X13, 0X13, 0X45, 0X44, 0X44,
+ 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D,
+ 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E,
+ 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45, 0X45, 0X45,
+ 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D,
+ 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F,
+ 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45,
+ 0X45, 0X45, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D,
+ 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F,
+ 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45,
+ 0X45, 0X45, 0X45, 0X45, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44,
+ 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C,
+ 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E,
+ 0X45, 0X45, 0X45, 0X45, 0X45, 0X45, 0X44, 0X44, 0X44, 0X44,
+ 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C,
+ 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E,
+ 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45, 0X45, 0X45, 0X05, 0X44,
+ 0X44, 0X44, 0X44, 0X44, 0X30, 0X30, 0X7D, 0X7D, 0X7D, 0X7D,
+ 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E,
+ 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45, 0X45, 0X05,
+ 0X05, 0X05, 0X0E, 0X0E, 0X0E, 0X0E, 0X30, 0X30, 0X30, 0X30,
+ 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C, 0X7B, 0X7B, 0X7B, 0X7B,
+ 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79,
+ 0X79, 0X05, 0X05, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X30, 0X30,
+ 0X30, 0X30, 0X42, 0X42, 0X42, 0X78, 0X78, 0X78, 0X7B, 0X7B,
+ 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79,
+ 0X79, 0X79, 0X79, 0X79, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E, 0X0E,
+ 0X30, 0X30, 0X30, 0X42, 0X42, 0X42, 0X42, 0X78, 0X78, 0X78,
+ 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A,
+ 0X79, 0X79, 0X79, 0X79, 0X79, 0X79, 0X0E, 0X0E, 0X0E, 0X0E,
+ 0X0E, 0X0E, 0X28, 0X28, 0X28, 0X28, 0X42, 0X42, 0X42, 0X78,
+ 0X78, 0X78, 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A,
+ 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79, 0X79, 0X79, 0X0E, 0X0E,
+ 0X0E, 0X0E, 0X0E, 0X0E, 0X28, 0X28, 0X28, 0X28, 0X28, 0X42,
+ 0X6A, 0X33, 0X78, 0X78, 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A,
+ 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79, 0X79, 0X79,
+ 0X0E, 0X0E, 0X0E, 0X0E, 0X43, 0X43, 0X28, 0X28, 0X28, 0X28,
+ 0X28, 0X6A, 0X33, 0X33, 0X33, 0X33, 0X7B, 0X7B, 0X7B, 0X7B,
+ 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79,
+ 0X79, 0X79, 0X43, 0X43, 0X43, 0X43, 0X43, 0X28, 0X28, 0X28,
+ 0X28, 0X28, 0X2D, 0X2D, 0X33, 0X33, 0X33, 0X33, 0X77, 0X77,
+ 0X77, 0X77, 0X76, 0X76, 0X76, 0X76, 0X76, 0X76, 0X75, 0X75,
+ 0X75, 0X75, 0X75, 0X75, 0X74, 0X74, 0X74, 0X74, 0X74, 0X74,
+ 0X28, 0X28, 0X28, 0X28, 0X2D, 0X2D, 0X2D, 0X33, 0X69, 0X69,
+ 0X77, 0X77, 0X77, 0X77, 0X76, 0X76, 0X76, 0X76, 0X76, 0X76,
+ 0X75, 0X75, 0X75, 0X75, 0X75, 0X75, 0X74, 0X74, 0X74, 0X74,
+ 0X74, 0X74, 0X74, 0X28, 0X41, 0X2D, 0X2D, 0X2D, 0X2D, 0X69,
+ 0X69, 0X69, 0X77, 0X77, 0X77, 0X77, 0X76, 0X76, 0X76, 0X76,
+ 0X76, 0X76, 0X75, 0X75, 0X75, 0X75, 0X75, 0X75, 0X74, 0X74,
+ 0X74, 0X74, 0X74, 0X74, 0X74, 0X41, 0X41, 0X41, 0X41, 0X2D,
+ 0X69, 0X69, 0X69, 0X0D, 0X91, 0X91, 0X91, 0X91, 0X90, 0X90,
+ 0X90, 0X90, 0X90, 0X90, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F,
+ 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8D, 0X8D, 0X8D,
+ 0X8D, 0X8D, 0X8D, 0X8C, 0X8C, 0X8C, 0X91, 0X91, 0X91, 0X91,
+ 0X90, 0X90, 0X90, 0X90, 0X90, 0X90, 0X8F, 0X8F, 0X8F, 0X8F,
+ 0X8F, 0X8F, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8D,
+ 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8C, 0X8C, 0X8C, 0X91, 0X91,
+ 0X91, 0X91, 0X90, 0X90, 0X90, 0X90, 0X90, 0X90, 0X8F, 0X8F,
+ 0X8F, 0X8F, 0X8F, 0X8F, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E, 0X8E,
+ 0X8E, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8C, 0X8C, 0X8C,
+ 0X91, 0X91, 0X91, 0X91, 0X90, 0X90, 0X90, 0X90, 0X90, 0X90,
+ 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8F, 0X8E, 0X8E, 0X8E, 0X8E,
+ 0X8E, 0X8E, 0X8E, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8D, 0X8C,
+ 0X8C, 0X8C, 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A,
+ 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89, 0X89, 0X89, 0X88, 0X88,
+ 0X88, 0X88, 0X88, 0X88, 0X88, 0X87, 0X87, 0X87, 0X87, 0X87,
+ 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A,
+ 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89, 0X89, 0X89,
+ 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X87, 0X87, 0X87,
+ 0X87, 0X87, 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B,
+ 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89,
+ 0X89, 0X89, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88, 0X87,
+ 0X87, 0X87, 0X87, 0X87, 0X87, 0X86, 0X86, 0X86, 0X8B, 0X8B,
+ 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X89, 0X89,
+ 0X89, 0X89, 0X89, 0X89, 0X88, 0X88, 0X88, 0X88, 0X88, 0X88,
+ 0X88, 0X87, 0X87, 0X87, 0X87, 0X87, 0X87, 0X86, 0X86, 0X86,
+ 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A, 0X8A,
+ 0X89, 0X89, 0X89, 0X89, 0X89, 0X89, 0X88, 0X88, 0X88, 0X88,
+ 0X88, 0X88, 0X88, 0X87, 0X87, 0X87, 0X87, 0X87, 0X87, 0X86,
+ 0X86, 0X86, 0X8B, 0X8B, 0X8B, 0X8B, 0X8A, 0X8A, 0X8A, 0X8A,
+ 0X8A, 0X8A, 0X89, 0X89, 0X89, 0X89, 0X89, 0X89, 0X88, 0X88,
+ 0X88, 0X88, 0X88, 0X88, 0X88, 0X87, 0X87, 0X87, 0X87, 0X87,
+ 0X87, 0X86, 0X86, 0X86, 0X85, 0X85, 0X85, 0X85, 0X84, 0X84,
+ 0X84, 0X84, 0X84, 0X84, 0X83, 0X83, 0X83, 0X83, 0X83, 0X83,
+ 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X81, 0X81, 0X81,
+ 0X81, 0X81, 0X81, 0X80, 0X80, 0X80, 0X85, 0X85, 0X85, 0X85,
+ 0X84, 0X84, 0X84, 0X84, 0X84, 0X84, 0X83, 0X83, 0X83, 0X83,
+ 0X83, 0X83, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X81,
+ 0X81, 0X81, 0X81, 0X81, 0X81, 0X80, 0X80, 0X80, 0X85, 0X85,
+ 0X85, 0X85, 0X84, 0X84, 0X84, 0X84, 0X84, 0X84, 0X83, 0X83,
+ 0X83, 0X83, 0X83, 0X83, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82,
+ 0X82, 0X81, 0X81, 0X81, 0X81, 0X81, 0X81, 0X80, 0X80, 0X80,
+ 0X85, 0X85, 0X85, 0X85, 0X84, 0X84, 0X84, 0X84, 0X84, 0X84,
+ 0X83, 0X83, 0X83, 0X83, 0X83, 0X83, 0X82, 0X82, 0X82, 0X82,
+ 0X82, 0X82, 0X82, 0X81, 0X81, 0X81, 0X81, 0X81, 0X81, 0X80,
+ 0X80, 0X80, 0X85, 0X85, 0X85, 0X85, 0X84, 0X84, 0X84, 0X84,
+ 0X84, 0X84, 0X83, 0X83, 0X83, 0X83, 0X83, 0X83, 0X82, 0X82,
+ 0X82, 0X82, 0X82, 0X82, 0X82, 0X81, 0X81, 0X81, 0X81, 0X81,
+ 0X81, 0X80, 0X80, 0X80, 0X85, 0X85, 0X85, 0X85, 0X84, 0X84,
+ 0X84, 0X84, 0X84, 0X84, 0X83, 0X83, 0X83, 0X83, 0X83, 0X83,
+ 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X82, 0X81, 0X81, 0X81,
+ 0X81, 0X81, 0X81, 0X80, 0X80, 0X80, 0X7F, 0X7F, 0X7F, 0X7F,
+ 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X13, 0X45, 0X45, 0X45,
+ 0X45, 0X45, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D,
+ 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F,
+ 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45,
+ 0X45, 0X45, 0X45, 0X45, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44,
+ 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C,
+ 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E,
+ 0X45, 0X45, 0X45, 0X45, 0X45, 0X45, 0X44, 0X44, 0X44, 0X44,
+ 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C,
+ 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E,
+ 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45, 0X45, 0X45, 0X44, 0X44,
+ 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D,
+ 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F, 0X7E, 0X7E,
+ 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45, 0X45, 0X45,
+ 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D, 0X7D, 0X7D,
+ 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F, 0X7F, 0X7F,
+ 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45, 0X45, 0X45,
+ 0X45, 0X45, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X44, 0X7D,
+ 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C, 0X7F, 0X7F,
+ 0X7F, 0X7F, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X7E, 0X45, 0X45,
+ 0X45, 0X45, 0X45, 0X45, 0X05, 0X44, 0X44, 0X44, 0X44, 0X44,
+ 0X30, 0X30, 0X7D, 0X7D, 0X7D, 0X7D, 0X7D, 0X7C, 0X7C, 0X7C,
+ 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A,
+ 0X79, 0X79, 0X79, 0X79, 0X79, 0X79, 0X43, 0X43, 0X43, 0X43,
+ 0X43, 0X43, 0X30, 0X30, 0X42, 0X42, 0X42, 0X42, 0X42, 0X78,
+ 0X78, 0X78, 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A,
+ 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79, 0X79, 0X79, 0X43, 0X43,
+ 0X43, 0X43, 0X43, 0X43, 0X43, 0X42, 0X42, 0X42, 0X42, 0X42,
+ 0X42, 0X78, 0X78, 0X78, 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A,
+ 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79, 0X79, 0X79,
+ 0X43, 0X43, 0X43, 0X43, 0X43, 0X43, 0X28, 0X28, 0X42, 0X42,
+ 0X42, 0X42, 0X42, 0X78, 0X78, 0X78, 0X7B, 0X7B, 0X7B, 0X7B,
+ 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79, 0X79, 0X79,
+ 0X79, 0X79, 0X43, 0X43, 0X43, 0X43, 0X43, 0X43, 0X28, 0X28,
+ 0X28, 0X28, 0X42, 0X42, 0X42, 0X78, 0X78, 0X78, 0X7B, 0X7B,
+ 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X79, 0X79,
+ 0X79, 0X79, 0X79, 0X79, 0X43, 0X43, 0X43, 0X43, 0X43, 0X43,
+ 0X28, 0X28, 0X28, 0X28, 0X28, 0X2D, 0X2D, 0X33, 0X33, 0X78,
+ 0X7B, 0X7B, 0X7B, 0X7B, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A, 0X7A,
+ 0X79, 0X79, 0X79, 0X79, 0X79, 0X79, 0X43, 0X43, 0X43, 0X43,
+ 0X43, 0X43, 0X28, 0X28, 0X28, 0X28, 0X2D, 0X2D, 0X2D, 0X33,
+ 0X33, 0X69, 0X77, 0X77, 0X77, 0X77, 0X76, 0X76, 0X76, 0X76,
+ 0X76, 0X76, 0X75, 0X75, 0X75, 0X75, 0X75, 0X75, 0X74, 0X74,
+ 0X74, 0X74, 0X74, 0X74, 0X28, 0X28, 0X28, 0X2D, 0X2D, 0X2D,
+ 0X2D, 0X69, 0X69, 0X69, 0X77, 0X77, 0X77, 0X77, 0X76, 0X76,
+ 0X76, 0X76, 0X76, 0X76, 0X75, 0X75, 0X75, 0X75, 0X75, 0X75,
+ 0X74, 0X74, 0X74, 0X74, 0X74, 0X74, 0X74, 0X41, 0X41, 0X41,
+ 0X2D, 0X2D, 0X2D, 0X69, 0X69, 0X0D, 0X77, 0X77, 0X77, 0X77,
+ 0X76, 0X76, 0X76, 0X76, 0X76, 0X76, 0X75, 0X75, 0X75, 0X75,
+ 0X75, 0X75, 0X74, 0X74, 0X74, 0X74, 0X74, 0X74, 0X74, 0X41,
+ 0X41, 0X41, 0X41, 0X2D, 0X2D, 0X69, 0X0D, 0X0D
+};
+
+
+} // End of namespace Lab
diff --git a/engines/lab/special.cpp b/engines/lab/special.cpp
new file mode 100644
index 0000000000..5542b05716
--- /dev/null
+++ b/engines/lab/special.cpp
@@ -0,0 +1,2219 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/labfun.h"
+#include "lab/parsefun.h"
+#include "lab/interface.h"
+#include "lab/diff.h"
+#include "lab/vga.h"
+#include "lab/text.h"
+#include "lab/mouse.h"
+#include "lab/timing.h"
+#include "lab/stddefines.h"
+#include "lab/parsetypes.h"
+
+#define MODERNGAMESAVE 1
+
+#if defined(MODERNGAMESAVE)
+#include "lab/modernsavegame.h"
+#endif
+
+namespace Lab {
+
+#ifdef GAME_TRIAL
+int g_IsRegistered;
+#endif
+
+extern bool nopalchange, DoBlack, IsHiRes;
+
+extern struct BitMap *DispBitMap, *DrawBitMap;
+extern char diffcmap[3 * 256];
+
+extern uint32 VGAScreenWidth, VGAScreenHeight;
+
+
+#define COMBINATIONUNLOCKED 130
+#define BRICKOPEN 115
+
+
+static uint16 hipal[20];
+extern uint16 *FadePalette;
+
+
+static byte *loadBackPict(const char *fileName, bool tomem) {
+ uint16 counter;
+ byte *res = NULL;
+
+ FadePalette = hipal;
+ nopalchange = true;
+
+ if (tomem)
+ res = readPictToMem(fileName, VGAScreenWidth, VGAScreenHeight);
+ else
+ readPict(fileName, true);
+
+ for (counter = 0; counter < 16; counter++) {
+ hipal[counter] = ((diffcmap[counter * 3] >> 2) << 8) +
+ ((diffcmap[counter * 3 + 1] >> 2) << 4) +
+ ((diffcmap[counter * 3 + 2] >> 2));
+ }
+
+ nopalchange = false;
+
+ return res;
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+/*-------------------------- Combination Lock Rules --------------------------*/
+/*----------------------------------------------------------------------------*/
+
+
+
+
+static struct Image *Images[10];
+
+
+uint16 combination[6] = {0, 0, 0, 0, 0, 0}, solution[] = {0, 4, 0, 8, 7, 2};
+
+static uint16 combx[] = {45, 83, 129, 166, 211, 248};
+
+
+
+/*****************************************************************************/
+/* Draws the images of the combination lock to the display bitmap. */
+/*****************************************************************************/
+static void doCombination(void) {
+ uint16 counter;
+
+ for (counter = 0; counter <= 5; counter++)
+ drawImage(Images[combination[counter]], VGAScaleX(combx[counter]), VGAScaleY(65));
+}
+
+
+extern char *TempScrollData;
+
+/*****************************************************************************/
+/* Reads in a backdrop picture. */
+/*****************************************************************************/
+void showCombination(const char *filename) {
+ uint16 CurBit;
+ byte **buffer;
+
+ resetBuffer();
+ DoBlack = true;
+ nopalchange = true;
+ readPict(filename, true);
+ nopalchange = false;
+
+ blackScreen();
+
+ buffer = g_music->newOpen("P:Numbers");
+
+ for (CurBit = 0; CurBit < 10; CurBit++)
+ readImage(buffer, &(Images[CurBit]));
+
+ allocFile((void **)&TempScrollData, Images[0]->Width * Images[0]->Height * 2L, "tempdata");
+
+ doCombination();
+
+ VGASetPal(diffcmap, 256);
+}
+
+
+
+/*****************************************************************************/
+/* Changes the combination number of one of the slots */
+/*****************************************************************************/
+static void changeCombination(LargeSet Conditions, uint16 number) {
+ struct Image display;
+ uint16 counter, combnum;
+ bool unlocked = true;
+
+ if (combination[number] < 9)
+ (combination[number])++;
+ else
+ combination[number] = 0;
+
+ combnum = combination[number];
+
+ display.ImageData = getVGABaseAddr();
+ display.Width = VGAScreenWidth;
+ display.Height = VGAScreenHeight;
+
+ /* NYI:
+ readPict("Music:Thunk", true);
+ */
+
+ for (counter = 1; counter <= (Images[combnum]->Height / 2); counter++) {
+ if (IsHiRes) {
+ if (counter & 1)
+ waitTOF();
+ } else
+ waitTOF();
+
+#if !defined(DOSCODE)
+ display.ImageData = getVGABaseAddr();
+#endif
+
+ scrollDisplayY(2, VGAScaleX(combx[number]), VGAScaleY(65), VGAScaleX(combx[number]) + (Images[combnum])->Width - 1, VGAScaleY(65) + (Images[combnum])->Height);
+
+ bltBitMap(Images[combnum], 0, (Images[combnum])->Height - (2 * counter), &(display), VGAScaleX(combx[number]), VGAScaleY(65), (Images[combnum])->Width, 2);
+ }
+
+ /*
+ if (memcmp(combination, solution, (size_t) 12) == 0)
+ inclElement(Conditions, COMBINATIONUNLOCKED);
+ else
+ exclElement(Conditions, COMBINATIONUNLOCKED);
+ */
+
+ for (counter = 0; counter < 6; counter++)
+ unlocked = (combination[counter] == solution[counter]) && unlocked;
+
+ if (unlocked)
+ inclElement(Conditions, COMBINATIONUNLOCKED);
+ else
+ exclElement(Conditions, COMBINATIONUNLOCKED);
+
+#if !defined(DOSCODE)
+ ungetVGABaseAddr();
+#endif
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Processes mouse clicks and changes the combination. */
+/*****************************************************************************/
+void mouseCombination(LargeSet Conditions, uint16 x, uint16 y) {
+ uint16 number;
+
+ x = VGAUnScaleX(x);
+ y = VGAUnScaleY(y);
+
+ if ((y >= 63) && (y <= 99)) {
+ if ((x >= 44) && (x < 83))
+ number = 0;
+ else if (x < 127)
+ number = 1;
+ else if (x < 165)
+ number = 2;
+ else if (x < 210)
+ number = 3;
+ else if (x < 245)
+ number = 4;
+ else if (x < 286)
+ number = 5;
+ else
+ return;
+
+ changeCombination(Conditions, number);
+ }
+}
+
+
+
+/*----------------------------------------------------------------------------*/
+/*----------------------------- Tile Puzzle Rules ----------------------------*/
+/*----------------------------------------------------------------------------*/
+
+
+
+
+struct Image *Tiles[16];
+int16 CurTile[4] [4] = {
+ { 1, 5, 9, 13 },
+ { 2, 6, 10, 14 },
+ { 3, 7, 11, 15 },
+ { 4, 8, 12, 0 }
+}, TileSolution[4] [4] = {
+ { 7, 1, 8, 3 },
+ { 2, 11, 15, 4 },
+ { 9, 5, 14, 6 },
+ { 10, 13, 12, 0}
+};
+
+
+/*****************************************************************************/
+/* Draws the images of the combination lock to the display bitmap. */
+/*****************************************************************************/
+static void doTile(bool showsolution) {
+ uint16 row = 0, col = 0, rowm, colm, num;
+ int16 rows, cols;
+
+ if (showsolution) {
+ rowm = VGAScaleY(23);
+ colm = VGAScaleX(27);
+
+ rows = VGAScaleY(31);
+ cols = VGAScaleX(105);
+ } else {
+ setAPen(0);
+ rectFill(VGAScaleX(97), VGAScaleY(22), VGAScaleX(220), VGAScaleY(126));
+
+ rowm = VGAScaleY(25);
+ colm = VGAScaleX(30);
+
+ rows = VGAScaleY(25);
+ cols = VGAScaleX(100);
+ }
+
+ while (row < 4) {
+ while (col < 4) {
+ if (showsolution)
+ num = TileSolution[col] [row];
+ else
+ num = CurTile[col] [row];
+
+ if (showsolution || num)
+ drawImage(Tiles[num], cols + (col * colm), rows + (row * rowm));
+
+ col++;
+ }
+
+ row++;
+ col = 0;
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads in a backdrop picture. */
+/*****************************************************************************/
+void showTile(const char *filename, bool showsolution) {
+ uint16 CurBit, start;
+ byte **buffer;
+
+ resetBuffer();
+ DoBlack = true;
+ nopalchange = true;
+ readPict(filename, true);
+ nopalchange = false;
+ blackScreen();
+
+ if (showsolution) {
+ start = 0;
+ buffer = g_music->newOpen("P:TileSolution");
+ } else {
+ start = 1;
+ buffer = g_music->newOpen("P:Tile");
+ }
+
+ if (!buffer)
+ return;
+
+ for (CurBit = start; CurBit < 16; CurBit++)
+ readImage(buffer, &(Tiles[CurBit]));
+
+ allocFile((void **)&TempScrollData, Tiles[1]->Width * Tiles[1]->Height * 2L, "tempdata");
+
+ doTile(showsolution);
+
+ VGASetPal(diffcmap, 256);
+}
+
+
+
+#define LEFTSCROLL 1
+#define RIGHTSCROLL 2
+#define UPSCROLL 3
+#define DOWNSCROLL 4
+
+
+
+
+static void scrollRaster(int16 dx, int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+ if (dx)
+ scrollDisplayX(dx, x1, y1, x2, y2);
+
+ if (dy)
+ scrollDisplayY(dy, x1, y1, x2, y2);
+}
+
+
+
+
+/*****************************************************************************/
+/* Does the scrolling for the tiles on the tile puzzle. */
+/*****************************************************************************/
+static void doTileScroll(uint16 col, uint16 row, uint16 scrolltype) {
+ int16 dX = 0, dY = 0, dx = 0, dy = 0, sx = 0, sy = 0;
+ uint16 last = 0, x1, y1;
+ uint16 counter;
+
+ if (scrolltype == LEFTSCROLL) {
+ dX = VGAScaleXs(5);
+ sx = VGAScaleXs(5);
+ last = 6;
+ } else if (scrolltype == RIGHTSCROLL) {
+ dX = VGAScaleXs(-5);
+ dx = VGAScaleXs(-5);
+ sx = VGAScaleX(5);
+ last = 6;
+ } else if (scrolltype == UPSCROLL) {
+ dY = VGAScaleYs(5);
+ sy = VGAScaleYs(5);
+ last = 5;
+ } else if (scrolltype == DOWNSCROLL) {
+ dY = VGAScaleYs(-5);
+ dy = VGAScaleYs(-5);
+ sy = VGAScaleYs(5);
+ last = 5;
+ }
+
+ sx += SVGACord(2);
+
+ x1 = VGAScaleX(100) + (col * VGAScaleX(30)) + dx;
+ y1 = VGAScaleY(25) + (row * VGAScaleY(25)) + dy;
+
+ for (counter = 0; counter < last; counter++) {
+ waitTOF();
+ scrollRaster(dX, dY, x1, y1, x1 + VGAScaleX(28) + sx, y1 + VGAScaleY(23) + sy);
+ x1 += dX;
+ y1 += dY;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Changes the combination number of one of the slots */
+/*****************************************************************************/
+static void changeTile(LargeSet Conditions, uint16 col, uint16 row) {
+ bool check;
+ int16 scrolltype = -1;
+
+ if (row > 0) {
+ if (CurTile[col] [row - 1] == 0) {
+ CurTile[col] [row - 1] = CurTile[col] [row];
+ CurTile[col] [row] = 0;
+ scrolltype = DOWNSCROLL;
+ }
+ }
+
+ if (col > 0) {
+ if (CurTile[col - 1] [row] == 0) {
+ CurTile[col - 1] [row] = CurTile[col] [row];
+ CurTile[col] [row] = 0;
+ scrolltype = RIGHTSCROLL;
+ }
+ }
+
+ if (row < 3) {
+ if (CurTile[col] [row + 1] == 0) {
+ CurTile[col] [row + 1] = CurTile[col] [row];
+ CurTile[col] [row] = 0;
+ scrolltype = UPSCROLL;
+ }
+ }
+
+ if (col < 3) {
+ if (CurTile[col + 1] [row] == 0) {
+ CurTile[col + 1] [row] = CurTile[col] [row];
+ CurTile[col] [row] = 0;
+ scrolltype = LEFTSCROLL;
+ }
+ }
+
+ if (scrolltype != -1) {
+ /* NYI:
+ readPict("Music:Click", true);
+ */
+ doTileScroll(col, row, scrolltype);
+
+#if defined(LABDEMO)
+ return;
+#endif
+
+#if defined(GAME_TRIAL)
+
+ if (!g_IsRegistered)
+ return;
+
+#endif
+
+ check = true;
+ row = 0;
+ col = 0;
+
+ while (row < 4) {
+ while (col < 4) {
+ check = check && (CurTile[row] [col] == TileSolution[row] [col]);
+ col++;
+ }
+
+ row++;
+ col = 0;
+ }
+
+ if (check) {
+ inclElement(Conditions, BRICKOPEN); /* unlocked combination */
+ DoBlack = true;
+ check = readPict("p:Up/BDOpen", true);
+ }
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Processes mouse clicks and changes the combination. */
+/*****************************************************************************/
+void mouseTile(LargeSet Conditions, uint16 x, uint16 y) {
+ x = VGAUnScaleX(x);
+ y = VGAUnScaleY(y);
+
+ if ((x < 101) || (y < 26))
+ return;
+
+ x = (x - 101) / 30;
+ y = (y - 26) / 25;
+
+ if ((x < 4) && (y < 4))
+ changeTile(Conditions, x, y);
+}
+
+
+/*---------------------------------------------------------------------------*/
+/*------------------------ Does the detective notes. ------------------------*/
+/*---------------------------------------------------------------------------*/
+
+extern struct TextFont *MsgFont;
+static struct TextFont *BigMsgFont;
+static struct TextFont bmfont;
+
+
+/*****************************************************************************/
+/* Does the things to properly set up the detective notes. */
+/*****************************************************************************/
+void doNotes(void) {
+ char *ntext;
+
+ /* Load in the data */
+ BigMsgFont = &bmfont;
+
+ if (!getFont("P:Note.fon", BigMsgFont)) {
+ BigMsgFont = NULL;
+ return;
+ }
+
+ if ((ntext = getText("Lab:Rooms/Notes")) == NULL)
+ return;
+
+ flowText(BigMsgFont, -2 + SVGACord(1), 0, 0, false, false, true, true, VGAScaleX(25) + SVGACord(15), VGAScaleY(50), VGAScaleX(295) - SVGACord(15), VGAScaleY(148), ntext);
+
+ VGASetPal(diffcmap, 256);
+ freeAllStolenMem();
+}
+
+
+
+
+/*---------------------------------------------------------------------------*/
+/*---------------------- Does the Old West newspaper. ----------------------*/
+/*---------------------------------------------------------------------------*/
+
+
+
+/*****************************************************************************/
+/* Does the things to properly set up the old west newspaper. Assumes that */
+/* OpenHiRes already called. */
+/*****************************************************************************/
+void doWestPaper(void) {
+ char *ntext;
+ int32 FileLen, CharsPrinted;
+ uint16 y = 268;
+
+ BigMsgFont = &bmfont;
+
+ if (!getFont("P:News22.fon", BigMsgFont)) {
+ BigMsgFont = NULL;
+ return;
+ }
+
+ if ((ntext = getText("Lab:Rooms/Date")) == NULL)
+ return;
+
+ flowText(BigMsgFont, 0, 0, 0, false, true, false, true, VGAScaleX(57), VGAScaleY(77) + SVGACord(2), VGAScaleX(262), VGAScaleY(91), ntext);
+
+ BigMsgFont = &bmfont;
+
+ if (!getFont("P:News32.fon", BigMsgFont)) {
+ BigMsgFont = NULL;
+ return;
+ }
+
+ if ((ntext = getText("Lab:Rooms/Headline")) == NULL)
+ return;
+
+ FileLen = strlen(ntext) - 1;
+ CharsPrinted = flowText(BigMsgFont, -8, 0, 0, false, true, false, true, VGAScaleX(57), VGAScaleY(86) - SVGACord(2), VGAScaleX(262), VGAScaleY(118), ntext);
+
+ if (CharsPrinted < FileLen) {
+ y = 130 - SVGACord(5);
+ flowText(BigMsgFont, -8 - SVGACord(1), 0, 0, false, true, false, true, VGAScaleX(57), VGAScaleY(86) - SVGACord(2), VGAScaleX(262), VGAScaleY(132), ntext);
+ } else
+ y = 115 - SVGACord(5);
+
+ BigMsgFont = &bmfont;
+
+ if (!getFont("P:Note.fon", BigMsgFont)) {
+ BigMsgFont = NULL;
+ return;
+ }
+
+ if ((ntext = getText("Lab:Rooms/Col1")) == NULL)
+ return;
+
+ CharsPrinted = flowText(BigMsgFont, -4, 0, 0, false, false, false, true, VGAScaleX(45), VGAScaleY(y), VGAScaleX(158), VGAScaleY(148), ntext);
+
+ if ((ntext = getText("Lab:Rooms/Col2")) == NULL)
+ return;
+
+ CharsPrinted = flowText(BigMsgFont, -4, 0, 0, false, false, false, true, VGAScaleX(162), VGAScaleY(y), VGAScaleX(275), VGAScaleY(148), ntext);
+
+ VGASetPal(diffcmap, 256);
+ freeAllStolenMem();
+}
+
+
+
+
+/*---------------------------------------------------------------------------*/
+/*---------------------------- The Journal stuff ----------------------------*/
+/*---------------------------------------------------------------------------*/
+
+
+#define BRIDGE0 148
+#define BRIDGE1 104
+#define DIRTY 175
+#define NONEWS 135
+#define NOCLEAN 152
+
+
+static char *journaltext, *journaltexttitle;
+static uint16 JPage = 0;
+
+static bool lastpage = false;
+
+static struct Image *JCancel, *JCancelAlt, *JLeft, *JLeftAlt, *JRight, *JRightAlt, JBackImage, ScreenImage;
+
+static uint16 JGadX[3] = {80, 144, 194}, JGadY[3] = {162, 164, 162};
+static struct Gadget ForwardG, CancelG, BackG;
+
+
+
+
+/*****************************************************************************/
+/* Loads in the data for the journal. */
+/*****************************************************************************/
+static bool loadJournalData(LargeSet Conditions) {
+ byte **buffer;
+ char filename[20];
+ struct Gadget *TopGadget = &BackG;
+ uint16 counter;
+ bool bridge, dirty, news, clean;
+
+ BigMsgFont = &bmfont;
+
+ if (!getFont("P:Journal.fon", BigMsgFont)) {
+ BigMsgFont = NULL;
+ return false;
+ }
+
+ g_music->checkMusic();
+
+ strcpy(filename, "Lab:Rooms/j0");
+ bridge = In(Conditions, BRIDGE0) || In(Conditions, BRIDGE1);
+ dirty = In(Conditions, DIRTY);
+ news = !In(Conditions, NONEWS);
+ clean = !In(Conditions, NOCLEAN);
+
+ if (bridge && clean && news)
+ filename[11] = '8';
+ else if (clean && news)
+ filename[11] = '9';
+ else if (bridge && clean)
+ filename[11] = '6';
+ else if (clean)
+ filename[11] = '7';
+ else if (bridge && dirty && news)
+ filename[11] = '4';
+ else if (dirty && news)
+ filename[11] = '5';
+ else if (bridge && dirty)
+ filename[11] = '2';
+ else if (dirty)
+ filename[11] = '3';
+ else if (bridge)
+ filename[11] = '1';
+
+ if ((journaltext = getText(filename)) == NULL)
+ return false;
+
+ if ((journaltexttitle = getText("Lab:Rooms/jt")) == NULL)
+ return false;
+
+ buffer = g_music->newOpen("P:JImage");
+
+ if (!buffer)
+ return false;
+
+ readImage(buffer, &JLeft);
+ readImage(buffer, &JLeftAlt);
+ readImage(buffer, &JRight);
+ readImage(buffer, &JRightAlt);
+ readImage(buffer, &JCancel);
+ readImage(buffer, &JCancelAlt);
+
+ BackG.Im = JLeft;
+ BackG.ImAlt = JLeftAlt;
+#if !defined(DOSCODE)
+ BackG.KeyEquiv = VKEY_LTARROW;
+#endif
+ ForwardG.Im = JRight;
+ ForwardG.ImAlt = JRightAlt;
+#if !defined(DOSCODE)
+ ForwardG.KeyEquiv = VKEY_RTARROW;
+#endif
+ CancelG.Im = JCancel;
+ CancelG.ImAlt = JCancelAlt;
+
+ counter = 0;
+
+ while (TopGadget) {
+ TopGadget->x = VGAScaleX(JGadX[counter]);
+
+ if (counter == 1)
+ TopGadget->y = VGAScaleY(JGadY[counter]) + SVGACord(1);
+ else
+ TopGadget->y = VGAScaleY(JGadY[counter]) - SVGACord(1);
+
+ TopGadget->GadgetID = counter;
+ TopGadget = TopGadget->NextGadget;
+ counter++;
+ }
+
+ return true;
+}
+
+
+
+/*****************************************************************************/
+/* Draws the text to the back journal screen to the appropriate Page number */
+/*****************************************************************************/
+static void drawJournalText(void) {
+ uint16 DrawingToPage = 1;
+ int32 CharsDrawn = 0L;
+ char *CurText = journaltext;
+
+ while (DrawingToPage < JPage) {
+ g_music->newCheckMusic();
+ CurText = (char *)(journaltext + CharsDrawn);
+ CharsDrawn += flowText(BigMsgFont, -2, 2, 0, false, false, false, false, VGAScaleX(52), VGAScaleY(32), VGAScaleX(152), VGAScaleY(148), CurText);
+
+ lastpage = (*CurText == 0);
+
+ if (lastpage)
+ JPage = (DrawingToPage / 2) * 2;
+ else
+ DrawingToPage++;
+ }
+
+ if (JPage <= 1) {
+ CurText = journaltexttitle;
+ flowTextToMem(&JBackImage, BigMsgFont, -2, 2, 0, false, true, true, true, VGAScaleX(52), VGAScaleY(32), VGAScaleX(152), VGAScaleY(148), CurText);
+ } else {
+ CurText = (char *)(journaltext + CharsDrawn);
+ CharsDrawn += flowTextToMem(&JBackImage, BigMsgFont, -2, 2, 0, false, false, false, true, VGAScaleX(52), VGAScaleY(32), VGAScaleX(152), VGAScaleY(148), CurText);
+ }
+
+ g_music->checkMusic();
+ CurText = (char *)(journaltext + CharsDrawn);
+ lastpage = (*CurText == 0);
+ flowTextToMem(&JBackImage, BigMsgFont, -2, 2, 0, false, false, false, true, VGAScaleX(171), VGAScaleY(32), VGAScaleX(271), VGAScaleY(148), CurText);
+
+ CurText = (char *)(journaltext + CharsDrawn);
+ lastpage = lastpage || (*CurText == 0);
+}
+
+
+
+
+/*****************************************************************************/
+/* Does the turn page wipe. */
+/*****************************************************************************/
+static void turnPage(bool FromLeft) {
+ uint16 counter;
+
+ if (FromLeft) {
+ for (counter = 0; counter < VGAScreenWidth; counter += 8) {
+ g_music->updateMusic();
+ waitTOF();
+#if !defined(DOSCODE)
+ ScreenImage.ImageData = getVGABaseAddr();
+#endif
+ bltBitMap(&JBackImage, counter, 0, &ScreenImage, counter, 0, 8, VGAScreenHeight);
+ }
+ } else {
+ for (counter = (VGAScreenWidth - 8); counter > 0; counter -= 8) {
+ g_music->updateMusic();
+ waitTOF();
+#if !defined(DOSCODE)
+ ScreenImage.ImageData = getVGABaseAddr();
+#endif
+ bltBitMap(&JBackImage, counter, 0, &ScreenImage, counter, 0, 8, VGAScreenHeight);
+ }
+ }
+}
+
+
+
+static bool GotBackImage = false;
+
+/*****************************************************************************/
+/* Draws the journal from page x. */
+/*****************************************************************************/
+static void drawJournal(uint16 wipenum, bool needFade) {
+ mouseHide();
+
+ g_music->checkMusic();
+
+ if (!GotBackImage)
+ JBackImage.ImageData = loadBackPict("P:Journal.pic", true);
+
+ drawJournalText();
+
+#if !defined(DOSCODE)
+ ScreenImage.ImageData = getVGABaseAddr();
+#endif
+
+ if (wipenum == 0)
+ bltBitMap(&JBackImage, 0, 0, &ScreenImage, 0, 0, VGAScreenWidth, VGAScreenHeight);
+ else
+ turnPage((bool)(wipenum == 1));
+
+ if (JPage == 0)
+ ghoastGadget(&BackG, 15);
+ else
+ unGhoastGadget(&BackG);
+
+ if (lastpage)
+ ghoastGadget(&ForwardG, 15);
+ else
+ unGhoastGadget(&ForwardG);
+
+#if !defined(DOSCODE)
+ ungetVGABaseAddr();
+#endif
+
+
+ if (needFade)
+ fade(true, 0);
+
+ nopalchange = true;
+ JBackImage.ImageData = readPictToMem("P:Journal.pic", VGAScreenWidth, VGAScreenHeight);
+ GotBackImage = true;
+
+ eatMessages();
+ mouseShow();
+
+ nopalchange = false;
+}
+
+
+
+
+/*****************************************************************************/
+/* Processes user input. */
+/*****************************************************************************/
+static void processJournal() {
+ struct IntuiMessage *Msg;
+ uint32 Class;
+ uint16 Qualifier, GadID;
+
+ while (1) {
+ g_music->checkMusic(); /* Make sure we check the music at least after every message */
+ Msg = (struct IntuiMessage *) getMsg();
+
+ if (Msg == NULL) {
+ g_music->newCheckMusic();
+ } else {
+ Class = Msg->Class;
+ Qualifier = Msg->Qualifier;
+ GadID = Msg->Code;
+
+ replyMsg((void *) Msg);
+
+ if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
+ ((Class == RAWKEY) && (GadID == 27)))
+ return;
+
+ else if (Class == GADGETUP) {
+ if (GadID == 0) {
+ if (JPage >= 2) {
+ JPage -= 2;
+ drawJournal(1, false);
+ }
+ } else if (GadID == 1) {
+ return;
+ } else if (GadID == 2) {
+ if (!lastpage) {
+ JPage += 2;
+ drawJournal(2, false);
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Cleans up behind all memory allocations. */
+/*****************************************************************************/
+static void journalCleanUp(void) {
+ freeAllStolenMem();
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Does the journal processing. */
+/*****************************************************************************/
+void doJournal(LargeSet Conditions) {
+ resetBuffer();
+ blackAllScreen();
+
+ lastpage = false;
+ GotBackImage = false;
+
+ JBackImage.Width = VGAScreenWidth;
+ JBackImage.Height = VGAScreenHeight;
+ JBackImage.ImageData = NULL;
+
+ BackG.NextGadget = &CancelG;
+ CancelG.NextGadget = &ForwardG;
+
+ ScreenImage = JBackImage;
+ ScreenImage.ImageData = getVGABaseAddr();
+
+ g_music->checkMusic();
+ loadJournalData(Conditions);
+
+ drawJournal(0, true);
+
+ attachGadgetList(&BackG);
+ mouseShow();
+ processJournal();
+ attachGadgetList(NULL);
+ fade(false, 0);
+ mouseHide();
+
+#if !defined(DOSCODE)
+ ScreenImage.ImageData = getVGABaseAddr();
+#endif
+
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, VGAScreenHeight - 1);
+ blackScreen();
+
+ journalCleanUp();
+
+#if !defined(DOSCODE)
+ ungetVGABaseAddr();
+#endif
+}
+
+
+
+/*---------------------------------------------------------------------------*/
+/*------------------------- The Save/Restore stuff --------------------------*/
+/*---------------------------------------------------------------------------*/
+
+
+struct Image *Arrow1, *NoArrow1, *DriveButton;
+
+
+extern InventoryData *Inventory;
+extern uint16 RoomNum, Direction;
+extern LargeSet Conditions, RoomsFound;
+
+
+
+extern char *SAVETEXT, *LOADTEXT, *BOOKMARKTEXT, *PERSONALTEXT, *DISKTEXT, *SAVEBOOK, *RESTOREBOOK, *SAVEFLASH, *RESTOREFLASH, *SAVEDISK, *RESTOREDISK, *SELECTDISK, *NODISKINDRIVE, *WRITEPROTECTED, *FORMATFLOPPY, *FORMATTING;
+
+static uint16 device;
+
+#define MAXDEVNAMES 5
+
+static char DriveName[5] [MAXDEVNAMES];
+
+
+
+
+
+
+/*----- Gets the devices -----*/
+
+/*****************************************************************************/
+/* Finds all the disk drives, puts them in an array of strings, sorts them, */
+/* and returned the number of drives that it found. */
+/*****************************************************************************/
+uint16 doDisks(void) {
+#if defined(DOSCODE)
+ uint16 many = 0, counter = 2;
+ union REGS regs;
+ char str[5];
+
+ if (manydisks)
+ return manydisks;
+
+ while ((counter < 7) && (many < MAXDEVNAMES)) {
+ memset(&regs, 0, sizeof(regs));
+ /*
+ regs.h.ah = 0x32;
+ regs.h.dl = counter+1;
+ int386(0x21, &regs, &regs);
+ if (regs.h.al == 0)
+ {
+ */
+ regs.h.ah = 0x36;
+ regs.h.dl = counter + 1;
+ int386(0x21, &regs, &regs);
+
+ if (regs.w.ax != 0xFFFF) {
+ str[0] = counter + 'A';
+ str[1] = ':';
+ str[2] = '\\';
+ str[3] = 0;
+ strcpy(DriveName[many], str);
+ many++;
+ }
+
+ counter++;
+ }
+
+ return many;
+#elif defined(WIN32)
+ extern void winGetDriveLetters(char cdLetters[], int size);
+ char letters[28];
+ char str[5];
+ uint16 many = 0, counter = 2;
+
+ if (manydisks)
+ return manydisks;
+
+ winGetDriveLetters(letters, 28);
+
+ while ((counter < 7) && (many < MAXDEVNAMES) && letters[many] != 0) {
+ str[0] = letters[many];
+ str[1] = ':';
+ str[2] = '\\';
+ str[3] = 0;
+ strcpy(DriveName[many], str);
+ many++;
+ counter++;
+ }
+
+ return many;
+#else
+ // !!!!goofy test code
+ char str[5];
+ str[0] = 'C';
+ str[1] = ':';
+ str[2] = '\\';
+ str[3] = 0;
+ strcpy(DriveName[0], str);
+ return 1;
+#endif
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Does the user interface to save or restore a game position */
+/*****************************************************************************/
+#if defined(MODERNGAMESAVE)
+
+extern const byte ThePalMap[];
+
+void getRoomMessage(int MyRoomNum, int MyDirection, char *msg);
+
+#define QUARTERNUM 30
+
+#define NEXTEMPTYSLOTTEXT "Next Empty Slot"
+
+extern char g_SaveGamePath[512];
+extern char g_PathSeperator[4];
+
+struct SaveGameInfo g_SaveGameInfo[MAX_SAVED_GAMES];
+int g_TotalSavedGames;
+char g_CommonPalette[3 * 256];
+int g_LastSaveGameNumber = 0;
+int g_CurSaveGameNumber = 0;
+int g_CurSaveSet = 0;
+int g_PendingNewSave = 0;
+
+enum UI_Ident {
+ ID_SAVE, ID_LOAD, ID_NEWSLOT, ID_1_TO_5, ID_6_TO_10, ID_11_TO_15, ID_SLOT_A, ID_SLOT_B, ID_SLOT_C, ID_SLOT_D, ID_SLOT_E, ID_CANCEL, ID_LAST
+};
+
+struct ModernUI {
+ int id;
+ int x, y, w, h;
+};
+
+struct ModernUI theUI[ID_LAST] = {
+ { ID_LOAD, 491, 182, 128, 54 }, { ID_SAVE, 491, 255, 128, 54 }, { ID_NEWSLOT, 491, 328, 128, 54 }, { ID_1_TO_5, 27, 40, 146, 25 }, { ID_6_TO_10, 175, 40, 146, 25 }, { ID_11_TO_15, 323, 40, 146, 25 }, { ID_SLOT_A, 27, 67, 442, 72 }, { ID_SLOT_B, 27, 142, 442, 72 }, { ID_SLOT_C, 27, 217, 442, 72 }, { ID_SLOT_D, 27, 292, 442, 72 }, { ID_SLOT_E, 27, 367, 442, 72 }, { ID_CANCEL, 531, 405, 52, 52 }
+};
+
+enum {
+ SG_BLACK = 1, SG_TAN = 14, SG_DKTAN = 38, SG_WHITE = 105, SG_YELLOW = 118
+};
+
+/*****************************************************************************/
+/* Draw display */
+/*****************************************************************************/
+static void flowTextBold(void *font, /* the TextAttr pointer */
+ uint16 spacing, /* How much vertical spacing between the lines */
+ uint16 pencolor, /* pen number to use for text */
+ uint16 backpen, /* the background color */
+ bool outline, /* Whether to outline in background color */
+ bool centerh, /* Whether to center the text horizontally */
+ bool centerv, /* Whether to center the text vertically */
+ bool output, /* Whether to output any text */
+ uint16 x1, /* Cords */
+ uint16 y1, uint16 x2, uint16 y2, const char *text) { /* The text itself */
+
+ if (outline) {
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 - 1, y1, x2 - 1, y2, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 - 1, y1 - 1, x2 - 1, y2 - 1, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1, y1 + 2, x2, y2 + 2, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 - 1, y1 + 2, x2 - 1, y2 + 2, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 + 2, y1, x2 + 2, y2, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 + 2, y1 + 2, x2 + 2, y2 + 2, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1, y1 - 1, x2, y2 - 1, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 + 2, y1 - 1, x2 + 2, y2 - 1, text);
+ }
+
+ flowText(font, spacing, pencolor, 0, false, centerh, centerv, output, x1, y1, x2, y2, text);
+ flowText(font, spacing, pencolor, 0, false, centerh, centerv, output, x1 + 1, y1, x2 + 1, y2, text);
+ flowText(font, spacing, pencolor, 0, false, centerh, centerv, output, x1, y1 + 1, x2, y2 + 1, text);
+ flowText(font, spacing, pencolor, 0, false, centerh, centerv, output, x1 + 1, y1 + 1, x2 + 1, y2 + 1, text);
+}
+
+/*****************************************************************************/
+/* Draw display */
+/*****************************************************************************/
+static void flowTextShadow(void *font, /* the TextAttr pointer */
+ uint16 spacing, /* How much vertical spacing between the lines */
+ uint16 pencolor, /* pen number to use for text */
+ uint16 backpen, /* the background color */
+ bool outline, /* Whether to outline in background color */
+ bool centerh, /* Whether to center the text horizontally */
+ bool centerv, /* Whether to center the text vertically */
+ bool output, /* Whether to output any text */
+ uint16 x1, /* Cords */
+ uint16 y1, uint16 x2, uint16 y2, char *text) { /* The text itself */
+
+ if (outline) {
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 - 1, y1 - 1, x2 - 1, y2 - 1, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 - 1, y1 + 1, x2 - 1, y2 + 1, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 + 1, y1 + 1, x2 + 1, y2 + 1, text);
+ flowText(font, spacing, backpen, 0, false, centerh, centerv, output, x1 + 1, y1 - 1, x2 + 1, y2 - 1, text);
+ }
+
+ flowText(font, spacing, pencolor, 0, false, centerh, centerv, output, x1, y1, x2, y2, text);
+}
+
+static void drawSaveLoad() {
+ int i, j;
+
+ flowTextBold(MsgFont, 0, g_CurSaveGameNumber < g_TotalSavedGames ? SG_YELLOW : SG_DKTAN, SG_BLACK, true, true, true, true, 491 + 3, 182, 619 + 3, 236, LOADTEXT);
+ flowTextBold(MsgFont, 0, g_TotalSavedGames + g_PendingNewSave > 0 ? SG_YELLOW : SG_DKTAN, SG_BLACK, true, true, true, true, 491 + 3, 255, 619 + 3, 309, SAVETEXT);
+ flowTextBold(MsgFont, 0, g_PendingNewSave ? SG_DKTAN : SG_YELLOW, SG_BLACK, true, true, true, true, 491 + 3, 328, 619 + 3, 382, NEXTEMPTYSLOTTEXT);
+
+ flowTextBold(MsgFont, 0, (g_CurSaveSet == 0 ? SG_YELLOW : SG_WHITE), SG_BLACK, true, true, true, true, 27 + 3, 40, 175 + 3, 65, "Saves 1-5");
+ flowTextBold(MsgFont, 0, (g_CurSaveSet == 1 ? SG_YELLOW : SG_WHITE), SG_BLACK, true, true, true, true, 175 + 3, 40, 321 + 3, 65, "Saves 6-10");
+ flowTextBold(MsgFont, 0, (g_CurSaveSet == 2 ? SG_YELLOW : SG_WHITE), SG_BLACK, true, true, true, true, 323 + 3, 40, 469 + 3, 65, "Saves 11-15");
+
+ for (i = 0, j = 5 * g_CurSaveSet; i < 5; i++, j++) {
+ uint16 hue, y;
+ char num_text[4];
+ struct Image thumbnail, screen;
+
+ if (j < g_TotalSavedGames + g_PendingNewSave) {
+ char msg[256];
+
+ getRoomMessage(g_SaveGameInfo[j].RoomNumber, g_SaveGameInfo[j].Direction, msg);
+
+ hue = (j == g_CurSaveGameNumber ? SG_YELLOW : SG_WHITE);
+ y = 67 + 2 + i * 75;
+ flowText(MsgFont, 0, hue, 0, false, false, false, true, 202 + 2, y, 469 - 2, y + 48, msg);
+ y += 46;
+ flowText(MsgFont, 0, hue, 0, false, false, false, true, 202 + 2, y, 469 - 2, y + 24, g_SaveGameInfo[j].SaveGameDate);
+
+ // blast image
+ thumbnail.Width = 128;
+ thumbnail.Height = 72;
+ thumbnail.ImageData = g_SaveGameInfo[j].SaveGameImage;
+ screen.Width = 640;
+ screen.Height = 480;
+ screen.ImageData = getVGABaseAddr();
+ bltBitMap(&thumbnail, 0, 0, &screen, 72, 67 + i * 75, 128, 72);
+ ungetVGABaseAddr();
+
+ hue = (j == g_CurSaveGameNumber ? SG_YELLOW : SG_WHITE);
+ } else {
+ y = 67 + 2 + i * 75;
+ flowText(MsgFont, 0, SG_TAN, 0, false, true, true, true, 202 + 2, y, 469 - 2, y + 70, "[Empty Slot]");
+
+ hue = SG_DKTAN;
+ }
+
+ y = 67 + i * 75;
+ sprintf(num_text, "%d", j + 1);
+ flowTextShadow(BigMsgFont, 0, hue, SG_BLACK, true, true, true, true, 27 + 4, y, 72 + 4, y + 72, num_text);
+ }
+
+ // Add ".1" to version number
+ setAPen(SG_WHITE);
+ rectFill(271, 454, 271, 454);
+ rectFill(275, 449, 275, 454);
+ rectFill(274, 450, 274, 450);
+ rectFill(274, 454, 276, 454);
+
+ g_system->updateScreen();
+}
+
+static void makeThumbnail(struct SaveGameInfo *info) {
+ char *pictName;
+ CloseDataPtr CPtr = NULL;
+ byte *BitMapMem;
+ int x, y, u, v;
+
+ // load pict
+ pictName = getPictName(&CPtr);
+ nopalchange = true;
+ BitMapMem = readPictToMem(pictName, VGAScreenWidth, VGAScreenHeight);
+ nopalchange = false;
+
+ for (y = 0; y < 72; y++) {
+ for (x = 0; x < 128; x++) {
+ unsigned int r = 0, g = 0, b = 0;
+
+ for (v = 5 * y; v < 5 * y + 5; v++) {
+ for (u = 5 * x; u < 5 * x + 5; u++) {
+ byte n = (byte)BitMapMem[u + v * VGAScreenWidth];
+ // 6-bit color (VGA)
+ r += (unsigned int)diffcmap[3 * n + 0];
+ g += (unsigned int)diffcmap[3 * n + 1];
+ b += (unsigned int)diffcmap[3 * n + 2];
+ }
+ }
+
+ r = (r / 25) >> 1;
+ g = (g / 25) >> 1;
+ b = (b / 25) >> 1;
+ warning("STUB: makeThumbnail");
+ info->SaveGameImage[x + 128 * y] = ThePalMap[(r << 10) | (g << 5) | b];
+ }
+ }
+}
+
+static void addSaveSlot() {
+ struct SaveGameInfo *info;
+
+ if (g_PendingNewSave || g_TotalSavedGames == MAX_SAVED_GAMES)
+ return;
+
+ g_PendingNewSave = 1;
+ g_CurSaveGameNumber = g_TotalSavedGames;
+ g_CurSaveSet = g_CurSaveGameNumber / 5;
+
+ // set-up saved game
+ info = &g_SaveGameInfo[g_CurSaveGameNumber];
+ info->RoomNumber = RoomNum;
+ info->Direction = Direction;
+
+ // not really a date yet
+ strcpy(info->SaveGameDate, "Click SAVE GAME to Confirm");
+
+ info->SaveGameImage = (byte *)malloc(SAVED_IMAGE_SIZE);
+ makeThumbnail(info);
+
+ mouseHide();
+ warning("STUB: addSaveSlot()");
+ //SDL_IgnoreUpdateDisplay(1);
+ loadBackPict("P:ModSave", false);
+ //SDL_IgnoreUpdateDisplay(0);
+ drawSaveLoad();
+ mouseShow();
+}
+
+static void selectSave(int n) {
+ if (g_CurSaveGameNumber == n || n >= g_TotalSavedGames + g_PendingNewSave)
+ return;
+
+ g_CurSaveGameNumber = n;
+
+ mouseHide();
+ warning("STUB: selectSave()");
+ //SDL_IgnoreUpdateDisplay(1);
+ loadBackPict("P:ModSave", false);
+ //SDL_IgnoreUpdateDisplay(0);
+ drawSaveLoad();
+ mouseShow();
+}
+
+static void selectSaveSet(int n) {
+ if (g_CurSaveSet != n) {
+ g_CurSaveSet = n;
+
+ mouseHide();
+ warning("STUB: selectSaveSet");
+ //SDL_IgnoreUpdateDisplay(1);
+ loadBackPict("P:ModSave", false);
+ //SDL_IgnoreUpdateDisplay(0);
+ drawSaveLoad();
+ mouseShow();
+ }
+}
+
+/*****************************************************************************/
+/* Do modern save. */
+/*****************************************************************************/
+static bool doSaveGame() {
+ bool isok;
+ char DrivePath[260];
+
+ if (g_CurSaveGameNumber != g_TotalSavedGames) {
+ makeThumbnail(&g_SaveGameInfo[g_CurSaveGameNumber]);
+ } else {
+ // set time of save for new saved game
+ //struct tm *create_date;
+ //time_t ticks;
+
+ warning("STUB: doSaveGame");
+ //ticks = time(NULL);
+ //create_date = localtime(&ticks);
+ //strcpy(g_SaveGameInfo[g_CurSaveGameNumber].SaveGameDate, asctime(create_date));
+ }
+
+ memcpy(g_SaveGameImage, g_SaveGameInfo[g_CurSaveGameNumber].SaveGameImage, SAVED_IMAGE_SIZE);
+
+ sprintf(DrivePath, "%s%s%d", g_SaveGamePath, g_PathSeperator, g_CurSaveGameNumber);
+
+ isok = saveFloppy(DrivePath, RoomNum, Direction, Inventory[QUARTERNUM].Many, Conditions, RoomsFound, g_CurSaveGameNumber, device);
+ g_music->resetMusic();
+
+ if (isok)
+ g_LastSaveGameNumber = g_CurSaveGameNumber;
+
+ return isok;
+}
+
+/*****************************************************************************/
+/* Do modern load. */
+/*****************************************************************************/
+static bool doLoadGame() {
+ bool isok;
+ char drivePath[260];
+
+ snprintf(drivePath, 260, "%s%s%d", g_SaveGamePath, g_PathSeperator, g_CurSaveGameNumber);
+
+ isok = readFloppy(drivePath, &RoomNum, &Direction, &(Inventory[QUARTERNUM].Many), Conditions, RoomsFound, g_CurSaveGameNumber, device);
+ g_music->resetMusic();
+
+ if (isok)
+ g_LastSaveGameNumber = g_CurSaveGameNumber;
+
+ return isok;
+}
+
+/*****************************************************************************/
+/* Processes user input. */
+/*****************************************************************************/
+static bool processSaveLoad() {
+ struct IntuiMessage *Msg;
+
+ uint32 Class;
+ uint16 Qualifier, MouseX, MouseY, Code;
+ int i;
+
+ drawSaveLoad();
+
+ while (1) {
+ g_music->checkMusic(); /* Make sure we check the music at least after every message */
+ Msg = getMsg();
+
+ if (Msg == NULL) {
+ g_music->newCheckMusic();
+ } else {
+ Class = Msg->Class;
+ Qualifier = Msg->Qualifier;
+ MouseX = Msg->MouseX;
+ MouseY = Msg->MouseY;
+ Code = Msg->Code;
+
+ replyMsg(Msg);
+
+ if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
+ ((Class == RAWKEY) && (Code == 27)))
+ return -1;
+
+ if (Class == RAWKEY) {
+ if (Code == 'l' || Code == 'L') {
+ if (g_CurSaveGameNumber < g_TotalSavedGames)
+ return doLoadGame();
+ } else if (Code == 's' || Code == 'S') {
+ if (g_TotalSavedGames + g_PendingNewSave > 0)
+ return doSaveGame();
+ } else if (Code == 'n' || Code == 'N') {
+ addSaveSlot();
+ } else if (Code == VKEY_LTARROW) {
+ i = g_CurSaveSet - 1;
+
+ if (i < 0) i = 2;
+
+ selectSaveSet(i);
+ } else if (Code == VKEY_RTARROW) {
+ i = g_CurSaveSet + 1;
+
+ if (i > 2) i = 0;
+
+ selectSaveSet(i);
+ } else if (Code == VKEY_UPARROW) {
+ if (g_TotalSavedGames + g_PendingNewSave > 0) {
+ i = g_CurSaveGameNumber - 1;
+
+ if (i < 0)
+ i = g_TotalSavedGames + g_PendingNewSave - 1;
+
+ if (i / 5 != g_CurSaveSet)
+ selectSaveSet(i / 5);
+
+ selectSave(i);
+ }
+ } else if (Code == VKEY_DNARROW) {
+ if (g_TotalSavedGames + g_PendingNewSave > 0) {
+ i = g_CurSaveGameNumber + 1;
+
+ if (i >= g_TotalSavedGames + g_PendingNewSave)
+ i = 0;
+
+ if (i / 5 != g_CurSaveSet)
+ selectSaveSet(i / 5);
+
+ selectSave(i);
+ }
+ }
+ } else if ((Class == MOUSEBUTTONS) && (IEQUALIFIER_LEFTBUTTON & Qualifier)) {
+ for (i = 0; i < ID_LAST; i++) {
+ if (MouseX >= theUI[i].x && MouseY >= theUI[i].y &&
+ MouseX < theUI[i].x + theUI[i].w && MouseY < theUI[i].y + theUI[i].h) {
+ switch (theUI[i].id) {
+ case ID_SAVE:
+ if (g_TotalSavedGames + g_PendingNewSave > 0)
+ return doSaveGame();
+
+ break;
+
+ case ID_LOAD:
+ if (g_CurSaveGameNumber < g_TotalSavedGames)
+ return doLoadGame();
+
+ break;
+
+ case ID_NEWSLOT:
+ addSaveSlot();
+ break;
+
+ case ID_1_TO_5:
+ case ID_6_TO_10:
+ case ID_11_TO_15:
+ selectSaveSet(theUI[i].id - ID_1_TO_5);
+ break;
+
+ case ID_SLOT_A:
+ case ID_SLOT_B:
+ case ID_SLOT_C:
+ case ID_SLOT_D:
+ case ID_SLOT_E:
+ selectSave(5 * g_CurSaveSet + theUI[i].id - ID_SLOT_A);
+ break;
+
+ case ID_CANCEL:
+ return -1;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool saveRestoreGame(void) {
+ byte **buffer;
+ bool isok = true;
+
+ blackAllScreen();
+
+ BigMsgFont = &bmfont;
+
+ if (!getFont("P:Map.fon", BigMsgFont)) {
+ BigMsgFont = NULL;
+ return false;
+ }
+
+ buffer = g_music->newOpen("P:ModSave");
+
+ if (!buffer) {
+ freeAllStolenMem();
+ return false;
+ }
+
+ g_TotalSavedGames = getSaveGameList(g_SaveGameInfo, MAX_SAVED_GAMES);
+ g_CurSaveGameNumber = g_LastSaveGameNumber;
+ g_CurSaveSet = g_CurSaveGameNumber / 5;
+ g_PendingNewSave = 0;
+
+ loadBackPict("P:ModSave", false);
+
+ mouseShow();
+
+ VGASetPal(diffcmap, 256);
+ memcpy(g_CommonPalette, diffcmap, 3 * 256);
+
+ isok = processSaveLoad();
+ eatMessages();
+
+ mouseHide();
+ memset(diffcmap, 0, 3 * 256);
+ VGASetPal(diffcmap, 256);
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, VGAScreenHeight - 1);
+ blackScreen();
+ g_system->updateScreen();
+
+ journalCleanUp();
+
+ freeAllStolenMem();
+
+ freeSaveGameList(g_SaveGameInfo, g_TotalSavedGames);
+
+ return isok;
+}
+#else
+
+static uint16 manydisks = 0;
+
+static uint16 issave, ghoast, arrow, ManyDrives, DriveInitX, DriveNum = -1, FileNum = -1;
+
+/*****************************************************************************/
+/* Draws the number arrows. */
+/*****************************************************************************/
+static void doNumArrows(void) {
+ uint16 counterx, countery, curnum, cordx[3], cordy[3];
+
+ cordx[0] = VGAScaleX(53) + SVGACord(3);
+ cordx[1] = VGAScaleX(126) + SVGACord(1);
+ cordx[2] = VGAScaleX(197) + SVGACord(3);
+
+ cordy[0] = VGAScaleY(58) + SVGACord(2);
+ cordy[1] = VGAScaleY(86) + SVGACord(3);
+ cordy[2] = VGAScaleY(114) + SVGACord(3);
+
+ mouseHide();
+
+ for (countery = 0; countery < 3; countery++) {
+ for (counterx = 0; counterx < 3; counterx++) {
+ curnum = countery + counterx * 3;
+
+ if INBIT(arrow, curnum)
+ drawImage(Arrow1, cordx[counterx], cordy[countery]);
+ else
+ drawImage(NoArrow1, cordx[counterx], (int32) cordy[countery]);
+
+ if INBIT(ghoast, curnum)
+ ghoastRect(0, cordx[counterx], cordy[countery], cordx[counterx] + VGAScaleX(69), cordy[countery] + NoArrow1->Height);
+ }
+ }
+
+ mouseShow();
+}
+
+/*****************************************************************************/
+/* Does the drive buttons for the final save/restore screen. */
+/*****************************************************************************/
+static void doDriveButtons(void) {
+ uint16 curx, counter;
+
+ if (ManyDrives > 5)
+ ManyDrives = 5;
+
+ DriveInitX = (VGAScreenWidth / 2) - ((ManyDrives * DriveButton->Width) / 2);
+ curx = DriveInitX;
+
+ mouseHide();
+
+ for (counter = 0; counter < ManyDrives; counter++) {
+ drawImage(DriveButton, curx, VGAScaleY(153));
+
+ flowText(BigMsgFont, 0, 1, 0, false, true, true, true, curx + VGAScaleX(5), VGAScaleY(158), curx + DriveButton->Width - VGAScaleX(5), VGAScaleY(148) + DriveButton->Height, DriveName[counter]);
+
+ curx += DriveButton->Width;
+ }
+
+ mouseShow();
+}
+
+
+static void drawSRMessage(char *rtext) {
+ mouseHide();
+ flowText(BigMsgFont, 0, 1, 10, true, true, true, true, VGAScaleX(22), VGAScaleY(21), VGAScaleX(289), VGAScaleY(48), rtext);
+ mouseShow();
+}
+
+/*****************************************************************************/
+/* Draws the correct message to the message box. */
+/*****************************************************************************/
+static void doSaveRestoreText(void) {
+ char *rtext, text[100];
+
+ if (DriveNum >= ManyDrives) {
+ rtext = SELECTDISK;
+ } else if (issave) {
+ strcpy(text, SAVEDISK);
+ strcat(text, " ");
+ strcat(text, DriveName[DriveNum]);
+ rtext = text;
+ } else {
+ strcpy(text, RESTOREDISK);
+ strcat(text, " ");
+ strcat(text, DriveName[DriveNum]);
+ rtext = text;
+ }
+
+ drawSRMessage(rtext);
+}
+
+static uint16 processSaveRestore(uint16 type);
+
+static char DrivePath[50];
+
+/*****************************************************************************/
+/* Checks for the existence of previous saved game positions on disk. */
+/*****************************************************************************/
+static void floppyCheckFiles(void) {
+ char temp[7], *name, len;
+ int fl;
+ uint16 counter;
+
+ doSaveRestoreText();
+
+ arrow = 0;
+ ghoast = 0;
+
+ strcpy(DrivePath, DriveName[DriveNum]);
+ strcat(DrivePath, "LabSaves");
+
+ warning("STUB: floppyCheckFiles");
+
+#if 0
+#if defined(WIN32)
+ mkdir(DrivePath);
+#else
+ mkdir(DrivePath, 0x644);
+#endif
+ strcat(DrivePath, "\\");
+
+ len = strlen(DrivePath);
+
+ for (counter = 0; counter < 9; counter++) {
+ name = numtostr(temp, counter);
+ strcat(DrivePath, name);
+
+ if ((fl = open(DrivePath, O_RDONLY)) != -1) {
+ close(fl);
+ SETBIT(arrow, counter);
+ } else
+ SETBIT(ghoast, counter);
+
+ DrivePath[len] = 0;
+ }
+#endif
+}
+
+/*****************************************************************************/
+/* Checks for the existence of previously saved game positions. */
+/*****************************************************************************/
+static void checkFiles(void) {
+ ghoast = -1;
+ arrow = 0;
+
+ g_music->fillUpMusic(true);
+
+ /* NYI: check for empty drive */
+ floppyCheckFiles();
+
+ if (issave)
+ ghoast = 0;
+}
+
+/*****************************************************************************/
+/* Processes user input. */
+/*****************************************************************************/
+static uint16 processSaveRestore(uint16 type) {
+ struct IntuiMessage *Msg;
+
+ uint32 Class;
+ uint16 Qualifier, MouseX, MouseY, Code, Temp;
+
+ while (1) {
+ g_music->checkMusic(); /* Make sure we check the music at least after every message */
+ Msg = getMsg();
+
+ if (Msg == NULL) {
+ g_music->newCheckMusic();
+ } else {
+ Class = Msg->Class;
+ Qualifier = Msg->Qualifier;
+ MouseX = Msg->MouseX;
+ MouseY = Msg->MouseY;
+ Code = Msg->Code;
+
+ replyMsg(Msg);
+
+ if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
+ ((Class == RAWKEY) && (Code == 27)))
+ return -1;
+
+ else if ((Class == MOUSEBUTTONS) && (IEQUALIFIER_LEFTBUTTON & Qualifier)) {
+ if (type == 0) { /* The save or restore screen */
+ if ((MouseX >= VGAScaleX(64)) && (MouseX <= VGAScaleX(257))) {
+ if ((MouseY >= VGAScaleY(57)) && (MouseY <= VGAScaleY(92)))
+ return true;
+ else if ((MouseY >= VGAScaleY(108)) && (MouseY <= VGAScaleY(142)))
+ return false;
+ }
+ }
+
+ else if (type == 2) { /* The files screen */
+ if ((MouseY >= VGAScaleY(153)) && (MouseY <= VGAScaleY(180))) { /* the drive buttons */
+ Temp = ((MouseX - DriveInitX) / DriveButton->Width);
+
+ if (Temp < ManyDrives) {
+ DriveNum = Temp;
+
+ fade(false, 0);
+ checkFiles();
+
+ loadBackPict("P:Disk/Nums.pic", false);
+ doNumArrows();
+ doDriveButtons();
+ doSaveRestoreText();
+
+ fade(true, 0);
+ }
+ }
+
+ else if ((MouseX >= VGAScaleX(53)) && (MouseY >= VGAScaleY(58)) &&
+ (MouseX <= VGAScaleX(266)) && (MouseY <= VGAScaleY(142))) {
+ MouseX = (MouseX - VGAScaleX(53)) / VGAScaleX(71);
+ MouseY = (MouseY - VGAScaleY(58)) / VGAScaleY(28);
+
+ Temp = MouseY + (MouseX * 3);
+
+ if (!(INBIT(ghoast, Temp))) {
+
+ SETBIT(arrow, Temp);
+ doNumArrows();
+
+ FileNum = Temp;
+ return FileNum;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Sets up the Save or Restore screen. */
+/*****************************************************************************/
+static uint16 saveOrRestore(void) {
+ uint16 res;
+
+ mouseHide();
+ loadBackPict("P:Disk/Choose.pic", false);
+
+ flowText(BigMsgFont, 0, 1, 4, false, true, true, true, VGAScaleX(74), VGAScaleY(65), VGAScaleX(247), VGAScaleY(84), SAVETEXT);
+ flowText(BigMsgFont, 0, 1, 4, false, true, true, true, VGAScaleX(74), VGAScaleY(116), VGAScaleX(247), VGAScaleY(135), LOADTEXT);
+ mouseShow();
+
+ fade(true, 0);
+ res = processSaveRestore(0);
+ fade(false, 0);
+ eatMessages();
+
+ return res;
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Sets up the final save/restore screen. */
+/*****************************************************************************/
+static uint16 saveRestore(void) {
+ uint16 res;
+
+ loadBackPict("P:Disk/Nums.pic", false);
+
+ if ((DriveNum < ManyDrives)) {
+ checkFiles();
+ } else {
+ ghoast = -1;
+ arrow = 0;
+ }
+
+ doNumArrows();
+ doDriveButtons();
+ doSaveRestoreText();
+ g_music->newCheckMusic();
+
+ eatMessages();
+ fade(true, 0);
+ res = processSaveRestore(2);
+ fade(false, 0);
+
+ return res;
+}
+
+
+#define QUARTERNUM 30
+
+
+bool saveRestoreGame(void) {
+ uint16 filenum;
+ byte **buffer;
+ char temp[10], *name;
+ bool isok = true;
+
+ blackAllScreen();
+
+ ManyDrives = doDisks();
+
+ FadePalette = hipal;
+ memset(&(hipal[0]), 0, 32L);
+
+ BigMsgFont = &bmfont;
+
+ if (!getFont("P:Map.fon", BigMsgFont)) {
+ BigMsgFont = NULL;
+ return false;
+ }
+
+ buffer = g_music->newOpen("P:SaveImage");
+
+ if (!buffer) {
+ freeAllStolenMem();
+ return false;
+ }
+
+ readImage(buffer, &Arrow1);
+ readImage(buffer, &NoArrow1);
+ readImage(buffer, &DriveButton);
+
+ mouseShow();
+
+ if ((issave = saveOrRestore()) != (uint16) - 1) {
+ eatMessages();
+
+ if ((filenum = saveRestore()) != (uint16) - 1) {
+ name = numtostr(temp, filenum);
+ strcat(DrivePath, name);
+
+ eatMessages();
+
+ if (issave)
+ isok = saveFloppy(DrivePath, RoomNum, Direction, Inventory[QUARTERNUM].Many, Conditions, RoomsFound, filenum, device);
+ else {
+ isok = readFloppy(DrivePath, &RoomNum, &Direction, &(Inventory[QUARTERNUM].Many), Conditions, RoomsFound, filenum, device);
+ g_music->resetMusic();
+ }
+ }
+ }
+
+ mouseHide();
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, VGAScreenHeight - 1);
+ blackScreen();
+
+ journalCleanUp();
+
+ freeAllStolenMem();
+
+ return isok;
+}
+
+#endif
+
+
+
+/*---------------------------------------------------------------------------*/
+/*--------------------------- The Monitors stuff ----------------------------*/
+/*---------------------------------------------------------------------------*/
+
+
+extern CloseDataPtr CPtr;
+
+static uint16 monpage;
+static const char *TextFileName;
+
+
+struct Image *MonButton, *AltMonButton, *MonQuit, *AltMonQuit, *MonBack, *AltMonBack, *MonDown, *AltMonDown, *MonUp, *AltMonUp;
+
+
+
+
+/*****************************************************************************/
+/* Makes sure that the buttons are in memory. */
+/*****************************************************************************/
+static void getMonImages(void) {
+ byte **buffer;
+
+ resetBuffer();
+
+ buffer = g_music->newOpen("P:MonImage");
+
+ if (!buffer)
+ return;
+
+ readImage(buffer, &MonButton);
+
+ stealBufMem(sizeOfFile("P:MonImage")); /* Trick: protects the memory where the buttons are so they won't be over-written */
+}
+
+
+static uint16 MonGadHeight = 1;
+
+
+/*****************************************************************************/
+/* Draws the text for the monitor. */
+/*****************************************************************************/
+static void drawMonText(char *text, uint16 x1, uint16 y1, uint16 x2, uint16 y2, bool isinteractive) {
+ uint16 DrawingToPage = 0, yspacing = 0, numlines, fheight, counter;
+ int32 CharsDrawn = 0L;
+ char *CurText = text;
+
+ mouseHide();
+
+ if (*text == '%') {
+ text++;
+ numlines = (*text - '0') * 10;
+ text++;
+ numlines += (*text - '0');
+ text += 2;
+
+ fheight = textHeight(BigMsgFont);
+ x1 = MonButton->Width + VGAScaleX(3);
+ MonGadHeight = MonButton->Height + VGAScaleY(3);
+
+ if (MonGadHeight > fheight)
+ yspacing = MonGadHeight - fheight;
+ else
+ MonGadHeight = fheight;
+
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, y2);
+
+ for (counter = 0; counter < numlines; counter++)
+ drawImage(MonButton, 0, counter * MonGadHeight);
+ } else if (isinteractive) {
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, y2);
+ } else {
+ setAPen(0);
+ rectFill(x1, y1, x2, y2);
+ }
+
+ while (DrawingToPage < monpage) {
+ g_music->newCheckMusic();
+ CurText = (char *)(text + CharsDrawn);
+ CharsDrawn += flowText(BigMsgFont, yspacing, 0, 0, false, false, false, false, x1, y1, x2, y2, CurText);
+ lastpage = (*CurText == 0);
+
+ if (lastpage)
+ monpage = DrawingToPage;
+ else
+ DrawingToPage++;
+ }
+
+ CurText = (char *)(text + CharsDrawn);
+ lastpage = (*CurText == 0);
+ CharsDrawn = flowText(BigMsgFont, yspacing, 2, 0, false, false, false, true, x1, y1, x2, y2, CurText);
+ CurText += CharsDrawn;
+ lastpage = lastpage || (*CurText == 0);
+
+ mouseShow();
+}
+
+/*****************************************************************************/
+/* Processes user input. */
+/*****************************************************************************/
+static void processMonitor(char *ntext, bool isinteractive, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+ struct IntuiMessage *Msg;
+ uint32 Class;
+ uint16 Qualifier, Code, MouseX, MouseY;
+ const char *Test = " ", *StartFileName = TextFileName;
+ CloseDataPtr StartCPtr = CPtr, TestCPtr, LastCPtr[10];
+ uint16 depth = 0;
+
+ LastCPtr[0] = CPtr;
+
+ while (1) {
+ if (isinteractive) {
+ if (CPtr == NULL)
+ CPtr = StartCPtr;
+
+ if (CPtr == StartCPtr)
+ Test = StartFileName;
+ else
+ Test = CPtr->GraphicName;
+
+ if (strcmp(Test, TextFileName)) {
+ monpage = 0;
+ TextFileName = Test;
+
+ ntext = getText(TextFileName);
+ fade(false, 0);
+ drawMonText(ntext, x1, y1, x2, y2, isinteractive);
+ fade(true, 0);
+ }
+ }
+
+ g_music->checkMusic(); /* Make sure we check the music at least after every message */
+ Msg = getMsg();
+
+ if (Msg == NULL) {
+ g_music->newCheckMusic();
+ } else {
+ Class = Msg->Class;
+ Qualifier = Msg->Qualifier;
+ MouseX = Msg->MouseX;
+ MouseY = Msg->MouseY;
+ Code = Msg->Code;
+
+ replyMsg(Msg);
+
+ if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
+ ((Class == RAWKEY) && (Code == 27)))
+ return;
+
+ else if ((Class == MOUSEBUTTONS) && (IEQUALIFIER_LEFTBUTTON & Qualifier)) {
+ if ((MouseY >= VGAScaleY(171)) && (MouseY <= VGAScaleY(200))) {
+ if ((MouseX >= VGAScaleX(259)) && (MouseX <= VGAScaleX(289))) {
+ if (!lastpage) {
+ monpage += 1;
+ drawMonText(ntext, x1, y1, x2, y2, isinteractive);
+ }
+ } else if ((MouseX >= VGAScaleX(0)) && (MouseX <= VGAScaleX(31))) {
+ return;
+ } else if ((MouseX >= VGAScaleX(290)) && (MouseX <= VGAScaleX(320))) {
+ if (monpage >= 1) {
+ monpage -= 1;
+ drawMonText(ntext, x1, y1, x2, y2, isinteractive);
+ }
+ } else if ((MouseX >= VGAScaleX(31)) && (MouseX <= VGAScaleX(59))) {
+ if (isinteractive) {
+ monpage = 0;
+
+ if (depth) {
+ depth--;
+ CPtr = LastCPtr[depth];
+ }
+ } else if (monpage > 0) {
+ monpage = 0;
+ drawMonText(ntext, x1, y1, x2, y2, isinteractive);
+ }
+ }
+ } else if (isinteractive) {
+ TestCPtr = CPtr;
+ MouseY = 64 + (MouseY / MonGadHeight) * 42;
+ MouseX = 101;
+ setCurCloseAbs(MouseX, MouseY, &CPtr);
+
+ if (TestCPtr != CPtr) {
+ LastCPtr[depth] = TestCPtr;
+ depth++;
+ }
+ }
+ }
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Does what's necessary for the monitor. */
+/*****************************************************************************/
+void doMonitor(char *background, char *textfile, bool isinteractive, uint16 x1, uint16 y1, uint16 x2, uint16 y2) {
+ char *ntext;
+
+ x1 = VGAScaleX(x1);
+ x2 = VGAScaleX(x2);
+ y1 = VGAScaleY(y1);
+ y2 = VGAScaleY(y2);
+
+ TextFileName = textfile;
+
+ blackAllScreen();
+
+ readPict("P:Mon/Monitor.1", true);
+ readPict("P:Mon/NWD1", true);
+ readPict("P:Mon/NWD2", true);
+ readPict("P:Mon/NWD3", true);
+ blackAllScreen();
+
+ resetBuffer();
+ monpage = 0;
+ lastpage = false;
+ FadePalette = hipal;
+
+ BigMsgFont = &bmfont;
+
+ if (!getFont("P:Map.font", BigMsgFont)) {
+ freeAllStolenMem();
+ BigMsgFont = NULL;
+ return;
+ }
+
+ getMonImages();
+
+ if ((ntext = getText(textfile)) == NULL) {
+ freeAllStolenMem();
+ return;
+ }
+
+ loadBackPict(background, false);
+
+ drawMonText(ntext, x1, y1, x2, y2, isinteractive);
+
+ mouseShow();
+ fade(true, 0);
+ processMonitor(ntext, isinteractive, x1, y1, x2, y2);
+ fade(false, 0);
+ mouseHide();
+
+ freeAllStolenMem();
+
+ setAPen(0);
+ rectFill(0, 0, VGAScreenWidth - 1, VGAScreenHeight - 1);
+ blackAllScreen();
+}
+
+#if defined(LABDEMO)
+void doTrialBlock() {
+ struct IntuiMessage *Msg;
+
+ uint32 Class;
+ uint16 Qualifier, MouseX, MouseY, Code, Temp;
+ int i;
+
+ loadBackPict("P:Warning", false);
+ mouseShow();
+
+ VGASetPal(diffcmap, 256);
+ memcpy(g_CommonPalette, diffcmap, 3 * 256);
+
+ while (1) {
+ g_music->checkMusic(); /* Make sure we check the music at least after every message */
+ Msg = getMsg();
+
+ if (Msg == NULL) {
+ g_music->newCheckMusic();
+ } else {
+ Class = Msg->Class;
+ Qualifier = Msg->Qualifier;
+ MouseX = Msg->MouseX;
+ MouseY = Msg->MouseY;
+ Code = Msg->Code;
+
+ replyMsg(Msg);
+
+ if (((Class == MOUSEBUTTONS) && (IEQUALIFIER_RBUTTON & Qualifier)) ||
+ ((Class == RAWKEY) && (Code == 27)))
+ return;
+
+ if ((Class == MOUSEBUTTONS) && (IEQUALIFIER_LEFTBUTTON & Qualifier)) {
+ if (MouseY > 399) {
+ // click on control panel, exit
+ break;
+ }
+
+ if (MouseX >= 0 && MouseX <= 319 && MouseY >= 0 && MouseY <= 399) {
+ extern void getItNow();
+ getItNow();
+ } else if (MouseX >= 320 && MouseX <= 639 && MouseY >= 0 && MouseY <= 399) {
+ break;
+ }
+ }
+ }
+ }
+
+ eatMessages();
+ mouseHide();
+}
+#endif
+
+} // End of namespace Lab
diff --git a/engines/lab/stddefines.h b/engines/lab/stddefines.h
new file mode 100644
index 0000000000..b7e5fa6dda
--- /dev/null
+++ b/engines/lab/stddefines.h
@@ -0,0 +1,105 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "common/system.h"
+#include "common/debug.h"
+#include "common/textconsole.h"
+
+#ifndef LAB_STDDEFINES_H
+#define LAB_STDDEFINES_H
+
+namespace Lab {
+
+#define IS_MACOSX 1
+#define USE_SWAP 1
+
+
+#define INCL(BITSET,BIT) ((BITSET) |= (BIT))
+
+#define EXCL(BITSET,BIT) ((BITSET) &= (~(BIT)))
+
+
+
+#define SETBIT(BITSET,BITNUM) INCL(BITSET, (1 << (BITNUM)))
+
+#define UNSETBIT(BITSET,BITNUM) EXCL(BITSET, (1 << (BITNUM)))
+
+#define INBIT(BITSET,BITNUM) ( ((1 << (BITNUM)) & (BITSET)) > 0 )
+
+#if !defined(WIN32)
+#ifndef min
+#define min(a,b) ((a)<(b) ? (a) : (b))
+#endif
+#ifndef max
+#define max(a,b) ((a)>(b) ? (a) : (b))
+#endif
+#endif
+
+#if defined(IS_MACOSX)
+#define getTime Lab_GetTime
+#define delay Lab_Delay
+#endif
+
+#if !defined(DOSCODE)
+#if defined(USE_NOSWAP)
+#define swapUShort(value) (value)
+#define swapUShortPtr(ptr,count) (ptr)
+#define swapShort(value) (value)
+#define swapShortPtr(ptr,count) (ptr)
+#define swapUInt(value) (value)
+#define swapUIntPtr(ptr,count) (ptr)
+#define swapInt(value) (value)
+#define swapIntPtr(ptr,count) (ptr)
+#define swapULong(value) (value)
+#define swapULongPtr(ptr,count) (ptr)
+#define swapLong(value) (value)
+#define swapLongPtr(ptr,count) (ptr)
+#elif defined(USE_SWAP)
+uint16 swapUShort(uint16 value);
+uint16 *swapUShortPtr(uint16 *ptr, int count);
+int16 swapShort(int16 value);
+int16 *swapShortPtr(int16 *ptr, int count);
+unsigned int swapUInt(unsigned int value);
+unsigned int *swapUIntPtr(unsigned int *ptr, int count);
+int swapInt(int value);
+int *swapIntPtr(int *ptr, int count);
+uint32 swapULong(uint32 value);
+uint32 *swapULongPtr(uint32 *ptr, int count);
+int32 swapLong(int32 value);
+int32 *swapLongPtr(int32 *ptr, int count);
+#else
+#error Please tell me about swapping bytes!
+#endif
+
+#endif
+
+} // End of namespace Lab
+
+#endif /* LAB_STDDEFINES_H */
diff --git a/engines/lab/storage.cpp b/engines/lab/storage.cpp
new file mode 100644
index 0000000000..0d21b937c9
--- /dev/null
+++ b/engines/lab/storage.cpp
@@ -0,0 +1,89 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+
+namespace Lab {
+
+/*****************************************************************************/
+/* Allocates a chunk of memory. */
+/*****************************************************************************/
+bool allocate(void **Ptr, uint32 Size) {
+ (*Ptr) = malloc(Size);
+
+ if (*Ptr)
+ memset(*Ptr, 0, (size_t) Size);
+
+ return (*Ptr != NULL);
+}
+
+
+
+
+/*****************************************************************************/
+/* Allocates a piece of chip memory. */
+/*****************************************************************************/
+bool allocatechip(void **Ptr, uint32 Size) {
+ return allocate(Ptr, Size);
+}
+
+/*****************************************************************************/
+/* Allocates a chunk of dos memory. */
+/*****************************************************************************/
+bool allocatedos(void **Ptr, uint32 Size) {
+#if defined(DOSCODE)
+ static union REGS regs;
+
+ regs.x.eax = 0x100;
+ regs.x.ebx = (Size >> 4);
+ int386(0x31, &regs, &regs);
+
+ if (regs.x.cflag) {
+ *Ptr = NULL;
+ return false;
+ }
+
+ *Ptr = (char *)((regs.x.eax & 0xFFFF) << 4);
+ return (*Ptr != NULL);
+#else
+ *Ptr = malloc(Size);
+ return (*Ptr != NULL);
+#endif
+}
+
+/*****************************************************************************/
+/* Deallocates a piece of memory. */
+/*****************************************************************************/
+void deallocate(void *Ptr, uint32 Size) {
+ if (Ptr)
+ free(Ptr);
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/storage.h b/engines/lab/storage.h
new file mode 100644
index 0000000000..bb14bef23c
--- /dev/null
+++ b/engines/lab/storage.h
@@ -0,0 +1,48 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+
+#ifndef LAB_STORAGE_H
+#define LAB_STORAGE_H
+
+namespace Lab {
+
+bool allocate(void **Ptr, uint32 Size);
+
+bool allocatechip(void **Ptr, uint32 Size);
+
+bool allocatedos(void **Ptr, uint32 Size);
+
+void deallocate(void *Ptr, uint32 Size);
+
+} // End of namespace Lab
+
+#endif /* LAB_STORAGE_H */
diff --git a/engines/lab/text.cpp b/engines/lab/text.cpp
new file mode 100644
index 0000000000..4376dba182
--- /dev/null
+++ b/engines/lab/text.cpp
@@ -0,0 +1,293 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/labfun.h"
+#include "lab/storage.h"
+#include "lab/text.h"
+#include "lab/vga.h"
+
+namespace Lab {
+
+/*****************************************************************************/
+/* Opens up a font from disk, but uses buffer memory to store it in. */
+/*****************************************************************************/
+bool openFontMem(const char *TextFontPath, struct TextFont *tf, byte *fontbuffer) {
+ byte **file = NULL;
+ char header[5];
+ int32 filesize, headersize = 4L + 2L + 256 * 3 + 4L;
+
+ filesize = sizeOfFile(TextFontPath);
+ file = g_music->newOpen(TextFontPath);
+
+ if ((file != NULL) && (filesize > headersize)) {
+ header[4] = 0;
+ readBlock(&header, 4L, file);
+
+ if (strcmp(header, "VGAF") == 0) {
+ tf->DataLength = filesize - headersize;
+ readBlock(&(tf->Height), 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&(tf->Height), 1);
+#endif
+ readBlock(tf->Widths, 256L, file);
+ readBlock(tf->Offsets, 256L * 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(tf->Offsets, 256);
+#endif
+ skip(file, 4L);
+ tf->data = fontbuffer;
+ readBlock(tf->data, tf->DataLength, file);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+/*****************************************************************************/
+/* Opens up a font from disk. */
+/*****************************************************************************/
+bool openFont(const char *TextFontPath, struct TextFont **tf) {
+ byte **file = NULL;
+ char header[5];
+ int32 filesize, headersize = 4L + 2L + 256 * 3 + 4L;
+
+ if (allocate((void **)tf, sizeof(struct TextFont))) {
+ filesize = sizeOfFile(TextFontPath);
+ file = g_music->newOpen(TextFontPath);
+
+ if ((file != NULL) && (filesize > headersize)) {
+ header[4] = 0;
+ readBlock(&header, 4L, file);
+
+ if (strcmp(header, "VGAF") == 0) {
+ (*tf)->DataLength = filesize - headersize;
+ readBlock(&((*tf)->Height), 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr(&((*tf)->Height), 1);
+#endif
+ readBlock((*tf)->Widths, 256L, file);
+ readBlock((*tf)->Offsets, 256L * 2L, file);
+#if !defined(DOSCODE)
+ swapUShortPtr((*tf)->Offsets, 256);
+#endif
+ skip(file, 4L);
+
+ if (allocate((void **) & ((*tf)->data), (*tf)->DataLength)) {
+ readBlock((*tf)->data, (*tf)->DataLength, file);
+ return true;
+ }
+ }
+ }
+
+ deallocate(*tf, sizeof(struct TextFont));
+ }
+
+ *tf = NULL;
+ return false;
+}
+
+
+/*****************************************************************************/
+/* Closes a font and frees all memory associated with it. */
+/*****************************************************************************/
+void closeFont(struct TextFont *tf) {
+ if (tf) {
+ if (tf->data && tf->DataLength)
+ deallocate(tf->data, tf->DataLength);
+
+ deallocate(tf, sizeof(struct TextFont));
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Returns the length of a text in the specified font. */
+/*****************************************************************************/
+uint16 textLength(struct TextFont *tf, const char *text, uint16 numchars) {
+ uint16 counter, length = 0;
+
+ if (tf)
+ for (counter = 0; counter < numchars; counter++) {
+ length += tf->Widths[(uint)*text];
+ text++;
+ }
+
+ return length;
+}
+
+
+
+/*****************************************************************************/
+/* Returns the height of a specified font. */
+/*****************************************************************************/
+uint16 textHeight(struct TextFont *tf) {
+ if (tf)
+ return tf->Height;
+ else
+ return 0;
+}
+
+
+
+extern uint32 VGAScreenWidth, VGABytesPerPage;
+
+
+/*****************************************************************************/
+/* Draws the text to the screen. */
+/*****************************************************************************/
+void text(struct TextFont *tf, uint16 x, uint16 y, uint16 color, const char *text, uint16 numchars) {
+ byte *VGATop, *VGACur, *VGATemp, *VGATempLine, *cdata;
+ uint32 RealOffset, SegmentOffset;
+ int32 templeft, LeftInSegment;
+ uint16 counter, counterb, bwidth, mask, curpage, rows, cols, data;
+
+ VGATop = getVGABaseAddr();
+
+ for (counter = 0; counter < numchars; counter++) {
+ RealOffset = (VGAScreenWidth * y) + x;
+ curpage = RealOffset / VGABytesPerPage;
+ SegmentOffset = RealOffset - (curpage * VGABytesPerPage);
+ LeftInSegment = VGABytesPerPage - SegmentOffset;
+ VGACur = VGATop + SegmentOffset;
+ setPage(curpage);
+
+ if (tf->Widths[(uint)*text]) {
+ cdata = tf->data + tf->Offsets[(uint)*text];
+ bwidth = *cdata;
+ cdata++;
+ VGATemp = VGACur;
+ VGATempLine = VGACur;
+
+ for (rows = 0; rows < tf->Height; rows++) {
+ VGATemp = VGATempLine;
+ templeft = LeftInSegment;
+
+ for (cols = 0; cols < bwidth; cols++) {
+ data = *cdata;
+ cdata++;
+
+ if (data && (templeft >= 8)) {
+ if (0x80 & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ if (0x40 & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ if (0x20 & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ if (0x10 & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ if (0x08 & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ if (0x04 & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ if (0x02 & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ if (0x01 & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ templeft -= 8;
+ } else if (data) {
+ mask = 0x80;
+ templeft = LeftInSegment;
+
+ for (counterb = 0; counterb < 8; counterb++) {
+ if (templeft <= 0) {
+ curpage++;
+ setPage(curpage);
+ VGATemp = (byte *)(VGATop - templeft);
+ /* Set up VGATempLine for next line */
+ VGATempLine -= VGABytesPerPage;
+ /* Set up LeftInSegment for next line */
+ LeftInSegment += VGABytesPerPage + templeft;
+ templeft += VGABytesPerPage;
+ }
+
+ if (mask & data)
+ *VGATemp = color;
+
+ VGATemp++;
+
+ mask = mask >> 1;
+ templeft--;
+ }
+ } else {
+ templeft -= 8;
+ VGATemp += 8;
+ }
+ }
+
+ VGATempLine += VGAScreenWidth;
+ LeftInSegment -= VGAScreenWidth;
+
+ if (LeftInSegment <= 0) {
+ curpage++;
+ setPage(curpage);
+ VGATempLine -= VGABytesPerPage;
+ LeftInSegment += VGABytesPerPage;
+ }
+ }
+ }
+
+ x += tf->Widths[(int)*text];
+ text++;
+ }
+
+#if !defined(DOSCODE)
+ ungetVGABaseAddr();
+#endif
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/text.h b/engines/lab/text.h
new file mode 100644
index 0000000000..4947fda7fe
--- /dev/null
+++ b/engines/lab/text.h
@@ -0,0 +1,69 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#ifndef LAB_TEXT_H
+#define LAB_TEXT_H
+
+
+#include "lab/stddefines.h"
+
+namespace Lab {
+
+#if defined(WIN32)
+#pragma pack(push, 1)
+#endif
+
+struct TextFont {
+ uint32 DataLength;
+ uint16 Height;
+ byte Widths[256];
+ uint16 Offsets[256];
+ byte *data;
+};
+
+#if defined(WIN32)
+#pragma pack(pop)
+#endif
+
+bool openFontMem(const char *TextFontPath, struct TextFont *tf, byte *fontbuffer);
+
+bool openFont(const char *TextFontPath, struct TextFont **tf);
+
+void closeFont(struct TextFont *tf);
+
+uint16 textLength(struct TextFont *tf, const char *text, uint16 numchars);
+
+uint16 textHeight(struct TextFont *tf);
+
+void text(struct TextFont *tf, uint16 x, uint16 y, uint16 color, const char *text, uint16 numchars);
+
+} // End of namespace Lab
+
+#endif /* LAB_TEXT_H */
diff --git a/engines/lab/timing.cpp b/engines/lab/timing.cpp
new file mode 100644
index 0000000000..acba16d98e
--- /dev/null
+++ b/engines/lab/timing.cpp
@@ -0,0 +1,147 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+#include "lab/timing.h"
+#include "lab/vga.h"
+
+namespace Lab {
+
+/*****************************************************************************/
+/* Waits for for Secs seconds and Micros microseconds to pass. */
+/*****************************************************************************/
+void microDelay(uint32 secs, uint32 micros) {
+ uint32 waitSecs, waitMicros;
+
+ addCurTime(secs, micros, &waitSecs, &waitMicros);
+
+ while (1) {
+ getTime(&secs, &micros);
+
+ if ((secs > waitSecs) || ((secs == waitSecs) && (micros >= waitMicros)))
+ return;
+
+ g_system->delayMillis(10);
+ }
+}
+
+/*****************************************************************************/
+/* Gets the current system time. */
+/*****************************************************************************/
+void getTime(uint32 *secs, uint32 *micros) {
+ uint32 t = g_system->getMillis();
+
+ *secs = t / 1000;
+ *micros = t % 1000;
+}
+
+/*****************************************************************************/
+/* Adds seconds and microseconds to current time to get a new time. */
+/*****************************************************************************/
+void addCurTime(uint32 sec, uint32 micros, uint32 *timeSec, uint32 *timeMicros) {
+ getTime(timeSec, timeMicros);
+
+ (*timeSec) += sec;
+ (*timeMicros) += micros;
+
+ if (*timeMicros >= ONESECOND) {
+ (*timeSec)++;
+ (*timeMicros) -= ONESECOND;
+ }
+}
+
+/*****************************************************************************/
+/* Finds the difference between time1 and time2. If time1 is later than */
+/* time2, returns 0. */
+/*****************************************************************************/
+void anyTimeDiff(uint32 sec1, uint32 micros1, uint32 sec2, uint32 micros2, uint32 *diffSecs, uint32 *diffMicros) {
+ *diffSecs = 0;
+ *diffMicros = 0;
+
+ if (sec1 > sec2)
+ return;
+ else if ((sec1 == sec2) && (micros1 >= micros2))
+ return;
+
+ if (micros1 > micros2) {
+ *diffSecs = sec2 - sec1 - 1;
+ *diffMicros = (ONESECOND - micros1) + micros2;
+ } else {
+ *diffSecs = sec2 - sec1;
+ *diffMicros = micros2 - micros1;
+ }
+}
+
+/*****************************************************************************/
+/* Finds the difference between the current time, and a future time. Returns */
+/* 0 if the future time is actually before the current time. */
+/*****************************************************************************/
+void timeDiff(uint32 sec, uint32 micros, uint32 *diffSec, uint32 *diffMicros) {
+ uint32 curSec, curMicros;
+
+ *diffSec = 0;
+ *diffMicros = 0;
+
+ getTime(&curSec, &curMicros);
+
+ if (curSec > sec) /* Already passed the time */
+ return;
+ else if ((curSec == sec) && (curMicros >= micros)) /* Already passed the time */
+ return;
+
+ if (curMicros > micros) {
+ *diffSec = sec - curSec - 1;
+ *diffMicros = (ONESECOND - curMicros) + micros;
+ } else {
+ *diffSec = sec - curSec;
+ *diffMicros = micros - curMicros;
+ }
+}
+
+/*****************************************************************************/
+/* Waits for a specified time to occur. */
+/*****************************************************************************/
+void waitForTime(uint32 sec, uint32 micros) {
+ uint32 curSec, curMicros;
+
+ getTime(&curSec, &curMicros);
+
+ if (curSec > sec)
+ return;
+ else if ((curSec == sec) && (curMicros >= micros))
+ return;
+
+ if (curMicros > micros)
+ microDelay(sec - curSec - 1, (ONESECOND - curMicros) + micros - 1);
+ else
+ microDelay(sec - curSec, micros - curMicros - 1);
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/timing.h b/engines/lab/timing.h
new file mode 100644
index 0000000000..adbaf950d8
--- /dev/null
+++ b/engines/lab/timing.h
@@ -0,0 +1,47 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#ifndef LAB_TIMING_H
+#define LAB_TIMING_H
+
+namespace Lab {
+
+#define ONESECOND 1000
+
+void microDelay(uint32 secs, uint32 micros);
+void getTime(uint32 *secs, uint32 *micros);
+void addCurTime(uint32 sec, uint32 micros, uint32 *timeSec, uint32 *timeMicros);
+void anyTimeDiff(uint32 sec1, uint32 micros1, uint32 sec2, uint32 micros2, uint32 *diffSecs, uint32 *diffMicros);
+void timeDiff(uint32 sec, uint32 micros, uint32 *diffSec, uint32 *diffMicros);
+void waitForTime(uint32 sec, uint32 micros);
+
+} // End of namespace Lab
+
+#endif /* LAB_TIMING_H */
diff --git a/engines/lab/undiff.cpp b/engines/lab/undiff.cpp
new file mode 100644
index 0000000000..2218db485a
--- /dev/null
+++ b/engines/lab/undiff.cpp
@@ -0,0 +1,498 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+
+namespace Lab {
+
+extern uint16 DataBytesPerRow;
+
+
+
+/*****************************************************************************/
+/* Copies memory. */
+/*****************************************************************************/
+#define turbocopymem(Dest, Source, Len) (memcpy(Dest, Source, Len))
+
+
+static void copytwo(byte *Dest, byte *Source) {
+#if defined(USE_SWAP)
+ Dest[1] = Source[0];
+ Dest[0] = Source[1];
+#else
+ *Dest = *Source;
+ Dest++;
+ Source++;
+ *Dest = *Source;
+#endif
+}
+
+
+
+
+/*------------------------ unDiff Horizontal Memory -------------------------*/
+
+
+
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is also a byte. */
+/*****************************************************************************/
+static void unDIFFByteByte(byte *Dest, byte *diff) {
+ uint16 skip, copy;
+
+ while (1) {
+ skip = *diff;
+ diff++;
+ copy = *diff;
+ diff++;
+
+ if (skip == 255) {
+ if (copy == 0) {
+ copytwo((byte *) &skip, diff);
+ diff += 2;
+ copytwo((byte *) &copy, diff);
+ diff += 2;
+ } else if (copy == 255)
+ return;
+ }
+
+ Dest += skip;
+ turbocopymem(Dest, diff, copy);
+ Dest += copy;
+ diff += copy;
+ }
+}
+
+
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a word. */
+/*****************************************************************************/
+static void unDIFFByteWord(uint16 *Dest, uint16 *diff) {
+ uint16 skip, copy;
+
+ while (1) {
+ skip = ((byte *)diff)[0];
+ copy = ((byte *)diff)[1];
+
+ diff++;
+
+ if (skip == 255) {
+ if (copy == 0) {
+ skip = swapUShort(*diff);
+ diff++;
+ copy = swapUShort(*diff);
+ diff++;
+ } else if (copy == 255)
+ return;
+ }
+
+ Dest += skip;
+
+ while (copy > 3) {
+ *Dest = *diff; //swapUShort(*diff);
+ Dest++;
+ diff++;
+
+ *Dest = *diff; //swapUShort(*diff);
+ Dest++;
+ diff++;
+
+ *Dest = *diff; //swapUShort(*diff);
+ Dest++;
+ diff++;
+
+ *Dest = *diff; //swapUShort(*diff);
+ Dest++;
+ diff++;
+
+ copy -= 4;
+ }
+
+ while (copy) {
+ *Dest = *diff; //swapUShort(*diff);
+ Dest++;
+ diff++;
+ copy--;
+ }
+ }
+}
+
+
+
+#ifdef undef
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a long word. */
+/*****************************************************************************/
+static void unDIFFByteLong(byte *Dest, byte *diff) {
+ uint16 skip, copy;
+
+ while (1) {
+ skip = *diff << 2;
+ diff++;
+ copy = *diff << 2;
+ diff++;
+
+ if (skip == (255 << 2)) {
+ if (copy == 0) {
+ skip = swapUShort(*((uint16 *) diff)) << 2;
+ diff += 2;
+ copy = swapUShort(*((uint16 *) diff) << 2;
+ diff += 2;
+ } else if (copy == (255 << 2))
+ return;
+ }
+
+ Dest += skip;
+ turbocopymem(Dest, diff, copy);
+ Dest += copy;
+ diff += copy;
+ }
+}
+
+#endif
+
+
+
+/*****************************************************************************/
+/* UnDiffs a coded DIFF string onto an already initialized piece of memory. */
+/*****************************************************************************/
+bool unDIFFMemory(byte *Dest, byte *diff, uint16 HeaderSize, uint16 CopySize) {
+ if (HeaderSize == 1) {
+ if (CopySize == 1)
+ unDIFFByteByte(Dest, diff);
+
+ else if (CopySize == 2)
+ unDIFFByteWord((uint16 *)Dest, (uint16 *)diff);
+
+#ifdef undef
+ else if (CopySize == 4)
+ unDIFFByteLong((uint32 *)Dest, (uint32 *)diff);
+
+#endif
+
+ else
+ return false;
+ }
+ /*
+ else if (HeaderSize == 2)
+ {
+ if (CopySize == 1)
+ unDIFFWordByte(Dest, diff);
+
+ else if (CopySize == 2)
+ unDIFFWordWord(Dest, diff);
+
+ else if (CopySize == 4)
+ unDIFFWordLong(Dest, diff);
+
+ else
+ return false;
+ }
+ */
+ else
+ return (false);
+
+ return true;
+}
+
+
+
+
+/*------------------------- unDiff Vertical Memory --------------------------*/
+
+
+
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a byte. */
+/*****************************************************************************/
+static void VUnDIFFByteByte(byte *Dest, byte *diff, uint16 bytesperrow) {
+ byte *CurPtr;
+ uint16 skip, copy;
+ uint16 counter = 0;
+
+
+ while (counter < DataBytesPerRow) {
+ CurPtr = Dest + counter;
+
+ for (;;) {
+ skip = *diff;
+ diff++;
+ copy = *diff;
+ diff++;
+
+ if (skip == 255) {
+ counter += copy;
+ break;
+ }
+
+ else {
+ CurPtr += (skip * bytesperrow);
+
+ while (copy) {
+ copy--;
+ *CurPtr = *diff;
+ CurPtr += bytesperrow;
+ diff++;
+ }
+ }
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a word. */
+/*****************************************************************************/
+static void VUnDIFFByteWord(uint16 *Dest, uint16 *diff, uint16 bytesperrow) {
+ uint16 *CurPtr;
+ uint16 skip, copy;
+ uint16 counter = 0, wordsperrow;
+
+
+ wordsperrow = bytesperrow / 2;
+
+ while (counter < (DataBytesPerRow >> 1)) {
+ CurPtr = Dest + counter;
+
+ for (;;) {
+ skip = ((byte *)diff)[0];
+ copy = ((byte *)diff)[1];
+
+ diff++;
+
+
+ if (skip == 255) {
+ counter += copy;
+ break;
+ }
+
+ else {
+ CurPtr += (skip * wordsperrow);
+
+ while (copy) {
+ *CurPtr = *diff; //swapUShort(*diff);
+ CurPtr += wordsperrow;
+ diff++;
+ copy--;
+ }
+ }
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Undiffs a piece of memory when header size is a byte, and copy/skip size */
+/* is a long. */
+/*****************************************************************************/
+static void VUnDIFFByteLong(uint32 *Dest, uint32 *diff, uint16 bytesperrow) {
+ uint32 *CurPtr;
+ uint16 skip, copy;
+ uint16 counter = 0, longsperrow;
+ byte *diff1 = (byte *)diff;
+
+
+ longsperrow = bytesperrow / 4;
+
+ while (counter < (DataBytesPerRow >> 2)) {
+ CurPtr = Dest + counter;
+
+ for (;;) {
+ skip = *diff1;
+ diff1++;
+
+ copy = *diff1;
+ diff1++;
+
+
+ if (skip == 255) {
+ counter += copy;
+ break;
+ }
+
+ else {
+ CurPtr += (skip * longsperrow);
+
+ while (copy) {
+ *CurPtr = *(uint32 *)diff1; //swapULong(*diff);
+ CurPtr += longsperrow;
+ diff1 += 4;
+ copy--;
+ }
+ }
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* UnDiffs a coded DIFF string onto an already initialized piece of memory. */
+/*****************************************************************************/
+bool VUnDIFFMemory(byte *Dest, byte *diff, uint16 HeaderSize, uint16 CopySize, uint16 bytesperrow) {
+ if (HeaderSize == 1) {
+ if (CopySize == 1)
+ VUnDIFFByteByte(Dest, diff, bytesperrow);
+
+ else if (CopySize == 2)
+ VUnDIFFByteWord((uint16 *)Dest, (uint16 *)diff, bytesperrow);
+
+ else if (CopySize == 4)
+ VUnDIFFByteLong((uint32 *)Dest, (uint32 *)diff, bytesperrow);
+
+ else
+ return false;
+ }
+ /*
+ else if (HeaderSize == 2)
+ {
+ if (CopySize == 1)
+ VUnDIFFWordByte(Dest, diff, bytesperrow);
+
+ else if (CopySize == 2)
+ VUnDIFFWordWord(Dest, diff, bytesperrow);
+
+ else if (CopySize == 4)
+ VUnDIFFWordLong(Dest, diff, bytesperrow);
+
+ else
+ return false;
+ }
+ */
+ else
+ return (false);
+
+ return true;
+}
+
+
+
+
+
+/*---------------------------- Runlength Decodes ----------------------------*/
+
+
+
+
+
+/*****************************************************************************/
+/* Runlength decodes a chunk of memory. */
+/*****************************************************************************/
+void runLengthDecode(byte *Dest, byte *Source) {
+ int8 num;
+ int16 count;
+
+
+ while (1) {
+ num = (int8)*Source;
+ Source++;
+
+ if (num == 127) {
+ return;
+ } else if (num > '\0') {
+ turbocopymem(Dest, Source, num);
+ Source += num;
+ Dest += num;
+ } else {
+ count = (int16)(-num);
+ num = *Source;
+ Source++;
+
+ while (count) {
+ *Dest = num;
+ Dest++;
+ count--;
+ }
+ }
+ }
+}
+
+
+
+
+/*****************************************************************************/
+/* Does a vertical run length decode. */
+/*****************************************************************************/
+void VRunLengthDecode(byte *Dest, byte *Source, uint16 bytesperrow) {
+ int8 num;
+ int16 count;
+ uint16 Counter;
+ byte *Top;
+
+ Top = Dest;
+
+ for (Counter = 0; Counter < DataBytesPerRow; Counter++) {
+ Dest = Top;
+ Dest += Counter;
+
+ num = (int8)*Source;
+ Source++;
+
+ while (num != 127) {
+ if (num > '\0') {
+ while (num) {
+ *Dest = *Source;
+ Source++;
+ Dest += bytesperrow;
+ num--;
+ }
+ } else {
+ count = (int16)(-num);
+ num = (int8)*Source;
+ Source++;
+
+ while (count) {
+ *Dest = num;
+ Dest += bytesperrow;
+ count--;
+ }
+ }
+
+ num = *Source;
+ Source++;
+ }
+ }
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/vga.cpp b/engines/lab/vga.cpp
new file mode 100644
index 0000000000..235d247145
--- /dev/null
+++ b/engines/lab/vga.cpp
@@ -0,0 +1,1082 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/vga.h"
+#include "lab/stddefines.h"
+#include "lab/storage.h"
+
+namespace Lab {
+
+//static uint16 NotInRefresh = 0;
+
+uint32 VGAScreenWidth = 320UL,
+ VGAScreenHeight = 200UL,
+ VGAPages = 1UL,
+ VGABytesPerPage = 65536UL;
+
+uint32 VGABASEADDRESS = 0xA0000L;
+
+
+/*****************************************************************************/
+/* Sets the display mode. */
+/*****************************************************************************/
+void setMode(char mode) {
+ // There are no modes for SDL.
+}
+
+/*****************************************************************************/
+/* Sets up either a low-res or a high-res 256 color screen. */
+/*****************************************************************************/
+bool createScreen(bool HiRes) {
+// VGABASEADDRESS = (unsigned long)malloc(640 * 480);
+ VGABASEADDRESS = 1;
+ VGAScreenWidth = 640;
+ VGAScreenHeight = 480;
+ VGAPages = 1;
+ VGABytesPerPage = 640 * 480;
+ return true;
+}
+
+
+
+/*****************************************************************************/
+/* Sets the current page on the VGA card. */
+/*****************************************************************************/
+void setPage(uint16 PageNum) {
+ // PageNum should always calculated out to zero for SDL.
+ assert(PageNum == 0);
+}
+
+
+
+void VGAStorePage(void) {
+ // does nothing in SDL
+}
+
+void VGARestorePage(void) {
+ // does nothing in SDL
+}
+
+
+void waitTOF(void) {
+ warning("STUB: waitTOF");
+ //WSDL_WaitTOF(1);
+}
+
+
+// NOTE: I don't think this function is called anywhere in the code.
+void waitTOFQuick(void) {
+ warning("STUB: waitTOFQuick");
+ //WSDL_WaitTOF(0);
+}
+
+
+static char curvgapal[256 * 3];
+
+/*****************************************************************************/
+/* Writes any number of the 256 color registers. */
+/* first: the number of the first color register to write. */
+/* numreg: the number of registers to write */
+/* buf: a char pointer which contains the selected color registers. */
+/* Each value representing a color register occupies 3 bytes in */
+/* the array. The order is red, green then blue. The first byte */
+/* in the array is the red component of the first element selected.*/
+/* The length of the buffer is 3 times the number of registers */
+/* selected. */
+/*****************************************************************************/
+void writeColorRegs(char *buf,
+ uint16 first,
+ uint16 numreg) {
+ warning("STUB: writeColorRegs");
+ //WSDL_SetColors(buf, first, numreg, 0);
+ memcpy(&(curvgapal[first * 3]), buf, numreg * 3);
+}
+
+
+
+
+void writeColorRegsSmooth(char *buf,
+ uint16 first,
+ uint16 numreg) {
+ warning("STUB: writeColorRegsSmooth");
+ //WSDL_SetColors(buf, first, numreg, 1);
+ memcpy(&(curvgapal[first * 3]), buf, numreg * 3);
+}
+
+
+
+
+/*****************************************************************************/
+/* Sets one of the 256 (0..255) color registers. buf is a char pointer, */
+/* the first character in the string is the red value, then green, then */
+/* blue. Each color value is a 6 bit value. */
+/*****************************************************************************/
+void writeColorReg(char *buf,
+ uint16 regnum) {
+ writeColorRegs(buf, regnum, 1);
+}
+
+
+
+
+
+void VGASetPal(void *cmap,
+ uint16 numcolors) {
+ if (memcmp(cmap, curvgapal, numcolors * 3) != 0)
+ writeColorRegs((char *) cmap, 0, numcolors);
+}
+
+
+
+/*****************************************************************************/
+/* Returns the base address of the current VGA display. */
+/*****************************************************************************/
+byte *getVGABaseAddr(void) {
+ if (VGABASEADDRESS != 1)
+ return (byte *)VGABASEADDRESS;
+
+ warning("STUB: getVGABaseAddr");
+ return 0; // WSDL_LockVideo();
+}
+
+#if !defined(DOSCODE)
+void ungetVGABaseAddr() {
+ warning("STUB: ungetVGABaseAddr");
+ if (VGABASEADDRESS == 1)
+ ; //WSDL_UnlockVideo();
+}
+#endif
+
+
+/*****************************************************************************/
+/* Gets information about the current display. */
+/*****************************************************************************/
+void getMode(uint16 *Mode) {
+ // Only one mode in SDL.
+}
+
+
+
+
+/*****************************************************************************/
+/* Draws an image to the screen. */
+/*****************************************************************************/
+void drawImage(struct Image *Im,
+ uint16 x,
+ uint16 y) {
+#if !defined(DOSCODE)
+ int sx, sy, dx, dy, w, h;
+
+ sx = 0;
+ sy = 0;
+ dx = x;
+ dy = y;
+ w = Im->Width;
+ h = Im->Height;
+
+ if (dx < 0) {
+ sx -= dx;
+ w += dx;
+ dx = 0;
+ }
+
+ if (dy < 0) {
+ sy -= dy;
+ w += dy;
+ dy = 0;
+ }
+
+ if ((uint)(dx + w) > VGAScreenWidth)
+ w = VGAScreenWidth - dx;
+
+ if ((uint)(dy + h) > VGAScreenHeight)
+ h = VGAScreenHeight - dy;
+
+ if (w > 0 && h > 0) {
+ byte *s = Im->ImageData + sy * Im->Width + sx;
+ byte *d = getVGABaseAddr() + dy * VGAScreenWidth + dx;
+
+ while (h-- > 0) {
+ memcpy(d, s, w);
+ s += Im->Width;
+ d += VGAScreenWidth;
+ }
+
+ ungetVGABaseAddr();
+ }
+
+#else
+ uint32 RealOffset,
+ SegmentOffset,
+ LeftInSegment;
+ char *video,
+ *curline,
+ *imdata = Im->ImageData;
+ uint16 counterx,
+ countery = 0,
+ numwholelines,
+ numpartiallines,
+ curpage;
+
+ while (countery < Im->Height) {
+ RealOffset = (VGAScreenWidth * (y + countery)) + x;
+ curpage = RealOffset / VGABytesPerPage;
+ SegmentOffset = RealOffset - (curpage * VGABytesPerPage);
+ LeftInSegment = VGABytesPerPage - SegmentOffset;
+ setPage(curpage);
+ video = (char *)(((int32)(VGABASEADDRESS)) + SegmentOffset);
+
+ numwholelines = LeftInSegment / VGAScreenWidth;
+ numpartiallines = 0;
+ counterx = LeftInSegment - (numwholelines * VGAScreenWidth);
+
+ if (counterx >= Im->Width)
+ numwholelines++;
+ else
+ numpartiallines = 1;
+
+ while (numwholelines && (countery < Im->Height)) {
+ curline = video;
+
+ for (counterx = 0; counterx < Im->Width; counterx++) {
+ *video = *imdata;
+ video++;
+ imdata++;
+ }
+
+ video = curline;
+ video += VGAScreenWidth;
+ countery ++;
+ numwholelines --;
+ LeftInSegment -= VGAScreenWidth;
+ }
+
+ if (numpartiallines && (countery < Im->Height)) {
+ countery ++;
+ curline = video;
+
+ for (counterx = 0; counterx < Im->Width; counterx++) {
+ if (LeftInSegment == 0L) {
+ setPage(curpage + 1);
+ LeftInSegment = VGABytesPerPage;
+ video = (char *)(VGABASEADDRESS);
+ }
+
+ *video = *imdata;
+ video++;
+ imdata++;
+ LeftInSegment--;
+ }
+ }
+ }
+
+#endif
+}
+
+
+
+
+/*****************************************************************************/
+/* Draws an image to the screen. */
+/*****************************************************************************/
+void drawMaskImage(struct Image *Im,
+ uint16 x,
+ uint16 y) {
+#if !defined(DOSCODE)
+ int sx, sy, dx, dy, w, h;
+
+ sx = 0;
+ sy = 0;
+ dx = x;
+ dy = y;
+ w = Im->Width;
+ h = Im->Height;
+
+ if (dx < 0) {
+ sx -= dx;
+ w += dx;
+ dx = 0;
+ }
+
+ if (dy < 0) {
+ sy -= dy;
+ w += dy;
+ dy = 0;
+ }
+
+ if ((uint)(dx + w) > VGAScreenWidth)
+ w = VGAScreenWidth - dx;
+
+ if ((uint)(dy + h) > VGAScreenHeight)
+ h = VGAScreenHeight - dy;
+
+ if (w > 0 && h > 0) {
+ byte *s = Im->ImageData + sy * Im->Width + sx;
+ byte *d = getVGABaseAddr() + dy * VGAScreenWidth + dx;
+
+ while (h-- > 0) {
+ byte *ss = s;
+ byte *dd = d;
+ int ww = w;
+
+ while (ww-- > 0) {
+ byte c = *ss++;
+
+ if (c) *dd++ = c - 1;
+ else dd++;
+ }
+
+ s += Im->Width;
+ d += VGAScreenWidth;
+ }
+
+ ungetVGABaseAddr();
+ }
+
+#else
+ uint32 RealOffset,
+ SegmentOffset,
+ LeftInSegment;
+ char *video,
+ *curline,
+ *imdata = Im->ImageData;
+ uint16 counterx,
+ countery = 0,
+ numwholelines,
+ numpartiallines,
+ curpage;
+
+ while (countery < Im->Height) {
+ RealOffset = (VGAScreenWidth * (y + countery)) + x;
+ curpage = RealOffset / VGABytesPerPage;
+ SegmentOffset = RealOffset - (curpage * VGABytesPerPage);
+ LeftInSegment = VGABytesPerPage - SegmentOffset;
+ setPage(curpage);
+ video = (char *)(((int32)(VGABASEADDRESS)) + SegmentOffset);
+
+ numwholelines = LeftInSegment / VGAScreenWidth;
+ numpartiallines = 0;
+ counterx = LeftInSegment - (numwholelines * VGAScreenWidth);
+
+ if (counterx >= Im->Width)
+ numwholelines++;
+ else
+ numpartiallines = 1;
+
+ while (numwholelines && (countery < Im->Height)) {
+ curline = video;
+
+ for (counterx = 0; counterx < Im->Width; counterx++) {
+ if (*imdata)
+ *video = *imdata - 1;
+
+ video++;
+ imdata++;
+ }
+
+ video = curline;
+ video += VGAScreenWidth;
+ countery ++;
+ numwholelines --;
+ LeftInSegment -= VGAScreenWidth;
+ }
+
+ if (numpartiallines && (countery < Im->Height)) {
+ countery ++;
+ curline = video;
+
+ for (counterx = 0; counterx < Im->Width; counterx++) {
+ if (LeftInSegment == 0L) {
+ setPage(curpage + 1);
+ LeftInSegment = VGABytesPerPage;
+ video = (char *)(VGABASEADDRESS);
+ }
+
+ if (*imdata)
+ *video = *imdata - 1;
+
+ video++;
+ imdata++;
+ LeftInSegment--;
+ }
+ }
+ }
+
+#endif
+}
+
+
+
+
+/*****************************************************************************/
+/* Reads an image from the screen. */
+/*****************************************************************************/
+void readScreenImage(struct Image *Im,
+ uint16 x,
+ uint16 y) {
+#if !defined(DOSCODE)
+ int sx, sy, dx, dy, w, h;
+
+ sx = 0;
+ sy = 0;
+ dx = x;
+ dy = y;
+ w = Im->Width;
+ h = Im->Height;
+
+ if (dx < 0) {
+ sx -= dx;
+ w += dx;
+ dx = 0;
+ }
+
+ if (dy < 0) {
+ sy -= dy;
+ w += dy;
+ dy = 0;
+ }
+
+ if ((uint)(dx + w) > VGAScreenWidth)
+ w = VGAScreenWidth - dx;
+
+ if ((uint)(dy + h) > VGAScreenHeight)
+ h = VGAScreenHeight - dy;
+
+ if (w > 0 && h > 0) {
+ byte *s = Im->ImageData + sy * Im->Width + sx;
+ byte *d = getVGABaseAddr() + dy * VGAScreenWidth + dx;
+
+ while (h-- > 0) {
+ memcpy(s, d, w);
+ s += Im->Width;
+ d += VGAScreenWidth;
+ }
+
+ ungetVGABaseAddr();
+ }
+
+#else
+ uint32 RealOffset,
+ SegmentOffset,
+ LeftInSegment;
+ char *video,
+ *curline,
+ *imdata = Im->ImageData;
+ uint16 counterx,
+ countery = 0,
+ numwholelines,
+ numpartiallines,
+ curpage;
+
+ while (countery < Im->Height) {
+ RealOffset = (VGAScreenWidth * (y + countery)) + x;
+ curpage = RealOffset / VGABytesPerPage;
+ SegmentOffset = RealOffset - (curpage * VGABytesPerPage);
+ LeftInSegment = VGABytesPerPage - SegmentOffset;
+ setPage(curpage);
+ video = (char *)(((int32)(VGABASEADDRESS)) + SegmentOffset);
+
+ numwholelines = LeftInSegment / VGAScreenWidth;
+ numpartiallines = 0;
+ counterx = LeftInSegment - (numwholelines * VGAScreenWidth);
+
+ if (counterx >= Im->Width)
+ numwholelines++;
+ else
+ numpartiallines = 1;
+
+ while (numwholelines && (countery < Im->Height)) {
+ curline = video;
+
+ for (counterx = 0; counterx < Im->Width; counterx++) {
+ *imdata = *video;
+ video++;
+ imdata++;
+ }
+
+ video = curline;
+ video += VGAScreenWidth;
+ countery ++;
+ numwholelines --;
+ LeftInSegment -= VGAScreenWidth;
+ }
+
+ if (numpartiallines && (countery < Im->Height)) {
+ countery ++;
+ curline = video;
+
+ for (counterx = 0; counterx < Im->Width; counterx++) {
+ if (LeftInSegment == 0L) {
+ setPage(curpage + 1);
+ LeftInSegment = VGABytesPerPage;
+ video = (char *)(VGABASEADDRESS);
+ }
+
+ *imdata = *video;
+ video++;
+ imdata++;
+ LeftInSegment--;
+ }
+ }
+ }
+
+#endif
+}
+
+
+
+
+/*****************************************************************************/
+/* Blits a piece of one image to another. */
+/* NOTE: for our purposes, assumes that ImDest is to be in VGA memory. */
+/*****************************************************************************/
+void bltBitMap(struct Image *ImSource,
+ uint16 xs,
+ uint16 ys,
+ struct Image *ImDest,
+ uint16 xd,
+ uint16 yd,
+ uint16 width,
+ uint16 height) {
+#if !defined(DOSCODE)
+ // I think the old code assumed that the source image data was valid for the given box.
+ // I will proceed on that assumption.
+ int sx, sy, dx, dy, w, h;
+
+ sx = xs;
+ sy = ys;
+ dx = xd;
+ dy = yd;
+ w = width;
+ h = height;
+
+ if (dx < 0) {
+ sx -= dx;
+ w += dx;
+ dx = 0;
+ }
+
+ if (dy < 0) {
+ sy -= dy;
+ w += dy;
+ dy = 0;
+ }
+
+ if (dx + w > ImDest->Width) w = ImDest->Width - dx;
+
+ if (dy + h > ImDest->Height) h = ImDest->Height - dy;
+
+ if (w > 0 && h > 0) {
+ byte *s = ImSource->ImageData + sy * ImSource->Width + sx;
+ byte *d = ImDest->ImageData + dy * ImDest->Width + dx;
+
+ while (h-- > 0) {
+ memcpy(d, s, w);
+ s += ImSource->Width;
+ d += ImDest->Width;
+ }
+ }
+
+#else
+ uint32 RealOffset,
+ SegmentOffset,
+ LeftInSegment;
+ char *video,
+ *curdestline,
+ *cursourceline = ImSource->ImageData,
+ *imdata;
+ uint16 counterx,
+ countery = 0,
+ numwholelines,
+ numpartiallines,
+ curpage;
+
+ cursourceline += (((int32) ys) * ImSource->Width) + xs;
+ imdata = cursourceline;
+
+ while (countery < height) {
+ RealOffset = (ImDest->Width * (yd + countery)) + xd;
+ curpage = RealOffset / VGABytesPerPage;
+ SegmentOffset = RealOffset - (curpage * VGABytesPerPage);
+ LeftInSegment = VGABytesPerPage - SegmentOffset;
+ setPage(curpage);
+
+ video = (char *)(((int32)(ImDest->ImageData)) + SegmentOffset);
+
+ numwholelines = LeftInSegment / ImDest->Width;
+ numpartiallines = 0;
+ counterx = LeftInSegment - (numwholelines * ImDest->Width);
+
+ if (counterx >= width)
+ numwholelines++;
+ else
+ numpartiallines = 1;
+
+ while (numwholelines && (countery < height)) {
+ curdestline = video;
+ cursourceline = imdata;
+
+ for (counterx = 0; counterx < width; counterx++) {
+ *video = *imdata;
+ video++;
+ imdata++;
+ }
+
+ video = curdestline;
+ video += ImDest->Width;
+ imdata = cursourceline;
+ imdata += ImSource->Width;
+
+ countery ++;
+ numwholelines --;
+ LeftInSegment -= ImDest->Width;
+ }
+
+ if (numpartiallines && (countery < height)) {
+ countery ++;
+ curdestline = video;
+ cursourceline = imdata;
+
+ for (counterx = 0; counterx < width; counterx++) {
+ if (LeftInSegment == 0L) {
+ setPage(curpage + 1);
+ LeftInSegment = VGABytesPerPage;
+ video = ImDest->ImageData;
+ }
+
+ *video = *imdata;
+ video++;
+ imdata++;
+ LeftInSegment--;
+ }
+
+ video = curdestline;
+ video += ImDest->Width;
+ imdata = cursourceline;
+ imdata += ImSource->Width;
+ }
+ }
+
+#endif
+}
+
+
+byte *TempScrollData;
+
+
+/*****************************************************************************/
+/* Scrolls the display in the x direction by blitting. */
+/* The TempScrollData variable must be initialized to some memory, or this */
+/* function will fail. */
+/*****************************************************************************/
+void scrollDisplayX(int16 dx,
+ uint16 x1,
+ uint16 y1,
+ uint16 x2,
+ uint16 y2) {
+ struct Image Im;
+ uint16 temp;
+
+ Im.ImageData = TempScrollData;
+
+ if (x1 > x2) {
+ temp = x2;
+ x2 = x1;
+ x1 = temp;
+ }
+
+ if (y1 > y2) {
+ temp = y2;
+ y2 = y1;
+ y1 = temp;
+ }
+
+ if (dx > 0) {
+ Im.Width = x2 - x1 + 1 - dx;
+ Im.Height = y2 - y1 + 1;
+
+ readScreenImage(&Im, x1, y1);
+ drawImage(&Im, x1 + dx, y1);
+
+ setAPen(0);
+ rectFill(x1, y1, x1 + dx - 1, y2);
+ } else if (dx < 0) {
+ Im.Width = x2 - x1 + 1 + dx;
+ Im.Height = y2 - y1 + 1;
+
+ readScreenImage(&Im, x1 - dx, y1);
+ drawImage(&Im, x1, y1);
+
+ setAPen(0);
+ rectFill(x2 + dx + 1, y1, x2, y2);
+ }
+}
+
+
+
+
+
+/*****************************************************************************/
+/* Scrolls the display in the y direction by blitting. */
+/*****************************************************************************/
+void scrollDisplayY(int16 dy,
+ uint16 x1,
+ uint16 y1,
+ uint16 x2,
+ uint16 y2) {
+ struct Image Im;
+ uint16 temp;
+
+ Im.ImageData = TempScrollData;
+
+ if (x1 > x2) {
+ temp = x2;
+ x2 = x1;
+ x1 = temp;
+ }
+
+ if (y1 > y2) {
+ temp = y2;
+ y2 = y1;
+ y1 = temp;
+ }
+
+ if (dy > 0) {
+ Im.Width = x2 - x1 + 1;
+ Im.Height = y2 - y1 + 1 - dy;
+
+ readScreenImage(&Im, x1, y1);
+ drawImage(&Im, x1, y1 + dy);
+
+ setAPen(0);
+ rectFill(x1, y1, x2, y1 + dy - 1);
+ } else if (dy < 0) {
+ Im.Width = x2 - x1 + 1;
+ Im.Height = y2 - y1 + 1 + dy;
+
+ readScreenImage(&Im, x1, y1 - dy);
+ drawImage(&Im, x1, y1);
+
+ setAPen(0);
+ rectFill(x1, y2 + dy + 1, x2, y2);
+ }
+}
+
+
+
+static unsigned char curapen = 0;
+
+/*****************************************************************************/
+/* Sets the pen number to use on all the drawing operations. */
+/*****************************************************************************/
+void setAPen(uint16 pennum) {
+ curapen = (unsigned char)pennum;
+}
+
+
+
+
+/*****************************************************************************/
+/* Fills in a rectangle. */
+/*****************************************************************************/
+void rectFill(uint16 x1,
+ uint16 y1,
+ uint16 x2,
+ uint16 y2) {
+#if !defined(DOSCODE)
+ int dx, dy, w, h;
+
+ dx = x1;
+ dy = y1;
+ w = x2 - x1 + 1;
+ h = y2 - y1 + 1;
+
+ if (dx < 0) {
+ w += dx;
+ dx = 0;
+ }
+
+ if (dy < 0) {
+ w += dy;
+ dy = 0;
+ }
+
+ if ((uint)(dx + w) > VGAScreenWidth)
+ w = VGAScreenWidth - dx;
+
+ if ((uint)(dy + h) > VGAScreenHeight)
+ h = VGAScreenHeight - dy;
+
+ if (w > 0 && h > 0) {
+ char *d = (char *)getVGABaseAddr() + dy * VGAScreenWidth + dx;
+
+ while (h-- > 0) {
+ char *dd = d;
+ int ww = w;
+
+ while (ww-- > 0) {
+ *dd++ = curapen;
+ }
+
+ d += VGAScreenWidth;
+ }
+
+ ungetVGABaseAddr();
+ }
+
+#else
+ uint32 RealOffset,
+ SegmentOffset,
+ LeftInSegment;
+ char *video,
+ *curline;
+ uint16 counterx,
+ countery = y1,
+ numwholelines,
+ numpartiallines,
+ curpage;
+
+ while (countery <= y2) {
+ RealOffset = (VGAScreenWidth * countery) + x1;
+ curpage = RealOffset / VGABytesPerPage;
+ SegmentOffset = RealOffset - (curpage * VGABytesPerPage);
+ LeftInSegment = VGABytesPerPage - SegmentOffset;
+ setPage(curpage);
+ video = (char *)(((int32)(VGABASEADDRESS)) + SegmentOffset);
+
+ numwholelines = LeftInSegment / VGAScreenWidth;
+ numpartiallines = 0;
+ counterx = LeftInSegment - (numwholelines * VGAScreenWidth);
+
+ if (counterx >= (x2 - x1 + 1))
+ numwholelines++;
+ else
+ numpartiallines = 1;
+
+ while (numwholelines && (countery <= y2)) {
+ curline = video;
+
+ for (counterx = x1; counterx <= x2; counterx++) {
+ *video = curapen;
+ video++;
+ }
+
+ video = curline;
+ video += VGAScreenWidth;
+ countery ++;
+ numwholelines --;
+ LeftInSegment -= VGAScreenWidth;
+ }
+
+ if (numpartiallines && (countery <= y2)) {
+ countery ++;
+ curline = video;
+
+ for (counterx = x1; counterx <= x2; counterx++) {
+ if (LeftInSegment == 0L) {
+ setPage(curpage + 1);
+ LeftInSegment = VGABytesPerPage;
+ video = (char *)(VGABASEADDRESS);
+ }
+
+ *video = curapen;
+ video++;
+ LeftInSegment--;
+ }
+ }
+ }
+
+#endif
+}
+
+
+
+/*****************************************************************************/
+/* Draws a horizontal line. */
+/*****************************************************************************/
+void drawVLine(uint16 x,
+ uint16 y1,
+ uint16 y2) {
+ rectFill(x, y1, x, y2);
+}
+
+
+
+
+/*****************************************************************************/
+/* Draws a vertical line. */
+/*****************************************************************************/
+void drawHLine(uint16 x1,
+ uint16 y,
+ uint16 x2) {
+ rectFill(x1, y, x2, y);
+}
+
+
+
+
+/*****************************************************************************/
+/* Ghoasts a region on the screen using the desired pen color. */
+/*****************************************************************************/
+void ghoastRect(uint16 pencolor,
+ uint16 x1,
+ uint16 y1,
+ uint16 x2,
+ uint16 y2) {
+#if !defined(DOSCODE)
+ int dx, dy, w, h;
+
+ dx = x1;
+ dy = y1;
+ w = x2 - x1 + 1;
+ h = y2 - y1 + 1;
+
+ if (dx < 0) {
+ w += dx;
+ dx = 0;
+ }
+
+ if (dy < 0) {
+ w += dy;
+ dy = 0;
+ }
+
+ if ((uint)(dx + w) > VGAScreenWidth)
+ w = VGAScreenWidth - dx;
+
+ if ((uint)(dy + h) > VGAScreenHeight)
+ h = VGAScreenHeight - dy;
+
+ if (w > 0 && h > 0) {
+ char *d = (char *)getVGABaseAddr() + dy * VGAScreenWidth + dx;
+
+ while (h-- > 0) {
+ char *dd = d;
+ int ww = w;
+
+ if (dy & 1) {
+ dd++;
+ ww--;
+ }
+
+ while (ww > 0) {
+ *dd = pencolor;
+ dd += 2;
+ ww -= 2;
+ }
+
+ d += VGAScreenWidth;
+ dy++;
+ }
+
+ ungetVGABaseAddr();
+ }
+
+#else
+ uint32 RealOffset,
+ SegmentOffset;
+ int32 LeftInSegment;
+ char *video,
+ *curline;
+ uint16 counterx,
+ countery = y1,
+ numwholelines,
+ numpartiallines,
+ curpage;
+
+ while (countery <= y2) {
+ RealOffset = (VGAScreenWidth * countery) + x1;
+ curpage = RealOffset / VGABytesPerPage;
+ SegmentOffset = RealOffset - (curpage * VGABytesPerPage);
+ LeftInSegment = VGABytesPerPage - SegmentOffset;
+ setPage(curpage);
+ video = (char *)(((int32)(VGABASEADDRESS)) + SegmentOffset);
+
+ numwholelines = LeftInSegment / VGAScreenWidth;
+ numpartiallines = 0;
+ counterx = LeftInSegment - (numwholelines * VGAScreenWidth);
+
+ if (counterx >= (x2 - x1 + 1))
+ numwholelines++;
+ else
+ numpartiallines = 1;
+
+ while (numwholelines && (countery <= y2)) {
+ curline = video;
+ counterx = x1;
+
+ if (1 & countery) {
+ video++;
+ counterx ++;
+ }
+
+ while (counterx <= x2) {
+ *video = pencolor;
+ video += 2;
+ counterx += 2;
+ }
+
+ video = curline;
+ video += VGAScreenWidth;
+ countery ++;
+ numwholelines --;
+ LeftInSegment -= VGAScreenWidth;
+ }
+
+ if (numpartiallines && (countery <= y2)) {
+ countery ++;
+ curline = video;
+ counterx = x1;
+
+ if (1 & countery) {
+ video++;
+ counterx ++;
+ LeftInSegment --;
+ }
+
+ while (counterx < x2) {
+ if (LeftInSegment <= 0L) {
+ setPage(curpage + 1);
+ video = (char *)(((int32)(VGABASEADDRESS)) - LeftInSegment);
+ LeftInSegment = VGABytesPerPage + LeftInSegment;
+ }
+
+ *video = pencolor;
+ video += 2;
+ counterx += 2;
+ LeftInSegment -= 2;
+ }
+ }
+ }
+
+#endif
+}
+
+} // End of namespace Lab
diff --git a/engines/lab/vga.h b/engines/lab/vga.h
new file mode 100644
index 0000000000..7080f4ae03
--- /dev/null
+++ b/engines/lab/vga.h
@@ -0,0 +1,100 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Labyrinth of Time code with assistance of
+ *
+ * Copyright (c) 1993 Terra Nova Development
+ * Copyright (c) 2004 The Wyrmkeep Entertainment Co.
+ *
+ */
+
+#include "lab/stddefines.h"
+
+#ifndef LAB_VGA_H
+#define LAB_VGA_H
+
+namespace Lab {
+
+struct Image {
+ uint16 Width;
+ uint16 Height;
+ byte *ImageData;
+};
+
+void setMode(char mode);
+
+void getMode(uint16 *Mode);
+
+void setPage(uint16 PageNum);
+
+void VGAStorePage(void);
+
+void VGARestorePage(void);
+
+bool createScreen(bool HiRes);
+
+void waitTOF(void);
+
+void quickWaitTOF(void);
+
+byte *getVGABaseAddr(void);
+
+#if !defined(DOSCODE)
+void ungetVGABaseAddr();
+#endif
+
+void writeColorReg(char *buf, uint16 regnum);
+
+void writeColorRegs(char *buf, uint16 first, uint16 numreg);
+
+void writeColorRegsSmooth(char *buf, uint16 first, uint16 numreg);
+
+void VGASetPal(void *cmap, uint16 numcolors);
+
+/*---------- Drawing Routines ----------*/
+
+void drawImage(struct Image *Im, uint16 x, uint16 y);
+
+void drawMaskImage(struct Image *Im, uint16 x, uint16 y);
+
+void readScreenImage(struct Image *Im, uint16 x, uint16 y);
+
+void bltBitMap(struct Image *ImSource, uint16 xs, uint16 ys, struct Image *ImDest, uint16 xd, uint16 yd, uint16 width, uint16 height);
+
+void scrollDisplayX(int16 dx, uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+
+void scrollDisplayY(int16 dy, uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+
+void setAPen(uint16 pennum);
+
+void drawHLine(uint16 x, uint16 y1, uint16 y2);
+
+void drawVLine(uint16 x1, uint16 y, uint16 x2);
+
+void rectFill(uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+
+void ghoastRect(uint16 pencolor, uint16 x1, uint16 y1, uint16 x2, uint16 y2);
+
+} // End of namespace Lab
+
+#endif /* LAB_VGA_H */