From 7f1af541a6d25de9a6b41460201db3795d75b23a Mon Sep 17 00:00:00 2001 From: Gregory Montoir Date: Sun, 25 Feb 2018 00:00:00 +0800 Subject: [PATCH] Import 0.4.1 --- Makefile | 2 +- README.txt | 2 +- game.cpp | 6 ++--- intern.h | 1 + piege.cpp | 9 +++++++ resource.cpp | 44 ++++++++++++++++++++++++++++++++ resource.h | 22 ++++++++-------- rs.cfg | 2 +- unpack.cpp | 71 ++++++++++++++++++++++++---------------------------- video.cpp | 18 +++++++++---- 10 files changed, 118 insertions(+), 59 deletions(-) diff --git a/Makefile b/Makefile index c0a1722..b0c60bb 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ MODPLUG_LIBS := -lmodplug TREMOR_LIBS := -lvorbisidec -logg ZLIB_LIBS := -lz -CXXFLAGS += -Wall -MMD $(SDL_CFLAGS) -DUSE_MODPLUG -DUSE_TREMOR -DUSE_ZLIB +CXXFLAGS += -O2 -Wall -MMD $(SDL_CFLAGS) -DUSE_MODPLUG -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 \ diff --git a/README.txt b/README.txt index 8c74e8c..74c5278 100644 --- a/README.txt +++ b/README.txt @@ -1,6 +1,6 @@ REminiscence README -Release version: 0.4.0 +Release version: 0.4.1 ------------------------------------------------------------------------------- diff --git a/game.cpp b/game.cpp index 55fa1c7..3e435f1 100644 --- a/game.cpp +++ b/game.cpp @@ -82,6 +82,7 @@ void Game::run() { case kResourceTypeMac: _res.MAC_loadIconData(); _res.MAC_loadPersoData(); + _res.MAC_loadSounds(); break; } @@ -1496,10 +1497,10 @@ void Game::loadLevelMap() { case kResourceTypeDOS: if (_res._map) { _vid.PC_decodeMap(_currentLevel, _currentRoom); + _vid.PC_setLevelPalettes(); } else if (_res._lev) { _vid.PC_decodeLev(_currentLevel, _currentRoom); } - _vid.PC_setLevelPalettes(); break; case kResourceTypeMac: { @@ -1728,8 +1729,7 @@ void Game::playSound(uint8_t sfxId, uint8_t softVol) { MixerChunk mc; mc.data = sfx->data; mc.len = sfx->len; - const int freq = _res.isAmiga() ? 3546897 / 650 : 6000; - _mix.play(&mc, freq, Mixer::MAX_VOLUME >> softVol); + _mix.play(&mc, sfx->freq, Mixer::MAX_VOLUME >> softVol); } } else { // in-game music diff --git a/intern.h b/intern.h index 0fd89ab..71a8d8a 100644 --- a/intern.h +++ b/intern.h @@ -246,6 +246,7 @@ struct InventoryItem { struct SoundFx { uint32_t offset; uint16_t len; + uint16_t freq; uint8_t *data; }; diff --git a/piege.cpp b/piege.cpp index 52da2d4..83b0827 100644 --- a/piege.cpp +++ b/piege.cpp @@ -133,6 +133,15 @@ void Game::pge_process(LivePGE *pge) { return; } uint16_t _ax = pge_execute(pge, init_pge, obj); + if (_res.isDOS()) { + if (_currentLevel == 6 && (_currentRoom == 50 || _currentRoom == 51)) { + if (pge->index == 79 && _ax == 0xFFFF && obj->opcode1 == 0x60 && obj->opcode2 == 0 && obj->opcode3 == 0) { + if (col_getGridPos(&_pgeLive[79], 0) == col_getGridPos(&_pgeLive[0], 0)) { + pge_updateGroup(79, 0, 4); + } + } + } + } if (_ax != 0) { anim_data = _res.getAniData(pge->obj_type); uint8_t snd = anim_data[2]; diff --git a/resource.cpp b/resource.cpp index 56d205e..651a1ad 100644 --- a/resource.cpp +++ b/resource.cpp @@ -140,6 +140,7 @@ void Resource::load_FIB(const char *fileName) { SoundFx *sfx = &_sfxList[i]; sfx->offset = f.readUint32LE(); sfx->len = f.readUint16LE(); + sfx->freq = 6000; sfx->data = 0; } for (i = 0; i < _numSfx; ++i) { @@ -190,6 +191,7 @@ void Resource::load_SPL_demo() { f.read(sfx->data, size); sfx->offset = 0; sfx->len = size; + sfx->freq = kPaulaFreq / 650; } } } @@ -1202,6 +1204,7 @@ void Resource::load_SPL(File *f) { if (i != 64) { _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); @@ -1647,3 +1650,44 @@ void Resource::MAC_loadCutsceneText() { _cine_txt = decodeResourceMacData("Movie strings", false); _cine_off = 0; // offsets are prepended to _cine_txt } + +void Resource::MAC_loadSounds() { + static const int8_t table[NUM_SFXS] = { + 0, -1, 1, 2, 3, 4, -1, 5, 6, 7, 8, 9, 10, 11, -1, 12, + 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, 26, 27, + 28, -1, 29, -1, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, -1, 53, 54, 55, 56, + -1, 57 + }; + _numSfx = NUM_SFXS; + _sfxList = (SoundFx *)calloc(_numSfx, sizeof(SoundFx)); + if (!_sfxList) { + return; + } + static const int kHeaderSize = 0x24; + static const int kSoundType = 4; + for (int i = 0; i < NUM_SFXS; ++i) { + const int num = table[i]; + if (num != -1) { + assert(num >= 0 && num < _mac->_types[kSoundType].count); + const ResourceMacEntry *entry = &_mac->_entries[kSoundType][num]; + _mac->_f.seek(_mac->_dataOffset + entry->dataOffset); + int dataSize = _mac->_f.readUint32BE(); + assert(dataSize > kHeaderSize); + uint8_t buf[kHeaderSize]; + _mac->_f.read(buf, kHeaderSize); + dataSize -= kHeaderSize; + uint8_t *p = (uint8_t *)malloc(dataSize); + if (p) { + _mac->_f.read(p, dataSize); + for (int j = 0; j < dataSize; ++j) { + p[j] ^= 0x80; + } + _sfxList[i].len = READ_BE_UINT32(buf + 0x12); + _sfxList[i].freq = READ_BE_UINT16(buf + 0x16); + _sfxList[i].data = p; + debug(DBG_RES, "sfx #%d len %d datasize %d freq %d", i, _sfxList[i].len, dataSize, _sfxList[i].freq); + } + } + } +} diff --git a/resource.h b/resource.h index 80bf8dc..fbb2c5c 100644 --- a/resource.h +++ b/resource.h @@ -111,6 +111,7 @@ struct Resource { }; enum { + kPaulaFreq = 3546897, kClutSize = 1024 }; @@ -238,6 +239,12 @@ struct Resource { return _ani + 2 + offset; } const uint8_t *getTextString(int level, int num) const { + if (_type == kResourceTypeMac) { + const int count = READ_BE_UINT16(_tbn); + assert(num < count); + const int offset = READ_BE_UINT16(_tbn + 2 + num * 2); + return _tbn + offset; + } if (_lang == LANG_JP) { const uint8_t *p = 0; switch (level) { @@ -267,12 +274,6 @@ struct Resource { } return p + READ_LE_UINT16(p + num * 2); } - if (_type == kResourceTypeMac) { - const int count = READ_BE_UINT16(_tbn); - assert(num < count); - const int offset = READ_BE_UINT16(_tbn + 2 + num * 2); - return _tbn + offset; - } return _tbn + _readUint16(_tbn + num * 2); } const uint8_t *getGameString(int num) const { @@ -285,16 +286,16 @@ struct Resource { return _stringsTable + READ_LE_UINT16(_stringsTable + num * 2); } const uint8_t *getCineString(int num) const { - if (_lang == LANG_JP) { - const int offset = READ_BE_UINT16(LocaleData::_cineBinJP + num * 2); - return LocaleData::_cineTxtJP + offset; - } if (_type == kResourceTypeMac) { const int count = READ_BE_UINT16(_cine_txt); assert(num < count); const int offset = READ_BE_UINT16(_cine_txt + 2 + num * 2); return _cine_txt + offset; } + if (_lang == LANG_JP) { + const int offset = READ_BE_UINT16(LocaleData::_cineBinJP + num * 2); + return LocaleData::_cineTxtJP + offset; + } if (_cine_off) { const int offset = READ_BE_UINT16(_cine_off + num * 2); return _cine_txt + offset; @@ -329,6 +330,7 @@ struct Resource { void MAC_unloadCutscene(); void MAC_loadCutscene(const char *cutscene); void MAC_loadCutsceneText(); + void MAC_loadSounds(); int MAC_getPersoFrame(int anim) const { static const int data[] = { diff --git a/rs.cfg b/rs.cfg index fb5f9d6..08fc206 100644 --- a/rs.cfg +++ b/rs.cfg @@ -17,7 +17,7 @@ use_text_cutscenes=false use_seq_cutscenes=true # enable playback of 'ASC' cutscene -play_asc_cutscene=true +play_asc_cutscene=false # enable playback of 'CAILLOU-F.SET' cutscene play_caillou_cutscene=true diff --git a/unpack.cpp b/unpack.cpp index dd8218e..ad490a2 100644 --- a/unpack.cpp +++ b/unpack.cpp @@ -7,35 +7,28 @@ #include "unpack.h" struct UnpackCtx { - int size, datasize; + int datasize; uint32_t crc; uint32_t bits; uint8_t *dst; const uint8_t *src; }; -static int shiftBit(UnpackCtx *uc, int CF) { - int rCF = (uc->bits & 1); +static bool nextBit(UnpackCtx *uc) { + bool carry = (uc->bits & 1) != 0; uc->bits >>= 1; - if (CF) { - uc->bits |= 0x80000000; - } - return rCF; -} - -static int nextBit(UnpackCtx *uc) { - int CF = shiftBit(uc, 0); if (uc->bits == 0) { uc->bits = READ_BE_UINT32(uc->src); uc->src -= 4; uc->crc ^= uc->bits; - CF = shiftBit(uc, 1); + carry = (uc->bits & 1) != 0; + uc->bits = (1 << 31) | (uc->bits >> 1); } - return CF; + return carry; } -static uint16_t getBits(UnpackCtx *uc, uint8_t num_bits) { +static uint16_t getBits(UnpackCtx *uc, int bitsCount) { uint16_t c = 0; - while (num_bits--) { + for (int i = 0; i < bitsCount; ++i) { c <<= 1; if (nextBit(uc)) { c |= 1; @@ -44,23 +37,22 @@ static uint16_t getBits(UnpackCtx *uc, uint8_t num_bits) { return c; } -static void unpackHelper1(UnpackCtx *uc, uint8_t num_bits, uint8_t add_count) { - uint16_t count = getBits(uc, num_bits) + add_count + 1; - uc->datasize -= count; - while (count--) { +static void copyLiteral(UnpackCtx *uc, int bitsCount, int len) { + const int count = getBits(uc, bitsCount) + len + 1; + for (int i = 0; i < count; ++i) { *uc->dst = (uint8_t)getBits(uc, 8); --uc->dst; } + uc->datasize -= count; } -static void unpackHelper2(UnpackCtx *uc, uint8_t num_bits) { - uint16_t i = getBits(uc, num_bits); - uint16_t count = uc->size + 1; - uc->datasize -= count; - while (count--) { - *uc->dst = *(uc->dst + i); +static void copyReference(UnpackCtx *uc, int bitsCount, int count) { + const uint16_t offset = getBits(uc, bitsCount); + for (int i = 0; i < count; ++i) { + *uc->dst = *(uc->dst + offset); --uc->dst; } + uc->datasize -= count; } bool delphine_unpack(uint8_t *dst, const uint8_t *src, int len) { @@ -68,28 +60,31 @@ bool delphine_unpack(uint8_t *dst, const uint8_t *src, int len) { uc.src = src + len - 4; uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4; uc.dst = dst + uc.datasize - 1; - uc.size = 0; uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4; uc.bits = READ_BE_UINT32(uc.src); uc.src -= 4; uc.crc ^= uc.bits; do { if (!nextBit(&uc)) { - uc.size = 1; if (!nextBit(&uc)) { - unpackHelper1(&uc, 3, 0); + copyLiteral(&uc, 3, 0); } else { - unpackHelper2(&uc, 8); + copyReference(&uc, 8, 2); } } else { - uint16_t c = getBits(&uc, 2); - if (c == 3) { - unpackHelper1(&uc, 8, 8); - } else if (c < 2) { - uc.size = c + 2; - unpackHelper2(&uc, c + 9); - } else { - uc.size = getBits(&uc, 8); - unpackHelper2(&uc, 12); + const int code = getBits(&uc, 2); + switch (code) { + case 3: + copyLiteral(&uc, 8, 8); + break; + case 2: + copyReference(&uc, 12, getBits(&uc, 8) + 1); + break; + case 1: + copyReference(&uc, 10, 4); + break; + case 0: + copyReference(&uc, 9, 3); + break; } } } while (uc.datasize > 0); diff --git a/video.cpp b/video.cpp index 99bae0a..b4a41c6 100644 --- a/video.cpp +++ b/video.cpp @@ -259,18 +259,23 @@ void Video::PC_setLevelPalettes() { if (_unkPalSlot1 == 0) { _unkPalSlot1 = _mapPalSlot3; } + // background setPaletteSlotBE(0x0, _mapPalSlot1); + // objects setPaletteSlotBE(0x1, _mapPalSlot2); setPaletteSlotBE(0x2, _mapPalSlot3); setPaletteSlotBE(0x3, _mapPalSlot4); + // conrad if (_unkPalSlot1 == _mapPalSlot3) { setPaletteSlotLE(4, _conradPal1); } else { setPaletteSlotLE(4, _conradPal2); } // slot 5 is monster palette + // foreground setPaletteSlotBE(0x8, _mapPalSlot1); setPaletteSlotBE(0x9, _mapPalSlot2); + // inventory setPaletteSlotBE(0xA, _unkPalSlot2); setPaletteSlotBE(0xB, _mapPalSlot4); // slots 0xC and 0xD are cutscene palettes @@ -438,8 +443,8 @@ static void decodeSgd(uint8_t *dst, const uint8_t *src, const uint8_t *data, con int count = READ_BE_UINT16(src) - 1; src += 2; do { int d2 = READ_BE_UINT16(src); src += 2; - int d0 = READ_BE_UINT16(src); src += 2; - int d1 = READ_BE_UINT16(src); src += 2; + const int d0 = (int16_t)READ_BE_UINT16(src); src += 2; + const int d1 = (int16_t)READ_BE_UINT16(src); src += 2; if (d2 != 0xFFFF) { d2 &= ~(1 << 15); const int32_t offset = READ_BE_UINT32(data + d2 * 4); @@ -464,9 +469,9 @@ static void decodeSgd(uint8_t *dst, const uint8_t *src, const uint8_t *data, con const int h = buf[1] + 1; const int planarSize = READ_BE_UINT16(buf + 2); if (isAmiga) { - AMIGA_planar_mask(dst, (int16_t)d0, (int16_t)d1, w, h, buf + 4, buf + 4 + planarSize, planarSize); + AMIGA_planar_mask(dst, d0, d1, w, h, buf + 4, buf + 4 + planarSize, planarSize); } else { - PC_drawTileMask(dst, (int16_t)d0, (int16_t)d1, w, h, buf + 4, buf + 4 + planarSize, planarSize); + PC_drawTileMask(dst, d0, d1, w, h, buf + 4, buf + 4 + planarSize, planarSize); } } while (--count >= 0); } @@ -662,7 +667,10 @@ void Video::AMIGA_decodeLev(int level, int room) { _mapPalSlot3 = READ_BE_UINT16(tmp + 6); _mapPalSlot4 = READ_BE_UINT16(tmp + 8); if (_res->isDOS()) { - // done in ::PC_setLevelPalettes + PC_setLevelPalettes(); + if (level == 0) { // tiles with color slot 0x9 + setPaletteSlotBE(0x9, _mapPalSlot1); + } return; } // background