diff options
-rw-r--r-- | engines/sci/engine/kernel.h | 18 | ||||
-rw-r--r-- | engines/sci/engine/kernel_tables.h | 28 | ||||
-rw-r--r-- | engines/sci/engine/kgraphics32.cpp | 330 | ||||
-rw-r--r-- | engines/sci/graphics/celobj32.cpp | 45 | ||||
-rw-r--r-- | engines/sci/graphics/celobj32.h | 28 | ||||
-rw-r--r-- | engines/sci/graphics/text32.cpp | 40 | ||||
-rw-r--r-- | engines/sci/graphics/text32.h | 5 |
7 files changed, 272 insertions, 222 deletions
diff --git a/engines/sci/engine/kernel.h b/engines/sci/engine/kernel.h index 3a6809aec1..f844d96c35 100644 --- a/engines/sci/engine/kernel.h +++ b/engines/sci/engine/kernel.h @@ -460,7 +460,22 @@ reg_t kUpdateScreenItem(EngineState *s, int argc, reg_t *argv); reg_t kDeleteScreenItem(EngineState *s, int argc, reg_t *argv); reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv); -reg_t kDisposeTextBitmap(EngineState *s, int argc, reg_t *argv); +reg_t kBitmap(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapDrawLine(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapDrawBitmap(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapInvert(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapSetDisplace(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapCreateFromView(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapCopyPixels(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapClone(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapGetInfo(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapScale(EngineState *s, int argc, reg_t *argv); +reg_t kBitmapCreateFromUnknown(EngineState *s, int argc, reg_t *argv); reg_t kAddPlane(EngineState *s, int argc, reg_t *argv); reg_t kDeletePlane(EngineState *s, int argc, reg_t *argv); @@ -521,7 +536,6 @@ reg_t kScrollWindow(EngineState *s, int argc, reg_t *argv); reg_t kSetFontHeight(EngineState *s, int argc, reg_t *argv); reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv); reg_t kFont(EngineState *s, int argc, reg_t *argv); -reg_t kBitmap(EngineState *s, int argc, reg_t *argv); reg_t kAddLine(EngineState *s, int argc, reg_t *argv); reg_t kUpdateLine(EngineState *s, int argc, reg_t *argv); reg_t kDeleteLine(EngineState *s, int argc, reg_t *argv); diff --git a/engines/sci/engine/kernel_tables.h b/engines/sci/engine/kernel_tables.h index 88702e1aef..6258197206 100644 --- a/engines/sci/engine/kernel_tables.h +++ b/engines/sci/engine/kernel_tables.h @@ -65,12 +65,14 @@ struct SciKernelMapSubEntry { #define SIG_SCI1 SCI_VERSION_1_EGA_ONLY, SCI_VERSION_1_LATE #define SIG_SCI11 SCI_VERSION_1_1, SCI_VERSION_1_1 #define SIG_SINCE_SCI11 SCI_VERSION_1_1, SCI_VERSION_NONE +#define SIG_SCI2 SCI_VERSION_2, SCI_VERSION_2 #define SIG_SCI21EARLY SCI_VERSION_2_1_EARLY, SCI_VERSION_2_1_EARLY #define SIG_UNTIL_SCI21EARLY SCI_VERSION_2, SCI_VERSION_2_1_EARLY #define SIG_UNTIL_SCI21MID SCI_VERSION_2, SCI_VERSION_2_1_MIDDLE #define SIG_SINCE_SCI21 SCI_VERSION_2_1_EARLY, SCI_VERSION_3 #define SIG_SINCE_SCI21MID SCI_VERSION_2_1_MIDDLE, SCI_VERSION_3 #define SIG_SINCE_SCI21LATE SCI_VERSION_2_1_LATE, SCI_VERSION_3 +#define SIG_SCI3 SCI_VERSION_3, SCI_VERSION_3 #define SIG_SCI16 SCI_VERSION_NONE, SCI_VERSION_1_1 #define SIG_SCI32 SCI_VERSION_2, SCI_VERSION_NONE @@ -300,6 +302,28 @@ static const SciKernelMapSubEntry kText_subops[] = { }; // version, subId, function-mapping, signature, workarounds +static const SciKernelMapSubEntry kBitmap_subops[] = { + { SIG_SINCE_SCI21, 0, MAP_CALL(BitmapCreate), "iiii(i)(i)(i)", NULL }, + { SIG_SINCE_SCI21, 1, MAP_CALL(BitmapDestroy), "r", NULL }, + { SIG_SINCE_SCI21, 2, MAP_CALL(BitmapDrawLine), "riiiii(i)(i)", NULL }, + { SIG_SINCE_SCI21, 3, MAP_CALL(BitmapDrawView), "riii(i)(i)(0)(i)(i)", NULL }, + { SIG_SINCE_SCI21, 4, MAP_CALL(BitmapDrawText), "rriiiiiiiiiii", NULL }, + { SIG_SINCE_SCI21, 5, MAP_CALL(BitmapDrawColor), "riiiii", NULL }, + { SIG_SINCE_SCI21, 6, MAP_CALL(BitmapDrawBitmap), "rr(i)(i)(i)", NULL }, + { SIG_SINCE_SCI21, 7, MAP_CALL(BitmapInvert), "riiiiii", NULL }, + { SIG_SINCE_SCI21MID, 8, MAP_CALL(BitmapSetDisplace), "rii", NULL }, + { SIG_SINCE_SCI21MID, 9, MAP_CALL(BitmapCreateFromView), "iii(i)(i)(i)([r0])", NULL }, + { SIG_SINCE_SCI21MID, 10, MAP_CALL(BitmapCopyPixels), "rr", NULL }, + { SIG_SINCE_SCI21MID, 11, MAP_CALL(BitmapClone), "r", NULL }, + { SIG_SINCE_SCI21LATE, 12, MAP_CALL(BitmapGetInfo), "r(i)(i)", NULL }, + { SIG_SINCE_SCI21LATE, 13, MAP_CALL(BitmapScale), "r...ii", NULL }, + { SIG_SCI3, 14, MAP_CALL(BitmapCreateFromUnknown), "......", NULL }, + { SIG_SCI3, 15, MAP_EMPTY(Bitmap), "(.*)", NULL }, + { SIG_SCI3, 16, MAP_EMPTY(Bitmap), "(.*)", NULL }, + SCI_SUBOPENTRY_TERMINATOR +}; + +// version, subId, function-mapping, signature, workarounds static const SciKernelMapSubEntry kList_subops[] = { { SIG_SINCE_SCI21, 0, MAP_CALL(NewList), "", NULL }, { SIG_SINCE_SCI21, 1, MAP_CALL(DisposeList), "l", NULL }, @@ -607,7 +631,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(CreateTextBitmap), SIG_EVERYWHERE, "i(.*)", NULL, NULL }, { MAP_CALL(DeletePlane), SIG_EVERYWHERE, "o", NULL, NULL }, { MAP_CALL(DeleteScreenItem), SIG_EVERYWHERE, "o", NULL, NULL }, - { MAP_CALL(DisposeTextBitmap), SIG_EVERYWHERE, "r", NULL, NULL }, + { "DisposeTextBitmap", kBitmapDestroy, SIG_SCI2, SIGFOR_ALL, "r", NULL, NULL }, { MAP_CALL(FrameOut), SIG_EVERYWHERE, "(i)", NULL, NULL }, { MAP_CALL(GetHighPlanePri), SIG_EVERYWHERE, "", NULL, NULL }, { MAP_CALL(InPolygon), SIG_EVERYWHERE, "iio", NULL, NULL }, @@ -693,7 +717,7 @@ static SciKernelMapEntry s_kernelMap[] = { { MAP_CALL(ScrollWindow), SIG_EVERYWHERE, "i(.*)", kScrollWindow_subops, NULL }, { MAP_CALL(SetFontRes), SIG_SCI21EARLY, SIGFOR_ALL, "ii", NULL, NULL }, { MAP_CALL(Font), SIG_SINCE_SCI21MID, SIGFOR_ALL, "i(.*)", kFont_subops, NULL }, - { MAP_CALL(Bitmap), SIG_EVERYWHERE, "(.*)", NULL, NULL }, + { MAP_CALL(Bitmap), SIG_EVERYWHERE, "(.*)", kBitmap_subops, NULL }, { MAP_CALL(AddLine), SIG_EVERYWHERE, "oiiiiiiiii", NULL, NULL }, { MAP_CALL(UpdateLine), SIG_EVERYWHERE, "[r0]oiiiiiiiii", NULL, NULL }, { MAP_CALL(DeleteLine), SIG_EVERYWHERE, "[r0]o", NULL, NULL }, diff --git a/engines/sci/engine/kgraphics32.cpp b/engines/sci/engine/kgraphics32.cpp index 36f637be0f..8fa7b960b0 100644 --- a/engines/sci/engine/kgraphics32.cpp +++ b/engines/sci/engine/kgraphics32.cpp @@ -49,11 +49,12 @@ #include "sci/graphics/text16.h" #include "sci/graphics/view.h" #ifdef ENABLE_SCI32 -#include "sci/graphics/palette32.h" +#include "sci/graphics/celobj32.h" #include "sci/graphics/controls32.h" #include "sci/graphics/font.h" // TODO: remove once kBitmap is moved in a separate class -#include "sci/graphics/text32.h" #include "sci/graphics/frameout.h" +#include "sci/graphics/palette32.h" +#include "sci/graphics/text32.h" #endif namespace Sci { @@ -209,11 +210,6 @@ reg_t kCreateTextBitmap(EngineState *s, int argc, reg_t *argv) { } } -reg_t kDisposeTextBitmap(EngineState *s, int argc, reg_t *argv) { - g_sci->_gfxText32->disposeTextBitmap(argv[0]); - return s->r_acc; -} - reg_t kText(EngineState *s, int argc, reg_t *argv) { if (!s) return make_reg(0, getSciVersion()); @@ -503,183 +499,171 @@ reg_t kSetFontRes(EngineState *s, int argc, reg_t *argv) { return NULL_REG; } -// TODO: Eventually, all of the kBitmap operations should be put -// in a separate class +reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { + if (!s) + return make_reg(0, getSciVersion()); + error("not supposed to call this"); +} -// NOTE: This size is correct only for SCI2.1mid; the size for -// SCI2/2.1early is 36 -#define BITMAP_HEADER_SIZE 46 +reg_t kBitmapCreate(EngineState *s, int argc, reg_t *argv) { + uint32 bitmapHeaderSize = CelObjMem::getBitmapHeaderSize(); + int16 width = argv[0].toSint16(); + int16 height = argv[1].toSint16(); + int16 skipColor = argv[2].toSint16(); + int16 backColor = argv[3].toSint16(); + int16 scaledWidth = argc > 4 ? argv[4].toSint16() : g_sci->_gfxText32->_scaledWidth; + int16 scaledHeight = argc > 5 ? argv[5].toSint16() : g_sci->_gfxText32->_scaledHeight; + bool useRemap = argc > 6 ? argv[6].toSint16() : false; -reg_t kBitmap(EngineState *s, int argc, reg_t *argv) { - // Used for bitmap operations in SCI2.1 and SCI3. - // This is the SCI2.1 version, the functionality seems to have changed in SCI3. + reg_t bitmapMemId = s->_segMan->allocateHunkEntry("Bitmap()", width * height + bitmapHeaderSize); + byte *bitmap = s->_segMan->getHunkPointer(bitmapMemId); + memset(bitmap + bitmapHeaderSize, backColor, width * height); + CelObjMem::buildBitmapHeader(bitmap, width, height, skipColor, 0, 0, scaledWidth, scaledHeight, 0, useRemap); + return bitmapMemId; +} - switch (argv[0].toUint16()) { - case 0: // init bitmap surface - { - // 6 params, called e.g. from TextView::init() in Torin's Passage, - // script 64890 and TransView::init() in script 64884 - uint16 width = argv[1].toUint16(); - uint16 height = argv[2].toUint16(); - //uint16 skip = argv[3].toUint16(); - uint16 back = argv[4].toUint16(); // usually equals skip - //uint16 width2 = (argc >= 6) ? argv[5].toUint16() : 0; - //uint16 height2 = (argc >= 7) ? argv[6].toUint16() : 0; - //uint16 transparentFlag = (argc >= 8) ? argv[7].toUint16() : 0; - - // TODO: skip, width2, height2, transparentFlag - // (used for transparent bitmaps) - int entrySize = width * height + BITMAP_HEADER_SIZE; - reg_t memoryId = s->_segMan->allocateHunkEntry("Bitmap()", entrySize); - byte *memoryPtr = s->_segMan->getHunkPointer(memoryId); - memset(memoryPtr, 0, BITMAP_HEADER_SIZE); // zero out the bitmap header - memset(memoryPtr + BITMAP_HEADER_SIZE, back, width * height); - // Save totalWidth, totalHeight - // TODO: Save the whole bitmap header, like SSCI does - WRITE_SCI11ENDIAN_UINT16(memoryPtr, width); - WRITE_SCI11ENDIAN_UINT16(memoryPtr + 2, height); - WRITE_SCI11ENDIAN_UINT16(memoryPtr + 4, 0); - WRITE_SCI11ENDIAN_UINT16(memoryPtr + 6, 0); - memoryPtr[8] = 0; - WRITE_SCI11ENDIAN_UINT16(memoryPtr + 10, 0); - WRITE_SCI11ENDIAN_UINT16(memoryPtr + 20, BITMAP_HEADER_SIZE); - WRITE_SCI11ENDIAN_UINT32(memoryPtr + 28, 46); - WRITE_SCI11ENDIAN_UINT16(memoryPtr + 36, width); - WRITE_SCI11ENDIAN_UINT16(memoryPtr + 38, width); - return memoryId; - } - break; - case 1: // dispose text bitmap surface - return kDisposeTextBitmap(s, argc - 1, argv + 1); - case 2: // dispose bitmap surface, with extra param - // 2 params, called e.g. from MenuItem::dispose in Torin's Passage, - // script 64893 - warning("kBitmap(2), unk1 %d, bitmap ptr %04x:%04x", argv[1].toUint16(), PRINT_REG(argv[2])); - break; - case 3: // tiled surface - { - // 6 params, called e.g. from TiledBitmap::resize() in Torin's Passage, - // script 64869 - reg_t hunkId = argv[1]; // obtained from kBitmap(0) - // The tiled view seems to always have 2 loops. - // These loops need to have 1 cel in loop 0 and 8 cels in loop 1. - uint16 viewNum = argv[2].toUint16(); // vTiles selector - uint16 loop = argv[3].toUint16(); - uint16 cel = argv[4].toUint16(); - uint16 x = argv[5].toUint16(); - uint16 y = argv[6].toUint16(); - - byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); - // Get totalWidth, totalHeight - uint16 totalWidth = READ_LE_UINT16(memoryPtr); - uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); - byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; - - GfxView *view = g_sci->_gfxCache->getView(viewNum); - uint16 tileWidth = view->getWidth(loop, cel); - uint16 tileHeight = view->getHeight(loop, cel); - const byte *tileBitmap = view->getBitmap(loop, cel); - uint16 width = MIN<uint16>(totalWidth - x, tileWidth); - uint16 height = MIN<uint16>(totalHeight - y, tileHeight); - - for (uint16 curY = 0; curY < height; curY++) { - for (uint16 curX = 0; curX < width; curX++) { - bitmap[(curY + y) * totalWidth + (curX + x)] = tileBitmap[curY * tileWidth + curX]; - } - } +reg_t kBitmapDestroy(EngineState *s, int argc, reg_t *argv) { + s->_segMan->freeHunkEntry(argv[0]); + return NULL_REG; +} - } - break; - case 4: // add text to bitmap - { - warning("kBitmap(4)"); - return NULL_REG; - } -#if 0 - // 13 params, called e.g. from TextButton::createBitmap() in Torin's Passage, - // script 64894 - reg_t hunkId = argv[1]; // obtained from kBitmap(0) - Common::String text = s->_segMan->getString(argv[2]); - uint16 textX = argv[3].toUint16(); - uint16 textY = argv[4].toUint16(); - //reg_t unk5 = argv[5]; - //reg_t unk6 = argv[6]; - //reg_t unk7 = argv[7]; // skip? - //reg_t unk8 = argv[8]; // back? - //reg_t unk9 = argv[9]; - uint16 fontId = argv[10].toUint16(); - //uint16 mode = argv[11].toUint16(); - uint16 dimmed = argv[12].toUint16(); - //warning("kBitmap(4): bitmap ptr %04x:%04x, font %d, mode %d, dimmed %d - text: \"%s\"", - // PRINT_REG(bitmapPtr), font, mode, dimmed, text.c_str()); - uint16 foreColor = 255; // TODO - - byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); - // Get totalWidth, totalHeight - uint16 totalWidth = READ_LE_UINT16(memoryPtr); - uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); - byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; - - GfxFont *font = g_sci->_gfxCache->getFont(fontId); - - int16 charCount = 0; - uint16 curX = textX, curY = textY; - const char *txt = text.c_str(); - - while (*txt) { - charCount = g_sci->_gfxText32->GetLongest(txt, totalWidth, font); - if (charCount == 0) - break; - - for (int i = 0; i < charCount; i++) { - unsigned char curChar = txt[i]; - font->drawToBuffer(curChar, curY, curX, foreColor, dimmed, bitmap, totalWidth, totalHeight); - curX += font->getCharWidth(curChar); - } - - curX = textX; - curY += font->getHeight(); - txt += charCount; - while (*txt == ' ') - txt++; // skip over breaking spaces - } +reg_t kBitmapDrawLine(EngineState *s, int argc, reg_t *argv) { + // bitmapMemId, (x1, y1, x2, y2) OR (x2, y2, x1, y1), line color, unknown int, unknown int + return kStubNull(s, argc + 1, argv - 1); +} + +reg_t kBitmapDrawView(EngineState *s, int argc, reg_t *argv) { + // viewId, loopNo, celNo, displace x, displace y, unused, view x, view y + + // called e.g. from TiledBitmap::resize() in Torin's Passage, script 64869 + // The tiled view seems to always have 2 loops. + // These loops need to have 1 cel in loop 0 and 8 cels in loop 1. + + return kStubNull(s, argc + 1, argv - 1); +#if 0 + // tiled surface + // 6 params, called e.g. from TiledBitmap::resize() in Torin's Passage, + // script 64869 + reg_t hunkId = argv[1]; // obtained from kBitmap(0) + // The tiled view seems to always have 2 loops. + // These loops need to have 1 cel in loop 0 and 8 cels in loop 1. + uint16 viewNum = argv[2].toUint16(); // vTiles selector + uint16 loop = argv[3].toUint16(); + uint16 cel = argv[4].toUint16(); + uint16 x = argv[5].toUint16(); + uint16 y = argv[6].toUint16(); + + byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); + // Get totalWidth, totalHeight + uint16 totalWidth = READ_LE_UINT16(memoryPtr); + uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); + byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; + + GfxView *view = g_sci->_gfxCache->getView(viewNum); + uint16 tileWidth = view->getWidth(loop, cel); + uint16 tileHeight = view->getHeight(loop, cel); + const byte *tileBitmap = view->getBitmap(loop, cel); + uint16 width = MIN<uint16>(totalWidth - x, tileWidth); + uint16 height = MIN<uint16>(totalHeight - y, tileHeight); + + for (uint16 curY = 0; curY < height; curY++) { + for (uint16 curX = 0; curX < width; curX++) { + bitmap[(curY + y) * totalWidth + (curX + x)] = tileBitmap[curY * tileWidth + curX]; } - break; + } #endif - case 5: // fill with color - { - // 6 params, called e.g. from TextView::init() and TextView::draw() - // in Torin's Passage, script 64890 - reg_t hunkId = argv[1]; // obtained from kBitmap(0) - uint16 x = argv[2].toUint16(); - uint16 y = argv[3].toUint16(); - uint16 fillWidth = argv[4].toUint16(); // width - 1 - uint16 fillHeight = argv[5].toUint16(); // height - 1 - uint16 back = argv[6].toUint16(); - - byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); - // Get totalWidth, totalHeight - uint16 totalWidth = READ_LE_UINT16(memoryPtr); - uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); - uint16 width = MIN<uint16>(totalWidth - x, fillWidth); - uint16 height = MIN<uint16>(totalHeight - y, fillHeight); - byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; - - for (uint16 curY = 0; curY < height; curY++) { - for (uint16 curX = 0; curX < width; curX++) { - bitmap[(curY + y) * totalWidth + (curX + x)] = back; - } - } +} + +reg_t kBitmapDrawText(EngineState *s, int argc, reg_t *argv) { + // called e.g. from TextButton::createBitmap() in Torin's Passage, script 64894 + + // bitmap, text, textLeft, textTop, textRight, textBottom, foreColor, backColor, skipColor, fontNo, alignment, borderColor, dimmed + return kStubNull(s, argc + 1, argv - 1); +} +reg_t kBitmapDrawColor(EngineState *s, int argc, reg_t *argv) { + // bitmap, left, top, right, bottom, color + + // called e.g. from TextView::init() and TextView::draw() in Torin's Passage, script 64890 + return kStubNull(s, argc + 1, argv - 1); +#if 0 + reg_t hunkId = argv[1]; // obtained from kBitmap(0) + uint16 x = argv[2].toUint16(); + uint16 y = argv[3].toUint16(); + uint16 fillWidth = argv[4].toUint16(); // width - 1 + uint16 fillHeight = argv[5].toUint16(); // height - 1 + uint16 back = argv[6].toUint16(); + + byte *memoryPtr = s->_segMan->getHunkPointer(hunkId); + // Get totalWidth, totalHeight + uint16 totalWidth = READ_LE_UINT16(memoryPtr); + uint16 totalHeight = READ_LE_UINT16(memoryPtr + 2); + uint16 width = MIN<uint16>(totalWidth - x, fillWidth); + uint16 height = MIN<uint16>(totalHeight - y, fillHeight); + byte *bitmap = memoryPtr + BITMAP_HEADER_SIZE; + + for (uint16 curY = 0; curY < height; curY++) { + for (uint16 curX = 0; curX < width; curX++) { + bitmap[(curY + y) * totalWidth + (curX + x)] = back; } - break; - default: - kStub(s, argc, argv); - break; } +#endif +} - return s->r_acc; +reg_t kBitmapDrawBitmap(EngineState *s, int argc, reg_t *argv) { + // target bitmap, source bitmap, x, y, unknown boolean + + return kStubNull(s, argc + 1, argv - 1); +} + +reg_t kBitmapInvert(EngineState *s, int argc, reg_t *argv) { + // bitmap, left, top, right, bottom, foreColor, backColor + + return kStubNull(s, argc + 1, argv - 1); +} + +reg_t kBitmapSetDisplace(EngineState *s, int argc, reg_t *argv) { + // bitmap, x, y + + return kStubNull(s, argc + 1, argv - 1); +} + +reg_t kBitmapCreateFromView(EngineState *s, int argc, reg_t *argv) { + // viewId, loopNo, celNo, skipColor, backColor, useRemap, source overlay bitmap + + return kStub(s, argc + 1, argv - 1); +} + +reg_t kBitmapCopyPixels(EngineState *s, int argc, reg_t *argv) { + // target bitmap, source bitmap + + return kStubNull(s, argc + 1, argv - 1); +} + +reg_t kBitmapClone(EngineState *s, int argc, reg_t *argv) { + // bitmap + + return kStub(s, argc + 1, argv - 1); +} + +reg_t kBitmapGetInfo(EngineState *s, int argc, reg_t *argv) { + // bitmap + + // argc 1 = get width + // argc 2 = pixel at row 0 col n + // argc 3 = pixel at row n col n + return kStub(s, argc + 1, argv - 1); +} + +reg_t kBitmapScale(EngineState *s, int argc, reg_t *argv) { + // TODO: SCI3 + return kStubNull(s, argc + 1, argv - 1); +} + +reg_t kBitmapCreateFromUnknown(EngineState *s, int argc, reg_t *argv) { + // TODO: SCI3 + return kStub(s, argc + 1, argv - 1); } // Used for edit boxes in save/load dialogs. It's a rewritten version of kEditControl, diff --git a/engines/sci/graphics/celobj32.cpp b/engines/sci/graphics/celobj32.cpp index 62db02b554..787d295d5e 100644 --- a/engines/sci/graphics/celobj32.cpp +++ b/engines/sci/graphics/celobj32.cpp @@ -968,6 +968,40 @@ byte *CelObjPic::getResPointer() const { #pragma mark - #pragma mark CelObjMem +void CelObjMem::buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap) { + const uint16 bitmapHeaderSize = getBitmapHeaderSize(); + + WRITE_SCI11ENDIAN_UINT16(bitmap + 0, width); + WRITE_SCI11ENDIAN_UINT16(bitmap + 2, height); + WRITE_SCI11ENDIAN_UINT16(bitmap + 4, (uint16)displaceX); + WRITE_SCI11ENDIAN_UINT16(bitmap + 6, (uint16)displaceY); + bitmap[8] = skipColor; + bitmap[9] = 0; + WRITE_SCI11ENDIAN_UINT16(bitmap + 10, 0); + + if (useRemap) { + bitmap[10] |= 2; + } + + WRITE_SCI11ENDIAN_UINT32(bitmap + 12, width * height); + WRITE_SCI11ENDIAN_UINT32(bitmap + 16, 0); + + if (hunkPaletteOffset) { + WRITE_SCI11ENDIAN_UINT32(bitmap + 20, hunkPaletteOffset + bitmapHeaderSize); + } else { + WRITE_SCI11ENDIAN_UINT32(bitmap + 20, 0); + } + + WRITE_SCI11ENDIAN_UINT32(bitmap + 24, bitmapHeaderSize); + WRITE_SCI11ENDIAN_UINT32(bitmap + 28, bitmapHeaderSize); + WRITE_SCI11ENDIAN_UINT32(bitmap + 32, 0); + + if (bitmapHeaderSize >= 40) { + WRITE_SCI11ENDIAN_UINT16(bitmap + 36, scaledWidth); + WRITE_SCI11ENDIAN_UINT16(bitmap + 38, scaledHeight); + } +} + CelObjMem::CelObjMem(const reg_t bitmap) { _info.type = kCelTypeMem; _info.bitmap = bitmap; @@ -976,8 +1010,9 @@ CelObjMem::CelObjMem(const reg_t bitmap) { _celHeaderOffset = 0; _transparent = true; + const uint32 bitmapHeaderSize = getBitmapHeaderSize(); byte *bitmapData = g_sci->getEngineState()->_segMan->getHunkPointer(bitmap); - if (bitmapData == nullptr || READ_SCI11ENDIAN_UINT32(bitmapData + 28) != 46) { + if (bitmapData == nullptr || READ_SCI11ENDIAN_UINT32(bitmapData + 28) != bitmapHeaderSize) { error("Invalid Text bitmap %04x:%04x", PRINT_REG(bitmap)); } @@ -986,8 +1021,12 @@ CelObjMem::CelObjMem(const reg_t bitmap) { _displace.x = READ_SCI11ENDIAN_UINT16(bitmapData + 4); _displace.y = READ_SCI11ENDIAN_UINT16(bitmapData + 6); _transparentColor = bitmapData[8]; - _scaledWidth = READ_SCI11ENDIAN_UINT16(bitmapData + 36); - _scaledHeight = READ_SCI11ENDIAN_UINT16(bitmapData + 38); + if (bitmapHeaderSize >= 40) { + _scaledWidth = READ_SCI11ENDIAN_UINT16(bitmapData + 36); + _scaledHeight = READ_SCI11ENDIAN_UINT16(bitmapData + 38); + } else { + error("TODO: SCI2 bitmaps not implemented yet!"); + } _hunkPaletteOffset = READ_SCI11ENDIAN_UINT16(bitmapData + 20); _remap = (READ_SCI11ENDIAN_UINT16(bitmapData + 10) & 2) ? true : false; } diff --git a/engines/sci/graphics/celobj32.h b/engines/sci/graphics/celobj32.h index 1422b76a57..5707333818 100644 --- a/engines/sci/graphics/celobj32.h +++ b/engines/sci/graphics/celobj32.h @@ -547,6 +547,34 @@ public: */ class CelObjMem : public CelObj { public: + /** + * Writes a bitmap header to the given data buffer. + */ + static void buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap); + + /** + * Gets the size of the bitmap header for the current + * engine version. + */ + inline static uint32 getBitmapHeaderSize() { + // TODO: These values are accurate for each engine, but there may be no reason + // to not simply just always use size 40, since SCI2.1mid does not seem to + // actually store any data above byte 40, and SCI2 did not allow bitmaps with + // scaling resolutions other than the default (320x200). Perhaps SCI3 used + // the extra bytes, or there is some reason why they tried to align the header + // size with other headers like pic headers? +// uint32 bitmapHeaderSize; +// if (getSciVersion() >= SCI_VERSION_2_1_MIDDLE) { +// bitmapHeaderSize = 46; +// } else if (getSciVersion() == SCI_VERSION_2_1_EARLY) { +// bitmapHeaderSize = 40; +// } else { +// bitmapHeaderSize = 36; +// } +// return bitmapHeaderSize; + return 46; + } + CelObjMem(reg_t bitmap); virtual ~CelObjMem() override {}; diff --git a/engines/sci/graphics/text32.cpp b/engines/sci/graphics/text32.cpp index d7738b22c9..ca132d8b11 100644 --- a/engines/sci/graphics/text32.cpp +++ b/engines/sci/graphics/text32.cpp @@ -29,6 +29,7 @@ #include "sci/engine/selector.h" #include "sci/engine/state.h" #include "sci/graphics/cache.h" +#include "sci/graphics/celobj32.h" #include "sci/graphics/compare.h" #include "sci/graphics/font.h" #include "sci/graphics/frameout.h" @@ -59,37 +60,6 @@ GfxText32::GfxText32(SegManager *segMan, GfxCache *fonts, GfxScreen *screen) : _font = _cache->getFont(_defaultFontId); } -#define BITMAP_HEADER_SIZE 46 -void GfxText32::buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap) const { - - WRITE_SCI11ENDIAN_UINT16(bitmap + 0, width); - WRITE_SCI11ENDIAN_UINT16(bitmap + 2, height); - WRITE_SCI11ENDIAN_UINT16(bitmap + 4, (uint16)displaceX); - WRITE_SCI11ENDIAN_UINT16(bitmap + 6, (uint16)displaceY); - bitmap[8] = skipColor; - bitmap[9] = 0; - WRITE_SCI11ENDIAN_UINT16(bitmap + 10, 0); - - if (useRemap) { - bitmap[10] |= 2; - } - - WRITE_SCI11ENDIAN_UINT32(bitmap + 12, width * height); - WRITE_SCI11ENDIAN_UINT32(bitmap + 16, 0); - - if (hunkPaletteOffset) { - WRITE_SCI11ENDIAN_UINT32(bitmap + 20, hunkPaletteOffset + BITMAP_HEADER_SIZE); - } else { - WRITE_SCI11ENDIAN_UINT32(bitmap + 20, 0); - } - - WRITE_SCI11ENDIAN_UINT32(bitmap + 24, BITMAP_HEADER_SIZE); - WRITE_SCI11ENDIAN_UINT32(bitmap + 28, BITMAP_HEADER_SIZE); - WRITE_SCI11ENDIAN_UINT32(bitmap + 32, 0); - WRITE_SCI11ENDIAN_UINT16(bitmap + 36, scaledWidth); - WRITE_SCI11ENDIAN_UINT16(bitmap + 38, scaledHeight); -} - reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect &rect, const Common::String &text, const uint8 foreColor, const uint8 backColor, const uint8 skipColor, const GuiResourceId fontId, const TextAlign alignment, const int16 borderColor, const bool dimmed, const bool doScaling, reg_t *outBitmapObject) { _field_22 = 0; @@ -128,10 +98,10 @@ reg_t GfxText32::createFontBitmap(int16 width, int16 height, const Common::Rect _textRect = Common::Rect(); } - _bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + BITMAP_HEADER_SIZE); + _bitmap = _segMan->allocateHunkEntry("FontBitmap()", _width * _height + CelObjMem::getBitmapHeaderSize()); byte *bitmap = _segMan->getHunkPointer(_bitmap); - buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false); + CelObjMem::buildBitmapHeader(bitmap, _width, _height, _skipColor, 0, 0, _scaledWidth, _scaledHeight, 0, false); erase(bitmapRect, false); @@ -526,10 +496,6 @@ void GfxText32::erase(const Common::Rect &rect, const bool doScaling) { buffer.fillRect(targetRect, _backColor); } -void GfxText32::disposeTextBitmap(reg_t hunkId) { - _segMan->freeHunkEntry(hunkId); -} - int16 GfxText32::getStringWidth(const Common::String &text) { // TODO: The fact that this double-scales the text makes it // seem pretty unlikely that this is ever called in real life diff --git a/engines/sci/graphics/text32.h b/engines/sci/graphics/text32.h index f9a302a65c..d95792aa8d 100644 --- a/engines/sci/graphics/text32.h +++ b/engines/sci/graphics/text32.h @@ -132,11 +132,6 @@ private: */ Common::Point _drawPosition; - // TODO: This is general for all CelObjMem and should be - // put in a single location, like maybe as a static - // method of CelObjMem?! - void buildBitmapHeader(byte *bitmap, const int16 width, const int16 height, const uint8 skipColor, const int16 displaceX, const int16 displaceY, const int16 scaledWidth, const int16 scaledHeight, const uint32 hunkPaletteOffset, const bool useRemap) const; - void drawFrame(const Common::Rect &rect, const int16 size, const uint8 color, const bool doScaling); void drawTextBox(); void erase(const Common::Rect &rect, const bool doScaling); |