Import 0.4.1

This commit is contained in:
Gregory Montoir 2018-02-25 00:00:00 +08:00
parent bfef522ada
commit 7f1af541a6
10 changed files with 118 additions and 59 deletions

View File

@ -7,7 +7,7 @@ MODPLUG_LIBS := -lmodplug
TREMOR_LIBS := -lvorbisidec -logg TREMOR_LIBS := -lvorbisidec -logg
ZLIB_LIBS := -lz 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 \ 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 \ menu.cpp mixer.cpp mod_player.cpp ogg_player.cpp piege.cpp resource.cpp resource_aba.cpp \

View File

@ -1,6 +1,6 @@
REminiscence README REminiscence README
Release version: 0.4.0 Release version: 0.4.1
------------------------------------------------------------------------------- -------------------------------------------------------------------------------

View File

@ -82,6 +82,7 @@ void Game::run() {
case kResourceTypeMac: case kResourceTypeMac:
_res.MAC_loadIconData(); _res.MAC_loadIconData();
_res.MAC_loadPersoData(); _res.MAC_loadPersoData();
_res.MAC_loadSounds();
break; break;
} }
@ -1496,10 +1497,10 @@ void Game::loadLevelMap() {
case kResourceTypeDOS: case kResourceTypeDOS:
if (_res._map) { if (_res._map) {
_vid.PC_decodeMap(_currentLevel, _currentRoom); _vid.PC_decodeMap(_currentLevel, _currentRoom);
_vid.PC_setLevelPalettes();
} else if (_res._lev) { } else if (_res._lev) {
_vid.PC_decodeLev(_currentLevel, _currentRoom); _vid.PC_decodeLev(_currentLevel, _currentRoom);
} }
_vid.PC_setLevelPalettes();
break; break;
case kResourceTypeMac: case kResourceTypeMac:
{ {
@ -1728,8 +1729,7 @@ void Game::playSound(uint8_t sfxId, uint8_t softVol) {
MixerChunk mc; MixerChunk mc;
mc.data = sfx->data; mc.data = sfx->data;
mc.len = sfx->len; mc.len = sfx->len;
const int freq = _res.isAmiga() ? 3546897 / 650 : 6000; _mix.play(&mc, sfx->freq, Mixer::MAX_VOLUME >> softVol);
_mix.play(&mc, freq, Mixer::MAX_VOLUME >> softVol);
} }
} else { } else {
// in-game music // in-game music

View File

@ -246,6 +246,7 @@ struct InventoryItem {
struct SoundFx { struct SoundFx {
uint32_t offset; uint32_t offset;
uint16_t len; uint16_t len;
uint16_t freq;
uint8_t *data; uint8_t *data;
}; };

View File

@ -133,6 +133,15 @@ void Game::pge_process(LivePGE *pge) {
return; return;
} }
uint16_t _ax = pge_execute(pge, init_pge, obj); 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) { if (_ax != 0) {
anim_data = _res.getAniData(pge->obj_type); anim_data = _res.getAniData(pge->obj_type);
uint8_t snd = anim_data[2]; uint8_t snd = anim_data[2];

View File

@ -140,6 +140,7 @@ void Resource::load_FIB(const char *fileName) {
SoundFx *sfx = &_sfxList[i]; SoundFx *sfx = &_sfxList[i];
sfx->offset = f.readUint32LE(); sfx->offset = f.readUint32LE();
sfx->len = f.readUint16LE(); sfx->len = f.readUint16LE();
sfx->freq = 6000;
sfx->data = 0; sfx->data = 0;
} }
for (i = 0; i < _numSfx; ++i) { for (i = 0; i < _numSfx; ++i) {
@ -190,6 +191,7 @@ void Resource::load_SPL_demo() {
f.read(sfx->data, size); f.read(sfx->data, size);
sfx->offset = 0; sfx->offset = 0;
sfx->len = size; sfx->len = size;
sfx->freq = kPaulaFreq / 650;
} }
} }
} }
@ -1202,6 +1204,7 @@ void Resource::load_SPL(File *f) {
if (i != 64) { if (i != 64) {
_sfxList[i].offset = offset; _sfxList[i].offset = offset;
_sfxList[i].len = size; _sfxList[i].len = size;
_sfxList[i].freq = kPaulaFreq / 650;
_sfxList[i].data = (uint8_t *)malloc(size); _sfxList[i].data = (uint8_t *)malloc(size);
assert(_sfxList[i].data); assert(_sfxList[i].data);
f->read(_sfxList[i].data, size); f->read(_sfxList[i].data, size);
@ -1647,3 +1650,44 @@ void Resource::MAC_loadCutsceneText() {
_cine_txt = decodeResourceMacData("Movie strings", false); _cine_txt = decodeResourceMacData("Movie strings", false);
_cine_off = 0; // offsets are prepended to _cine_txt _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);
}
}
}
}

View File

@ -111,6 +111,7 @@ struct Resource {
}; };
enum { enum {
kPaulaFreq = 3546897,
kClutSize = 1024 kClutSize = 1024
}; };
@ -238,6 +239,12 @@ struct Resource {
return _ani + 2 + offset; return _ani + 2 + offset;
} }
const uint8_t *getTextString(int level, int num) const { 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) { if (_lang == LANG_JP) {
const uint8_t *p = 0; const uint8_t *p = 0;
switch (level) { switch (level) {
@ -267,12 +274,6 @@ struct Resource {
} }
return p + READ_LE_UINT16(p + num * 2); 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); return _tbn + _readUint16(_tbn + num * 2);
} }
const uint8_t *getGameString(int num) const { const uint8_t *getGameString(int num) const {
@ -285,16 +286,16 @@ struct Resource {
return _stringsTable + READ_LE_UINT16(_stringsTable + num * 2); return _stringsTable + READ_LE_UINT16(_stringsTable + num * 2);
} }
const uint8_t *getCineString(int num) const { 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) { if (_type == kResourceTypeMac) {
const int count = READ_BE_UINT16(_cine_txt); const int count = READ_BE_UINT16(_cine_txt);
assert(num < count); assert(num < count);
const int offset = READ_BE_UINT16(_cine_txt + 2 + num * 2); const int offset = READ_BE_UINT16(_cine_txt + 2 + num * 2);
return _cine_txt + offset; 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) { if (_cine_off) {
const int offset = READ_BE_UINT16(_cine_off + num * 2); const int offset = READ_BE_UINT16(_cine_off + num * 2);
return _cine_txt + offset; return _cine_txt + offset;
@ -329,6 +330,7 @@ struct Resource {
void MAC_unloadCutscene(); void MAC_unloadCutscene();
void MAC_loadCutscene(const char *cutscene); void MAC_loadCutscene(const char *cutscene);
void MAC_loadCutsceneText(); void MAC_loadCutsceneText();
void MAC_loadSounds();
int MAC_getPersoFrame(int anim) const { int MAC_getPersoFrame(int anim) const {
static const int data[] = { static const int data[] = {

2
rs.cfg
View File

@ -17,7 +17,7 @@ use_text_cutscenes=false
use_seq_cutscenes=true use_seq_cutscenes=true
# enable playback of 'ASC' cutscene # enable playback of 'ASC' cutscene
play_asc_cutscene=true play_asc_cutscene=false
# enable playback of 'CAILLOU-F.SET' cutscene # enable playback of 'CAILLOU-F.SET' cutscene
play_caillou_cutscene=true play_caillou_cutscene=true

View File

@ -7,35 +7,28 @@
#include "unpack.h" #include "unpack.h"
struct UnpackCtx { struct UnpackCtx {
int size, datasize; int datasize;
uint32_t crc; uint32_t crc;
uint32_t bits; uint32_t bits;
uint8_t *dst; uint8_t *dst;
const uint8_t *src; const uint8_t *src;
}; };
static int shiftBit(UnpackCtx *uc, int CF) { static bool nextBit(UnpackCtx *uc) {
int rCF = (uc->bits & 1); bool carry = (uc->bits & 1) != 0;
uc->bits >>= 1; uc->bits >>= 1;
if (CF) {
uc->bits |= 0x80000000;
}
return rCF;
}
static int nextBit(UnpackCtx *uc) {
int CF = shiftBit(uc, 0);
if (uc->bits == 0) { if (uc->bits == 0) {
uc->bits = READ_BE_UINT32(uc->src); uc->src -= 4; uc->bits = READ_BE_UINT32(uc->src); uc->src -= 4;
uc->crc ^= uc->bits; 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; uint16_t c = 0;
while (num_bits--) { for (int i = 0; i < bitsCount; ++i) {
c <<= 1; c <<= 1;
if (nextBit(uc)) { if (nextBit(uc)) {
c |= 1; c |= 1;
@ -44,23 +37,22 @@ static uint16_t getBits(UnpackCtx *uc, uint8_t num_bits) {
return c; return c;
} }
static void unpackHelper1(UnpackCtx *uc, uint8_t num_bits, uint8_t add_count) { static void copyLiteral(UnpackCtx *uc, int bitsCount, int len) {
uint16_t count = getBits(uc, num_bits) + add_count + 1; const int count = getBits(uc, bitsCount) + len + 1;
uc->datasize -= count; for (int i = 0; i < count; ++i) {
while (count--) {
*uc->dst = (uint8_t)getBits(uc, 8); *uc->dst = (uint8_t)getBits(uc, 8);
--uc->dst; --uc->dst;
} }
uc->datasize -= count;
} }
static void unpackHelper2(UnpackCtx *uc, uint8_t num_bits) { static void copyReference(UnpackCtx *uc, int bitsCount, int count) {
uint16_t i = getBits(uc, num_bits); const uint16_t offset = getBits(uc, bitsCount);
uint16_t count = uc->size + 1; for (int i = 0; i < count; ++i) {
uc->datasize -= count; *uc->dst = *(uc->dst + offset);
while (count--) {
*uc->dst = *(uc->dst + i);
--uc->dst; --uc->dst;
} }
uc->datasize -= count;
} }
bool delphine_unpack(uint8_t *dst, const uint8_t *src, int len) { 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.src = src + len - 4;
uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4; uc.datasize = READ_BE_UINT32(uc.src); uc.src -= 4;
uc.dst = dst + uc.datasize - 1; uc.dst = dst + uc.datasize - 1;
uc.size = 0;
uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4; uc.crc = READ_BE_UINT32(uc.src); uc.src -= 4;
uc.bits = READ_BE_UINT32(uc.src); uc.src -= 4; uc.bits = READ_BE_UINT32(uc.src); uc.src -= 4;
uc.crc ^= uc.bits; uc.crc ^= uc.bits;
do { do {
if (!nextBit(&uc)) { if (!nextBit(&uc)) {
uc.size = 1;
if (!nextBit(&uc)) { if (!nextBit(&uc)) {
unpackHelper1(&uc, 3, 0); copyLiteral(&uc, 3, 0);
} else { } else {
unpackHelper2(&uc, 8); copyReference(&uc, 8, 2);
} }
} else { } else {
uint16_t c = getBits(&uc, 2); const int code = getBits(&uc, 2);
if (c == 3) { switch (code) {
unpackHelper1(&uc, 8, 8); case 3:
} else if (c < 2) { copyLiteral(&uc, 8, 8);
uc.size = c + 2; break;
unpackHelper2(&uc, c + 9); case 2:
} else { copyReference(&uc, 12, getBits(&uc, 8) + 1);
uc.size = getBits(&uc, 8); break;
unpackHelper2(&uc, 12); case 1:
copyReference(&uc, 10, 4);
break;
case 0:
copyReference(&uc, 9, 3);
break;
} }
} }
} while (uc.datasize > 0); } while (uc.datasize > 0);

View File

@ -259,18 +259,23 @@ void Video::PC_setLevelPalettes() {
if (_unkPalSlot1 == 0) { if (_unkPalSlot1 == 0) {
_unkPalSlot1 = _mapPalSlot3; _unkPalSlot1 = _mapPalSlot3;
} }
// background
setPaletteSlotBE(0x0, _mapPalSlot1); setPaletteSlotBE(0x0, _mapPalSlot1);
// objects
setPaletteSlotBE(0x1, _mapPalSlot2); setPaletteSlotBE(0x1, _mapPalSlot2);
setPaletteSlotBE(0x2, _mapPalSlot3); setPaletteSlotBE(0x2, _mapPalSlot3);
setPaletteSlotBE(0x3, _mapPalSlot4); setPaletteSlotBE(0x3, _mapPalSlot4);
// conrad
if (_unkPalSlot1 == _mapPalSlot3) { if (_unkPalSlot1 == _mapPalSlot3) {
setPaletteSlotLE(4, _conradPal1); setPaletteSlotLE(4, _conradPal1);
} else { } else {
setPaletteSlotLE(4, _conradPal2); setPaletteSlotLE(4, _conradPal2);
} }
// slot 5 is monster palette // slot 5 is monster palette
// foreground
setPaletteSlotBE(0x8, _mapPalSlot1); setPaletteSlotBE(0x8, _mapPalSlot1);
setPaletteSlotBE(0x9, _mapPalSlot2); setPaletteSlotBE(0x9, _mapPalSlot2);
// inventory
setPaletteSlotBE(0xA, _unkPalSlot2); setPaletteSlotBE(0xA, _unkPalSlot2);
setPaletteSlotBE(0xB, _mapPalSlot4); setPaletteSlotBE(0xB, _mapPalSlot4);
// slots 0xC and 0xD are cutscene palettes // 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; int count = READ_BE_UINT16(src) - 1; src += 2;
do { do {
int d2 = READ_BE_UINT16(src); src += 2; int d2 = READ_BE_UINT16(src); src += 2;
int d0 = READ_BE_UINT16(src); src += 2; const int d0 = (int16_t)READ_BE_UINT16(src); src += 2;
int d1 = READ_BE_UINT16(src); src += 2; const int d1 = (int16_t)READ_BE_UINT16(src); src += 2;
if (d2 != 0xFFFF) { if (d2 != 0xFFFF) {
d2 &= ~(1 << 15); d2 &= ~(1 << 15);
const int32_t offset = READ_BE_UINT32(data + d2 * 4); 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 h = buf[1] + 1;
const int planarSize = READ_BE_UINT16(buf + 2); const int planarSize = READ_BE_UINT16(buf + 2);
if (isAmiga) { 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 { } 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); } while (--count >= 0);
} }
@ -662,7 +667,10 @@ void Video::AMIGA_decodeLev(int level, int room) {
_mapPalSlot3 = READ_BE_UINT16(tmp + 6); _mapPalSlot3 = READ_BE_UINT16(tmp + 6);
_mapPalSlot4 = READ_BE_UINT16(tmp + 8); _mapPalSlot4 = READ_BE_UINT16(tmp + 8);
if (_res->isDOS()) { if (_res->isDOS()) {
// done in ::PC_setLevelPalettes PC_setLevelPalettes();
if (level == 0) { // tiles with color slot 0x9
setPaletteSlotBE(0x9, _mapPalSlot1);
}
return; return;
} }
// background // background