- Fixed the IMD playing within mults, the non-interactive Gob3 demo should work better now

- Replaced strcpy with strncpy where appropriate
- Added detection entries for other languages of the multilingual Gob3 CD; bug #1691230

svn-id: r26327
This commit is contained in:
Sven Hesse 2007-03-30 17:52:31 +00:00
parent 33c6a6f460
commit d65e05841a
19 changed files with 136 additions and 62 deletions

View File

@ -53,7 +53,7 @@ void CDROM::readLIC(const char *fname) {
*_curTrack = 0;
strcpy(tmp, fname);
strncpy0(tmp, fname, 79);
handle = _vm->_dataIO->openData(tmp);
@ -171,7 +171,7 @@ void CDROM::startTrack(const char *trackname) {
return;
}
strcpy(_curTrack, trackname);
strncpy0(_curTrack, trackname, 15);
stopPlaying();

View File

@ -277,9 +277,11 @@ void DataIO::openDataFile(const char *src, bool itk) {
char path[128];
int16 file;
strcpy(path, src);
if (!strchr(path, '.'))
strncpy0(path, src, 127);
if (!strchr(path, '.')) {
path[123] = 0;
strcat(path, ".stk");
}
for (file = 0; file < MAX_DATA_FILES; file++)
if (_dataFiles[file] == 0)
@ -441,7 +443,8 @@ int32 DataIO::getDataSize(const char *name) {
int32 chunkSz;
Common::File file;
strcpy(buf, name);
strncpy0(buf, name, 127);
chunkSz = getChunkSize(buf);
if (chunkSz >= 0)
return chunkSz;

View File

@ -798,7 +798,19 @@ static const GOBGameDescription gameDescriptions[] = {
GF_GOB2,
"intro"
},
{ // Supplied by paul66 in bug report #1652352
{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230
{
"gob3cd",
"v1.02",
AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"),
EN_ANY,
kPlatformPC,
Common::ADGF_NO_FLAGS
},
GF_GOB2,
"intro"
},
{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230
{
"gob3cd",
"v1.02",
@ -810,6 +822,42 @@ static const GOBGameDescription gameDescriptions[] = {
GF_GOB2,
"intro"
},
{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230
{
"gob3cd",
"v1.02",
AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"),
FR_FRA,
kPlatformPC,
Common::ADGF_NO_FLAGS
},
GF_GOB2,
"intro"
},
{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230
{
"gob3cd",
"v1.02",
AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"),
IT_ITA,
kPlatformPC,
Common::ADGF_NO_FLAGS
},
GF_GOB2,
"intro"
},
{ // Supplied by paul66 and noizert in bug reports #1652352 and #1691230
{
"gob3cd",
"v1.02",
AD_ENTRY1("intro.stk", "c3e9132ea9dc0fb866b6d60dcda10261"),
ES_ESP,
kPlatformPC,
Common::ADGF_NO_FLAGS
},
GF_GOB2,
"intro"
},
{
{
"gob3",
@ -946,6 +994,18 @@ static const GOBGameDescription fallbackDescs[] = {
GF_BARGON,
"intro"
},
{
{
"gob3cd",
"unknown",
AD_ENTRY1(0, 0),
UNK_LANG,
kPlatformPC,
Common::ADGF_NO_FLAGS
},
GF_GOB2 | GF_CD,
"intro"
},
};
static const ADFileBasedFallback fileBased[] = {
@ -955,6 +1015,7 @@ static const ADFileBasedFallback fileBased[] = {
{ &fallbackDescs[2], { "intro.stk", "disk2.stk", "disk3.stk", 0 } },
{ &fallbackDescs[3], { "intro.stk", "gobnew.lic", 0 } },
{ &fallbackDescs[4], { "intro.stk", "scaa.imd", "scba.imd", "scbf.imd", 0 } },
{ &fallbackDescs[5], { "intro.stk", "mus_gob3.lic", 0 } },
{ 0, { 0 } }
};

View File

@ -267,7 +267,7 @@ void Draw_v1::printTotText(int16 id) {
} else if (cmd == 1) {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
strcpy(buf, GET_VARO_STR(val));
strncpy0(buf, GET_VARO_STR(val), 19);
} else {
val = READ_LE_UINT16(ptrEnd + 18) * 4;

View File

@ -482,7 +482,7 @@ void Draw_v2::printTotText(int16 id) {
sprintf(buf, "%d", VAR_OFFSET(val));
} else if (cmd == 1) {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
strcpy(buf, GET_VARO_STR(val));
strncpy0(buf, GET_VARO_STR(val), 19);
} else {
val = READ_LE_UINT16(ptrEnd + 18) * 4;
sprintf(buf, "%d", VAR_OFFSET(val));

View File

@ -292,7 +292,7 @@ int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
_vm->_util->processInput();
if (_vm->_mult->_multData && (_vm->_global->_inter_variables != 0) &&
if (_vm->_mult->_multData && _vm->_global->_inter_variables &&
(VAR(58) != 0)) {
if (_vm->_mult->_multData->frameStart != (int) VAR(58) - 1)
_vm->_mult->_multData->frameStart++;
@ -309,9 +309,6 @@ int16 Game::checkKeys(int16 *pMouseX, int16 *pMouseY,
_vm->_inter->_soundEndTimeKey = 0;
}
if (_vm->_global->_useMouse == 0)
error("checkKeys: Can't work without mouse!");
_vm->_util->getMouseState(pMouseX, pMouseY, pButtons);
if (*pButtons == 3)
@ -436,7 +433,7 @@ void Game::totSub(int8 flags, char *newTotFile) {
_vm->_global->_inter_variablesSizes = 0;
}
strcpy(_curTotFile, newTotFile);
strncpy0(_curTotFile, newTotFile, 9);
strcat(_curTotFile, ".TOT");
if (_vm->_inter->_terminate != 0)

View File

@ -1025,7 +1025,7 @@ void Game_v1::collisionsBlock(void) {
if ((_collisionAreas[i].flags & 0x0F) > 8) {
char *ptr;
strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key));
strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
while ((ptr = strchr(_tempStr, ' ')) != 0) {
_vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
ptr = strchr(_tempStr, ' ');
@ -1037,14 +1037,14 @@ void Game_v1::collisionsBlock(void) {
((_collisionAreas[i].flags & 0x0F) <= 8)) {
str = descArray[var_24].ptr;
strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key));
strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
if ((_collisionAreas[i].flags & 0x0F) < 7)
_vm->_util->prepareStr(_tempStr);
int16 pos = 0;
do {
strcpy(_collStr, str);
strncpy0(_collStr, str, 255);
pos += strlen(str) + 1;
str += strlen(str) + 1;
@ -1115,7 +1115,7 @@ int16 Game_v1::multiEdit(int16 time, int16 index, int16 *pCurPos,
if ((collArea->flags & 0x0F) > 10)
continue;
strcpy(_tempStr, GET_VARO_STR(collArea->key));
strncpy0(_tempStr, GET_VARO_STR(collArea->key), 255);
_vm->_draw->_destSpriteX = collArea->left;
_vm->_draw->_destSpriteY = collArea->top;
@ -1278,10 +1278,10 @@ int16 Game_v1::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
editSize = width / pFont->itemWidth;
while (1) {
strcpy(_tempStr, str);
strncpy0(_tempStr, str, 254);
strcat(_tempStr, " ");
if (strlen(_tempStr) > editSize)
strcpy(_tempStr, str);
strncpy0(_tempStr, str, 255);
_vm->_draw->_destSpriteX = xPos;
_vm->_draw->_destSpriteY = yPos;

View File

@ -1052,7 +1052,7 @@ void Game_v2::collisionsBlock(void) {
if ((_collisionAreas[i].flags & 0x0F) > 8) {
char *ptr;
strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key));
strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
while ((ptr = strchr(_tempStr, ' ')))
_vm->_util->cutFromStr(_tempStr, (ptr - _tempStr), 1);
if (_vm->_language == 2)
@ -1065,14 +1065,14 @@ void Game_v2::collisionsBlock(void) {
((_collisionAreas[i].flags & 0x0F) <= 8)) {
str = descArray[var_24].ptr;
strcpy(_tempStr, GET_VARO_STR(_collisionAreas[i].key));
strncpy0(_tempStr, GET_VARO_STR(_collisionAreas[i].key), 255);
if ((_collisionAreas[i].flags & 0x0F) < 7)
_vm->_util->prepareStr(_tempStr);
int16 pos = 0;
do {
strcpy(_collStr, str);
strncpy0(_collStr, str, 255);
pos += strlen(str) + 1;
str += strlen(str) + 1;
@ -1155,7 +1155,7 @@ int16 Game_v2::multiEdit(int16 time, int16 index, int16 *pCurPos,
if ((collArea->flags & 0x0F) > 10)
continue;
strcpy(_tempStr, GET_VARO_STR(collArea->key));
strncpy0(_tempStr, GET_VARO_STR(collArea->key), 255);
_vm->_draw->_destSpriteX = collArea->left;
_vm->_draw->_destSpriteY = collArea->top;
@ -1355,10 +1355,10 @@ int16 Game_v2::inputArea(int16 xPos, int16 yPos, int16 width, int16 height,
editSize = width / pFont->itemWidth;
while (1) {
strcpy(_tempStr, str);
strncpy0(_tempStr, str, 254);
strcat(_tempStr, " ");
if (strlen(_tempStr) > editSize)
strcpy(_tempStr, str);
strncpy0(_tempStr, str, 255);
fontExtraBak = _vm->_draw->_fonts[fontIndex]->extraData;
needAdjust = _vm->_draw->_needAdjust;

View File

@ -103,6 +103,12 @@ enum SaveFiles {
SAVE_BLO // Notes
};
inline char *strncpy0(char *dest, const char *src, size_t n) {
strncpy(dest, src, n);
dest[n] = 0;
return dest;
}
// A "smart" reference counting templated class
template<typename T>
class ReferenceCounter {

View File

@ -1221,7 +1221,7 @@ void Goblin::loadObjects(char *source) {
freeObjects();
initList();
strcpy(_vm->_map->_sourceFile, source);
strncpy0(_vm->_map->_sourceFile, source, 14);
_vm->_map->_sourceFile[strlen(_vm->_map->_sourceFile) - 4] = 0;
_vm->_map->loadMapObjects(source);

View File

@ -92,8 +92,11 @@ ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc,
uint32 framesPosPos = 0;
uint32 framesCordsPos = 0;
strcpy(buf, path);
strcat(buf, ".IMD");
strncpy0(buf, path, 17);
if (!strchr(buf, '.')) {
buf[13] = 0;
strcat(buf, ".IMD");
}
handle = _vm->_dataIO->openData(buf);
@ -196,7 +199,6 @@ ImdPlayer::Imd *ImdPlayer::loadImdFile(const char *path, SurfaceDesc *surfDesc,
assert(_soundBuffer);
memset(_soundBuffer, 0, _soundSliceSize * _soundSlicesCount);
_vm->_snd->stopSound(0);
_soundDesc.set(SOUND_SND, SOUND_TOT, _soundBuffer,
_soundSliceSize * _soundSlicesCount);
@ -279,7 +281,7 @@ int8 ImdPlayer::openImd(const char *path, int16 x, int16 y,
_curX = _curImd->x;
_curY = _curImd->y;
strcpy(_curFile, src);
strncpy0(_curFile, src, 17);
delete[] _frameData;
_frameData = new byte[_curImd->frameDataSize + 500];
@ -852,7 +854,7 @@ inline void ImdPlayer::drawFrame(int16 frame) {
}
inline void ImdPlayer::copyPalette(int16 palStart, int16 palEnd) {
if (palStart == -1)
if ((palStart == -1) || (palEnd == -1))
memcpy((char *) _vm->_global->_pPaletteDesc->vgaPal,
(char *) _curImd->palette, 768);
else

View File

@ -92,7 +92,7 @@ public:
int16 frames, bool fade, bool interruptible);
protected:
char _curFile[15];
char _curFile[18];
int16 _curX;
int16 _curY;

View File

@ -136,10 +136,10 @@ void Init::initGame(char *totName) {
}
if (totName) {
strcpy(buffer, totName);
strncpy0(buffer, totName, 15);
strcat(buffer, ".tot");
} else
strcpy(buffer, _vm->_startTot);
strncpy0(buffer, _vm->_startTot, 19);
handle = _vm->_dataIO->openData(buffer);
@ -152,7 +152,6 @@ void Init::initGame(char *totName) {
_vm->_global->_inter_variables = new char[varsCount * 4];
_vm->_global->_inter_variablesSizes = new byte[varsCount * 4];
_vm->_global->clearVars(varsCount);
WRITE_VAR(58, 1);
strcpy(_vm->_game->_curTotFile, buffer);

View File

@ -1432,7 +1432,7 @@ bool Inter_v1::o1_loadTot(OpFuncParams &params) {
if ((*_vm->_global->_inter_execPtr & 0x80) != 0) {
_vm->_global->_inter_execPtr++;
evalExpr(0);
strcpy(buf, _vm->_global->_inter_resStr);
strncpy0(buf, _vm->_global->_inter_resStr, 15);
} else {
size = *_vm->_global->_inter_execPtr++;
for (int i = 0; i < size; i++)
@ -1948,7 +1948,7 @@ bool Inter_v1::o1_strToLong(OpFuncParams &params) {
int32 res;
strVar = _vm->_parse->parseVarIndex();
strcpy(str, GET_VARO_STR(strVar));
strncpy0(str, GET_VARO_STR(strVar), 19);
res = atol(str);
destVar = _vm->_parse->parseVarIndex();

View File

@ -1074,7 +1074,7 @@ void Inter_v2::o2_readLIC() {
char path[40];
evalExpr(0);
strcpy(path, _vm->_global->_inter_resStr);
strncpy0(path, _vm->_global->_inter_resStr, 35);
strcat(path, ".LIC");
_vm->_cdrom->readLIC(path);
@ -1460,7 +1460,7 @@ void Inter_v2::o2_playImd() {
evalExpr(0);
_vm->_global->_inter_resStr[8] = 0;
strcpy(imd, _vm->_global->_inter_resStr);
strncpy0(imd, _vm->_global->_inter_resStr, 127);
x = _vm->_parse->parseValExpr();
y = _vm->_parse->parseValExpr();
@ -1542,7 +1542,7 @@ void Inter_v2::o2_openItk() {
char fileName[32];
evalExpr(0);
strcpy(fileName, _vm->_global->_inter_resStr);
strncpy0(fileName, _vm->_global->_inter_resStr, 27);
strcat(fileName, ".ITK");
_vm->_dataIO->openDataFile(fileName, true);
@ -1920,7 +1920,7 @@ void Inter_v2::o2_loadInfogramesIns(OpGobParams &params) {
if (_vm->_noMusic)
return;
strcpy(fileName, GET_VAR_STR(varName));
strncpy0(fileName, GET_VAR_STR(varName), 15);
strcat(fileName, ".INS");
debugC(1, kDebugMusic, "Loading Infogrames instrument file \"%s\"",
fileName);
@ -1950,7 +1950,7 @@ void Inter_v2::o2_playInfogrames(OpGobParams &params) {
if (_vm->_noMusic)
return;
strcpy(fileName, GET_VAR_STR(varName));
strncpy0(fileName, GET_VAR_STR(varName), 15);
strcat(fileName, ".DUM");
debugC(1, kDebugMusic, "Playing Infogrames music file \"%s\"", fileName);
@ -2026,7 +2026,7 @@ int16 Inter_v2::loadSound(int16 search) {
source = SOUND_FILE;
strcpy(sndfile, _vm->_global->_inter_execPtr);
strncpy0(sndfile, _vm->_global->_inter_execPtr, 9);
_vm->_global->_inter_execPtr += 9;
if (type == SOUND_ADL)

View File

@ -141,13 +141,14 @@ void Map_v1::loadMapObjects(char *avjFile) {
void Map_v1::loadSounds(Common::SeekableReadStream &data) {
int16 count;
int16 handle;
char buf[128];
char buf[19];
char sndNames[20][14];
count = data.readUint16LE();
for (int i = 0; i < count; i++) {
data.read(buf, 14);
buf[14] = 0;
strcat(buf, ".SND");
strcpy(sndNames[i], buf);
}

View File

@ -156,7 +156,7 @@ public:
int16 field_4;
int16 field_6;
uint16 flags;
int16 field_A;
int16 palFrame;
int16 lastFrame;
int8 palStart;
int8 palEnd;

View File

@ -268,7 +268,7 @@ void Mult_v2::loadImds(Common::SeekableReadStream &data) {
_multData->imdKeys[i][j].field_4 = data.readSint16LE();
_multData->imdKeys[i][j].field_6 = data.readSint16LE();
_multData->imdKeys[i][j].flags = data.readUint16LE();
_multData->imdKeys[i][j].field_A = data.readSint16LE();
_multData->imdKeys[i][j].palFrame = data.readSint16LE();
_multData->imdKeys[i][j].lastFrame = data.readSint16LE();
_multData->imdKeys[i][j].palStart = data.readSByte();
_multData->imdKeys[i][j].palEnd = data.readSByte();
@ -462,8 +462,10 @@ void Mult_v2::multSub(uint16 multindex) {
for (int i = 0; i < 4; i++) {
_multData->imdKeysIndices[index][i] = 0;
for (int j = 0; j < _multData->imdKeysCount[i]; j++)
if (_multData->imdKeys[i][j].frame >= firstFrame)
if (_multData->imdKeys[i][j].frame >= firstFrame) {
_multData->imdKeysIndices[index][i] = j;
break;
}
}
_multData->animKeysStartFrames[index] = startFrame;
@ -998,12 +1000,9 @@ void Mult_v2::animate() {
void Mult_v2::playImd(char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
int16 startFrame) {
int16 x, y;
int16 repeat = 0;
int16 palStart, palEnd;
int16 lastFrame;
int16 baseFrame, palFrame, lastFrame;
uint16 flags;
int16 di;
int16 var_6;
if (_vm->_draw->_renderFlags & 0x100) {
x = VAR(55);
@ -1022,26 +1021,27 @@ void Mult_v2::playImd(char *imdFile, Mult::Mult_ImdKey &key, int16 dir,
palStart = key.palStart;
palEnd = key.palEnd;
di = key.field_A;
palFrame = key.palFrame;
lastFrame = key.lastFrame;
if ((di == -1) && (lastFrame == -1))
if (startFrame > 0)
if ((palFrame != -1) && (lastFrame != -1))
if ((lastFrame - palFrame) < startFrame)
if (!(key.flags & 0x4000)) {
_vm->_imdPlayer->closeImd();
return;
}
if (!_vm->_imdPlayer->openImd(imdFile, x, y, repeat, flags))
if (!_vm->_imdPlayer->openImd(imdFile, x, y, 0, flags))
return;
if (di == -1)
di = 0;
if (palFrame == -1)
palFrame = 0;
if (lastFrame == -1)
lastFrame = _vm->_imdPlayer->_curImd->framesCount - 1;
var_6 = startFrame % (lastFrame - di + 1);
_vm->_imdPlayer->play(var_6 + di, flags & 0x7F, palStart, palEnd, di, lastFrame);
baseFrame = startFrame % (lastFrame - palFrame + 1);
_vm->_imdPlayer->play(baseFrame + palFrame, flags & 0x7F,
palStart, palEnd, palFrame, lastFrame);
}
void Mult_v2::advanceObjects(int16 index) {
@ -1136,12 +1136,13 @@ void Mult_v2::advanceObjects(int16 index) {
int dir;
int startFrame;
fileN = -_multData->imdKeys[i][_multData->imdIndices[i]].imdFile - 2;
Mult_ImdKey &key = _multData->imdKeys[i][_multData->imdIndices[i]];
fileN = -key.imdFile - 2;
if (fileN < 0)
return;
Mult_ImdKey &key = _multData->imdKeys[i][_multData->imdIndices[i]];
imdFile = _multData->imdFiles + fileN * 14;
dir = _multData->animDirection;
startFrame = frame - key.frame;
if ((dir != 1) && (--startFrame > 0))

View File

@ -313,6 +313,10 @@ void Snd::setSample(SoundDesc &sndDesc, int16 repCount, int16 frequency,
_data = (int8 *) sndDesc.getData();
_length = sndDesc.size();
_freq = frequency;
if ((frequency % 100) == 0)
_freq--;
_ratio = ((double) _freq) / _rate;
_offset = 0.0;
_frac = 0;