diff options
author | Eugene Sandulenko | 2014-10-06 14:50:05 +0200 |
---|---|---|
committer | Eugene Sandulenko | 2015-12-15 00:05:02 +0100 |
commit | 8ca14d1d642fce2617513fdc0c3223af2ab4e7e7 (patch) | |
tree | 191bf0157fbb79df4721e6094141db206dc41ffa | |
parent | 64f9c902ddf0c8294fd9e5f66cf96661eb12040b (diff) | |
download | scummvm-rg350-8ca14d1d642fce2617513fdc0c3223af2ab4e7e7.tar.gz scummvm-rg350-8ca14d1d642fce2617513fdc0c3223af2ab4e7e7.tar.bz2 scummvm-rg350-8ca14d1d642fce2617513fdc0c3223af2ab4e7e7.zip |
LAB: Initial code
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, µs); + anyTimeDiff(lastsecs, lastmicros, secs, micros, &secs, µs); + + 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, ®, ®); + + *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, µs); + 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(®s, 0, sizeof(regs)); + /* + regs.h.ah = 0x32; + regs.h.dl = counter+1; + int386(0x21, ®s, ®s); + if (regs.h.al == 0) + { + */ + regs.h.ah = 0x36; + regs.h.dl = counter + 1; + int386(0x21, ®s, ®s); + + 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, ®s, ®s); + + 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, µs); + + 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 *) ©, 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 */ |