SHERLOCK: 3DO: implement map support + cel 8-bit

added PLUT shading
This commit is contained in:
Martin Kiewitz 2015-06-13 16:29:21 +02:00
parent d9ccf57dd0
commit 9c59dc8c8d
2 changed files with 76 additions and 15 deletions

View File

@ -490,8 +490,44 @@ void ImageFile3DO::load3DOCelFile(Common::SeekableReadStream &stream) {
assert(dataSize >= 4 + (plutCount * 2)); // security check
assert(plutCount <= 256); // security check
for (uint32 plutColor = 0; plutColor < plutCount; plutColor++) {
plutRGBlookupTable.pixelColor[plutColor] = stream.readUint16BE();
assert(plutCount <= 32); // PLUT should never contain more than 32 entries
for (uint32 plutColorNr = 0; plutColorNr < plutCount; plutColorNr++) {
plutRGBlookupTable.pixelColor[plutColorNr] = stream.readUint16BE();
}
if (ccbPRE0_bitsPerPixel == 8) {
// In case we are getting 8-bits per pixel, we calculate the shades accordingly
// I'm not 100% sure if the calculation is correct. It's difficult to find information
// on this topic.
// The map uses this type of cel
assert(plutCount == 32); // And we expect 32 entries inside PLUT chunk
uint16 plutColorRGB = 0;
for (uint32 plutColorNr = 0; plutColorNr < plutCount; plutColorNr++) {
plutColorRGB = plutRGBlookupTable.pixelColor[plutColorNr];
// Extract RGB values
byte plutColorRed = (plutColorRGB >> 10) & 0x1F;
byte plutColorGreen = (plutColorRGB >> 5) & 0x1F;
byte plutColorBlue = plutColorRGB & 0x1F;
byte shadeMultiplier = 2;
for (uint32 plutShadeNr = 1; plutShadeNr < 8; plutShadeNr++) {
uint16 shadedColorRGB;
byte shadedColorRed = (plutColorRed * shadeMultiplier) >> 3;
byte shadedColorGreen = (plutColorGreen * shadeMultiplier) >> 3;
byte shadedColorBlue = (plutColorBlue * shadeMultiplier) >> 3;
shadedColorRed = CLIP<byte>(shadedColorRed, 0, 0x1F);
shadedColorGreen = CLIP<byte>(shadedColorGreen, 0, 0x1F);
shadedColorBlue = CLIP<byte>(shadedColorBlue, 0, 0x1F);
shadedColorRGB = (shadedColorRed << 10) | (shadedColorGreen << 5) | shadedColorBlue;
plutRGBlookupTable.pixelColor[plutColorNr + (plutShadeNr << 5)] = shadedColorRGB;
shadeMultiplier++;
}
}
}
break;

View File

@ -141,16 +141,28 @@ int ScalpelMap::show() {
screen.clear();
// Load the entire map
ImageFile bigMap("bigmap.vgs");
screen.setPalette(bigMap._palette);
ImageFile *bigMap = NULL;
if (_vm->getPlatform() != Common::kPlatform3DO) {
// PC
bigMap = new ImageFile("bigmap.vgs");
screen.setPalette(bigMap->_palette);
} else {
// 3DO
bigMap = new ImageFile3DO("overland.cel", kImageFile3DOType_Cel);
}
// Load need sprites
setupSprites();
screen._backBuffer1.blitFrom(bigMap[0], Common::Point(-_bigPos.x, -_bigPos.y));
screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
screen._backBuffer1.blitFrom(bigMap[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y));
screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
if (_vm->getPlatform() != Common::kPlatform3DO) {
screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
screen._backBuffer1.blitFrom((*bigMap)[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
screen._backBuffer1.blitFrom((*bigMap)[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y));
screen._backBuffer1.blitFrom((*bigMap)[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
} else {
screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
screen.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
}
_drawMap = true;
_charPoint = -1;
@ -208,10 +220,14 @@ int ScalpelMap::show() {
// Map has scrolled, so redraw new map view
changed = false;
screen._backBuffer1.blitFrom(bigMap[0], Common::Point(-_bigPos.x, -_bigPos.y));
screen._backBuffer1.blitFrom(bigMap[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
screen._backBuffer1.blitFrom(bigMap[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y));
screen._backBuffer1.blitFrom(bigMap[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
if (_vm->getPlatform() != Common::kPlatform3DO) {
screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
screen._backBuffer1.blitFrom((*bigMap)[1], Common::Point(-_bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
screen._backBuffer1.blitFrom((*bigMap)[2], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, -_bigPos.y));
screen._backBuffer1.blitFrom((*bigMap)[3], Common::Point(SHERLOCK_SCREEN_WIDTH - _bigPos.x, SHERLOCK_SCREEN_HEIGHT - _bigPos.y));
} else {
screen._backBuffer1.blitFrom((*bigMap)[0], Common::Point(-_bigPos.x, -_bigPos.y));
}
showPlaces();
_placesShown = false;
@ -281,12 +297,21 @@ void ScalpelMap::setupSprites() {
Scene &scene = *_vm->_scene;
_savedPos.x = -1;
_mapCursors = new ImageFile("omouse.vgs");
if (_vm->getPlatform() != Common::kPlatform3DO) {
// PC
_mapCursors = new ImageFile("omouse.vgs");
_shapes = new ImageFile("mapicon.vgs");
_iconShapes = new ImageFile("overicon.vgs");
} else {
// 3DO
_mapCursors = new ImageFile3DO("omouse.vgs", kImageFile3DOType_RoomFormat);
_shapes = new ImageFile3DO("mapicon.vgs", kImageFile3DOType_RoomFormat);
_iconShapes = new ImageFile3DO("overicon.vgs", kImageFile3DOType_RoomFormat);
}
_cursorIndex = 0;
events.setCursor((*_mapCursors)[_cursorIndex]._frame);
_shapes = new ImageFile("mapicon.vgs");
_iconShapes = new ImageFile("overicon.vgs");
_iconSave.create((*_shapes)[4]._width, (*_shapes)[4]._height, _vm->getPlatform());
Person &p = people[HOLMES];
p._description = " ";