diff options
author | Eugene Sandulenko | 2008-05-24 22:11:41 +0000 |
---|---|---|
committer | Eugene Sandulenko | 2008-05-24 22:11:41 +0000 |
commit | f2d72d9473be5dd3d942976e8ed84d58d746def9 (patch) | |
tree | 3ed192e94ea18c91fe08f01d420dbcff55550eea | |
parent | 0147dd10dccd19ba140ccc11acff596369025ff0 (diff) | |
download | scummvm-rg350-f2d72d9473be5dd3d942976e8ed84d58d746def9.tar.gz scummvm-rg350-f2d72d9473be5dd3d942976e8ed84d58d746def9.tar.bz2 scummvm-rg350-f2d72d9473be5dd3d942976e8ed84d58d746def9.zip |
Patch #1969189: "CinE renderer rewrite"
svn-id: r32257
-rw-r--r-- | engines/cine/anim.cpp | 1 | ||||
-rw-r--r-- | engines/cine/bg.cpp | 96 | ||||
-rw-r--r-- | engines/cine/bg.h | 15 | ||||
-rw-r--r-- | engines/cine/bg_list.cpp | 60 | ||||
-rw-r--r-- | engines/cine/bg_list.h | 4 | ||||
-rw-r--r-- | engines/cine/cine.cpp | 12 | ||||
-rw-r--r-- | engines/cine/gfx.cpp | 1396 | ||||
-rw-r--r-- | engines/cine/gfx.h | 158 | ||||
-rw-r--r-- | engines/cine/main_loop.cpp | 16 | ||||
-rw-r--r-- | engines/cine/object.cpp | 4 | ||||
-rw-r--r-- | engines/cine/pal.cpp | 62 | ||||
-rw-r--r-- | engines/cine/pal.h | 8 | ||||
-rw-r--r-- | engines/cine/prc.cpp | 4 | ||||
-rw-r--r-- | engines/cine/rel.cpp | 4 | ||||
-rw-r--r-- | engines/cine/script.h | 3 | ||||
-rw-r--r-- | engines/cine/script_fw.cpp | 67 | ||||
-rw-r--r-- | engines/cine/script_os.cpp | 50 | ||||
-rw-r--r-- | engines/cine/texte.cpp | 92 | ||||
-rw-r--r-- | engines/cine/texte.h | 2 | ||||
-rw-r--r-- | engines/cine/various.cpp | 833 | ||||
-rw-r--r-- | engines/cine/various.h | 16 | ||||
-rw-r--r-- | engines/cine/xref.txt | 37 |
22 files changed, 1743 insertions, 1197 deletions
diff --git a/engines/cine/anim.cpp b/engines/cine/anim.cpp index 6edc714da7..73837308ca 100644 --- a/engines/cine/anim.cpp +++ b/engines/cine/anim.cpp @@ -53,6 +53,7 @@ AnimData animDataTable[NUM_MAX_ANIMDATA]; static const AnimDataEntry transparencyData[] = { {"ALPHA", 0xF}, + {"TITRE", 0xF}, {"TITRE2", 0xF}, {"ET", 0xC}, {"L311", 0x3}, diff --git a/engines/cine/bg.cpp b/engines/cine/bg.cpp index b6c07a05cb..c5b7fb4e3d 100644 --- a/engines/cine/bg.cpp +++ b/engines/cine/bg.cpp @@ -37,7 +37,7 @@ uint16 bgVar0; byte *additionalBgTable[9]; byte currentAdditionalBgIdx = 0, currentAdditionalBgIdx2 = 0; -byte loadCt(const char *ctName) { +byte loadCtFW(const char *ctName) { uint16 header[32]; byte *ptr, *dataPtr; @@ -46,79 +46,62 @@ byte loadCt(const char *ctName) { ptr = dataPtr = readBundleFile(findFileInBundle(ctName)); - if (g_cine->getGameType() == Cine::GType_OS) { - uint16 bpp = READ_BE_UINT16(ptr); ptr += 2; - if (bpp == 8) { - ctColorMode = 1; - memcpy(newPalette, ptr, 256 * 3); - ptr += 3 * 256; - memcpy(page3Raw, ptr, 320 * 200); - } else { - ctColorMode = 0; - for (int i = 0; i < 16; i++) { - tempPalette[i] = READ_BE_UINT16(ptr); - ptr += 2; - } - - gfxResetRawPage(page3Raw); - gfxConvertSpriteToRaw(page3Raw, ptr, 160, 200); - } - } else { - loadRelatedPalette(ctName); + loadRelatedPalette(ctName); - assert(strstr(ctName, ".NEO")); + assert(strstr(ctName, ".NEO")); - Common::MemoryReadStream readS(ptr, 32); - - for (int i = 0; i < 16; i++) { - header[i] = readS.readUint16BE(); - } + Common::MemoryReadStream readS(ptr, 32); - gfxConvertSpriteToRaw(page3Raw, ptr + 0x80, 160, 200); + for (int i = 0; i < 16; i++) { + header[i] = readS.readUint16BE(); } + gfxConvertSpriteToRaw(page3Raw, ptr + 0x80, 160, 200); + free(dataPtr); return 0; } -void loadBgHigh(const char *currentPtr) { - memcpy(newPalette, currentPtr, 256 * 3); - currentPtr += 256 * 3; +byte loadCtOS(const char *ctName) { + byte *ptr, *dataPtr; - memcpy(page2Raw, currentPtr, 320 * 200); + if (currentCtName != ctName) + strcpy(currentCtName, ctName); + + ptr = dataPtr = readBundleFile(findFileInBundle(ctName)); - newColorMode = 2; - bgColorMode = 1; + uint16 bpp = READ_BE_UINT16(ptr); + ptr += 2; + + if (bpp == 8) { + memcpy(page3Raw, ptr + 256 * 3, 320 * 200); + renderer->loadCt256(ptr, ctName); + } else { + gfxConvertSpriteToRaw(page3Raw, ptr + 32, 160, 200); + renderer->loadCt16(ptr, ctName); + } + free(dataPtr); + return 0; } byte loadBg(const char *bgName) { byte *ptr, *dataPtr; - if (currentBgName[0] != bgName) - strcpy(currentBgName[0], bgName); - byte fileIdx = findFileInBundle(bgName); ptr = dataPtr = readBundleFile(fileIdx); - uint16 bpp = READ_BE_UINT16(ptr); ptr += 2; + uint16 bpp = READ_BE_UINT16(ptr); + ptr += 2; + if (bpp == 8) { - loadBgHigh((const char *)ptr); + renderer->loadBg256(ptr, bgName); } else { - newColorMode = 1; - bgColorMode = 0; - - for (int i = 0; i < 16; i++) { - tempPalette[i] = READ_BE_UINT16(ptr); - ptr += 2; - } - if (g_cine->getGameType() == Cine::GType_FW) { loadRelatedPalette(bgName); } - gfxResetRawPage(page2Raw); - gfxConvertSpriteToRaw(page2Raw, ptr, 160, 200); + renderer->loadBg16(ptr, bgName); } free(dataPtr); return 0; @@ -127,28 +110,15 @@ byte loadBg(const char *bgName) { void addBackground(const char *bgName, uint16 bgIdx) { byte *ptr, *dataPtr; - strcpy(currentBgName[bgIdx], bgName); - byte fileIdx = findFileInBundle(bgName); ptr = dataPtr = readBundleFile(fileIdx); - additionalBgTable[bgIdx] = (byte *) malloc(320 * 200); - uint16 bpp = READ_BE_UINT16(ptr); ptr += 2; if (bpp == 8) { - bgColorMode = 1; - memcpy(newPalette, ptr, 256 * 3); - ptr += 3 * 256; - memcpy(additionalBgTable[bgIdx], ptr, 320 * 200); + renderer->loadBg256(ptr, bgName, bgIdx); } else { - bgColorMode = 0; - for (int i = 0; i < 16; i++) { - tempPalette[i] = READ_BE_UINT16(ptr); - ptr += 2; - } - - gfxConvertSpriteToRaw(additionalBgTable[bgIdx], ptr, 160, 200); + renderer->loadBg16(ptr, bgName, bgIdx); } free(dataPtr); } diff --git a/engines/cine/bg.h b/engines/cine/bg.h index ca5c222131..5fa8209131 100644 --- a/engines/cine/bg.h +++ b/engines/cine/bg.h @@ -27,20 +27,9 @@ #define CINE_BG_H namespace Cine { -struct bgData { - byte *data; - byte colorMode; - byte *highPalette; - uint16 *lowPalette; -}; - byte loadBg(const char *bgName); -byte loadCt(const char *bgName); - -//extern bgData additionalBgTable[9]; -extern byte *additionalBgTable[9]; -extern byte currentAdditionalBgIdx; -extern byte currentAdditionalBgIdx2; +byte loadCtFW(const char *bgName); +byte loadCtOS(const char *bgName); void addBackground(const char *bgName, uint16 bgIdx); diff --git a/engines/cine/bg_list.cpp b/engines/cine/bg_list.cpp index a70733dc68..cf25f1d355 100644 --- a/engines/cine/bg_list.cpp +++ b/engines/cine/bg_list.cpp @@ -40,62 +40,20 @@ Common::List<BGIncrust> bgIncrustList; /*! \brief Add masked sprite to the background * \param objIdx Sprite description - * \param addList Add sprite to incrust list if true - * \todo Fix incrust objects on CT background. Always drawing incrust elements - * on CT background breaks game zones */ -void addToBGList(int16 objIdx, bool addList) { - int16 x = objectTable[objIdx].x; - int16 y = objectTable[objIdx].y; - int16 width = animDataTable[objectTable[objIdx].frame]._var1; - int16 height = animDataTable[objectTable[objIdx].frame]._height; - const byte *data = animDataTable[objectTable[objIdx].frame].data(); - const byte *mask = animDataTable[objectTable[objIdx].frame].mask(); -// int16 part = objectTable[objIdx].part; - - // Operation Stealth may switch among multiple backgrounds - if (g_cine->getGameType() == GType_OS) { - for (int i = 0; i < 8; i++) { - if (additionalBgTable[i]) { - drawSpriteRaw2(data, objectTable[objIdx].part, width, height, additionalBgTable[i], x, y); - } - } - } else { - drawSpriteRaw(data, mask, width, height, page2Raw, x, y); - } +void addToBGList(int16 objIdx) { + renderer->incrustSprite(objectTable[objIdx]); - if (addList) - createBgIncrustListElement(objIdx, 0); + createBgIncrustListElement(objIdx, 0); } /*! \brief Add filled sprite to the background * \param objIdx Sprite description - * \param addList Add sprite to incrust list if true - * \todo Fix incrust objects on CT background. Always drawing incrust elements - * on CT background breaks game zones */ -void addSpriteFilledToBGList(int16 objIdx, bool addList) { - int16 x = objectTable[objIdx].x; - int16 y = objectTable[objIdx].y; - int16 width = animDataTable[objectTable[objIdx].frame]._realWidth; - int16 height = animDataTable[objectTable[objIdx].frame]._height; - const byte *data = animDataTable[objectTable[objIdx].frame].data(); - - if (data) { - // Operation Stealth may switch among multiple backgrounds - if (g_cine->getGameType() == GType_OS) { - for (int i = 0; i < 8; i++) { - if (additionalBgTable[i]) { - gfxFillSprite(data, width, height, additionalBgTable[i], x, y); - } - } - } else { - gfxFillSprite(data, width, height, page2Raw, x, y); - } - } +void addSpriteFilledToBGList(int16 objIdx) { + renderer->incrustMask(objectTable[objIdx]); - if (addList) - createBgIncrustListElement(objIdx, 1); + createBgIncrustListElement(objIdx, 1); } /*! \brief Add new element to incrust list @@ -115,7 +73,7 @@ void createBgIncrustListElement(int16 objIdx, int16 param) { bgIncrustList.push_back(tmp); } -/*! \brief Reset var8 (probably something related to bgIncrustList +/*! \brief Reset var8 (probably something related to bgIncrustList) */ void resetBgIncrustList(void) { var8 = 0; @@ -142,9 +100,9 @@ void loadBgIncrustFromSave(Common::InSaveFile &fHandle) { bgIncrustList.push_back(tmp); if (tmp.param == 0) { - addToBGList(tmp.objIdx, false); + renderer->incrustSprite(objectTable[tmp.objIdx]); } else { - addSpriteFilledToBGList(tmp.objIdx, false); + renderer->incrustMask(objectTable[tmp.objIdx]); } } } diff --git a/engines/cine/bg_list.h b/engines/cine/bg_list.h index 9ceae0acf5..1849d6ec3d 100644 --- a/engines/cine/bg_list.h +++ b/engines/cine/bg_list.h @@ -46,8 +46,8 @@ struct BGIncrust { extern Common::List<BGIncrust> bgIncrustList; extern uint32 var8; -void addToBGList(int16 objIdx, bool addList = true); -void addSpriteFilledToBGList(int16 idx, bool addList = true); +void addToBGList(int16 objIdx); +void addSpriteFilledToBGList(int16 idx); void createBgIncrustListElement(int16 objIdx, int16 param); void resetBgIncrustList(void); diff --git a/engines/cine/cine.cpp b/engines/cine/cine.cpp index 41dd9be16f..efc33fadaf 100644 --- a/engines/cine/cine.cpp +++ b/engines/cine/cine.cpp @@ -95,7 +95,9 @@ int CineEngine::init() { int CineEngine::go() { CursorMan.showMouse(true); mainLoop(1); - gfxDestroy(); + + delete renderer; + delete[] page3Raw; delete g_sound; return 0; } @@ -105,8 +107,14 @@ void CineEngine::initialize() { setupOpcodes(); initLanguage(g_cine->getLanguage()); - gfxInit(); + if (g_cine->getGameType() == Cine::GType_OS) { + renderer = new OSRenderer; + } else { + renderer = new FWRenderer; + } + + page3Raw = new byte[320 * 200]; textDataPtr = (byte *)malloc(8000); partBuffer = (PartBuffer *)malloc(NUM_MAX_PARTDATA * sizeof(PartBuffer)); diff --git a/engines/cine/gfx.cpp b/engines/cine/gfx.cpp index 2730a92e62..e20dd46c53 100644 --- a/engines/cine/gfx.cpp +++ b/engines/cine/gfx.cpp @@ -27,6 +27,7 @@ #include "cine/bg.h" #include "cine/bg_list.h" #include "cine/various.h" +#include "cine/pal.h" #include "common/endian.h" #include "common/system.h" @@ -35,18 +36,8 @@ namespace Cine { -uint16 c_palette[256]; -byte colorMode256 = 0; -byte palette256[256 * 3]; -byte newPalette[256 * 3]; -byte newColorMode = 0; -byte ctColorMode = 0; -byte bgColorMode = 0; - -byte *screenBuffer; -byte *page1Raw; -byte *page2Raw; byte *page3Raw; +FWRenderer *renderer = NULL; static const byte mouseCursorNormal[] = { 0x00, 0x00, 0x40, 0x00, 0x60, 0x00, 0x70, 0x00, @@ -96,28 +87,1189 @@ static const byte cursorPalette[] = { 0xff, 0xff, 0xff, 0xff }; -void gfxInit() { - screenBuffer = (byte *)malloc(320 * 200); - page1Raw = (byte *)malloc(320 * 200); - page2Raw = (byte *)malloc(320 * 200); - page3Raw = (byte *)malloc(320 * 200); - if (!screenBuffer || !page1Raw || !page2Raw || !page3Raw) { - error("Unable to allocate offscreen buffers"); +/*! \brief Initialize renderer + */ +FWRenderer::FWRenderer() : _background(NULL), _palette(NULL), _cmd(""), + _cmdY(0), _messageBg(0), _backBuffer(new byte[_screenSize]), + _activeLowPal(NULL), _changePal(0) { + + assert(_backBuffer); + + memset(_backBuffer, 0, _screenSize); + memset(_bgName, 0, sizeof (_bgName)); +} + +/* \brief Destroy renderer + */ +FWRenderer::~FWRenderer() { + delete[] _background; + delete[] _palette; + delete[] _backBuffer; + delete[] _activeLowPal; +} + +/* \brief Reset renderer state + */ +void FWRenderer::clear() { + delete[] _background; + delete[] _palette; + delete[] _activeLowPal; + + _background = NULL; + _palette = NULL; + _activeLowPal = NULL; + + memset(_backBuffer, 0, _screenSize); + + _cmd = ""; + _cmdY = 0; + _messageBg = 0; + _changePal = 0; +} + +/*! \brief Draw 1bpp sprite using selected color + * \param obj Object info + * \param fillColor Sprite color + */ +void FWRenderer::fillSprite(const objectStruct &obj, uint8 color) { + const byte *data = animDataTable[obj.frame].data(); + int x, y, width, height; + + x = obj.x; + y = obj.y; + width = animDataTable[obj.frame]._realWidth; + height = animDataTable[obj.frame]._height; + + gfxFillSprite(data, width, height, _backBuffer, x, y, color); +} + +/*! \brief Draw 1bpp sprite using selected color on background + * \param obj Object info + * \param fillColor Sprite color + */ +void FWRenderer::incrustMask(const objectStruct &obj, uint8 color) { + const byte *data = animDataTable[obj.frame].data(); + int x, y, width, height; + + x = obj.x; + y = obj.y; + width = animDataTable[obj.frame]._realWidth; + height = animDataTable[obj.frame]._height; + + gfxFillSprite(data, width, height, _background, x, y, color); +} + +/*! \brief Draw color sprite using with external mask + * \param obj Object info + * \param mask External mask + */ +void FWRenderer::drawMaskedSprite(const objectStruct &obj, const byte *mask) { + const byte *data = animDataTable[obj.frame].data(); + int x, y, width, height; + + x = obj.x; + y = obj.y; + width = animDataTable[obj.frame]._realWidth; + height = animDataTable[obj.frame]._height; + + assert(mask); + + drawSpriteRaw(data, mask, width, height, _backBuffer, x, y); +} + +/*! \brief Draw color sprite + * \param obj Object info + */ +void FWRenderer::drawSprite(const objectStruct &obj) { + const byte *mask = animDataTable[obj.frame].mask(); + drawMaskedSprite(obj, mask); +} + +/*! \brief Draw color sprite on background + * \param obj Object info + */ +void FWRenderer::incrustSprite(const objectStruct &obj) { + const byte *data = animDataTable[obj.frame].data(); + const byte *mask = animDataTable[obj.frame].mask(); + int x, y, width, height; + + x = obj.x; + y = obj.y; + width = animDataTable[obj.frame]._realWidth; + height = animDataTable[obj.frame]._height; + + assert(mask); + + drawSpriteRaw(data, mask, width, height, _background, x, y); +} + +/*! \brief Draw command box on screen + */ +void FWRenderer::drawCommand() { + unsigned int i; + int x = 10, y = _cmdY; + + drawPlainBox(x, y, 301, 11, 0); + drawBorder(x - 1, y - 1, 302, 12, 2); + + x += 2; + y += 2; + + for (i = 0; i < _cmd.size(); i++) { + x = drawChar(_cmd[i], x, y); + } +} + +/*! \brief Draw message in a box + * \param str Message to draw + * \param x Top left message box corner coordinate + * \param y Top left message box corner coordinate + * \param width Message box width + * \param color Message box background color + */ +void FWRenderer::drawMessage(const char *str, int x, int y, int width, byte color) { + int i, tx, ty, tw; + int line = 0, words = 0, cw = 0; + int space = 0, extraSpace = 0; + + drawPlainBox(x, y, width, 4, color); + tx = x + 4; + ty = str[0] ? y - 5 : y + 4; + tw = width - 8; + + for (i = 0; str[i]; i++, line--) { + // Fit line of text into textbox + if (!line) { + while (str[i] == ' ') i++; + line = fitLine(str + i, tw, words, cw); + + if ( str[i + line] != '\0' && str[i + line] != 0x7C && words) { + space = (tw - cw) / words; + extraSpace = (tw - cw) % words; + } else { + space = 5; + extraSpace = 0; + } + + ty += 9; + drawPlainBox(x, ty, width, 9, color); + tx = x + 4; + } + + // draw characters + if (str[i] == ' ') { + tx += space + extraSpace; + + if (extraSpace) { + extraSpace = 0; + } + } else { + tx = drawChar(str[i], tx, ty); + } + } + + ty += 9; + drawPlainBox(x, ty, width, 4, color); + drawDoubleBorder(x, y, width, ty - y + 4, 2); +} + +/*! \brief Draw rectangle on screen + * \param x Top left corner coordinate + * \param y Top left corner coordinate + * \param width Rectangle width + * \param height Rectangle height + * \param color Fill color + */ +void FWRenderer::drawPlainBox(int x, int y, int width, int height, byte color) { + int i; + byte *dest = _backBuffer + y * 320 + x; + + if (width < 0) { + x += width; + width = -width; + } + + if (height < 0) { + y += height; + height = -height; + } + + for (i = 0; i < height; i++) { + memset(dest + i * 320, color, width); + } +} + +/*! \brief Draw empty rectangle + * \param x Top left corner coordinate + * \param y Top left corner coordinate + * \param width Rectangle width + * \param height Rectangle height + * \param color Line color + */ +void FWRenderer::drawBorder(int x, int y, int width, int height, byte color) { + drawLine(x, y, width, 1, color); + drawLine(x, y + height, width, 1, color); + drawLine(x, y, 1, height, color); + drawLine(x + width, y, 1, height + 1, color); +} + +/*! \brief Draw empty 2 color rectangle (inner line color is black) + * \param x Top left corner coordinate + * \param y Top left corner coordinate + * \param width Rectangle width + * \param height Rectangle height + * \param color Outter line color + */ +void FWRenderer::drawDoubleBorder(int x, int y, int width, int height, byte color) { + drawBorder(x + 1, y + 1, width - 2, height - 2, 0); + drawBorder(x, y, width, height, color); +} + +/*! \brief Draw text character on screen + * \param character Character to draw + * \param x Character coordinate + * \param y Character coordinate + */ +int FWRenderer::drawChar(char character, int x, int y) { + int width, idx; + + if (character == ' ') { + x += 5; + } else if ((width = fontParamTable[character].characterWidth)) { + idx = fontParamTable[character].characterIdx; + drawSpriteRaw(textTable[idx][0], textTable[idx][1], 16, 8, _backBuffer, x, y); + x += width + 1; + } + + return x; +} + +/*! \brief Draw Line + * \param x Line end coordinate + * \param y Line end coordinate + * \param width Horizontal line length + * \param height Vertical line length + * \param color Line color + * \note Either width or height must be equal to 1 + */ +void FWRenderer::drawLine(int x, int y, int width, int height, byte color) { + // this line is a special case of rectangle ;-) + drawPlainBox(x, y, width, height, color); +} + +/*! \brief Hide invisible parts of the sprite + * \param[in,out] mask Mask to be updated + * \param it Overlay info from overlayList + */ +void FWRenderer::remaskSprite(byte *mask, Common::List<overlay>::iterator it) { + AnimData &sprite = animDataTable[objectTable[it->objIdx].frame]; + int x, y, width, height, idx; + int mx, my, mw, mh; + + x = objectTable[it->objIdx].x; + y = objectTable[it->objIdx].y; + width = sprite._realWidth; + height = sprite._height; + + for (++it; it != overlayList.end(); ++it) { + if (it->type != 5) { + continue; + } + + idx = ABS(objectTable[it->objIdx].frame); + mx = objectTable[it->objIdx].x; + my = objectTable[it->objIdx].y; + mw = animDataTable[idx]._realWidth; + mh = animDataTable[idx]._height; + + gfxUpdateSpriteMask(mask, x, y, width, height, animDataTable[idx].data(), mx, my, mw, mh); + } +} + +/*! \brief Draw background to backbuffer + */ +void FWRenderer::drawBackground() { + assert(_background); + memcpy(_backBuffer, _background, _screenSize); +} + +/*! \brief Draw one overlay + * \param it Overlay info + */ +void FWRenderer::renderOverlay(const Common::List<overlay>::iterator &it) { + int idx, len, width; + objectStruct *obj; + AnimData *sprite; + byte *mask; + + switch (it->type) { + // color sprite + case 0: + sprite = animDataTable + objectTable[it->objIdx].frame; + len = sprite->_realWidth * sprite->_height; + mask = new byte[len]; + memcpy(mask, sprite->mask(), len); + remaskSprite(mask, it); + drawMaskedSprite(objectTable[it->objIdx], mask); + delete[] mask; + break; + + // game message + case 2: + if (it->objIdx >= messageTable.size()) { + return; + } + + _messageLen += messageTable[it->objIdx].size(); + drawMessage(messageTable[it->objIdx].c_str(), it->x, it->y, it->width, it->color); + break; + + // action failure message + case 3: + idx = it->objIdx * 4 + g_cine->_rnd.getRandomNumber(3); + len = strlen(failureMessages[idx]); + _messageLen += len; + width = 6 * len + 20; + width = width > 300 ? 300 : width; + + drawMessage(failureMessages[idx], (320 - width) / 2, 80, width, 4); + break; + + // bitmap + case 4: + assert(it->objIdx < NUM_MAX_OBJECT); + obj = objectTable + it->objIdx; + + if (obj->frame < 0) { + return; + } + + if (!animDataTable[obj->frame].data()) { + return; + } + + fillSprite(*obj); + break; + } +} + +/*! \brief Draw overlays + */ +void FWRenderer::drawOverlays() { + Common::List<overlay>::iterator it; + + for (it = overlayList.begin(); it != overlayList.end(); ++it) { + renderOverlay(it); + } +} + +/*! \brief Draw another frame + */ +void FWRenderer::drawFrame() { + drawBackground(); + drawOverlays(); + + if (!_cmd.empty()) { + drawCommand(); + } + + if (_changePal) { + refreshPalette(); + } + + blit(); +} + +/*! \brief Update screen + */ +void FWRenderer::blit() { + g_system->copyRectToScreen(_backBuffer, 320, 0, 0, 320, 200); +} + +/*! \brief Set player command string + * \param cmd New command string + */ +void FWRenderer::setCommand(const char *cmd) { + _cmd = cmd; +} + +/*! \brief Refresh current palette + */ +void FWRenderer::refreshPalette() { + int i; + byte pal[16*4]; + + assert(_activeLowPal); + + for (i = 0; i < 16; i++) { + // This seems to match the output from DOSbox. + pal[i * 4 + 2] = ((_activeLowPal[i] & 0x00f) >> 0) * 32; + pal[i * 4 + 1] = ((_activeLowPal[i] & 0x0f0) >> 4) * 32; + pal[i * 4 + 0] = ((_activeLowPal[i] & 0xf00) >> 8) * 32; + pal[i * 4 + 3] = 0; + } + + g_system->setPalette(pal, 0, 16); + _changePal = 0; +} + +/*! \brief Load palette of current background + */ +void FWRenderer::reloadPalette() { + assert(_palette); + + if (!_activeLowPal) { + _activeLowPal = new uint16[_lowPalSize]; } - memset(page1Raw, 0, 320 * 200); - memset(page2Raw, 0, 320 * 200); - memset(page3Raw, 0, 320 * 200); - memset(additionalBgTable, 0, sizeof(additionalBgTable)); - additionalBgTable[0] = page2Raw; - additionalBgTable[8] = page3Raw; + assert(_activeLowPal); + + memcpy(_activeLowPal, _palette, _lowPalSize * sizeof (uint16)); + _changePal = 1; +} + +/*! \brief Load background into renderer + * \param bg Raw background data + */ +void FWRenderer::loadBg16(const byte *bg, const char *name) { + int i; + + if (!_background) { + _background = new byte[_screenSize]; + } + + if (!_palette) { + _palette = new uint16[_lowPalSize]; + } + + assert(_background && _palette); + + strcpy(_bgName, name); + + for (i = 0; i < _lowPalSize; i++, bg += 2) { + _palette[i] = READ_BE_UINT16(bg); + } + + gfxConvertSpriteToRaw(_background, bg, 160, 200); +} + +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::loadBg16(const byte *bg, const char *name, unsigned int idx) { + error("Future Wars renderer doesn't support multiple backgrounds"); +} + +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::loadCt16(const byte *ct, const char *name) { + error("Future Wars renderer doesn't support multiple backgrounds"); +} + +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::loadBg256(const byte *bg, const char *name) { + error("Future Wars renderer doesn't support 256 color mode"); +} + +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::loadBg256(const byte *bg, const char *name, unsigned int idx) { + error("Future Wars renderer doesn't support multiple backgrounds"); +} + +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::loadCt256(const byte *ct, const char *name) { + error("Future Wars renderer doesn't support multiple backgrounds"); +} + +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::selectBg(unsigned int idx) { + error("Future Wars renderer doesn't support multiple backgrounds"); } -void gfxDestroy() { - free(screenBuffer); - free(page1Raw); - free(page2Raw); - free(page3Raw); +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::selectScrollBg(unsigned int idx) { + error("Future Wars renderer doesn't support multiple backgrounds"); +} + +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::setScroll(unsigned int shift) { + error("Future Wars renderer doesn't support multiple backgrounds"); +} + +/*! \brief Placeholder for Operation Stealth implementation + */ +void FWRenderer::removeBg(unsigned int idx) { + error("Future Wars renderer doesn't support multiple backgrounds"); +} + +void FWRenderer::saveBg(Common::OutSaveFile &fHandle) { + fHandle.write(_bgName, 13); +} + +/*! \brief Restore active and backup palette from save + * \param fHandle Savefile open for reading + */ +void FWRenderer::restorePalette(Common::InSaveFile &fHandle) { + int i; + + if (!_palette) { + _palette = new uint16[_lowPalSize]; + } + + if (!_activeLowPal) { + _activeLowPal = new uint16[_lowPalSize]; + } + + assert(_palette && _activeLowPal); + + for (i = 0; i < _lowPalSize; i++) { + _activeLowPal[i] = fHandle.readUint16BE(); + } + + for (i = 0; i < _lowPalSize; i++) { + _palette[i] = fHandle.readUint16BE(); + } + + _changePal = 1; +} + +/*! \brief Write active and backup palette to save + * \param fHandle Savefile open for writing + */ +void FWRenderer::savePalette(Common::OutSaveFile &fHandle) { + int i; + + assert(_palette && _activeLowPal); + + for (i = 0; i < _lowPalSize; i++) { + fHandle.writeUint16BE(_activeLowPal[i]); + } + + for (i = 0; i < _lowPalSize; i++) { + fHandle.writeUint16BE(_palette[i]); + } +} + +/*! \brief Rotate active palette + * \param a First color to rotate + * \param b Last color to rotate + * \param c Possibly rotation step, must be equal to 1 at the moment + */ +void FWRenderer::rotatePalette(int a, int b, int c) { + palRotate(_activeLowPal, a, b, c); + refreshPalette(); +} + +/*! \brief Copy part of backup palette to active palette and transform + * \param first First color to transform + * \param last Last color to transform + * \param r Red channel transformation + * \param g Green channel transformation + * \param b Blue channel transformation + */ +void FWRenderer::transformPalette(int first, int last, int r, int g, int b) { + if (!_activeLowPal) { + _activeLowPal = new uint16[_lowPalSize]; + memset(_activeLowPal, 0, _lowPalSize * sizeof (uint16)); + } + + transformPaletteRange(_activeLowPal, _palette, first, last, r, g, b); + refreshPalette(); +} + +/*! \brief Draw menu box, one item per line with possible highlight + * \param items Menu items + * \param height Item count + * \param x Top left menu corner coordinate + * \param y Top left menu corner coordinate + * \param width Menu box width + * \param selected Index of highlighted item (no highlight if less than 0) + */ +void FWRenderer::drawMenu(const CommandeType *items, unsigned int height, int x, int y, int width, int selected) { + int tx, ty, th = height * 9 + 10; + unsigned int i, j; + + if (x + width > 319) { + x = 319 - width; + } + + if (y + th > 199) { + y = 199 - th; + } + + drawPlainBox(x, y, width, 4, _messageBg); + + ty = y + 4; + + for (i = 0; i < height; i++, ty += 9) { + drawPlainBox(x, ty, width, 9, (int)i == selected ? 0 : _messageBg); + tx = x + 4; + + for (j = 0; items[i][j]; j++) { + tx = drawChar(items[i][j], tx, ty); + } + } + + drawPlainBox(x, ty, width, 4, _messageBg); + drawDoubleBorder(x, y, width, ty - y + 4, 2); +} + +/*! \brief Draw text input box + * \param info Input box message + * \param input Text entered in the input area + * \param cursor Cursor position in the input area + * \param x Top left input box corner coordinate + * \param y Top left input box corner coordinate + * \param width Input box width + */ +void FWRenderer::drawInputBox(const char *info, const char *input, int cursor, int x, int y, int width) { + int i, tx, ty, tw; + int line = 0, words = 0, cw = 0; + int space = 0, extraSpace = 0; + + drawPlainBox(x, y, width, 4, _messageBg); + tx = x + 4; + ty = info[0] ? y - 5 : y + 4; + tw = width - 8; + + // input box info message + for (i = 0; info[i]; i++, line--) { + // fit line of text + if (!line) { + line = fitLine(info + i, tw, words, cw); + + if ( info[i + line] != '\0' && words) { + space = (tw - cw) / words; + extraSpace = (tw - cw) % words; + } else { + space = 5; + extraSpace = 0; + } + + ty += 9; + drawPlainBox(x, ty, width, 9, _messageBg); + tx = x + 4; + } + + // draw characters + if (info[i] == ' ') { + tx += space + extraSpace; + + if (extraSpace) { + extraSpace = 0; + } + } else { + tx = drawChar(info[i], tx, ty); + } + } + + // input area background + ty += 9; + drawPlainBox(x, ty, width, 9, _messageBg); + drawPlainBox(x + 16, ty - 1, width - 32, 9, 0); + tx = x + 20; + + // text in input area + for (i = 0; input[i]; i++) { + tx = drawChar(input[i], tx, ty); + + if (cursor == i + 2) { + drawLine(tx, ty - 1, 1, 9, 2); + } + } + + if (!input[0] || cursor == 1) { + drawLine(x + 20, ty - 1, 1, 9, 2); + } + + ty += 9; + drawPlainBox(x, ty, width, 4, _messageBg); + drawDoubleBorder(x, y, width, ty - y + 4, 2); +} + +/*! \brief Fade to black + */ +void FWRenderer::fadeToBlack() { + assert(_activeLowPal); + + for (int i = 0; i < 8; i++) { + for (int j = 0; j < 16; j++) { + _activeLowPal[j] = transformColor(_activeLowPal[j], -1, -1, -1); + } + + refreshPalette(); + g_system->updateScreen(); + g_system->delayMillis(50); + } +} + +/*! \brief Initialize Operation Stealth renderer + */ +OSRenderer::OSRenderer() : _activeHiPal(NULL), _currentBg(0), _scrollBg(0), + _bgShift(0) { + + int i; + for (i = 0; i < 9; i++) { + _bgTable[i].bg = NULL; + _bgTable[i].lowPal = NULL; + _bgTable[i].hiPal = NULL; + memset(_bgTable[i].name, 0, sizeof (_bgTable[i].name)); + } +} + +/*! \brief Destroy Operation Stealth renderer + */ +OSRenderer::~OSRenderer() { + delete[] _activeHiPal; + + for (int i = 0; i < 9; i++) { + delete[] _bgTable[i].bg; + delete[] _bgTable[i].lowPal; + delete[] _bgTable[i].hiPal; + } +} + +/*! \brief Reset Operation Stealth renderer state + */ +void OSRenderer::clear() { + delete[] _activeHiPal; + _activeHiPal = NULL; + + for (int i = 0; i < 9; i++) { + delete[] _bgTable[i].bg; + delete[] _bgTable[i].lowPal; + delete[] _bgTable[i].hiPal; + + _bgTable[i].bg = NULL; + _bgTable[i].lowPal = NULL; + _bgTable[i].hiPal = NULL; + memset(_bgTable[i].name, 0, sizeof (_bgTable[i].name)); + } + + _currentBg = 0; + _scrollBg = 0; + _bgShift = 0; + + FWRenderer::clear(); +} + +/*! \brief Draw 1bpp sprite using selected color on backgrounds + * \param obj Object info + * \param fillColor Sprite color + */ +void OSRenderer::incrustMask(const objectStruct &obj, uint8 color) { + const byte *data = animDataTable[obj.frame].data(); + int x, y, width, height, i; + + x = obj.x; + y = obj.y; + width = animDataTable[obj.frame]._realWidth; + height = animDataTable[obj.frame]._height; + + for (i = 0; i < 8; i++) { + if (!_bgTable[i].bg) { + continue; + } + + gfxFillSprite(data, width, height, _bgTable[i].bg, x, y, color); + } +} + +/*! \brief Draw color sprite + * \param obj Object info + */ +void OSRenderer::drawSprite(const objectStruct &obj) { + const byte *data = animDataTable[obj.frame].data(); + int x, y, width, height, transColor; + + x = obj.x; + y = obj.y; + transColor = obj.part; + width = animDataTable[obj.frame]._realWidth; + height = animDataTable[obj.frame]._height; + + drawSpriteRaw2(data, transColor, width, height, _backBuffer, x, y); +} + +/*! \brief Draw color sprite + * \param obj Object info + */ +void OSRenderer::incrustSprite(const objectStruct &obj) { + const byte *data = animDataTable[obj.frame].data(); + int x, y, width, height, transColor, i; + + x = obj.x; + y = obj.y; + transColor = obj.part; + width = animDataTable[obj.frame]._realWidth; + height = animDataTable[obj.frame]._height; + + for (i = 0; i < 8; i++) { + if (!_bgTable[i].bg) { + continue; + } + + drawSpriteRaw2(data, transColor, width, height, _bgTable[i].bg, x, y); + } +} + +/*! \brief Draw text character on screen + * \param character Character to draw + * \param x Character coordinate + * \param y Character coordinate + */ +int OSRenderer::drawChar(char character, int x, int y) { + int width, idx; + + if (character == ' ') { + x += 5; + } else if ((width = fontParamTable[character].characterWidth)) { + idx = fontParamTable[character].characterIdx; + drawSpriteRaw2(textTable[idx][0], 0, 16, 8, _backBuffer, x, y); + x += width + 1; + } + + return x; +} + +/*! \brief Draw background to backbuffer + */ +void OSRenderer::drawBackground() { + byte *main; + + main = _bgTable[_currentBg].bg; + assert(main); + + if (!_bgShift) { + memcpy(_backBuffer, main, _screenSize); + } else { + byte *scroll = _bgTable[_scrollBg].bg; + int mainShift = _bgShift * _screenWidth; + int mainSize = _screenSize - mainShift; + + assert(scroll); + + memcpy(_backBuffer, main + mainShift, mainSize); + memcpy(_backBuffer + mainSize, scroll, mainShift); + } +} + +/*! \brief Draw one overlay + * \param it Overlay info + */ +void OSRenderer::renderOverlay(const Common::List<overlay>::iterator &it) { + int len; + objectStruct *obj; + AnimData *sprite; + byte *mask; + + switch (it->type) { + // color sprite + case 0: + sprite = animDataTable + objectTable[it->objIdx].frame; + len = sprite->_realWidth * sprite->_height; + mask = new byte[len]; + generateMask(sprite->data(), mask, len, objectTable[it->objIdx].part); + remaskSprite(mask, it); + drawMaskedSprite(objectTable[it->objIdx], mask); + delete[] mask; + break; + + // masked background + case 20: + assert(it->objIdx < NUM_MAX_OBJECT); + obj = objectTable + it->objIdx; + sprite = animDataTable + obj->frame; + + if (obj->frame < 0 || it->x > 8 || !_bgTable[it->x].bg || sprite->_bpp != 1) { + break; + } + + maskBgOverlay(_bgTable[it->x].bg, sprite->data(), sprite->_realWidth, sprite->_height, _backBuffer, obj->x, obj->y); + break; + + // something else + default: + FWRenderer::renderOverlay(it); + break; + } +} + +/*! \brief Refresh current palette + */ +void OSRenderer::refreshPalette() { + if (!_activeHiPal) { + FWRenderer::refreshPalette(); + return; + } + + int i; + byte pal[256*4]; + + for (i = 0; i < 256; i++) { + pal[i * 4 + 0] = _activeHiPal[i * 3 + 0]; + pal[i * 4 + 1] = _activeHiPal[i * 3 + 1]; + pal[i * 4 + 2] = _activeHiPal[i * 3 + 2]; + pal[i * 4 + 3] = 0; + } + + g_system->setPalette(pal, 0, 256); + _changePal = 0; +} + +/*! \brief Load palette of current background + */ +void OSRenderer::reloadPalette() { + // selected background in plane takeoff scene has swapped colors 12 + // and 14, shift background has it right + palBg *bg = _bgShift ? &_bgTable[_scrollBg] : &_bgTable[_currentBg]; + + assert(bg->lowPal || bg->hiPal); + + if (bg->lowPal) { + if (!_activeLowPal) { + _activeLowPal = new uint16[_lowPalSize]; + } + + assert(_activeLowPal); + + delete[] _activeHiPal; + _activeHiPal = NULL; + + memcpy(_activeLowPal, bg->lowPal, _lowPalSize * sizeof (uint16)); + } else { + if (!_activeHiPal) { + _activeHiPal = new byte[_hiPalSize]; + } + + assert(_activeHiPal); + + delete[] _activeLowPal; + _activeLowPal = NULL; + + memcpy(_activeHiPal, bg->hiPal, _hiPalSize); + } + _changePal = 1; +} + +/*! \brief Rotate active palette + * \param a First color to rotate + * \param b Last color to rotate + * \param c Possibly rotation step, must be equal to 1 at the moment + */ +void OSRenderer::rotatePalette(int a, int b, int c) { + if (_activeLowPal) { + FWRenderer::rotatePalette(a, b, c); + return; + } + + palRotate(_activeHiPal, a, b, c); + refreshPalette(); +} + +/*! \brief Copy part of backup palette to active palette and transform + * \param first First color to transform + * \param last Last color to transform + * \param r Red channel transformation + * \param g Green channel transformation + * \param b Blue channel transformation + */ +void OSRenderer::transformPalette(int first, int last, int r, int g, int b) { + palBg *bg = _bgShift ? &_bgTable[_scrollBg] : &_bgTable[_currentBg]; + + if (!bg->lowPal) { + if (!_activeHiPal) { + _activeHiPal = new byte[_hiPalSize]; + memset(_activeHiPal, 0, _hiPalSize); + } + + delete[] _activeLowPal; + _activeLowPal = NULL; + + transformPaletteRange(_activeHiPal, bg->hiPal, first, last, r, g, b); + } else { + if (!_activeLowPal) { + _activeLowPal = new uint16[_lowPalSize]; + memset(_activeLowPal, 0, _lowPalSize * sizeof (uint16)); + } + + delete[] _activeHiPal; + _activeHiPal = NULL; + + transformPaletteRange(_activeLowPal, bg->lowPal, first, last, r, g, b); + } + + refreshPalette(); +} + +/*! \brief Load 16 color background into renderer + * \param bg Raw background data + * \param name Background filename + */ +void OSRenderer::loadBg16(const byte *bg, const char *name) { + loadBg16(bg, name, 0); +} + +/*! \brief Load 16 color background into renderer + * \param bg Raw background data + * \param name Background filename + * \param pos Background index + */ +void OSRenderer::loadBg16(const byte *bg, const char *name, unsigned int idx) { + int i; + assert(idx < 9); + + if (!_bgTable[idx].bg) { + _bgTable[idx].bg = new byte[_screenSize]; + } + + if (!_bgTable[idx].lowPal) { + _bgTable[idx].lowPal = new uint16[_lowPalSize]; + } + + assert(_bgTable[idx].bg && _bgTable[idx].lowPal); + + delete[] _bgTable[idx].hiPal; + _bgTable[idx].hiPal = NULL; + + strcpy(_bgTable[idx].name, name); + + for (i = 0; i < _lowPalSize; i++, bg += 2) { + _bgTable[idx].lowPal[i] = READ_BE_UINT16(bg); + } + + gfxConvertSpriteToRaw(_bgTable[idx].bg, bg, 160, 200); +} + +/*! \brief Load 16 color CT data as background into renderer + * \param ct Raw CT data + * \param name Background filename + */ +void OSRenderer::loadCt16(const byte *ct, const char *name) { + loadBg16(ct, name, 8); +} + +/*! \brief Load 256 color background into renderer + * \param bg Raw background data + * \param name Background filename + */ +void OSRenderer::loadBg256(const byte *bg, const char *name) { + loadBg256(bg, name, 0); +} + +/*! \brief Load 256 color background into renderer + * \param bg Raw background data + * \param name Background filename + * \param pos Background index + */ +void OSRenderer::loadBg256(const byte *bg, const char *name, unsigned int idx) { + assert(idx < 9); + + if (!_bgTable[idx].bg) { + _bgTable[idx].bg = new byte[_screenSize]; + } + + if (!_bgTable[idx].hiPal) { + _bgTable[idx].hiPal = new byte[_hiPalSize]; + } + + assert(_bgTable[idx].bg && _bgTable[idx].hiPal); + + delete[] _bgTable[idx].lowPal; + _bgTable[idx].lowPal = NULL; + + strcpy(_bgTable[idx].name, name); + memcpy(_bgTable[idx].hiPal, bg, _hiPalSize); + memcpy(_bgTable[idx].bg, bg + _hiPalSize, _screenSize); +} + +/*! \brief Load 256 color CT data as background into renderer + * \param ct Raw CT data + * \param name Background filename + */ +void OSRenderer::loadCt256(const byte *ct, const char *name) { + loadBg256(ct, name, 8); +} + +/*! \brief Select active background and load its palette + * \param idx Background index + */ +void OSRenderer::selectBg(unsigned int idx) { + assert(idx < 9 && _bgTable[idx].bg); + assert(_bgTable[idx].lowPal || _bgTable[idx].hiPal); + + _currentBg = idx; + reloadPalette(); +} + +/*! \brief Select scroll background + * \param idx Scroll background index + */ +void OSRenderer::selectScrollBg(unsigned int idx) { + assert(idx < 9); + + if (_bgTable[idx].bg) { + _scrollBg = idx; + } + reloadPalette(); +} + +/*! \brief Set background scroll + * \param shift Background scroll in pixels + */ +void OSRenderer::setScroll(unsigned int shift) { + assert(shift <= 200); + + _bgShift = shift; +} + +/*! \brief Unload background from renderer + * \param idx Background to unload + */ +void OSRenderer::removeBg(unsigned int idx) { + assert(idx > 0 && idx < 9); + + if (_currentBg == idx) { + _currentBg = 0; + } + + if (_scrollBg == idx) { + _scrollBg = 0; + } + + delete[] _bgTable[idx].bg; + delete[] _bgTable[idx].lowPal; + delete[] _bgTable[idx].hiPal; + _bgTable[idx].bg = NULL; + _bgTable[idx].lowPal = NULL; + _bgTable[idx].hiPal = NULL; + memset(_bgTable[idx].name, 0, sizeof (_bgTable[idx].name)); +} + +/*! \brief Fade to black + * \bug Operation Stealth sometimes seems to fade to black using + * transformPalette resulting in double fadeout + */ +void OSRenderer::fadeToBlack() { + if (!_activeHiPal) { + FWRenderer::fadeToBlack(); + return; + } + + for (int i = 0; i < 8; i++) { + for (int j = 0; j < _hiPalSize; j++) { + _activeHiPal[j] = CLIP(_activeHiPal[j] - 32, 0, 255); + } + + refreshPalette(); + g_system->updateScreen(); + g_system->delayMillis(50); + } } void setMouseCursor(int cursor) { @@ -147,21 +1299,6 @@ void setMouseCursor(int cursor) { } } -static uint16 transformColor(uint16 baseColor, int8 r, int8 g, int8 b) { - int8 oriR = CLIP( (baseColor & 0x007) + r, 0, 7); - int8 oriG = CLIP(((baseColor & 0x070) >> 4) + g, 0, 7); - int8 oriB = CLIP(((baseColor & 0x700) >> 8) + b, 0, 7); - - return oriR | (oriG << 4) | (oriB << 8); -} - -void transformPaletteRange(byte startColor, byte stopColor, int8 r, int8 g, int8 b) { - for (byte i = startColor; i <= stopColor; i++) { - c_palette[i] = transformColor(tempPalette[i], b, g, r); - } - //gfxFlipPage(page2); -} - void gfxFillSprite(const byte *spritePtr, uint16 width, uint16 height, byte *page, int16 x, int16 y, uint8 fillColor) { int16 i, j; @@ -170,17 +1307,12 @@ void gfxFillSprite(const byte *spritePtr, uint16 width, uint16 height, byte *pag destPtr += i * 320; for (j = 0; j < width; j++) { - if (x + j >= 0 && x + j < 320 && i + y >= 0 - && i + y < 200) { - if (!*(spritePtr++)) { - *(destPtr++) = fillColor; - } else { - destPtr++; - } - } else { - destPtr++; - spritePtr++; + if (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200 && !*spritePtr) { + *destPtr = fillColor; } + + destPtr++; + spritePtr++; } } } @@ -360,53 +1492,7 @@ void gfxConvertSpriteToRaw(byte *dst, const byte *src, uint16 w, uint16 h) { } } -void gfxCopyRawPage(byte *source, byte *dest) { - memcpy(dest, source, 320 * 200); -} - -void gfxFlipRawPage(byte *frontBuffer) { - byte *page = frontBuffer; - int x, y, i; - byte *pixels = (byte *) screenBuffer; - byte c; - byte pal[256 * 4]; - - for (y = 0; y < 200; y++) { - for (x = 0; x < 320; x++) { - c = *(page++); - - if (!colorMode256) { - c = c & 15; - } - - pixels[x + 0 + y * 320] = c; - } - } - - if (colorMode256) { - for (i = 0; i < 256; i++) { - pal[i * 4 + 0] = palette256[i * 3 + 0]; - pal[i * 4 + 1] = palette256[i * 3 + 1]; - pal[i * 4 + 2] = palette256[i * 3 + 2]; - pal[i * 4 + 3] = 0; - } - g_system->setPalette(pal, 0, 256); - } else { - for (i = 0; i < 16; i++) { - // This seems to match the output from DOSbox. - pal[i * 4 + 2] = ((c_palette[i] & 0x00f) >> 0) * 32; - pal[i * 4 + 1] = ((c_palette[i] & 0x0f0) >> 4) * 32; - pal[i * 4 + 0] = ((c_palette[i] & 0xf00) >> 8) * 32; - pal[i * 4 + 3] = 0; - } - g_system->setPalette(pal, 0, 16); - } - - g_system->copyRectToScreen(screenBuffer, 320, 0, 0, 320, 200); -} - -void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int16 height, - byte *page, int16 x, int16 y) { +void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int16 height, byte *page, int16 x, int16 y) { int16 i, j; // FIXME: Is it a bug if maskPtr == NULL? @@ -417,9 +1503,8 @@ void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int1 byte *destPtr = page + x + y * 320; destPtr += i * 320; - for (j = 0; j < width * 8; j++) { - if (((g_cine->getGameType() == Cine::GType_FW && (!maskPtr || !(*maskPtr))) || (g_cine->getGameType() == Cine::GType_OS)) && (x + j >= 0 - && x + j < 320 && i + y >= 0 && i + y < 200)) { + for (j = 0; j < width; j++) { + if ((!maskPtr || !(*maskPtr)) && x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200) { *(destPtr++) = *(spritePtr++); } else { destPtr++; @@ -432,21 +1517,19 @@ void drawSpriteRaw(const byte *spritePtr, const byte *maskPtr, int16 width, int1 } } -void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 height, - byte *page, int16 x, int16 y) { +void drawSpriteRaw2(const byte *spritePtr, byte transColor, int16 width, int16 height, byte *page, int16 x, int16 y) { int16 i, j; for (i = 0; i < height; i++) { byte *destPtr = page + x + y * 320; destPtr += i * 320; - for (j = 0; j < width * 8; j++) { - if ((*(spritePtr) != transColor) && (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200)) { - *(destPtr++) = *(spritePtr++); - } else { - destPtr++; - spritePtr++; + for (j = 0; j < width; j++) { + if ((*spritePtr != transColor) && (x + j >= 0 && x + j < 320 && i + y >= 0 && i + y < 200)) { + *destPtr = *spritePtr; } + destPtr++; + spritePtr++; } } } @@ -499,93 +1582,4 @@ void maskBgOverlay(const byte *bgPtr, const byte *maskPtr, int16 width, int16 he } } -/*! \todo Fix rendering to prevent fadein artifacts - */ -void fadeFromBlack() { - int i, j; - int r, g, b, tr, tg, tb; - if (newColorMode == 2) { - colorMode256 = 1; - memset(palette256, 0, 256*3); - } else if (newColorMode == 1) { - colorMode256 = 0; - memset(c_palette, 0, 16 * sizeof(uint16)); - } - - for (i = 0; i < 8; i++ ) { - gfxFlipRawPage(page1Raw); - g_system->updateScreen(); - g_system->delayMillis(50); - - if (colorMode256) { - for (j = 0; j < 256*3; j++) { - r = palette256[j] + (newPalette[j] + 7) / 8; - palette256[j] = CLIP(r, 0, (int)newPalette[j]); - } - } else { - for (j = 0; j < 16; j++) { - r = c_palette[j] & 0xf; - g = (c_palette[j] & 0xf0) >> 4; - b = (c_palette[j] & 0xf00) >> 8; - - tr = tempPalette[j] & 0xf; - tg = (tempPalette[j] & 0xf0) >> 4; - tb = (tempPalette[j] & 0xf00) >> 8; - - r = CLIP(r + (tr + 7) / 8, 0, tr); - g = CLIP(g + (tg + 7) / 8, 0, tg); - b = CLIP(b + (tb + 7) / 8, 0, tb); - - c_palette[j] = r | (g << 4) | (b << 8); - } - - } - } - - if (colorMode256) { - memcpy(palette256, newPalette, 256*3); - } else { - memcpy(c_palette, tempPalette, sizeof(uint16) * 16); - } -} - -void fadeToBlack() { - for (int i = 0; i < 8; i++) { - if (colorMode256) { - for (int j = 0; j < 256*3; j++) { - palette256[j] = CLIP(palette256[j] - 32, 0, 255); - } - } else { - for (int j = 0; j < 16; j++) { - c_palette[j] = transformColor(c_palette[j], -1, -1, -1); - } - } - gfxFlipRawPage(page1Raw); - g_system->updateScreen(); - g_system->delayMillis(50); - } -} - -void blitRawScreen(byte *frontBuffer) { - gfxFlipRawPage(frontBuffer); -} - -void flip(void) { - blitRawScreen(page1Raw); - if (fadeRequired) { - if (newColorMode == 3) { - newColorMode = ctColorMode + 1; - } - - if (newColorMode == 2) { - colorMode256 = 1; - memcpy(palette256, newPalette, 256*3); - } else { - colorMode256 = 0; - memcpy(c_palette, tempPalette, sizeof(uint16) * 16); - } - fadeRequired = false; - } -} - } // End of namespace Cine diff --git a/engines/cine/gfx.h b/engines/cine/gfx.h index 3812b52113..c63c79ac82 100644 --- a/engines/cine/gfx.h +++ b/engines/cine/gfx.h @@ -26,24 +26,158 @@ #ifndef CINE_GFX_H #define CINE_GFX_H +#include "common/noncopyable.h" +#include "cine/object.h" + namespace Cine { +/*! \brief Background with palette + */ +struct palBg { + byte *bg; ///< Background data + byte *hiPal; ///< 256 color palette + uint16 *lowPal; ///< 16 color palette + char name[15]; ///< Background filename +}; + +/*! \brief Future Wars renderer + * + * Screen backbuffer is not cleared between frames, you can draw menus etc. + * without calling drawFrame() all the time + */ +class FWRenderer : public Common::NonCopyable { +private: + byte *_background; ///< Current background + char _bgName[13]; ///< Background filename + uint16 *_palette; ///< 16 color backup palette + + Common::String _cmd; ///< Player command string + +protected: + static const int _screenSize = 320 * 200; ///< Screen size + static const int _screenWidth = 320; ///< Screen width + static const int _screenHeight = 200; ///< Screen height + static const int _lowPalSize = 16; ///< 16 color palette size + + byte *_backBuffer; ///< Screen backbuffer + uint16 *_activeLowPal; ///< Active 16 color palette + int _changePal; ///< Load active palette to video backend on next frame + + void fillSprite(const objectStruct &obj, uint8 color = 0); + void drawMaskedSprite(const objectStruct &obj, const byte *mask); + virtual void drawSprite(const objectStruct &obj); + + void drawCommand(); + void drawMessage(const char *str, int x, int y, int width, byte color); + void drawPlainBox(int x, int y, int width, int height, byte color); + void drawBorder(int x, int y, int width, int height, byte color); + void drawDoubleBorder(int x, int y, int width, int height, byte color); + virtual int drawChar(char character, int x, int y); + void drawLine(int x, int y, int width, int height, byte color); + void remaskSprite(byte *mask, Common::List<overlay>::iterator it); + virtual void drawBackground(); + + virtual void renderOverlay(const Common::List<overlay>::iterator &it); + void drawOverlays(); + +public: + uint16 _messageBg; ///< Message box background color + uint16 _cmdY; ///< Player command string position on screen + + FWRenderer(); + virtual ~FWRenderer(); + + /*! \brief Test if renderer is ready to draw */ + virtual bool ready() { return _background != NULL; } + + virtual void clear(); + + void drawFrame(); + void blit(); + void setCommand(const char *cmd); + + virtual void incrustMask(const objectStruct &obj, uint8 color = 0); + virtual void incrustSprite(const objectStruct &obj); + + virtual void loadBg16(const byte *bg, const char *name); + virtual void loadBg16(const byte *bg, const char *name, unsigned int idx); + virtual void loadCt16(const byte *ct, const char *name); + virtual void loadBg256(const byte *bg, const char *name); + virtual void loadBg256(const byte *bg, const char *name, unsigned int idx); + virtual void loadCt256(const byte *ct, const char *name); + virtual void selectBg(unsigned int idx); + virtual void selectScrollBg(unsigned int idx); + virtual void setScroll(unsigned int shift); + virtual void removeBg(unsigned int idx); + void saveBg(Common::OutSaveFile &fHandle); + + virtual void refreshPalette(); + virtual void reloadPalette(); + void restorePalette(Common::InSaveFile &fHandle); + void savePalette(Common::OutSaveFile &fHandle); + virtual void rotatePalette(int a, int b, int c); + virtual void transformPalette(int first, int last, int r, int g, int b); + + void drawMenu(const CommandeType *items, unsigned int height, int x, int y, int width, int selected); + void drawInputBox(const char *info, const char *input, int cursor, int x, int y, int width); + + virtual void fadeToBlack(); +}; + +/*! \brief Operation Stealth renderer + */ +class OSRenderer : public FWRenderer { +private: + palBg _bgTable[9]; ///< Table of backgrounds loaded into renderer + byte *_activeHiPal; ///< Active 256 color palette + unsigned int _currentBg; ///< Current background + unsigned int _scrollBg; ///< Current scroll background + unsigned int _bgShift; ///< Background shift + +protected: + static const int _hiPalSize = 256 * 3; ///< 256 color palette size + + void drawSprite(const objectStruct &obj); + int drawChar(char character, int x, int y); + void drawBackground(); + void renderOverlay(const Common::List<overlay>::iterator &it); + +public: + OSRenderer(); + ~OSRenderer(); + + /*! \brief Test if renderer is ready to draw */ + bool ready() { return _bgTable[_currentBg].bg != NULL; } + + void clear(); + + void incrustMask(const objectStruct &obj, uint8 color = 0); + void incrustSprite(const objectStruct &obj); + + void loadBg16(const byte *bg, const char *name); + void loadBg16(const byte *bg, const char *name, unsigned int idx); + void loadCt16(const byte *ct, const char *name); + void loadBg256(const byte *bg, const char *name); + void loadBg256(const byte *bg, const char *name, unsigned int idx); + void loadCt256(const byte *ct, const char *name); + void selectBg(unsigned int idx); + void selectScrollBg(unsigned int idx); + void setScroll(unsigned int shift); + void removeBg(unsigned int idx); + + void refreshPalette(); + void reloadPalette(); + void rotatePalette(int a, int b, int c); + void transformPalette(int first, int last, int r, int g, int b); + + void fadeToBlack(); +}; + void gfxDrawSprite(byte *src4, uint16 sw, uint16 sh, byte *dst4, int16 sx, int16 sy); -extern byte *page1Raw; -extern byte *page2Raw; extern byte *page3Raw; +extern FWRenderer *renderer; -extern uint16 c_palette[256]; -extern byte colorMode256; -extern byte palette256[256 * 3]; -extern byte newPalette[256 * 3]; -extern byte newColorMode; -extern byte ctColorMode; -extern byte bgColorMode; - -void gfxInit(); -void gfxDestroy(); void setMouseCursor(int cursor); void gfxCopyPage(byte *source, byte *dest); diff --git a/engines/cine/main_loop.cpp b/engines/cine/main_loop.cpp index 6042849f59..cfb828cf3c 100644 --- a/engines/cine/main_loop.cpp +++ b/engines/cine/main_loop.cpp @@ -182,14 +182,12 @@ int getKeyData() { void CineEngine::mainLoop(int bootScriptIdx) { bool playerAction; uint16 quitFlag; - uint16 i; byte di; uint16 mouseButton; quitFlag = 0; if (_preLoad == false) { - resetSeqList(); resetBgIncrustList(); setTextWindow(0, 0, 20, 200); @@ -223,17 +221,10 @@ void CineEngine::mainLoop(int bootScriptIdx) { globalVars[VAR_LOW_MEMORY] = 0; // set to 1 to disable some animations, sounds etc. } - for (i = 0; i < 16; i++) { - c_palette[i] = 0; - } - - _paletteNeedUpdate = true; - strcpy(newPrcName, ""); strcpy(newRelName, ""); strcpy(newObjectName, ""); strcpy(newMsgName, ""); - strcpy(currentBgName[0], ""); strcpy(currentCtName, ""); strcpy(currentPartName, ""); @@ -257,8 +248,9 @@ void CineEngine::mainLoop(int bootScriptIdx) { setMouseCursor(MOUSE_CURSOR_CROSS); } - drawOverlays(); - flip(); + if (renderer->ready()) { + renderer->drawFrame(); + } if (waitForPlayerClick) { playerAction = false; @@ -289,6 +281,8 @@ void CineEngine::mainLoop(int bootScriptIdx) { } while (mouseButton != 0); waitForPlayerClick = 0; + + removeMessages(); } if (checkForPendingDataLoadSwitch) { diff --git a/engines/cine/object.cpp b/engines/cine/object.cpp index 36f7b17a69..89d6b99592 100644 --- a/engines/cine/object.cpp +++ b/engines/cine/object.cpp @@ -236,6 +236,10 @@ uint16 compareObjectParam(byte objIdx, byte type, int16 value) { return compareResult; } +/*! \bug In Operation Stealth, if you try to go downstairs to the sea in the + * location between bank and hotel, getObjectParam is called with paramIdx 16 + * and crashes + */ int16 getObjectParam(uint16 objIdx, uint16 paramIdx) { assert(objIdx <= NUM_MAX_OBJECT); diff --git a/engines/cine/pal.cpp b/engines/cine/pal.cpp index 9341563898..3e6f5adf40 100644 --- a/engines/cine/pal.cpp +++ b/engines/cine/pal.cpp @@ -28,8 +28,6 @@ namespace Cine { -uint16 tempPalette[256]; - uint16 palEntriesCount; PalEntry *palPtr = NULL; @@ -113,4 +111,64 @@ void loadRelatedPalette(const char *fileName) { } } +void palRotate(uint16 *pal, byte a, byte b, byte c) { + assert(pal); + + if (c == 1) { + uint16 currentColor = pal[b]; + + for (int i = b; i > a; i--) { + pal[i] = pal[i - 1]; + } + + pal[a] = currentColor; + } +} + +void palRotate(byte *pal, byte a, byte b, byte c) { + assert(pal); + + if (c == 1) { + byte currentR = pal[3 * b + 0]; + byte currentG = pal[3 * b + 1]; + byte currentB = pal[3 * b + 2]; + + for (int i = b; i > a; i--) { + pal[3 * i + 0] = pal[3 * (i - 1) + 0]; + pal[3 * i + 1] = pal[3 * (i - 1) + 1]; + pal[3 * i + 2] = pal[3 * (i - 1) + 2]; + } + + pal[3 * a + 0] = currentR; + pal[3 * a + 1] = currentG; + pal[3 * a + 2] = currentB; + } +} + +uint16 transformColor(uint16 baseColor, int r, int g, int b) { + int8 oriR = CLIP( (baseColor & 0x007) + b, 0, 7); + int8 oriG = CLIP(((baseColor & 0x070) >> 4) + g, 0, 7); + int8 oriB = CLIP(((baseColor & 0x700) >> 8) + r, 0, 7); + + return oriR | (oriG << 4) | (oriB << 8); +} + +void transformPaletteRange(uint16 *dstPal, uint16 *srcPal, int startColor, int stopColor, int r, int g, int b) { + assert(srcPal && dstPal); + + for (int i = startColor; i <= stopColor; i++) { + dstPal[i] = transformColor(srcPal[i], r, g, b); + } +} + +void transformPaletteRange(byte *dstPal, byte *srcPal, int startColor, int stopColor, int r, int g, int b) { + assert(srcPal && dstPal); + + for (int i = startColor; i <= stopColor; i++) { + dstPal[3 * i + 0] = CLIP(srcPal[3 * i + 0] + r * 32, 0, 255); + dstPal[3 * i + 1] = CLIP(srcPal[3 * i + 1] + g * 32, 0, 255); + dstPal[3 * i + 2] = CLIP(srcPal[3 * i + 2] + b * 32, 0, 255); + } +} + } // End of namespace Cine diff --git a/engines/cine/pal.h b/engines/cine/pal.h index da822fa1a1..70fcc0d98a 100644 --- a/engines/cine/pal.h +++ b/engines/cine/pal.h @@ -36,10 +36,14 @@ struct PalEntry { void loadPal(const char *fileName); -extern uint16 tempPalette[256]; - void loadRelatedPalette(const char *fileName); +void palRotate(uint16 *pal, byte a, byte b, byte c); +void palRotate(byte *pal, byte a, byte b, byte c); +uint16 transformColor(uint16 baseColor, int r, int g, int b); +void transformPaletteRange(uint16 *srcPal, uint16 *dstPal, int startColor, int stopColor, int r, int g, int b); +void transformPaletteRange(byte *srcPal, byte *dstPal, int startColor, int stopColor, int r, int g, int b); + } // End of namespace Cine #endif diff --git a/engines/cine/prc.cpp b/engines/cine/prc.cpp index 0f068a197e..402c97b1a6 100644 --- a/engines/cine/prc.cpp +++ b/engines/cine/prc.cpp @@ -98,10 +98,10 @@ void loadPrc(const char *pPrcName) { char buffer[256]; for (s = 0; s < numScripts; s++) { - if (scriptTable[s].size) { + if (scriptTable[s]->_size) { sprintf(buffer, "%s_%03d.txt", pPrcName, s); - decompileScript(scriptTable[s].ptr, scriptTable[s].stack, scriptTable[s].size, s); + decompileScript((const byte *)scriptTable[s]->getString(0), scriptTable[s]->_size, s); dumpScript(buffer); } } diff --git a/engines/cine/rel.cpp b/engines/cine/rel.cpp index f550efed27..dd2d0f68b6 100644 --- a/engines/cine/rel.cpp +++ b/engines/cine/rel.cpp @@ -81,10 +81,10 @@ void loadRel(char *pRelName) { char buffer[256]; for (s = 0; s < numEntry; s++) { - if (relTable[s].size) { + if (relTable[s]->_size) { sprintf(buffer, "%s_%03d.txt", pRelName, s); - decompileScript(relTable[s].data, NULL, relTable[s].size, s); + decompileScript((const byte *)relTable[s]->getString(0), relTable[s]->_size, s); dumpScript(buffer); } } diff --git a/engines/cine/script.h b/engines/cine/script.h index 4a2e7072ee..23bb179ee5 100644 --- a/engines/cine/script.h +++ b/engines/cine/script.h @@ -230,6 +230,7 @@ protected: int o1_unloadMask5(); // pointers to member functions in C++ suck... + int o2_loadCt(); int o2_loadPart(); int o2_addSeqListElement(); int o2_removeSeq(); @@ -362,7 +363,7 @@ extern ScriptVars globalVars; void setupOpcodes(); -void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 scriptIdx); +void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx); void dumpScript(char *dumpName); #define OP_loadPart 0x3F diff --git a/engines/cine/script_fw.cpp b/engines/cine/script_fw.cpp index f833d7c30b..4f6749517e 100644 --- a/engines/cine/script_fw.cpp +++ b/engines/cine/script_fw.cpp @@ -41,11 +41,6 @@ namespace Cine { ScriptVars globalVars(NUM_MAX_VAR); uint16 compareVars(int16 a, int16 b); -void palRotate(byte a, byte b, byte c); -void removeSeq(uint16 param1, uint16 param2, uint16 param3); -uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3); -void addGfxElementA0(int16 param1, int16 param2); -void removeGfxElementA0(int16 idx, int16 param); const Opcode FWScript::_opcodeTable[] = { /* 00 */ @@ -1299,7 +1294,7 @@ int FWScript::o1_loadCt() { const char *param = getNextString(); debugC(5, kCineDebugScript, "Line: %d: loadCt(\"%s\")", _line, param); - loadCt(param); + loadCtFW(param); return 0; } @@ -1355,31 +1350,29 @@ int FWScript::o1_blitAndFade() { debugC(5, kCineDebugScript, "Line: %d: request fadein", _line); // TODO: use real code - drawOverlays(); - fadeRequired = true; - flip(); - // fadeFromBlack(); + + renderer->reloadPalette(); return 0; } int FWScript::o1_fadeToBlack() { debugC(5, kCineDebugScript, "Line: %d: request fadeout", _line); - fadeToBlack(); + renderer->fadeToBlack(); return 0; } int FWScript::o1_transformPaletteRange() { byte startColor = getNextByte(); byte numColor = getNextByte(); - uint16 r = getNextWord(); - uint16 g = getNextWord(); - uint16 b = getNextWord(); + int16 r = getNextWord(); + int16 g = getNextWord(); + int16 b = getNextWord(); debugC(5, kCineDebugScript, "Line: %d: transformPaletteRange(from:%d,numIdx:%d,r:%d,g:%d,b:%d)", _line, startColor, numColor, r, g, b); - transformPaletteRange(startColor, numColor, r, g, b); + renderer->transformPalette(startColor, numColor, r, g, b); return 0; } @@ -1387,7 +1380,8 @@ int FWScript::o1_setDefaultMenuColor2() { byte param = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: setDefaultMenuColor2(%d)", _line, param); - defaultMenuBoxColor2 = param; + + renderer->_messageBg = param; return 0; } @@ -1397,7 +1391,8 @@ int FWScript::o1_palRotate() { byte c = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: palRotate(%d,%d,%d)", _line, a, b, c); - palRotate(a, b, c); + + renderer->rotatePalette(a, b, c); return 0; } @@ -1475,11 +1470,7 @@ int FWScript::o1_compareGlobalVar() { debugC(5, kCineDebugScript, "Line: %d: compare globalVars[%d] and %d", _line, varIdx, value); - if (varIdx == 255 && (g_cine->getGameType() == Cine::GType_FW)) { // TODO: fix - _compare = 1; - } else { - _compare = compareVars(_globalVars[varIdx], value); - } + _compare = compareVars(_globalVars[varIdx], value); } return 0; @@ -1558,7 +1549,8 @@ int FWScript::o1_setDefaultMenuColor() { byte param = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: setDefaultMenuColor(%d)", _line, param); - defaultMenuBoxColor = param; + + renderer->_cmdY = param; return 0; } @@ -1728,18 +1720,6 @@ int FWScript::o1_unloadMask5() { //----------------------------------------------------------------------- -void palRotate(byte a, byte b, byte c) { - if (c == 1) { - uint16 currentColor = c_palette[b]; - - for (int16 i = b; i > a; i--) { - c_palette[i] = c_palette[i - 1]; - } - - c_palette[a] = currentColor; - } -} - void addScriptToList0(uint16 idx) { ScriptPtr tmp(scriptInfo->create(*scriptTable[idx], idx)); assert(tmp); @@ -1863,14 +1843,13 @@ const char *getObjPramName(byte paramIdx) { } } -void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 scriptIdx) { +void decompileScript(const byte *scriptPtr, uint16 scriptSize, uint16 scriptIdx) { char lineBuffer[256]; - byte *localScriptPtr = scriptPtr; + const byte *localScriptPtr = scriptPtr; uint16 exitScript; uint32 position = 0; assert(scriptPtr); - // assert(stackPtr); exitScript = 0; @@ -2292,7 +2271,7 @@ void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 sprintf(lineBuffer, "loadPart(%s)\n", localScriptPtr + position); } - position += strlen((char *)localScriptPtr + position) + 1; + position += strlen((const char *)localScriptPtr + position) + 1; break; } case 0x40: @@ -2309,7 +2288,7 @@ void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 sprintf(lineBuffer, "loadPrc(%d,%s)\n", param, localScriptPtr + position); - position += strlen((char *)localScriptPtr + position) + 1; + position += strlen((const char *)localScriptPtr + position) + 1; break; } case OP_requestCheckPendingDataLoad: // nop @@ -2461,7 +2440,7 @@ void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 { sprintf(lineBuffer, "comment: %s\n", localScriptPtr + position); - position += strlen((char *)localScriptPtr + position); + position += strlen((const char *)localScriptPtr + position); break; } case 0x5A: @@ -2540,7 +2519,7 @@ void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 { sprintf(lineBuffer, "loadDat(%s)\n", localScriptPtr + position); - position += strlen((char *)localScriptPtr + position) + 1; + position += strlen((const char *)localScriptPtr + position) + 1; break; } case 0x6E: // nop @@ -2801,7 +2780,7 @@ void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 sprintf(lineBuffer, "ADDBG(%d,%s)\n", param1, localScriptPtr + position); - position += strlen((char *)localScriptPtr + position); + position += strlen((const char *)localScriptPtr + position); break; } @@ -2825,7 +2804,7 @@ void decompileScript(byte *scriptPtr, int16 *stackPtr, uint16 scriptSize, uint16 sprintf(lineBuffer, "loadABS(%d,%s)\n", param1, localScriptPtr + position); - position += strlen((char *)localScriptPtr + position); + position += strlen((const char *)localScriptPtr + position); break; } diff --git a/engines/cine/script_os.cpp b/engines/cine/script_os.cpp index 1f5ea2b838..36eda007c6 100644 --- a/engines/cine/script_os.cpp +++ b/engines/cine/script_os.cpp @@ -116,7 +116,7 @@ const Opcode OSScript::_opcodeTable[] = { { &FWScript::o1_loadAnim, "s" }, /* 3C */ { &FWScript::o1_loadBg, "s" }, - { &FWScript::o1_loadCt, "s" }, + { &FWScript::o2_loadCt, "s" }, { 0, 0 }, { &FWScript::o2_loadPart, "s" }, /* 40 */ @@ -365,6 +365,14 @@ FWScript *OSScriptInfo::create(const RawObjectScript &script, int16 index, const // OPERATION STEALTH opcodes // ------------------------------------------------------------------------ +int FWScript::o2_loadCt() { + const char *param = getNextString(); + + debugC(5, kCineDebugScript, "Line: %d: loadCt(\"%s\")", _line, param); + loadCtOS(param); + return 0; +} + int FWScript::o2_loadPart() { const char *param = getNextString(); @@ -615,20 +623,7 @@ int FWScript::o2_removeBackground() { debugC(5, kCineDebugScript, "Line: %d: removeBackground(%d)", _line, param); - if (additionalBgTable[param]) { - free(additionalBgTable[param]); - additionalBgTable[param] = NULL; - } - - if (currentAdditionalBgIdx == param) { - currentAdditionalBgIdx = 0; - } - - if (currentAdditionalBgIdx2 == param) { - currentAdditionalBgIdx2 = 0; - } - - strcpy(currentBgName[param], ""); + renderer->removeBg(param); return 0; } @@ -644,22 +639,11 @@ int FWScript::o2_loadAbs() { int FWScript::o2_loadBg() { byte param = getNextByte(); - assert(param <= 8); + assert(param < 9); debugC(5, kCineDebugScript, "Line: %d: useBg(%d)", _line, param); - if (additionalBgTable[param]) { - currentAdditionalBgIdx = param; - if (param == 8) { - newColorMode = 3; - } else { - newColorMode = bgColorMode + 1; - } - //if (_screenNeedFadeOut == 0) { - // adBgVar1 = 1; - //} - fadeRequired = true; - } + renderer->selectBg(param); return 0; } @@ -699,13 +683,11 @@ int FWScript::o2_op9C() { int FWScript::o2_useBgScroll() { byte param = getNextByte(); - assert(param <= 8); + assert(param < 9); debugC(5, kCineDebugScript, "Line: %d: useBgScroll(%d)", _line, param); - if (additionalBgTable[param]) { - currentAdditionalBgIdx2 = param; - } + renderer->selectScrollBg(param); return 0; } @@ -716,12 +698,12 @@ int FWScript::o2_setAdditionalBgVScroll() { byte param2 = getNextByte(); debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = var[%d]", _line, param2); - additionalBgVScroll = _localVars[param2]; + renderer->setScroll(_localVars[param2]); } else { uint16 param2 = getNextWord(); debugC(5, kCineDebugScript, "Line: %d: additionalBgVScroll = %d", _line, param2); - additionalBgVScroll = param2; + renderer->setScroll(param2); } return 0; } diff --git a/engines/cine/texte.cpp b/engines/cine/texte.cpp index e41626cad1..91a209074d 100644 --- a/engines/cine/texte.cpp +++ b/engines/cine/texte.cpp @@ -611,65 +611,49 @@ void freePoldatDat() { fontParamTable = 0; } -uint16 computeMessageLength(const byte *ptr, uint16 width, uint16 *numWords, uint16 *messageWidth, uint16 *lineResult) { - const byte *localPtr = ptr; - - uint16 var_2 = 0; - uint16 localLineResult = 0; - uint16 var_6 = 0; - uint16 var_8 = 0; - uint16 localMessageWidth = 0; - uint16 var_16 = 0; - uint16 finished = 0; - uint16 si = 0; - uint16 di = 0; - - while (!finished) { - byte character = *(localPtr++); - - if (character == ' ') { - var_8 = var_16; - var_6 = localMessageWidth; - localLineResult = si; - var_2 = di; - - if (si + 5 < width) { - var_16++; - si += 5; - } else { - finished = 1; - } - } else if (character == 0x7C || character == 0) { - finished = 1; - si = 0; +/*! \brief Fit a substring of text into one line of fixed width text box + * \param str Text to fit + * \param maxWidth Text box width + * \param[out] words Number of words that fit + * \param[out] width Total width of nonblank characters that fit + * \return Length of substring which fits + */ +int fitLine(const char *str, int maxWidth, int &words, int &width) { + int i, bkpWords = 0, bkpWidth = 0, bkpLen = 0; + int charWidth = 0, fullWidth = 0; + + words = 0; + width = 0; + + for (i = 0; str[i]; i++) { + if (str[i] == 0x7C) { + i++; + break; + } else if (str[i] == ' ') { + charWidth = 5; + bkpWords = words++; + bkpWidth = width; + bkpLen = i + 1; } else { - if (fontParamTable[character].characterWidth) { - uint16 var_C = fontParamTable[character].characterWidth + 1; - - if (si + var_C < width) { - si += var_C; - localMessageWidth += var_C; - } else { - finished = 1; - - if (localLineResult) { - var_16 = var_8; - localMessageWidth = var_6; - si = localLineResult; - di = var_2; - } - } - } + charWidth = fontParamTable[str[i]].characterWidth + 1; + width += charWidth; } - di++; - } + if (!charWidth) { + continue; + } - *numWords = var_16; - *messageWidth = localMessageWidth; - *lineResult = si; + if (fullWidth + charWidth < maxWidth) { + fullWidth += charWidth; + } else if (fullWidth) { + words = bkpWords; + width = bkpWidth; + i = bkpLen; + break; + } + } - return di; + return i; } } // End of namespace Cine diff --git a/engines/cine/texte.h b/engines/cine/texte.h index b5eaef9211..ae82832aea 100644 --- a/engines/cine/texte.h +++ b/engines/cine/texte.h @@ -56,7 +56,7 @@ void freeErrmessDat(void); void loadPoldatDat(const char *fname); void freePoldatDat(void); -uint16 computeMessageLength(const byte *ptr, uint16 width, uint16 *numWords, uint16 *messageWidth, uint16 *lineResult); +int fitLine(const char *ptr, int maxWidth, int &words, int &width); } // End of namespace Cine diff --git a/engines/cine/various.cpp b/engines/cine/various.cpp index a6bd9964c0..9b98ddb253 100644 --- a/engines/cine/various.cpp +++ b/engines/cine/various.cpp @@ -87,7 +87,6 @@ char newPrcName[20]; char newRelName[20]; char newObjectName[20]; char newMsgName[20]; -char currentBgName[8][15]; char currentCtName[15]; char currentPartName[15]; char currentDatName[30]; @@ -96,8 +95,6 @@ int16 saveVar2; byte isInPause = 0; -uint16 defaultMenuBoxColor; - byte inputVar1 = 0; uint16 inputVar2 = 0, inputVar3 = 0; @@ -114,7 +111,6 @@ CommandeType objectListCommand[20]; int16 objListTab[20]; uint16 exitEngine; -uint16 defaultMenuBoxColor2; uint16 zoneData[NUM_MAX_ZONE]; @@ -140,6 +136,7 @@ void addPlayerCommandMessage(int16 cmd) { tmp.type = 3; overlayList.push_back(tmp); + waitForPlayerClick = 1; } int16 getRelEntryForObject(uint16 param1, uint16 param2, SelectedObjStruct *pSelectedObject) { @@ -393,11 +390,14 @@ bool brokenSave(Common::InSaveFile &fHandle) { return broken; } +/*! \todo Implement Operation Stealth loading, this is obviously Future Wars only + */ bool CineEngine::makeLoad(char *saveName) { int16 i; int16 size; bool broken; Common::InSaveFile *fHandle; + char bgName[13]; fHandle = g_saveFileMan->openForLoading(saveName); @@ -440,7 +440,6 @@ bool CineEngine::makeLoad(char *saveName) { strcpy(newRelName, ""); strcpy(newObjectName, ""); strcpy(newMsgName, ""); - strcpy(currentBgName[0], ""); strcpy(currentCtName, ""); allowPlayerInput = 0; @@ -455,9 +454,7 @@ bool CineEngine::makeLoad(char *saveName) { fadeRequired = false; - for (i = 0; i < 16; i++) { - c_palette[i] = 0; - } + renderer->clear(); checkForPendingDataLoadSwitch = 0; @@ -473,7 +470,7 @@ bool CineEngine::makeLoad(char *saveName) { fHandle->read(currentPrcName, 13); fHandle->read(currentRelName, 13); fHandle->read(currentMsgName, 13); - fHandle->read(currentBgName[0], 13); + fHandle->read(bgName, 13); fHandle->read(currentCtName, 13); checkDataDisk(currentDisk); @@ -490,12 +487,12 @@ bool CineEngine::makeLoad(char *saveName) { loadRel(currentRelName); } - if (strlen(currentBgName[0])) { - loadBg(currentBgName[0]); + if (strlen(bgName)) { + loadBg(bgName); } if (strlen(currentCtName)) { - loadCt(currentCtName); + loadCtFW(currentCtName); } fHandle->readUint16BE(); @@ -511,13 +508,7 @@ bool CineEngine::makeLoad(char *saveName) { objectTable[i].part = fHandle->readUint16BE(); } - for (i = 0; i < 16; i++) { - c_palette[i] = fHandle->readUint16BE(); - } - - for (i = 0; i < 16; i++) { - tempPalette[i] = fHandle->readUint16BE(); - } + renderer->restorePalette(*fHandle); globalVars.load(*fHandle, NUM_MAX_VAR - 1); @@ -530,8 +521,10 @@ bool CineEngine::makeLoad(char *saveName) { } fHandle->read(commandBuffer, 0x50); + renderer->setCommand(commandBuffer); + + renderer->_cmdY = fHandle->readUint16BE(); - defaultMenuBoxColor = fHandle->readUint16BE(); bgVar0 = fHandle->readUint16BE(); allowPlayerInput = fHandle->readUint16BE(); playerCommand = fHandle->readSint16BE(); @@ -542,7 +535,8 @@ bool CineEngine::makeLoad(char *saveName) { var3 = fHandle->readUint16BE(); var2 = fHandle->readUint16BE(); commandVar2 = fHandle->readSint16BE(); - defaultMenuBoxColor2 = fHandle->readUint16BE(); + + renderer->_messageBg = fHandle->readUint16BE(); fHandle->readUint16BE(); fHandle->readUint16BE(); @@ -615,7 +609,7 @@ void makeSave(char *saveFileName) { fHandle->write(currentPrcName, 13); fHandle->write(currentRelName, 13); fHandle->write(currentMsgName, 13); - fHandle->write(currentBgName[0], 13); + renderer->saveBg(*fHandle); fHandle->write(currentCtName, 13); fHandle->writeUint16BE(0xFF); @@ -631,13 +625,7 @@ void makeSave(char *saveFileName) { fHandle->writeUint16BE(objectTable[i].part); } - for (i = 0; i < 16; i++) { - fHandle->writeUint16BE(c_palette[i]); - } - - for (i = 0; i < 16; i++) { - fHandle->writeUint16BE(tempPalette[i]); - } + renderer->savePalette(*fHandle); globalVars.save(*fHandle, NUM_MAX_VAR - 1); @@ -651,7 +639,8 @@ void makeSave(char *saveFileName) { fHandle->write(commandBuffer, 0x50); - fHandle->writeUint16BE(defaultMenuBoxColor); + fHandle->writeUint16BE(renderer->_cmdY); + fHandle->writeUint16BE(bgVar0); fHandle->writeUint16BE(allowPlayerInput); fHandle->writeUint16BE(playerCommand); @@ -662,7 +651,8 @@ void makeSave(char *saveFileName) { fHandle->writeUint16BE(var3); fHandle->writeUint16BE(var2); fHandle->writeUint16BE(commandVar2); - fHandle->writeUint16BE(defaultMenuBoxColor2); + + fHandle->writeUint16BE(renderer->_messageBg); fHandle->writeUint16BE(0xFF); fHandle->writeUint16BE(0x1E); @@ -864,26 +854,6 @@ void CineEngine::makeSystemMenu(void) { } } -int drawChar(byte character, int16 x, int16 y) { - if (character == ' ') { - x += 5; - } else { - byte characterWidth = fontParamTable[character].characterWidth; - - if (characterWidth) { - byte characterIdx = fontParamTable[character].characterIdx; - if (g_cine->getGameType() == Cine::GType_OS) { - drawSpriteRaw2(textTable[characterIdx][0], 0, 2, 8, page1Raw, x, y); - } else { - drawSpriteRaw(textTable[characterIdx][0], textTable[characterIdx][1], 2, 8, page1Raw, x, y); - } - x += characterWidth + 1; - } - } - - return x; -} - void drawMessageBox(int16 x, int16 y, int16 width, int16 currentY, int16 offset, int16 color, byte* page) { gfxDrawLine(x + offset, y + offset, x + width - offset, y + offset, color, page); // top gfxDrawLine(x + offset, currentY + 4 - offset, x + width - offset, currentY + 4 - offset, color, page); // bottom @@ -896,49 +866,6 @@ void drawDoubleMessageBox(int16 x, int16 y, int16 width, int16 currentY, int16 c drawMessageBox(x, y, width, currentY, 0, color, page); } -void makeTextEntry(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, uint16 width) { - byte color = 2; - byte color2 = defaultMenuBoxColor2; - int16 paramY = (height * 9) + 10; - int16 currentX, currentY; - int16 i; - uint16 j; - byte currentChar; - - if (X + width > 319) { - X = 319 - width; - } - - if (Y + paramY > 199) { - Y = 199 - paramY; - } - - hideMouse(); - blitRawScreen(page1Raw); - - gfxDrawPlainBoxRaw(X, Y, X + width, Y + 4, color2, page1Raw); - - currentX = X + 4; - currentY = Y + 4; - - for (i = 0; i < height; i++) { - gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 9, color2, page1Raw); - currentX = X + 4; - - for (j = 0; j < strlen(commandList[i]); j++) { - currentChar = commandList[i][j]; - currentX = drawChar(currentChar, currentX, currentY); - } - - currentY += 9; - } - - gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 4, color2, page1Raw); // bottom part - drawDoubleMessageBox(X, Y, width, currentY, color, page1Raw); - - blitRawScreen(page1Raw); -} - void processInventory(int16 x, int16 y) { int16 listSize = buildObjectListCommand(-2); uint16 button; @@ -946,7 +873,8 @@ void processInventory(int16 x, int16 y) { if (!listSize) return; - makeTextEntry(objectListCommand, listSize, x, y, 140); + renderer->drawMenu(objectListCommand, listSize, x, y, 140, -1); + renderer->blit(); do { manageEvents(); @@ -1085,7 +1013,7 @@ void makeCommandLine(void) { } if (!disableSystemMenu) { - isDrawCommandEnabled = 1; + renderer->setCommand(commandBuffer); } } @@ -1094,13 +1022,8 @@ uint16 needMouseSave = 0; uint16 menuVar4 = 0; uint16 menuVar5 = 0; -int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, - uint16 width, bool recheckValue) { - byte color = 2; - byte color2 = defaultMenuBoxColor2; +int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, uint16 Y, uint16 width, bool recheckValue) { int16 paramY; - int16 currentX, currentY; - int16 i; uint16 button; int16 var_A; int16 di; @@ -1110,7 +1033,6 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, int16 var_14; int16 currentSelection, oldSelection; int16 var_4; - byte currentChar; if (disableSystemMenu) return -1; @@ -1125,30 +1047,8 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, Y = 199 - paramY; } - hideMouse(); - blitRawScreen(page1Raw); - - gfxDrawPlainBoxRaw(X, Y, X + width, Y + 4, color2, page1Raw); - - currentX = X + 4; - currentY = Y + 4; - - for (i = 0; i < height; i++) { - gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 9, color2, page1Raw); - currentX = X + 4; - - for (j = 0; j < strlen(commandList[i]); j++) { - currentChar = commandList[i][j]; - currentX = drawChar(currentChar, currentX, currentY); - } - - currentY += 9; - } - - gfxDrawPlainBoxRaw(X, currentY, X + width, currentY + 4, color2, page1Raw); // bottom part - drawDoubleMessageBox(X, Y, width, currentY, color, page1Raw); - - blitRawScreen(page1Raw); + renderer->drawMenu(commandList, height, X, Y, width, -1); + renderer->blit(); do { manageEvents(); @@ -1160,15 +1060,9 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, currentSelection = 0; di = currentSelection * 9 + Y + 4; - gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, 0, page1Raw); // draw black box behind selection - currentX = X + 4; - - for (j = 0; j < strlen(commandList[currentSelection]); j++) { - currentChar = commandList[currentSelection][j]; - currentX = drawChar(currentChar, currentX, di); - } - blitRawScreen(page1Raw); + renderer->drawMenu(commandList, height, X, Y, width, currentSelection); + renderer->blit(); manageEvents(); getMouseData(mouseUpdateStatus, &button, (uint16 *)&mouseX, (uint16 *)&mouseY); @@ -1219,29 +1113,10 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, hideMouse(); } - di = oldSelection * 9 + Y + 4; - - gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, color2, page1Raw); // restore color - - currentX = X + 4; - - for (j = 0; j < strlen(commandList[oldSelection]); j++) { - currentChar = commandList[oldSelection][j]; - currentX = drawChar(currentChar, currentX, di); - } - di = currentSelection * 9 + Y + 4; - gfxDrawPlainBoxRaw(X + 2, di - 1, X + width - 2, di + 7, 0, page1Raw); // black new - - currentX = X + 4; - - for (j = 0; j < strlen(commandList[currentSelection]); j++) { - currentChar = commandList[currentSelection][j]; - currentX = drawChar(currentChar, currentX, di); - } - - blitRawScreen(page1Raw); + renderer->drawMenu(commandList, height, X, Y, width, currentSelection); + renderer->blit(); // if (needMouseSave) { // gfxRedrawMouseCursor(); @@ -1271,38 +1146,6 @@ int16 makeMenuChoice(const CommandeType commandList[], uint16 height, uint16 X, return currentSelection; } -void drawMenuBox(char *command, int16 x, int16 y) { - byte j; - byte lColor = 2; - - hideMouse(); - - gfxDrawPlainBoxRaw(x, y, x + 300, y + 10, 0, page2Raw); - - drawMessageBox(x, y, 300, y + 6, -1, lColor, page2Raw); - - x += 2; - y += 2; - - for (j = 0; j < strlen(command); j++) { - byte currentChar = command[j]; - - if (currentChar == ' ') { - x += 5; - } else { - byte characterWidth = fontParamTable[currentChar].characterWidth; - - if (characterWidth) { - byte characterIdx = fontParamTable[currentChar].characterIdx; - drawSpriteRaw(textTable[characterIdx][0], textTable[characterIdx][1], 2, 8, page2Raw, x, y); - x += characterWidth + 1; - } - } - } - -// gfxRedrawMouseCursor(); -} - void makeActionMenu(void) { uint16 mouseButton; uint16 mouseX; @@ -1342,11 +1185,6 @@ uint16 executePlayerInput(void) { } if (allowPlayerInput) { - if (isDrawCommandEnabled) { - drawMenuBox(commandBuffer, 10, defaultMenuBoxColor); - isDrawCommandEnabled = 0; - } - getMouseData(mouseUpdateStatus, &mouseButton, &mouseX, &mouseY); while (mouseButton && currentEntry < 200) { @@ -1393,7 +1231,6 @@ uint16 executePlayerInput(void) { if (choiceResultTable[playerCommand] == commandVar1) { int16 relEntry; - drawMenuBox(commandBuffer, 10, defaultMenuBoxColor); SelectedObjStruct obj; obj.idx = commandVar3[0]; obj.param = commandVar3[1]; @@ -1410,41 +1247,40 @@ uint16 executePlayerInput(void) { commandVar1 = 0; strcpy(commandBuffer, ""); + renderer->setCommand(""); } } else { globalVars[VAR_MOUSE_X_POS] = mouseX; globalVars[VAR_MOUSE_Y_POS] = mouseY; } } - } else { - if (mouseButton & 2) { - if (mouseButton & 1) { - g_cine->makeSystemMenu(); - } + } else if (mouseButton & 2) { + if (mouseButton & 1) { + g_cine->makeSystemMenu(); + } - makeActionMenu(); - makeCommandLine(); - } else { - int16 objIdx; + makeActionMenu(); + makeCommandLine(); + } else { + int16 objIdx; - objIdx = getObjectUnderCursor(mouseX, mouseY); + objIdx = getObjectUnderCursor(mouseX, mouseY); - if (commandVar2 != objIdx) { - if (objIdx != -1) { - char command[256]; + if (commandVar2 != objIdx) { + if (objIdx != -1) { + char command[256]; - strcpy(command, commandBuffer); - strcat(command, " "); - strcat(command, objectTable[objIdx].name); + strcpy(command, commandBuffer); + strcat(command, " "); + strcat(command, objectTable[objIdx].name); - drawMenuBox(command, 10, defaultMenuBoxColor); - } else { - isDrawCommandEnabled = 1; - } + renderer->setCommand(command); + } else { + isDrawCommandEnabled = 1; } - - commandVar2 = objIdx; } + + commandVar2 = objIdx; } } else { if (mouseButton & 2) { @@ -1653,257 +1489,9 @@ void drawSprite(Common::List<overlay>::iterator it, const byte *spritePtr, const free(msk); } -int16 additionalBgVScroll = 0; - -void backupOverlayPage(void) { - byte *scrollBg; - byte *bgPage = additionalBgTable[currentAdditionalBgIdx]; - - if (bgPage) { - if (!additionalBgVScroll) { - memcpy(page1Raw, bgPage, 320 * 200); - } else { - scrollBg = additionalBgTable[currentAdditionalBgIdx2]; - - for (int16 i = additionalBgVScroll; i < 200 + additionalBgVScroll; i++) { - if (i > 200) { - memcpy(page1Raw + (i - additionalBgVScroll) * 320, scrollBg + (i - 200) * 320, 320); - } else { - memcpy(page1Raw + (i - additionalBgVScroll) * 320, bgPage + (i-1) * 320, 320); - } - } - } - } -} - -void drawMessage(const char *messagePtr, int16 x, int16 y, int16 width, int16 color) { - byte color2 = 2; - byte endOfMessageReached = 0; - int16 localX, localY, localWidth; - uint16 messageLength = 0, numWords = 0, messageWidth = 0; - uint16 lineResult, fullLineWidth; - uint16 interWordSize, interWordSizeRemain; - const char *endOfMessagePtr; - byte currentChar; //, characterWidth; - - gfxDrawPlainBoxRaw(x, y, x + width, y + 4, color, page1Raw); - - localX = x + 4; - localY = y + 4; - localWidth = width - 8; - - do { - messageLength = 0; - - while (messagePtr[messageLength] == ' ') { - messageLength++; - } - - messagePtr += messageLength; - - messageLength = computeMessageLength((const byte *)messagePtr, localWidth, &numWords, &messageWidth, &lineResult); - - endOfMessagePtr = messagePtr + messageLength; - - if (lineResult) { - fullLineWidth = localWidth - messageWidth; - - if (numWords) { - interWordSize = fullLineWidth / numWords; - interWordSizeRemain = fullLineWidth % numWords; - } else { - interWordSize = 5; - interWordSizeRemain = 0; - } - } else { - interWordSize = 5; - interWordSizeRemain = 0; - } - - gfxDrawPlainBoxRaw(x, localY, x + width, localY + 9, color, page1Raw); - - do { - currentChar = *(messagePtr++); - - if (currentChar == 0) { - endOfMessageReached = 1; - } else if (currentChar == ' ') { - localX += interWordSizeRemain + interWordSize; - - if (interWordSizeRemain) - interWordSizeRemain = 0; - } else { - localX = drawChar(currentChar, localX, localY); - } - } while ((messagePtr < endOfMessagePtr) && !endOfMessageReached); - - localX = x + 4; - localY += 9; - } while (!endOfMessageReached); - - gfxDrawPlainBoxRaw(x, localY, x + width, localY + 4, color, page1Raw); - - drawDoubleMessageBox(x, y, width, localY, color2, page1Raw); -} - -void drawDialogueMessage(byte msgIdx, int16 x, int16 y, int16 width, int16 color) { - if (msgIdx >= messageTable.size()) { -// removeOverlay(msgIdx, 2); - return; - } - - _messageLen += messageTable[msgIdx].size(); - drawMessage(messageTable[msgIdx].c_str(), x, y, width, color); - - // this invalidates the iterator in drawOverlays() -// removeOverlay(msgIdx, 2); -} - -void drawFailureMessage(byte cmd) { - byte msgIdx = cmd * 4 + g_cine->_rnd.getRandomNumber(3); - - const char *messagePtr = failureMessages[msgIdx]; - int len = strlen(messagePtr); - - _messageLen += len; - - int16 width = 6 * len + 20; - - if (width > 300) - width = 300; - - int16 x = (320 - width) / 2; - int16 y = 80; - int16 color = 4; - - drawMessage(messagePtr, x, y, width, color); - - // this invalidates the iterator in drawOverlays() -// removeOverlay(cmd, 3); -} - -void drawOverlays(void) { - uint16 width, height; - AnimData *pPart; - int16 x, y; - objectStruct *objPtr; - byte messageIdx; +void removeMessages() { Common::List<overlay>::iterator it; - backupOverlayPage(); - - _messageLen = 0; - - for (it = overlayList.begin(); it != overlayList.end(); ++it) { - switch (it->type) { - case 0: // sprite - assert(it->objIdx < NUM_MAX_OBJECT); - - objPtr = &objectTable[it->objIdx]; - x = objPtr->x; - y = objPtr->y; - - if (objPtr->frame < 0) { - continue; - } - - pPart = &animDataTable[objPtr->frame]; - width = pPart->_realWidth; - height = pPart->_height; - - if (!pPart->data()) { - continue; - } - - // drawSprite ignores masks of Operation Stealth sprites - drawSprite(it, pPart->data(), pPart->mask(), width, height, page1Raw, x, y); - break; - - case 2: // text - // gfxWaitVSync(); - // hideMouse(); - - messageIdx = it->objIdx; - x = it->x; - y = it->y; - width = it->width; - height = it->color; - - blitRawScreen(page1Raw); - - drawDialogueMessage(messageIdx, x, y, width, height); - - // blitScreen(page0, NULL); - // gfxRedrawMouseCursor(); - - waitForPlayerClick = 1; - - break; - - case 3: - // gfxWaitSync() - // hideMouse(); - - blitRawScreen(page1Raw); - - drawFailureMessage(it->objIdx); - - // blitScreen(page0, NULL); - // gfxRedrawMouseCursor(); - - waitForPlayerClick = 1; - - break; - - case 4: - assert(it->objIdx < NUM_MAX_OBJECT); - - objPtr = &objectTable[it->objIdx]; - x = objPtr->x; - y = objPtr->y; - - if (objPtr->frame < 0) { - continue; - } - - assert(objPtr->frame < NUM_MAX_ANIMDATA); - - pPart = &animDataTable[objPtr->frame]; - - width = pPart->_realWidth; - height = pPart->_height; - - if (!pPart->data()) { - continue; - } - - gfxFillSprite(pPart->data(), width, height, page1Raw, x, y); - break; - - case 20: - assert(it->objIdx < NUM_MAX_OBJECT); - - objPtr = &objectTable[it->objIdx]; - x = objPtr->x; - y = objPtr->y; - var5 = it->x; - - if (objPtr->frame < 0 || var5 > 8 || !additionalBgTable[var5] || animDataTable[objPtr->frame]._bpp != 1) { - continue; - } - - width = animDataTable[objPtr->frame]._realWidth; - height = animDataTable[objPtr->frame]._height; - - if (!animDataTable[objPtr->frame].data()) { - continue; - } - - maskBgOverlay(additionalBgTable[var5], animDataTable[objPtr->frame].data(), width, height, page1Raw, x, y); - break; - } - } - for (it = overlayList.begin(); it != overlayList.end(); ) { if (it->type == 2 || it->type == 3) { it = overlayList.erase(it); @@ -1978,115 +1566,96 @@ void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 par tmp.color = param5; overlayList.push_back(tmp); + waitForPlayerClick = 1; } -SeqListElement seqList; +Common::List<SeqListElement> seqList; void removeSeq(uint16 param1, uint16 param2, uint16 param3) { - SeqListElement *currentHead = &seqList; - SeqListElement *tempHead = currentHead; + Common::List<SeqListElement>::iterator it; - while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { - tempHead = currentHead; - currentHead = tempHead->next; - } - - if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) { - currentHead->var4 = -1; + for (it = seqList.begin(); it != seqList.end(); ++it) { + if (it->objIdx == param1 && it->var4 == param2 && it->varE == param3) { + it->var4 = -1; + break; + } } } uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3) { - SeqListElement *currentHead = &seqList; - SeqListElement *tempHead = currentHead; - - while (currentHead && (currentHead->var6 != param1 || currentHead->var4 != param2 || currentHead->varE != param3)) { - tempHead = currentHead; - currentHead = tempHead->next; - } + Common::List<SeqListElement>::iterator it; - if (currentHead && currentHead->var6 == param1 && currentHead->var4 == param2 && currentHead->varE == param3) { - return 1; + for (it = seqList.begin(); it != seqList.end(); ++it) { + if (it->objIdx == param1 && it->var4 == param2 && it->varE == param3) { + return 1; + } } return 0; } -void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8) { - SeqListElement *currentHead = &seqList; - SeqListElement *tempHead = currentHead; - SeqListElement *newElement; - - currentHead = tempHead->next; - - while (currentHead && currentHead->varE < param7) { - tempHead = currentHead; - currentHead = tempHead->next; - } - - newElement = new SeqListElement; - - newElement->next = tempHead->next; - tempHead->next = newElement; - - newElement->var6 = param0; - newElement->var4 = param1; - newElement->var8 = param2; - newElement->varA = param3; - newElement->varC = param4; - newElement->var14 = 0; - newElement->var16 = 0; - newElement->var18 = param5; - newElement->var1A = param6; - newElement->varE = param7; - newElement->var10 = param8; - newElement->var12 = param8; - newElement->var1C = 0; - newElement->var1E = 0; -} - -void resetSeqList() { - seqList.next = NULL; +void addSeqListElement(uint16 objIdx, int16 param1, int16 param2, int16 frame, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8) { + Common::List<SeqListElement>::iterator it; + SeqListElement tmp; + + for (it = seqList.begin(); it != seqList.end() && it->varE < param7; ++it) ; + + tmp.objIdx = objIdx; + tmp.var4 = param1; + tmp.var8 = param2; + tmp.frame = frame; + tmp.varC = param4; + tmp.var14 = 0; + tmp.var16 = 0; + tmp.var18 = param5; + tmp.var1A = param6; + tmp.varE = param7; + tmp.var10 = param8; + tmp.var12 = param8; + tmp.var1C = 0; + tmp.var1E = 0; + + seqList.insert(it, tmp); } -void computeMove1(SeqListElement *element, int16 x, int16 y, int16 param1, +void computeMove1(SeqListElement &element, int16 x, int16 y, int16 param1, int16 param2, int16 x2, int16 y2) { - element->var16 = 0; - element->var14 = 0; + element.var16 = 0; + element.var14 = 0; if (y2) { if (y - param2 > y2) { - element->var16 = 2; + element.var16 = 2; } if (y + param2 < y2) { - element->var16 = 1; + element.var16 = 1; } } if (x2) { if (x - param1 > x2) { - element->var14 = 2; + element.var14 = 2; } if (x + param1 < x2) { - element->var14 = 1; + element.var14 = 1; } } } -uint16 computeMove2(SeqListElement *element) { +uint16 computeMove2(SeqListElement &element) { int16 returnVar = 0; - if (element->var16 == 1) { + if (element.var16 == 1) { returnVar = 4; - } else if (element->var16 == 2) { + } else if (element.var16 == 2) { returnVar = 3; } - if (element->var14 == 1) { + if (element.var14 == 1) { returnVar = 1; - } else if (element->var14 == 2) { + } else if (element.var14 == 2) { returnVar = 2; } @@ -2165,14 +1734,13 @@ void resetGfxEntityEntry(uint16 objIdx) { #endif } -uint16 addAni(uint16 param1, uint16 param2, const byte *ptr, SeqListElement *element, uint16 param3, int16 *param4) { +uint16 addAni(uint16 param1, uint16 objIdx, const byte *ptr, SeqListElement &element, uint16 param3, int16 *param4) { const byte *currentPtr = ptr; const byte *ptrData; const byte *ptr2; int16 di; assert(ptr); - assert(element); assert(param4); dummyU16 = READ_BE_UINT16((currentPtr + param1 * 2) + 8); @@ -2181,25 +1749,25 @@ uint16 addAni(uint16 param1, uint16 param2, const byte *ptr, SeqListElement *ele assert(*ptrData); - di = (objectTable[param2].costume + 1) % (*ptrData); + di = (objectTable[objIdx].costume + 1) % (*ptrData); ptr2 = (ptrData + (di * 8)) + 1; - if ((checkCollision(param2, ptr2[0], ptr2[1], ptr2[2], ptr[0]) & 1)) { + if ((checkCollision(objIdx, ptr2[0], ptr2[1], ptr2[2], ptr[0]) & 1)) { return 0; } - objectTable[param2].x += (int8)ptr2[4]; - objectTable[param2].y += (int8)ptr2[5]; - objectTable[param2].mask += (int8)ptr2[6]; + objectTable[objIdx].x += (int8)ptr2[4]; + objectTable[objIdx].y += (int8)ptr2[5]; + objectTable[objIdx].mask += (int8)ptr2[6]; - if (objectTable[param2].frame) { - resetGfxEntityEntry(param2); + if (objectTable[objIdx].frame) { + resetGfxEntityEntry(objIdx); } - objectTable[param2].frame = ptr2[7] + element->var8; + objectTable[objIdx].frame = ptr2[7] + element.var8; - if (param3 || !element->var14) { - objectTable[param2].costume = di; + if (param3 || !element.var14) { + objectTable[objIdx].costume = di; } else { *param4 = di; } @@ -2207,86 +1775,86 @@ uint16 addAni(uint16 param1, uint16 param2, const byte *ptr, SeqListElement *ele return 1; } -void processSeqListElement(SeqListElement *element) { - int16 x = objectTable[element->var6].x; - int16 y = objectTable[element->var6].y; - const byte *ptr1 = animDataTable[element->varA].data(); +void processSeqListElement(SeqListElement &element) { + int16 x = objectTable[element.objIdx].x; + int16 y = objectTable[element.objIdx].y; + const byte *ptr1 = animDataTable[element.frame].data(); int16 var_10; int16 var_4; int16 var_2; - if (element->var12 < element->var10) { - element->var12++; + if (element.var12 < element.var10) { + element.var12++; return; } - element->var12 = 0; + element.var12 = 0; if (ptr1) { uint16 param1 = ptr1[1]; uint16 param2 = ptr1[2]; - if (element->varC != 255) { + if (element.varC != 255) { // FIXME: Why is this here? Fingolfin gets lots of these // in his copy of Operation Stealth (value 0 or 236) under // Mac OS X. Maybe it's a endian issue? At least the graphics // in the copy protection screen are partially messed up. - warning("processSeqListElement: varC = %d", element->varC); + warning("processSeqListElement: varC = %d", element.varC); } if (globalVars[VAR_MOUSE_X_POS] || globalVars[VAR_MOUSE_Y_POS]) { computeMove1(element, ptr1[4] + x, ptr1[5] + y, param1, param2, globalVars[VAR_MOUSE_X_POS], globalVars[VAR_MOUSE_Y_POS]); } else { - element->var16 = 0; - element->var14 = 0; + element.var16 = 0; + element.var14 = 0; } var_10 = computeMove2(element); if (var_10) { - element->var1C = var_10; - element->var1E = var_10; + element.var1C = var_10; + element.var1E = var_10; } var_4 = -1; - if ((element->var16 == 1 - && !addAni(3, element->var6, ptr1, element, 0, &var_4)) || (element->var16 == 2 && !addAni(2, element->var6, ptr1, element, 0, + if ((element.var16 == 1 + && !addAni(3, element.objIdx, ptr1, element, 0, &var_4)) || (element.var16 == 2 && !addAni(2, element.objIdx, ptr1, element, 0, &var_4))) { - if (element->varC == 255) { + if (element.varC == 255) { globalVars[VAR_MOUSE_Y_POS] = 0; } } - if ((element->var14 == 1 - && !addAni(0, element->var6, ptr1, element, 1, &var_2))) { - if (element->varC == 255) { + if ((element.var14 == 1 + && !addAni(0, element.objIdx, ptr1, element, 1, &var_2))) { + if (element.varC == 255) { globalVars[VAR_MOUSE_X_POS] = 0; if (var_4 != -1) { - objectTable[element->var6].costume = var_4; + objectTable[element.objIdx].costume = var_4; } } } - if ((element->var14 == 2 && !addAni(1, element->var6, ptr1, element, 1, &var_2))) { - if (element->varC == 255) { + if ((element.var14 == 2 && !addAni(1, element.objIdx, ptr1, element, 1, &var_2))) { + if (element.varC == 255) { globalVars[VAR_MOUSE_X_POS] = 0; if (var_4 != -1) { - objectTable[element->var6].costume = var_4; + objectTable[element.objIdx].costume = var_4; } } } - if (element->var16 + element->var14) { - if (element->var1C) { - if (element->var1E) { - objectTable[element->var6].costume = 0; - element->var1E = 0; + if (element.var16 + element.var14) { + if (element.var1C) { + if (element.var1E) { + objectTable[element.objIdx].costume = 0; + element.var1E = 0; } - addAni(element->var1C + 3, element->var6, ptr1, element, 1, (int16 *) & var2); + addAni(element.var1C + 3, element.objIdx, ptr1, element, 1, (int16 *) & var2); } } @@ -2295,119 +1863,28 @@ void processSeqListElement(SeqListElement *element) { } void processSeqList(void) { - SeqListElement *currentHead = &seqList; - SeqListElement *tempHead = currentHead; + Common::List<SeqListElement>::iterator it; - currentHead = tempHead->next; - - while (currentHead) { - if (currentHead->var4 != -1) { - processSeqListElement(currentHead); + for (it = seqList.begin(); it != seqList.end(); ++it) { + if (it->var4 == -1) { + continue; } - tempHead = currentHead; - currentHead = tempHead->next; + processSeqListElement(*it); } } bool makeTextEntryMenu(const char *messagePtr, char *inputString, int stringMaxLength, int y) { - int16 color = 2; - byte color2 = defaultMenuBoxColor2; - byte endOfMessageReached = 0; - int16 localX, localY, localWidth; - int margins = 16; int len = strlen(messagePtr); int16 width = 6 * len + 20; - uint16 messageLength = 0, numWords = 0, messageWidth = 0; - uint16 lineResult, fullLineWidth; - uint16 interWordSize, interWordSizeRemain; - const char *endOfMessagePtr; - byte currentChar, characterWidth; width = CLIP((int)width, 180, 250); int16 x = (320 - width) / 2; - gfxDrawPlainBoxRaw(x - margins, y, x + width + margins, y + 4, color2, page1Raw); - - localX = x + 4; - localY = y + 4; - localWidth = width; - getKeyData(); // clear input key - do { - messageLength = 0; - - while (messagePtr[messageLength] == ' ') { - messageLength++; - } - - messagePtr += messageLength; - - messageLength = computeMessageLength((const byte *)messagePtr, localWidth, &numWords, &messageWidth, &lineResult); - - endOfMessagePtr = messagePtr + messageLength; - - if (lineResult) { - fullLineWidth = localWidth - messageWidth; - - if (numWords) { - interWordSize = fullLineWidth / numWords; - interWordSizeRemain = fullLineWidth % numWords; - } else { - interWordSize = 5; - interWordSizeRemain = 0; - } - } else { - interWordSize = 5; - interWordSizeRemain = 0; - } - - gfxDrawPlainBoxRaw(x - margins, localY, x + width + margins, localY + 9, color2, page1Raw); - - do { - currentChar = *(messagePtr++); - - if (currentChar == 0) { - endOfMessageReached = 1; - } else if (currentChar == ' ') { - localX += interWordSizeRemain + interWordSize; - - if (interWordSizeRemain) - interWordSizeRemain = 0; - } else { - characterWidth = fontParamTable[currentChar].characterWidth; - - if (characterWidth) { - byte characterIdx = fontParamTable[currentChar].characterIdx; - drawSpriteRaw(textTable[characterIdx][0], textTable[characterIdx][1], 2, 8, page1Raw, localX, localY); - localX += characterWidth + 1; - } - } - } while ((messagePtr < endOfMessagePtr) && !endOfMessageReached); - - localX = x + 4; - localY += 9; - } while (!endOfMessageReached); - - // Input string - gfxDrawPlainBoxRaw(x - margins, localY, x + width + margins, localY + 9, color2, page1Raw); - localY += 9; - - x -= margins; - width += margins * 2; - - gfxDrawPlainBoxRaw(x, localY, x + width, localY + 4, color2, page1Raw); - - drawDoubleMessageBox(x, y, width, localY, color, page1Raw); - - x += margins; - width -= margins * 2; - localY -= 9; - - int quit = 0; bool redraw = true; CommandeType tempString; @@ -2416,24 +1893,8 @@ bool makeTextEntryMenu(const char *messagePtr, char *inputString, int stringMaxL while (!quit) { if (redraw) { - gfxDrawPlainBoxRaw(x, localY - 1, x + width, localY + 8, 0, page1Raw); - - int currentX = x + 4; - - for (uint j = 0; j < strlen(inputString); j++) { - currentChar = inputString[j]; - currentX = drawChar(currentChar, currentX, localY); - - // draw cursor here - if (inputPos == (int)(j + 2)) - gfxDrawLine(currentX, localY - 1, currentX, localY + 8, color, page1Raw); - - } - - if (strlen(inputString) == 0 || inputPos == 1) // cursor wasn't yet drawn - gfxDrawLine(x + 4, localY - 1, x + 4, localY + 8, color, page1Raw); - - blitRawScreen(page1Raw); + renderer->drawInputBox(messagePtr, inputString, inputPos, x - 16, y, width + 32); + renderer->blit(); redraw = false; } diff --git a/engines/cine/various.h b/engines/cine/various.h index f906b2aa19..91662c16ff 100644 --- a/engines/cine/various.h +++ b/engines/cine/various.h @@ -43,11 +43,10 @@ extern bool disableSystemMenu; extern bool inMenu; struct SeqListElement { - struct SeqListElement *next; int16 var4; - int16 var6; + uint16 objIdx; int16 var8; - int16 varA; + int16 frame; int16 varC; int16 varE; int16 var10; @@ -60,7 +59,7 @@ struct SeqListElement { int16 var1E; }; -extern SeqListElement seqList; +extern Common::List<SeqListElement> seqList; extern uint16 var2; extern uint16 var3; @@ -97,7 +96,6 @@ extern char newRelName[20]; extern char newObjectName[20]; extern char newMsgName[20]; -extern char currentBgName[8][15]; extern char currentCtName[15]; extern char currentPartName[15]; @@ -130,20 +128,16 @@ struct SelectedObjStruct { int16 param; }; -extern uint16 defaultMenuBoxColor; -extern uint16 defaultMenuBoxColor2; - #define NUM_MAX_ZONE 16 extern uint16 zoneData[NUM_MAX_ZONE]; void addMessage(byte param1, int16 param2, int16 param3, int16 param4, int16 param5); -extern int16 additionalBgVScroll; +void removeMessages(); void removeSeq(uint16 param1, uint16 param2, uint16 param3); uint16 isSeqRunning(uint16 param1, uint16 param2, uint16 param3); -void addSeqListElement(int16 param0, int16 param1, int16 param2, int16 param3, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8); -void resetSeqList(); +void addSeqListElement(uint16 objIdx, int16 param1, int16 param2, int16 frame, int16 param4, int16 param5, int16 param6, int16 param7, int16 param8); void processSeqList(void); bool makeTextEntryMenu(const char *caption, char *string, int strLen, int y); diff --git a/engines/cine/xref.txt b/engines/cine/xref.txt index 3640ef83d6..5a8d2eef0f 100644 --- a/engines/cine/xref.txt +++ b/engines/cine/xref.txt @@ -1,4 +1,4 @@ -script.cpp: +script_fw.cpp: setupOpcodes() - replaced with FWScript/OSScript class members getNextByte() - replaced with RawScript/FWScript class members getNextWord() - replaced with RawScript/FWScript class members @@ -89,6 +89,9 @@ o1_disableSystemMenu() - replaced with FWScript::o1_disableSystemMenu() o1_loadMask5() - replaced with FWScript::o1_loadMask5() o1_unloadMask5() - replaced with FWScript::o1_unloadMask5() +palRotate() - modified and moved to pal.cpp + +script_os.cpp: o2_loadPart() - replaced with FWScript::o2_loadPart() o2_addSeqListElement() - replaced with FWScript::o2_addSeqListElement() o2_removeSeq() - replaced with FWScript::o2_removeSeq() @@ -134,20 +137,48 @@ releaseObjectScripts() - removed (obsoleted by Common::List::clear()) various.cpp: setupScriptList() - removed (obsoleted by new makeLoad() and loadScriptFromSave() implementation) +drawChar() - removed (obsoleted by FWRenderer::drawChar()) +makeTextEntry() - removed (obsoleted by FWRenderer::drawMenu()) +drawMenuBox() - removed (obsoleted by FWRenderer::drawCommand()) +backupOverlayPage() - removed (obsoleted by FWRenderer::drawBackground()) +drawMessage() - removed (obsoleted by FWRenderer::drawMessage()) +drawDialogueMessage() - removed (obsoleted by FWRenderer::renderOverlay()) +drawFailureMessage() - removed (obsoleted by FWRenderer::renderOverlay()) +drawOverlays() - removed (obsoleted by FWRenderer::drawOverlays()) +resetSeqList() - removed (obsoleted by Common::List) anim.cpp: freeAnimData() - replaced with animData::clear() allocFrame() - replaced with animData::load() reserveFrame() - replaced with animData::load() -bg_list.cpp +bg_list.cpp: reincrustAllBg() - removed (obsoleted by new loadResourcesFromSave() and loadBgIncrustFromSave() implementation) freeBgIncrustList() - removed (obsoleted by Common::List::clear()) -object.cpp +object.cpp: unloadAllMasks() - removed (obsoleted by Common::List::clear()) resetMessageHead() - removed (obsoleted by Common::List) freeOverlay() - removed (duplicate of removeOverlay) removeOverlayElement() - renamed to removeOverlay loadOverlayElement() - renamed to addOverlay + +gfx.cpp: +gfxInit() - removed (obsoleted by FWRenderer) +gfxDestroy() - removed (obsoleted by FWRenderer) +transformColor() - moved to pal.cpp +transformPaletteRange() - modified and moved to pal.cpp +gfxCopyRawPage() - removed (obsoleted by FWRenderer) +gfxFlipRawPage() - removed (obsoleted by FWRenderer::blit() and + FWRenderer::refreshPalette()) +fadeToBlack() - removed (obsoleted by FWRenderer::fadeToBlack()) +blitRawScreen() - removed (obsoleted by FWRenderer) +flip() - removed (obsoleted by FWRenderer::reloadPalette()) + +bg.cpp: +loadCt() - split into loadCtFW() and loadCtOS() +loadBgHigh() - removed (obsoleted by OSRenderer::loadBg256()) + +texte.cpp: +computeMessageLength() - replaced with fitLine() |