Import 0.4.5
This commit is contained in:
parent
222984d851
commit
86baaa3a9a
|
@ -0,0 +1,139 @@
|
|||
* release 0.4.5
|
||||
- added low-pass filtering for in-game music
|
||||
- added support for 3DO background music (tunes/*.Cpc)
|
||||
- added protection screen for DOS SSI version
|
||||
- fixed ASC and CARTE cutscenes enablement
|
||||
- fixed loudness of sound effects and in-game music
|
||||
|
||||
* release 0.4.4
|
||||
- added auto-save
|
||||
- fixed graphical glitches with Macintosh data files
|
||||
|
||||
* release 0.4.3
|
||||
- added title and logo screens for Macintosh
|
||||
- fixed cutscene offsets with Macintosh data files
|
||||
|
||||
* release 0.4.2
|
||||
- added graphic borders (16:9 displays)
|
||||
- added detection for Macintosh AppleDouble
|
||||
- added language selection in title screen
|
||||
- added story texts for Macintosh
|
||||
|
||||
* release 0.4.1
|
||||
- added support for Macintosh sounds playback
|
||||
- improved graphics scalers performance
|
||||
- fixed palette glitches with .BNQ DOS data files
|
||||
|
||||
* release 0.4.0
|
||||
- added initial support for Macintosh data files (512x448 resolution)
|
||||
- added configuration file entries for disabled cutscenes
|
||||
- fixed screen shaking offset (level 2)
|
||||
|
||||
* release 0.3.7
|
||||
- added 'caillou-f.set' cutscene
|
||||
- added detection for 'fbdemofr.zip' DOS demo data files
|
||||
- fixed cutscene text offsets with Japanese language
|
||||
|
||||
* release 0.3.6
|
||||
- added cutscene music looping
|
||||
- added 'DEMO' to title menu
|
||||
- fixed potential crash with the 'walk through walls' glitch
|
||||
|
||||
* release 0.3.5
|
||||
- added Japanese in-game texts
|
||||
- added support for localized .TBN (PC-CD)
|
||||
|
||||
* release 0.3.4
|
||||
- added screenshot for SDL2
|
||||
- added support for external graphics scalers (xbrz, scale2x)
|
||||
- fixed keypress detection for fullscreen/windowed
|
||||
|
||||
* release 0.3.3
|
||||
- added configuration for disabling .SEQ playback
|
||||
- fixed some Amiga palette glitches
|
||||
- fixed protection screen for Amiga
|
||||
|
||||
* release 0.3.2
|
||||
- added support for DOS demo*.bin files
|
||||
- added detection for DOS SSI version
|
||||
- added compilation with SDL2
|
||||
|
||||
* release 0.3.1
|
||||
- added workarounds for cutscene glitches present in the game (espions, voyage)
|
||||
- fixed DOS credits sequence
|
||||
- fixed Amiga cutscene captions display
|
||||
- fixed Amiga 24px sprites
|
||||
|
||||
* release 0.3.0
|
||||
- added configuration file
|
||||
- added optional playback for disabled cutscenes (asc, metro, serrure)
|
||||
- added support for DOS demo data file (DEMO_UK.ABA)
|
||||
- set frame rate to 30Hz
|
||||
|
||||
* release 0.2.2
|
||||
- added support for level background music
|
||||
- added italian texts
|
||||
- fixed PC-CD SEQ cutscenes numbering
|
||||
- fixed several issues with Amiga data files
|
||||
|
||||
* release 0.2.1 (2011/03/15)
|
||||
- added music playback to PC-CD SEQ cutscenes
|
||||
- fixed some palette and sprite issues with Amiga data
|
||||
|
||||
* release 0.2.0 (2011/03/11)
|
||||
- added support for PC-CD SEQ cutscenes
|
||||
- added support for Amiga data files (experimental)
|
||||
- fixed minor sound glitches
|
||||
|
||||
* release 0.1.9 (2007/03/16)
|
||||
- fixed minor glitches in cutscenes
|
||||
- fixed several Conrad moves
|
||||
- fixed fast mode
|
||||
- made game version autodetection defaulting to English
|
||||
- added support for SegaCD speech files
|
||||
|
||||
* release 0.1.8 (2005/08/31)
|
||||
- fixed crash in MOD player
|
||||
- fixed minor glitch with in-game save switches
|
||||
|
||||
* release 0.1.7 (2005/08/24)
|
||||
- improved in-game menu
|
||||
- added autodetection for language of the game
|
||||
- added support for Amiga music files
|
||||
- added support for the protection screen (disabled by default)
|
||||
|
||||
* release 0.1.6 (2005/06/05)
|
||||
- added in-game menu
|
||||
- fixed remaining graphical glitches
|
||||
|
||||
* release 0.1.5 (2005/04/05)
|
||||
- added spanish and german versions support
|
||||
- added input keys recording
|
||||
- reduced memory usage
|
||||
|
||||
* release 0.2.0 (2005/04/02)
|
||||
- added screen shaking (level 2)
|
||||
- added support for Amiga music (experimental)
|
||||
- fixed screen refresh after teleportation
|
||||
- fixed bug in savestate restore
|
||||
|
||||
* release 0.1.3 (2005/02/15)
|
||||
- added dirty blocks rendering
|
||||
- added save/load states
|
||||
- fixed issues with level 2 cutscenes (subway maps, mission screens)
|
||||
- fixed glitch in continue/abort screen
|
||||
|
||||
* release 0.1.2 (2005/02/07)
|
||||
- added sound effects playback
|
||||
- added support for polygonal cutscenes
|
||||
- added support for final credits sequence
|
||||
- fixed instructions screen display in english version
|
||||
|
||||
* release 0.1.1 (2005/01/29)
|
||||
- added missing opcodes, game should now be completable
|
||||
- added scale2x and scale3x filters
|
||||
- enabled level switching
|
||||
- fixed several engine bugs
|
||||
|
||||
* release 0.1.0 (2005/01/23)
|
||||
- first public release
|
8
Makefile
8
Makefile
|
@ -9,12 +9,12 @@ ZLIB_LIBS := -lz
|
|||
|
||||
CXXFLAGS += -Wall -Wpedantic -MMD $(SDL_CFLAGS) -DUSE_MODPLUG -DUSE_STATIC_SCALER -DUSE_TREMOR -DUSE_ZLIB
|
||||
|
||||
SRCS = collision.cpp cutscene.cpp decode_mac.cpp dynlib.cpp file.cpp fs.cpp game.cpp graphics.cpp main.cpp \
|
||||
menu.cpp mixer.cpp mod_player.cpp ogg_player.cpp piege.cpp resource.cpp resource_aba.cpp \
|
||||
SRCS = collision.cpp cpc_player.cpp cutscene.cpp decode_mac.cpp dynlib.cpp file.cpp fs.cpp game.cpp graphics.cpp main.cpp \
|
||||
menu.cpp mixer.cpp mod_player.cpp ogg_player.cpp piege.cpp protection.cpp resource.cpp resource_aba.cpp \
|
||||
resource_mac.cpp scaler.cpp screenshot.cpp seq_player.cpp \
|
||||
sfx_player.cpp staticres.cpp systemstub_sdl.cpp unpack.cpp util.cpp video.cpp
|
||||
|
||||
SCALERS := scalers/scaler_nearest.cpp scalers/scaler_tv2x.cpp scalers/scaler_xbrz.cpp scalers/xbrz/xbrz.cpp
|
||||
SCALERS := scalers/scaler_nearest.cpp scalers/scaler_tv2x.cpp scalers/scaler_xbr.cpp
|
||||
|
||||
OBJS = $(SRCS:.cpp=.o) $(SCALERS:.cpp=.o)
|
||||
DEPS = $(SRCS:.cpp=.d) $(SCALERS:.cpp=.d)
|
||||
|
@ -25,6 +25,6 @@ rs: $(OBJS)
|
|||
$(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LIBS)
|
||||
|
||||
clean:
|
||||
rm -f *.o *.d
|
||||
rm -f $(OBJS) $(DEPS)
|
||||
|
||||
-include $(DEPS)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
|
||||
REminiscence README
|
||||
Release version: 0.4.4
|
||||
Release version: 0.4.5
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ Data Files:
|
|||
You will need the original files of the PC (DOS or CD), Amiga or Macintosh
|
||||
release. Support for Amiga and Macintosh is still experimental.
|
||||
|
||||
For the Macintosh release, the resource fork must dumped as a file named
|
||||
For the Macintosh release, the resource fork must be dumped as a file named
|
||||
'FLASHBACK.BIN' (MacBinary) or 'FLASHBACK.RSRC' (AppleDouble).
|
||||
|
||||
To hear music during polygonal cutscenes with the PC version, you need to copy
|
||||
|
@ -43,7 +43,7 @@ These paths can be changed using command line switches :
|
|||
--savepath=PATH Path to save files (default '.')
|
||||
--levelnum=NUM Level to start from (default '0')
|
||||
--fullscreen Fullscreen display
|
||||
--widescreen=MODE 16:9 display
|
||||
--widescreen=MODE 16:9 display (adjacent,mirror,blur,none)
|
||||
--scaler=NAME@X Graphics scaler (default 'scale@3')
|
||||
--language=LANG Language (fr,en,de,sp,it,jp)
|
||||
--autosave Save game state automatically
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "game.h"
|
||||
|
|
|
@ -0,0 +1,129 @@
|
|||
|
||||
#include "cpc_player.h"
|
||||
#include "mixer.h"
|
||||
#include "util.h"
|
||||
|
||||
static const char *_tunes[] = {
|
||||
"Options.Cpc",
|
||||
"Jungle.Cpc",
|
||||
"Subway.Cpc",
|
||||
"TVshow.Cpc",
|
||||
"City.Cpc",
|
||||
"Alien.Cpc"
|
||||
};
|
||||
|
||||
CpcPlayer::CpcPlayer(Mixer *mixer, FileSystem *fs)
|
||||
: _mix(mixer), _fs(fs) {
|
||||
}
|
||||
|
||||
CpcPlayer::~CpcPlayer() {
|
||||
}
|
||||
|
||||
bool CpcPlayer::playTrack(int num) {
|
||||
_compression[0] = 0;
|
||||
const int tuneNum = num - 2;
|
||||
if (tuneNum >= 0 && tuneNum < ARRAYSIZE(_tunes) && _f.open(_tunes[tuneNum], "rb", _fs)) {
|
||||
_pos = 0;
|
||||
_sampleL = _sampleR = 0;
|
||||
while (nextChunk()) {
|
||||
if (_compression[0]) {
|
||||
_restartPos = _nextPos;
|
||||
_mix->setPremixHook(mixCallback, this);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CpcPlayer::stopTrack() {
|
||||
_f.close();
|
||||
}
|
||||
|
||||
void CpcPlayer::pauseTrack() {
|
||||
_mix->setPremixHook(0, 0);
|
||||
}
|
||||
|
||||
void CpcPlayer::resumeTrack() {
|
||||
_mix->setPremixHook(mixCallback, this);
|
||||
}
|
||||
|
||||
bool CpcPlayer::nextChunk() {
|
||||
bool found = false;
|
||||
while (!_f.ioErr() && !found) {
|
||||
const uint32_t pos = _pos;
|
||||
char tag[4];
|
||||
_f.read(tag, sizeof(tag));
|
||||
const uint32_t len = _f.readUint32BE();
|
||||
_nextPos = pos + len;
|
||||
if (memcmp(tag, "SNDS", 4) == 0) {
|
||||
_f.readUint32BE();
|
||||
_f.readUint32BE();
|
||||
char type[4];
|
||||
_f.read(type, sizeof(type));
|
||||
if (memcmp(type, "SHDR", 4) == 0) {
|
||||
uint8_t buf[24];
|
||||
_f.read(buf, sizeof(buf));
|
||||
const uint32_t rate = _f.readUint32BE();
|
||||
const uint32_t channels = _f.readUint32BE();
|
||||
if (channels != 2 || rate != _mix->getSampleRate()) {
|
||||
warning("Unsupported CPC tune channels %d rate %d", channels, rate);
|
||||
break;
|
||||
}
|
||||
_f.read(_compression, sizeof(_compression) - 1);
|
||||
_compression[sizeof(_compression) - 1] = 0;
|
||||
if (strcmp(_compression, "SDX2") != 0) {
|
||||
warning("Unsupported CPC compression '%s'", _compression);
|
||||
break;
|
||||
}
|
||||
found = true;
|
||||
} else if (memcmp(type, "SSMP", 4) == 0) {
|
||||
_samplesLeft = _f.readUint32BE();
|
||||
found = true;
|
||||
break;
|
||||
} else {
|
||||
warning("Unhandled SNDS chunk '%c%c%c%c'", type[0], type[1], type[2], type[3]);
|
||||
}
|
||||
} else if (memcmp(tag, "SHDR", 4) == 0 || memcmp(tag, "FILL", 4) == 0 || memcmp(tag, "CTRL", 4) == 0) {
|
||||
// ignore
|
||||
} else {
|
||||
warning("Unhandled chunk '%c%c%c%c' size %d", tag[0], tag[1], tag[2], tag[3], len);
|
||||
}
|
||||
_f.seek(_nextPos);
|
||||
_pos = _nextPos;
|
||||
}
|
||||
return found;
|
||||
}
|
||||
|
||||
static int16_t decodeSDX2(int16_t prev, int8_t data) {
|
||||
const int sqr = data * ABS(data) * 2;
|
||||
return (data & 1) != 0 ? prev + sqr : sqr;
|
||||
}
|
||||
|
||||
int8_t CpcPlayer::readSampleData() {
|
||||
if (_samplesLeft <= 0) {
|
||||
_f.seek(_nextPos);
|
||||
_pos = _nextPos;
|
||||
if (!nextChunk()) {
|
||||
// rewind
|
||||
_f.seek(_restartPos);
|
||||
nextChunk();
|
||||
}
|
||||
}
|
||||
const int8_t data = _f.readByte();
|
||||
--_samplesLeft;
|
||||
return data;
|
||||
}
|
||||
|
||||
bool CpcPlayer::mix(int16_t *buf, int len) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
_sampleL = decodeSDX2(_sampleL, readSampleData());
|
||||
_sampleR = decodeSDX2(_sampleR, readSampleData());
|
||||
*buf++ = (_sampleL + _sampleR) / 2;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CpcPlayer::mixCallback(void *param, int16_t *buf, int len) {
|
||||
return ((CpcPlayer *)param)->mix(buf, len);
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
#ifndef CPC_PLAYER_H__
|
||||
#define CPC_PLAYER_H__
|
||||
|
||||
#include "intern.h"
|
||||
#include "file.h"
|
||||
|
||||
struct FileSystem;
|
||||
struct Mixer;
|
||||
|
||||
struct CpcPlayer {
|
||||
|
||||
Mixer *_mix;
|
||||
FileSystem *_fs;
|
||||
File _f;
|
||||
uint32_t _pos;
|
||||
uint32_t _nextPos;
|
||||
uint32_t _restartPos;
|
||||
char _compression[5];
|
||||
int _samplesLeft;
|
||||
int16_t _sampleL, _sampleR;
|
||||
|
||||
CpcPlayer(Mixer *mixer, FileSystem *fs);
|
||||
~CpcPlayer();
|
||||
|
||||
bool playTrack(int num);
|
||||
void stopTrack();
|
||||
void pauseTrack();
|
||||
void resumeTrack();
|
||||
|
||||
bool nextChunk();
|
||||
int8_t readSampleData();
|
||||
bool mix(int16_t *buf, int len);
|
||||
static bool mixCallback(void *param, int16_t *buf, int len);
|
||||
};
|
||||
|
||||
#endif
|
93
cutscene.cpp
93
cutscene.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
|
@ -94,6 +94,15 @@ void Cutscene::setPalette() {
|
|||
sin(330) table: 221, math:-127
|
||||
*/
|
||||
|
||||
/*
|
||||
a = rotation angle
|
||||
b = scale/distort vertically (180)
|
||||
c = scale/distort horizontally (90)
|
||||
|
||||
| x | cos_a sin_a | cos_b | cos_c * sin_b |
|
||||
| y | sin_a -cos_a | sin_c | 1 |
|
||||
*/
|
||||
|
||||
void Cutscene::setRotationTransform(uint16_t a, uint16_t b, uint16_t c) { // identity a:0 b:180 c:90
|
||||
const int16_t sin_a = SIN(a);
|
||||
const int16_t cos_a = COS(a);
|
||||
|
@ -101,10 +110,10 @@ void Cutscene::setRotationTransform(uint16_t a, uint16_t b, uint16_t c) { // ide
|
|||
const int16_t cos_c = COS(c);
|
||||
const int16_t sin_b = SIN(b);
|
||||
const int16_t cos_b = COS(b);
|
||||
_rotMat[0] /* .x1 */ = ((cos_a * cos_b) >> 8) - ((((cos_c * sin_a) >> 8) * sin_b) >> 8);
|
||||
_rotMat[1] /* .y1 */ = ((sin_a * cos_b) >> 8) + ((((cos_c * cos_a) >> 8) * sin_b) >> 8);
|
||||
_rotMat[2] /* .x2 */ = ( sin_c * sin_a) >> 8;
|
||||
_rotMat[3] /* .y2 */ = (-sin_c * cos_a) >> 8;
|
||||
_rotMat[0] = ((cos_a * cos_b) >> 8) - ((((cos_c * sin_a) >> 8) * sin_b) >> 8);
|
||||
_rotMat[1] = ((sin_a * cos_b) >> 8) + ((((cos_c * cos_a) >> 8) * sin_b) >> 8);
|
||||
_rotMat[2] = ( sin_c * sin_a) >> 8;
|
||||
_rotMat[3] = (-sin_c * cos_a) >> 8;
|
||||
}
|
||||
|
||||
static bool isNewLineChar(uint8_t chr, Resource *res) {
|
||||
|
@ -188,21 +197,20 @@ void Cutscene::swapLayers() {
|
|||
|
||||
void Cutscene::drawCreditsText() {
|
||||
if (_creditsSequence) {
|
||||
if (_textUnk2 != 0) {
|
||||
if (_varText == 0) {
|
||||
_textUnk2 = 0;
|
||||
if (_creditsKeepText != 0) {
|
||||
if (_creditsSlowText == 0) {
|
||||
_creditsKeepText = 0;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_creditsTextCounter <= 0) {
|
||||
uint8_t code = *_textCurPtr;
|
||||
const uint8_t code = *_textCurPtr;
|
||||
if (code == 0xFF) {
|
||||
_textBuf[0] = 0xA;
|
||||
} else if (code == 0xFE) {
|
||||
++_textCurPtr;
|
||||
code = *_textCurPtr++;
|
||||
_creditsTextCounter = code;
|
||||
_creditsTextCounter = *_textCurPtr++;
|
||||
} else if (code == 1) {
|
||||
++_textCurPtr;
|
||||
_creditsTextPosX = *_textCurPtr++;
|
||||
|
@ -211,8 +219,8 @@ void Cutscene::drawCreditsText() {
|
|||
_textCurBuf = _textBuf;
|
||||
_textBuf[0] = 0xA;
|
||||
++_textCurPtr;
|
||||
if (_varText != 0) {
|
||||
_textUnk2 = 0xFF;
|
||||
if (_creditsSlowText != 0) {
|
||||
_creditsKeepText = 0xFF;
|
||||
}
|
||||
} else {
|
||||
*_textCurBuf++ = code;
|
||||
|
@ -235,7 +243,6 @@ void Cutscene::drawProtectionShape(uint8_t shapeNum, int16_t zoom) {
|
|||
int16_t x = 0;
|
||||
int16_t y = 0;
|
||||
zoom += 512;
|
||||
setRotationTransform(0, 180, 90);
|
||||
|
||||
const uint8_t *shapeOffsetTable = _protectionShapeData + READ_BE_UINT16(_protectionShapeData + 0x02);
|
||||
const uint8_t *shapeDataTable = _protectionShapeData + READ_BE_UINT16(_protectionShapeData + 0x0E);
|
||||
|
@ -257,7 +264,7 @@ void Cutscene::drawProtectionShape(uint8_t shapeNum, int16_t zoom) {
|
|||
}
|
||||
_hasAlphaColor = (verticesOffset & 0x4000) != 0;
|
||||
_primitiveColor = 0xC0 + *shapeData++;
|
||||
drawShapeScaleRotate(p, zoom, dx, dy, x, y, 0, 0);
|
||||
drawShapeScale(p, zoom, dx, dy, x, y, 0, 0);
|
||||
++_shape_count;
|
||||
}
|
||||
}
|
||||
|
@ -269,7 +276,7 @@ void Cutscene::op_markCurPos() {
|
|||
_frameDelay = 5;
|
||||
setPalette();
|
||||
swapLayers();
|
||||
_varText = 0;
|
||||
_creditsSlowText = 0;
|
||||
}
|
||||
|
||||
void Cutscene::op_refreshScreen() {
|
||||
|
@ -277,7 +284,7 @@ void Cutscene::op_refreshScreen() {
|
|||
_clearScreen = fetchNextCmdByte();
|
||||
if (_clearScreen != 0) {
|
||||
swapLayers();
|
||||
_varText = 0;
|
||||
_creditsSlowText = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -286,7 +293,7 @@ void Cutscene::op_waitForSync() {
|
|||
if (_creditsSequence) {
|
||||
uint16_t n = fetchNextCmdByte() * 2;
|
||||
do {
|
||||
_varText = 0xFF;
|
||||
_creditsSlowText = 0xFF;
|
||||
_frameDelay = 3;
|
||||
if (_textBuf == _textCurBuf) {
|
||||
_creditsTextCounter = _res->isAmiga() ? 60 : 20;
|
||||
|
@ -296,7 +303,7 @@ void Cutscene::op_waitForSync() {
|
|||
setPalette();
|
||||
} while (--n);
|
||||
swapLayers();
|
||||
_varText = 0;
|
||||
_creditsSlowText = 0;
|
||||
} else {
|
||||
_frameDelay = fetchNextCmdByte() * 4;
|
||||
sync(); // XXX handle input
|
||||
|
@ -447,7 +454,7 @@ void Cutscene::op_refreshAll() {
|
|||
_frameDelay = 5;
|
||||
setPalette();
|
||||
swapLayers();
|
||||
_varText = 0xFF;
|
||||
_creditsSlowText = 0xFF;
|
||||
op_handleKeys();
|
||||
}
|
||||
|
||||
|
@ -859,7 +866,7 @@ void Cutscene::op_drawShapeScaleRotate() {
|
|||
|
||||
void Cutscene::op_drawCreditsText() {
|
||||
debug(DBG_CUT, "Cutscene::op_drawCreditsText()");
|
||||
_varText = 0xFF;
|
||||
_creditsSlowText = 0xFF;
|
||||
if (_textCurBuf == _textBuf) {
|
||||
++_creditsTextCounter;
|
||||
}
|
||||
|
@ -1009,11 +1016,13 @@ void Cutscene::mainLoop(uint16_t num) {
|
|||
|
||||
bool Cutscene::load(uint16_t cutName) {
|
||||
assert(cutName != 0xFFFF);
|
||||
const char *name = _namesTable[cutName & 0xFF];
|
||||
const char *name = _namesTableDOS[cutName & 0xFF];
|
||||
switch (_res->_type) {
|
||||
case kResourceTypeAmiga:
|
||||
if (strncmp(name, "INTRO", 5) == 0) {
|
||||
if (cutName == 7) {
|
||||
name = "INTRO";
|
||||
} else if (cutName == 10) {
|
||||
name = "SERRURE";
|
||||
}
|
||||
_res->load(name, Resource::OT_CMP);
|
||||
if (_id == 0x39 && _res->_lang != LANG_FR) {
|
||||
|
@ -1091,8 +1100,8 @@ void Cutscene::playCredits() {
|
|||
_textBuf[0] = 0xA;
|
||||
_textCurBuf = _textBuf;
|
||||
_creditsSequence = true;
|
||||
_varText = 0;
|
||||
_textUnk2 = 0;
|
||||
_creditsSlowText = 0;
|
||||
_creditsKeepText = 0;
|
||||
_creditsTextCounter = 0;
|
||||
_interrupted = false;
|
||||
const uint16_t *cut_seq = _creditsCutSeq;
|
||||
|
@ -1102,8 +1111,9 @@ void Cutscene::playCredits() {
|
|||
break;
|
||||
}
|
||||
prepare();
|
||||
uint16_t cutName = _offsetsTable[cut_id * 2 + 0];
|
||||
uint16_t cutOff = _offsetsTable[cut_id * 2 + 1];
|
||||
const uint16_t *offsets = _res->isAmiga() ? _offsetsTableAmiga : _offsetsTableDOS;
|
||||
uint16_t cutName = offsets[cut_id * 2 + 0];
|
||||
uint16_t cutOff = offsets[cut_id * 2 + 1];
|
||||
if (load(cutName)) {
|
||||
mainLoop(cutOff);
|
||||
unload();
|
||||
|
@ -1149,18 +1159,26 @@ void Cutscene::play() {
|
|||
debug(DBG_CUT, "Cutscene::play() _id=0x%X", _id);
|
||||
_creditsSequence = false;
|
||||
prepare();
|
||||
uint16_t cutName = _offsetsTable[_id * 2 + 0];
|
||||
uint16_t cutOff = _offsetsTable[_id * 2 + 1];
|
||||
const uint16_t *offsets = _res->isAmiga() ? _offsetsTableAmiga : _offsetsTableDOS;
|
||||
uint16_t cutName = offsets[_id * 2 + 0];
|
||||
uint16_t cutOff = offsets[_id * 2 + 1];
|
||||
if (cutName == 0xFFFF) {
|
||||
switch (_id) {
|
||||
case 3: // keys
|
||||
if (g_options.play_carte_cutscene) {
|
||||
cutName = 2; // CARTE
|
||||
}
|
||||
break;
|
||||
case 8: // save checkpoints
|
||||
break;
|
||||
case 19:
|
||||
if (g_options.play_serrure_cutscene) {
|
||||
cutName = 31; // SERRURE
|
||||
}
|
||||
break;
|
||||
case 22:
|
||||
case 23:
|
||||
case 24:
|
||||
case 22: // Level 2 fuse repaired
|
||||
case 23: // switches
|
||||
case 24: // Level 2 fuse is blown
|
||||
if (g_options.play_asc_cutscene) {
|
||||
cutName = 12; // ASC
|
||||
}
|
||||
|
@ -1171,6 +1189,11 @@ void Cutscene::play() {
|
|||
cutName = 14; // METRO
|
||||
}
|
||||
break;
|
||||
case 46: // Level 2 terminal card mission
|
||||
break;
|
||||
default:
|
||||
warning("Unknown cutscene %d", _id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_patchedOffsetsTable) {
|
||||
|
@ -1284,7 +1307,7 @@ void Cutscene::playSet(const uint8_t *p, int offset) {
|
|||
|
||||
offset = 10;
|
||||
const int frames = READ_BE_UINT16(p + offset); offset += 2;
|
||||
for (int i = 0; i < frames && !_stub->_pi.quit; ++i) {
|
||||
for (int i = 0; i < frames && !_stub->_pi.quit && !_interrupted; ++i) {
|
||||
const uint32_t timestamp = _stub->getTimeStamp();
|
||||
|
||||
memset(_page1, 0xC0, _vid->_layerSize);
|
||||
|
@ -1339,5 +1362,9 @@ void Cutscene::playSet(const uint8_t *p, int offset) {
|
|||
const int diff = 6 * TIMER_SLICE - (_stub->getTimeStamp() - timestamp);
|
||||
_stub->sleep((diff < 16) ? 16 : diff);
|
||||
_stub->processEvents();
|
||||
if (_stub->_pi.backspace) {
|
||||
_stub->_pi.backspace = false;
|
||||
_interrupted = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
13
cutscene.h
13
cutscene.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef CUTSCENE_H__
|
||||
|
@ -39,8 +39,9 @@ struct Cutscene {
|
|||
};
|
||||
|
||||
static const OpcodeStub _opcodeTable[];
|
||||
static const char *_namesTable[];
|
||||
static const uint16_t _offsetsTable[];
|
||||
static const char *_namesTableDOS[];
|
||||
static const uint16_t _offsetsTableDOS[];
|
||||
static const uint16_t _offsetsTableAmiga[];
|
||||
static const uint8_t _amigaDemoOffsetsTable[];
|
||||
static const uint8_t _ssiOffsetsTable[];
|
||||
static const uint16_t _cosTable[];
|
||||
|
@ -70,7 +71,7 @@ struct Cutscene {
|
|||
uint32_t _tstamp;
|
||||
uint8_t _frameDelay;
|
||||
bool _newPal;
|
||||
uint8_t _palBuf[0x20 * 2];
|
||||
uint8_t _palBuf[16 * sizeof(uint16_t) * 2];
|
||||
uint16_t _baseOffset;
|
||||
bool _creditsSequence;
|
||||
uint32_t _rotMat[4];
|
||||
|
@ -78,7 +79,6 @@ struct Cutscene {
|
|||
uint8_t _clearScreen;
|
||||
Point _vertices[0x80];
|
||||
bool _hasAlphaColor;
|
||||
uint8_t _varText;
|
||||
uint8_t _varKey;
|
||||
int16_t _shape_ix;
|
||||
int16_t _shape_iy;
|
||||
|
@ -97,7 +97,8 @@ struct Cutscene {
|
|||
uint8_t _textBuf[500];
|
||||
const uint8_t *_textCurPtr;
|
||||
uint8_t *_textCurBuf;
|
||||
uint8_t _textUnk2;
|
||||
uint8_t _creditsSlowText;
|
||||
uint8_t _creditsKeepText;
|
||||
uint8_t _creditsTextPosX;
|
||||
uint8_t _creditsTextPosY;
|
||||
int16_t _creditsTextCounter;
|
||||
|
|
141
decode_mac.cpp
141
decode_mac.cpp
|
@ -30,57 +30,64 @@ uint8_t *decodeLzss(File &f, uint32_t &decodedSize) {
|
|||
}
|
||||
|
||||
static void setPixel(int x, int y, int w, int h, uint8_t color, DecodeBuffer *buf) {
|
||||
buf->setPixel(buf, x, y, w, h, color);
|
||||
}
|
||||
|
||||
void decodeC103(const uint8_t *a3, int w, int h, DecodeBuffer *buf) {
|
||||
uint8_t d0;
|
||||
int d3 = 0;
|
||||
int d7 = 1;
|
||||
int d6 = 0;
|
||||
int d1 = 0;
|
||||
static const uint32_t d5 = 0xFFF;
|
||||
uint8_t a1[0x1000];
|
||||
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
assert(d6 >= 0);
|
||||
if (d6 == 0) {
|
||||
int carry = d7 & 1;
|
||||
d7 >>= 1;
|
||||
if (d7 == 0) {
|
||||
d7 = *a3++;
|
||||
const int extended_bit = carry ? 0x80 : 0;
|
||||
carry = d7 & 1;
|
||||
d7 = extended_bit | (d7 >> 1);
|
||||
}
|
||||
if (!carry) {
|
||||
d0 = *a3++;
|
||||
a1[d3] = d0;
|
||||
++d3;
|
||||
d3 &= d5;
|
||||
setPixel(x, y, w, h, d0, buf);
|
||||
continue;
|
||||
}
|
||||
d1 = READ_BE_UINT16(a3); a3 += 2;
|
||||
d6 = d1;
|
||||
d1 &= d5;
|
||||
++d1;
|
||||
d1 = (d3 - d1) & d5;
|
||||
d6 >>= 12;
|
||||
d6 += 3;
|
||||
}
|
||||
d0 = a1[d1++];
|
||||
d1 &= d5;
|
||||
a1[d3++] = d0;
|
||||
d3 &= d5;
|
||||
setPixel(x, y, w, h, d0, buf);
|
||||
--d6;
|
||||
y += buf->y;
|
||||
if (y >= 0 && y < buf->h) {
|
||||
if (buf->xflip) {
|
||||
x = w - 1 - x;
|
||||
}
|
||||
x += buf->x;
|
||||
if (x >= 0 && x < buf->w) {
|
||||
buf->setPixel(buf, x, y, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decodeC211(const uint8_t *a3, int w, int h, DecodeBuffer *buf) {
|
||||
void decodeC103(const uint8_t *src, int w, int h, DecodeBuffer *buf) {
|
||||
static const int kBits = 12;
|
||||
static const int kMask = (1 << kBits) - 1;
|
||||
int cursor = 0;
|
||||
int bits = 1;
|
||||
int count = 0;
|
||||
int offset = 0;
|
||||
uint8_t window[(1 << kBits)];
|
||||
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
if (count == 0) {
|
||||
int carry = bits & 1;
|
||||
bits >>= 1;
|
||||
if (bits == 0) {
|
||||
bits = *src++;
|
||||
if (carry) {
|
||||
bits |= 0x100;
|
||||
}
|
||||
carry = bits & 1;
|
||||
bits >>= 1;
|
||||
}
|
||||
if (!carry) {
|
||||
const uint8_t color = *src++;
|
||||
window[cursor] = color;
|
||||
++cursor;
|
||||
cursor &= kMask;
|
||||
setPixel(x, y, w, h, color, buf);
|
||||
continue;
|
||||
}
|
||||
offset = READ_BE_UINT16(src); src += 2;
|
||||
count = 3 + (offset >> 12);
|
||||
offset &= kMask;
|
||||
offset = (cursor - offset - 1) & kMask;
|
||||
}
|
||||
const uint8_t color = window[offset++];
|
||||
offset &= kMask;
|
||||
window[cursor++] = color;
|
||||
cursor &= kMask;
|
||||
setPixel(x, y, w, h, color, buf);
|
||||
--count;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void decodeC211(const uint8_t *src, int w, int h, DecodeBuffer *buf) {
|
||||
struct {
|
||||
const uint8_t *ptr;
|
||||
int repeatCount;
|
||||
|
@ -90,52 +97,48 @@ void decodeC211(const uint8_t *a3, int w, int h, DecodeBuffer *buf) {
|
|||
int sp = 0;
|
||||
|
||||
while (1) {
|
||||
uint8_t d0 = *a3++;
|
||||
if ((d0 & 0x80) != 0) {
|
||||
const uint8_t code = *src++;
|
||||
if ((code & 0x80) != 0) {
|
||||
++y;
|
||||
x = 0;
|
||||
}
|
||||
int d1 = d0 & 0x1F;
|
||||
if (d1 == 0) {
|
||||
d1 = READ_BE_UINT16(a3); a3 += 2;
|
||||
int count = code & 0x1F;
|
||||
if (count == 0) {
|
||||
count = READ_BE_UINT16(src); src += 2;
|
||||
}
|
||||
const int carry_set = (d0 & 0x40) != 0;
|
||||
d0 <<= 2;
|
||||
if (!carry_set) {
|
||||
if ((d0 & 0x80) == 0) {
|
||||
--d1;
|
||||
if (d1 == 0) {
|
||||
if ((code & 0x40) == 0) {
|
||||
if ((code & 0x20) == 0) {
|
||||
if (count == 1) {
|
||||
assert(sp > 0);
|
||||
--stack[sp - 1].repeatCount;
|
||||
if (stack[sp - 1].repeatCount >= 0) {
|
||||
a3 = stack[sp - 1].ptr;
|
||||
src = stack[sp - 1].ptr;
|
||||
} else {
|
||||
--sp;
|
||||
}
|
||||
} else {
|
||||
assert(sp < ARRAYSIZE(stack));
|
||||
stack[sp].ptr = a3;
|
||||
stack[sp].repeatCount = d1;
|
||||
stack[sp].ptr = src;
|
||||
stack[sp].repeatCount = count - 1;
|
||||
++sp;
|
||||
}
|
||||
} else {
|
||||
x += d1;
|
||||
x += count;
|
||||
}
|
||||
} else {
|
||||
if ((d0 & 0x80) == 0) {
|
||||
if (d1 == 1) {
|
||||
if ((code & 0x20) == 0) {
|
||||
if (count == 1) {
|
||||
return;
|
||||
}
|
||||
const uint8_t color = *a3++;
|
||||
for (int i = 0; i < d1; ++i) {
|
||||
const uint8_t color = *src++;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
setPixel(x++, y, w, h, color, buf);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < d1; ++i) {
|
||||
setPixel(x++, y, w, h, *a3++, buf);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
setPixel(x++, y, w, h, *src++, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ struct DecodeBuffer {
|
|||
int x, y;
|
||||
bool xflip;
|
||||
|
||||
void (*setPixel)(DecodeBuffer *buf, int src_x, int src_y, int src_w, int src_h, uint8_t color);
|
||||
void (*setPixel)(DecodeBuffer *buf, int x, int y, uint8_t color);
|
||||
void *dataPtr;
|
||||
};
|
||||
|
||||
|
|
25
file.cpp
25
file.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -324,6 +324,16 @@ void File::writeByte(uint8_t b) {
|
|||
write(&b, 1);
|
||||
}
|
||||
|
||||
void File::writeUint16LE(uint16_t n) {
|
||||
writeByte(n & 0xFF);
|
||||
writeByte(n >> 8);
|
||||
}
|
||||
|
||||
void File::writeUint32LE(uint32_t n) {
|
||||
writeUint16LE(n & 0xFFFF);
|
||||
writeUint16LE(n >> 16);
|
||||
}
|
||||
|
||||
void File::writeUint16BE(uint16_t n) {
|
||||
writeByte(n >> 8);
|
||||
writeByte(n & 0xFF);
|
||||
|
@ -333,3 +343,16 @@ void File::writeUint32BE(uint32_t n) {
|
|||
writeUint16BE(n >> 16);
|
||||
writeUint16BE(n & 0xFFFF);
|
||||
}
|
||||
|
||||
void dumpFile(const char *filename, const uint8_t *p, int size) {
|
||||
char path[MAXPATHLEN];
|
||||
snprintf(path, sizeof(path), "DUMP/%s", filename);
|
||||
FILE *fp = fopen(filename, "wb");
|
||||
if (fp) {
|
||||
const int count = fwrite(p, 1, size, fp);
|
||||
if (count != size) {
|
||||
warning("Failed to write %d bytes (expected %d)", count, size);
|
||||
}
|
||||
fclose(fp);
|
||||
}
|
||||
}
|
||||
|
|
6
file.h
6
file.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef FILE_H__
|
||||
|
@ -32,8 +32,12 @@ struct File {
|
|||
uint32_t readUint32BE();
|
||||
uint32_t write(const void *ptr, uint32_t size);
|
||||
void writeByte(uint8_t b);
|
||||
void writeUint16LE(uint16_t n);
|
||||
void writeUint32LE(uint32_t n);
|
||||
void writeUint16BE(uint16_t n);
|
||||
void writeUint32BE(uint32_t n);
|
||||
};
|
||||
|
||||
void dumpFile(const char *filename, const uint8_t *p, int size);
|
||||
|
||||
#endif // FILE_H__
|
||||
|
|
2
fs.cpp
2
fs.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
2
fs.h
2
fs.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef FS_H__
|
||||
|
|
273
game.cpp
273
game.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include <time.h>
|
||||
|
@ -16,7 +16,7 @@
|
|||
|
||||
Game::Game(SystemStub *stub, FileSystem *fs, const char *savePath, int level, ResourceType ver, Language lang, WidescreenMode widescreenMode, bool autoSave)
|
||||
: _cut(&_res, stub, &_vid), _menu(&_res, stub, &_vid),
|
||||
_mix(fs, stub), _res(fs, ver, lang), _seq(stub, &_mix), _vid(&_res, stub),
|
||||
_mix(fs, stub), _res(fs, ver, lang), _seq(stub, &_mix), _vid(&_res, stub, widescreenMode),
|
||||
_stub(stub), _fs(fs), _savePath(savePath) {
|
||||
_stateSlot = 1;
|
||||
_inp_demPos = 0;
|
||||
|
@ -55,10 +55,11 @@ void Game::run() {
|
|||
break;
|
||||
}
|
||||
|
||||
if (!g_options.bypass_protection) {
|
||||
while (!handleProtectionScreen());
|
||||
if (_stub->_pi.quit) {
|
||||
return;
|
||||
if (!g_options.bypass_protection && !g_options.use_words_protection && !_res.isMac()) {
|
||||
while (!handleProtectionScreenShape()) {
|
||||
if (_stub->_pi.quit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,6 +95,14 @@ void Game::run() {
|
|||
break;
|
||||
}
|
||||
|
||||
if (!g_options.bypass_protection && g_options.use_words_protection && _res.isDOS()) {
|
||||
while (!handleProtectionScreenWords()) {
|
||||
if (_stub->_pi.quit) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool presentMenu = ((_res._type != kResourceTypeDOS) || _res.fileExists("MENU1.MAP"));
|
||||
while (!_stub->_pi.quit) {
|
||||
if (presentMenu) {
|
||||
|
@ -132,9 +141,12 @@ void Game::run() {
|
|||
displayTitleScreenMac(Menu::kMacTitleScreen_Flashback);
|
||||
break;
|
||||
}
|
||||
if (_stub->_pi.quit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.quit) {
|
||||
break;
|
||||
}
|
||||
if (_stub->hasWidescreen()) {
|
||||
_stub->clearWidescreen();
|
||||
}
|
||||
if (_currentLevel == 7) {
|
||||
_vid.fadeOut();
|
||||
|
@ -166,11 +178,6 @@ void Game::run() {
|
|||
_stub->_pi.enter = false;
|
||||
_stub->_pi.space = false;
|
||||
_stub->_pi.shift = false;
|
||||
// clear widescreen borders
|
||||
if (_stub->hasWidescreen()) {
|
||||
_stub->copyRectLeftBorder(_vid._w, _vid._h, 0);
|
||||
_stub->copyRectRightBorder(_vid._w, _vid._h, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,6 +205,7 @@ void Game::displayTitleScreenAmiga() {
|
|||
Color c = Video::AMIGA_convertColor(kAmigaColors[i]);
|
||||
_stub->setPaletteEntry(i, &c);
|
||||
}
|
||||
_vid.setTextPalette();
|
||||
_stub->setScreenSize(kW, kH);
|
||||
// fill with black
|
||||
_stub->copyRect(0, 0, kW, kH, buf, kW);
|
||||
|
@ -210,6 +218,32 @@ void Game::displayTitleScreenAmiga() {
|
|||
_stub->copyRect(0, y, kW, h * 2, buf, kW);
|
||||
_stub->updateScreen(0);
|
||||
h += 2;
|
||||
} else {
|
||||
static const uint8_t selectedColor = 0xE4;
|
||||
static const uint8_t defaultColor = 0xE8;
|
||||
for (int i = 0; i < 7; ++i) {
|
||||
const char *str = Menu::_levelNames[i];
|
||||
const uint8_t color = (_currentLevel == i) ? selectedColor : defaultColor;
|
||||
const int x = 24;
|
||||
const int y = 24 + i * 16;
|
||||
for (int j = 0; str[j]; ++j) {
|
||||
_vid.AMIGA_drawStringChar(buf, kW, x + j * Video::CHAR_W, y, _res._fnt, color, str[j]);
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.dirMask & PlayerInput::DIR_UP) {
|
||||
_stub->_pi.dirMask &= ~PlayerInput::DIR_UP;
|
||||
if (_currentLevel > 0) {
|
||||
--_currentLevel;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.dirMask & PlayerInput::DIR_DOWN) {
|
||||
_stub->_pi.dirMask &= ~PlayerInput::DIR_DOWN;
|
||||
if (_currentLevel < 6) {
|
||||
++_currentLevel;
|
||||
}
|
||||
}
|
||||
_stub->copyRect(0, 0, kW, kH, buf, kW);
|
||||
_stub->updateScreen(0);
|
||||
}
|
||||
_stub->processEvents();
|
||||
if (_stub->_pi.quit) {
|
||||
|
@ -249,7 +283,7 @@ void Game::displayTitleScreenMac(int num) {
|
|||
buf.h = _vid._h;
|
||||
buf.x = (_vid._w - w) / 2;
|
||||
buf.y = (_vid._h - h) / 2;
|
||||
buf.setPixel = Video::MAC_drawBuffer;
|
||||
buf.setPixel = Video::MAC_setPixel;
|
||||
memset(_vid._frontLayer, 0, _vid._layerSize);
|
||||
_res.MAC_loadTitleImage(num, &buf);
|
||||
for (int i = 0; i < 12; ++i) {
|
||||
|
@ -444,6 +478,9 @@ void Game::playCutscene(int id) {
|
|||
_cut._id = id;
|
||||
}
|
||||
if (_cut._id != 0xFFFF) {
|
||||
if (_stub->hasWidescreen()) {
|
||||
_stub->enableWidescreen(false);
|
||||
}
|
||||
_mix.stopMusic();
|
||||
if (_res._hasSeqData) {
|
||||
int num = 0;
|
||||
|
@ -520,6 +557,9 @@ void Game::playCutscene(int id) {
|
|||
_cut.playCredits();
|
||||
}
|
||||
_mix.stopMusic();
|
||||
if (_stub->hasWidescreen()) {
|
||||
_stub->enableWidescreen(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -566,8 +606,7 @@ void Game::drawCurrentInventoryItem() {
|
|||
|
||||
void Game::showFinalScore() {
|
||||
if (_stub->hasWidescreen()) {
|
||||
_stub->copyRectLeftBorder(_vid._w, _vid._h, 0);
|
||||
_stub->copyRectRightBorder(_vid._w, _vid._h, 0);
|
||||
_stub->clearWidescreen();
|
||||
}
|
||||
playCutscene(0x49);
|
||||
char buf[50];
|
||||
|
@ -673,7 +712,8 @@ bool Game::handleConfigPanel() {
|
|||
_menu.drawString(_res.getMenuString(LocaleData::LI_19_ABORT_GAME), y + 4, 9, colors[1]);
|
||||
_menu.drawString(_res.getMenuString(LocaleData::LI_20_LOAD_GAME), y + 6, 9, colors[2]);
|
||||
_menu.drawString(_res.getMenuString(LocaleData::LI_21_SAVE_GAME), y + 8, 9, colors[3]);
|
||||
char buf[30];
|
||||
_vid.fillRect(Video::CHAR_W * (x + 1), Video::CHAR_H * (y + 10), Video::CHAR_W * (w - 2), Video::CHAR_H, 0xE2);
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%s < %02d >", _res.getMenuString(LocaleData::LI_22_SAVE_SLOT), _stateSlot);
|
||||
_menu.drawString(buf, y + 10, 9, 1);
|
||||
|
||||
|
@ -730,8 +770,7 @@ bool Game::handleConfigPanel() {
|
|||
|
||||
bool Game::handleContinueAbort() {
|
||||
if (_stub->hasWidescreen()) {
|
||||
_stub->copyRectLeftBorder(_vid._w, _vid._h, 0);
|
||||
_stub->copyRectRightBorder(_vid._w, _vid._h, 0);
|
||||
_stub->clearWidescreen();
|
||||
}
|
||||
playCutscene(0x48);
|
||||
int timeout = 100;
|
||||
|
@ -799,87 +838,6 @@ bool Game::handleContinueAbort() {
|
|||
return false;
|
||||
}
|
||||
|
||||
bool Game::handleProtectionScreen() {
|
||||
bool valid = true;
|
||||
_cut.prepare();
|
||||
const int palOffset = _res.isAmiga() ? 32 : 0;
|
||||
_cut.copyPalette(_protectionPal + palOffset, 0);
|
||||
|
||||
_cut.updatePalette();
|
||||
_cut._gfx.setClippingRect(64, 48, 128, 128);
|
||||
|
||||
_menu._charVar1 = 0xE0;
|
||||
_menu._charVar2 = 0xEF;
|
||||
_menu._charVar4 = 0xE5;
|
||||
_menu._charVar5 = 0xE2;
|
||||
|
||||
int shapeNum = getRandomNumber() % 30;
|
||||
for (int16_t zoom = 2000; zoom != 0; zoom -= 100) {
|
||||
_cut.drawProtectionShape(shapeNum, zoom);
|
||||
_stub->copyRect(0, 0, _vid._w, _vid._h, _vid._tempLayer, _vid._w);
|
||||
_stub->updateScreen(0);
|
||||
_stub->sleep(30);
|
||||
}
|
||||
int codeNum = getRandomNumber() % 5;
|
||||
_cut.drawProtectionShape(shapeNum, 1);
|
||||
_vid.setTextPalette();
|
||||
char codeText[7];
|
||||
int len = 0;
|
||||
do {
|
||||
codeText[len] = '\0';
|
||||
memcpy(_vid._frontLayer, _vid._tempLayer, _vid._layerSize);
|
||||
_vid.drawString("PROTECTION", 11 * Video::CHAR_W, 2 * Video::CHAR_H, _menu._charVar2);
|
||||
char buf[20];
|
||||
snprintf(buf, sizeof(buf), "CODE %d : %s", codeNum + 1, codeText);
|
||||
_vid.drawString(buf, 8 * Video::CHAR_W, 23 * Video::CHAR_H, _menu._charVar2);
|
||||
_vid.updateScreen();
|
||||
_stub->sleep(50);
|
||||
_stub->processEvents();
|
||||
char c = _stub->_pi.lastChar;
|
||||
if (c != 0) {
|
||||
_stub->_pi.lastChar = 0;
|
||||
if (len < 6) {
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
c &= ~0x20;
|
||||
}
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
|
||||
codeText[len] = c;
|
||||
++len;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.backspace) {
|
||||
_stub->_pi.backspace = false;
|
||||
if (len > 0) {
|
||||
--len;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.enter) {
|
||||
_stub->_pi.enter = false;
|
||||
if (len > 0) {
|
||||
const uint8_t *p = _protectionCodeData + shapeNum * 0x1E + codeNum * 6;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
uint8_t r = 0;
|
||||
uint8_t ch = codeText[i];
|
||||
for (int b = 0; b < 8; ++b) {
|
||||
if (ch & (1 << b)) {
|
||||
r |= (1 << (7 - b));
|
||||
}
|
||||
}
|
||||
r ^= 0x55;
|
||||
if (r != *p++) {
|
||||
valid = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!_stub->_pi.quit);
|
||||
_vid.fadeOut();
|
||||
return valid;
|
||||
}
|
||||
|
||||
void Game::printLevelCode() {
|
||||
if (_printLevelCodeCounter != 0) {
|
||||
--_printLevelCodeCounter;
|
||||
|
@ -1006,22 +964,23 @@ void Game::drawStoryTexts() {
|
|||
yPos += 8;
|
||||
}
|
||||
}
|
||||
MixerChunk chunk;
|
||||
_res.load_VCE(_textToDisplay, textSpeechSegment++, &chunk.data, &chunk.len);
|
||||
if (chunk.data) {
|
||||
_mix.play(&chunk, 32000, Mixer::MAX_VOLUME);
|
||||
uint8_t *voiceSegmentData = 0;
|
||||
uint32_t voiceSegmentLen = 0;
|
||||
_res.load_VCE(_textToDisplay, textSpeechSegment++, &voiceSegmentData, &voiceSegmentLen);
|
||||
if (voiceSegmentData) {
|
||||
_mix.play(voiceSegmentData, voiceSegmentLen, 32000, Mixer::MAX_VOLUME);
|
||||
}
|
||||
_vid.updateScreen();
|
||||
while (!_stub->_pi.backspace && !_stub->_pi.quit) {
|
||||
if (chunk.data && !_mix.isPlaying(&chunk)) {
|
||||
if (voiceSegmentData && !_mix.isPlaying(voiceSegmentData)) {
|
||||
break;
|
||||
}
|
||||
inp_update();
|
||||
_stub->sleep(80);
|
||||
}
|
||||
if (chunk.data) {
|
||||
if (voiceSegmentData) {
|
||||
_mix.stopAll();
|
||||
free(chunk.data);
|
||||
free(voiceSegmentData);
|
||||
}
|
||||
_stub->_pi.backspace = false;
|
||||
if (_res._type == kResourceTypeMac) {
|
||||
|
@ -1220,7 +1179,7 @@ void Game::drawAnimBuffer(uint8_t stateNum, AnimBufferState *state) {
|
|||
break;
|
||||
case kResourceTypeDOS:
|
||||
if (!(state->dataPtr[-2] & 0x80)) {
|
||||
decodeCharacterFrame(state->dataPtr, _res._scratchBuffer);
|
||||
_vid.PC_decodeSpm(state->dataPtr, _res._scratchBuffer);
|
||||
drawCharacter(_res._scratchBuffer, state->x, state->y, state->h, state->w, pge->flags);
|
||||
} else {
|
||||
drawCharacter(state->dataPtr, state->x, state->y, state->h, state->w, pge->flags);
|
||||
|
@ -1398,39 +1357,6 @@ void Game::drawObjectFrame(const uint8_t *bankDataPtr, const uint8_t *dataPtr, i
|
|||
_vid.markBlockAsDirty(sprite_x, sprite_y, sprite_clipped_w, sprite_clipped_h, _vid._layerScale);
|
||||
}
|
||||
|
||||
void Game::decodeCharacterFrame(const uint8_t *dataPtr, uint8_t *dstPtr) {
|
||||
int n = READ_BE_UINT16(dataPtr); dataPtr += 2;
|
||||
uint16_t len = n * 2;
|
||||
uint8_t *dst = dstPtr + 0x400;
|
||||
while (n--) {
|
||||
uint8_t c = *dataPtr++;
|
||||
dst[0] = (c & 0xF0) >> 4;
|
||||
dst[1] = (c & 0x0F) >> 0;
|
||||
dst += 2;
|
||||
}
|
||||
dst = dstPtr;
|
||||
const uint8_t *src = dstPtr + 0x400;
|
||||
do {
|
||||
uint8_t c1 = *src++;
|
||||
if (c1 == 0xF) {
|
||||
uint8_t c2 = *src++;
|
||||
uint16_t c3 = *src++;
|
||||
if (c2 == 0xF) {
|
||||
c1 = *src++;
|
||||
c2 = *src++;
|
||||
c3 = (c3 << 4) | c1;
|
||||
len -= 2;
|
||||
}
|
||||
memset(dst, c2, c3 + 4);
|
||||
dst += c3 + 4;
|
||||
len -= 3;
|
||||
} else {
|
||||
*dst++ = c1;
|
||||
--len;
|
||||
}
|
||||
} while (len != 0);
|
||||
}
|
||||
|
||||
void Game::drawCharacter(const uint8_t *dataPtr, int16_t pos_x, int16_t pos_y, uint8_t a, uint8_t b, uint8_t flags) {
|
||||
debug(DBG_GAME, "Game::drawCharacter(%p, %d, %d, 0x%X, 0x%X, 0x%X)", dataPtr, pos_x, pos_y, a, b, flags);
|
||||
bool var16 = false; // sprite_mirror_y
|
||||
|
@ -1604,6 +1530,7 @@ bool Game::hasLevelMap(int level, int room) const {
|
|||
|
||||
void Game::loadLevelMap() {
|
||||
debug(DBG_GAME, "Game::loadLevelMap() room=%d", _currentRoom);
|
||||
bool widescreenUpdated = false;
|
||||
_currentIcon = 0xFF;
|
||||
switch (_res._type) {
|
||||
case kResourceTypeAmiga:
|
||||
|
@ -1637,17 +1564,18 @@ void Game::loadLevelMap() {
|
|||
const int leftRoom = _res._ctData[CT_LEFT_ROOM + _currentRoom];
|
||||
if (leftRoom > 0 && hasLevelMap(_currentLevel, leftRoom)) {
|
||||
_vid.PC_decodeMap(_currentLevel, leftRoom);
|
||||
_stub->copyRectLeftBorder(Video::GAMESCREEN_W, Video::GAMESCREEN_H, _vid._backLayer);
|
||||
_stub->copyWidescreenLeft(Video::GAMESCREEN_W, Video::GAMESCREEN_H, _vid._backLayer);
|
||||
} else {
|
||||
_stub->copyRectLeftBorder(Video::GAMESCREEN_W, Video::GAMESCREEN_H, 0);
|
||||
_stub->copyWidescreenLeft(Video::GAMESCREEN_W, Video::GAMESCREEN_H, 0);
|
||||
}
|
||||
const int rightRoom = _res._ctData[CT_RIGHT_ROOM + _currentRoom];
|
||||
if (rightRoom > 0 && hasLevelMap(_currentLevel, rightRoom)) {
|
||||
_vid.PC_decodeMap(_currentLevel, rightRoom);
|
||||
_stub->copyRectRightBorder(Video::GAMESCREEN_W, Video::GAMESCREEN_H, _vid._backLayer);
|
||||
_stub->copyWidescreenRight(Video::GAMESCREEN_W, Video::GAMESCREEN_H, _vid._backLayer);
|
||||
} else {
|
||||
_stub->copyRectRightBorder(Video::GAMESCREEN_W, Video::GAMESCREEN_H, 0);
|
||||
_stub->copyWidescreenRight(Video::GAMESCREEN_W, Video::GAMESCREEN_H, 0);
|
||||
}
|
||||
widescreenUpdated = true;
|
||||
}
|
||||
_vid.PC_decodeMap(_currentLevel, _currentRoom);
|
||||
break;
|
||||
|
@ -1656,23 +1584,24 @@ void Game::loadLevelMap() {
|
|||
const int leftRoom = _res._ctData[CT_LEFT_ROOM + _currentRoom];
|
||||
if (leftRoom > 0 && hasLevelMap(_currentLevel, leftRoom)) {
|
||||
_vid.MAC_decodeMap(_currentLevel, leftRoom);
|
||||
_stub->copyRectLeftBorder(_vid._w, _vid._h, _vid._backLayer);
|
||||
_stub->copyWidescreenLeft(_vid._w, _vid._h, _vid._backLayer);
|
||||
} else {
|
||||
_stub->copyRectLeftBorder(_vid._w, _vid._h, 0);
|
||||
_stub->copyWidescreenLeft(_vid._w, _vid._h, 0);
|
||||
}
|
||||
const int rightRoom = _res._ctData[CT_RIGHT_ROOM + _currentRoom];
|
||||
if (rightRoom > 0 && hasLevelMap(_currentLevel, rightRoom)) {
|
||||
_vid.MAC_decodeMap(_currentLevel, rightRoom);
|
||||
_stub->copyRectRightBorder(_vid._w, _vid._h, _vid._backLayer);
|
||||
_stub->copyWidescreenRight(_vid._w, _vid._h, _vid._backLayer);
|
||||
} else {
|
||||
_stub->copyRectRightBorder(_vid._w, _vid._h, 0);
|
||||
_stub->copyWidescreenRight(_vid._w, _vid._h, 0);
|
||||
}
|
||||
widescreenUpdated = true;
|
||||
}
|
||||
_vid.MAC_decodeMap(_currentLevel, _currentRoom);
|
||||
break;
|
||||
}
|
||||
if (_stub->hasWidescreen() && _widescreenMode == kWidescreenMirrorRoom) {
|
||||
_stub->copyRectMirrorBorders(_vid._w, _vid._h, _vid._backLayer);
|
||||
if (!widescreenUpdated) {
|
||||
_vid.updateWidescreen();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1737,7 +1666,7 @@ void Game::loadLevelData() {
|
|||
_res.load(lvl->name, Resource::OT_CT);
|
||||
_res.load(lvl->name, Resource::OT_PAL);
|
||||
_res.load(lvl->name, Resource::OT_RP);
|
||||
if (_res._isDemo || g_options.use_tiledata) { // use .BNQ/.LEV/(.SGD) instead of .MAP (PC demo)
|
||||
if (_res._isDemo || g_options.use_tile_data) { // use .BNQ/.LEV/(.SGD) instead of .MAP (PC demo)
|
||||
if (_currentLevel == 0) {
|
||||
_res.load(lvl->name, Resource::OT_SGD);
|
||||
}
|
||||
|
@ -1858,18 +1787,22 @@ void Game::drawIcon(uint8_t iconNum, int16_t x, int16_t y, uint8_t colMask) {
|
|||
_vid.markBlockAsDirty(x, y, 16, 16, _vid._layerScale);
|
||||
}
|
||||
|
||||
void Game::playSound(uint8_t sfxId, uint8_t softVol) {
|
||||
if (sfxId < _res._numSfx) {
|
||||
SoundFx *sfx = &_res._sfxList[sfxId];
|
||||
void Game::playSound(uint8_t num, uint8_t softVol) {
|
||||
if (num < _res._numSfx) {
|
||||
SoundFx *sfx = &_res._sfxList[num];
|
||||
if (sfx->data) {
|
||||
MixerChunk mc;
|
||||
mc.data = sfx->data;
|
||||
mc.len = sfx->len;
|
||||
_mix.play(&mc, sfx->freq, Mixer::MAX_VOLUME >> softVol);
|
||||
const int volume = Mixer::MAX_VOLUME >> (2 * softVol);
|
||||
_mix.play(sfx->data, sfx->len, sfx->freq, volume);
|
||||
}
|
||||
} else {
|
||||
} else if (num == 66) {
|
||||
// open/close inventory (DOS)
|
||||
} else if (num >= 68 && num <= 75) {
|
||||
// in-game music
|
||||
_mix.playMusic(sfxId);
|
||||
_mix.playMusic(num);
|
||||
} else if (num == 77) {
|
||||
// triggered when Conrad reaches a platform
|
||||
} else {
|
||||
warning("Unknown sound num %d", num);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1918,19 +1851,13 @@ void Game::handleInventory() {
|
|||
case kResourceTypeAmiga:
|
||||
case kResourceTypeDOS: {
|
||||
// draw inventory background
|
||||
int icon_h = 5;
|
||||
int icon_y = 140;
|
||||
int icon_num = 31;
|
||||
do {
|
||||
int icon_x = 56;
|
||||
int icon_w = 9;
|
||||
do {
|
||||
drawIcon(icon_num, icon_x, icon_y, 0xF);
|
||||
for (int y = 140; y < 140 + 5 * icon_spr_h; y += icon_spr_h) {
|
||||
for (int x = 56; x < 56 + 9 * icon_spr_w; x += icon_spr_w) {
|
||||
drawIcon(icon_num, x, y, 0xF);
|
||||
++icon_num;
|
||||
icon_x += icon_spr_w;
|
||||
} while (--icon_w);
|
||||
icon_y += icon_spr_h;
|
||||
} while (--icon_h);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_res._type == kResourceTypeAmiga) {
|
||||
// draw outline rectangle
|
||||
|
|
12
game.h
12
game.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef GAME_H__
|
||||
|
@ -28,7 +28,7 @@ struct Game {
|
|||
enum {
|
||||
kIngameSaveSlot = 0,
|
||||
kAutoSaveSlot = 255,
|
||||
kAutoSaveIntervalMs = 30 * 1000
|
||||
kAutoSaveIntervalMs = 120 * 1000
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -54,6 +54,9 @@ struct Game {
|
|||
static const pge_OpcodeProc _pge_opcodeTable[];
|
||||
static const uint8_t _pge_modKeysTable[];
|
||||
static const uint8_t _protectionCodeData[];
|
||||
static const uint8_t _protectionWordData[];
|
||||
static const uint8_t _protectionNumberDataAmiga[];
|
||||
static const uint8_t _protectionCodeDataAmiga[];
|
||||
static const uint8_t _protectionPal[];
|
||||
|
||||
Cutscene _cut;
|
||||
|
@ -115,7 +118,6 @@ struct Game {
|
|||
void showFinalScore();
|
||||
bool handleConfigPanel();
|
||||
bool handleContinueAbort();
|
||||
bool handleProtectionScreen();
|
||||
void printSaveStateCompleted();
|
||||
void drawLevelTexts();
|
||||
void drawStoryTexts();
|
||||
|
@ -127,7 +129,6 @@ struct Game {
|
|||
void drawPiege(AnimBufferState *state);
|
||||
void drawObject(const uint8_t *dataPtr, int16_t x, int16_t y, uint8_t flags);
|
||||
void drawObjectFrame(const uint8_t *bankDataPtr, const uint8_t *dataPtr, int16_t x, int16_t y, uint8_t flags);
|
||||
void decodeCharacterFrame(const uint8_t *dataPtr, uint8_t *dstPtr);
|
||||
void drawCharacter(const uint8_t *dataPtr, int16_t x, int16_t y, uint8_t a, uint8_t b, uint8_t flags);
|
||||
int loadMonsterSprites(LivePGE *pge);
|
||||
void playSound(uint8_t sfxId, uint8_t softVol);
|
||||
|
@ -135,6 +136,9 @@ struct Game {
|
|||
void changeLevel();
|
||||
void handleInventory();
|
||||
|
||||
// protection
|
||||
bool handleProtectionScreenShape();
|
||||
bool handleProtectionScreenWords();
|
||||
|
||||
// pieges
|
||||
bool _pge_playAnimSound;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "graphics.h"
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef GRAPHICS_H__
|
||||
|
|
25
intern.h
25
intern.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef INTERN_H__
|
||||
|
@ -46,6 +46,17 @@ inline int16_t ADDC_S16(int a, int b) {
|
|||
return a;
|
||||
}
|
||||
|
||||
inline int16_t S8_to_S16(int a) {
|
||||
if (a < -128) {
|
||||
return -32768;
|
||||
} else if (a > 127) {
|
||||
return 32767;
|
||||
} else {
|
||||
const uint8_t u8 = (a ^ 0x80);
|
||||
return ((u8 << 8) | u8) - 32768;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline void SWAP(T &a, T &b) {
|
||||
T tmp = a;
|
||||
|
@ -106,6 +117,7 @@ enum WidescreenMode {
|
|||
kWidescreenNone,
|
||||
kWidescreenAdjacentRooms,
|
||||
kWidescreenMirrorRoom,
|
||||
kWidescreenBlur,
|
||||
};
|
||||
|
||||
struct Options {
|
||||
|
@ -113,13 +125,17 @@ struct Options {
|
|||
bool enable_password_menu;
|
||||
bool enable_language_selection;
|
||||
bool fade_out_palette;
|
||||
bool use_tiledata;
|
||||
bool use_tile_data;
|
||||
bool use_text_cutscenes;
|
||||
bool use_seq_cutscenes;
|
||||
bool use_words_protection;
|
||||
bool use_white_tshirt;
|
||||
bool play_asc_cutscene;
|
||||
bool play_caillou_cutscene;
|
||||
bool play_metro_cutscene;
|
||||
bool play_serrure_cutscene;
|
||||
bool play_carte_cutscene;
|
||||
bool play_gamesaved_sound;
|
||||
};
|
||||
|
||||
struct Color {
|
||||
|
@ -155,7 +171,7 @@ struct InitPGE {
|
|||
int16_t pos_y;
|
||||
uint16_t obj_node_number;
|
||||
uint16_t life;
|
||||
int16_t counter_values[4];
|
||||
int16_t counter_values[4]; // messages
|
||||
uint8_t object_type;
|
||||
uint8_t init_room;
|
||||
uint8_t room_location;
|
||||
|
@ -177,7 +193,7 @@ struct LivePGE {
|
|||
uint8_t anim_seq;
|
||||
uint8_t room_location;
|
||||
int16_t life;
|
||||
int16_t counter_value;
|
||||
int16_t counter_value; // msg
|
||||
uint8_t collision_slot;
|
||||
uint8_t next_inventory_PGE;
|
||||
uint8_t current_inventory_PGE;
|
||||
|
@ -267,6 +283,7 @@ struct SoundFx {
|
|||
uint16_t len;
|
||||
uint16_t freq;
|
||||
uint8_t *data;
|
||||
int8_t peak;
|
||||
};
|
||||
|
||||
extern Options g_options;
|
||||
|
|
26
main.cpp
26
main.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include <SDL.h>
|
||||
|
@ -22,7 +22,7 @@ static const char *USAGE =
|
|||
" --savepath=PATH Path to save files (default '.')\n"
|
||||
" --levelnum=NUM Start to level, bypass introduction\n"
|
||||
" --fullscreen Fullscreen display\n"
|
||||
" --widescreen=MODE 16:9 display\n"
|
||||
" --widescreen=MODE 16:9 display (adjacent,mirror,blur,none)\n"
|
||||
" --scaler=NAME@X Graphics scaler (default 'scale@3')\n"
|
||||
" --language=LANG Language (fr,en,de,sp,it,jp)\n"
|
||||
" --autosave Save game state automatically\n"
|
||||
|
@ -36,6 +36,7 @@ static int detectVersion(FileSystem *fs) {
|
|||
} table[] = {
|
||||
{ "DEMO_UK.ABA", kResourceTypeDOS, "DOS (Demo)" },
|
||||
{ "INTRO.SEQ", kResourceTypeDOS, "DOS CD" },
|
||||
{ "MENU1SSI.MAP", kResourceTypeDOS, "DOS SSI" },
|
||||
{ "LEVEL1.MAP", kResourceTypeDOS, "DOS" },
|
||||
{ "LEVEL1.BNQ", kResourceTypeDOS, "DOS (Demo)" },
|
||||
{ "LEVEL1.LEV", kResourceTypeAmiga, "Amiga" },
|
||||
|
@ -90,10 +91,14 @@ static void initOptions() {
|
|||
g_options.fade_out_palette = true;
|
||||
g_options.use_text_cutscenes = false;
|
||||
g_options.use_seq_cutscenes = true;
|
||||
g_options.use_words_protection = false;
|
||||
g_options.use_white_tshirt = false;
|
||||
g_options.play_asc_cutscene = false;
|
||||
g_options.play_caillou_cutscene = false;
|
||||
g_options.play_metro_cutscene = false;
|
||||
g_options.play_serrure_cutscene = false;
|
||||
g_options.play_carte_cutscene = false;
|
||||
g_options.play_gamesaved_sound = false;
|
||||
// read configuration file
|
||||
struct {
|
||||
const char *name;
|
||||
|
@ -103,13 +108,17 @@ static void initOptions() {
|
|||
{ "enable_password_menu", &g_options.enable_password_menu },
|
||||
{ "enable_language_selection", &g_options.enable_language_selection },
|
||||
{ "fade_out_palette", &g_options.fade_out_palette },
|
||||
{ "use_tiledata", &g_options.use_tiledata },
|
||||
{ "use_tile_data", &g_options.use_tile_data },
|
||||
{ "use_text_cutscenes", &g_options.use_text_cutscenes },
|
||||
{ "use_seq_cutscenes", &g_options.use_seq_cutscenes },
|
||||
{ "use_words_protection", &g_options.use_words_protection },
|
||||
{ "use_white_tshirt", &g_options.use_white_tshirt },
|
||||
{ "play_asc_cutscene", &g_options.play_asc_cutscene },
|
||||
{ "play_caillou_cutscene", &g_options.play_caillou_cutscene },
|
||||
{ "play_metro_cutscene", &g_options.play_metro_cutscene },
|
||||
{ "play_serrure_cutscene", &g_options.play_serrure_cutscene },
|
||||
{ "play_carte_cutscene", &g_options.play_carte_cutscene },
|
||||
{ "play_gamesaved_sound", &g_options.play_gamesaved_sound },
|
||||
{ 0, 0 }
|
||||
};
|
||||
static const char *filename = "rs.cfg";
|
||||
|
@ -147,7 +156,7 @@ static void initOptions() {
|
|||
}
|
||||
|
||||
static void parseScaler(char *name, ScalerParameters *scalerParameters) {
|
||||
struct {
|
||||
static const struct {
|
||||
const char *name;
|
||||
int type;
|
||||
const Scaler *scaler;
|
||||
|
@ -158,7 +167,7 @@ static void parseScaler(char *name, ScalerParameters *scalerParameters) {
|
|||
#ifdef USE_STATIC_SCALER
|
||||
{ "nearest", kScalerTypeInternal, &scaler_nearest },
|
||||
{ "tv2x", kScalerTypeInternal, &scaler_tv2x },
|
||||
{ "xbrz", kScalerTypeInternal, &scaler_xbrz },
|
||||
{ "xbr", kScalerTypeInternal, &scaler_xbr },
|
||||
#endif
|
||||
{ 0, -1 }
|
||||
};
|
||||
|
@ -200,6 +209,7 @@ static WidescreenMode parseWidescreen(const char *mode) {
|
|||
} modes[] = {
|
||||
{ "adjacent", kWidescreenAdjacentRooms },
|
||||
{ "mirror", kWidescreenMirrorRoom },
|
||||
{ "blur", kWidescreenBlur },
|
||||
{ 0, kWidescreenNone },
|
||||
};
|
||||
for (int i = 0; modes[i].name; ++i) {
|
||||
|
@ -207,8 +217,8 @@ static WidescreenMode parseWidescreen(const char *mode) {
|
|||
return modes[i].mode;
|
||||
}
|
||||
}
|
||||
warning("Unhandled widecreen mode '%s', defaults to adjacent rooms", mode);
|
||||
return kWidescreenAdjacentRooms; // default value
|
||||
warning("Unhandled widecreen mode '%s', defaults to 16:9 blur", mode);
|
||||
return kWidescreenBlur;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
|
@ -303,7 +313,7 @@ int main(int argc, char *argv[]) {
|
|||
const Language language = (forcedLanguage == -1) ? detectLanguage(&fs) : (Language)forcedLanguage;
|
||||
SystemStub *stub = SystemStub_SDL_create();
|
||||
Game *g = new Game(stub, &fs, savePath, levelNum, (ResourceType)version, language, widescreen, autoSave);
|
||||
stub->init(g_caption, g->_vid._w, g->_vid._h, fullscreen, widescreen != kWidescreenNone, &scalerParameters);
|
||||
stub->init(g_caption, g->_vid._w, g->_vid._h, fullscreen, widescreen, &scalerParameters);
|
||||
g->run();
|
||||
delete g;
|
||||
stub->destroy();
|
||||
|
|
16
menu.cpp
16
menu.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "game.h"
|
||||
|
@ -89,17 +89,20 @@ void Menu::drawString2(const char *str, int16_t y, int16_t x) {
|
|||
|
||||
void Menu::loadPicture(const char *prefix) {
|
||||
debug(DBG_MENU, "Menu::loadPicture('%s')", prefix);
|
||||
static const int kPictureW = 256;
|
||||
static const int kPictureH = 224;
|
||||
_res->load_MAP_menu(prefix, _res->_scratchBuffer);
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
for (int y = 0; y < 224; ++y) {
|
||||
for (int x = 0; x < 64; ++x) {
|
||||
_vid->_frontLayer[i + x * 4 + 256 * y] = _res->_scratchBuffer[0x3800 * i + x + 64 * y];
|
||||
for (int y = 0; y < kPictureH; ++y) {
|
||||
for (int x = 0; x < kPictureW / 4; ++x) {
|
||||
_vid->_frontLayer[i + x * 4 + kPictureW * y] = _res->_scratchBuffer[0x3800 * i + x + 64 * y];
|
||||
}
|
||||
}
|
||||
}
|
||||
memcpy(_vid->_backLayer, _vid->_frontLayer, _vid->_layerSize);
|
||||
_res->load_PAL_menu(prefix, _res->_scratchBuffer);
|
||||
_stub->setPalette(_res->_scratchBuffer, 256);
|
||||
_vid->updateWidescreen();
|
||||
}
|
||||
|
||||
void Menu::handleInfoScreen() {
|
||||
|
@ -386,7 +389,7 @@ void Menu::handleTitleScreen() {
|
|||
}
|
||||
}
|
||||
|
||||
while (!quitLoop) {
|
||||
while (!quitLoop && !_stub->_pi.quit) {
|
||||
|
||||
int selectedItem = -1;
|
||||
int previousLanguage = currentLanguage;
|
||||
|
@ -497,9 +500,6 @@ void Menu::handleTitleScreen() {
|
|||
_vid->updateScreen();
|
||||
_stub->sleep(EVENTS_DELAY);
|
||||
_stub->processEvents();
|
||||
if (_stub->_pi.quit) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
2
menu.h
2
menu.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef MENU_H__
|
||||
|
|
54
mixer.cpp
54
mixer.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "mixer.h"
|
||||
|
@ -9,8 +9,9 @@
|
|||
#include "util.h"
|
||||
|
||||
Mixer::Mixer(FileSystem *fs, SystemStub *stub)
|
||||
: _stub(stub), _musicType(MT_NONE), _mod(this, fs), _ogg(this, fs), _sfx(this) {
|
||||
: _stub(stub), _musicType(MT_NONE), _cpc(this, fs), _mod(this, fs), _ogg(this, fs), _sfx(this) {
|
||||
_musicTrack = -1;
|
||||
_backgroundMusicType = MT_NONE;
|
||||
}
|
||||
|
||||
void Mixer::init() {
|
||||
|
@ -32,14 +33,14 @@ void Mixer::setPremixHook(PremixHook premixHook, void *userData) {
|
|||
_premixHookData = userData;
|
||||
}
|
||||
|
||||
void Mixer::play(const MixerChunk *mc, uint16_t freq, uint8_t volume) {
|
||||
void Mixer::play(const uint8_t *data, uint32_t len, uint16_t freq, uint8_t volume) {
|
||||
debug(DBG_SND, "Mixer::play(%d, %d)", freq, volume);
|
||||
LockAudioStack las(_stub);
|
||||
MixerChannel *ch = 0;
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
MixerChannel *cur = &_channels[i];
|
||||
if (cur->active) {
|
||||
if (cur->chunk.data == mc->data) {
|
||||
if (cur->chunk.data == data) {
|
||||
cur->chunkPos = 0;
|
||||
return;
|
||||
}
|
||||
|
@ -51,18 +52,19 @@ void Mixer::play(const MixerChunk *mc, uint16_t freq, uint8_t volume) {
|
|||
if (ch) {
|
||||
ch->active = true;
|
||||
ch->volume = volume;
|
||||
ch->chunk = *mc;
|
||||
ch->chunk.data = data;
|
||||
ch->chunk.len = len;
|
||||
ch->chunkPos = 0;
|
||||
ch->chunkInc = (freq << FRAC_BITS) / _stub->getOutputSampleRate();
|
||||
}
|
||||
}
|
||||
|
||||
bool Mixer::isPlaying(const MixerChunk *mc) const {
|
||||
bool Mixer::isPlaying(const uint8_t *data) const {
|
||||
debug(DBG_SND, "Mixer::isPlaying");
|
||||
LockAudioStack las(_stub);
|
||||
for (int i = 0; i < NUM_CHANNELS; ++i) {
|
||||
const MixerChannel *ch = &_channels[i];
|
||||
if (ch->active && ch->chunk.data == mc->data) {
|
||||
if (ch->active && ch->chunk.data == data) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -93,15 +95,20 @@ void Mixer::playMusic(int num) {
|
|||
_musicTrack = num;
|
||||
return;
|
||||
}
|
||||
if (_cpc.playTrack(num - MUSIC_TRACK)) {
|
||||
_backgroundMusicType = _musicType = MT_CPC;
|
||||
_musicTrack = num;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (num == 1) { // menu screen
|
||||
if (_ogg.playTrack(2)) {
|
||||
_musicType = MT_OGG;
|
||||
if (_cpc.playTrack(2) || _ogg.playTrack(2)) {
|
||||
_backgroundMusicType = _musicType = MT_OGG;
|
||||
_musicTrack = 2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (_musicType == MT_OGG && isMusicSfx(num)) { // do not play level action music with background music
|
||||
if ((_musicType == MT_OGG || _musicType == MT_CPC) && isMusicSfx(num)) { // do not play level action music with background music
|
||||
return;
|
||||
}
|
||||
if (isMusicSfx(num)) { // level action sequence
|
||||
|
@ -131,14 +138,29 @@ void Mixer::stopMusic() {
|
|||
case MT_SFX:
|
||||
_sfx.stop();
|
||||
break;
|
||||
case MT_CPC:
|
||||
_cpc.pauseTrack();
|
||||
break;
|
||||
}
|
||||
_musicType = MT_NONE;
|
||||
if (_musicTrack != -1) {
|
||||
_ogg.resumeTrack();
|
||||
_musicType = MT_OGG;
|
||||
switch (_backgroundMusicType) {
|
||||
case MT_OGG:
|
||||
_ogg.resumeTrack();
|
||||
_musicType = MT_OGG;
|
||||
break;
|
||||
case MT_CPC:
|
||||
_cpc.resumeTrack();
|
||||
_musicType = MT_CPC;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const bool kUseNr = false;
|
||||
|
||||
static void nr(int16_t *buf, int len) {
|
||||
static int prev = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
|
@ -163,13 +185,15 @@ void Mixer::mix(int16_t *out, int len) {
|
|||
ch->active = false;
|
||||
break;
|
||||
}
|
||||
const int sample = ch->chunk.getPCM(ch->chunkPos >> FRAC_BITS);
|
||||
out[pos] = ADDC_S16(out[pos], (sample * ch->volume / Mixer::MAX_VOLUME) << 8);
|
||||
const int sample = ch->chunk.getPCM(ch->chunkPos >> FRAC_BITS) * ch->volume / Mixer::MAX_VOLUME;
|
||||
out[pos] = ADDC_S16(out[pos], S8_to_S16(sample));
|
||||
ch->chunkPos += ch->chunkInc;
|
||||
}
|
||||
}
|
||||
}
|
||||
nr(out, len);
|
||||
if (kUseNr) {
|
||||
nr(out, len);
|
||||
}
|
||||
}
|
||||
|
||||
void Mixer::mixCallback(void *param, int16_t *buf, int len) {
|
||||
|
|
12
mixer.h
12
mixer.h
|
@ -1,19 +1,20 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef MIXER_H__
|
||||
#define MIXER_H__
|
||||
|
||||
#include "intern.h"
|
||||
#include "cpc_player.h"
|
||||
#include "mod_player.h"
|
||||
#include "ogg_player.h"
|
||||
#include "sfx_player.h"
|
||||
|
||||
struct MixerChunk {
|
||||
uint8_t *data;
|
||||
const uint8_t *data;
|
||||
uint32_t len;
|
||||
|
||||
MixerChunk()
|
||||
|
@ -49,6 +50,7 @@ struct Mixer {
|
|||
MT_MOD,
|
||||
MT_OGG,
|
||||
MT_SFX,
|
||||
MT_CPC,
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -63,7 +65,9 @@ struct Mixer {
|
|||
MixerChannel _channels[NUM_CHANNELS];
|
||||
PremixHook _premixHook;
|
||||
void *_premixHookData;
|
||||
MusicType _backgroundMusicType;
|
||||
MusicType _musicType;
|
||||
CpcPlayer _cpc;
|
||||
ModPlayer _mod;
|
||||
OggPlayer _ogg;
|
||||
SfxPlayer _sfx;
|
||||
|
@ -73,8 +77,8 @@ struct Mixer {
|
|||
void init();
|
||||
void free();
|
||||
void setPremixHook(PremixHook premixHook, void *userData);
|
||||
void play(const MixerChunk *mc, uint16_t freq, uint8_t volume);
|
||||
bool isPlaying(const MixerChunk *mc) const;
|
||||
void play(const uint8_t *data, uint32_t len, uint16_t freq, uint8_t volume);
|
||||
bool isPlaying(const uint8_t *data) const;
|
||||
uint32_t getSampleRate() const;
|
||||
void stopAll();
|
||||
void playMusic(int num);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "file.h"
|
||||
|
@ -203,17 +203,20 @@ bool ModPlayer_impl::load(File *f) {
|
|||
f->read(_modInfo.patternOrderTable, NUM_PATTERNS);
|
||||
f->readUint32BE(); // 'M.K.', Protracker, 4 channels
|
||||
|
||||
uint16_t n = 0;
|
||||
uint8_t n = 0;
|
||||
for (int i = 0; i < NUM_PATTERNS; ++i) {
|
||||
if (_modInfo.patternOrderTable[i] != 0) {
|
||||
n = MAX(n, _modInfo.patternOrderTable[i]);
|
||||
}
|
||||
}
|
||||
debug(DBG_MOD, "numPatterns=%d",n + 1);
|
||||
n = (n + 1) * 64 * 4 * 4; // 64 lines of 4 notes per channel
|
||||
_modInfo.patternsTable = (uint8_t *)malloc(n);
|
||||
assert(_modInfo.patternsTable);
|
||||
f->read(_modInfo.patternsTable, n);
|
||||
const int patternsSize = (n + 1) * 64 * 4 * 4; // 64 lines of 4 notes per channel
|
||||
_modInfo.patternsTable = (uint8_t *)malloc(patternsSize);
|
||||
if (!_modInfo.patternsTable) {
|
||||
warning("Unable to allocate %d bytes for .MOD patterns table", patternsSize);
|
||||
return false;
|
||||
}
|
||||
f->read(_modInfo.patternsTable, patternsSize);
|
||||
|
||||
for (int s = 0; s < NUM_SAMPLES; ++s) {
|
||||
SampleInfo *si = &_modInfo.samples[s];
|
||||
|
@ -612,8 +615,8 @@ void ModPlayer_impl::mixSamples(int16_t *buf, int samplesLen) {
|
|||
curLen = 0;
|
||||
}
|
||||
while (count--) {
|
||||
const int out = si->getPCM(pos >> FRAC_BITS);
|
||||
*mixbuf = ADDC_S16(*mixbuf, (out * tk->volume / 64) << 8);
|
||||
const int out = si->getPCM(pos >> FRAC_BITS) * tk->volume / 64;
|
||||
*mixbuf = ADDC_S16(*mixbuf, S8_to_S16(out));
|
||||
++mixbuf;
|
||||
pos += deltaPos;
|
||||
}
|
||||
|
@ -676,7 +679,7 @@ void ModPlayer::stop() {
|
|||
if (_playing) {
|
||||
_mix->setPremixHook(0, 0);
|
||||
_impl->unload();
|
||||
_playing = true;
|
||||
_playing = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef MOD_PLAYER_H__
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifdef USE_TREMOR
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef OGG_PLAYER_H__
|
||||
|
|
12
piege.cpp
12
piege.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "cutscene.h"
|
||||
|
@ -1429,6 +1429,9 @@ int Game::pge_op_setCollisionState2(ObjectOpcodeArgs *args) {
|
|||
int Game::pge_op_saveState(ObjectOpcodeArgs *args) {
|
||||
_saveStateCompleted = true;
|
||||
_validSaveState = saveGameState(kIngameSaveSlot);
|
||||
if (_validSaveState and g_options.play_gamesaved_sound) {
|
||||
_mix.play(Resource::_gameSavedSoundData, Resource::_gameSavedSoundLen, 8000, Mixer::MAX_VOLUME);
|
||||
}
|
||||
return 0xFFFF;
|
||||
}
|
||||
|
||||
|
@ -1877,8 +1880,11 @@ int Game::pge_op_setPiegePosModX(ObjectOpcodeArgs *args) {
|
|||
int Game::pge_op_changeRoom(ObjectOpcodeArgs *args) {
|
||||
InitPGE *init_pge_1 = args->pge->init_PGE;
|
||||
assert(args->a >= 0 && args->a < 3);
|
||||
int16_t _ax = init_pge_1->counter_values[args->a];
|
||||
int16_t _bx = init_pge_1->counter_values[args->a + 1];
|
||||
const int16_t _ax = init_pge_1->counter_values[args->a];
|
||||
if (_ax == 0 && !g_options.bypass_protection) {
|
||||
warning("pge_op_changeRoom(): protection check");
|
||||
}
|
||||
const int16_t _bx = init_pge_1->counter_values[args->a + 1];
|
||||
LivePGE *live_pge_1 = &_pgeLive[_bx];
|
||||
LivePGE *live_pge_2 = &_pgeLive[_ax];
|
||||
int8_t pge_room = live_pge_1->room_location;
|
||||
|
|
|
@ -0,0 +1,265 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "game.h"
|
||||
#include "screenshot.h"
|
||||
#include "systemstub.h"
|
||||
|
||||
static uint8_t reverseBits(uint8_t ch) {
|
||||
uint8_t r = 0;
|
||||
for (int b = 0; b < 8; ++b) {
|
||||
if (ch & (1 << b)) {
|
||||
r |= (1 << (7 - b));
|
||||
}
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static uint8_t decryptChar(uint8_t ch) {
|
||||
return reverseBits(ch ^ 0x55);
|
||||
}
|
||||
|
||||
static uint8_t encryptChar(uint8_t ch) {
|
||||
return reverseBits(ch) ^ 0x55;
|
||||
}
|
||||
|
||||
bool Game::handleProtectionScreenShape() {
|
||||
bool valid = false;
|
||||
_cut.prepare();
|
||||
const int palOffset = _res.isAmiga() ? 32 : 0;
|
||||
_cut.copyPalette(_protectionPal + palOffset, 0);
|
||||
|
||||
_cut.updatePalette();
|
||||
_cut._gfx.setClippingRect(64, 48, 128, 128);
|
||||
|
||||
_menu._charVar1 = 0xE0;
|
||||
_menu._charVar2 = 0xEF;
|
||||
_menu._charVar4 = 0xE5;
|
||||
_menu._charVar5 = 0xE2;
|
||||
|
||||
// 5 codes per shape (a code is 6 characters long)
|
||||
if (0) {
|
||||
for (int shape = 0; shape < 30; ++shape) {
|
||||
fprintf(stdout, "Shape #%2d\n", shape);
|
||||
for (int code = 0; code < 5; ++code) {
|
||||
const int offset = (shape * 5 + code) * 6;
|
||||
if (_res.isAmiga()) {
|
||||
fprintf(stdout, "\t ");
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
const char chr = _protectionNumberDataAmiga[(shape * 5 + code) * 6 + i] ^ 0xD7;
|
||||
fprintf(stdout, "%c", chr);
|
||||
}
|
||||
fprintf(stdout, " : ");
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
fprintf(stdout, "%c", _protectionCodeDataAmiga[offset + i] ^ 0xD7);
|
||||
}
|
||||
} else {
|
||||
fprintf(stdout, "\t code %d : ", code + 1);
|
||||
for (int i = 0; i < 6; ++i) {
|
||||
fprintf(stdout, "%c", decryptChar(_protectionCodeData[offset + i]));
|
||||
}
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
if (0) {
|
||||
uint8_t palette[256 * 3];
|
||||
_stub->getPalette(palette, 256);
|
||||
for (int shape = 0; shape < 30; ++shape) {
|
||||
_cut.drawProtectionShape(shape, 0);
|
||||
char fname[32];
|
||||
snprintf(fname, sizeof(fname), "shape_%02d.bmp", shape);
|
||||
saveBMP(fname, _vid._tempLayer, palette, _vid._w, _vid._h);
|
||||
}
|
||||
}
|
||||
const int shapeNum = getRandomNumber() % 30;
|
||||
const int codeNum = getRandomNumber() % 5;
|
||||
for (int16_t zoom = 2000; zoom >= 0; zoom -= 100) {
|
||||
_cut.drawProtectionShape(shapeNum, zoom);
|
||||
_stub->copyRect(0, 0, _vid._w, _vid._h, _vid._tempLayer, _vid._w);
|
||||
_stub->updateScreen(0);
|
||||
_stub->sleep(30);
|
||||
}
|
||||
_vid.setTextPalette();
|
||||
|
||||
char codeNumber[8];
|
||||
if (_res.isAmiga()) {
|
||||
static const uint8_t kNumberLen = 6;
|
||||
for (int i = 0; i < kNumberLen; ++i) {
|
||||
codeNumber[i] = _protectionNumberDataAmiga[(shapeNum * 5 + codeNum) * kNumberLen + i] ^ 0xD7;
|
||||
}
|
||||
codeNumber[kNumberLen] = 0;
|
||||
} else {
|
||||
snprintf(codeNumber, sizeof(codeNumber), "CODE %d", codeNum + 1);
|
||||
}
|
||||
|
||||
static const int kCodeLen = 6;
|
||||
char codeText[kCodeLen + 1];
|
||||
int len = 0;
|
||||
do {
|
||||
codeText[len] = '\0';
|
||||
memcpy(_vid._frontLayer, _vid._tempLayer, _vid._layerSize);
|
||||
_vid.drawString("PROTECTION", 11 * Video::CHAR_W, 2 * Video::CHAR_H, _menu._charVar2);
|
||||
char buf[32];
|
||||
snprintf(buf, sizeof(buf), "%s : %s", codeNumber, codeText);
|
||||
_vid.drawString(buf, 8 * Video::CHAR_W, 23 * Video::CHAR_H, _menu._charVar2);
|
||||
_vid.updateScreen();
|
||||
_stub->sleep(50);
|
||||
_stub->processEvents();
|
||||
char c = _stub->_pi.lastChar;
|
||||
if (c != 0) {
|
||||
_stub->_pi.lastChar = 0;
|
||||
if (len < kCodeLen) {
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
c &= ~0x20;
|
||||
}
|
||||
if ((c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9')) {
|
||||
codeText[len] = c;
|
||||
++len;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.backspace) {
|
||||
_stub->_pi.backspace = false;
|
||||
if (len > 0) {
|
||||
--len;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.enter) {
|
||||
_stub->_pi.enter = false;
|
||||
if (len > 0) {
|
||||
int charsCount = 0;
|
||||
if (_res.isAmiga()) {
|
||||
const uint8_t *p = _protectionCodeDataAmiga + (shapeNum * 5 + codeNum) * kCodeLen;
|
||||
for (int i = 0; i < len && (codeText[i] ^ 0xD7) == p[i]; ++i) {
|
||||
++charsCount;
|
||||
}
|
||||
} else {
|
||||
const uint8_t *p = _protectionCodeData + (shapeNum * 5 + codeNum) * kCodeLen;
|
||||
for (int i = 0; i < len && encryptChar(codeText[i]) == p[i]; ++i) {
|
||||
++charsCount;
|
||||
}
|
||||
}
|
||||
valid = (charsCount == kCodeLen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (!_stub->_pi.quit);
|
||||
_vid.fadeOut();
|
||||
return valid;
|
||||
}
|
||||
|
||||
bool Game::handleProtectionScreenWords() {
|
||||
bool valid = false;
|
||||
static const int kWordsCount = 40;
|
||||
if (0) {
|
||||
for (int i = 0; i < kWordsCount * 18; i += 18) {
|
||||
const uint8_t *data = _protectionWordData + i;
|
||||
fprintf(stdout, "page %d column %d line %2d word %d : ", data[0], data[1], data[2], data[3]);
|
||||
for (int j = 4; j < 18; ++j) {
|
||||
const uint8_t ch = decryptChar(data[j]);
|
||||
if (!(ch >= 'A' && ch <= 'Z')) {
|
||||
break;
|
||||
}
|
||||
fprintf(stdout, "%c", ch);
|
||||
}
|
||||
fprintf(stdout, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
_vid.setTextPalette();
|
||||
_vid.setPalette0xF();
|
||||
|
||||
memset(_vid._frontLayer, 0, _vid._layerSize);
|
||||
|
||||
static const char *kText[] = {
|
||||
"Enter the word found in the",
|
||||
"following location in your",
|
||||
"rulebook. (Do not count the",
|
||||
"title header that appears on",
|
||||
"all pages. Ignore captions",
|
||||
"and header).",
|
||||
0
|
||||
};
|
||||
for (int i = 0; kText[i]; ++i) {
|
||||
_vid.drawString(kText[i], 24, 16 + i * Video::CHAR_H, 0xE5);
|
||||
}
|
||||
static const int icon_spr_w = 16;
|
||||
static const int icon_spr_h = 16;
|
||||
int icon_num = 31;
|
||||
for (int y = 140; y < 140 + 5 * icon_spr_h; y += icon_spr_h) {
|
||||
for (int x = 56; x < 56 + 9 * icon_spr_w; x += icon_spr_w) {
|
||||
drawIcon(icon_num, x, y, 0xF);
|
||||
++icon_num;
|
||||
}
|
||||
}
|
||||
|
||||
const uint8_t code = getRandomNumber() % kWordsCount;
|
||||
const uint8_t *protectionData = _protectionWordData + code * 18;
|
||||
|
||||
const char *kSecurityCodeText = "SECURITY CODE";
|
||||
_vid.drawString(kSecurityCodeText, 72 + (114 - strlen(kSecurityCodeText) * 8) / 2, 158, 0xE4);
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "PAGE %d", protectionData[0]);
|
||||
_vid.drawString(buf, 69, 189, 0xE5);
|
||||
snprintf(buf, sizeof(buf), "COLUMN %d", protectionData[1]);
|
||||
_vid.drawString(buf, 69, 197, 0xE5);
|
||||
snprintf(buf, sizeof(buf), "LINE %d", protectionData[2]);
|
||||
_vid.drawString(buf, (protectionData[2] < 10) ? 141 : 133, 189, 0xE5);
|
||||
snprintf(buf, sizeof(buf), "WORD %d", protectionData[3]);
|
||||
_vid.drawString(buf, 141, 197, 0xE5);
|
||||
|
||||
memcpy(_vid._tempLayer, _vid._frontLayer, _vid._layerSize);
|
||||
|
||||
static const int kCodeLen = 14;
|
||||
char codeText[kCodeLen + 1];
|
||||
int len = 0;
|
||||
do {
|
||||
memcpy(_vid._frontLayer, _vid._tempLayer, _vid._layerSize);
|
||||
codeText[len] = '\0';
|
||||
_vid.drawString(codeText, 72 + (114 - strlen(codeText) * 8) / 2, 166, 0xE3);
|
||||
_vid.updateScreen();
|
||||
_stub->sleep(50);
|
||||
_stub->processEvents();
|
||||
char c = _stub->_pi.lastChar;
|
||||
if (c != 0) {
|
||||
_stub->_pi.lastChar = 0;
|
||||
if (len < kCodeLen) {
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
c &= ~0x20;
|
||||
}
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
codeText[len] = c;
|
||||
++len;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.backspace) {
|
||||
_stub->_pi.backspace = false;
|
||||
if (len > 0) {
|
||||
--len;
|
||||
}
|
||||
}
|
||||
if (_stub->_pi.enter) {
|
||||
_stub->_pi.enter = false;
|
||||
if (len > 0) {
|
||||
int charsCount = 0;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
if (encryptChar(codeText[i]) != protectionData[4 + i]) {
|
||||
break;
|
||||
}
|
||||
++charsCount;
|
||||
}
|
||||
// words are padded with spaces
|
||||
valid = decryptChar(protectionData[4 + charsCount]) == 0x20;
|
||||
}
|
||||
}
|
||||
} while (!_stub->_pi.quit);
|
||||
_vid.fadeOut();
|
||||
return valid;
|
||||
}
|
||||
|
95
resource.cpp
95
resource.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "decode_mac.h"
|
||||
|
@ -53,6 +53,7 @@ Resource::~Resource() {
|
|||
free(_sfxList);
|
||||
free(_bankData);
|
||||
delete _aba;
|
||||
delete _mac;
|
||||
}
|
||||
|
||||
void Resource::init() {
|
||||
|
@ -138,10 +139,6 @@ void Resource::load_DEM(const char *filename) {
|
|||
|
||||
void Resource::load_FIB(const char *fileName) {
|
||||
debug(DBG_RES, "Resource::load_FIB('%s')", fileName);
|
||||
static const uint8_t fibonacciTable[] = {
|
||||
0xDE, 0xEB, 0xF3, 0xF8, 0xFB, 0xFD, 0xFE, 0xFF,
|
||||
0x00, 0x01, 0x02, 0x03, 0x05, 0x08, 0x0D, 0x15
|
||||
};
|
||||
snprintf(_entryName, sizeof(_entryName), "%s.FIB", fileName);
|
||||
File f;
|
||||
if (f.open(_entryName, "rb", _fs)) {
|
||||
|
@ -150,37 +147,48 @@ void Resource::load_FIB(const char *fileName) {
|
|||
if (!_sfxList) {
|
||||
error("Unable to allocate SoundFx table");
|
||||
}
|
||||
int i;
|
||||
for (i = 0; i < _numSfx; ++i) {
|
||||
for (int i = 0; i < _numSfx; ++i) {
|
||||
SoundFx *sfx = &_sfxList[i];
|
||||
sfx->offset = f.readUint32LE();
|
||||
sfx->len = f.readUint16LE();
|
||||
sfx->freq = 6000;
|
||||
sfx->data = 0;
|
||||
}
|
||||
for (i = 0; i < _numSfx; ++i) {
|
||||
for (int i = 0; i < _numSfx; ++i) {
|
||||
SoundFx *sfx = &_sfxList[i];
|
||||
if (sfx->len == 0) {
|
||||
continue;
|
||||
}
|
||||
f.seek(sfx->offset);
|
||||
uint8_t *data = (uint8_t *)malloc(sfx->len * 2);
|
||||
const int len = (sfx->len * 2) - 1;
|
||||
uint8_t *data = (uint8_t *)malloc(len);
|
||||
if (!data) {
|
||||
error("Unable to allocate SoundFx data buffer");
|
||||
}
|
||||
sfx->data = data;
|
||||
uint8_t c = f.readByte();
|
||||
|
||||
// Fibonacci-delta decoding
|
||||
static const int8_t codeToDelta[16] = { -34, -21, -13, -8, -5, -3, -2, -1, 0, 1, 2, 3, 5, 8, 13, 21 };
|
||||
int c = (int8_t)f.readByte();
|
||||
*data++ = c;
|
||||
*data++ = c;
|
||||
uint16_t sz = sfx->len - 1;
|
||||
while (sz--) {
|
||||
uint8_t d = f.readByte();
|
||||
c += fibonacciTable[d >> 4];
|
||||
*data++ = c;
|
||||
c += fibonacciTable[d & 15];
|
||||
*data++ = c;
|
||||
sfx->peak = ABS(c);
|
||||
|
||||
for (int j = 1; j < sfx->len; ++j) {
|
||||
const uint8_t d = f.readByte();
|
||||
|
||||
c += codeToDelta[d >> 4];
|
||||
*data++ = CLIP(c, -128, 127);
|
||||
if (ABS(c) > sfx->peak) {
|
||||
sfx->peak = ABS(c);
|
||||
}
|
||||
|
||||
c += codeToDelta[d & 15];
|
||||
*data++ = CLIP(c, -128, 127);
|
||||
if (ABS(c) > sfx->peak) {
|
||||
sfx->peak = ABS(c);
|
||||
}
|
||||
}
|
||||
sfx->len *= 2;
|
||||
sfx->len = len;
|
||||
}
|
||||
if (f.ioErr()) {
|
||||
error("I/O error when reading '%s'", _entryName);
|
||||
|
@ -190,6 +198,19 @@ void Resource::load_FIB(const char *fileName) {
|
|||
}
|
||||
}
|
||||
|
||||
static void normalizeSPL(SoundFx *sfx) {
|
||||
static const int kGain = 2;
|
||||
|
||||
sfx->peak = ABS(sfx->data[0]);
|
||||
for (int i = 1; i < sfx->len; ++i) {
|
||||
const int8_t sample = sfx->data[i];
|
||||
if (ABS(sample) > sfx->peak) {
|
||||
sfx->peak = ABS(sample);
|
||||
}
|
||||
sfx->data[i] = sample / kGain;
|
||||
}
|
||||
}
|
||||
|
||||
void Resource::load_SPL_demo() {
|
||||
_numSfx = NUM_SFXS;
|
||||
_sfxList = (SoundFx *)calloc(_numSfx, sizeof(SoundFx));
|
||||
|
@ -207,6 +228,7 @@ void Resource::load_SPL_demo() {
|
|||
sfx->offset = 0;
|
||||
sfx->len = size;
|
||||
sfx->freq = kPaulaFreq / 650;
|
||||
normalizeSPL(sfx);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -277,7 +299,7 @@ void Resource::load_CMP_menu(const char *fileName) {
|
|||
error("Failed to allocate CMP temporary buffer");
|
||||
}
|
||||
f.read(tmp, size);
|
||||
if (!delphine_unpack(_scratchBuffer, kScratchBufferSize, tmp, size)) {
|
||||
if (!bytekiller_unpack(_scratchBuffer, kScratchBufferSize, tmp, size)) {
|
||||
error("Bad CRC for %s", fileName);
|
||||
}
|
||||
free(tmp);
|
||||
|
@ -668,7 +690,7 @@ void Resource::load(const char *objName, int objType, const char *ext) {
|
|||
_pal = dat;
|
||||
break;
|
||||
case OT_CT:
|
||||
if (!delphine_unpack((uint8_t *)_ctData, sizeof(_ctData), dat, size)) {
|
||||
if (!bytekiller_unpack((uint8_t *)_ctData, sizeof(_ctData), dat, size)) {
|
||||
error("Bad CRC for '%s'", _entryName);
|
||||
}
|
||||
free(dat);
|
||||
|
@ -736,7 +758,7 @@ void Resource::load_CT(File *pf) {
|
|||
error("Unable to allocate CT buffer");
|
||||
} else {
|
||||
pf->read(tmp, len);
|
||||
if (!delphine_unpack((uint8_t *)_ctData, sizeof(_ctData), tmp, len)) {
|
||||
if (!bytekiller_unpack((uint8_t *)_ctData, sizeof(_ctData), tmp, len)) {
|
||||
error("Bad CRC for collision data");
|
||||
}
|
||||
free(tmp);
|
||||
|
@ -936,7 +958,7 @@ void Resource::load_OBC(File *f) {
|
|||
}
|
||||
f->seek(4);
|
||||
f->read(packedData, packedSize);
|
||||
if (!delphine_unpack(tmp, unpackedSize, packedData, packedSize)) {
|
||||
if (!bytekiller_unpack(tmp, unpackedSize, packedData, packedSize)) {
|
||||
error("Bad CRC for compressed object data");
|
||||
}
|
||||
free(packedData);
|
||||
|
@ -1153,7 +1175,7 @@ void Resource::load_CMP(File *pf) {
|
|||
}
|
||||
if (data[0].packedSize == data[0].size) {
|
||||
memcpy(_pol, tmp + data[0].offset, data[0].packedSize);
|
||||
} else if (!delphine_unpack(_pol, data[0].size, tmp + data[0].offset, data[0].packedSize)) {
|
||||
} else if (!bytekiller_unpack(_pol, data[0].size, tmp + data[0].offset, data[0].packedSize)) {
|
||||
error("Bad CRC for cutscene polygon data");
|
||||
}
|
||||
_cmd = (uint8_t *)malloc(data[1].size);
|
||||
|
@ -1162,7 +1184,7 @@ void Resource::load_CMP(File *pf) {
|
|||
}
|
||||
if (data[1].packedSize == data[1].size) {
|
||||
memcpy(_cmd, tmp + data[1].offset, data[1].packedSize);
|
||||
} else if (!delphine_unpack(_cmd, data[1].size, tmp + data[1].offset, data[1].packedSize)) {
|
||||
} else if (!bytekiller_unpack(_cmd, data[1].size, tmp + data[1].offset, data[1].packedSize)) {
|
||||
error("Bad CRC for cutscene command data");
|
||||
}
|
||||
free(tmp);
|
||||
|
@ -1229,15 +1251,18 @@ void Resource::load_SPL(File *f) {
|
|||
}
|
||||
debug(DBG_RES, "sfx=%d size=%d", i, size);
|
||||
assert(size != 0 && (size & 1) == 0);
|
||||
if (i != 64) {
|
||||
if (i == 64) {
|
||||
warning("Skipping sound #%d (%s) size %d", i, _splNames[i], size);
|
||||
f->seek(offset + size);
|
||||
} else {
|
||||
_sfxList[i].offset = offset;
|
||||
_sfxList[i].len = size;
|
||||
_sfxList[i].freq = kPaulaFreq / 650;
|
||||
_sfxList[i].data = (uint8_t *)malloc(size);
|
||||
assert(_sfxList[i].data);
|
||||
f->read(_sfxList[i].data, size);
|
||||
} else {
|
||||
f->seek(offset + size);
|
||||
if (_sfxList[i].data) {
|
||||
f->read(_sfxList[i].data, size);
|
||||
_sfxList[i].len = size;
|
||||
normalizeSPL(&_sfxList[i]);
|
||||
}
|
||||
}
|
||||
offset += size;
|
||||
}
|
||||
|
@ -1278,7 +1303,7 @@ void Resource::load_SGD(File *f) {
|
|||
if (!_sgd) {
|
||||
error("Unable to allocate SGD buffer");
|
||||
}
|
||||
if (!delphine_unpack(_sgd, size, tmp, len)) {
|
||||
if (!bytekiller_unpack(_sgd, size, tmp, len)) {
|
||||
error("Bad CRC for SGD data");
|
||||
}
|
||||
free(tmp);
|
||||
|
@ -1310,12 +1335,12 @@ void Resource::load_SPM(File *f) {
|
|||
if (!_spr1) {
|
||||
error("Unable to allocate SPR1 buffer");
|
||||
}
|
||||
if (!delphine_unpack(_spr1, size, tmp, len)) {
|
||||
if (!bytekiller_unpack(_spr1, size, tmp, len)) {
|
||||
error("Bad CRC for SPM data");
|
||||
}
|
||||
} else {
|
||||
assert(size <= sizeof(_sprm));
|
||||
if (!delphine_unpack(_sprm, sizeof(_sprm), tmp, len)) {
|
||||
if (!bytekiller_unpack(_sprm, sizeof(_sprm), tmp, len)) {
|
||||
error("Bad CRC for SPM data");
|
||||
}
|
||||
}
|
||||
|
@ -1391,7 +1416,7 @@ uint8_t *Resource::loadBankData(uint16_t num) {
|
|||
} else {
|
||||
assert(dataOffset > 4);
|
||||
assert(size == (int)READ_BE_UINT32(data - 4));
|
||||
if (!delphine_unpack(_bankDataHead, _bankDataTail - _bankDataHead, data, 0)) {
|
||||
if (!bytekiller_unpack(_bankDataHead, _bankDataTail - _bankDataHead, data, 0)) {
|
||||
error("Bad CRC for bank data %d", num);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef RESOURCE_H__
|
||||
|
@ -119,6 +119,8 @@ struct Resource {
|
|||
static const uint16_t _voicesOffsetsTable[];
|
||||
static const uint32_t _spmOffsetsTable[];
|
||||
static const char *_splNames[];
|
||||
static const uint8_t _gameSavedSoundData[];
|
||||
static const uint16_t _gameSavedSoundLen;
|
||||
|
||||
FileSystem *_fs;
|
||||
ResourceType _type;
|
||||
|
|
|
@ -74,7 +74,7 @@ uint8_t *ResourceAba::loadEntry(const char *name, uint32_t *size) {
|
|||
free(tmp);
|
||||
return 0;
|
||||
}
|
||||
const bool ret = delphine_unpack(dst, e->size, tmp, e->compressedSize);
|
||||
const bool ret = bytekiller_unpack(dst, e->size, tmp, e->compressedSize);
|
||||
if (!ret) {
|
||||
error("Bad CRC for '%s'", name);
|
||||
}
|
||||
|
|
20
rs.cfg
20
rs.cfg
|
@ -1,4 +1,4 @@
|
|||
# display copy protection shapes
|
||||
# display copy protection (shapes or words lookup)
|
||||
bypass_protection=true
|
||||
|
||||
# use original password level selection menu screen
|
||||
|
@ -11,22 +11,34 @@ enable_language_selection=true
|
|||
fade_out_palette=false
|
||||
|
||||
# use .BNQ & .LEV datafiles (tile based rendering) for backgrounds (instead of .MAP)
|
||||
use_tiledata=false
|
||||
use_tile_data=false
|
||||
|
||||
# display text instead of playing the polygon cutscenes
|
||||
use_text_cutscenes=false
|
||||
|
||||
# enable playback of .SEQ cutscenes (always use polygon cutscenes if false)
|
||||
# enable playback of PC CD .SEQ cutscenes (use polygon cutscenes if false)
|
||||
use_seq_cutscenes=true
|
||||
|
||||
# if copy protection is enabled, display the words manual lookup screen (as in DOS SSI version).
|
||||
use_words_protection=false
|
||||
|
||||
# white t-shirt for Conrad
|
||||
use_white_tshirt=false
|
||||
|
||||
# enable playback of 'ASC' cutscene
|
||||
play_asc_cutscene=false
|
||||
play_asc_cutscene=true
|
||||
|
||||
# enable playback of 'CAILLOU-F.SET' cutscene
|
||||
play_caillou_cutscene=true
|
||||
|
||||
# enable playback of 'CARTE' cutscene
|
||||
play_carte_cutscene=true
|
||||
|
||||
# enable playback of 'METRO' cutscene
|
||||
play_metro_cutscene=false
|
||||
|
||||
# enable playback of 'SERRURE' cutscene
|
||||
play_serrure_cutscene=true
|
||||
|
||||
# play 'Game saved' sample when saving with level checkpoints (as in the 3DO version)
|
||||
play_gamesaved_sound=true
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "scaler.h"
|
||||
|
|
4
scaler.h
4
scaler.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef SCALER_H__
|
||||
|
@ -34,7 +34,7 @@ const Scaler *findScaler(const char *name);
|
|||
#ifdef USE_STATIC_SCALER
|
||||
extern const Scaler scaler_nearest;
|
||||
extern const Scaler scaler_tv2x;
|
||||
extern const Scaler scaler_xbrz;
|
||||
extern const Scaler scaler_xbr;
|
||||
#endif
|
||||
|
||||
#endif // SCALER_H__
|
||||
|
|
|
@ -68,3 +68,54 @@ void saveTGA(const char *filename, const uint8_t *rgba, int w, int h) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const uint16_t TAG_BM = 0x4D42;
|
||||
|
||||
void saveBMP(const char *filename, const uint8_t *bits, const uint8_t *pal, int w, int h) {
|
||||
File f;
|
||||
if (f.open(filename, "wb", ".")) {
|
||||
const int alignWidth = (w + 3) & ~3;
|
||||
const int imageSize = alignWidth * h;
|
||||
|
||||
// Write file header
|
||||
f.writeUint16LE(TAG_BM);
|
||||
f.writeUint32LE(14 + 40 + 4 * 256 + imageSize);
|
||||
f.writeUint16LE(0); // reserved1
|
||||
f.writeUint16LE(0); // reserved2
|
||||
f.writeUint32LE(14 + 40 + 4 * 256);
|
||||
|
||||
// Write info header
|
||||
f.writeUint32LE(40);
|
||||
f.writeUint32LE(w);
|
||||
f.writeUint32LE(h);
|
||||
f.writeUint16LE(1); // planes
|
||||
f.writeUint16LE(8); // bit_count
|
||||
f.writeUint32LE(0); // compression
|
||||
f.writeUint32LE(imageSize); // size_image
|
||||
f.writeUint32LE(0); // x_pels_per_meter
|
||||
f.writeUint32LE(0); // y_pels_per_meter
|
||||
f.writeUint32LE(0); // num_colors_used
|
||||
f.writeUint32LE(0); // num_colors_important
|
||||
|
||||
// Write palette data
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
f.writeByte(pal[2]);
|
||||
f.writeByte(pal[1]);
|
||||
f.writeByte(pal[0]);
|
||||
f.writeByte(0);
|
||||
pal += 3;
|
||||
}
|
||||
|
||||
// Write bitmap data
|
||||
const int pitch = w;
|
||||
bits += h * pitch;
|
||||
for (int i = 0; i < h; ++i) {
|
||||
bits -= pitch;
|
||||
f.write(bits, w);
|
||||
int pad = alignWidth - w;
|
||||
while (pad--) {
|
||||
f.writeByte(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,6 @@
|
|||
#include <stdint.h>
|
||||
|
||||
void saveTGA(const char *filename, const uint8_t *rgb, int w, int h);
|
||||
void saveBMP(const char *filename, const uint8_t *bits, const uint8_t *pal, int w, int h);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "file.h"
|
||||
|
@ -226,10 +226,8 @@ SeqPlayer::~SeqPlayer() {
|
|||
|
||||
void SeqPlayer::play(File *f) {
|
||||
if (_demux.open(f)) {
|
||||
Color pal[256];
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
_stub->getPaletteEntry(i, &pal[i]);
|
||||
}
|
||||
uint8_t palette[256 * 3];
|
||||
_stub->getPalette(palette, 256);
|
||||
_mix->setPremixHook(mixCallback, this);
|
||||
memset(_buf, 0, 256 * 224);
|
||||
bool clearScreen = true;
|
||||
|
@ -315,9 +313,8 @@ void SeqPlayer::play(File *f) {
|
|||
_stub->sleep(diff);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
_stub->setPaletteEntry(i, &pal[i]);
|
||||
}
|
||||
// restore level palette
|
||||
_stub->setPalette(palette, 256);
|
||||
_mix->setPremixHook(0, 0);
|
||||
_demux.close();
|
||||
// flush sound queue
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef SEQ_PLAYER_H__
|
||||
|
|
|
@ -1,13 +1,35 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "mixer.h"
|
||||
#include "sfx_player.h"
|
||||
#include "util.h"
|
||||
|
||||
// volume instruments are either equal to 64 or 32 (this corresponds to aud0vol)
|
||||
// use one third of the volume for master (for comparison, modplug uses a master volume of 128, max 512)
|
||||
static const int kMasterVolume = 64 * 3;
|
||||
|
||||
// 12 dB/oct Butterworth low-pass filter at 3.3 kHz
|
||||
static const bool kLowPassFilter = true;
|
||||
|
||||
#define NZEROS 2
|
||||
#define NPOLES 2
|
||||
static float bw_xf[NZEROS+1], bw_yf[NPOLES+1];
|
||||
static const float GAIN = 7.655158005e+00;
|
||||
|
||||
static void butterworth(int16_t *p, int len) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
bw_xf[0] = bw_xf[1]; bw_xf[1] = bw_xf[2];
|
||||
bw_xf[2] = p[i] / GAIN;
|
||||
bw_yf[0] = bw_yf[1]; bw_yf[1] = bw_yf[2];
|
||||
bw_yf[2] = (bw_xf[0] + bw_xf[2]) + 2 * bw_xf[1] + (-0.2729352339 * bw_yf[0]) + (0.7504117278 * bw_yf[1]);
|
||||
p[i] = (int16_t)CLIP(bw_yf[2], -32768.f, 32767.f);
|
||||
}
|
||||
}
|
||||
|
||||
SfxPlayer::SfxPlayer(Mixer *mixer)
|
||||
: _mod(0), _playing(false), _mix(mixer) {
|
||||
}
|
||||
|
@ -15,20 +37,23 @@ SfxPlayer::SfxPlayer(Mixer *mixer)
|
|||
void SfxPlayer::play(uint8_t num) {
|
||||
debug(DBG_SFX, "SfxPlayer::play(%d)", num);
|
||||
if (!_playing) {
|
||||
if (num >= 68 && num <= 75) {
|
||||
static const Module *modTable[] = {
|
||||
&_module68, &_module68, &_module70, &_module70,
|
||||
&_module72, &_module73, &_module74, &_module75
|
||||
};
|
||||
_mod = modTable[num - 68];
|
||||
_curOrder = 0;
|
||||
_numOrders = READ_BE_UINT16(_mod->moduleData);
|
||||
_orderDelay = 0;
|
||||
_modData = _mod->moduleData + 0x22;
|
||||
memset(_samples, 0, sizeof(_samples));
|
||||
_samplesLeft = 0;
|
||||
_mix->setPremixHook(mixCallback, this);
|
||||
_playing = true;
|
||||
assert(num >= 68 && num <= 75);
|
||||
static const Module *modTable[] = {
|
||||
&_module68, &_module68, &_module70, &_module70,
|
||||
&_module72, &_module73, &_module74, &_module75
|
||||
};
|
||||
_mod = modTable[num - 68];
|
||||
_curOrder = 0;
|
||||
_numOrders = READ_BE_UINT16(_mod->moduleData);
|
||||
_orderDelay = 0;
|
||||
_modData = _mod->moduleData + 0x22;
|
||||
memset(_samples, 0, sizeof(_samples));
|
||||
_samplesLeft = 0;
|
||||
_mix->setPremixHook(mixCallback, this);
|
||||
_playing = true;
|
||||
if (kLowPassFilter) {
|
||||
memset(bw_xf, 0, sizeof(bw_xf));
|
||||
memset(bw_yf, 0, sizeof(bw_yf));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -126,8 +151,8 @@ void SfxPlayer::mixSamples(int16_t *buf, int samplesLen) {
|
|||
curLen = 0;
|
||||
}
|
||||
while (count--) {
|
||||
const int out = si->getPCM(pos >> FRAC_BITS);
|
||||
*mixbuf = ADDC_S16(*mixbuf, (out * si->vol / 64) << 8);
|
||||
const int out = si->getPCM(pos >> FRAC_BITS) * si->vol / kMasterVolume;
|
||||
*mixbuf = ADDC_S16(*mixbuf, S8_to_S16(out));
|
||||
++mixbuf;
|
||||
pos += deltaPos;
|
||||
}
|
||||
|
@ -153,6 +178,9 @@ bool SfxPlayer::mix(int16_t *buf, int len) {
|
|||
_samplesLeft -= count;
|
||||
len -= count;
|
||||
mixSamples(buf, count);
|
||||
if (kLowPassFilter) {
|
||||
butterworth(buf, count);
|
||||
}
|
||||
buf += count;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef SFX_PLAYER_H__
|
||||
|
|
714
staticres.cpp
714
staticres.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "game.h"
|
||||
|
@ -30,7 +30,7 @@ const Cutscene::OpcodeStub Cutscene::_opcodeTable[] = {
|
|||
&Cutscene::op_handleKeys
|
||||
};
|
||||
|
||||
const char *Cutscene::_namesTable[] = {
|
||||
const char *Cutscene::_namesTableDOS[] = {
|
||||
"DEBUT",
|
||||
"OBJET",
|
||||
"CARTE",
|
||||
|
@ -68,7 +68,7 @@ const char *Cutscene::_namesTable[] = {
|
|||
"LOGOSSSI",
|
||||
};
|
||||
|
||||
const uint16_t Cutscene::_offsetsTable[] = {
|
||||
const uint16_t Cutscene::_offsetsTableDOS[] = {
|
||||
0x0000, 0x0000, 0x0001, 0x0003, 0x0001, 0x0004, 0xFFFF, 0x0000, 0x0001, 0x0002,
|
||||
0x0003, 0x0000, 0x0004, 0x0000, 0xFFFF, 0x0100, 0xFFFF, 0x0000, 0x0006, 0x0000,
|
||||
0x0001, 0x0001, 0xFFFF, 0x0000, 0xFFFF, 0x0200, 0x8007, 0x0000, 0x0003, 0x0001,
|
||||
|
@ -87,6 +87,19 @@ const uint16_t Cutscene::_offsetsTable[] = {
|
|||
0xFFFF, 0x0000
|
||||
};
|
||||
|
||||
const uint16_t Cutscene::_offsetsTableAmiga[] = {
|
||||
0x0000, 0, 0x0001, 3, 0x0001, 4, 0x0002, 0, 0x0001, 2, 0x0003, 0, 0x0004, 0, 0xFFFF, 0,
|
||||
0xFFFF, 0, 0x0006, 0, 0x0001, 1, 0xFFFF, 0, 0xFFFF, 0, 0x0007, 0, 0x0003, 1, 0x0001, 11,
|
||||
0x0001, 5, 0x0009, 0, 0x0001, 6, 0x000A, 0, 0x000B, 0, 0x0001, 10, 0x000C, 1, 0xFFFF, 2,
|
||||
0xFFFF, 0, 0x000D, 4, 0x000D, 0, 0x000D, 1, 0x000D, 2, 0x000D, 3, 0xFFFF, 0, 0xFFFF, 1,
|
||||
0x0001, 12, 0x0001, 13, 0x0001, 14, 0x0001, 15, 0x0001, 16, 0x000F, 0, 0x000F, 1, 0x000F, 1,
|
||||
0x000F, 3, 0x000F, 2, 0x000F, 4, 0x0001, 8, 0x0001, 7, 0x000F, 5, 0xFFFF, 0, 0x0004, 1,
|
||||
0x0011, 0, 0x0001, 9, 0x0012, 0, 0xFFFF, 0, 0x0014, 0, 0x0015, 0, 0x0016, 0, 0x0016, 1,
|
||||
0xFFFF, 18, 0x0017, 0, 0x0001, 17, 0x0018, 0, 0x0001, 19, 0x0019, 0, 0x001A, 0, 0x0019, 1,
|
||||
0x001B, 0, 0x001C, 0, 0x000F, 6, 0x000F, 6, 0x000F, 7, 0x000F, 8, 0x000F, 9, 0x000F, 10,
|
||||
0x001D, 0, 0x001B, 1
|
||||
};
|
||||
|
||||
const uint8_t Cutscene::_amigaDemoOffsetsTable[] = {
|
||||
1, 32, 0, /* HOLOCUBE */
|
||||
6, 33, 0, /* CHUTE2 */
|
||||
|
@ -2928,7 +2941,7 @@ const char *Resource::_splNames[] = {
|
|||
"touche.spl",
|
||||
"coup",
|
||||
"chenille.spl",
|
||||
"robot.spl",
|
||||
"robot",
|
||||
"tombe.spl",
|
||||
"porte_ferme.spl",
|
||||
"canon_down",
|
||||
|
@ -2972,6 +2985,512 @@ const char *Resource::_splNames[] = {
|
|||
0
|
||||
};
|
||||
|
||||
const uint8_t Resource::_gameSavedSoundData[] = {
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x06, 0x06, 0xfd, 0x00, 0xff, 0xfc, 0x00, 0xff, 0xfd, 0x00,
|
||||
0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff,
|
||||
0x00, 0xff, 0xfd, 0xfe, 0xfa, 0xfd, 0xfc, 0xfd, 0x07, 0x09, 0x07, 0x00, 0x04, 0x01, 0x02, 0x05,
|
||||
0x01, 0x04, 0xfe, 0x02, 0x04, 0x06, 0x03, 0x02, 0x02, 0x00, 0xff, 0xff, 0xff, 0xfd, 0xff, 0xfb,
|
||||
0xfe, 0xfc, 0xfd, 0xfe, 0xfd, 0xfd, 0xff, 0xff, 0xfe, 0x01, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0xff, 0x00, 0xff, 0x01, 0x02,
|
||||
0x00, 0x01, 0x00, 0x02, 0x00, 0x00, 0x04, 0x00, 0x01, 0x03, 0x00, 0x02, 0x00, 0x00, 0x01, 0xff,
|
||||
0x00, 0x00, 0xff, 0xfe, 0xff, 0xfd, 0xfe, 0xff, 0xfb, 0xfc, 0xf9, 0xf8, 0xf7, 0xf5, 0xf5, 0xf5,
|
||||
0xf2, 0xf3, 0xf3, 0xf3, 0xf6, 0xf5, 0xf7, 0xfd, 0xfa, 0xfc, 0x05, 0x00, 0x02, 0x07, 0x06, 0x04,
|
||||
0x06, 0x08, 0x02, 0x04, 0x00, 0x00, 0xfe, 0xf8, 0xfd, 0xfb, 0xf4, 0xfa, 0x01, 0xf8, 0xfe, 0x0a,
|
||||
0x02, 0x04, 0x0e, 0x0d, 0x07, 0x0e, 0x0e, 0x08, 0x06, 0x07, 0x02, 0xfe, 0xfc, 0xf9, 0xf3, 0xef,
|
||||
0xf2, 0xee, 0xeb, 0xed, 0xec, 0xe7, 0xe6, 0xe9, 0xe3, 0xde, 0xdf, 0xdf, 0xd9, 0xea, 0xf1, 0xda,
|
||||
0x00, 0x02, 0xf0, 0x0c, 0x0c, 0x0c, 0x02, 0x15, 0x0c, 0x01, 0x08, 0xfb, 0x01, 0xee, 0xf1, 0xf3,
|
||||
0xe9, 0xe7, 0xe8, 0xf3, 0xe7, 0xf1, 0xfc, 0xfa, 0xff, 0x02, 0x0d, 0x07, 0x0f, 0x18, 0x0e, 0x13,
|
||||
0x14, 0x0e, 0x09, 0x0b, 0x02, 0x01, 0x00, 0xfd, 0x00, 0xff, 0x00, 0x01, 0x03, 0xff, 0x01, 0x00,
|
||||
0xfc, 0xf9, 0xf8, 0xf2, 0xec, 0xee, 0xe0, 0xd8, 0xda, 0xd6, 0xca, 0xd2, 0xd6, 0xed, 0xf6, 0xe7,
|
||||
0x1a, 0x1d, 0x0f, 0x23, 0x31, 0x26, 0x10, 0x22, 0x0f, 0xff, 0xf8, 0xed, 0xee, 0xdd, 0xdf, 0xe4,
|
||||
0xed, 0xed, 0xf4, 0x0d, 0x0b, 0x13, 0x1e, 0x24, 0x1f, 0x1c, 0x24, 0x17, 0x10, 0x0c, 0x08, 0xfe,
|
||||
0xfc, 0xfb, 0xfb, 0xfe, 0x00, 0x09, 0x0d, 0x13, 0x17, 0x1b, 0x18, 0x15, 0x0f, 0x07, 0x00, 0xf7,
|
||||
0xf0, 0xe8, 0xe4, 0xdf, 0xd6, 0xd6, 0xd4, 0xd2, 0xdd, 0xd3, 0xe1, 0xf5, 0x19, 0x09, 0x03, 0x4b,
|
||||
0x21, 0x18, 0x26, 0x20, 0x0b, 0xf0, 0xff, 0xe2, 0xe9, 0xdc, 0xd8, 0xf5, 0xf0, 0xf8, 0x05, 0x1f,
|
||||
0x18, 0x19, 0x2b, 0x1c, 0x1a, 0x0e, 0x05, 0xfb, 0xf3, 0xfa, 0xf1, 0xf6, 0x04, 0x08, 0x09, 0x1b,
|
||||
0x21, 0x1c, 0x21, 0x21, 0x1b, 0x15, 0x0f, 0x07, 0x04, 0xfd, 0xf6, 0xf5, 0xf2, 0xed, 0xef, 0xf1,
|
||||
0xf5, 0xf4, 0xf1, 0xf5, 0xe9, 0xe9, 0xee, 0xd7, 0xcb, 0xdf, 0xf6, 0x09, 0xef, 0x0b, 0x3b, 0x1a,
|
||||
0x18, 0x1e, 0x24, 0x0b, 0xf6, 0xf9, 0xea, 0xf0, 0xdd, 0xe0, 0xf9, 0xfc, 0x00, 0x07, 0x21, 0x1d,
|
||||
0x19, 0x1d, 0x14, 0x11, 0x00, 0xf7, 0xf2, 0xfa, 0xf9, 0xfe, 0x0c, 0x11, 0x19, 0x1f, 0x24, 0x1d,
|
||||
0x1d, 0x17, 0x0e, 0x08, 0x03, 0x00, 0xfd, 0xfc, 0xfa, 0xfa, 0xf8, 0xf7, 0xf4, 0xf2, 0xf5, 0xf5,
|
||||
0xf0, 0xee, 0xe5, 0xdc, 0xe4, 0xd3, 0xc3, 0xcf, 0xfb, 0x26, 0xef, 0x16, 0x46, 0x23, 0x20, 0x0a,
|
||||
0x14, 0xfc, 0xec, 0xdf, 0xcb, 0xf3, 0xe7, 0xe1, 0x00, 0x15, 0x1d, 0x16, 0x28, 0x20, 0x16, 0x12,
|
||||
0xf4, 0xf4, 0xeb, 0xe9, 0xeb, 0xf8, 0x03, 0x0f, 0x25, 0x22, 0x2a, 0x2f, 0x24, 0x11, 0x10, 0x05,
|
||||
0xf8, 0xf9, 0xf9, 0xfa, 0xfe, 0x01, 0x00, 0x03, 0x00, 0xf7, 0xf5, 0xf8, 0xed, 0xe5, 0xe7, 0xdf,
|
||||
0xd0, 0xd7, 0xcc, 0xc8, 0xc7, 0xee, 0x55, 0x0b, 0xf4, 0x4a, 0x3a, 0x13, 0xec, 0x00, 0xf3, 0xdc,
|
||||
0xde, 0xbd, 0xec, 0x0f, 0xf3, 0x01, 0x24, 0x3a, 0x18, 0x15, 0x19, 0xfd, 0x00, 0xe1, 0xd7, 0xe1,
|
||||
0xf7, 0xf5, 0xfd, 0x22, 0x2b, 0x30, 0x29, 0x2a, 0x21, 0x17, 0xfe, 0xf5, 0xfd, 0xf9, 0xf7, 0xff,
|
||||
0x0d, 0x0a, 0x0b, 0x01, 0xfd, 0xf7, 0xea, 0xe8, 0xe8, 0xe3, 0xdd, 0xdf, 0xd2, 0xcf, 0xd4, 0xc9,
|
||||
0xba, 0x1b, 0x4f, 0xe6, 0x15, 0x52, 0x26, 0x02, 0xf3, 0xfc, 0xe1, 0xe3, 0xd6, 0xbe, 0x00, 0x10,
|
||||
0xf2, 0x0f, 0x2f, 0x31, 0x10, 0x17, 0x0a, 0xf3, 0xfb, 0xd9, 0xd6, 0xea, 0xfc, 0xfb, 0x0c, 0x29,
|
||||
0x2c, 0x31, 0x29, 0x23, 0x1a, 0x0e, 0xf8, 0xf5, 0xfc, 0xfa, 0xfd, 0x07, 0x11, 0x0e, 0x0f, 0x05,
|
||||
0xfe, 0xf4, 0xe6, 0xd9, 0xda, 0xdd, 0xd2, 0xd3, 0xd7, 0xcc, 0xca, 0xe2, 0xd9, 0x2c, 0x45, 0xea,
|
||||
0x25, 0x43, 0x19, 0xec, 0xea, 0xfd, 0xd5, 0xdd, 0xdd, 0xd5, 0x0d, 0x11, 0x00, 0x19, 0x31, 0x2b,
|
||||
0x00, 0x10, 0x00, 0xec, 0xed, 0xda, 0xe3, 0xf0, 0x08, 0x08, 0x18, 0x2c, 0x2f, 0x29, 0x21, 0x1a,
|
||||
0x0c, 0x05, 0xf9, 0xf8, 0xfc, 0x01, 0x04, 0x0b, 0x10, 0x0d, 0x08, 0x00, 0xf8, 0xea, 0xe2, 0xdb,
|
||||
0xdc, 0xd4, 0xd8, 0xe1, 0xcf, 0xcd, 0xe2, 0xca, 0xdf, 0x5f, 0x11, 0xdc, 0x4c, 0x3c, 0x00, 0xe6,
|
||||
0x03, 0xf3, 0xd2, 0xea, 0xcc, 0xe4, 0x1c, 0xf9, 0xfd, 0x24, 0x37, 0x11, 0x04, 0x1d, 0xf6, 0xf6,
|
||||
0xea, 0xdc, 0xeb, 0xf8, 0xfe, 0x02, 0x23, 0x29, 0x27, 0x28, 0x29, 0x18, 0x0e, 0x04, 0xf8, 0xfd,
|
||||
0xfd, 0xfb, 0x01, 0x10, 0x0b, 0x08, 0x06, 0x01, 0xf8, 0xea, 0xdf, 0xe1, 0xe0, 0xd1, 0xd1, 0xd7,
|
||||
0xd6, 0xc4, 0xcc, 0xc7, 0x16, 0x46, 0xe1, 0x1b, 0x5a, 0x26, 0xfc, 0xf8, 0x0d, 0xe5, 0xd4, 0xd5,
|
||||
0xcb, 0xfe, 0xfc, 0xe7, 0x13, 0x2f, 0x2a, 0x0b, 0x22, 0x1a, 0xff, 0xf9, 0xdf, 0xe9, 0xee, 0xeb,
|
||||
0xef, 0x0b, 0x1e, 0x1e, 0x26, 0x2d, 0x2e, 0x1f, 0x10, 0x07, 0x04, 0xfc, 0xf3, 0xf9, 0x03, 0x05,
|
||||
0x01, 0x04, 0x06, 0x01, 0xf2, 0xe6, 0xe9, 0xe9, 0xda, 0xd4, 0xdf, 0xd4, 0xcf, 0xd4, 0xd5, 0xb4,
|
||||
0x0a, 0x54, 0xd3, 0x10, 0x67, 0x23, 0xfe, 0x05, 0x16, 0xe4, 0xe0, 0xda, 0xc4, 0x00, 0xf1, 0xd8,
|
||||
0x0e, 0x2e, 0x1b, 0x07, 0x33, 0x1e, 0x06, 0x06, 0xec, 0xf3, 0xf2, 0xe6, 0xe8, 0x09, 0x0d, 0x0f,
|
||||
0x25, 0x2f, 0x28, 0x24, 0x1e, 0x0e, 0x0b, 0x00, 0xf4, 0xfa, 0x00, 0xfb, 0xfc, 0x01, 0xff, 0xfc,
|
||||
0xf0, 0xf1, 0xf3, 0xe7, 0xdc, 0xdd, 0xe0, 0xd5, 0xc8, 0xc8, 0xc8, 0xc0, 0x2e, 0x1d, 0xd1, 0x4d,
|
||||
0x54, 0x0c, 0x04, 0x25, 0x0b, 0xda, 0xe8, 0xd1, 0xdc, 0xf4, 0xd0, 0xea, 0x1a, 0x19, 0x04, 0x24,
|
||||
0x38, 0x0f, 0x16, 0x0b, 0xff, 0xfc, 0xee, 0xe6, 0xf3, 0x00, 0xf8, 0x11, 0x24, 0x1f, 0x23, 0x2b,
|
||||
0x1e, 0x16, 0x11, 0x02, 0x00, 0x00, 0xfa, 0xf8, 0xfb, 0xf4, 0xf7, 0xf1, 0xea, 0xf1, 0xe9, 0xdc,
|
||||
0xe8, 0xec, 0xd5, 0xd7, 0xde, 0xca, 0xae, 0x18, 0x1a, 0xba, 0x2c, 0x4d, 0x02, 0x07, 0x32, 0x17,
|
||||
0xf0, 0x00, 0xe6, 0xea, 0xf9, 0xcf, 0xe5, 0x0e, 0xfe, 0xef, 0x1f, 0x28, 0x03, 0x1d, 0x1b, 0x0a,
|
||||
0x0b, 0x02, 0xf9, 0x01, 0xff, 0xf5, 0x0c, 0x10, 0x07, 0x14, 0x1e, 0x13, 0x15, 0x16, 0x11, 0x10,
|
||||
0x08, 0x05, 0x06, 0xfc, 0xf2, 0xf7, 0xee, 0xe3, 0xe5, 0xe6, 0xdc, 0xdd, 0xdf, 0xe0, 0xe8, 0xd4,
|
||||
0xc6, 0xcd, 0x23, 0xf9, 0xb9, 0x41, 0x36, 0xee, 0x0a, 0x3a, 0x15, 0xea, 0x06, 0xfb, 0x00, 0xe8,
|
||||
0xd9, 0x07, 0x00, 0xe4, 0xfb, 0x28, 0x06, 0xfa, 0x23, 0x18, 0x08, 0x0a, 0x0e, 0x0c, 0x07, 0xfa,
|
||||
0x05, 0x10, 0xfe, 0x02, 0x14, 0x0e, 0x08, 0x16, 0x16, 0x10, 0x0f, 0x10, 0x10, 0x07, 0xfc, 0xfe,
|
||||
0xfa, 0xe9, 0xe8, 0xe9, 0xdd, 0xda, 0xe2, 0xdf, 0xd9, 0xde, 0xd1, 0xcf, 0xcb, 0x00, 0x06, 0xce,
|
||||
0x25, 0x2d, 0xff, 0x12, 0x2c, 0x15, 0xfc, 0x10, 0xfc, 0xff, 0xf4, 0xe6, 0xff, 0xfb, 0xeb, 0xfc,
|
||||
0x15, 0x00, 0x00, 0x1c, 0x10, 0x09, 0x14, 0x0f, 0x09, 0x0a, 0x03, 0x04, 0x04, 0x00, 0x05, 0x08,
|
||||
0x06, 0x0c, 0x11, 0x0f, 0x13, 0x15, 0x12, 0x11, 0x0d, 0x07, 0x03, 0xfc, 0xf4, 0xf0, 0xe8, 0xe0,
|
||||
0xde, 0xdb, 0xd6, 0xd4, 0xd4, 0xce, 0xd4, 0xc3, 0xf4, 0x0a, 0xca, 0x1e, 0x2d, 0xf3, 0x17, 0x32,
|
||||
0x0f, 0x00, 0x20, 0x04, 0x00, 0x00, 0xf2, 0x03, 0xf6, 0xec, 0x00, 0x08, 0xf1, 0x03, 0x15, 0xfe,
|
||||
0x09, 0x18, 0x0a, 0x07, 0x13, 0x0b, 0x05, 0x06, 0x08, 0x07, 0x02, 0x07, 0x0d, 0x08, 0x0a, 0x15,
|
||||
0x11, 0x0f, 0x15, 0x11, 0x0a, 0x0a, 0x03, 0xfd, 0xf7, 0xf0, 0xea, 0xe4, 0xda, 0xdb, 0xd7, 0xcb,
|
||||
0xce, 0xd2, 0xc2, 0xda, 0x06, 0xc9, 0xff, 0x2b, 0xea, 0x11, 0x2c, 0x11, 0x0a, 0x26, 0x0e, 0x0b,
|
||||
0x0f, 0xfc, 0x0d, 0xfc, 0xf1, 0x05, 0xfe, 0xeb, 0x02, 0x06, 0xef, 0x03, 0x0d, 0x01, 0x04, 0x0f,
|
||||
0x0f, 0x07, 0x0d, 0x11, 0x0a, 0x06, 0x0e, 0x0b, 0x06, 0x0e, 0x10, 0x0b, 0x0f, 0x13, 0x0c, 0x0b,
|
||||
0x0c, 0x06, 0xff, 0xfb, 0xf8, 0xef, 0xe7, 0xe2, 0xdf, 0xd6, 0xd5, 0xcf, 0xcd, 0xc7, 0xde, 0xee,
|
||||
0xc3, 0x04, 0x06, 0xe2, 0x15, 0x14, 0x08, 0x13, 0x21, 0x11, 0x17, 0x12, 0x11, 0x14, 0xfe, 0x0c,
|
||||
0x0b, 0xf7, 0xff, 0x06, 0xf3, 0xf9, 0x02, 0xfa, 0xfe, 0x02, 0x02, 0x05, 0x04, 0x09, 0x0a, 0x06,
|
||||
0x0d, 0x0c, 0x08, 0x0f, 0x0f, 0x0b, 0x12, 0x12, 0x0e, 0x10, 0x0d, 0x0a, 0x09, 0x04, 0xff, 0xfb,
|
||||
0xf8, 0xef, 0xe9, 0xe4, 0xe4, 0xd8, 0xd9, 0xd5, 0xd1, 0xcd, 0xe7, 0xde, 0xce, 0x0e, 0xe7, 0xf0,
|
||||
0x15, 0x00, 0x0b, 0x15, 0x15, 0x14, 0x19, 0x0f, 0x1d, 0x0c, 0x08, 0x18, 0x02, 0x02, 0x0c, 0xfd,
|
||||
0xfb, 0x03, 0xfa, 0xfd, 0x00, 0xfe, 0x00, 0x00, 0x03, 0x06, 0x02, 0x09, 0x09, 0x06, 0x0e, 0x0c,
|
||||
0x0a, 0x11, 0x10, 0x0e, 0x12, 0x0d, 0x0b, 0x0c, 0x08, 0x02, 0xff, 0xfe, 0xf8, 0xee, 0xef, 0xe9,
|
||||
0xe3, 0xe1, 0xde, 0xd9, 0xd8, 0xd3, 0xe1, 0xe1, 0xd1, 0x01, 0xe7, 0xe8, 0x0e, 0xf9, 0x06, 0x0e,
|
||||
0x10, 0x0f, 0x15, 0x11, 0x1a, 0x0e, 0x0d, 0x1a, 0x05, 0x0a, 0x0e, 0x00, 0x00, 0x05, 0xfa, 0xff,
|
||||
0x00, 0xfb, 0xfe, 0xff, 0x00, 0x00, 0x02, 0x04, 0x04, 0x04, 0x0a, 0x08, 0x09, 0x0f, 0x0c, 0x0c,
|
||||
0x10, 0x0b, 0x09, 0x0c, 0x07, 0x02, 0x00, 0xff, 0xf9, 0xf3, 0xf1, 0xec, 0xe9, 0xe5, 0xe1, 0xdf,
|
||||
0xdc, 0xd9, 0xdd, 0xe4, 0xdb, 0xee, 0xf3, 0xe8, 0xff, 0xff, 0x00, 0x08, 0x0e, 0x0b, 0x0e, 0x15,
|
||||
0x0f, 0x11, 0x0f, 0x12, 0x0d, 0x0a, 0x0c, 0x07, 0x03, 0x03, 0x03, 0xff, 0x00, 0x00, 0xfe, 0xff,
|
||||
0x01, 0x00, 0x00, 0x03, 0x02, 0x04, 0x07, 0x08, 0x09, 0x0b, 0x0c, 0x0d, 0x0d, 0x0c, 0x0c, 0x0b,
|
||||
0x09, 0x06, 0x03, 0x02, 0xfc, 0xf8, 0xf8, 0xf4, 0xee, 0xeb, 0xeb, 0xe7, 0xe4, 0xe2, 0xe1, 0xe4,
|
||||
0xe8, 0xe8, 0xee, 0xf5, 0xf5, 0xf9, 0x00, 0x04, 0x06, 0x08, 0x0c, 0x0e, 0x0e, 0x0e, 0x10, 0x0f,
|
||||
0x0e, 0x0d, 0x0c, 0x0a, 0x08, 0x06, 0x05, 0x04, 0x03, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x04,
|
||||
0x05, 0x06, 0x07, 0x09, 0x0a, 0x0a, 0x0c, 0x0c, 0x0a, 0x0b, 0x0c, 0x09, 0x07, 0x07, 0x07, 0x01,
|
||||
0x00, 0x00, 0xfc, 0xf9, 0xf6, 0xf4, 0xf2, 0xee, 0xeb, 0xea, 0xe9, 0xe6, 0xe6, 0xeb, 0xed, 0xec,
|
||||
0xef, 0xf2, 0xf5, 0xf9, 0xfe, 0x00, 0x04, 0x08, 0x09, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c, 0x0c, 0x0a,
|
||||
0x08, 0x07, 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x05, 0x07, 0x09, 0x0a,
|
||||
0x0d, 0x10, 0x10, 0x10, 0x12, 0x12, 0x0f, 0x0e, 0x0e, 0x0d, 0x07, 0x06, 0x06, 0x01, 0xfe, 0xfc,
|
||||
0xfa, 0xf6, 0xf3, 0xf0, 0xef, 0xec, 0xe9, 0xea, 0xec, 0xef, 0xf0, 0xf3, 0xf6, 0xf8, 0xfc, 0x00,
|
||||
0x03, 0x04, 0x07, 0x09, 0x09, 0x09, 0x09, 0x0a, 0x09, 0x08, 0x07, 0x05, 0x04, 0x03, 0x02, 0x01,
|
||||
0x00, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfd, 0xfe, 0xfd, 0xfe, 0xff, 0x00, 0x00, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfc, 0xfc, 0xf8, 0xf6, 0xf4, 0xf1, 0xee, 0xec, 0xea, 0xe8,
|
||||
0xe5, 0xe2, 0xe5, 0xe7, 0xe8, 0xea, 0xee, 0xf1, 0xf4, 0xfa, 0xfd, 0x00, 0x03, 0x04, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x09, 0x08, 0x08, 0x07, 0x06, 0x05, 0x05, 0x04, 0x02, 0x01, 0x01, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00, 0x01, 0x00, 0x00,
|
||||
0xfd, 0xfc, 0xfb, 0xf7, 0xf5, 0xf2, 0xf0, 0xec, 0xe9, 0xe8, 0xe5, 0xe2, 0xe0, 0xe4, 0xe4, 0xe5,
|
||||
0xe9, 0xec, 0xf0, 0xf4, 0xfa, 0xfd, 0x00, 0x03, 0x04, 0x05, 0x08, 0x08, 0x08, 0x0a, 0x09, 0x08,
|
||||
0x08, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x01, 0x01, 0x02, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01,
|
||||
0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x02, 0x00, 0x00, 0x00, 0x00, 0xfd, 0xfc, 0xfc, 0xf8, 0xf5,
|
||||
0xf3, 0xf1, 0xed, 0xeb, 0xe9, 0xe7, 0xe4, 0xe3, 0xe7, 0xe7, 0xe7, 0xec, 0xef, 0xf2, 0xf7, 0xfb,
|
||||
0xfe, 0x01, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, 0x0a, 0x09, 0x08, 0x08, 0x07, 0x06,
|
||||
0x06, 0x05, 0x03, 0x03, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x03, 0x02, 0x02, 0x02, 0x00, 0xff, 0xff, 0xfd, 0xfa, 0xf8, 0xf6, 0xf4, 0xf1, 0xef, 0xed,
|
||||
0xeb, 0xe9, 0xe7, 0xe8, 0xe8, 0xe9, 0xec, 0xee, 0xf2, 0xf5, 0xf9, 0xfd, 0x00, 0x02, 0x06, 0x08,
|
||||
0x09, 0x0a, 0x0c, 0x0c, 0x0c, 0x0b, 0x0a, 0x09, 0x09, 0x08, 0x07, 0x06, 0x06, 0x04, 0x03, 0x03,
|
||||
0x03, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05, 0x04, 0x03,
|
||||
0x02, 0x02, 0x00, 0xff, 0xfe, 0xfb, 0xfa, 0xf7, 0xf5, 0xf3, 0xf1, 0xef, 0xee, 0xec, 0xea, 0xea,
|
||||
0xe9, 0xeb, 0xed, 0xee, 0xf0, 0xf3, 0xf8, 0xfb, 0xfe, 0x00, 0x04, 0x06, 0x07, 0x09, 0x0a, 0x0b,
|
||||
0x0b, 0x0a, 0x0a, 0x09, 0x08, 0x07, 0x06, 0x06, 0x05, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xfd,
|
||||
0xfc, 0xfa, 0xf9, 0xf7, 0xf6, 0xf4, 0xf2, 0xf1, 0xf0, 0xef, 0xee, 0xed, 0xec, 0xec, 0xee, 0xee,
|
||||
0xf0, 0xf2, 0xf4, 0xf6, 0xfa, 0xfe, 0x00, 0x03, 0x06, 0x08, 0x0a, 0x0b, 0x0c, 0x0c, 0x0c, 0x0c,
|
||||
0x0c, 0x0a, 0x0a, 0x0a, 0x0a, 0x08, 0x08, 0x07, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x05, 0x05,
|
||||
0x05, 0x05, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x05, 0x04, 0x03, 0x02, 0x00, 0x00, 0xfe,
|
||||
0xfd, 0xfb, 0xf9, 0xf8, 0xf7, 0xf5, 0xf4, 0xf3, 0xf1, 0xf0, 0xef, 0xee, 0xee, 0xef, 0xf0, 0xf2,
|
||||
0xf4, 0xf6, 0xfa, 0xfe, 0x00, 0x02, 0x05, 0x06, 0x08, 0x0a, 0x0b, 0x0b, 0x0b, 0x0b, 0x0b, 0x0a,
|
||||
0x08, 0x09, 0x09, 0x08, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x05, 0x06, 0x06, 0x06,
|
||||
0x07, 0x06, 0x07, 0x07, 0x07, 0x07, 0x06, 0x05, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0xff, 0xfd,
|
||||
0xfc, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xf6, 0xf5, 0xf5, 0xf5, 0xf4, 0xf5, 0xf6, 0xf6, 0xf7,
|
||||
0xf9, 0xfb, 0xfc, 0xfd, 0xff, 0x01, 0x02, 0x04, 0x05, 0x07, 0x08, 0x08, 0x09, 0x09, 0x09, 0x09,
|
||||
0x08, 0x07, 0x07, 0x08, 0x08, 0x07, 0x07, 0x07, 0x07, 0x07, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
|
||||
0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x01, 0x00,
|
||||
0x00, 0xff, 0xfd, 0xfc, 0xfb, 0xfb, 0xfa, 0xf9, 0xf8, 0xf8, 0xf7, 0xf6, 0xf6, 0xf5, 0xf4, 0xf4,
|
||||
0xf4, 0xf3, 0xf2, 0xf2, 0xf3, 0xf4, 0xf3, 0xf4, 0xf5, 0xf6, 0xf8, 0xfa, 0xfa, 0xfc, 0xfd, 0xfe,
|
||||
0xff, 0x00, 0x01, 0x03, 0x05, 0x07, 0x08, 0x0b, 0x0c, 0x0d, 0x0f, 0x0f, 0x10, 0x10, 0x10, 0x10,
|
||||
0x0e, 0x0d, 0x0c, 0x0a, 0x09, 0x08, 0x07, 0x07, 0x05, 0x05, 0x05, 0x03, 0x01, 0x00, 0xff, 0xfc,
|
||||
0xfc, 0xf9, 0xfa, 0xf9, 0xf9, 0xfb, 0xf8, 0xfb, 0xf9, 0xfb, 0xf9, 0xfc, 0xf9, 0xfc, 0xfc, 0xf9,
|
||||
0xfc, 0xf8, 0xfe, 0xf6, 0xf9, 0xf6, 0xf8, 0xf7, 0xf5, 0xf7, 0xf5, 0xf8, 0xf5, 0xf8, 0xf5, 0xf9,
|
||||
0xf6, 0xf8, 0xf8, 0xf6, 0xfa, 0xf7, 0xfa, 0xf8, 0xf9, 0xfa, 0xf8, 0xf8, 0xf8, 0xf9, 0xf8, 0xf7,
|
||||
0xf8, 0xf7, 0xf8, 0xf8, 0xf7, 0xf9, 0xfa, 0xfb, 0xfb, 0xfd, 0xfd, 0xff, 0xff, 0x00, 0x03, 0x05,
|
||||
0x04, 0x05, 0x07, 0x09, 0x0a, 0x09, 0x0a, 0x0b, 0x0a, 0x0a, 0x0b, 0x0a, 0x0a, 0x09, 0x0a, 0x09,
|
||||
0x07, 0x06, 0x05, 0x03, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x01, 0x01, 0x03, 0x02, 0x04, 0x05, 0x05, 0x05, 0x05, 0x06, 0x05, 0x04, 0x04, 0x03,
|
||||
0x03, 0x00, 0x00, 0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb,
|
||||
0xfb, 0xfa, 0xfa, 0xf9, 0xfb, 0xf9, 0xf9, 0xf9, 0xfa, 0xfa, 0xf8, 0xfa, 0xfa, 0xfa, 0xf9, 0xfa,
|
||||
0xf9, 0xfa, 0xfa, 0xfa, 0xf9, 0xf8, 0xf9, 0xf7, 0xf9, 0xf9, 0xf9, 0xf8, 0xf9, 0xf8, 0xf9, 0xf8,
|
||||
0xf9, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf6, 0xf8, 0xf7, 0xf7, 0xf8, 0xf7, 0xf9, 0xf9, 0xf9, 0xfa,
|
||||
0xfb, 0xfb, 0xfa, 0xfc, 0xfc, 0xfd, 0xfc, 0xfc, 0xfe, 0xfc, 0xfe, 0xfd, 0xff, 0xfe, 0xff, 0xfe,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xfd, 0xff, 0x00, 0xff, 0xfe, 0xff, 0xff, 0x00,
|
||||
0xfe, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x01, 0x01, 0x00, 0x03, 0x01, 0x02, 0x00, 0x02, 0x01,
|
||||
0x00, 0x01, 0x01, 0x02, 0x00, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0xfe, 0x01, 0xff, 0x00, 0xff, 0x00, 0x00, 0xff, 0x00, 0xfe, 0x00, 0xff, 0xff, 0xfe, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0x00, 0xff, 0x00, 0xfe, 0x00, 0xff, 0xfe, 0xff, 0xfe, 0x01, 0xff, 0xff,
|
||||
0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00,
|
||||
0x00, 0xff, 0xff, 0x00, 0xff, 0xfe, 0x00, 0x00, 0x00, 0xfe, 0xfe, 0xff, 0xff, 0x00, 0xfe, 0xfe,
|
||||
0xff, 0xff, 0x00, 0xff, 0xfe, 0x00, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xfd, 0xff, 0xfe, 0xfe,
|
||||
0xfe, 0xfd, 0xfe, 0xfd, 0xfe, 0xfe, 0xfd, 0xfd, 0xff, 0xfd, 0xfe, 0xfd, 0xff, 0x00, 0xfe, 0xff,
|
||||
0xfe, 0x00, 0xfd, 0xff, 0xff, 0x00, 0x00, 0xfd, 0x00, 0xfe, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0xfe, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0xfe, 0x00, 0x01, 0x00, 0x00, 0xff, 0x01,
|
||||
0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0xff, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xfe, 0xff, 0x00,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xfe, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0xfd, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe,
|
||||
0xfe, 0xfe, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x01, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xfd,
|
||||
0xff, 0xff, 0xfd, 0xff, 0xfe, 0xff, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0x00, 0xff, 0xff,
|
||||
0x00, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff,
|
||||
0xff, 0xff, 0xff, 0xfe, 0x00, 0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfe,
|
||||
0xfd, 0xfd, 0xfc, 0xfe, 0xfd, 0xfc, 0xfc, 0xfd, 0xfb, 0xfb, 0xfb, 0xfb, 0xfd, 0xfc, 0xfb, 0xfc,
|
||||
0xfc, 0xfc, 0xfc, 0xfb, 0xff, 0xfc, 0xfd, 0xfc, 0xfc, 0xfd, 0xfc, 0xfd, 0xfb, 0xfd, 0xfd, 0xfc,
|
||||
0xfb, 0xfc, 0xfd, 0xfc, 0xfb, 0xfd, 0xfb, 0xfb, 0xfc, 0xfb, 0xfd, 0xfc, 0xfc, 0xfc, 0xfb, 0xfb,
|
||||
0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfd, 0xfc, 0xfd, 0xfc, 0xfd, 0xfe, 0xfd, 0xfd, 0xfc, 0xfe, 0xfc,
|
||||
0xfd, 0xfc, 0xfd, 0xfe, 0xfc, 0xfd, 0xfe, 0xfe, 0xfc, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfe, 0xff, 0xfe, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xfe, 0xff, 0x00, 0xfe, 0x00, 0xfe,
|
||||
0xff, 0x00, 0xfe, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x01,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xff, 0x02, 0x01, 0x00,
|
||||
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xff, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||
0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x00, 0xff,
|
||||
0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xfe, 0x02, 0x00, 0x00, 0x00, 0xfe, 0x01, 0x02, 0x00, 0x04, 0x05, 0x02,
|
||||
0x03, 0x02, 0x04, 0x02, 0x00, 0xff, 0x02, 0x00, 0xfe, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02,
|
||||
0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff,
|
||||
0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfe, 0xff, 0xfe, 0xfd, 0xfd,
|
||||
0xfd, 0xfd, 0xfb, 0xfb, 0xfb, 0xf9, 0xf8, 0xf7, 0xf7, 0xf7, 0xf6, 0xf5, 0xf4, 0xf3, 0xf1, 0xef,
|
||||
0xed, 0xef, 0xf8, 0xfc, 0xfc, 0x00, 0x04, 0x08, 0x0a, 0x09, 0x08, 0x0b, 0x0b, 0x06, 0x03, 0x03,
|
||||
0x04, 0x02, 0x01, 0x02, 0x03, 0x06, 0x06, 0x05, 0x08, 0x0a, 0x0a, 0x0a, 0x0a, 0x0b, 0x0b, 0x08,
|
||||
0x04, 0x03, 0x02, 0x00, 0xfd, 0xfb, 0xfb, 0xfa, 0xf9, 0xf7, 0xf6, 0xf4, 0xf1, 0xee, 0xe9, 0xe3,
|
||||
0xdd, 0xd7, 0xd5, 0xef, 0xfb, 0xf1, 0xfd, 0x0b, 0x11, 0x15, 0x11, 0x09, 0x10, 0x12, 0x02, 0xfa,
|
||||
0xf8, 0xf4, 0xf1, 0xed, 0xe8, 0xee, 0xf9, 0xfb, 0xfb, 0x03, 0x0c, 0x11, 0x13, 0x11, 0x13, 0x18,
|
||||
0x14, 0x0c, 0x0a, 0x08, 0x04, 0x00, 0xfb, 0xfc, 0x00, 0x00, 0x00, 0x04, 0x09, 0x0c, 0x0c, 0x09,
|
||||
0x08, 0x07, 0x01, 0xfb, 0xf6, 0xf2, 0xee, 0xe8, 0xe2, 0xdd, 0xdc, 0xd6, 0xd2, 0xcc, 0xeb, 0x0f,
|
||||
0xff, 0x05, 0x1c, 0x23, 0x26, 0x1e, 0x0b, 0x0a, 0x12, 0xfd, 0xe7, 0xe5, 0xe6, 0xeb, 0xef, 0xe9,
|
||||
0xf0, 0x09, 0x17, 0x12, 0x15, 0x1f, 0x21, 0x1f, 0x10, 0x03, 0x04, 0x01, 0xf2, 0xe9, 0xf3, 0xfc,
|
||||
0x01, 0x05, 0x0b, 0x18, 0x20, 0x1b, 0x15, 0x17, 0x16, 0x0e, 0x05, 0x00, 0x01, 0x01, 0xfa, 0xf6,
|
||||
0xf9, 0xfb, 0xf9, 0xf7, 0xf7, 0xf9, 0xf7, 0xf0, 0xea, 0xe7, 0xde, 0xd9, 0xce, 0xd2, 0x0a, 0x06,
|
||||
0xf2, 0x13, 0x1e, 0x22, 0x22, 0x10, 0x02, 0x0d, 0x0a, 0xe5, 0xdf, 0xee, 0xeb, 0xf0, 0xf3, 0xf1,
|
||||
0x07, 0x1e, 0x14, 0x0b, 0x1b, 0x1b, 0x10, 0x07, 0xf6, 0xf2, 0xfa, 0xf2, 0xe1, 0xec, 0xfc, 0x01,
|
||||
0x0d, 0x12, 0x1c, 0x2a, 0x23, 0x14, 0x14, 0x0f, 0x04, 0xfc, 0xf6, 0xf9, 0x00, 0xff, 0xfc, 0x05,
|
||||
0x0b, 0x09, 0x04, 0x00, 0x00, 0x00, 0xf6, 0xed, 0xeb, 0xe7, 0xe0, 0xda, 0xd6, 0xd4, 0xd6, 0xd6,
|
||||
0x09, 0x20, 0x01, 0x1e, 0x2d, 0x22, 0x1e, 0x08, 0xf5, 0xf4, 0xf8, 0xdd, 0xce, 0xed, 0xf2, 0xf8,
|
||||
0x08, 0x07, 0x17, 0x29, 0x20, 0x09, 0x0c, 0x0d, 0xf6, 0xee, 0xe4, 0xde, 0xef, 0xf4, 0xee, 0xfa,
|
||||
0x14, 0x16, 0x14, 0x17, 0x14, 0x1b, 0x15, 0x03, 0xfd, 0x04, 0x01, 0xfb, 0xfb, 0x01, 0x0d, 0x10,
|
||||
0x09, 0x0b, 0x14, 0x0f, 0x05, 0x00, 0xff, 0xfc, 0xf5, 0xeb, 0xed, 0xf2, 0xee, 0xea, 0xeb, 0xee,
|
||||
0xed, 0xe4, 0xda, 0xdc, 0xd7, 0x08, 0x28, 0xf7, 0x0d, 0x28, 0x16, 0x11, 0x00, 0xf1, 0xf3, 0xfd,
|
||||
0xe8, 0xd1, 0xf9, 0x05, 0xfc, 0x0b, 0x09, 0x13, 0x21, 0x14, 0xfb, 0xfb, 0x08, 0xf1, 0xe7, 0xed,
|
||||
0xea, 0xfc, 0x02, 0xfa, 0x01, 0x17, 0x18, 0x05, 0x08, 0x03, 0x01, 0x07, 0xf8, 0xf9, 0x09, 0x0a,
|
||||
0x04, 0x0b, 0x0e, 0x12, 0x16, 0x09, 0x04, 0x0c, 0x06, 0xfa, 0xfc, 0xfd, 0xfd, 0xff, 0xfc, 0xfb,
|
||||
0x00, 0xfd, 0xf4, 0xf4, 0xf1, 0xef, 0xec, 0xe8, 0xe2, 0xe1, 0xda, 0xd1, 0xd4, 0x00, 0x2c, 0x01,
|
||||
0x08, 0x33, 0x1f, 0x18, 0x03, 0xe8, 0xf0, 0xf7, 0xe4, 0xcc, 0xeb, 0x0a, 0x00, 0x0c, 0x11, 0x14,
|
||||
0x28, 0x17, 0xfa, 0xf4, 0x00, 0xf2, 0xdd, 0xe6, 0xea, 0xfb, 0x0a, 0x00, 0x06, 0x1c, 0x20, 0x0a,
|
||||
0x01, 0x01, 0xfa, 0xf7, 0xf8, 0xf6, 0xfe, 0x0e, 0x0c, 0x0d, 0x17, 0x17, 0x0f, 0x0d, 0x07, 0x01,
|
||||
0x02, 0xfd, 0xfa, 0x01, 0x03, 0x00, 0x03, 0x03, 0x01, 0x00, 0xfb, 0xf4, 0xf4, 0xf1, 0xe9, 0xea,
|
||||
0xec, 0xea, 0xe9, 0xe4, 0xe3, 0xe1, 0xdc, 0xdb, 0x12, 0x2f, 0xf8, 0x12, 0x2f, 0x0f, 0x0e, 0xf8,
|
||||
0xe0, 0xed, 0xf5, 0xe4, 0xd3, 0xfd, 0x14, 0x03, 0x16, 0x14, 0x12, 0x21, 0x08, 0xed, 0xec, 0xf9,
|
||||
0xea, 0xdd, 0xf0, 0xf5, 0x05, 0x13, 0x06, 0x0d, 0x1d, 0x16, 0xfd, 0xf6, 0xf9, 0xef, 0xf0, 0xfd,
|
||||
0xfa, 0x03, 0x18, 0x13, 0x10, 0x18, 0x12, 0x06, 0x05, 0xfd, 0xfb, 0x00, 0xfd, 0xfd, 0x06, 0x07,
|
||||
0x03, 0x05, 0x01, 0xff, 0xff, 0xf7, 0xf2, 0xf5, 0xf5, 0xef, 0xee, 0xef, 0xf1, 0xf2, 0xec, 0xe9,
|
||||
0xea, 0xe6, 0xdc, 0xd7, 0xea, 0x2c, 0x15, 0xef, 0x29, 0x23, 0x0c, 0x08, 0xe8, 0xe8, 0xf7, 0xef,
|
||||
0xd8, 0xde, 0x10, 0x0d, 0x01, 0x17, 0x0f, 0x1b, 0x19, 0xf7, 0xeb, 0xf6, 0xfa, 0xe1, 0xe2, 0xf9,
|
||||
0xfd, 0x0d, 0x0d, 0x03, 0x16, 0x1b, 0x08, 0xf3, 0xf8, 0xf9, 0xf1, 0xfe, 0xfa, 0xff, 0x15, 0x16,
|
||||
0x0b, 0x13, 0x15, 0x09, 0x04, 0xfe, 0xfb, 0x02, 0x01, 0xfb, 0x05, 0x0c, 0x05, 0x03, 0x03, 0x00,
|
||||
0xff, 0xfc, 0xf3, 0xf4, 0xf9, 0xf3, 0xf1, 0xf1, 0xf3, 0xf3, 0xef, 0xed, 0xef, 0xee, 0xe7, 0xe2,
|
||||
0xe0, 0xd8, 0xfb, 0x33, 0x00, 0xf9, 0x34, 0x19, 0x05, 0x01, 0xe9, 0xec, 0xf5, 0xeb, 0xd7, 0xed,
|
||||
0x1a, 0x04, 0x04, 0x1c, 0x11, 0x18, 0x0e, 0xf3, 0xee, 0xf9, 0xf4, 0xdc, 0xeb, 0x01, 0xfe, 0x0c,
|
||||
0x0b, 0x09, 0x17, 0x14, 0xff, 0xf2, 0xfd, 0xf9, 0xfb, 0xfd, 0xfa, 0x0b, 0x16, 0x0c, 0x0a, 0x15,
|
||||
0x0f, 0x06, 0x02, 0x00, 0x02, 0x04, 0xfd, 0xff, 0x0a, 0x07, 0x01, 0x01, 0x02, 0x00, 0xfd, 0xf7,
|
||||
0xf6, 0xf9, 0xf7, 0xf0, 0xf2, 0xf4, 0xf2, 0xf1, 0xef, 0xef, 0xf3, 0xee, 0xe5, 0xe8, 0xe7, 0xdd,
|
||||
0xe5, 0x25, 0x1f, 0xec, 0x22, 0x2a, 0x03, 0x08, 0xf4, 0xe6, 0xf2, 0xf2, 0xe0, 0xde, 0x0c, 0x13,
|
||||
0xfb, 0x16, 0x17, 0x10, 0x14, 0xfd, 0xee, 0xf4, 0xfa, 0xe6, 0xe0, 0xff, 0x00, 0x02, 0x0f, 0x0a,
|
||||
0x12, 0x17, 0x0a, 0xf7, 0xf9, 0x03, 0x00, 0xf7, 0xfc, 0x0a, 0x0f, 0x0c, 0x09, 0x0f, 0x13, 0x0c,
|
||||
0x02, 0x02, 0x06, 0x02, 0xfd, 0xff, 0x05, 0x05, 0x00, 0xff, 0x02, 0x03, 0xfe, 0xfa, 0xfb, 0xfb,
|
||||
0xf7, 0xf2, 0xf4, 0xf6, 0xf3, 0xee, 0xef, 0xf3, 0xf4, 0xed, 0xed, 0xee, 0xed, 0xeb, 0xe7, 0xe7,
|
||||
0x08, 0x29, 0xfc, 0x00, 0x2a, 0x10, 0x00, 0xfb, 0xf0, 0xf5, 0xf6, 0xee, 0xe4, 0xfa, 0x17, 0x00,
|
||||
0x01, 0x18, 0x11, 0x0e, 0x03, 0xf8, 0xf7, 0xfb, 0xf4, 0xe3, 0xf4, 0x06, 0xfd, 0x03, 0x09, 0x0e,
|
||||
0x10, 0x0a, 0x00, 0xfd, 0x14, 0x02, 0xf2, 0x03, 0x0b, 0x02, 0x01, 0x08, 0x09, 0x12, 0x09, 0x02,
|
||||
0x0b, 0x0f, 0xff, 0xfd, 0x03, 0x01, 0xfe, 0xfc, 0xfd, 0x02, 0x05, 0xfb, 0xfd, 0x01, 0xfc, 0xf3,
|
||||
0xf3, 0xf3, 0xf2, 0xef, 0xeb, 0xf2, 0xf5, 0xf0, 0xed, 0xf0, 0xf2, 0xec, 0xe8, 0xed, 0xef, 0x11,
|
||||
0x1f, 0xf2, 0x0d, 0x28, 0x06, 0xfd, 0xfa, 0xf7, 0xf6, 0xef, 0xec, 0xe9, 0x02, 0x10, 0xf6, 0x08,
|
||||
0x1b, 0x0f, 0x08, 0x00, 0x00, 0xfc, 0xf9, 0xef, 0xe7, 0xfd, 0x00, 0xf5, 0x02, 0x0b, 0x10, 0x0a,
|
||||
0x09, 0x05, 0x06, 0x16, 0xfd, 0xfa, 0x0a, 0x06, 0xf9, 0x01, 0x09, 0x06, 0x0c, 0x08, 0x0b, 0x11,
|
||||
0x0c, 0x00, 0x05, 0x06, 0xfe, 0xfa, 0xfd, 0xfe, 0xff, 0xfe, 0xfc, 0x01, 0x00, 0xf9, 0xf7, 0xfb,
|
||||
0xf4, 0xf0, 0xee, 0xeb, 0xf2, 0xef, 0xe7, 0xef, 0xf5, 0xea, 0xe9, 0xf4, 0xf1, 0xff, 0x22, 0x03,
|
||||
0xfb, 0x27, 0x13, 0xf8, 0xfe, 0xfd, 0xf5, 0xee, 0xf0, 0xec, 0xf4, 0x0c, 0xfd, 0xfc, 0x1a, 0x13,
|
||||
0x06, 0x06, 0x07, 0x00, 0xf8, 0xf6, 0xed, 0xf3, 0xff, 0xf1, 0xf9, 0x0a, 0x0b, 0x07, 0x09, 0x0f,
|
||||
0x07, 0x14, 0x08, 0xfc, 0x0b, 0x07, 0xf8, 0xfe, 0x09, 0x00, 0x05, 0x09, 0x09, 0x0e, 0x0f, 0x04,
|
||||
0x06, 0x0b, 0x00, 0xfb, 0x00, 0xfe, 0xf9, 0xfd, 0xfc, 0xff, 0x00, 0xfa, 0xfa, 0xff, 0xfa, 0xf1,
|
||||
0xf4, 0xf4, 0xef, 0xf0, 0xee, 0xee, 0xf0, 0xee, 0xea, 0xec, 0xee, 0xe9, 0xf0, 0x1b, 0x12, 0xed,
|
||||
0x20, 0x24, 0xfe, 0x02, 0x02, 0xfb, 0xf4, 0xee, 0xea, 0xec, 0x02, 0xfd, 0xee, 0x14, 0x17, 0x05,
|
||||
0x0c, 0x10, 0x0b, 0x00, 0xfc, 0xf4, 0xf2, 0xfc, 0xed, 0xed, 0x04, 0x02, 0x00, 0x06, 0x12, 0x0e,
|
||||
0x11, 0x13, 0x08, 0x0e, 0x09, 0xfb, 0xfd, 0x04, 0xfb, 0xfc, 0x06, 0x07, 0x0b, 0x0c, 0x0a, 0x0d,
|
||||
0x0e, 0x02, 0x01, 0x04, 0xfe, 0xf9, 0xfc, 0xfd, 0xfc, 0xfd, 0xfa, 0xfc, 0xfe, 0xf9, 0xf7, 0xf8,
|
||||
0xf5, 0xf7, 0xf0, 0xed, 0xf3, 0xed, 0xe6, 0xe9, 0xef, 0xe7, 0xe9, 0xed, 0xfe, 0x1e, 0x00, 0xfe,
|
||||
0x2e, 0x16, 0xfe, 0x05, 0x05, 0xfe, 0xeb, 0xeb, 0xef, 0xf2, 0xfd, 0xee, 0xfd, 0x1b, 0x09, 0x05,
|
||||
0x13, 0x16, 0x09, 0xfd, 0x00, 0xfb, 0xf7, 0xf2, 0xe8, 0xfa, 0xfd, 0xf4, 0xfd, 0x09, 0x0e, 0x04,
|
||||
0x14, 0x1a, 0x0e, 0x0c, 0x0c, 0x06, 0x00, 0xfe, 0xf8, 0x00, 0x00, 0xfe, 0x04, 0x0c, 0x0a, 0x0a,
|
||||
0x0e, 0x0b, 0x09, 0x04, 0x00, 0xff, 0xfc, 0xf6, 0xf8, 0xfa, 0xf6, 0xf6, 0xf9, 0xf9, 0xf8, 0xf6,
|
||||
0xf7, 0xf9, 0xf3, 0xf3, 0xf4, 0xf1, 0xef, 0xef, 0xed, 0xec, 0xef, 0xeb, 0xed, 0xfc, 0x12, 0xff,
|
||||
0xfd, 0x26, 0x11, 0xfe, 0x0e, 0x0a, 0xfe, 0xf6, 0xf4, 0xf5, 0xf3, 0xf5, 0xee, 0xfb, 0x0c, 0xfc,
|
||||
0x01, 0x14, 0x0f, 0x07, 0x06, 0x0b, 0x04, 0xfd, 0xfa, 0xf5, 0xfc, 0xf5, 0xed, 0xfc, 0x02, 0x00,
|
||||
0x02, 0x11, 0x12, 0x0f, 0x10, 0x11, 0x0e, 0x07, 0x02, 0x02, 0x01, 0xfb, 0xfd, 0x02, 0x02, 0x01,
|
||||
0x05, 0x09, 0x0a, 0x07, 0x06, 0x08, 0x05, 0x00, 0xfe, 0xfe, 0xf9, 0xf5, 0xf4, 0xf6, 0xf5, 0xf2,
|
||||
0xf5, 0xf8, 0xf8, 0xf5, 0xf9, 0xf8, 0xf6, 0xf3, 0xf3, 0xf2, 0xed, 0xea, 0xe8, 0xec, 0xec, 0x06,
|
||||
0x00, 0xef, 0x1f, 0x18, 0xfc, 0x14, 0x17, 0x06, 0xff, 0xfe, 0xff, 0xf3, 0xf2, 0xee, 0xf0, 0x00,
|
||||
0xf0, 0xf6, 0x0d, 0x05, 0x03, 0x0d, 0x12, 0x0a, 0x05, 0x08, 0x00, 0x00, 0xf9, 0xf0, 0xfb, 0xf5,
|
||||
0xee, 0xf8, 0xff, 0x0a, 0x03, 0x07, 0x1c, 0x13, 0x09, 0x11, 0x14, 0x04, 0x03, 0x03, 0x00, 0xfc,
|
||||
0xfa, 0xfe, 0x00, 0xfe, 0xff, 0x09, 0x06, 0x02, 0x07, 0x09, 0x03, 0x01, 0x00, 0xfd, 0xf9, 0xf4,
|
||||
0xf4, 0xf3, 0xf0, 0xef, 0xf1, 0xf2, 0xf3, 0xf5, 0xf7, 0xf8, 0xf7, 0xf8, 0xf7, 0xf5, 0xf1, 0xf1,
|
||||
0xef, 0xec, 0x05, 0xfb, 0xe7, 0x18, 0x0d, 0xf3, 0x14, 0x12, 0x03, 0x05, 0x07, 0x05, 0xfd, 0xfb,
|
||||
0xf8, 0xf8, 0xfe, 0xeb, 0xf8, 0x05, 0xf4, 0xfc, 0x08, 0x04, 0x02, 0x07, 0x0d, 0x04, 0x05, 0x04,
|
||||
0x00, 0x03, 0xf7, 0xf9, 0xff, 0xf8, 0xf5, 0x09, 0x01, 0xfa, 0x14, 0x0b, 0x05, 0x11, 0x11, 0x07,
|
||||
0x0d, 0x08, 0x05, 0x07, 0xfe, 0x00, 0x02, 0xfc, 0xfb, 0x03, 0xfc, 0xfe, 0x04, 0x00, 0x00, 0x03,
|
||||
0x01, 0x00, 0xff, 0xfb, 0xfe, 0xf9, 0xf4, 0xf7, 0xf6, 0xf0, 0xf4, 0xf6, 0xf2, 0xf4, 0xf7, 0xf6,
|
||||
0xf6, 0xf8, 0xf5, 0xf7, 0xf5, 0xf3, 0xf4, 0xf9, 0x02, 0xf7, 0xfb, 0x12, 0xff, 0xfe, 0x12, 0x06,
|
||||
0x02, 0x07, 0x05, 0x04, 0xfe, 0xfe, 0xff, 0xfc, 0xf7, 0xf6, 0x00, 0xf9, 0xf4, 0x02, 0x00, 0xfd,
|
||||
0x03, 0x06, 0x05, 0x03, 0x06, 0x05, 0x02, 0x01, 0xff, 0x01, 0xfb, 0xfb, 0x06, 0xfa, 0xfc, 0x0a,
|
||||
0x01, 0x00, 0x0c, 0x08, 0x04, 0x0a, 0x08, 0x07, 0x06, 0x03, 0x05, 0x02, 0xfe, 0x01, 0x00, 0xfa,
|
||||
0x00, 0x00, 0xfd, 0xff, 0x00, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xfc, 0xfc, 0xfc, 0xf8, 0xf7, 0xfa,
|
||||
0xf6, 0xf4, 0xf9, 0xf7, 0xf4, 0xfa, 0xf8, 0xf5, 0xfa, 0xf7, 0xf4, 0xf7, 0xf4, 0xf3, 0xf5, 0xf4,
|
||||
0x02, 0xf7, 0xf7, 0x14, 0xfc, 0xff, 0x16, 0x03, 0x04, 0x0b, 0x05, 0x05, 0xff, 0x00, 0x00, 0xf9,
|
||||
0xf8, 0xf9, 0xfe, 0xf4, 0xf6, 0x02, 0xf8, 0xfb, 0x03, 0x00, 0x01, 0x02, 0x06, 0x05, 0x01, 0x05,
|
||||
0x04, 0x02, 0xfd, 0x02, 0x07, 0xf6, 0x02, 0x09, 0xfa, 0x01, 0x0a, 0x00, 0x01, 0x0a, 0x04, 0x05,
|
||||
0x05, 0x06, 0x06, 0x01, 0x03, 0x05, 0xff, 0x00, 0x04, 0xfd, 0xfe, 0x01, 0xfe, 0xfd, 0x00, 0xfe,
|
||||
0xfe, 0xfe, 0xfd, 0xff, 0xfc, 0xfc, 0xfd, 0xfb, 0xf9, 0xfb, 0xf8, 0xf6, 0xf9, 0xf6, 0xf6, 0xf8,
|
||||
0xf7, 0xf8, 0xf7, 0xf8, 0xf9, 0xf5, 0xf5, 0xf8, 0xf1, 0x00, 0xfd, 0xe9, 0x13, 0x01, 0xed, 0x1a,
|
||||
0x03, 0xfb, 0x12, 0x03, 0x05, 0x07, 0xfe, 0x09, 0xfe, 0xfa, 0x00, 0xfe, 0xf6, 0xf6, 0x01, 0xf4,
|
||||
0xf7, 0x03, 0xf9, 0xfd, 0x02, 0x00, 0x05, 0x00, 0x04, 0x07, 0x00, 0x02, 0x03, 0x01, 0xfa, 0x08,
|
||||
0x00, 0xf9, 0x0b, 0x00, 0xff, 0x07, 0x05, 0x00, 0x08, 0x04, 0x04, 0x05, 0x03, 0x07, 0x01, 0x03,
|
||||
0x05, 0x01, 0x00, 0x05, 0x00, 0xff, 0x03, 0xff, 0xfe, 0x00, 0xff, 0xfd, 0xff, 0xfd, 0xfd, 0xfc,
|
||||
0xfd, 0xfd, 0xfa, 0xfc, 0xfd, 0xf9, 0xf9, 0xfc, 0xf8, 0xf9, 0xf9, 0xf8, 0xf9, 0xf8, 0xf8, 0xf8,
|
||||
0xf8, 0xf7, 0xf6, 0xf7, 0xf4, 0x00, 0xfb, 0xef, 0x10, 0xfd, 0xf4, 0x16, 0xff, 0xff, 0x10, 0x00,
|
||||
0x08, 0x06, 0xff, 0x0b, 0xfe, 0xfd, 0x04, 0xfb, 0xf8, 0xfd, 0xfd, 0xf5, 0xfa, 0x00, 0xf7, 0xfd,
|
||||
0x00, 0xff, 0x02, 0xfe, 0x05, 0x03, 0xff, 0x05, 0x04, 0xff, 0x01, 0x02, 0x03, 0x00, 0xfe, 0x0b,
|
||||
0xff, 0x00, 0x0a, 0x01, 0x00, 0x09, 0x04, 0x00, 0x08, 0x03, 0x03, 0x03, 0x04, 0x03, 0x00, 0x02,
|
||||
0x02, 0xff, 0x00, 0x01, 0xfd, 0x00, 0x00, 0xfd, 0xfd, 0xff, 0xfc, 0xfb, 0xfc, 0xfb, 0xfa, 0xf9,
|
||||
0xfc, 0xfb, 0xfa, 0xfb, 0xfc, 0xf9, 0xfb, 0xfd, 0xf8, 0xfb, 0xfa, 0xf7, 0xf8, 0xf6, 0xf6, 0xf4,
|
||||
0xf1, 0xf7, 0xff, 0xef, 0xf9, 0x0d, 0xf0, 0x00, 0x11, 0xf8, 0x06, 0x0b, 0x00, 0x0b, 0x01, 0x03,
|
||||
0x0b, 0xf9, 0x02, 0x05, 0xf7, 0xfd, 0x00, 0xf9, 0xf7, 0xfd, 0xfb, 0xf7, 0xfd, 0xfd, 0xfd, 0xfd,
|
||||
0xfe, 0x03, 0xfe, 0x00, 0x07, 0x00, 0x00, 0x05, 0x01, 0x00, 0x00, 0x07, 0xff, 0xfe, 0x0b, 0xfd,
|
||||
0xff, 0x08, 0x00, 0xff, 0x08, 0x03, 0x00, 0x07, 0x04, 0x03, 0x02, 0x06, 0x02, 0x00, 0x03, 0x01,
|
||||
0xfd, 0x00, 0x01, 0xfa, 0xff, 0x00, 0xfc, 0xfc, 0xff, 0xfc, 0xfb, 0xfe, 0xfc, 0xfc, 0xfb, 0xfd,
|
||||
0xfb, 0xfa, 0xfd, 0xfb, 0xf8, 0xfc, 0xfc, 0xf8, 0xfc, 0xfb, 0xf9, 0xfa, 0xf9, 0xf8, 0xf7, 0xf5,
|
||||
0xf5, 0xf4, 0xfb, 0xf7, 0xef, 0x08, 0xfa, 0xf2, 0x10, 0xfd, 0xfd, 0x0f, 0x00, 0x06, 0x09, 0xff,
|
||||
0x0c, 0x00, 0xfe, 0x0a, 0xfa, 0xfb, 0x01, 0xfa, 0xf8, 0xfc, 0xfc, 0xf8, 0xfb, 0xfe, 0xfb, 0xfd,
|
||||
0xfe, 0x00, 0x00, 0xfd, 0x05, 0x01, 0xff, 0x06, 0x02, 0x02, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03,
|
||||
0x03, 0x02, 0x03, 0x01, 0x03, 0x02, 0x00, 0x03, 0x03, 0x00, 0x01, 0x04, 0x01, 0x01, 0x03, 0x01,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfd, 0xfd,
|
||||
0xfc, 0xfc, 0xfd, 0xfd, 0xfc, 0xfe, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfc, 0xfa, 0xf9, 0xfa,
|
||||
0xf8, 0xf8, 0xf7, 0xf5, 0xf8, 0xfe, 0xf0, 0xfb, 0x08, 0xed, 0x02, 0x0c, 0xf4, 0x07, 0x0a, 0xfe,
|
||||
0x0a, 0x04, 0x05, 0x0b, 0xfd, 0x08, 0x06, 0xfa, 0x03, 0x01, 0xfb, 0xfc, 0x00, 0xfb, 0xf9, 0x00,
|
||||
0xfd, 0xfa, 0x00, 0xff, 0xff, 0xff, 0x00, 0x04, 0x00, 0x01, 0x06, 0x02, 0x02, 0x08, 0x04, 0x03,
|
||||
0x08, 0x04, 0x03, 0x06, 0x05, 0x02, 0x04, 0x03, 0x01, 0x02, 0x02, 0x01, 0x00, 0x02, 0x02, 0x00,
|
||||
0x02, 0x03, 0x01, 0x01, 0x02, 0x00, 0x00, 0x01, 0x00, 0xff, 0x00, 0xff, 0xfd, 0xfe, 0xfe, 0xfc,
|
||||
0xfc, 0xfd, 0xfc, 0xfc, 0xfd, 0xfc, 0xfc, 0xfd, 0xfd, 0xfc, 0xfe, 0xfc, 0xfc, 0xfc, 0xfc, 0xfa,
|
||||
0xfb, 0xfa, 0xf8, 0xf8, 0xf6, 0xf6, 0xf9, 0xfc, 0xf1, 0xfd, 0x04, 0xee, 0x02, 0x08, 0xf5, 0x05,
|
||||
0x09, 0xfe, 0x06, 0x06, 0x03, 0x05, 0x00, 0x07, 0x01, 0xfd, 0x02, 0xff, 0xfc, 0xfb, 0x00, 0xfc,
|
||||
0xf7, 0xff, 0xfd, 0xf7, 0xff, 0xfe, 0xfa, 0xfe, 0xff, 0x00, 0xfc, 0x03, 0x03, 0xfd, 0x08, 0x04,
|
||||
0x00, 0x06, 0x07, 0x00, 0x04, 0x07, 0x00, 0x03, 0x04, 0x01, 0x00, 0x03, 0x00, 0xff, 0x01, 0x00,
|
||||
0xff, 0x00, 0x00, 0xff, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xfd, 0xfc, 0xfd,
|
||||
0xfc, 0xfa, 0xfc, 0xfb, 0xfa, 0xfb, 0xfb, 0xfa, 0xfb, 0xfc, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
|
||||
0xfb, 0xfa, 0xfb, 0xfa, 0xf9, 0xf8, 0xf7, 0xf6, 0xfb, 0xfc, 0xf1, 0x00, 0x01, 0xf1, 0x03, 0x06,
|
||||
0xf7, 0x01, 0x09, 0xff, 0x00, 0x07, 0x05, 0xfe, 0x02, 0x08, 0xfd, 0x00, 0x03, 0xfd, 0xfd, 0xfe,
|
||||
0xff, 0xfb, 0xf9, 0xfe, 0xfc, 0xf9, 0xfe, 0xff, 0xfc, 0xfd, 0x00, 0x01, 0xfc, 0x01, 0x04, 0xff,
|
||||
0x01, 0x05, 0x01, 0x00, 0x06, 0x03, 0x00, 0x05, 0x03, 0x00, 0x02, 0x03, 0x00, 0x00, 0x02, 0x00,
|
||||
0xff, 0x00, 0x00, 0xfe, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfd, 0xfd,
|
||||
0xfd, 0xfc, 0xfb, 0xfb, 0xfb, 0xfa, 0xfb, 0xfb, 0xfa, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc,
|
||||
0xfc, 0xfc, 0xfb, 0xfa, 0xfa, 0xfa, 0xf9, 0xf8, 0xf8, 0xf7, 0xf7, 0xfc, 0xf9, 0xf4, 0x00, 0x00,
|
||||
0xf6, 0x00, 0x05, 0xfe, 0xfe, 0x06, 0x06, 0xff, 0x02, 0x09, 0x00, 0xff, 0x06, 0x01, 0xfd, 0x00,
|
||||
0x00, 0xfd, 0xfb, 0xff, 0xfd, 0xfa, 0xfe, 0xfd, 0xfc, 0xfd, 0xfe, 0xfd, 0xfe, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x05, 0x00, 0x01, 0x05, 0x03, 0x01, 0x04, 0x05, 0x01, 0x03, 0x04, 0x01, 0x01,
|
||||
0x02, 0x00, 0x00, 0x01, 0xff, 0xff, 0x00, 0xff, 0xfe, 0x00, 0x00, 0xfd, 0x00, 0x00, 0xfe, 0xff,
|
||||
0xff, 0xfd, 0xfd, 0xfe, 0xfc, 0xfd, 0xfd, 0xfb, 0xfb, 0xfd, 0xfc, 0xfb, 0xfd, 0xfd, 0xfc, 0xfd,
|
||||
0xfd, 0xfc, 0xfd, 0xfd, 0xfc, 0xfc, 0xfd, 0xfc, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xfa, 0xfd,
|
||||
0xfb, 0xf9, 0xfe, 0x00, 0xfd, 0xfe, 0x01, 0x01, 0x00, 0x02, 0x03, 0x01, 0x02, 0x03, 0x01, 0x01,
|
||||
0x02, 0x00, 0x00, 0x00, 0x00, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x01, 0x02, 0x02, 0x00,
|
||||
0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfe, 0xfe,
|
||||
0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc,
|
||||
0xfc, 0xfc, 0xfc, 0xfc, 0xfb, 0xfb, 0xfc, 0xfc, 0xfb, 0xfc, 0xfc, 0xfd, 0xff, 0xfe, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x04, 0x04,
|
||||
0x05, 0x05, 0x05, 0x06, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x04, 0x05, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x03, 0x03, 0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xfe,
|
||||
0xfd, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfe, 0xff, 0xff, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd,
|
||||
0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
|
||||
0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb,
|
||||
0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfa, 0xfa, 0xfa, 0xf9, 0xf9,
|
||||
0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9, 0xf9,
|
||||
0xf9, 0xf9, 0xfa, 0xf9, 0xf9, 0xf9, 0xfa, 0xf9, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa,
|
||||
0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb, 0xfa, 0xfa, 0xfa, 0xfa, 0xfb,
|
||||
0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd,
|
||||
0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00,
|
||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00,
|
||||
0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01, 0x02, 0x02, 0x02, 0x02,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe,
|
||||
0xfe, 0xff, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd,
|
||||
0xfd, 0xfe, 0xfd, 0xfc, 0xfc, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe,
|
||||
0xff, 0xff, 0xfe, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xfe, 0xfe,
|
||||
0xff, 0xfe, 0xfd, 0xfe, 0xfe, 0xff, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfd, 0xfd, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc,
|
||||
0xfd, 0xfd, 0xfc, 0xfd, 0xfd, 0xfd, 0xfc, 0xfc, 0xfc, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd, 0xfd,
|
||||
0xfc, 0xfc, 0xfd, 0xfc, 0xfd, 0xfd, 0xfe, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
||||
0xfe, 0xfe, 0xfd, 0xfc, 0xfc, 0xfc, 0xfb, 0xfc, 0xfb, 0xf9, 0xfc, 0xf9, 0xfa, 0xf9, 0xf9, 0xfc,
|
||||
0xf8, 0xf9, 0xf9, 0xf9, 0xf8, 0xfa, 0xf6, 0xf8, 0xfb, 0xf6, 0xf9, 0xf7, 0xf9, 0xfa, 0xf7, 0xfa,
|
||||
0xf9, 0xfa, 0xfb, 0xfa, 0xfb, 0xfd, 0xfd, 0xfc, 0xff, 0xff, 0xfe, 0x00, 0x00, 0xfe, 0xff, 0x00,
|
||||
0xfe, 0xfd, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x03, 0x02,
|
||||
0x02, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01,
|
||||
0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe,
|
||||
0xff, 0xff, 0xff, 0xfe, 0xff, 0x05, 0x02, 0x00, 0x01, 0xfd, 0x01, 0x00, 0xfc, 0x01, 0xff, 0xff,
|
||||
0x00, 0xff, 0x00, 0xff, 0xfe, 0x05, 0x07, 0x01, 0x03, 0x06, 0x03, 0x01, 0x00, 0xff, 0xff, 0xfc,
|
||||
0xfe, 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x01, 0xff, 0x01, 0x00, 0x00, 0xff, 0x00, 0x01, 0x01,
|
||||
0x02, 0x00, 0x00, 0xfd, 0xff, 0xfe, 0xfd, 0x00, 0xfe, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff,
|
||||
0xfe, 0xfe, 0xfd, 0xfe, 0xfe, 0xfd, 0xff, 0xfe, 0xff, 0xfe, 0xfd, 0xff, 0xfd, 0xfe, 0xfc, 0xfe,
|
||||
0xfe, 0xfe, 0xff, 0xfc, 0x00, 0xfc, 0x00, 0xfc, 0xff, 0xfe, 0xfc, 0xff, 0xfa, 0x00, 0xfa, 0xfe,
|
||||
0xfb, 0xfd, 0xfe, 0xfa, 0xff, 0xfb, 0xfe, 0xfc, 0xfd, 0xfd, 0x00, 0x00, 0xff, 0x01, 0xff, 0xff,
|
||||
0xfa, 0xfb, 0xfc, 0xfd, 0xfa, 0xfc, 0xfe, 0xfd, 0xfe, 0xfc, 0xfe, 0xfe, 0xff, 0xfc, 0xfe, 0xfe,
|
||||
0xfd, 0xfd, 0xfb, 0xfc, 0xfa, 0xfc, 0xfa, 0xfd, 0xfc, 0xfe, 0xfd, 0xfc, 0xfe, 0xfc, 0xfe, 0xfb,
|
||||
0xfe, 0xfb, 0xfc, 0xfb, 0xfc, 0xfd, 0xfb, 0xfd, 0xfb, 0xfd, 0xfc, 0xfc, 0xfc, 0xfd, 0xfd, 0xfc,
|
||||
0xff, 0xfb, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfc, 0xfe, 0xfc, 0xfd, 0xfd, 0xfc, 0xfe, 0xfe,
|
||||
0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0x00, 0xfe, 0xff, 0xfe, 0xfc, 0xff, 0xfc, 0xfd,
|
||||
0xfd, 0xff, 0xfe, 0xfc, 0xfe, 0xfc, 0xff, 0xfb, 0xfe, 0xfe, 0xfd, 0xff, 0xfc, 0xff, 0xfd, 0xfe,
|
||||
0xfc, 0xfe, 0xfe, 0xfd, 0xfe, 0xfc, 0xff, 0xfd, 0xfe, 0xfc, 0xfe, 0xfe, 0xfd, 0xfd, 0xfc, 0xfe,
|
||||
0xfb, 0xfc, 0xfb, 0xfe, 0xfc, 0xfc, 0xfe, 0xfd, 0xfe, 0xfb, 0xfe, 0xfd, 0xfd, 0xfc, 0xfd, 0xff,
|
||||
0xfd, 0xff, 0xfe, 0x00, 0xfe, 0xff, 0xfe, 0x00, 0xff, 0xfe, 0xff, 0xff, 0x00, 0xff, 0x00, 0xff,
|
||||
0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x00, 0xfe, 0x00, 0xff, 0x00, 0x00, 0x00, 0x01, 0xff,
|
||||
0x01, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00,
|
||||
0xff, 0xff, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff,
|
||||
0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00,
|
||||
0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0xfe, 0xff, 0xfe, 0xff, 0xfd, 0xfe,
|
||||
0xfd, 0xfd, 0xfd, 0xfd, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0xff, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02,
|
||||
0x02, 0x02, 0x02, 0x03, 0x02, 0x02, 0x02, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff,
|
||||
0x00, 0x00, 0xff, 0x00, 0x00, 0xff, 0xff, 0xff, 0xfe, 0xff, 0xff, 0x00, 0x01, 0x01, 0x01, 0x00,
|
||||
0x01, 0x00, 0x00, 0xff, 0x00, 0xff, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfd, 0xfc, 0xfd, 0xfe, 0xfd,
|
||||
0xff, 0xfe, 0xff, 0xfe, 0xff, 0xfe, 0xff, 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x02, 0x02, 0x01,
|
||||
0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04,
|
||||
0x04, 0x03, 0x04, 0x04, 0x05, 0x04, 0x05, 0x05, 0x06, 0x06, 0x05, 0x05, 0x06, 0x06, 0x05, 0x05,
|
||||
0x05, 0x05, 0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x04, 0x04, 0x04, 0x04, 0x04, 0x03, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
|
||||
0x03, 0x03, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x03,
|
||||
0x03, 0x02, 0x02, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xfe, 0xfe, 0xfd, 0xfc,
|
||||
0xfc, 0xfc, 0xfb, 0xfb, 0xfa, 0xfa, 0xf9, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8, 0xf8,
|
||||
0xf8, 0xf9, 0xf9, 0xfa, 0xfa, 0xfa, 0xfb, 0xfb, 0xfb, 0xfc, 0xfc, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfd, 0xfd, 0xfd, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xff, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0xfe, 0xfe, 0xff, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe,
|
||||
0xfe, 0xfe, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
|
||||
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff,
|
||||
0xff, 0xff, 0x00, 0x00, 0x00
|
||||
};
|
||||
|
||||
const uint16_t Resource::_gameSavedSoundLen = 8005;
|
||||
|
||||
const Game::pge_OpcodeProc Game::_pge_opcodeTable[] = {
|
||||
/* 0x00 */
|
||||
0,
|
||||
|
@ -3214,6 +3733,174 @@ const uint8_t Game::_protectionCodeData[] = {
|
|||
0x37, 0x37, 0x39, 0xF9
|
||||
};
|
||||
|
||||
const uint8_t Game::_protectionWordData[] = {
|
||||
0x01, 0x01, 0x02, 0x05, 0xD7, 0x77, 0x3F, 0xF7, 0x27, 0x7F, 0xFF, 0x1F, 0xF7, 0x51, 0x51, 0x51,
|
||||
0x51, 0x00, 0x01, 0x01, 0x05, 0x03, 0xDF, 0xFF, 0xF7, 0x9F, 0x7F, 0x51, 0x51, 0x51, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x00, 0x01, 0x01, 0x05, 0x06, 0x97, 0x67, 0xF7, 0x3F, 0xF7, 0x1F, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x01, 0x02, 0x02, 0x07, 0x17, 0xD7, 0x97, 0x87, 0xFF, 0x5F,
|
||||
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x01, 0x02, 0x07, 0x01, 0x87, 0xF7, 0xCF, 0x17,
|
||||
0xA7, 0xD7, 0x1F, 0x77, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x02, 0x01, 0x03, 0x01, 0x5F, 0xA7,
|
||||
0xBF, 0xF7, 0x1F, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x02, 0x01, 0x05, 0x01,
|
||||
0xA7, 0x1F, 0xB7, 0xD7, 0x27, 0xC7, 0x0F, 0xD7, 0x7F, 0xC7, 0xA7, 0x27, 0x51, 0x00, 0x02, 0x02,
|
||||
0x01, 0x05, 0x97, 0xA7, 0x67, 0xA7, 0x27, 0xCF, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00,
|
||||
0x02, 0x02, 0x02, 0x01, 0xE7, 0xA7, 0xA7, 0x27, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
|
||||
0x51, 0x00, 0x02, 0x02, 0x05, 0x01, 0x1F, 0xF7, 0x37, 0xFF, 0xB7, 0xF7, 0xF7, 0x9F, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x00, 0x02, 0x03, 0x02, 0x04, 0x5F, 0x1F, 0xC7, 0x9F, 0xA7, 0x27, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x03, 0x01, 0x01, 0x04, 0x7F, 0xC7, 0x7F, 0xD7, 0x27, 0xB1,
|
||||
0x9F, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x03, 0x01, 0x04, 0x01, 0xD7, 0x97, 0x97, 0xC7,
|
||||
0x77, 0xF7, 0x27, 0x7F, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x03, 0x02, 0x01, 0x01, 0x5F, 0x1F,
|
||||
0xA7, 0x37, 0xF7, 0x9F, 0x9F, 0xA7, 0x1F, 0x51, 0x51, 0x51, 0x51, 0x00, 0x03, 0x02, 0x02, 0x05,
|
||||
0x7F, 0xF7, 0x67, 0xF7, 0x5F, 0xA7, 0x1F, 0x7F, 0xF7, 0x1F, 0x51, 0x51, 0x51, 0x00, 0x03, 0x02,
|
||||
0x04, 0x02, 0x97, 0x1F, 0xC7, 0xE7, 0xC7, 0x27, 0xD7, 0x67, 0x9F, 0x51, 0x51, 0x51, 0x51, 0x00,
|
||||
0x03, 0x03, 0x01, 0x01, 0x9F, 0x97, 0xC7, 0xF7, 0x27, 0x7F, 0xC7, 0x9F, 0x7F, 0x9F, 0x51, 0x51,
|
||||
0x51, 0x00, 0x03, 0x03, 0x02, 0x03, 0xB7, 0xF7, 0x27, 0xF7, 0x7F, 0xC7, 0x97, 0x51, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x00, 0x03, 0x03, 0x04, 0x01, 0xE7, 0xFF, 0x7F, 0xD7, 0x7F, 0xC7, 0xA7, 0x27,
|
||||
0x9F, 0x51, 0x51, 0x51, 0x51, 0x00, 0x04, 0x01, 0x01, 0x05, 0xF7, 0xCF, 0xF7, 0x9F, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x04, 0x01, 0x02, 0x01, 0x9F, 0xFF, 0x1F, 0x1F,
|
||||
0xA7, 0xFF, 0x27, 0x77, 0xC7, 0x27, 0xB7, 0x51, 0x51, 0x00, 0x04, 0x01, 0x03, 0x05, 0x17, 0x1F,
|
||||
0xD7, 0xC7, 0x27, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x04, 0x01, 0x04, 0x06,
|
||||
0xB7, 0x1F, 0xF7, 0xD7, 0x7F, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x05, 0x01,
|
||||
0x01, 0x03, 0xC7, 0x27, 0x7F, 0x1F, 0xA7, 0x77, 0xFF, 0x97, 0x7F, 0xC7, 0xA7, 0x27, 0x51, 0x00,
|
||||
0x05, 0x01, 0x05, 0x07, 0xA7, 0x5F, 0x7F, 0xC7, 0xA7, 0x27, 0x9F, 0x51, 0x51, 0x51, 0x51, 0x51,
|
||||
0x51, 0x00, 0x05, 0x01, 0x06, 0x06, 0xD7, 0x1F, 0x1F, 0xA7, 0xBF, 0x51, 0x51, 0x51, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x00, 0x05, 0x02, 0x02, 0x05, 0x9F, 0x87, 0xC7, 0x67, 0x67, 0x51, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x05, 0x02, 0x03, 0x06, 0xB7, 0xD7, 0xE7, 0xF7, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x06, 0x01, 0x03, 0x02, 0x9F, 0xFF, 0x1F, 0x3F,
|
||||
0xC7, 0x3F, 0xD7, 0x67, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x06, 0x01, 0x06, 0x06, 0xC7, 0x27,
|
||||
0x3F, 0xC7, 0x9F, 0xC7, 0x17, 0x67, 0xF7, 0x51, 0x51, 0x51, 0x51, 0x00, 0x06, 0x01, 0x07, 0x01,
|
||||
0x9F, 0x47, 0xC7, 0xF7, 0x67, 0x77, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x06, 0x02,
|
||||
0x05, 0x06, 0x9F, 0xC7, 0x7F, 0xFF, 0xD7, 0x7F, 0xC7, 0xA7, 0x27, 0x9F, 0x51, 0x51, 0x51, 0x00,
|
||||
0x06, 0x02, 0x06, 0x05, 0x77, 0xF7, 0xD7, 0x7F, 0x47, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51,
|
||||
0x51, 0x00, 0x07, 0x01, 0x02, 0x03, 0x5F, 0x1F, 0xF7, 0x97, 0xC7, 0x9F, 0xF7, 0x51, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x00, 0x07, 0x02, 0x07, 0x05, 0x97, 0xD7, 0x1F, 0x77, 0x51, 0x51, 0x51, 0x51,
|
||||
0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x08, 0x01, 0x0A, 0x02, 0x97, 0xC7, 0x27, 0xF7, 0xE7, 0xD7,
|
||||
0x7F, 0xC7, 0x97, 0x51, 0x51, 0x51, 0x51, 0x00, 0x08, 0x02, 0x04, 0x06, 0xC7, 0x27, 0x3F, 0xF7,
|
||||
0x27, 0x7F, 0xA7, 0x1F, 0xCF, 0x51, 0x51, 0x51, 0x51, 0x00, 0x08, 0x01, 0x10, 0x02, 0x77, 0xF7,
|
||||
0x3F, 0xC7, 0x97, 0xF7, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x09, 0x01, 0x01, 0x04,
|
||||
0x7F, 0xD7, 0x4F, 0xC7, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00, 0x09, 0x01,
|
||||
0x03, 0x04, 0x9F, 0xFF, 0x17, 0xBF, 0xD7, 0xCF, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x51, 0x00
|
||||
};
|
||||
|
||||
const uint8_t Game::_protectionNumberDataAmiga[] = {
|
||||
0xE5, 0xE3, 0x91, 0xE2, 0xE1, 0x91, 0xE6, 0xEF, 0xE3, 0x8D, 0xE1, 0xE5, 0xE3, 0x85, 0xE2, 0xE1,
|
||||
0x83, 0xE3, 0xEE, 0xE2, 0xE1, 0x93, 0xE2, 0xE1, 0xEE, 0xE1, 0xE1, 0xE2, 0x93, 0xE5, 0xE4, 0xE1,
|
||||
0xE2, 0x9D, 0xE1, 0x8E, 0xEE, 0x90, 0xEF, 0xEE, 0xE1, 0x91, 0xE4, 0xE3, 0xEF, 0xE2, 0xE3, 0x90,
|
||||
0xE6, 0x95, 0xE5, 0xE2, 0x83, 0xE3, 0xE2, 0x9F, 0xE3, 0xE1, 0x90, 0xE6, 0xEE, 0xE6, 0xE4, 0xE3,
|
||||
0x93, 0xE1, 0x9C, 0x9B, 0xE4, 0xE0, 0xEF, 0x99, 0xE1, 0x9B, 0x91, 0xE3, 0x81, 0xE4, 0xE0, 0xE0,
|
||||
0x81, 0xEE, 0xE1, 0x93, 0xEE, 0x91, 0xE3, 0xEE, 0xE5, 0xE5, 0x83, 0x8E, 0xE2, 0xE3, 0xE1, 0x93,
|
||||
0xE6, 0x9C, 0xE5, 0xE4, 0x82, 0x91, 0xE4, 0xE4, 0xE6, 0xE5, 0x99, 0x87, 0x9F, 0x93, 0x9D, 0xE1,
|
||||
0xE3, 0xE2, 0xE3, 0x9B, 0xE2, 0xE1, 0x96, 0xE3, 0x87, 0xEF, 0x86, 0xE3, 0xE4, 0xE5, 0xE4, 0x90,
|
||||
0xE6, 0xE2, 0xE4, 0x93, 0xE6, 0x81, 0xE1, 0x94, 0xE2, 0x93, 0xE6, 0x91, 0xE5, 0xE4, 0x90, 0xE2,
|
||||
0xE6, 0x95, 0xEE, 0xE2, 0xE4, 0xE5, 0x90, 0xE6, 0xE2, 0x95, 0xE4, 0x96, 0xE6, 0x90, 0xE4, 0xE5,
|
||||
0xE6, 0x91, 0x9C, 0xE1, 0xE2, 0xE0, 0xE0, 0xE4, 0xEF, 0x94, 0xE3, 0xE2, 0xE1, 0x93, 0xE6, 0x91,
|
||||
0xE5, 0xE4, 0xE1, 0xE3, 0xE3, 0xE2, 0xE1, 0x85, 0x83, 0x95, 0xE6, 0xE5, 0xE5, 0x91, 0xE2, 0xE1,
|
||||
0xEE, 0x91, 0xE3, 0x90, 0xE1, 0xE2, 0x9D, 0x99, 0xE4, 0xE6, 0xEE, 0xE3, 0xE6, 0x95, 0xE5, 0xE4,
|
||||
0x91, 0xEE, 0xE3, 0xE3, 0x90, 0x91, 0xE2, 0xE1, 0xE6, 0xE1, 0xE4, 0x91, 0xEE, 0xE2, 0xE6, 0x94,
|
||||
0xE2, 0x93, 0xE1, 0xE0, 0xE6, 0xE4, 0x9D, 0xE5, 0xE6, 0x8E, 0xE3, 0xE3, 0x90, 0xE2, 0xE1, 0x85,
|
||||
0x9D, 0x91, 0xE3, 0xE1, 0xE2, 0xE6, 0xE3, 0x91, 0xE2, 0xE2, 0x92, 0xE3, 0xE2, 0x93, 0xE3, 0xE1,
|
||||
0x9A, 0x80, 0xEF, 0xE3, 0x93, 0xE4, 0x92, 0xE3, 0xEE, 0xEE, 0x91, 0xE2, 0xE1, 0x85, 0x85, 0x96,
|
||||
0xE2, 0xE1, 0xEE, 0xEF, 0xEF, 0x95, 0xE2, 0xE3, 0x93, 0x96, 0xE2, 0x9F, 0xE6, 0xE5, 0x9F, 0x9A,
|
||||
0xE6, 0x94, 0xE5, 0xE4, 0x93, 0xE3, 0xE5, 0xEE, 0x81, 0xE3, 0xE1, 0xE3, 0xE1, 0x8F, 0xE5, 0x94,
|
||||
0xE2, 0xE1, 0xE4, 0x80, 0xE1, 0x93, 0xE2, 0xE3, 0x92, 0xE2, 0xE1, 0x91, 0xE6, 0xE4, 0xE6, 0x94,
|
||||
0xE4, 0xE5, 0x93, 0xE2, 0xE3, 0x91, 0xE1, 0xE2, 0x90, 0x99, 0xE4, 0xE5, 0xE3, 0xEE, 0x93, 0xE2,
|
||||
0xE4, 0x8F, 0xE1, 0x84, 0x92, 0xEE, 0xE0, 0x91, 0x91, 0xE2, 0xE6, 0xE4, 0x99, 0x9C, 0x93, 0x9B,
|
||||
0x9D, 0xEF, 0xE2, 0x9C, 0xE6, 0xE4, 0xEE, 0x85, 0x9B, 0xE2, 0x93, 0xE3, 0xE2, 0xE2, 0x83, 0x8E,
|
||||
0x93, 0xEE, 0xE2, 0xE4, 0x90, 0x95, 0xE3, 0x84, 0x83, 0xE2, 0xE1, 0xE1, 0xE4, 0xEE, 0xEF, 0xE5,
|
||||
0xE0, 0xE1, 0xE2, 0x84, 0x91, 0x9F, 0xE6, 0xE5, 0x9F, 0xE4, 0x90, 0xE2, 0xE6, 0xE4, 0x90, 0xE5,
|
||||
0xE3, 0xE2, 0x90, 0x9A, 0x99, 0xEE, 0xEE, 0xE1, 0xE2, 0x90, 0x85, 0xE1, 0xE6, 0xE5, 0xE6, 0x95,
|
||||
0xEE, 0xE2, 0x91, 0xE4, 0x9A, 0xE2, 0xE1, 0xE2, 0x91, 0xE4, 0xEE, 0x81, 0xE4, 0xE2, 0x93, 0xE4,
|
||||
0xEE, 0x95, 0xE4, 0x91, 0x90, 0xE4, 0xE6, 0x92, 0xE4, 0xE2, 0x84, 0xE1, 0xE6, 0x91, 0xE5, 0x92,
|
||||
0xE4, 0x92, 0xE3, 0x90, 0x9F, 0x87, 0x9A, 0xE6, 0xE5, 0xE5, 0xE1, 0xE4, 0xE6, 0xE1, 0xEE, 0x93,
|
||||
0xE2, 0xE1, 0xE0, 0xE5, 0xE1, 0x91, 0xE5, 0xE4, 0x93, 0xE6, 0xE2, 0x92, 0xE3, 0xE1, 0xE7, 0x84,
|
||||
0xE3, 0xE2, 0x91, 0x92, 0xE1, 0xE6, 0xE3, 0xE3, 0x91, 0xE2, 0xE1, 0x93, 0xE2, 0x85, 0xE3, 0xE1,
|
||||
0x92, 0xE6, 0xE6, 0xEE, 0x93, 0xEF, 0xE1, 0xE1, 0xEF, 0x8D, 0xE3, 0xE1, 0x93, 0xE4, 0xE3, 0xE2,
|
||||
0x91, 0xE4, 0xE6, 0x93, 0xEE, 0x84, 0x96, 0xE1, 0xE6, 0xE5, 0xE3, 0x8D, 0xE1, 0x94, 0x94, 0xE2,
|
||||
0xE6, 0xE6, 0x93, 0xE5, 0xEE, 0xEE, 0xE6, 0x91, 0xE5, 0xE4, 0x93, 0xE2, 0x81, 0x9E, 0x98, 0xE6,
|
||||
0xE5, 0x84, 0xE6, 0x91, 0xE4, 0x83, 0x92, 0x85, 0x86, 0x9B, 0xE2, 0x93, 0xEE, 0xE4, 0xEE, 0x94,
|
||||
0xE1, 0xE5, 0xE5, 0xE4, 0x93, 0xE2, 0xE3, 0x84, 0xE1, 0xE4, 0xE6, 0x93, 0xE5, 0x84, 0xE4, 0xE4,
|
||||
0x84, 0xE3, 0xE2, 0x84, 0x86, 0xE1, 0x93, 0x93, 0xE2, 0xE3, 0x84, 0xE4, 0x85, 0x90, 0xE3, 0xE2,
|
||||
0xE1, 0x9A, 0xE6, 0x84, 0xE1, 0x84, 0xE2, 0xEE, 0xE2, 0xE3, 0x9D, 0x9F, 0xE1, 0xE6, 0xEF, 0x91,
|
||||
0xE3, 0xE1, 0x93, 0xE2, 0x85, 0xEE, 0x92, 0xE3, 0xE2, 0xE1, 0x90, 0xE2, 0x91, 0xE1, 0x91, 0xE6,
|
||||
0xEE, 0x90, 0xE1, 0x91, 0xE4, 0xE5, 0xE1, 0x91, 0xE3, 0xE4, 0x93, 0xE2, 0x91, 0xE6, 0xE4, 0x93,
|
||||
0xE1, 0xE4, 0x96, 0xEE, 0x9D, 0x9F, 0x90, 0x9A, 0x9C, 0x9A, 0x93, 0xE1, 0xE2, 0xE4, 0xEF, 0xE3,
|
||||
0xE1, 0xE2, 0xE6, 0xE5, 0xE0, 0xE0, 0xEE, 0xE4, 0xE6, 0x96, 0xE2, 0x8D, 0xE1, 0xE4, 0xE6, 0xEE,
|
||||
0x9D, 0x9F, 0x94, 0xE2, 0xE1, 0xE6, 0xE4, 0x8D, 0xE2, 0xE4, 0x91, 0xE6, 0xE1, 0x84, 0xE3, 0xE4,
|
||||
0xE2, 0xE5, 0xE6, 0x95, 0xE4, 0x91, 0xE5, 0xE4, 0xEE, 0x91, 0xE2, 0x93, 0xE4, 0xE6, 0xE4, 0x91,
|
||||
0xE6, 0xE6, 0x93, 0xE4, 0xEF, 0x91, 0xE3, 0x93, 0xE1, 0xE5, 0x80, 0x85, 0x95, 0xE2, 0xE1, 0xE5,
|
||||
0xE2, 0x84, 0xE3, 0xE6, 0x94, 0xE5, 0xE4, 0x86, 0xE6, 0xE2, 0x84, 0xE1, 0x93, 0x93, 0x84, 0x91,
|
||||
0xE1, 0xE2, 0x91, 0x93, 0x90, 0x93, 0x84, 0xE1, 0xE5, 0xE4, 0x84, 0xE3, 0x86, 0xE1, 0xE6, 0x96,
|
||||
0x90, 0xE5, 0xE4, 0xE6, 0x85, 0xE6, 0x96, 0xE3, 0xE2, 0xE1, 0xE5, 0xE3, 0x93, 0xE2, 0xE1, 0x96,
|
||||
0xE5, 0x84, 0xE3, 0xE1, 0x96, 0xE2, 0xE5, 0xE6, 0x93, 0xE2, 0xE1, 0x92, 0x90, 0x91, 0x93, 0xE2,
|
||||
0xE3, 0xE1, 0xEE, 0x93, 0xE3, 0x84, 0xE1, 0xE5, 0xEE, 0x9F, 0x90, 0x9D, 0xE4, 0xE6, 0xE4, 0xE6,
|
||||
0xE5, 0xE4, 0x93, 0x86, 0xEE, 0x8E, 0x83, 0x8E, 0xE5, 0xE5, 0xE2, 0xE2, 0xE3, 0x9D, 0x9C, 0x9B,
|
||||
0xEE, 0xE0, 0x8E, 0x92, 0x83, 0x85, 0xE3, 0xE3, 0x92, 0x8D, 0x96, 0xE6, 0xE1, 0xE3, 0xE3, 0xE2,
|
||||
0x96, 0x92, 0xE1, 0xE3, 0xE2, 0xE2, 0xE0, 0x9A, 0xE3, 0xE3, 0x9C, 0x9B, 0x9D, 0xE4, 0xE3, 0xE3,
|
||||
0xE2, 0xE6, 0xE4, 0x9C, 0xE1, 0xE4, 0xE6, 0xE5, 0x92, 0x84, 0xEE, 0xE0, 0xE2, 0xE2, 0x9C, 0x9D,
|
||||
0xE6, 0xE6, 0xE4, 0xE5, 0xE1, 0x93, 0xE2, 0xE3, 0x9C, 0x9D, 0xEE, 0xEF, 0xE2, 0xE3, 0x92, 0x85,
|
||||
0x83, 0xEE, 0x92, 0x85, 0x8E, 0x95, 0xE1, 0xE5, 0x93, 0x84, 0x94, 0xE6, 0xE5, 0xE4, 0xE2, 0x91,
|
||||
0xE3, 0x93, 0xE1, 0xE4
|
||||
};
|
||||
|
||||
const uint8_t Game::_protectionCodeDataAmiga[] = {
|
||||
0xE2, 0x93, 0xE3, 0xE2, 0x92, 0xE1, 0xE3, 0xE2, 0x84, 0xE1, 0x92, 0x85, 0xEF, 0xE0, 0x85, 0xEE,
|
||||
0xE2, 0xE3, 0xE0, 0xE0, 0xEF, 0x91, 0xEE, 0xE2, 0xE0, 0x93, 0xE6, 0x9D, 0x93, 0x9F, 0xEE, 0xE3,
|
||||
0x9F, 0xE2, 0xE6, 0xE5, 0x9F, 0x9B, 0xE5, 0xE3, 0xE1, 0x92, 0xE2, 0xE3, 0x99, 0xE1, 0x90, 0xE3,
|
||||
0xE2, 0x90, 0xE0, 0xE1, 0x99, 0xE3, 0xE0, 0xEF, 0xE1, 0xE6, 0x90, 0x9A, 0xE2, 0x91, 0xE4, 0x9D,
|
||||
0x91, 0xE6, 0x90, 0xE2, 0xE3, 0x9F, 0xE5, 0xE5, 0xE6, 0x95, 0xE4, 0xE1, 0x91, 0xE2, 0xE1, 0x9D,
|
||||
0xE2, 0xE1, 0xE6, 0xE6, 0xE4, 0x95, 0xE6, 0xE0, 0xEF, 0x96, 0x9F, 0x93, 0x9C, 0xE1, 0xE2, 0x93,
|
||||
0xE6, 0xE2, 0x9C, 0xE1, 0x82, 0xE6, 0xE0, 0xEF, 0x8F, 0xE6, 0xE2, 0x94, 0x9F, 0xE2, 0x91, 0xE5,
|
||||
0x9C, 0x91, 0xEF, 0xEE, 0x96, 0x93, 0xE0, 0x95, 0xE6, 0xE6, 0x95, 0xE5, 0xE3, 0x90, 0xE1, 0x9B,
|
||||
0xE2, 0x93, 0xE3, 0xE1, 0xE0, 0xE2, 0x90, 0xE3, 0x91, 0x93, 0xE2, 0x95, 0xE6, 0xEE, 0xE2, 0xE4,
|
||||
0xE2, 0x90, 0xE1, 0xE6, 0x91, 0xE4, 0xE2, 0xE2, 0x99, 0xE1, 0xE5, 0xE4, 0xE2, 0xE6, 0x95, 0xEE,
|
||||
0xE2, 0x93, 0x9B, 0x9C, 0xE1, 0x90, 0xE2, 0x95, 0x8D, 0x85, 0x86, 0x95, 0xE5, 0xE5, 0xEF, 0xEF,
|
||||
0xE3, 0x95, 0xE1, 0xE6, 0xE3, 0xE5, 0x94, 0x99, 0x9C, 0x9B, 0xE6, 0x91, 0xE2, 0x9F, 0x94, 0xEE,
|
||||
0xE1, 0xE2, 0xE1, 0x91, 0xE6, 0xE6, 0xE5, 0xE1, 0x94, 0xE4, 0x81, 0x95, 0x95, 0x94, 0x99, 0xE1,
|
||||
0xE2, 0xE4, 0xE2, 0x90, 0x95, 0xE3, 0xE1, 0x90, 0xE3, 0xEE, 0xE2, 0xE3, 0xE4, 0xE6, 0xE2, 0x90,
|
||||
0xE6, 0xE4, 0x85, 0xE5, 0xE6, 0xE5, 0x90, 0xE4, 0xEE, 0xEE, 0xE6, 0x90, 0xE5, 0xE4, 0x85, 0x92,
|
||||
0xE5, 0xE6, 0x91, 0xE4, 0x92, 0xE2, 0xE2, 0x90, 0xE6, 0x99, 0x99, 0x92, 0x84, 0xE5, 0xE6, 0xE4,
|
||||
0x84, 0x92, 0xEE, 0xEF, 0xEE, 0x91, 0xE2, 0xE6, 0x9A, 0x8F, 0xE6, 0xE2, 0x84, 0xE5, 0xE6, 0xE6,
|
||||
0xE5, 0xE3, 0xE4, 0xE5, 0xE6, 0xE4, 0xE3, 0xE5, 0x85, 0x91, 0xE6, 0xE3, 0x81, 0xE2, 0x91, 0xE3,
|
||||
0xE4, 0x91, 0xE3, 0xE2, 0xE1, 0x92, 0xE0, 0xE3, 0x91, 0xE1, 0xE2, 0xE6, 0xE6, 0x9C, 0x90, 0xE1,
|
||||
0xE2, 0xE0, 0xE6, 0x91, 0xE5, 0xE4, 0x92, 0xE1, 0x87, 0x9B, 0xE2, 0x93, 0xE1, 0xE3, 0x94, 0x85,
|
||||
0xE2, 0x93, 0xE1, 0xE5, 0xE1, 0xE4, 0x85, 0xEE, 0xEF, 0xE0, 0xE6, 0xE6, 0xE2, 0x90, 0xEF, 0xE2,
|
||||
0x9F, 0x91, 0x91, 0xE3, 0xE2, 0xE4, 0xE6, 0xE2, 0x95, 0xE1, 0x90, 0x9B, 0xE6, 0x9F, 0x9B, 0x9A,
|
||||
0x91, 0xEE, 0xE5, 0xE4, 0x99, 0xE1, 0x9F, 0xE2, 0x9C, 0x9C, 0x95, 0x91, 0xE6, 0xE5, 0xE3, 0x91,
|
||||
0xE2, 0x92, 0xE1, 0x94, 0xE6, 0x93, 0xE5, 0xEE, 0x92, 0x9D, 0x9B, 0x9A, 0x9F, 0xEE, 0xE2, 0x91,
|
||||
0xE6, 0x95, 0xE5, 0xE4, 0xEE, 0xE2, 0xE3, 0xE3, 0xEE, 0xE1, 0x90, 0xE5, 0xE3, 0x9F, 0xE2, 0x83,
|
||||
0xE1, 0xE2, 0x9B, 0x99, 0xE1, 0xE4, 0xE5, 0xE6, 0xEE, 0x9F, 0xE3, 0xE1, 0x83, 0xE4, 0xE2, 0x90,
|
||||
0x91, 0xE3, 0xE1, 0xE6, 0xE0, 0xE4, 0x9F, 0xE6, 0xE4, 0xE5, 0xEE, 0x81, 0xE6, 0xE5, 0xE4, 0x93,
|
||||
0xE2, 0x81, 0xE4, 0xEE, 0x84, 0xE3, 0xEE, 0xE3, 0xE2, 0x90, 0xE4, 0xE6, 0xEE, 0x95, 0xE2, 0xE1,
|
||||
0x91, 0xE5, 0xE6, 0xE2, 0x8D, 0xEE, 0xE1, 0x93, 0xE6, 0x91, 0xE2, 0x92, 0xE1, 0xE0, 0xE0, 0x91,
|
||||
0xE3, 0xE2, 0x92, 0xE5, 0xE1, 0x90, 0x85, 0xE4, 0xE5, 0xE6, 0xE3, 0x93, 0xE4, 0xE4, 0xEE, 0xE2,
|
||||
0xE5, 0xE4, 0x84, 0xE3, 0xE6, 0xE5, 0xE6, 0xE5, 0x90, 0xE4, 0xE5, 0x91, 0xEE, 0xEE, 0x94, 0xE1,
|
||||
0xE4, 0x93, 0xE6, 0xE2, 0x84, 0x8F, 0x80, 0xEE, 0xE0, 0xE0, 0x95, 0xEE, 0x85, 0xE4, 0xE5, 0xE3,
|
||||
0x91, 0x93, 0x93, 0xE6, 0xE1, 0x94, 0xE3, 0x93, 0x84, 0xE1, 0x9B, 0x91, 0x9A, 0xEE, 0xE2, 0xE1,
|
||||
0xE1, 0x81, 0xE2, 0x91, 0xE1, 0xE4, 0xEE, 0xEE, 0x95, 0x90, 0xE3, 0xE5, 0xEE, 0xE0, 0x83, 0xE3,
|
||||
0xE1, 0x91, 0xE4, 0x90, 0x9F, 0xE2, 0x95, 0xEE, 0xE1, 0x95, 0xE3, 0x84, 0xE1, 0x83, 0xE6, 0xE6,
|
||||
0xE5, 0xE1, 0xEF, 0xE5, 0x95, 0x91, 0xE3, 0x93, 0xE1, 0xE6, 0xE1, 0x91, 0xE2, 0xEE, 0xE2, 0xE3,
|
||||
0xEE, 0x91, 0xE3, 0xE2, 0x93, 0xE4, 0xE2, 0x93, 0xE3, 0xE2, 0x84, 0x9B, 0xEE, 0x91, 0xE3, 0x93,
|
||||
0xE2, 0x84, 0x92, 0x8D, 0xEF, 0xE2, 0xE1, 0xE6, 0xE2, 0x83, 0xE3, 0xE5, 0x90, 0xE4, 0xE3, 0x90,
|
||||
0xEE, 0xEE, 0x90, 0xE3, 0xE6, 0xE6, 0x90, 0xE4, 0x91, 0xE3, 0xEE, 0xEE, 0x99, 0xE6, 0xE5, 0x90,
|
||||
0xE1, 0x84, 0xE5, 0xE4, 0xE3, 0xE2, 0xEE, 0xEE, 0xE1, 0x91, 0xE2, 0xE1, 0x9D, 0x9C, 0x9B, 0xE2,
|
||||
0xE1, 0xE5, 0x83, 0x93, 0xE5, 0x83, 0x93, 0xE4, 0xE3, 0x91, 0xE1, 0x93, 0xE5, 0x99, 0x9C, 0x9C,
|
||||
0xEE, 0xE2, 0xE1, 0xE4, 0xEE, 0xE1, 0xE1, 0x91, 0x92, 0xE4, 0xE3, 0x91, 0xE2, 0x92, 0xE1, 0xE1,
|
||||
0xE1, 0x93, 0xE2, 0xE3, 0xE5, 0xE6, 0xEE, 0x91, 0x93, 0xE3, 0xE1, 0xE5, 0xE6, 0x91, 0xE2, 0x93,
|
||||
0xE1, 0xE5, 0x85, 0x83, 0xEE, 0xE1, 0xE2, 0x91, 0xE1, 0x91, 0xE1, 0x91, 0xE6, 0xE5, 0xEE, 0x91,
|
||||
0xEF, 0xE1, 0x93, 0xE4, 0xE2, 0x91, 0x91, 0x96, 0x84, 0xE2, 0x87, 0x9A, 0x84, 0xEE, 0xE1, 0xE4,
|
||||
0xE1, 0x84, 0x84, 0xE3, 0xE2, 0x93, 0xE4, 0xE6, 0x93, 0xE5, 0xE4, 0x84, 0x9D, 0x91, 0xE1, 0xE6,
|
||||
0xE5, 0xE4, 0xEE, 0x93, 0xE3, 0x84, 0xE1, 0xE5, 0xE1, 0x93, 0xE2, 0x84, 0xE1, 0x99, 0x92, 0xE1,
|
||||
0x83, 0xEF, 0x84, 0xE2, 0x92, 0xE2, 0xE3, 0xEF, 0xE1, 0x93, 0x91, 0xE6, 0xE2, 0xE5, 0x92, 0xE1,
|
||||
0x96, 0xE3, 0xE2, 0xE1, 0x84, 0x92, 0xE3, 0xE2, 0x8D, 0xE1, 0xEF, 0xE0, 0xE6, 0x93, 0xE1, 0x86,
|
||||
0x9D, 0xE5, 0xE4, 0x91, 0xE6, 0xEE, 0xE1, 0xE1, 0xEE, 0x91, 0xE3, 0x93, 0xE3, 0xE3, 0xE6, 0x90,
|
||||
0x91, 0xE1, 0x91, 0xE5, 0xE1, 0x9F, 0xE2, 0xE1, 0xE1, 0x90, 0xE5, 0xE6, 0x9A, 0x9C, 0x9D, 0x90,
|
||||
0xE1, 0xE3, 0x90, 0x90, 0x9F, 0x99, 0xE1, 0xE3, 0x9C, 0x9D, 0x9F, 0x9B, 0xE6, 0xE4, 0xE4, 0xE3,
|
||||
0xE2, 0xE1, 0xE3, 0xE6, 0xE5, 0xE3, 0xE0, 0x9C, 0x96, 0x85, 0x93, 0xE2, 0xE3, 0x81, 0xE0, 0xEF,
|
||||
0xE2, 0x82, 0x83, 0xE5, 0xE4, 0xE3, 0x9A, 0x9D, 0x98, 0x87, 0xE6, 0xE3, 0xE2, 0xE1, 0x95, 0x81,
|
||||
0xE1, 0xE3, 0x87, 0x82, 0x99, 0xE2, 0xE4, 0xE4, 0x9F, 0x90, 0x91, 0x99, 0xE2, 0xE3, 0x9C, 0x81,
|
||||
0x94, 0xE4, 0x9F, 0x90, 0xE2, 0xE3, 0x93, 0xE6, 0xEE, 0xEF, 0x90, 0xE1, 0x91, 0xE6, 0xE2, 0x90,
|
||||
0xE3, 0x91, 0xE1, 0x8E
|
||||
};
|
||||
|
||||
const uint8_t Game::_protectionPal[] = {
|
||||
// DOS
|
||||
0x00, 0x00, 0x00, 0x42, 0x00, 0x63, 0x00, 0x00, 0x0F, 0xFF, 0x0F, 0xF0, 0x07, 0x77, 0x00, 0x00,
|
||||
|
@ -3223,7 +3910,7 @@ const uint8_t Game::_protectionPal[] = {
|
|||
0x08, 0x88, 0x09, 0x99, 0x0A, 0xAA, 0x0B, 0xBB, 0x0C, 0xCC, 0x0D, 0xDD, 0x0E, 0xEE, 0x0F, 0xFF
|
||||
};
|
||||
|
||||
const char *Menu::_levelNames[] {
|
||||
const char *Menu::_levelNames[] = {
|
||||
"Titan / The Jungle",
|
||||
"Titan / New Washington",
|
||||
"Titan / Death Tower Show",
|
||||
|
@ -4145,7 +4832,7 @@ const uint8_t SfxPlayer::_musicDataSample1[] = {
|
|||
0x2A, 0x26, 0x21, 0x1C, 0x16, 0x10, 0x0A, 0x04, 0xFE, 0xF8, 0xF2, 0xEC, 0xE6, 0xE0, 0xDB, 0xD6,
|
||||
0xD1, 0xCC, 0xC8, 0xC4, 0xC0, 0xBD, 0xB9, 0xB6, 0xB3, 0xB1, 0xAE, 0xAB, 0xA8, 0xA5, 0xA3, 0xA0,
|
||||
0x9D, 0x9A, 0x98, 0x95, 0x92, 0x8F, 0x8D, 0x8A, 0x88, 0x86, 0x84, 0x83, 0x82, 0x82, 0x82, 0x82,
|
||||
0x82, 0x83, 0x84, 0x86, 0x86
|
||||
0x82, 0x83, 0x84, 0x86
|
||||
};
|
||||
|
||||
const uint8_t SfxPlayer::_musicDataSample2[] = {
|
||||
|
@ -4366,7 +5053,7 @@ const uint8_t SfxPlayer::_musicDataSample2[] = {
|
|||
0x0E, 0x16, 0x14, 0x16, 0x10, 0x0E, 0x12, 0x16, 0x16, 0x14, 0x18, 0x10, 0x10, 0x10, 0x12, 0x10,
|
||||
0x10, 0x08, 0x08, 0x06, 0x08, 0x08, 0x06, 0x0C, 0x08, 0x08, 0x06, 0x08, 0x08, 0x0A, 0x08, 0x0A,
|
||||
0x0C, 0x06, 0x04, 0x04, 0x06, 0x04, 0x04, 0x06, 0x04, 0x02, 0x06, 0x06, 0x02, 0x04, 0x04, 0x06,
|
||||
0x08, 0x06, 0x04, 0x04, 0x06, 0x0C, 0x0A, 0x02, 0x02
|
||||
0x08, 0x06, 0x04, 0x04, 0x06, 0x0C, 0x0A, 0x02
|
||||
};
|
||||
|
||||
const uint8_t SfxPlayer::_musicDataSample3[] = {
|
||||
|
@ -4651,7 +5338,7 @@ const uint8_t SfxPlayer::_musicDataSample3[] = {
|
|||
0x0E, 0x09, 0xFF, 0xFB, 0x01, 0x10, 0x1C, 0x1A, 0x04, 0xEB, 0xE8, 0xFB, 0x0C, 0x0E, 0xF8, 0xE0,
|
||||
0xD8, 0xE3, 0xF5, 0x05, 0x11, 0x14, 0x0E, 0xFF, 0xF3, 0xE9, 0xF0, 0xFE, 0x03, 0xF3, 0xE3, 0xE1,
|
||||
0xF0, 0x03, 0x0E, 0x09, 0xFD, 0xF6, 0xF1, 0xED, 0xEA, 0xE7, 0xE9, 0xF6, 0xFD, 0xFD, 0xFF, 0x0B,
|
||||
0x16, 0x18, 0x11, 0x08, 0x08
|
||||
0x16, 0x18, 0x11, 0x08
|
||||
};
|
||||
|
||||
const uint8_t SfxPlayer::_musicDataSample4[] = {
|
||||
|
@ -4686,8 +5373,7 @@ const uint8_t SfxPlayer::_musicDataSample4[] = {
|
|||
0x07, 0x0F, 0x0D, 0x07, 0x0F, 0x19, 0x11, 0x0F, 0x10, 0x0D, 0x09, 0x0B, 0x13, 0x14, 0x10, 0x0E,
|
||||
0x11, 0x0A, 0x07, 0x0B, 0x17, 0x0F, 0x0D, 0x17, 0x14, 0x0B, 0x10, 0x11, 0x06, 0x06, 0x10, 0x13,
|
||||
0x0F, 0x10, 0x13, 0x0E, 0x07, 0x0E, 0x13, 0x0E, 0x0D, 0x13, 0x0F, 0x0E, 0x15, 0x11, 0x0B, 0x0D,
|
||||
0x0F, 0x0A, 0x0E, 0x14, 0x14, 0x0C, 0x0F, 0x0B, 0x0B, 0x11, 0x13, 0x10, 0x0C, 0x0B, 0x0F, 0x10,
|
||||
0x10
|
||||
0x0F, 0x0A, 0x0E, 0x14, 0x14, 0x0C, 0x0F, 0x0B, 0x0B, 0x11, 0x13, 0x10, 0x0C, 0x0B, 0x0F, 0x10
|
||||
};
|
||||
|
||||
const uint8_t SfxPlayer::_musicDataSample5[] = {
|
||||
|
@ -4849,7 +5535,7 @@ const uint8_t SfxPlayer::_musicDataSample5[] = {
|
|||
0x04, 0x18, 0x18, 0x08, 0x04, 0x18, 0x24, 0x14, 0x04, 0xF8, 0xE4, 0x00, 0x00, 0x04, 0x08, 0xFC,
|
||||
0xF4, 0xFC, 0xF0, 0xF0, 0x00, 0x08, 0xF4, 0xE4, 0xF4, 0xEC, 0xEC, 0xEC, 0xE8, 0xF4, 0xE8, 0xD8,
|
||||
0xDC, 0xE4, 0xF0, 0xEC, 0xF0, 0x04, 0xF4, 0xE8, 0xFC, 0xFC, 0xE4, 0xE8, 0xF4, 0xF4, 0x04, 0xEC,
|
||||
0xF0, 0xE4, 0xE8, 0x10, 0x0C, 0xF4, 0xEC, 0x00, 0x14, 0x0C, 0x0C, 0x04, 0x04
|
||||
0xF0, 0xE4, 0xE8, 0x10, 0x0C, 0xF4, 0xEC, 0x00, 0x14, 0x0C, 0x0C, 0x04
|
||||
};
|
||||
|
||||
const uint8_t SfxPlayer::_musicDataSample6[] = {
|
||||
|
@ -5000,7 +5686,7 @@ const uint8_t SfxPlayer::_musicDataSample6[] = {
|
|||
0xEB, 0xEF, 0xF7, 0xF8, 0xFF, 0xFA, 0xEA, 0xD8, 0xD0, 0xCD, 0xD4, 0xE0, 0xEC, 0xF7, 0x0C, 0x15,
|
||||
0x12, 0x19, 0x1D, 0x26, 0x30, 0x3E, 0x47, 0x49, 0x44, 0x32, 0x1E, 0x0F, 0xFE, 0xF0, 0xE8, 0xE7,
|
||||
0xEA, 0xF2, 0xF5, 0xFA, 0xFF, 0xF8, 0xE6, 0xD6, 0xCF, 0xCD, 0xD5, 0xE3, 0xEB, 0xFB, 0x0F, 0x12,
|
||||
0x15, 0x19, 0x1F, 0x27, 0x34, 0x3F, 0x3F
|
||||
0x15, 0x19, 0x1F, 0x27, 0x34, 0x3F
|
||||
};
|
||||
|
||||
const uint8_t SfxPlayer::_musicDataSample7[] = {
|
||||
|
@ -5056,11 +5742,11 @@ const uint8_t SfxPlayer::_musicDataSample7[] = {
|
|||
0x0E, 0x0F, 0x0A, 0x11, 0x0B, 0x0E, 0x0C, 0x10, 0x0E, 0x08, 0x14, 0x0B, 0x0E, 0x14, 0x04, 0x16,
|
||||
0x0A, 0x10, 0x0E, 0x0C, 0x0F, 0x02, 0x1B, 0x07, 0x10, 0x13, 0x08, 0x14, 0x07, 0x12, 0x07, 0x10,
|
||||
0x0F, 0x08, 0x14, 0x0B, 0x0E, 0x0F, 0x0E, 0x10, 0x0B, 0x11, 0x10, 0x0E, 0x0D, 0x08, 0x14, 0x0B,
|
||||
0x0E, 0x0F, 0x10, 0x0D, 0x0C, 0x13, 0x0C, 0x10, 0x0F, 0x0C, 0x0E, 0x0E, 0x0F, 0x00, 0x00
|
||||
0x0E, 0x0F, 0x10, 0x0D, 0x0C, 0x13, 0x0C, 0x10, 0x0F, 0x0C, 0x0E, 0x0E, 0x0F, 0x00
|
||||
};
|
||||
|
||||
const uint8_t SfxPlayer::_musicDataSample8[] = {
|
||||
0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00
|
||||
0x00, 0x02, 0x00, 0x40, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00
|
||||
};
|
||||
|
||||
const SfxPlayer::Module SfxPlayer::_module68 = {
|
||||
|
|
14
systemstub.h
14
systemstub.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef SYSTEMSTUB_H__
|
||||
|
@ -55,20 +55,24 @@ struct SystemStub {
|
|||
|
||||
virtual ~SystemStub() {}
|
||||
|
||||
virtual void init(const char *title, int w, int h, bool fullscreen, bool widescreen, ScalerParameters *scalerParameters) = 0;
|
||||
virtual void init(const char *title, int w, int h, bool fullscreen, int widescreenMode, ScalerParameters *scalerParameters) = 0;
|
||||
virtual void destroy() = 0;
|
||||
|
||||
virtual bool hasWidescreen() const = 0;
|
||||
virtual void setScreenSize(int w, int h) = 0;
|
||||
virtual void setPalette(const uint8_t *pal, int n) = 0;
|
||||
virtual void getPalette(uint8_t *pal, int n) = 0;
|
||||
virtual void setPaletteEntry(int i, const Color *c) = 0;
|
||||
virtual void getPaletteEntry(int i, Color *c) = 0;
|
||||
virtual void setOverscanColor(int i) = 0;
|
||||
virtual void copyRect(int x, int y, int w, int h, const uint8_t *buf, int pitch) = 0;
|
||||
virtual void copyRectRgb24(int x, int y, int w, int h, const uint8_t *rgb) = 0;
|
||||
virtual void copyRectLeftBorder(int w, int h, const uint8_t *buf) = 0;
|
||||
virtual void copyRectRightBorder(int w, int h, const uint8_t *buf) = 0;
|
||||
virtual void copyRectMirrorBorders(int w, int h, const uint8_t *buf) = 0;
|
||||
virtual void copyWidescreenLeft(int w, int h, const uint8_t *buf) = 0;
|
||||
virtual void copyWidescreenRight(int w, int h, const uint8_t *buf) = 0;
|
||||
virtual void copyWidescreenMirror(int w, int h, const uint8_t *buf) = 0;
|
||||
virtual void copyWidescreenBlur(int w, int h, const uint8_t *buf) = 0;
|
||||
virtual void clearWidescreen() = 0;
|
||||
virtual void enableWidescreen(bool enable) = 0;
|
||||
virtual void fadeScreen() = 0;
|
||||
virtual void updateScreen(int shakeOffset) = 0;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include <SDL.h>
|
||||
|
@ -49,24 +49,29 @@ struct SystemStub_SDL : SystemStub {
|
|||
ScalerType _scalerType;
|
||||
const Scaler *_scaler;
|
||||
int _scaleFactor;
|
||||
bool _widescreen;
|
||||
SDL_Texture *_wideTexture;
|
||||
int _widescreenMode;
|
||||
SDL_Texture *_widescreenTexture;
|
||||
int _wideMargin;
|
||||
bool _enableWidescreen;
|
||||
|
||||
virtual ~SystemStub_SDL() {}
|
||||
virtual void init(const char *title, int w, int h, bool fullscreen, bool widescreen, ScalerParameters *scalerParameters);
|
||||
virtual void init(const char *title, int w, int h, bool fullscreen, int widescreenMode, ScalerParameters *scalerParameters);
|
||||
virtual void destroy();
|
||||
virtual bool hasWidescreen() const;
|
||||
virtual void setScreenSize(int w, int h);
|
||||
virtual void setPalette(const uint8_t *pal, int n);
|
||||
virtual void getPalette(uint8_t *pal, int n);
|
||||
virtual void setPaletteEntry(int i, const Color *c);
|
||||
virtual void getPaletteEntry(int i, Color *c);
|
||||
virtual void setOverscanColor(int i);
|
||||
virtual void copyRect(int x, int y, int w, int h, const uint8_t *buf, int pitch);
|
||||
virtual void copyRectRgb24(int x, int y, int w, int h, const uint8_t *rgb);
|
||||
virtual void copyRectLeftBorder(int w, int h, const uint8_t *buf);
|
||||
virtual void copyRectRightBorder(int w, int h, const uint8_t *buf);
|
||||
virtual void copyRectMirrorBorders(int w, int h, const uint8_t *buf);
|
||||
virtual void copyWidescreenLeft(int w, int h, const uint8_t *buf);
|
||||
virtual void copyWidescreenRight(int w, int h, const uint8_t *buf);
|
||||
virtual void copyWidescreenMirror(int w, int h, const uint8_t *buf);
|
||||
virtual void copyWidescreenBlur(int w, int h, const uint8_t *buf);
|
||||
virtual void clearWidescreen();
|
||||
virtual void enableWidescreen(bool enable);
|
||||
virtual void fadeScreen();
|
||||
virtual void updateScreen(int shakeOffset);
|
||||
virtual void processEvents();
|
||||
|
@ -91,7 +96,7 @@ SystemStub *SystemStub_SDL_create() {
|
|||
return new SystemStub_SDL();
|
||||
}
|
||||
|
||||
void SystemStub_SDL::init(const char *title, int w, int h, bool fullscreen, bool widescreen, ScalerParameters *scalerParameters) {
|
||||
void SystemStub_SDL::init(const char *title, int w, int h, bool fullscreen, int widescreenMode, ScalerParameters *scalerParameters) {
|
||||
SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_JOYSTICK);
|
||||
SDL_ShowCursor(SDL_DISABLE);
|
||||
_caption = title;
|
||||
|
@ -109,9 +114,10 @@ void SystemStub_SDL::init(const char *title, int w, int h, bool fullscreen, bool
|
|||
memset(_rgbPalette, 0, sizeof(_rgbPalette));
|
||||
memset(_darkPalette, 0, sizeof(_darkPalette));
|
||||
_screenW = _screenH = 0;
|
||||
_widescreen = widescreen;
|
||||
_wideTexture = 0;
|
||||
_widescreenMode = widescreenMode;
|
||||
_widescreenTexture = 0;
|
||||
_wideMargin = 0;
|
||||
_enableWidescreen = false;
|
||||
setScreenSize(w, h);
|
||||
_joystick = 0;
|
||||
_controller = 0;
|
||||
|
@ -149,7 +155,7 @@ void SystemStub_SDL::destroy() {
|
|||
}
|
||||
|
||||
bool SystemStub_SDL::hasWidescreen() const {
|
||||
return _widescreen;
|
||||
return _widescreenMode != kWidescreenNone;
|
||||
}
|
||||
|
||||
void SystemStub_SDL::setScreenSize(int w, int h) {
|
||||
|
@ -184,6 +190,14 @@ void SystemStub_SDL::setPalette(const uint8_t *pal, int n) {
|
|||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::getPalette(uint8_t *pal, int n) {
|
||||
assert(n <= 256);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
SDL_GetRGB(_rgbPalette[i], _fmt, &pal[0], &pal[1], &pal[2]);
|
||||
pal += 3;
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::setPaletteEntry(int i, const Color *c) {
|
||||
setPaletteColor(i, c->r, c->g, c->b);
|
||||
}
|
||||
|
@ -259,7 +273,7 @@ static void clearTexture(SDL_Texture *texture, int h, SDL_PixelFormat *fmt) {
|
|||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::copyRectLeftBorder(int w, int h, const uint8_t *buf) {
|
||||
void SystemStub_SDL::copyWidescreenLeft(int w, int h, const uint8_t *buf) {
|
||||
assert(w >= _wideMargin);
|
||||
uint32_t *rgb = (uint32_t *)malloc(w * h * sizeof(uint32_t));
|
||||
if (rgb) {
|
||||
|
@ -279,12 +293,12 @@ void SystemStub_SDL::copyRectLeftBorder(int w, int h, const uint8_t *buf) {
|
|||
r.y = 0;
|
||||
r.w = _wideMargin;
|
||||
r.h = h;
|
||||
SDL_UpdateTexture(_wideTexture, &r, rgb + xOffset, w * sizeof(uint32_t));
|
||||
SDL_UpdateTexture(_widescreenTexture, &r, rgb + xOffset, w * sizeof(uint32_t));
|
||||
free(rgb);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::copyRectRightBorder(int w, int h, const uint8_t *buf) {
|
||||
void SystemStub_SDL::copyWidescreenRight(int w, int h, const uint8_t *buf) {
|
||||
assert(w >= _wideMargin);
|
||||
uint32_t *rgb = (uint32_t *)malloc(w * h * sizeof(uint32_t));
|
||||
if (rgb) {
|
||||
|
@ -304,12 +318,12 @@ void SystemStub_SDL::copyRectRightBorder(int w, int h, const uint8_t *buf) {
|
|||
r.y = 0;
|
||||
r.w = _wideMargin;
|
||||
r.h = h;
|
||||
SDL_UpdateTexture(_wideTexture, &r, rgb + xOffset, w * sizeof(uint32_t));
|
||||
SDL_UpdateTexture(_widescreenTexture, &r, rgb + xOffset, w * sizeof(uint32_t));
|
||||
free(rgb);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::copyRectMirrorBorders(int w, int h, const uint8_t *buf) {
|
||||
void SystemStub_SDL::copyWidescreenMirror(int w, int h, const uint8_t *buf) {
|
||||
assert(w >= _wideMargin);
|
||||
uint32_t *rgb = (uint32_t *)malloc(w * h * sizeof(uint32_t));
|
||||
if (rgb) {
|
||||
|
@ -318,7 +332,7 @@ void SystemStub_SDL::copyRectMirrorBorders(int w, int h, const uint8_t *buf) {
|
|||
}
|
||||
void *dst = 0;
|
||||
int pitch = 0;
|
||||
if (SDL_LockTexture(_wideTexture, 0, &dst, &pitch) == 0) {
|
||||
if (SDL_LockTexture(_widescreenTexture, 0, &dst, &pitch) == 0) {
|
||||
assert((pitch & 3) == 0);
|
||||
uint32_t *p = (uint32_t *)dst;
|
||||
for (int y = 0; y < h; ++y) {
|
||||
|
@ -332,12 +346,64 @@ void SystemStub_SDL::copyRectMirrorBorders(int w, int h, const uint8_t *buf) {
|
|||
}
|
||||
p += pitch / sizeof(uint32_t);
|
||||
}
|
||||
SDL_UnlockTexture(_wideTexture);
|
||||
SDL_UnlockTexture(_widescreenTexture);
|
||||
}
|
||||
free(rgb);
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t blurPixel(int x, int y, const uint8_t *src, const uint32_t *pal, int pitch, int w, int h, const SDL_PixelFormat *fmt) {
|
||||
static const uint8_t blurMat[3 * 3] = {
|
||||
2, 4, 2,
|
||||
4, 8, 4,
|
||||
2, 4, 2
|
||||
};
|
||||
static const int blurMatSigma = 32 * 2;
|
||||
|
||||
const uint32_t redBlueMask = fmt->Rmask | fmt->Bmask;
|
||||
const uint32_t greenMask = fmt->Gmask;
|
||||
|
||||
uint32_t redBlueBlurSum = 0;
|
||||
uint32_t greenBlurSum = 0;
|
||||
|
||||
for (int v = 0; v < 3; ++v) {
|
||||
const int ym = CLIP(y + v - 1, 0, h - 1);
|
||||
for (int u = 0; u < 3; ++u) {
|
||||
const int xm = CLIP(x + u - 1, 0, w - 1);
|
||||
const uint32_t color = pal[src[ym * pitch + xm]];
|
||||
const int mul = blurMat[v * 3 + u];
|
||||
redBlueBlurSum += (color & redBlueMask) * mul;
|
||||
greenBlurSum += (color & greenMask) * mul;
|
||||
}
|
||||
}
|
||||
return ((redBlueBlurSum / blurMatSigma) & redBlueMask) | ((greenBlurSum / blurMatSigma) & greenMask);
|
||||
}
|
||||
|
||||
void SystemStub_SDL::copyWidescreenBlur(int w, int h, const uint8_t *buf) {
|
||||
assert(w == _screenW && h == _screenH);
|
||||
void *dst = 0;
|
||||
int pitch = 0;
|
||||
if (SDL_LockTexture(_widescreenTexture, 0, &dst, &pitch) == 0) {
|
||||
assert((pitch & 3) == 0);
|
||||
uint32_t *p = (uint32_t *)dst;
|
||||
for (int y = 0; y < h; ++y) {
|
||||
for (int x = 0; x < w; ++x) {
|
||||
p[x] = blurPixel(x, y, buf, _rgbPalette, w, w, h, _fmt);
|
||||
}
|
||||
p += pitch / sizeof(uint32_t);
|
||||
}
|
||||
SDL_UnlockTexture(_widescreenTexture);
|
||||
}
|
||||
}
|
||||
|
||||
void SystemStub_SDL::clearWidescreen() {
|
||||
clearTexture(_widescreenTexture, _screenH, _fmt);
|
||||
}
|
||||
|
||||
void SystemStub_SDL::enableWidescreen(bool enable) {
|
||||
_enableWidescreen = enable;
|
||||
}
|
||||
|
||||
void SystemStub_SDL::fadeScreen() {
|
||||
_fadeOnUpdateScreen = true;
|
||||
}
|
||||
|
@ -355,9 +421,11 @@ void SystemStub_SDL::updateScreen(int shakeOffset) {
|
|||
SDL_UpdateTexture(_texture, 0, _screenBuffer, _screenW * sizeof(uint32_t));
|
||||
}
|
||||
SDL_RenderClear(_renderer);
|
||||
if (_widescreen) {
|
||||
// borders / background screen
|
||||
SDL_RenderCopy(_renderer, _wideTexture, 0, 0);
|
||||
if (_widescreenMode != kWidescreenNone) {
|
||||
if (_enableWidescreen) {
|
||||
// borders / background screen
|
||||
SDL_RenderCopy(_renderer, _widescreenTexture, 0, 0);
|
||||
}
|
||||
// game screen
|
||||
SDL_Rect r;
|
||||
r.y = shakeOffset * _scaleFactor;
|
||||
|
@ -756,6 +824,10 @@ void SystemStub_SDL::unlockAudio() {
|
|||
SDL_UnlockAudio();
|
||||
}
|
||||
|
||||
static bool is16_9(const SDL_DisplayMode *mode) {
|
||||
return (mode->w / (float)mode->h) >= (16 / 9.f);
|
||||
}
|
||||
|
||||
void SystemStub_SDL::prepareGraphics() {
|
||||
_texW = _screenW;
|
||||
_texH = _screenH;
|
||||
|
@ -781,7 +853,15 @@ void SystemStub_SDL::prepareGraphics() {
|
|||
} else {
|
||||
flags |= SDL_WINDOW_RESIZABLE;
|
||||
}
|
||||
if (_widescreen) {
|
||||
if (0 /* && _widescreenMode == kWidescreenDefault */) {
|
||||
SDL_DisplayMode dm;
|
||||
if (SDL_GetDesktopDisplayMode(0, &dm) == 0 && is16_9(&dm)) {
|
||||
_widescreenMode = kWidescreenBlur; // default widescreen mode
|
||||
} else {
|
||||
_widescreenMode = kWidescreenNone;
|
||||
}
|
||||
}
|
||||
if (_widescreenMode != kWidescreenNone) {
|
||||
windowW = windowH * 16 / 9;
|
||||
}
|
||||
_window = SDL_CreateWindow(_caption, SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, windowW, windowH, flags);
|
||||
|
@ -793,11 +873,13 @@ void SystemStub_SDL::prepareGraphics() {
|
|||
_renderer = SDL_CreateRenderer(_window, -1, SDL_RENDERER_ACCELERATED);
|
||||
SDL_RenderSetLogicalSize(_renderer, windowW, windowH);
|
||||
_texture = SDL_CreateTexture(_renderer, kPixelFormat, SDL_TEXTUREACCESS_STREAMING, _texW, _texH);
|
||||
if (_widescreen) {
|
||||
const int w = _screenH * 16 / 9;
|
||||
if (_widescreenMode != kWidescreenNone) {
|
||||
// in blur mode, the background texture has the same dimensions as the game texture
|
||||
// SDL stretches the texture to 16:9
|
||||
const int w = (_widescreenMode == kWidescreenBlur) ? _screenW : _screenH * 16 / 9;
|
||||
const int h = _screenH;
|
||||
_wideTexture = SDL_CreateTexture(_renderer, kPixelFormat, SDL_TEXTUREACCESS_STREAMING, w, h);
|
||||
clearTexture(_wideTexture, _screenH, _fmt);
|
||||
_widescreenTexture = SDL_CreateTexture(_renderer, kPixelFormat, SDL_TEXTUREACCESS_STREAMING, w, h);
|
||||
clearTexture(_widescreenTexture, _screenH, _fmt);
|
||||
|
||||
// left and right borders
|
||||
_wideMargin = (w - _screenW) / 2;
|
||||
|
@ -809,9 +891,9 @@ void SystemStub_SDL::cleanupGraphics() {
|
|||
SDL_DestroyTexture(_texture);
|
||||
_texture = 0;
|
||||
}
|
||||
if (_wideTexture) {
|
||||
SDL_DestroyTexture(_wideTexture);
|
||||
_wideTexture = 0;
|
||||
if (_widescreenTexture) {
|
||||
SDL_DestroyTexture(_widescreenTexture);
|
||||
_widescreenTexture = 0;
|
||||
}
|
||||
if (_renderer) {
|
||||
SDL_DestroyRenderer(_renderer);
|
||||
|
@ -859,7 +941,7 @@ void SystemStub_SDL::changeScaler(int scaler) {
|
|||
break;
|
||||
case 5:
|
||||
scalerParameters.type = kScalerTypeInternal;
|
||||
scalerParameters.scaler = &scaler_xbrz;
|
||||
scalerParameters.scaler = &scaler_xbr;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
|
@ -868,13 +950,13 @@ void SystemStub_SDL::changeScaler(int scaler) {
|
|||
if (_scalerType != scalerParameters.type || scalerParameters.scaler != _scaler) {
|
||||
_scalerType = scalerParameters.type;
|
||||
_scaler = scalerParameters.scaler;
|
||||
const int scaleFactor = CLIP(_scaleFactor, _scaler->factorMin, _scaler->factorMax);
|
||||
// only recreate the window if dimensions actually changed
|
||||
if (scaleFactor != _scaleFactor) {
|
||||
cleanupGraphics();
|
||||
_scaleFactor = scaleFactor;
|
||||
prepareGraphics();
|
||||
if (_scalerType == kScalerTypeInternal || _scalerType == kScalerTypeExternal) {
|
||||
_scaleFactor = CLIP(_scaleFactor, _scaler->factorMin, _scaler->factorMax);
|
||||
} else {
|
||||
_scaleFactor = 1;
|
||||
}
|
||||
cleanupGraphics();
|
||||
prepareGraphics();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
12
unpack.cpp
12
unpack.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "unpack.h"
|
||||
|
@ -18,7 +18,7 @@ struct UnpackCtx {
|
|||
static bool nextBit(UnpackCtx *uc) {
|
||||
bool carry = (uc->bits & 1) != 0;
|
||||
uc->bits >>= 1;
|
||||
if (uc->bits == 0) {
|
||||
if (uc->bits == 0) { // getnextlwd
|
||||
uc->bits = READ_BE_UINT32(uc->src); uc->src -= 4;
|
||||
uc->crc ^= uc->bits;
|
||||
carry = (uc->bits & 1) != 0;
|
||||
|
@ -27,7 +27,7 @@ static bool nextBit(UnpackCtx *uc) {
|
|||
return carry;
|
||||
}
|
||||
|
||||
static int getBits(UnpackCtx *uc, int count) {
|
||||
static int getBits(UnpackCtx *uc, int count) { // rdd1bits
|
||||
int bits = 0;
|
||||
for (int i = 0; i < count; ++i) {
|
||||
bits <<= 1;
|
||||
|
@ -38,7 +38,7 @@ static int getBits(UnpackCtx *uc, int count) {
|
|||
return bits;
|
||||
}
|
||||
|
||||
static void copyLiteral(UnpackCtx *uc, int bitsCount, int len) {
|
||||
static void copyLiteral(UnpackCtx *uc, int bitsCount, int len) { // getd3chr
|
||||
int count = getBits(uc, bitsCount) + len + 1;
|
||||
uc->size -= count;
|
||||
if (uc->size < 0) {
|
||||
|
@ -51,7 +51,7 @@ static void copyLiteral(UnpackCtx *uc, int bitsCount, int len) {
|
|||
uc->dst -= count;
|
||||
}
|
||||
|
||||
static void copyReference(UnpackCtx *uc, int bitsCount, int count) {
|
||||
static void copyReference(UnpackCtx *uc, int bitsCount, int count) { // copyd3bytes
|
||||
uc->size -= count;
|
||||
if (uc->size < 0) {
|
||||
count += uc->size;
|
||||
|
@ -64,7 +64,7 @@ static void copyReference(UnpackCtx *uc, int bitsCount, int count) {
|
|||
uc->dst -= count;
|
||||
}
|
||||
|
||||
bool delphine_unpack(uint8_t *dst, int dstSize, const uint8_t *src, int srcSize) {
|
||||
bool bytekiller_unpack(uint8_t *dst, int dstSize, const uint8_t *src, int srcSize) {
|
||||
UnpackCtx uc;
|
||||
uc.src = src + srcSize - 4;
|
||||
uc.size = READ_BE_UINT32(uc.src); uc.src -= 4;
|
||||
|
|
4
unpack.h
4
unpack.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef UNPACK_H__
|
||||
|
@ -9,6 +9,6 @@
|
|||
|
||||
#include "intern.h"
|
||||
|
||||
extern bool delphine_unpack(uint8_t *dst, int dstSize, const uint8_t *src, int srcSize);
|
||||
extern bool bytekiller_unpack(uint8_t *dst, int dstSize, const uint8_t *src, int srcSize);
|
||||
|
||||
#endif // UNPACK_H__
|
||||
|
|
2
util.cpp
2
util.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
2
util.h
2
util.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H__
|
||||
|
|
121
video.cpp
121
video.cpp
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#include "decode_mac.h"
|
||||
|
@ -11,8 +11,8 @@
|
|||
#include "util.h"
|
||||
#include "video.h"
|
||||
|
||||
Video::Video(Resource *res, SystemStub *stub)
|
||||
: _res(res), _stub(stub) {
|
||||
Video::Video(Resource *res, SystemStub *stub, WidescreenMode widescreenMode)
|
||||
: _res(res), _stub(stub), _widescreenMode(widescreenMode) {
|
||||
_layerScale = (_res->_type == kResourceTypeMac) ? 2 : 1; // Macintosh version is 512x448
|
||||
_w = GAMESCREEN_W * _layerScale;
|
||||
_h = GAMESCREEN_H * _layerScale;
|
||||
|
@ -115,6 +115,18 @@ void Video::updateScreen() {
|
|||
}
|
||||
}
|
||||
|
||||
void Video::updateWidescreen() {
|
||||
if (_stub->hasWidescreen()) {
|
||||
if (_widescreenMode == kWidescreenMirrorRoom) {
|
||||
_stub->copyWidescreenMirror(_w, _h, _backLayer);
|
||||
} else if (_widescreenMode == kWidescreenBlur) {
|
||||
_stub->copyWidescreenBlur(_w, _h, _backLayer);
|
||||
} else {
|
||||
_stub->clearWidescreen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Video::fullRefresh() {
|
||||
debug(DBG_VIDEO, "Video::fullRefresh()");
|
||||
_fullRefresh = true;
|
||||
|
@ -154,20 +166,26 @@ void Video::setPaletteColorBE(int num, int offset) {
|
|||
|
||||
void Video::setPaletteSlotBE(int palSlot, int palNum) {
|
||||
debug(DBG_VIDEO, "Video::setPaletteSlotBE()");
|
||||
const uint8_t *p = _res->_pal + palNum * 0x20;
|
||||
const uint8_t *p = _res->_pal + palNum * 32;
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
const int color = READ_BE_UINT16(p); p += 2;
|
||||
Color c = AMIGA_convertColor(color, true);
|
||||
_stub->setPaletteEntry(palSlot * 0x10 + i, &c);
|
||||
_stub->setPaletteEntry(palSlot * 16 + i, &c);
|
||||
}
|
||||
}
|
||||
|
||||
void Video::setPaletteSlotLE(int palSlot, const uint8_t *palData) {
|
||||
debug(DBG_VIDEO, "Video::setPaletteSlotLE()");
|
||||
for (int i = 0; i < 16; ++i) {
|
||||
uint16_t color = READ_LE_UINT16(palData); palData += 2;
|
||||
const uint16_t color = READ_LE_UINT16(palData + i * 2);
|
||||
Color c = AMIGA_convertColor(color);
|
||||
_stub->setPaletteEntry(palSlot * 0x10 + i, &c);
|
||||
_stub->setPaletteEntry(palSlot * 16 + i, &c);
|
||||
}
|
||||
if (palSlot == 4 && g_options.use_white_tshirt) {
|
||||
const Color color12 = AMIGA_convertColor(0x888);
|
||||
const Color color13 = AMIGA_convertColor((palData == _conradPal2) ? 0x888 : 0xCCC);
|
||||
_stub->setPaletteEntry(palSlot * 16 + 12, &color12);
|
||||
_stub->setPaletteEntry(palSlot * 16 + 13, &color13);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -315,6 +333,33 @@ void Video::PC_decodeSpc(const uint8_t *src, int w, int h, uint8_t *dst) {
|
|||
}
|
||||
}
|
||||
|
||||
void Video::PC_decodeSpm(const uint8_t *dataPtr, uint8_t *dst) {
|
||||
const int len = 2 * READ_BE_UINT16(dataPtr); dataPtr += 2;
|
||||
uint8_t *dst2 = dst + 1024;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
*dst2++ = dataPtr[i] >> 4;
|
||||
*dst2++ = dataPtr[i] & 15;
|
||||
}
|
||||
const uint8_t *src = dst + 1024;
|
||||
const uint8_t *end = src + len;
|
||||
do {
|
||||
const uint8_t code = *src++;
|
||||
if (code == 0xF) {
|
||||
uint8_t color = *src++;
|
||||
int count = *src++;
|
||||
if (color == 0xF) {
|
||||
count = (count << 4) | *src++;
|
||||
color = *src++;
|
||||
}
|
||||
count += 4;
|
||||
memset(dst, color, count);
|
||||
dst += count;
|
||||
} else {
|
||||
*dst++ = code;
|
||||
}
|
||||
} while (src < end);
|
||||
}
|
||||
|
||||
static void AMIGA_planar16(uint8_t *dst, int w, int h, int depth, const uint8_t *src) {
|
||||
const int pitch = w * 16;
|
||||
const int planarSize = w * 2 * h;
|
||||
|
@ -629,7 +674,7 @@ static void decodeLevHelper(uint8_t *dst, const uint8_t *src, int offset10, int
|
|||
void Video::AMIGA_decodeLev(int level, int room) {
|
||||
uint8_t *tmp = _res->_scratchBuffer;
|
||||
const int offset = READ_BE_UINT32(_res->_lev + room * 4);
|
||||
if (!delphine_unpack(tmp, Resource::kScratchBufferSize, _res->_lev, offset)) {
|
||||
if (!bytekiller_unpack(tmp, Resource::kScratchBufferSize, _res->_lev, offset)) {
|
||||
warning("Bad CRC for level %d room %d", level, room);
|
||||
return;
|
||||
}
|
||||
|
@ -912,7 +957,7 @@ void Video::MAC_drawStringChar(uint8_t *dst, int pitch, int x, int y, const uint
|
|||
buf.h = _h;
|
||||
buf.x = x * _layerScale;
|
||||
buf.y = y * _layerScale;
|
||||
buf.setPixel = Video::MAC_drawBufferFont;
|
||||
buf.setPixel = Video::MAC_setPixelFont;
|
||||
_MAC_fontFrontColor = color;
|
||||
_MAC_fontShadowColor = _charShadowColor;
|
||||
assert(chr >= 32);
|
||||
|
@ -963,7 +1008,7 @@ void Video::MAC_decodeMap(int level, int room) {
|
|||
buf.ptr = _frontLayer;
|
||||
buf.w = buf.pitch = _w;
|
||||
buf.h = _h;
|
||||
buf.setPixel = Video::MAC_drawBuffer;
|
||||
buf.setPixel = Video::MAC_setPixel;
|
||||
_res->MAC_loadLevelRoom(level, room, &buf);
|
||||
memcpy(_backLayer, _frontLayer, _layerSize);
|
||||
Color roomPalette[256];
|
||||
|
@ -979,45 +1024,27 @@ void Video::MAC_decodeMap(int level, int room) {
|
|||
}
|
||||
}
|
||||
|
||||
void Video::MAC_drawBuffer(DecodeBuffer *buf, int src_x, int src_y, int src_w, int src_h, uint8_t color) {
|
||||
const int y = buf->y + src_y;
|
||||
if (y >= 0 && y < buf->h) {
|
||||
const int x = buf->xflip ? (buf->x + (src_w - 1 - src_x)) : (buf->x + src_x);
|
||||
if (x >= 0 && x < buf->w) {
|
||||
const int offset = y * buf->pitch + x;
|
||||
buf->ptr[offset] = color;
|
||||
}
|
||||
void Video::MAC_setPixel(DecodeBuffer *buf, int x, int y, uint8_t color) {
|
||||
const int offset = y * buf->pitch + x;
|
||||
buf->ptr[offset] = color;
|
||||
}
|
||||
|
||||
void Video::MAC_setPixelMask(DecodeBuffer *buf, int x, int y, uint8_t color) {
|
||||
const int offset = y * buf->pitch + x;
|
||||
if ((buf->ptr[offset] & 0x80) == 0) {
|
||||
buf->ptr[offset] = color;
|
||||
}
|
||||
}
|
||||
|
||||
void Video::MAC_drawBufferMask(DecodeBuffer *buf, int src_x, int src_y, int src_w, int src_h, uint8_t color) {
|
||||
const int y = buf->y + src_y;
|
||||
if (y >= 0 && y < buf->h) {
|
||||
const int x = buf->xflip ? (buf->x + (src_w - 1 - src_x)) : (buf->x + src_x);
|
||||
if (x >= 0 && x < buf->w) {
|
||||
const int offset = y * buf->pitch + x;
|
||||
if ((buf->ptr[offset] & 0x80) == 0) {
|
||||
buf->ptr[offset] = color;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Video::MAC_drawBufferFont(DecodeBuffer *buf, int src_x, int src_y, int src_w, int src_h, uint8_t color) {
|
||||
const int y = buf->y + src_y;
|
||||
if (y >= 0 && y < buf->h) {
|
||||
const int x = buf->x + src_x;
|
||||
if (x >= 0 && x < buf->w) {
|
||||
const int offset = y * buf->pitch + x;
|
||||
switch (color) {
|
||||
case 0xC0:
|
||||
buf->ptr[offset] = _MAC_fontShadowColor;
|
||||
break;
|
||||
case 0xC1:
|
||||
buf->ptr[offset] = _MAC_fontFrontColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
void Video::MAC_setPixelFont(DecodeBuffer *buf, int x, int y, uint8_t color) {
|
||||
const int offset = y * buf->pitch + x;
|
||||
switch (color) {
|
||||
case 0xC0:
|
||||
buf->ptr[offset] = _MAC_fontShadowColor;
|
||||
break;
|
||||
case 0xC1:
|
||||
buf->ptr[offset] = _MAC_fontFrontColor;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1049,7 +1076,7 @@ void Video::MAC_drawSprite(int x, int y, const uint8_t *data, int frame, bool xf
|
|||
buf.h = _h;
|
||||
buf.x = x * _layerScale;
|
||||
buf.y = y * _layerScale;
|
||||
buf.setPixel = eraseBackground ? MAC_drawBuffer : MAC_drawBufferMask;
|
||||
buf.setPixel = eraseBackground ? MAC_setPixel : MAC_setPixelMask;
|
||||
fixOffsetDecodeBuffer(&buf, dataPtr);
|
||||
_res->MAC_decodeImageData(data, frame, &buf);
|
||||
markBlockAsDirty(buf.x, buf.y, READ_BE_UINT16(dataPtr), READ_BE_UINT16(dataPtr + 2), 1);
|
||||
|
|
13
video.h
13
video.h
|
@ -1,7 +1,7 @@
|
|||
|
||||
/*
|
||||
* REminiscence - Flashback interpreter
|
||||
* Copyright (C) 2005-2018 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
* Copyright (C) 2005-2019 Gregory Montoir (cyx@users.sourceforge.net)
|
||||
*/
|
||||
|
||||
#ifndef VIDEO_H__
|
||||
|
@ -32,6 +32,7 @@ struct Video {
|
|||
|
||||
Resource *_res;
|
||||
SystemStub *_stub;
|
||||
WidescreenMode _widescreenMode;
|
||||
|
||||
int _w, _h;
|
||||
int _layerSize;
|
||||
|
@ -50,11 +51,12 @@ struct Video {
|
|||
uint8_t _shakeOffset;
|
||||
drawCharFunc _drawChar;
|
||||
|
||||
Video(Resource *res, SystemStub *stub);
|
||||
Video(Resource *res, SystemStub *stub, WidescreenMode widescreenMode);
|
||||
~Video();
|
||||
|
||||
void markBlockAsDirty(int16_t x, int16_t y, uint16_t w, uint16_t h, int scale);
|
||||
void updateScreen();
|
||||
void updateWidescreen();
|
||||
void fullRefresh();
|
||||
void fadeOut();
|
||||
void fadeOutPalette();
|
||||
|
@ -68,6 +70,7 @@ struct Video {
|
|||
void PC_setLevelPalettes();
|
||||
void PC_decodeIcn(const uint8_t *src, int num, uint8_t *dst);
|
||||
void PC_decodeSpc(const uint8_t *src, int w, int h, uint8_t *dst);
|
||||
void PC_decodeSpm(const uint8_t *dataPtr, uint8_t *dstPtr);
|
||||
void AMIGA_decodeLev(int level, int room);
|
||||
void AMIGA_decodeSpm(const uint8_t *src, uint8_t *dst);
|
||||
void AMIGA_decodeIcn(const uint8_t *src, int num, uint8_t *dst);
|
||||
|
@ -87,9 +90,9 @@ struct Video {
|
|||
void drawStringLen(const char *str, int len, int x, int y, uint8_t color);
|
||||
static Color AMIGA_convertColor(const uint16_t color, bool bgr = false);
|
||||
void MAC_decodeMap(int level, int room);
|
||||
static void MAC_drawBuffer(DecodeBuffer *buf, int src_x, int src_y, int src_w, int src_h, uint8_t color);
|
||||
static void MAC_drawBufferMask(DecodeBuffer *buf, int src_x, int src_y, int src_w, int src_h, uint8_t color);
|
||||
static void MAC_drawBufferFont(DecodeBuffer *buf, int src_x, int src_y, int src_w, int src_h, uint8_t color);
|
||||
static void MAC_setPixel(DecodeBuffer *buf, int x, int y, uint8_t color);
|
||||
static void MAC_setPixelMask(DecodeBuffer *buf, int x, int y, uint8_t color);
|
||||
static void MAC_setPixelFont(DecodeBuffer *buf, int x, int y, uint8_t color);
|
||||
void fillRect(int x, int y, int w, int h, uint8_t color);
|
||||
void MAC_drawSprite(int x, int y, const uint8_t *data, int frame, bool xflip, bool eraseBackground);
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue