aboutsummaryrefslogtreecommitdiff
path: root/engines
diff options
context:
space:
mode:
Diffstat (limited to 'engines')
-rw-r--r--engines/gob/dataio.cpp5
-rw-r--r--engines/gob/draw.cpp60
-rw-r--r--engines/gob/draw.h9
-rw-r--r--engines/gob/draw_v1.cpp37
-rw-r--r--engines/gob/draw_v2.cpp47
-rw-r--r--engines/gob/driver_vga.cpp16
-rw-r--r--engines/gob/driver_vga.h2
-rw-r--r--engines/gob/gob.cpp2
-rw-r--r--engines/gob/hotspots.cpp37
-rw-r--r--engines/gob/hotspots.h3
-rw-r--r--engines/gob/init.cpp7
-rw-r--r--engines/gob/inter_v1.cpp5
-rw-r--r--engines/gob/inter_v5.cpp30
-rw-r--r--engines/gob/util.cpp32
-rw-r--r--engines/gob/util.h6
-rw-r--r--engines/gob/video.cpp112
-rw-r--r--engines/gob/video.h51
-rw-r--r--engines/kyra/lol.cpp13
-rw-r--r--engines/parallaction/sound.h2
-rw-r--r--engines/sci/debug.h2
-rw-r--r--engines/sci/detection.cpp8
-rw-r--r--engines/sci/engine/state.h2
-rw-r--r--engines/sci/resource.cpp62
23 files changed, 307 insertions, 243 deletions
diff --git a/engines/gob/dataio.cpp b/engines/gob/dataio.cpp
index f59fa80e8d..99cf7c1193 100644
--- a/engines/gob/dataio.cpp
+++ b/engines/gob/dataio.cpp
@@ -488,6 +488,9 @@ int16 DataIO::openData(const char *path) {
}
bool DataIO::existData(const char *path) {
+ if (!path || (path[0] == '\0'))
+ return false;
+
int16 handle = openData(path);
if (handle < 0)
@@ -584,7 +587,7 @@ byte *DataIO::getData(const char *path) {
}
DataStream *DataIO::getDataStream(const char *path) {
- if (!path || (path[0] == '\0') || !existData(path))
+ if (!existData(path))
return 0;
uint32 size = getDataSize(path);
diff --git a/engines/gob/draw.cpp b/engines/gob/draw.cpp
index c20bece7b4..fb3cb9bbcd 100644
--- a/engines/gob/draw.cpp
+++ b/engines/gob/draw.cpp
@@ -29,6 +29,7 @@
#include "gob/draw.h"
#include "gob/global.h"
#include "gob/util.h"
+#include "gob/dataio.h"
#include "gob/game.h"
#include "gob/script.h"
#include "gob/inter.h"
@@ -60,7 +61,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) {
_backDeltaX = 0;
_backDeltaY = 0;
- for (int i = 0; i < 8; i++)
+ for (int i = 0; i < kFontCount; i++)
_fonts[i] = 0;
_spritesArray.resize(SPRITES_COUNT);
@@ -128,7 +129,7 @@ Draw::Draw(GobEngine *vm) : _vm(vm) {
}
Draw::~Draw() {
- for (int i = 0; i < 8; i++)
+ for (int i = 0; i < kFontCount; i++)
delete _fonts[i];
}
@@ -346,6 +347,8 @@ int Draw::stringLength(const char *str, int16 fontIndex) {
if ((fontIndex < 0) || (fontIndex > 7) || !_fonts[fontIndex])
return 0;
+ Font &font = *_fonts[fontIndex];
+
int len = 0;
if (_vm->_global->_language == 10) {
@@ -355,16 +358,16 @@ int Draw::stringLength(const char *str, int16 fontIndex) {
len += japaneseExtraCharLen[4];
i++;
} else
- len += _fonts[fontIndex]->itemWidth;
+ len += font.getCharWidth();
}
} else {
- if (_fonts[fontIndex]->charWidths)
- while (*str != 0)
- len += *(_fonts[fontIndex]->charWidths + (*str++ - _fonts[fontIndex]->startItem));
+ if (!font.isMonospaced())
+ while (*str != '\0')
+ len += font.getCharWidth(*str++);
else
- len = (strlen(str) * _fonts[fontIndex]->itemWidth);
+ len = strlen(str) * font.getCharWidth();
}
@@ -372,14 +375,11 @@ int Draw::stringLength(const char *str, int16 fontIndex) {
}
void Draw::drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2,
- int16 transp, SurfaceDesc &dest, Video::FontDesc *font) {
+ int16 transp, SurfaceDesc &dest, const Font &font) {
while (*str != '\0') {
_vm->_video->drawLetter(*str, x, y, font, transp, color1, color2, dest);
- if (!font->charWidths)
- x += font->itemWidth;
- else
- x += *(font->charWidths + (*str - font->startItem));
+ x += font.getCharWidth(*str);
str++;
}
}
@@ -407,23 +407,23 @@ void Draw::printTextCentered(int16 id, int16 left, int16 top, int16 right,
if (str[0] == '\0')
return;
- int16 width = 0;
-
_transparency = 1;
_destSpriteX = left;
_destSpriteY = top;
_fontIndex = fontIndex;
_frontColor = color;
_textToPrint = str;
- if (_fonts[fontIndex]->charWidths != 0) {
- uint8 *widths = _fonts[fontIndex]->charWidths;
- int length = strlen(str);
- for (int i = 0; i < length; i++)
- width += *(widths + (str[i] - _fonts[_fontIndex]->startItem));
+ Font &font = *_fonts[fontIndex];
+
+ int16 width = 0;
+ if (!font.isMonospaced()) {
+ const char *s = str;
+ while (*s != '\0')
+ width += font.getCharWidth(*s++);
}
else
- width = strlen(str) * _fonts[fontIndex]->itemWidth;
+ width = strlen(str) * font.getCharWidth();
adjustCoords(1, &width, 0);
_destSpriteX += (right - left + 1 - width) / 2;
@@ -546,4 +546,24 @@ void Draw::wobble(SurfaceDesc &surfDesc) {
delete[] offsets;
}
+Font *Draw::loadFont(const char *path) const {
+ if (!_vm->_dataIO->existData(path))
+ return 0;
+
+ byte *data = _vm->_dataIO->getData(path);
+
+ return new Font(data);
+}
+
+bool Draw::loadFont(int fontIndex, const char *path) {
+ if ((fontIndex < 0) || (fontIndex >= kFontCount))
+ return false;
+
+ delete _fonts[fontIndex];
+
+ _fonts[fontIndex] = loadFont(path);
+
+ return _fonts[fontIndex] != 0;
+}
+
} // End of namespace Gob
diff --git a/engines/gob/draw.h b/engines/gob/draw.h
index 26f78ce3b3..ba32df0c3e 100644
--- a/engines/gob/draw.h
+++ b/engines/gob/draw.h
@@ -45,6 +45,8 @@ namespace Gob {
class Draw {
public:
+ static const int kFontCount = 8;
+
struct FontToSprite {
int8 sprite;
int8 base;
@@ -76,7 +78,7 @@ public:
int16 _backDeltaY;
FontToSprite _fontToSprite[4];
- Video::FontDesc *_fonts[8];
+ Font *_fonts[kFontCount];
Common::Array<SurfaceDescPtr> _spritesArray;
@@ -152,7 +154,7 @@ public:
}
int stringLength(const char *str, int16 fontIndex);
void drawString(const char *str, int16 x, int16 y, int16 color1, int16 color2,
- int16 transp, SurfaceDesc &dest, Video::FontDesc *font);
+ int16 transp, SurfaceDesc &dest, const Font &font);
void printTextCentered(int16 id, int16 left, int16 top, int16 right,
int16 bottom, const char *str, int16 fontIndex, int16 color);
int32 getSpriteRectSize(int16 index);
@@ -161,6 +163,9 @@ public:
static const int16 _wobbleTable[360];
void wobble(SurfaceDesc &surfDesc);
+ Font *loadFont(const char *path) const;
+ bool loadFont(int fontIndex, const char *path);
+
virtual void initScreen() = 0;
virtual void closeScreen() = 0;
virtual void blitCursor() = 0;
diff --git a/engines/gob/draw_v1.cpp b/engines/gob/draw_v1.cpp
index 91f2a45637..e2cfcb613d 100644
--- a/engines/gob/draw_v1.cpp
+++ b/engines/gob/draw_v1.cpp
@@ -248,7 +248,7 @@ void Draw_v1::printTotText(int16 id) {
_letterToPrint = (char) *ptr;
spriteOperation(DRAW_DRAWLETTER);
_destSpriteX +=
- _fonts[_fontIndex]->itemWidth;
+ _fonts[_fontIndex]->getCharWidth();
ptr++;
} else {
cmd = ptrEnd[17] & 0x7F;
@@ -281,7 +281,7 @@ void Draw_v1::printTotText(int16 id) {
spriteOperation(DRAW_PRINTTEXT);
if (ptrEnd[17] & 0x80) {
if (ptr[1] == ' ') {
- _destSpriteX += _fonts[_fontIndex]->itemWidth;
+ _destSpriteX += _fonts[_fontIndex]->getCharWidth();
while (ptr[1] == ' ')
ptr++;
if (ptr[1] == 2) {
@@ -290,10 +290,10 @@ void Draw_v1::printTotText(int16 id) {
}
} else if (ptr[1] == 2 && READ_LE_UINT16(ptr + 4) == _destSpriteY) {
ptr += 5;
- _destSpriteX += _fonts[_fontIndex]->itemWidth;
+ _destSpriteX += _fonts[_fontIndex]->getCharWidth();
}
} else {
- _destSpriteX = destSpriteX + _fonts[_fontIndex]->itemWidth;
+ _destSpriteX = destSpriteX + _fonts[_fontIndex]->getCharWidth();
}
ptrEnd += 23;
ptr++;
@@ -341,6 +341,7 @@ void Draw_v1::spriteOperation(int16 operation) {
}
}
+ Font *font = 0;
switch (operation) {
case DRAW_BLITSURF:
_vm->_video->drawSprite(*_spritesArray[_sourceSurface],
@@ -402,20 +403,25 @@ void Draw_v1::spriteOperation(int16 operation) {
break;
case DRAW_PRINTTEXT:
+ font = _fonts[_fontIndex];
+ if (!font) {
+ warning("Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex);
+ break;
+ }
+
len = strlen(_textToPrint);
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
- _destSpriteX + len * _fonts[_fontIndex]->itemWidth - 1,
- _destSpriteY + _fonts[_fontIndex]->itemHeight - 1);
+ _destSpriteX + len * font->getCharWidth() - 1,
+ _destSpriteY + font->getCharHeight() - 1);
for (int i = 0; i < len; i++) {
_vm->_video->drawLetter(_textToPrint[i],
_destSpriteX, _destSpriteY,
- _fonts[_fontIndex],
- _transparency,
+ *font, _transparency,
_frontColor, _backColor,
*_spritesArray[_destSurface]);
- _destSpriteX += _fonts[_fontIndex]->itemWidth;
+ _destSpriteX += font->getCharWidth();
}
break;
@@ -458,14 +464,19 @@ void Draw_v1::spriteOperation(int16 operation) {
break;
case DRAW_DRAWLETTER:
+ font = _fonts[_fontIndex];
+ if (!font) {
+ warning("Trying to print \'%c\' with undefined font %d", _letterToPrint, _fontIndex);
+ break;
+ }
+
if (_fontToSprite[_fontIndex].sprite == -1) {
dirtiedRect(_destSurface, _destSpriteX, _destSpriteY,
- _destSpriteX + _fonts[_fontIndex]->itemWidth - 1,
- _destSpriteY + _fonts[_fontIndex]->itemHeight - 1);
+ _destSpriteX + font->getCharWidth() - 1,
+ _destSpriteY + font->getCharHeight() - 1);
_vm->_video->drawLetter(_letterToPrint,
_destSpriteX, _destSpriteY,
- _fonts[_fontIndex],
- _transparency,
+ *font, _transparency,
_frontColor, _backColor,
*_spritesArray[_destSurface]);
break;
diff --git a/engines/gob/draw_v2.cpp b/engines/gob/draw_v2.cpp
index a0be23516c..8fe70589a7 100644
--- a/engines/gob/draw_v2.cpp
+++ b/engines/gob/draw_v2.cpp
@@ -371,14 +371,14 @@ void Draw_v2::printTotText(int16 id) {
if ((((*ptr >= 1) && (*ptr <= 7)) || (*ptr == 10)) && (strPos != 0)) {
str[MAX(strPos, strPos2)] = 0;
strPosBak = strPos;
- width = strlen(str) * _fonts[fontIndex]->itemWidth;
+ width = strlen(str) * _fonts[fontIndex]->getCharWidth();
adjustCoords(1, &width, 0);
if (colCmd & 0x0F) {
rectLeft = offX - 2;
rectTop = offY - 2;
rectRight = offX + width + 1;
- rectBottom = _fonts[fontIndex]->itemHeight;
+ rectBottom = _fonts[fontIndex]->getCharHeight();
adjustCoords(1, &rectBottom, 0);
rectBottom += offY + 1;
adjustCoords(0, &rectLeft, &rectTop);
@@ -404,9 +404,9 @@ void Draw_v2::printTotText(int16 id) {
if (_needAdjust != 2) {
if ((_destSpriteX >= destX) && (_destSpriteY >= destY) &&
- (((_fonts[_fontIndex]->itemHeight / 2) + _destSpriteY - 1) <= spriteBottom)) {
+ (((_fonts[_fontIndex]->getCharHeight() / 2) + _destSpriteY - 1) <= spriteBottom)) {
while (((_destSpriteX + width - 1) > spriteRight) && (width > 0)) {
- width -= _fonts[_fontIndex]->itemWidth / 2;
+ width -= _fonts[_fontIndex]->getCharWidth() / 2;
str[strlen(str) - 1] = '\0';
}
spriteOperation(DRAW_PRINTTEXT);
@@ -419,8 +419,8 @@ void Draw_v2::printTotText(int16 id) {
if (mask[strPos] == '\0')
continue;
- rectLeft = _fonts[fontIndex]->itemWidth;
- rectTop = _fonts[fontIndex]->itemHeight;
+ rectLeft = _fonts[fontIndex]->getCharWidth();
+ rectTop = _fonts[fontIndex]->getCharHeight();
adjustCoords(1, &rectLeft, &rectTop);
_destSpriteX = strPos * rectLeft + offX;
_spriteRight = _destSpriteX + rectLeft - 1;
@@ -430,7 +430,7 @@ void Draw_v2::printTotText(int16 id) {
}
}
- rectLeft = _fonts[_fontIndex]->itemWidth;
+ rectLeft = _fonts[_fontIndex]->getCharWidth();
adjustCoords(1, &rectLeft, 0);
offX += strPosBak * rectLeft;
strPos = 0;
@@ -598,8 +598,6 @@ void Draw_v2::spriteOperation(int16 operation) {
int16 left;
int16 ratio;
Resource *resource;
- // Always assigned to -1 in Game::loadTotFile()
- int16 someHandle = -1;
deltaVeto = (operation & 0x10) != 0;
operation &= 0x0F;
@@ -761,8 +759,13 @@ void Draw_v2::spriteOperation(int16 operation) {
left = _destSpriteX;
if ((_fontIndex >= 4) || (_fontToSprite[_fontIndex].sprite == -1)) {
+ Font *font = _fonts[_fontIndex];
+ if (!font) {
+ warning("Trying to print \"%s\" with undefined font %d", _textToPrint, _fontIndex);
+ break;
+ }
- if (!_fonts[_fontIndex]->charWidths) {
+ if (font->isMonospaced()) {
if (((int8) _textToPrint[0]) == -1) {
_vm->validateLanguage();
@@ -770,26 +773,20 @@ void Draw_v2::spriteOperation(int16 operation) {
len = *dataBuf++;
for (int i = 0; i < len; i++, dataBuf += 2) {
_vm->_video->drawLetter(READ_LE_UINT16(dataBuf), _destSpriteX,
- _destSpriteY, _fonts[_fontIndex], _transparency, _frontColor,
+ _destSpriteY, *font, _transparency, _frontColor,
_backColor, *_spritesArray[_destSurface]);
}
} else {
drawString(_textToPrint, _destSpriteX, _destSpriteY, _frontColor,
- _backColor, _transparency, *_spritesArray[_destSurface],
- _fonts[_fontIndex]);
- _destSpriteX += len * _fonts[_fontIndex]->itemWidth;
+ _backColor, _transparency, *_spritesArray[_destSurface], *font);
+ _destSpriteX += len * font->getCharWidth();
}
} else {
for (int i = 0; i < len; i++) {
- if ((someHandle < 0) || (_textToPrint[i] != ' ')) {
- _vm->_video->drawLetter(_textToPrint[i], _destSpriteX,
- _destSpriteY, _fonts[_fontIndex], _transparency,
- _frontColor, _backColor, *_spritesArray[_destSurface]);
- _destSpriteX += *(_fonts[_fontIndex]->charWidths +
- (_textToPrint[i] - _fonts[_fontIndex]->startItem));
- }
- else
- _destSpriteX += _fonts[_fontIndex]->itemWidth;
+ _vm->_video->drawLetter(_textToPrint[i], _destSpriteX,
+ _destSpriteY, *font, _transparency,
+ _frontColor, _backColor, *_spritesArray[_destSurface]);
+ _destSpriteX += font->getCharWidth(_textToPrint[i]);
}
}
@@ -813,7 +810,7 @@ void Draw_v2::spriteOperation(int16 operation) {
}
dirtiedRect(_destSurface, left, _destSpriteY,
- _destSpriteX - 1, _destSpriteY + _fonts[_fontIndex]->itemHeight - 1);
+ _destSpriteX - 1, _destSpriteY + _fonts[_fontIndex]->getCharHeight() - 1);
break;
case DRAW_DRAWBAR:
@@ -884,7 +881,7 @@ void Draw_v2::spriteOperation(int16 operation) {
_sourceSurface = sourceSurface;
if (operation == DRAW_PRINTTEXT) {
- len = _fonts[_fontIndex]->itemWidth;
+ len = _fonts[_fontIndex]->getCharWidth();
adjustCoords(1, &len, 0);
_destSpriteX += len * strlen(_textToPrint);
}
diff --git a/engines/gob/driver_vga.cpp b/engines/gob/driver_vga.cpp
index aff971164f..c93962c206 100644
--- a/engines/gob/driver_vga.cpp
+++ b/engines/gob/driver_vga.cpp
@@ -70,24 +70,22 @@ void VGAVideoDriver::fillRect(SurfaceDesc &dest, int16 left, int16 top,
}
void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y,
- Video::FontDesc *fontDesc, byte color1, byte color2,
+ const Font &font, byte color1, byte color2,
byte transp, SurfaceDesc &dest) {
- byte *src, *dst;
uint16 data;
- src = fontDesc->dataPtr +
- (item - fontDesc->startItem) * (fontDesc->itemSize & 0xFF);
- dst = dest.getVidMem() + x + dest.getWidth() * y;
+ const byte *src = font.getCharData(item);
+ byte *dst = dest.getVidMem() + x + dest.getWidth() * y;
- int nWidth = fontDesc->itemWidth;
+ int nWidth = font.getCharWidth();
if (nWidth & 7)
nWidth = (nWidth & 0xF8) + 8;
nWidth >>= 3;
- for (int i = 0; i < fontDesc->itemHeight; i++) {
- int width = fontDesc->itemWidth;
+ for (int i = 0; i < font.getCharHeight(); i++) {
+ int width = font.getCharWidth();
for (int k = 0; k < nWidth; k++) {
@@ -106,7 +104,7 @@ void VGAVideoDriver::drawLetter(unsigned char item, int16 x, int16 y,
}
- dst += dest.getWidth() - fontDesc->itemWidth;
+ dst += dest.getWidth() - font.getCharWidth();
}
}
diff --git a/engines/gob/driver_vga.h b/engines/gob/driver_vga.h
index c50ea5c475..3102016cb5 100644
--- a/engines/gob/driver_vga.h
+++ b/engines/gob/driver_vga.h
@@ -41,7 +41,7 @@ public:
void fillRect(SurfaceDesc &dest, int16 left, int16 top,
int16 right, int16 bottom, byte color);
void drawLetter(unsigned char item, int16 x, int16 y,
- Video::FontDesc *fontDesc, byte color1, byte color2,
+ const Font &font, byte color1, byte color2,
byte transp, SurfaceDesc &dest);
void drawSprite(SurfaceDesc &source, SurfaceDesc &dest, int16 left,
int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp);
diff --git a/engines/gob/gob.cpp b/engines/gob/gob.cpp
index 94255b1277..fa4f04eab8 100644
--- a/engines/gob/gob.cpp
+++ b/engines/gob/gob.cpp
@@ -456,7 +456,7 @@ bool GobEngine::initGameParts() {
_init = new Init_v2(this);
_video = new Video_v2(this);
// _inter = new Inter_Playtoons(this);
- _inter = new Inter_v4(this);
+ _inter = new Inter_v6(this);
_mult = new Mult_v2(this);
_draw = new Draw_v2(this);
_map = new Map_v2(this);
diff --git a/engines/gob/hotspots.cpp b/engines/gob/hotspots.cpp
index fb8e29f528..b218634d4e 100644
--- a/engines/gob/hotspots.cpp
+++ b/engines/gob/hotspots.cpp
@@ -805,7 +805,7 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig
uint16 backColor, uint16 frontColor, char *str, uint16 fontIndex,
Type type, int16 &duration, uint16 &id, uint16 &index) {
- if ((fontIndex >= 8) || !_vm->_draw->_fonts[fontIndex]) {
+ if ((fontIndex >= Draw::kFontCount) || !_vm->_draw->_fonts[fontIndex]) {
warning("Hotspots::updateInput(): Invalid font specified: %d", fontIndex);
return 0;
}
@@ -816,16 +816,13 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig
((_vm->_global->_useMouse != 0) || (_vm->_game->_forceHandleMouse != 0)))
handleMouse = true;
- const Video::FontDesc &font = *_vm->_draw->_fonts[fontIndex];
-
- // The font doesn't specify individual character widths => monospaced
- bool monoSpaced = (font.charWidths == 0);
+ const Font &font = *_vm->_draw->_fonts[fontIndex];
// Current position in the string, preset to the end
uint32 pos = strlen(str);
/* Size of input field in characters.
* If the font is not monospaced, we can't know that */
- uint32 editSize = monoSpaced ? (width / font.itemWidth) : 0;
+ uint32 editSize = font.isMonospaced() ? (width / font.getCharWidth()) : 0;
uint16 key = 0;
char tempStr[256];
@@ -839,11 +836,11 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig
// Clear input area
fillRect(xPos, yPos,
- monoSpaced ? (editSize * font.itemWidth) : width, height,
+ font.isMonospaced() ? (editSize * font.getCharWidth()) : width, height,
backColor);
// Print the current string, vertically centered
- printText(xPos, yPos + (height - font.itemHeight) / 2,
+ printText(xPos, yPos + (height - font.getCharHeight()) / 2,
tempStr, fontIndex, frontColor);
// If we've reached the end of the input field, set the cursor to the last character
@@ -889,7 +886,7 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig
fillRect(cursorX, cursorY, cursorWidth, cursorHeight, backColor);
// Print the current string, vertically centered
- printText(cursorX, yPos + (height - font.itemHeight) / 2,
+ printText(cursorX, yPos + (height - font.getCharHeight()) / 2,
tempStr, fontIndex, frontColor);
if ((key != 0) || (id != 0))
@@ -1027,8 +1024,7 @@ uint16 Hotspots::updateInput(uint16 xPos, uint16 yPos, uint16 width, uint16 heig
if (editSize == 0) {
// Length of the string + current character + next one
int length = _vm->_draw->stringLength(str, fontIndex) +
- font.charWidths[' ' - font.startItem] +
- font.charWidths[key - font.startItem];
+ font.getCharWidth(' ') + font.getCharWidth(key);
if (length > width)
// We're above the limit, ignore the key
@@ -1220,7 +1216,7 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs,
int16 key = 0;
int16 flags = 0;
- Video::FontDesc *font = 0;
+ Font *font = 0;
uint32 funcEnter = 0, funcLeave = 0;
// Evaluate parameters for the new hotspot
@@ -1292,9 +1288,8 @@ void Hotspots::evaluateNew(uint16 i, uint16 *ids, InputDesc *inputs,
}
font = _vm->_draw->_fonts[inputs[inputCount].fontIndex];
- if (!font->charWidths)
- // Monospaced font
- right = left + width * font->itemWidth - 1;
+ if (font->isMonospaced())
+ right = left + width * font->getCharWidth() - 1;
funcEnter = 0;
funcPos = 0;
@@ -1890,11 +1885,11 @@ uint16 Hotspots::convertSpecialKey(uint16 key) const {
return key;
}
-void Hotspots::getTextCursorPos(const Video::FontDesc &font, const char *str,
+void Hotspots::getTextCursorPos(const Font &font, const char *str,
uint32 pos, uint16 x, uint16 y, uint16 width, uint16 height,
uint16 &cursorX, uint16 &cursorY, uint16 &cursorWidth, uint16 &cursorHeight) const {
- if (font.charWidths) {
+ if (!font.isMonospaced()) {
// Cursor to the right of the current character
cursorX = x;
@@ -1904,14 +1899,14 @@ void Hotspots::getTextCursorPos(const Video::FontDesc &font, const char *str,
// Iterate through the string and add each character's width
for (uint32 i = 0; i < pos; i++)
- cursorX += font.charWidths[str[i] - font.startItem];
+ cursorX += font.getCharWidth(str[i]);
} else {
// Cursor underlining the current character
- cursorX = x + font.itemWidth * pos;
+ cursorX = x + font.getCharWidth() * pos;
cursorY = y + height - 1;
- cursorWidth = font.itemWidth;
+ cursorWidth = font.getCharWidth();
cursorHeight = 1;
}
}
@@ -1969,7 +1964,7 @@ void Hotspots::updateAllTexts(const InputDesc *inputs) const {
fillRect(x, y, width, height, inputs[input].backColor);
// Center the text vertically
- y += (height - _vm->_draw->_fonts[_vm->_draw->_fontIndex]->itemHeight) / 2;
+ y += (height - _vm->_draw->_fonts[_vm->_draw->_fontIndex]->getCharHeight()) / 2;
// Draw it
printText(x, y, tempStr, inputs[input].fontIndex, inputs[input].frontColor);
diff --git a/engines/gob/hotspots.h b/engines/gob/hotspots.h
index c269cbb290..a389987c27 100644
--- a/engines/gob/hotspots.h
+++ b/engines/gob/hotspots.h
@@ -32,6 +32,7 @@
namespace Gob {
+class Font;
class Script;
class Hotspots {
@@ -253,7 +254,7 @@ private:
uint16 convertSpecialKey(uint16 key) const;
/** Calculate the graphical cursor position. */
- void getTextCursorPos(const Video::FontDesc &font, const char *str,
+ void getTextCursorPos(const Font &font, const char *str,
uint32 pos, uint16 x, uint16 y, uint16 width, uint16 height,
uint16 &cursorX, uint16 &cursorY, uint16 &cursorWidth, uint16 &cursorHeight) const;
diff --git a/engines/gob/init.cpp b/engines/gob/init.cpp
index f9a22f52fb..faf85a5b41 100644
--- a/engines/gob/init.cpp
+++ b/engines/gob/init.cpp
@@ -123,8 +123,7 @@ void Init::initGame() {
if (!_vm->_dataIO->existData("intro.inf")) {
for (int i = 0; i < 4; i++)
- if (_vm->_dataIO->existData(_fontNames[i]))
- _vm->_draw->_fonts[i] = _vm->_util->loadFont(_fontNames[i]);
+ _vm->_draw->loadFont(i, _fontNames[i]);
} else {
infBuf = _vm->_dataIO->getData("intro.inf");
@@ -140,8 +139,8 @@ void Init::initGame() {
buffer[j] = 0;
strcat(buffer, ".let");
- if (_vm->_dataIO->existData(buffer))
- _vm->_draw->_fonts[i] = _vm->_util->loadFont(buffer);
+
+ _vm->_draw->loadFont(i, buffer);
if ((infPtr + 1) >= infEnd)
break;
diff --git a/engines/gob/inter_v1.cpp b/engines/gob/inter_v1.cpp
index 7c5094d175..69c392b198 100644
--- a/engines/gob/inter_v1.cpp
+++ b/engines/gob/inter_v1.cpp
@@ -1712,12 +1712,9 @@ bool Inter_v1::o1_loadFont(OpFuncParams &params) {
_vm->_game->_script->evalExpr(0);
index = _vm->_game->_script->readInt16();
- delete _vm->_draw->_fonts[index];
-
_vm->_draw->animateCursor(4);
- _vm->_draw->_fonts[index] =
- _vm->_util->loadFont(_vm->_game->_script->getResultStr());
+ _vm->_draw->loadFont(index, _vm->_game->_script->getResultStr());
return false;
}
diff --git a/engines/gob/inter_v5.cpp b/engines/gob/inter_v5.cpp
index 1c20851c8d..986bad7cd3 100644
--- a/engines/gob/inter_v5.cpp
+++ b/engines/gob/inter_v5.cpp
@@ -266,9 +266,9 @@ void Inter_v5::o5_spaceShooter(OpGobParams &params) {
void Inter_v5::o5_getSystemCDSpeed(OpGobParams &params) {
WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
- Video::FontDesc *font;
- if ((font = _vm->_util->loadFont("SPEED.LET"))) {
- _vm->_draw->drawString("100 %", 402, 89, 112, 144, 0, *_vm->_draw->_backSurface, font);
+ Font *font;
+ if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
+ _vm->_draw->drawString("100 %", 402, 89, 112, 144, 0, *_vm->_draw->_backSurface, *font);
_vm->_draw->forceBlit();
delete font;
@@ -278,9 +278,9 @@ void Inter_v5::o5_getSystemCDSpeed(OpGobParams &params) {
void Inter_v5::o5_getSystemRAM(OpGobParams &params) {
WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
- Video::FontDesc *font;
- if ((font = _vm->_util->loadFont("SPEED.LET"))) {
- _vm->_draw->drawString("100 %", 402, 168, 112, 144, 0, *_vm->_draw->_backSurface, font);
+ Font *font;
+ if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
+ _vm->_draw->drawString("100 %", 402, 168, 112, 144, 0, *_vm->_draw->_backSurface, *font);
_vm->_draw->forceBlit();
delete font;
@@ -290,9 +290,9 @@ void Inter_v5::o5_getSystemRAM(OpGobParams &params) {
void Inter_v5::o5_getSystemCPUSpeed(OpGobParams &params) {
WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
- Video::FontDesc *font;
- if ((font = _vm->_util->loadFont("SPEED.LET"))) {
- _vm->_draw->drawString("100 %", 402, 248, 112, 144, 0, *_vm->_draw->_backSurface, font);
+ Font *font;
+ if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
+ _vm->_draw->drawString("100 %", 402, 248, 112, 144, 0, *_vm->_draw->_backSurface, *font);
_vm->_draw->forceBlit();
delete font;
@@ -302,9 +302,9 @@ void Inter_v5::o5_getSystemCPUSpeed(OpGobParams &params) {
void Inter_v5::o5_getSystemDrawSpeed(OpGobParams &params) {
WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
- Video::FontDesc *font;
- if ((font = _vm->_util->loadFont("SPEED.LET"))) {
- _vm->_draw->drawString("100 %", 402, 326, 112, 144, 0, *_vm->_draw->_backSurface, font);
+ Font *font;
+ if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
+ _vm->_draw->drawString("100 %", 402, 326, 112, 144, 0, *_vm->_draw->_backSurface, *font);
_vm->_draw->forceBlit();
delete font;
@@ -314,9 +314,9 @@ void Inter_v5::o5_getSystemDrawSpeed(OpGobParams &params) {
void Inter_v5::o5_totalSystemSpecs(OpGobParams &params) {
WRITE_VAR_UINT32(_vm->_game->_script->readInt16(), 100); // Fudging 100%
- Video::FontDesc *font;
- if ((font = _vm->_util->loadFont("SPEED.LET"))) {
- _vm->_draw->drawString("100 %", 402, 405, 112, 144, 0, *_vm->_draw->_backSurface, font);
+ Font *font;
+ if ((font = _vm->_draw->loadFont("SPEED.LET"))) {
+ _vm->_draw->drawString("100 %", 402, 405, 112, 144, 0, *_vm->_draw->_backSurface, *font);
_vm->_draw->forceBlit();
delete font;
diff --git a/engines/gob/util.cpp b/engines/gob/util.cpp
index 429b0269cf..356eb3c643 100644
--- a/engines/gob/util.cpp
+++ b/engines/gob/util.cpp
@@ -379,38 +379,6 @@ void Util::setScrollOffset(int16 x, int16 y) {
_vm->_video->waitRetrace();
}
-Video::FontDesc *Util::loadFont(const char *path) {
- Video::FontDesc *fontDesc = new Video::FontDesc;
- byte *data;
-
- if (!fontDesc)
- return 0;
-
- data = _vm->_dataIO->getData(path);
- if (!data) {
- delete fontDesc;
- return 0;
- }
-
- fontDesc->dataPtr = data + 4;
- fontDesc->itemWidth = data[0] & 0x7F;
- fontDesc->itemHeight = data[1];
- fontDesc->startItem = data[2];
- fontDesc->endItem = data[3];
-
- fontDesc->itemSize =
- ((fontDesc->itemWidth - 1) / 8 + 1) * fontDesc->itemHeight;
- fontDesc->bitWidth = fontDesc->itemWidth;
-
- if (data[0] & 0x80)
- fontDesc->charWidths = data + 4 + fontDesc->itemSize *
- (fontDesc->endItem - fontDesc->startItem + 1);
- else
- fontDesc->charWidths = 0;
-
- return fontDesc;
-}
-
void Util::insertStr(const char *str1, char *str2, int16 pos) {
int len1 = strlen(str1);
int len2 = strlen(str2);
diff --git a/engines/gob/util.h b/engines/gob/util.h
index 088a78a64d..82e2df94de 100644
--- a/engines/gob/util.h
+++ b/engines/gob/util.h
@@ -28,10 +28,10 @@
#include "common/keyboard.h"
-#include "gob/video.h"
-
namespace Gob {
+class GobEngine;
+
#define KEYBUFSIZE 16
enum MouseButtons {
@@ -121,8 +121,6 @@ public:
void waitEndFrame();
void setScrollOffset(int16 x = -1, int16 y = -1);
- Video::FontDesc *loadFont(const char *path);
-
static void insertStr(const char *str1, char *str2, int16 pos);
static void cutFromStr(char *str, int16 from, int16 cutlen);
static void cleanupStr(char *str);
diff --git a/engines/gob/video.cpp b/engines/gob/video.cpp
index 3b4822cc77..f05ee8565f 100644
--- a/engines/gob/video.cpp
+++ b/engines/gob/video.cpp
@@ -40,6 +40,82 @@
namespace Gob {
+Font::Font(const byte *data) : _dataPtr(data) {
+ assert(data);
+
+ bool hasWidths = _dataPtr[0] & 0x80;
+
+ _data = _dataPtr + 4;
+ _itemWidth = _dataPtr[0] & 0x7F;
+ _itemHeight = _dataPtr[1];
+ _startItem = _dataPtr[2];
+ _endItem = _dataPtr[3];
+ _charWidths = 0;
+
+ uint8 rowAlignedBits = (_itemWidth - 1) / 8 + 1;
+
+ _itemSize = rowAlignedBits * _itemHeight;
+ _bitWidth = _itemWidth;
+
+ if (hasWidths)
+ _charWidths = _dataPtr + 4 + _itemSize * getCharCount();
+}
+
+Font::~Font() {
+ delete _dataPtr;
+}
+
+uint8 Font::getCharWidth(uint8 c) const {
+ if (!_charWidths || (_endItem == 0))
+ return _itemWidth;
+
+ if ((c < _startItem) || (c > _endItem))
+ return _itemWidth;
+
+ return _charWidths[c - _startItem];
+}
+
+uint8 Font::getCharWidth() const {
+ return _itemWidth;
+}
+
+uint8 Font::getCharHeight() const {
+ return _itemHeight;
+}
+
+uint16 Font::getCharCount() const {
+ return _endItem - _startItem + 1;
+}
+
+uint8 Font::getFirstChar() const {
+ return _startItem;
+}
+
+uint8 Font::getLastChar() const {
+ return _endItem;
+}
+
+uint8 Font::getCharSize() const {
+ return _itemSize;
+}
+
+bool Font::isMonospaced() const {
+ return _charWidths == 0;
+}
+
+const byte *Font::getCharData(uint8 c) const {
+ if (_endItem == 0) {
+ warning("Font::getCharData(): _endItem == 0");
+ return 0;
+ }
+
+ if ((c < _startItem) || (c > _endItem))
+ return 0;
+
+ return _data + (c - _startItem) * _itemSize;
+}
+
+
SurfaceDesc::SurfaceDesc(int16 vidMode, int16 width, int16 height,
byte *vidMem) : _width(width), _height(height) {
@@ -381,41 +457,9 @@ void Video::drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest,
_videoDriver->drawSpriteDouble(source, dest, left, top, right, bottom, x, y, transp);
}
-void Video::drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc,
+void Video::drawLetter(int16 item, int16 x, int16 y, const Font &font,
int16 color1, int16 color2, int16 transp, SurfaceDesc &dest) {
- byte *dataPtr;
- byte *itemData;
- int16 itemSize;
- int16 newItem;
- int16 curItem;
- int16 newItemPos;
- int16 curItemPos;
-
- if (fontDesc->endItem == 0) {
- itemSize = fontDesc->itemSize + 3;
- dataPtr = fontDesc->dataPtr;
- // startItem
- curItem = READ_LE_UINT16(dataPtr - 2) - 1;
-
- curItemPos = 0;
- do {
- newItemPos = ((curItemPos + curItem) / 2) * itemSize;
- itemData = fontDesc->dataPtr + newItemPos;
- newItem = (READ_LE_UINT16(itemData) & 0x7FFF);
- if (item > newItem)
- curItem = newItemPos - 1;
- else
- curItemPos = newItemPos + 1;
- } while ((newItem != item) && (curItemPos <= curItem));
-
- if (newItem != item)
- return;
-
- fontDesc->dataPtr = itemData + 3;
- item = 0;
- }
-
- _videoDriver->drawLetter((unsigned char)item, x, y, fontDesc, color1, color2, transp, dest);
+ _videoDriver->drawLetter((unsigned char)item, x, y, font, color1, color2, transp, dest);
}
void Video::drawPackedSprite(byte *sprBuf, int16 width, int16 height,
diff --git a/engines/gob/video.h b/engines/gob/video.h
index 8716a637c2..b8a46598b7 100644
--- a/engines/gob/video.h
+++ b/engines/gob/video.h
@@ -38,6 +38,36 @@ namespace Graphics {
namespace Gob {
+class Font {
+public:
+ uint8 getCharWidth (uint8 c) const;
+ uint8 getCharWidth () const;
+ uint8 getCharHeight() const;
+ uint16 getCharCount () const;
+ uint8 getFirstChar () const;
+ uint8 getLastChar () const;
+ uint8 getCharSize () const;
+
+ bool isMonospaced() const;
+
+ const byte *getCharData(uint8 c) const;
+
+ Font(const byte *data);
+ ~Font();
+
+private:
+ const byte *_dataPtr;
+ const byte *_data;
+ const uint8 *_charWidths;
+
+ int8 _itemWidth;
+ int8 _itemHeight;
+ uint8 _startItem;
+ uint8 _endItem;
+ int8 _itemSize;
+ int8 _bitWidth;
+};
+
// Some Surfaces are simultaneous in Draw::spritesArray and discrete
// variables, so if in doubt you should use a SurfaceDescPtr shared
// pointer object to refer to any SurfaceDesc.
@@ -70,23 +100,6 @@ typedef Common::SharedPtr<SurfaceDesc> SurfaceDescPtr;
class Video {
public:
- struct FontDesc {
- byte *dataPtr;
- int8 itemWidth;
- int8 itemHeight;
- uint8 startItem;
- uint8 endItem;
- int8 itemSize;
- int8 bitWidth;
- uint8 *charWidths;
- FontDesc() : dataPtr(0), itemWidth(0), itemHeight(0), startItem(0),
- endItem(0), itemSize(0), bitWidth(0) {}
- ~FontDesc() {
- if (dataPtr)
- delete[] (dataPtr - 4);
- }
- };
-
#define GDR_VERSION 4
#define PRIMARY_SURFACE 0x80
@@ -154,7 +167,7 @@ public:
int16 x, int16 y, int16 transp);
void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest,
int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp);
- void drawLetter(int16 item, int16 x, int16 y, FontDesc *fontDesc,
+ void drawLetter(int16 item, int16 x, int16 y, const Font &font,
int16 color1, int16 color2, int16 transp, SurfaceDesc &dest);
void drawPackedSprite(byte *sprBuf, int16 width, int16 height,
int16 x, int16 y, int16 transp, SurfaceDesc &dest);
@@ -266,7 +279,7 @@ public:
virtual void drawSpriteDouble(SurfaceDesc &source, SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, int16 x, int16 y, int16 transp) = 0;
virtual void fillRect(SurfaceDesc &dest, int16 left, int16 top, int16 right, int16 bottom, byte color) = 0;
virtual void putPixel(int16 x, int16 y, byte color, SurfaceDesc &dest) = 0;
- virtual void drawLetter(unsigned char item, int16 x, int16 y, Video::FontDesc *fontDesc, byte color1, byte color2, byte transp, SurfaceDesc &dest) = 0;
+ virtual void drawLetter(unsigned char item, int16 x, int16 y, const Font &font, byte color1, byte color2, byte transp, SurfaceDesc &dest) = 0;
virtual void drawLine(SurfaceDesc &dest, int16 x0, int16 y0, int16 x1, int16 y1, byte color) = 0;
virtual void drawPackedSprite(byte *sprBuf, int16 width, int16 height, int16 x, int16 y, byte transp, SurfaceDesc &dest) = 0;
};
diff --git a/engines/kyra/lol.cpp b/engines/kyra/lol.cpp
index f2617dc8b4..d2c8be9556 100644
--- a/engines/kyra/lol.cpp
+++ b/engines/kyra/lol.cpp
@@ -1877,15 +1877,8 @@ int LoLEngine::rollDice(int times, int pips) {
return 0;
int res = 0;
- int d = 0;
-
- do {
- int val = (((int)_rnd.getRandomNumber(0x7fff) * pips) / 0x8000) + 1;
- if (val > pips)
- val -= pips;
- res += val;
- d++;
- } while (d < times);
+ while (times--)
+ res += _rnd.getRandomNumberRng(1, pips);
return res;
}
@@ -1901,7 +1894,7 @@ int LoLEngine::castSpell(int charNum, int spellType, int spellLevel) {
_activeSpell.spell = spellType;
_activeSpell.p = &_spellProperties[spellType];
- _activeSpell.level = spellLevel < 0 ? -spellLevel : spellLevel;
+ _activeSpell.level = ABS(spellLevel);
if ((_spellProperties[spellType].flags & 0x100) && testWallFlag(calcNewBlockPosition(_currentBlock, _currentDirection), _currentDirection, 1)) {
_txt->printMessage(2, getLangString(0x4257));
diff --git a/engines/parallaction/sound.h b/engines/parallaction/sound.h
index 8fcfb94a9a..5a2c5e1c38 100644
--- a/engines/parallaction/sound.h
+++ b/engines/parallaction/sound.h
@@ -30,7 +30,7 @@
#include "common/mutex.h"
#include "sound/audiostream.h"
-#include "sound/iff.h"
+#include "sound/iff_sound.h"
#include "sound/mixer.h"
#include "sound/mididrv.h"
diff --git a/engines/sci/debug.h b/engines/sci/debug.h
index ccf0602600..0963159c98 100644
--- a/engines/sci/debug.h
+++ b/engines/sci/debug.h
@@ -46,7 +46,7 @@ struct ScriptState {
int old_pc_offset;
StackPtr old_sp;
ExecStack *xs;
- uint16 restadjust;
+ int16 restadjust;
reg_t *variables[4]; // global, local, temp, param, as immediate pointers
reg_t *variables_base[4]; // Used for referencing VM ops
SegmentId variables_seg[4]; // Same as above, contains segment IDs
diff --git a/engines/sci/detection.cpp b/engines/sci/detection.cpp
index a9dac98572..a80baf182e 100644
--- a/engines/sci/detection.cpp
+++ b/engines/sci/detection.cpp
@@ -1850,7 +1850,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "4462fe48c7452d98fddcec327a3e738d", 5789138},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
0,
- SCI_VERSION_1_1,
+ SCI_VERSION_AUTODETECT,
SCI_VERSION_1_1
},
@@ -1861,7 +1861,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "57d5fe8bb9e044158514476ea7678eb0", 5754790},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NONE},
0,
- SCI_VERSION_1_1,
+ SCI_VERSION_AUTODETECT,
SCI_VERSION_1_1
},
@@ -2574,7 +2574,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "ecace1a2771846b1a8aa1afdd44111a0", 6570147},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, 0, GUIO_NOSPEECH},
0,
- SCI_VERSION_1,
+ SCI_VERSION_AUTODETECT,
SCI_VERSION_1_1
},
@@ -2585,7 +2585,7 @@ static const struct SciGameDescription SciGameDescriptions[] = {
{"resource.000", 0, "ec6f5cf369054dd3e5392995e9975b9e", 768218},
{NULL, 0, NULL, 0}}, Common::EN_ANY, Common::kPlatformPC, ADGF_DEMO, GUIO_NOSPEECH},
0,
- SCI_VERSION_1,
+ SCI_VERSION_AUTODETECT,
SCI_VERSION_1_1
},
diff --git a/engines/sci/engine/state.h b/engines/sci/engine/state.h
index 92a5b5e411..1759b26dcb 100644
--- a/engines/sci/engine/state.h
+++ b/engines/sci/engine/state.h
@@ -208,7 +208,7 @@ public:
bool _executionStackPosChanged; /**< Set to true if the execution stack position should be re-evaluated by the vm */
reg_t r_acc; /**< Accumulator */
- uint16 restAdjust; /**< &rest register (only used for save games) */
+ int16 restAdjust; /**< &rest register (only used for save games) */
reg_t r_prev; /**< previous comparison result */
SegmentId stack_segment; /**< Heap area for the stack to use */
diff --git a/engines/sci/resource.cpp b/engines/sci/resource.cpp
index 30e917557d..5fdc286894 100644
--- a/engines/sci/resource.cpp
+++ b/engines/sci/resource.cpp
@@ -728,32 +728,51 @@ int ResourceManager::detectMapVersion() {
}
return SCI_VERSION_0;
}
- // SCI1E/L and some SCI1.1 maps have last directory entry set to 0xFF
- // and offset set to filesize
- // SCI1 have 6-bytes entries, while SCI1.1 have 5-byte entries
- file.seek(1, SEEK_SET);
- uint16 off1, off = file.readUint16LE();
- uint16 nEntries = off / 3;
- file.seek(1, SEEK_CUR);
- file.seek(off - 3, SEEK_SET);
- if (file.readByte() == 0xFF && file.readUint16LE() == file.size()) {
- file.seek(3, SEEK_SET);
- for (int i = 0; i < nEntries; i++) {
- file.seek(1, SEEK_CUR);
- off1 = file.readUint16LE();
- if ((off1 - off) % 5 && (off1 - off) % 6 == 0)
- return SCI_VERSION_1;
- if ((off1 - off) % 5 == 0 && (off1 - off) % 6)
- return SCI_VERSION_1_1;
- off = off1;
+
+ // SCI1 and SCI1.1 maps consist of a fixed 3-byte header, a directory list (3-bytes each) that has one entry
+ // of id FFh and points to EOF. The actual entries have 6-bytes on SCI1 and 5-bytes on SCI1.1
+ byte directoryType = 0;
+ uint16 directoryOffset = 0;
+ uint16 lastDirectoryOffset = 0;
+ uint16 directorySize = 0;
+ int mapDetected = 0;
+ file.seek(0, SEEK_SET);
+ while (!file.eos()) {
+ directoryType = file.readByte();
+ directoryOffset = file.readUint16LE();
+ if ((directoryType < 0x80) || ((directoryType > 0xA0) && (directoryType != 0xFF)))
+ break;
+ // Offset is above file size? -> definitely not SCI1/SCI1.1
+ if (directoryOffset > file.size())
+ break;
+ if (lastDirectoryOffset) {
+ directorySize = directoryOffset - lastDirectoryOffset;
+ if ((directorySize % 5) && (directorySize % 6 == 0))
+ mapDetected = SCI_VERSION_1;
+ if ((directorySize % 5 == 0) && (directorySize % 6))
+ mapDetected = SCI_VERSION_1_1;
}
- return SCI_VERSION_1;
+ if (directoryType==0xFF) {
+ // FFh entry needs to point to EOF
+ if (directoryOffset != file.size())
+ break;
+ if (mapDetected)
+ return mapDetected;
+ return SCI_VERSION_1;
+ }
+ lastDirectoryOffset = directoryOffset;
}
#ifdef ENABLE_SCI32
// late SCI1.1 and SCI32 maps have last directory entry set to 0xFF
// offset set to filesize and 4 more bytes
- file.seek(off - 7, SEEK_SET);
+
+ // TODO/FIXME: This code was not updated in r42300, which changed the behavior of this
+ // function a lot. To make it compile again "off" was changed to the newly introduced
+ // "lastDirectoryOffset". This is probably not the correct fix, since before r43000
+ // the loop above could not prematurely terminate and thus this would always check the
+ // last directory entry instead of the last checked directory entry.
+ file.seek(lastDirectoryOffset - 7, SEEK_SET);
if (file.readByte() == 0xFF && file.readUint16LE() == file.size())
return SCI_VERSION_32; // TODO : check if there is a difference between these maps
#endif
@@ -974,6 +993,9 @@ int ResourceManager::readResourceMapSCI0(ResourceSource *map) {
res->file_offset = offset & (((~bMask) << 24) | 0xFFFFFF);
res->id = resId;
res->source = getVolume(map, offset >> bShift);
+ if (!res->source) {
+ warning("Could not get volume for resource %d, VolumeID %d\n", id, offset >> bShift);
+ }
_resMap.setVal(resId, res);
}
} while (!file.eos());