diff options
-rw-r--r-- | engines/kyra/debugger.cpp | 5 | ||||
-rw-r--r-- | engines/kyra/gui.cpp | 193 | ||||
-rw-r--r-- | engines/kyra/gui.h | 51 | ||||
-rw-r--r-- | engines/kyra/gui_v1.cpp | 18 | ||||
-rw-r--r-- | engines/kyra/gui_v1.h | 3 | ||||
-rw-r--r-- | engines/kyra/gui_v2.cpp | 195 | ||||
-rw-r--r-- | engines/kyra/kyra.h | 4 | ||||
-rw-r--r-- | engines/kyra/kyra_v1.cpp | 2 | ||||
-rw-r--r-- | engines/kyra/kyra_v2.cpp | 8 | ||||
-rw-r--r-- | engines/kyra/kyra_v2.h | 14 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.cpp | 340 | ||||
-rw-r--r-- | engines/kyra/kyra_v3.h | 51 | ||||
-rw-r--r-- | engines/kyra/module.mk | 1 | ||||
-rw-r--r-- | engines/kyra/resource.cpp | 3 | ||||
-rw-r--r-- | engines/kyra/screen.cpp | 567 | ||||
-rw-r--r-- | engines/kyra/screen.h | 168 | ||||
-rw-r--r-- | engines/kyra/screen_v1.cpp | 190 | ||||
-rw-r--r-- | engines/kyra/screen_v1.h | 29 | ||||
-rw-r--r-- | engines/kyra/screen_v2.cpp | 322 | ||||
-rw-r--r-- | engines/kyra/screen_v2.h | 39 | ||||
-rw-r--r-- | engines/kyra/screen_v3.cpp | 50 | ||||
-rw-r--r-- | engines/kyra/screen_v3.h | 49 | ||||
-rw-r--r-- | engines/kyra/sequences_v2.cpp | 20 | ||||
-rw-r--r-- | engines/kyra/staticres.cpp | 13 | ||||
-rw-r--r-- | engines/kyra/wsamovie.cpp | 47 | ||||
-rw-r--r-- | engines/kyra/wsamovie.h | 10 |
26 files changed, 1159 insertions, 1233 deletions
diff --git a/engines/kyra/debugger.cpp b/engines/kyra/debugger.cpp index b378382be8..ab49f18e97 100644 --- a/engines/kyra/debugger.cpp +++ b/engines/kyra/debugger.cpp @@ -74,10 +74,11 @@ bool Debugger::cmd_loadPalette(int argc, const char **argv) { } if (_vm->gameFlags().gameID != GI_KYRA1 && _vm->resource()->getFileSize(argv[1]) != 768) { - _vm->screen()->savePageToDisk("TEMP", 5); + uint8 buffer[320*200]; + _vm->screen()->copyRegionToBuffer(5, 0, 0, 320, 200, buffer); _vm->screen()->loadBitmap(argv[1], 5, 5, 0); memcpy(palette, _vm->screen()->getCPagePtr(5), 768); - _vm->screen()->loadPageFromDisk("TEMP", 5); + _vm->screen()->copyBlockToPage(5, 0, 0, 320, 200, buffer); } else if (!_vm->screen()->loadPalette(argv[1], palette)) { DebugPrintf("ERROR: Palette '%s' not found!\n", argv[1]); return true; diff --git a/engines/kyra/gui.cpp b/engines/kyra/gui.cpp index 09ce9e9302..170971bc90 100644 --- a/engines/kyra/gui.cpp +++ b/engines/kyra/gui.cpp @@ -27,6 +27,7 @@ #include "kyra/screen.h" #include "kyra/text.h" +#include "kyra/wsamovie.h" #include "common/savefile.h" @@ -334,5 +335,197 @@ int GUI::getNextSavegameSlot() { return 0; } +#pragma mark - + +MainMenu::MainMenu(KyraEngine *vm) : _vm(vm), _screen(0) { + _screen = _vm->screen(); + _nextUpdate = 0; + _system = g_system; +} + +void MainMenu::init(StaticData data, Animation anim) { + _static = data; + _anim = anim; + _animIntern.curFrame = _anim.startFrame; + _animIntern.direction = 1; +} + +void MainMenu::updateAnimation() { + if (_anim.anim) { + uint32 now = _system->getMillis(); + if (now > _nextUpdate) { + _nextUpdate = now + _anim.delay * _vm->tickLength(); + + _anim.anim->displayFrame(_animIntern.curFrame, 0); + _animIntern.curFrame += _animIntern.direction ; + if (_animIntern.curFrame < _anim.startFrame) { + _animIntern.curFrame = _anim.startFrame; + _animIntern.direction = 1; + } else if (_animIntern.curFrame > _anim.endFrame) { + _animIntern.curFrame = _anim.endFrame; + _animIntern.direction = -1; + } + } + } + + _screen->updateScreen(); +} + +bool MainMenu::getInput() { + Common::Event event; + + while (_system->getEventManager()->pollEvent(event)) { + switch (event.type) { + case Common::EVENT_QUIT: + _quitFlag = true; + break; + case Common::EVENT_LBUTTONUP: + return true; + default: + break; + } + } + return false; +} + +int MainMenu::handle(int dim) { + debugC(9, kDebugLevelMain, "MainMenu::handle(%d)", dim); + int command = -1; + _quitFlag = false; + + uint8 colorMap[16]; + memset(colorMap, 0, sizeof(colorMap)); + _screen->setTextColorMap(colorMap); + + Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT); + int charWidthBackUp = _screen->_charWidth; + + _screen->_charWidth = -2; + _screen->setScreenDim(dim); + + int backUpX = _screen->_curDim->sx; + int backUpY = _screen->_curDim->sy; + int backUpWidth = _screen->_curDim->w; + int backUpHeight = _screen->_curDim->h; + _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3); + + int x = _screen->_curDim->sx << 3; + int y = _screen->_curDim->sy; + int width = _screen->_curDim->w << 3; + int height = _screen->_curDim->h; + + drawBox(x, y, width, height, 1); + drawBox(x + 1, y + 1, width - 2, height - 2, 0); + + int selected = 0; + + draw(selected); + + _screen->showMouse(); + + int fh = _screen->getFontHeight(); + int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3; + + Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * 4); + + while (!_quitFlag) { + updateAnimation(); + bool mousePressed = getInput(); + + Common::Point mouse = _vm->getMousePos(); + if (menuRect.contains(mouse)) { + int item = (mouse.y - menuRect.top) / fh; + + if (item != selected) { + printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorNormal, 0, 5); + printString(_static.strings[item], textPos, menuRect.top + item * fh, _static.colorFlash, 0, 5); + + selected = item; + } + + if (mousePressed) { + for (int i = 0; i < 3; i++) { + printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorNormal, 0, 5); + _screen->updateScreen(); + _system->delayMillis(50); + printString(_static.strings[selected], textPos, menuRect.top + selected * fh, _static.colorFlash, 0, 5); + _screen->updateScreen(); + _system->delayMillis(50); + } + command = item; + break; + } + } + _system->delayMillis(10); + } + + if (_quitFlag) + command = -1; + + _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0); + _screen->_charWidth = charWidthBackUp; + _screen->setFont(oldFont); + + return command; +} + +void MainMenu::draw(int select) { + debugC(9, kDebugLevelMain, "MainMenu::draw(%d)", select); + int top = _screen->_curDim->sy; + top += _static.menuTable[1]; + + for (int i = 0; i < _static.menuTable[3]; ++i) { + int curY = top + i * _screen->getFontHeight(); + int color = (i == select) ? _static.menuTable[6] : _static.menuTable[5]; + printString(_static.strings[i], ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5); + } +} + +void MainMenu::drawBox(int x, int y, int w, int h, int fill) { + debugC(9, kDebugLevelMain, "MainMenu::drawBox(%d, %d, %d, %d, %d)", x, y, w, h, fill); + --w; --h; + + if (fill) + _screen->fillRect(x, y, x+w, y+h, _static.colorTable[0]); + + _screen->drawClippedLine(x, y+h, x+w, y+h, _static.colorTable[1]); + _screen->drawClippedLine(x+w, y, x+w, y+h, _static.colorTable[1]); + _screen->drawClippedLine(x, y, x+w, y, _static.colorTable[2]); + _screen->drawClippedLine(x, y, x, y+h, _static.colorTable[2]); + + _screen->setPagePixel(_screen->_curPage, x, y+h, _static.colorTable[3]); + _screen->setPagePixel(_screen->_curPage, x+w, y, _static.colorTable[3]); +} + +void MainMenu::printString(const char *format, int x, int y, int col1, int col2, int flags, ...) { + debugC(9, kDebugLevelMain, "MainMenu::printString('%s', %d, %d, %d, %d, %d, ...)", format, x, y, col1, col2, flags); + if (!format) + return; + + char string[512]; + va_list vaList; + va_start(vaList, flags); + vsprintf(string, format, vaList); + va_end(vaList); + + if (flags & 1) + x -= _screen->getTextWidth(string) >> 1; + + if (flags & 2) + x -= _screen->getTextWidth(string); + + if (flags & 4) { + _screen->printText(string, x - 1, y, 240, col2); + _screen->printText(string, x, y + 1, 240, col2); + } + + if (flags & 8) { + _screen->printText(string, x - 1, y, 227, col2); + _screen->printText(string, x, y + 1, 227, col2); + } + + _screen->printText(string, x, y, col1, col2); +} + } // end of namespace Kyra diff --git a/engines/kyra/gui.h b/engines/kyra/gui.h index 17f13469e9..214f112995 100644 --- a/engines/kyra/gui.h +++ b/engines/kyra/gui.h @@ -191,6 +191,57 @@ protected: int getNextSavegameSlot(); }; +class Movie; + +class MainMenu { +public: + MainMenu(KyraEngine *vm); + virtual ~MainMenu() {} + + struct Animation { + Animation() : anim(0), startFrame(0), endFrame(0), delay(0) {} + + Movie *anim; + int startFrame; + int endFrame; + int delay; + }; + + struct StaticData { + const char *strings[4]; + + uint8 menuTable[11]; + uint8 colorTable[4]; + uint8 colorNormal, colorFlash; + }; + + void init(StaticData data, Animation anim); + int handle(int dim); +private: + KyraEngine *_vm; + Screen *_screen; + OSystem *_system; + + bool _quitFlag; + + StaticData _static; + struct AnimIntern { + int curFrame; + int direction; + }; + Animation _anim; + AnimIntern _animIntern; + + uint32 _nextUpdate; + + void updateAnimation(); + void draw(int select); + void drawBox(int x, int y, int w, int h, int fill); + bool getInput(); + + void printString(const char *string, int x, int y, int col1, int col2, int flags, ...); +}; + } // end of namesapce Kyra #endif diff --git a/engines/kyra/gui_v1.cpp b/engines/kyra/gui_v1.cpp index fd6e0cbdf5..61129956b6 100644 --- a/engines/kyra/gui_v1.cpp +++ b/engines/kyra/gui_v1.cpp @@ -186,7 +186,7 @@ int KyraEngine_v1::buttonAmuletCallback(Button *caller) { #pragma mark - -GUI_v1::GUI_v1(KyraEngine_v1 *vm) : GUI(vm), _vm(vm) { +GUI_v1::GUI_v1(KyraEngine_v1 *vm, Screen_v1 *screen) : GUI(vm), _vm(vm), _screen(screen) { _menu = 0; initStaticResource(); _scrollUpFunctor = BUTTON_FUNCTOR(GUI_v1, this, &GUI_v1::scrollUp); @@ -212,16 +212,16 @@ int GUI_v1::processButtonList(Button *list, uint16 inputFlag) { int x = list->x; int y = list->y; - assert(list->dimTableIndex < _screen->_screenDimTableCount); + assert(_screen->getScreenDim(list->dimTableIndex) != 0); if (x < 0) { - x += _screen->_screenDimTable[list->dimTableIndex].w << 3; + x += _screen->getScreenDim(list->dimTableIndex)->w << 3; } - x += _screen->_screenDimTable[list->dimTableIndex].sx << 3; + x += _screen->getScreenDim(list->dimTableIndex)->sx << 3; if (y < 0) { - y += _screen->_screenDimTable[list->dimTableIndex].h; + y += _screen->getScreenDim(list->dimTableIndex)->h; } - y += _screen->_screenDimTable[list->dimTableIndex].sy; + y += _screen->getScreenDim(list->dimTableIndex)->sy; Common::Point mouse = _vm->getMousePos(); if (mouse.x >= x && mouse.y >= y && x + list->width >= mouse.x && y + list->height >= mouse.y) { @@ -302,12 +302,12 @@ void GUI_v1::processButton(Button *button) { int x = button->x; int y = button->y; - assert(button->dimTableIndex < _screen->_screenDimTableCount); + assert(_screen->getScreenDim(button->dimTableIndex) != 0); if (x < 0) - x += _screen->_screenDimTable[button->dimTableIndex].w << 3; + x += _screen->getScreenDim(button->dimTableIndex)->w << 3; if (y < 0) - y += _screen->_screenDimTable[button->dimTableIndex].h; + y += _screen->getScreenDim(button->dimTableIndex)->h; if (processType == 1 && shape) _screen->drawShape(_screen->_curPage, shape, x, y, button->dimTableIndex, 0x10); diff --git a/engines/kyra/gui_v1.h b/engines/kyra/gui_v1.h index 94c7013ad3..8155d604d6 100644 --- a/engines/kyra/gui_v1.h +++ b/engines/kyra/gui_v1.h @@ -89,7 +89,7 @@ class KyraEngine_v1; class GUI_v1 : public GUI { friend class KyraEngine_v1; public: - GUI_v1(KyraEngine_v1 *vm); + GUI_v1(KyraEngine_v1 *vm, Screen_v1 *screen); ~GUI_v1(); void processButton(Button *button); @@ -150,6 +150,7 @@ private: const char *getMenuItemLabel(const MenuItem &menuItem) { return menuItem.labelString; } KyraEngine_v1 *_vm; + Screen_v1 *_screen; bool _menuRestoreScreen; uint8 _toplevelMenu; diff --git a/engines/kyra/gui_v2.cpp b/engines/kyra/gui_v2.cpp index fa74f0def0..80b54116ce 100644 --- a/engines/kyra/gui_v2.cpp +++ b/engines/kyra/gui_v2.cpp @@ -34,199 +34,6 @@ namespace Kyra { -void KyraEngine_v2::gui_updateMainMenuAnimation() { - _screen->updateScreen(); -} - -bool KyraEngine_v2::gui_mainMenuGetInput() { - Common::Event event; - - while (_eventMan->pollEvent(event)) { - switch (event.type) { - case Common::EVENT_QUIT: - quitGame(); - break; - case Common::EVENT_LBUTTONUP: - return true; - default: - break; - } - } - return false; -} - -int KyraEngine_v2::gui_handleMainMenu() { - debugC(9, kDebugLevelMain, "KyraEngine_v2::gui_handleMainMenu()"); - int command = -1; - - uint8 colorMap[16]; - memset(colorMap, 0, sizeof(colorMap)); - _screen->setTextColorMap(colorMap); - - const char * const *strings; - const char *k2strings[4]; - - Screen::FontId oldFont = _screen->setFont(Screen::FID_8_FNT); - int charWidthBackUp = _screen->_charWidth; - - _screen->_charWidth = -2; - - if (_flags.gameID == GI_KYRA2) { - _screen->setScreenDim(11); - k2strings[0] = _sequenceStrings[97]; - k2strings[1] = _sequenceStrings[96]; - k2strings[2] = _sequenceStrings[95]; - k2strings[3] = _sequenceStrings[98]; - strings = k2strings; - } else { - _screen->setScreenDim(3); - strings = &_mainMenuStrings[_lang << 2]; - } - - int backUpX = _screen->_curDim->sx; - int backUpY = _screen->_curDim->sy; - int backUpWidth = _screen->_curDim->w; - int backUpHeight = _screen->_curDim->h; - _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 0, 3); - - int x = _screen->_curDim->sx << 3; - int y = _screen->_curDim->sy; - int width = _screen->_curDim->w << 3; - int height = _screen->_curDim->h; - - gui_drawMainBox(x, y, width, height, 1); - gui_drawMainBox(x + 1, y + 1, width - 2, height - 2, 0); - - int selected = 0; - - gui_drawMainMenu(strings, selected); - - _screen->showMouse(); - - int fh = _screen->getFontHeight(); - int textPos = ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3; - - Common::Rect menuRect(x + 16, y + 4, x + width - 16, y + 4 + fh * 4); - - while (!_quitFlag) { - gui_updateMainMenuAnimation(); - bool mousePressed = gui_mainMenuGetInput(); - - Common::Point mouse = getMousePos(); - if (menuRect.contains(mouse)) { - int item = (mouse.y - menuRect.top) / fh; - - if (item != selected) { - gui_printString(strings[selected], textPos, menuRect.top + selected * fh, (_flags.gameID == GI_KYRA3) ? 0x80 : 0xd7, 0, 5); - gui_printString(strings[item], textPos, menuRect.top + item * fh, (_flags.gameID == GI_KYRA3) ? 0xFF : 0xd6, 0, 5); - - selected = item; - } - - if (mousePressed) { - for (int i = 0; i < 3; i++) { - gui_printString(strings[selected], textPos, menuRect.top + selected * fh, (_flags.gameID == GI_KYRA3) ? 0x80 : 0xd7, 0, 5); - _screen->updateScreen(); - _system->delayMillis(50); - gui_printString(strings[selected], textPos, menuRect.top + selected * fh, (_flags.gameID == GI_KYRA3) ? 0xFF : 0xd6, 0, 5); - _screen->updateScreen(); - _system->delayMillis(50); - } - command = item; - break; - } - } - _system->delayMillis(10); - } - - if (_quitFlag) - command = -1; - - _screen->copyRegion(backUpX, backUpY, backUpX, backUpY, backUpWidth, backUpHeight, 3, 0); - _screen->_charWidth = charWidthBackUp; - _screen->setFont(oldFont); - - return command; -} - -void KyraEngine_v2::gui_drawMainMenu(const char *const *strings, int select) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::gui_drawMainMenu(%p)", (const void*)strings); - static const uint16 menuTable2[] = { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6, 0x00, 0x01, 0x02, 0x03 }; - static const uint16 menuTable3[] = { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 }; - const uint16 *menuTable; - - if (_flags.gameID == GI_KYRA3) - menuTable = menuTable3; - else - menuTable = menuTable2; - - int top = _screen->_curDim->sy; - top += menuTable[1]; - - for (int i = 0; i < menuTable[3]; ++i) { - int curY = top + i * _screen->getFontHeight(); - int color = (i == select) ? menuTable[6] : menuTable[5]; - gui_printString(strings[i], ((_screen->_curDim->w >> 1) + _screen->_curDim->sx) << 3, curY, color, 0, 5); - } -} - -void KyraEngine_v2::gui_drawMainBox(int x, int y, int w, int h, int fill) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::gui_drawMainBox(%d, %d, %d, %d, %d)", x, y, w, h, fill); - static const uint8 kyra3ColorTable[] = { 0x16, 0x19, 0x1A, 0x16 }; - static const uint8 kyra2ColorTable[] = { 0xd8, 0xda, 0xd9, 0xd8 }; - - const uint8 *colorTable; - if (_flags.gameID == GI_KYRA3) - colorTable = kyra3ColorTable; - else - colorTable = kyra2ColorTable; - - --w; --h; - - if (fill) - _screen->fillRect(x, y, x+w, y+h, colorTable[0]); - - _screen->drawClippedLine(x, y+h, x+w, y+h, colorTable[1]); - _screen->drawClippedLine(x+w, y, x+w, y+h, colorTable[1]); - _screen->drawClippedLine(x, y, x+w, y, colorTable[2]); - _screen->drawClippedLine(x, y, x, y+h, colorTable[2]); - - _screen->setPagePixel(_screen->_curPage, x, y+h, colorTable[3]); - _screen->setPagePixel(_screen->_curPage, x+w, y, colorTable[3]); -} - -void KyraEngine_v2::gui_printString(const char *format, int x, int y, int col1, int col2, int flags, ...) { - debugC(9, kDebugLevelMain, "KyraEngine_v2::gui_printString('%s', %d, %d, %d, %d, %d, ...)", format, x, y, col1, col2, flags); - if (!format) - return; - - char string[512]; - va_list vaList; - va_start(vaList, flags); - vsprintf(string, format, vaList); - va_end(vaList); - - if (flags & 1) - x -= _screen->getTextWidth(string) >> 1; - - if (flags & 2) - x -= _screen->getTextWidth(string); - - if (flags & 4) { - _screen->printText(string, x - 1, y, 240, col2); - _screen->printText(string, x, y + 1, 240, col2); - } - - if (flags & 8) { - _screen->printText(string, x - 1, y, 227, col2); - _screen->printText(string, x, y + 1, 227, col2); - } - - _screen->printText(string, x, y, col1, col2); -} - -#pragma mark - - void KyraEngine_v2::loadButtonShapes() { const uint8 *src = _screen->getCPagePtr(3); _screen->loadBitmap("_BUTTONS.CSH", 3, 3, 0); @@ -796,7 +603,7 @@ void KyraEngine_v2::redrawInventory(int page) { } void KyraEngine_v2::scrollInventoryWheel() { - WSAMovieV2 movie(this); + WSAMovieV2 movie(this, _screen); movie.open("INVWHEEL.WSA", 0, 0); int frames = movie.opened() ? movie.frames() : 6; memcpy(_screenBuffer, _screen->getCPagePtr(2), 64000); diff --git a/engines/kyra/kyra.h b/engines/kyra/kyra.h index 2fac6a039b..20a7ba7c7f 100644 --- a/engines/kyra/kyra.h +++ b/engines/kyra/kyra.h @@ -128,6 +128,9 @@ public: Common::RandomSource _rnd; + // input + Common::Point getMousePos() const; + // config specific bool speechEnabled(); bool textEnabled(); @@ -223,7 +226,6 @@ protected: int _trackMapSize; // input - Common::Point getMousePos() const; void setMousePos(int x, int y); // pathfinder diff --git a/engines/kyra/kyra_v1.cpp b/engines/kyra/kyra_v1.cpp index 3705c29763..90e62895d0 100644 --- a/engines/kyra/kyra_v1.cpp +++ b/engines/kyra/kyra_v1.cpp @@ -180,7 +180,7 @@ int KyraEngine_v1::init() { assert(*_animator); _text = new TextDisplayer(this, screen()); assert(_text); - _gui = new GUI_v1(this); + _gui = new GUI_v1(this, _screen); assert(_gui); initStaticResource(); diff --git a/engines/kyra/kyra_v2.cpp b/engines/kyra/kyra_v2.cpp index a4adf26798..e4beedecd5 100644 --- a/engines/kyra/kyra_v2.cpp +++ b/engines/kyra/kyra_v2.cpp @@ -179,7 +179,7 @@ KyraEngine_v2::~KyraEngine_v2() { } Movie *KyraEngine_v2::createWSAMovie() { - return new WSAMovieV2(this); + return new WSAMovieV2(this, _screen); } int KyraEngine_v2::init() { @@ -329,10 +329,10 @@ void KyraEngine_v2::startup() { memset(_sceneAnims, 0, sizeof(_sceneAnims)); for (int i = 0; i < ARRAYSIZE(_sceneAnimMovie); ++i) - _sceneAnimMovie[i] = new WSAMovieV2(this); + _sceneAnimMovie[i] = new WSAMovieV2(this, _screen); memset(_wsaSlots, 0, sizeof(_wsaSlots)); for (int i = 0; i < ARRAYSIZE(_wsaSlots); ++i) - _wsaSlots[i] = new WSAMovieV2(this); + _wsaSlots[i] = new WSAMovieV2(this, _screen); _screen->_curPage = 0; @@ -1855,7 +1855,7 @@ void KyraEngine_v2::loadInvWsa(const char *filename, int run, int delayTime, int wsaFlags |= 2; if (!_invWsa.wsa) - _invWsa.wsa = new WSAMovieV2(this); + _invWsa.wsa = new WSAMovieV2(this, _screen); if (!_invWsa.wsa->open(filename, wsaFlags, 0)) error("Couldn't open inventory WSA file '%s'", filename); diff --git a/engines/kyra/kyra_v2.h b/engines/kyra/kyra_v2.h index f273b7dce1..c0cdaaebbb 100644 --- a/engines/kyra/kyra_v2.h +++ b/engines/kyra/kyra_v2.h @@ -202,18 +202,6 @@ public: virtual Movie *createWSAMovie(); protected: - // Main menu code, also used for Kyra 3 - static const char *_mainMenuStrings[]; - - virtual void gui_initMainMenu() {} - int gui_handleMainMenu(); - virtual void gui_updateMainMenuAnimation(); - void gui_drawMainMenu(const char *const *strings, int select); - void gui_drawMainBox(int x, int y, int w, int h, int fill); - bool gui_mainMenuGetInput(); - - void gui_printString(const char *string, int x, int y, int col1, int col2, int flags, ...); - // intro/outro void seq_playSequences(int startSeq, int endSeq = -1); @@ -328,6 +316,8 @@ protected: void loadItemShapes(); // run + MainMenu *_menu; + bool _runFlag; bool _showCredits; diff --git a/engines/kyra/kyra_v3.cpp b/engines/kyra/kyra_v3.cpp index 666de9f478..0d6b1934d9 100644 --- a/engines/kyra/kyra_v3.cpp +++ b/engines/kyra/kyra_v3.cpp @@ -25,20 +25,18 @@ #include "kyra/kyra.h" #include "kyra/kyra_v3.h" -#include "kyra/screen.h" +#include "kyra/screen_v3.h" #include "kyra/wsamovie.h" #include "kyra/sound.h" #include "kyra/text.h" #include "kyra/vqa.h" +#include "kyra/gui.h" #include "common/system.h" #include "common/config-manager.h" -// TODO: Temporary, to get the mouse cursor mock-up working -#include "graphics/cursorman.h" - namespace Kyra { -KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngine_v2(system, flags) { +KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngine(system, flags) { _soundDigital = 0; _musicSoundChannel = -1; _menuAudioFile = "TITLE1.AUD"; @@ -46,10 +44,8 @@ KyraEngine_v3::KyraEngine_v3(OSystem *system, const GameFlags &flags) : KyraEngi _unkPage1 = _unkPage2 = 0; _interfaceCPS1 = _interfaceCPS2 = 0; memset(_gameShapes, 0, sizeof(_gameShapes)); - _shapePoolBuffer = 0; _itemBuffer1 = _itemBuffer2 = 0; _mouseSHPBuf = 0; - _tableBuffer1 = _tableBuffer2 = 0; _unkBuffer5 = _unkBuffer6 = _unkBuffer7 = _unkBuffer9 = 0; _costpalData = 0; _unkWSAPtr = 0; @@ -70,8 +66,6 @@ KyraEngine_v3::~KyraEngine_v3() { delete [] _itemBuffer1; delete [] _itemBuffer2; - delete [] _shapePoolBuffer; - delete [] _mouseSHPBuf; delete [] _unkBuffer5; @@ -88,15 +82,13 @@ KyraEngine_v3::~KyraEngine_v3() { } int KyraEngine_v3::init() { - _screen = new Screen_v2(this, _system); + _screen = new Screen_v3(this, _system); assert(_screen); if (!_screen->init()) error("_screen->init() failed"); KyraEngine::init(); - gui_initMainMenu(); - _soundDigital = new SoundDigital(this, _mixer); assert(_soundDigital); if (!_soundDigital->init()) @@ -108,12 +100,6 @@ int KyraEngine_v3::init() { _screen->setAnimBlockPtr(3500); _screen->setScreenDim(0); - _shapePoolBuffer = new uint8[300000]; - assert(_shapePoolBuffer); - memset(_shapePoolBuffer, 0, 300000); - - initTableBuffer(_shapePoolBuffer, 300000); - _itemBuffer1 = new uint8[72]; _itemBuffer2 = new uint8[144]; assert(_itemBuffer1 && _itemBuffer2); @@ -132,47 +118,38 @@ int KyraEngine_v3::init() { } int KyraEngine_v3::go() { - uint8 *pal = _screen->getPalette(1); - assert(pal); - - _mainMenuLogo = createWSAMovie(); - assert(_mainMenuLogo); - _mainMenuLogo->open("REVENGE.WSA", 1, pal); - assert(_mainMenuLogo->opened()); - bool running = true; + initMainMenu(); while (running && !_quitFlag) { _screen->_curPage = 0; _screen->clearPage(0); - pal[0] = pal[1] = pal[2] = 0; - - _screen->setScreenPalette(pal); + _screen->setScreenPalette(_screen->getPalette(0)); // XXX playMenuAudioFile(); - _mainMenuLogo->setX(0); _mainMenuLogo->setY(0); - _mainMenuLogo->setDrawPage(0); + _menuAnim->setX(0); _menuAnim->setY(0); + _menuAnim->setDrawPage(0); for (int i = 0; i < 64 && !_quitFlag; ++i) { uint32 nextRun = _system->getMillis() + 3 * _tickLength; - _mainMenuLogo->displayFrame(i); + _menuAnim->displayFrame(i, 0); _screen->updateScreen(); delayUntil(nextRun); } for (int i = 64; i > 29 && !_quitFlag; --i) { uint32 nextRun = _system->getMillis() + 3 * _tickLength; - _mainMenuLogo->displayFrame(i); + _menuAnim->displayFrame(i, 0); _screen->updateScreen(); delayUntil(nextRun); } - switch (gui_handleMainMenu()) { + switch (_menu->handle(3)) { case 0: - delete _mainMenuLogo; - _mainMenuLogo = 0; + uninitMainMenu(); + preinit(); realInit(); // XXX @@ -184,13 +161,13 @@ int KyraEngine_v3::go() { break; case 2: - //delete _mainMenuLogo; - //_mainMenuLogo = 0; + //uninitMainMenu(); //show load dialog //running = false; break; case 3: + uninitMainMenu(); _soundDigital->beginFadeOut(_musicSoundChannel); _screen->fadeToBlack(); _soundDigital->stopSound(_musicSoundChannel); @@ -199,14 +176,45 @@ int KyraEngine_v3::go() { break; default: + uninitMainMenu(); + quitGame(); + running = false; break; } } - delete _mainMenuLogo; return 0; } +void KyraEngine_v3::initMainMenu() { + _menuAnim = createWSAMovie(); + _menuAnim->open("REVENGE.WSA", 1, _screen->getPalette(0)); + memset(_screen->getPalette(0), 0, 3); + + _menu = new MainMenu(this); + MainMenu::StaticData data = { + { _mainMenuStrings[_lang*4+0], _mainMenuStrings[_lang*4+1], _mainMenuStrings[_lang*4+2], _mainMenuStrings[_lang*4+3] }, + { 0x01, 0x04, 0x0C, 0x04, 0x00, 0x80, 0xFF, 0x00, 0x01, 0x02, 0x03 }, + { 0x16, 0x19, 0x1A, 0x16 }, + 0x80, 0xFF + }; + + MainMenu::Animation anim; + anim.anim = _menuAnim; + anim.startFrame = 29; + anim.endFrame = 63; + anim.delay = 2; + + _menu->init(data, anim); +} + +void KyraEngine_v3::uninitMainMenu() { + delete _menuAnim; + _menuAnim = 0; + delete _menu; + _menu = 0; +} + void KyraEngine_v3::playVQA(const char *name) { debugC(9, kDebugLevelMain, "KyraEngine::playVQA('%s')", name); VQAMovie vqa(this, _system); @@ -315,39 +323,6 @@ int KyraEngine_v3::musicUpdate(int forceRestart) { #pragma mark - -void KyraEngine_v3::gui_initMainMenu() { - KyraEngine_v2::gui_initMainMenu(); - _mainMenuFrame = 29; - _mainMenuFrameAdd = 1; -} - -void KyraEngine_v3::gui_updateMainMenuAnimation() { - uint32 nextRun = 0; - - uint32 now = _system->getMillis(); - if (now < nextRun) - return; - - // yes 2 * _tickLength here not 3 * like in the first draw - nextRun = now + 2 * _tickLength; - - _mainMenuLogo->displayFrame(_mainMenuFrame); - _screen->updateScreen(); - - _mainMenuFrame += _mainMenuFrameAdd; - if (_mainMenuFrame < 29) { - _mainMenuFrame = 29; - _mainMenuFrameAdd = 1; - } else if (_mainMenuFrame > 63) { - _mainMenuFrame = 64; - _mainMenuFrameAdd = -1; - } - - // XXX -} - -#pragma mark - - void KyraEngine_v3::preinit() { debugC(9, kDebugLevelMain, "KyraEngine::preinit()"); @@ -404,216 +379,6 @@ void KyraEngine_v3::realInit() { musicUpdate(0); } -#pragma mark - - -int KyraEngine_v3::initTableBuffer(uint8 *buf, int size) { - debugC(9, kDebugLevelMain, "KyraEngine::initTableBuffer(%p, %d)", (void *)buf, size); - - if (!buf || size < 6320) - return 0; - - if (_tableBuffer2 != _tableBuffer1 && _tableBuffer2 && _tableBuffer1) { - // no idea if this *should* be called - memmove(_tableBuffer2, _tableBuffer1, 6320); - } - - _tableBuffer1 = buf; - size -= 6320; - - *((uint16*)(_tableBuffer1)) = 0; - *((uint16*)(_tableBuffer1 + 2)) = 1; - *((uint16*)(_tableBuffer1 + 4)) = 1; - *((uint32*)(_tableBuffer1 + 6)) = size >> 4; - *((uint16*)(_tableBuffer1 + 10)) = 1; - *((uint32*)(_tableBuffer1 + 16)) = 6320; - *((uint32*)(_tableBuffer1 + 22)) = size >> 4; - - _tableBuffer2 = buf; - - return 1; -} - -void KyraEngine_v3::updateTableBuffer(uint8 *buf) { - debugC(9, kDebugLevelMain, "KyraEngine::updateTableBuffer(%p)", (void *)buf); - - if (_tableBuffer2 == buf) - return; - - if (_tableBuffer1 != _tableBuffer2) - memmove(_tableBuffer2, _tableBuffer1, 6320); - - _tableBuffer2 = _tableBuffer1 = buf; -} - -int KyraEngine_v3::addShapeToTable(const uint8 *buf, int id, int shapeNum) { - debugC(9, kDebugLevelMain, "KyraEngine::addShapeToTable(%p, %d, %d)", (const void *)buf, id, shapeNum); - - if (!buf) - return 0; - - const uint8 *shapePtr = _screen->getPtrToShape(buf, shapeNum); - if (!shapePtr) - return 0; - - int shapeSize = _screen->getShapeSize(shapePtr); - - if (getTableSize(_shapePoolBuffer) < shapeSize) { - // XXX - error("[1] unimplemented table handling"); - } - - uint8 *ptr = allocTableSpace(_shapePoolBuffer, shapeSize, id); - - if (!ptr) { - // XXX - error("[2] unimplemented table handling"); - } - - if (!ptr) { - warning("adding shape %d to _shapePoolBuffer not possible, not enough space left\n", id); - return shapeSize; - } - - memcpy(ptr, shapePtr, shapeSize); - return shapeSize; -} - -int KyraEngine_v3::getTableSize(uint8 *buf) { - debugC(9, kDebugLevelMain, "KyraEngine::getTableSize(%p)", (void *)buf); - updateTableBuffer(buf); - - if (*((uint16*)(_tableBuffer1 + 4)) >= 450) - return 0; - - return (*((uint32*)(_tableBuffer1 + 6)) << 4); -} - -uint8 *KyraEngine_v3::allocTableSpace(uint8 *buf, int size, int id) { - debugC(9, kDebugLevelMain, "KyraEngine::allocTableSpace(%p, %d, %d)", (void *)buf, size, id); - - if (!buf || !size) - return 0; - - updateTableBuffer(buf); - - int entries = *(uint16*)(_tableBuffer1 + 4); - - if (entries >= 450) - return 0; - - size += 0xF; - size &= 0xFFFFFFF0; - - uint size2 = size >> 4; - - if (*(uint32*)(_tableBuffer1 + 6) < size2) - return 0; - - int unk1 = *(uint16*)(_tableBuffer1); - int usedEntry = unk1; - int ok = 0; - - for (; usedEntry < entries; ++usedEntry) { - if (size2 <= *(uint32*)(_tableBuffer1 + usedEntry * 14 + 22)) { - ok = 1; - break; - } - } - - if (!ok) - return 0; - - ok = 0; - int unk3 = unk1 - 1; - while (ok <= unk3) { - int temp = (ok + unk3) >> 1; - - if (*(uint32*)(_tableBuffer1 + temp * 14 + 12) >= (uint)id) { - if (*(uint32*)(_tableBuffer1 + temp * 14 + 12) <= (uint)id) { - return 0; - } else { - unk3 = temp - 1; - continue; - } - } - - ok = temp + 1; - } - - uint8 *buf2 = _tableBuffer1 + usedEntry * 14; - - uint unkValue1 = *(uint32*)(buf2 + 16); - uint unkValue2 = *(uint32*)(buf2 + 22); - - if (size2 < unkValue2) { - *(uint32*)(buf2 + 22) = unkValue2 - size2; - *(uint32*)(buf2 + 16) = unkValue1 + size; - memcpy(_tableBuffer1 + entries * 14 + 12, _tableBuffer1 + unk1 * 14 + 12, 14); - } else { - if (usedEntry > unk1) - memcpy(buf2 + 12, _tableBuffer1 + unk1 * 14 + 12, 14); - int temp = *(uint16*)(_tableBuffer1 + 2) - 1; - *(uint16*)(_tableBuffer1 + 2) = temp; - temp = *(uint16*)(_tableBuffer1 + 4) - 1; - *(uint16*)(_tableBuffer1 + 4) = temp; - } - - for (int i = unk1; i > ok; --i) - memcpy(_tableBuffer1 + i * 14 + 12, _tableBuffer1 + (i-1) * 14 + 12, 14); - - buf2 = _tableBuffer1 + ok * 14; - - *(uint32*)(buf2 + 12) = id; - *(uint32*)(buf2 + 16) = unkValue1; - *(uint32*)(buf2 + 20) = (_system->getMillis() / 60) >> 4; - *(uint32*)(buf2 + 22) = size2; - - int temp = *(uint16*)(_tableBuffer1) + 1; - *(uint16*)(_tableBuffer1) = temp; - temp = *(uint16*)(_tableBuffer1 + 4) + 1; - *(uint16*)(_tableBuffer1 + 4) = temp; - - if (temp > *(uint16*)(_tableBuffer1 + 10)) { - *(uint16*)(_tableBuffer1 + 10) = temp; - if (temp > _unkTableValue) - _unkTableValue = temp; - } - - temp = *(uint32*)(_tableBuffer1 + 6) - size2; - *(uint32*)(_tableBuffer1 + 6) = temp; - - return _tableBuffer2 + unkValue1; -} - -namespace { -int tableIdCompare(const void *l, const void *r) { - int lV = *(const uint32*)(l); - int rV = *(const uint32*)(r); - - return CLIP(lV - rV, -1, 1); -} -} - -uint8 *KyraEngine_v3::findIdInTable(uint8 *buf, int id) { - debugC(9, kDebugLevelMain, "KyraEngine::findIdInTable(%p, %d)", (void *)buf, id); - - updateTableBuffer(buf); - - uint32 idVal = id; - uint8 *ptr = (uint8*)bsearch(&idVal, _tableBuffer1 + 12, *(uint16*)(_tableBuffer1), 14, &tableIdCompare); - - if (!ptr) - return 0; - - return _tableBuffer2 + *(uint32*)(ptr + 4); -} - -uint8 *KyraEngine_v3::findShapeInTable(int id) { - debugC(9, kDebugLevelMain, "KyraEngine::findShapeInTable(%d)", id); - - return findIdInTable(_shapePoolBuffer, id); -} - #pragma mark - items void KyraEngine_v3::initItems() { @@ -621,13 +386,13 @@ void KyraEngine_v3::initItems() { _screen->loadBitmap("ITEMS.CSH", 3, 3, 0); - for (int i = 248; i <= 319; ++i) - addShapeToTable(_screen->getCPagePtr(3), i, i-248); + //for (int i = 248; i <= 319; ++i) + // addShapeToTable(_screen->getCPagePtr(3), i, i-248); _screen->loadBitmap("ITEMS2.CSH", 3, 3, 0); - for (int i = 320; i <= 397; ++i) - addShapeToTable(_screen->getCPagePtr(3), i, i-320); + //for (int i = 320; i <= 397; ++i) + // addShapeToTable(_screen->getCPagePtr(3), i, i-320); uint32 size = 0; uint8 *itemsDat = _res->fileData("_ITEMS.DAT", &size); @@ -689,9 +454,8 @@ bool KyraEngine_v3::loadLanguageFile(const char *file, uint8 *&buffer) { } Movie *KyraEngine_v3::createWSAMovie() { - WSAMovieV2 *movie = new WSAMovieV2(this); + WSAMovieV2 *movie = new WSAMovieV2(this, _screen); assert(movie); - movie->flagOldOff(true); return movie; } diff --git a/engines/kyra/kyra_v3.h b/engines/kyra/kyra_v3.h index 78ce6382a4..6d476a066a 100644 --- a/engines/kyra/kyra_v3.h +++ b/engines/kyra/kyra_v3.h @@ -26,17 +26,21 @@ #ifndef KYRA_KYRA_V3_H #define KYRA_KYRA_V3_H -#include "kyra/kyra_v2.h" +#include "kyra/kyra.h" +#include "kyra/screen_v3.h" namespace Kyra { class SoundDigital; +class Screen_v3; +class MainMenu; -class KyraEngine_v3 : public KyraEngine_v2 { +class KyraEngine_v3 : public KyraEngine { public: KyraEngine_v3(OSystem *system, const GameFlags &flags); ~KyraEngine_v3(); + Screen *screen() { return _screen; } SoundDigital *soundDigital() { return _soundDigital; } int go(); @@ -52,6 +56,7 @@ private: void setupOpcodeTable() {} + Screen_v3 *_screen; SoundDigital *_soundDigital; // sound specific @@ -71,8 +76,25 @@ private: int musicUpdate(int forceRestart); - virtual void gui_initMainMenu(); - virtual void gui_updateMainMenuAnimation(); + void snd_playVoiceFile(int) {} + + // main menu + void initMainMenu(); + void uninitMainMenu(); + + Movie *_menuAnim; + MainMenu *_menu; + + // game speed + bool skipFlag() const { return false; } + void resetSkipFlag(bool) {} + + // timer + void setupTimers() {} + void setWalkspeed(uint8) {} + + // pathfinder + bool lineIsPassable(int, int) { return false; } // unknown private: @@ -91,9 +113,7 @@ private: uint8 *_unkShapeTable[20]; // main menu - Movie *_mainMenuLogo; - int _mainMenuFrame; - int _mainMenuFrameAdd; + static const char *_mainMenuStrings[]; // translation stuff uint8 *_scoreFile; @@ -106,7 +126,6 @@ private: // shapes uint8 *_gameShapes[50]; - uint8 *_shapePoolBuffer; uint8 *_mouseSHPBuf; @@ -118,22 +137,6 @@ private: void initItems(); - // used for CSH loading and some sound stuff (maybe voice files?) -private: - uint8 *_tableBuffer1; - uint8 *_tableBuffer2; - int _unkTableValue; - - // do not think of thouching the code belonging to these functions - int initTableBuffer(uint8 *buf, int size); - void updateTableBuffer(uint8 *buf); - int getTableSize(uint8 *buf); - uint8 *allocTableSpace(uint8 *buf, int size, int id); - uint8 *findIdInTable(uint8 *buf, int id); - - int addShapeToTable(const uint8 *buf, int id, int shapeNum); - uint8 *findShapeInTable(int id); - // resource specific private: static const char *_languageExtension[]; diff --git a/engines/kyra/module.mk b/engines/kyra/module.mk index ce7b5ccd0a..aa2eea7122 100644 --- a/engines/kyra/module.mk +++ b/engines/kyra/module.mk @@ -24,6 +24,7 @@ MODULE_OBJS := \ screen.o \ screen_v1.o \ screen_v2.o \ + screen_v3.o \ script_v1.o \ script_v2.o \ script.o \ diff --git a/engines/kyra/resource.cpp b/engines/kyra/resource.cpp index d95caf1ab8..142f50e789 100644 --- a/engines/kyra/resource.cpp +++ b/engines/kyra/resource.cpp @@ -83,6 +83,8 @@ bool Resource::reset() { } else if (_vm->game() == GI_KYRA3) { loadPakFile("WESTWOOD.001"); loadFileList("FILEDATA.FDT"); + + return true; } FSList fslist; @@ -258,7 +260,6 @@ bool Resource::isInPakList(const Common::String &filename) { void Resource::unloadAllPakFiles() { // remove all entries _map.clear(); - detectFileTypes(); } uint8 *Resource::fileData(const char *file, uint32 *size) { diff --git a/engines/kyra/screen.cpp b/engines/kyra/screen.cpp index 9abc0cbd80..8135dbb2af 100644 --- a/engines/kyra/screen.cpp +++ b/engines/kyra/screen.cpp @@ -33,8 +33,6 @@ namespace Kyra { -#define BITBLIT_RECTS 10 - Screen::Screen(KyraEngine *vm, OSystem *system) : _system(system), _vm(vm) { } @@ -62,21 +60,6 @@ Screen::~Screen() { delete [] _palettes[i]; } - delete [] _bitBlitRects; - - for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) { - delete [] _saveLoadPage[i]; - _saveLoadPage[i] = 0; - } - - for (int i = 0; i < ARRAYSIZE(_saveLoadPageOvl); ++i) { - delete [] _saveLoadPageOvl[i]; - _saveLoadPageOvl[i] = 0; - } - - delete [] _unkPtr1; - delete [] _unkPtr2; - delete [] _dirtyRects; } @@ -125,7 +108,7 @@ bool Screen::init() { } setScreenPalette(_currentPalette); - _curDim = &_screenDimTable[0]; + _curDim = 0; _charWidth = 0; _charOffset = 0; memset(_fonts, 0, sizeof(_fonts)); @@ -138,20 +121,6 @@ bool Screen::init() { _mouseLockCount = 1; CursorMan.showMouse(false); - _bitBlitRects = new Rect[BITBLIT_RECTS]; - assert(_bitBlitRects); - memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS); - _bitBlitNum = 0; - memset(_saveLoadPage, 0, sizeof(_saveLoadPage)); - memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl)); - - _unkPtr1 = new uint8[getRectSize(1, 144)]; - assert(_unkPtr1); - memset(_unkPtr1, 0, getRectSize(1, 144)); - _unkPtr2 = new uint8[getRectSize(1, 144)]; - assert(_unkPtr2); - memset(_unkPtr2, 0, getRectSize(1, 144)); - _forceFullUpdate = false; _numDirtyRects = 0; _dirtyRects = new Rect[kMaxDirtyRects]; @@ -877,11 +846,6 @@ void Screen::setAnimBlockPtr(int size) { _animBlockSize = size; } -void Screen::setTextColorMap(const uint8 *cmap) { - debugC(9, kDebugLevelScreen, "Screen::setTextColorMap(%p)", (const void *)cmap); - setTextColor(cmap, 0, 11); -} - void Screen::setTextColor(const uint8 *cmap, int a, int b) { debugC(9, kDebugLevelScreen, "Screen::setTextColor(%p, %d, %d)", (const void *)cmap, a, b); memcpy(&_textColorsMap[a], cmap, b-a+1); @@ -1108,18 +1072,6 @@ void Screen::drawCharANSI(uint8 c, int x, int y) { addDirtyRect(x, y, charWidth, *(fnt->fontData + fnt->charSizeOffset + 4)); } -void Screen::setScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen::setScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - _curDim = &_screenDimTable[dim]; -} - -const ScreenDim *Screen::getScreenDim(int dim) { - debugC(9, kDebugLevelScreen, "Screen::getScreenDim(%d)", dim); - assert(dim < _screenDimTableCount); - return &_screenDimTable[dim]; -} - void Screen::drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...) { debugC(9, kDebugLevelScreen, "Screen::drawShape(%d, %p, %d, %d, %d, 0x%.04X, ...)", pageNum, (const void *)shapeData, x, y, sd, flags); if (!shapeData) @@ -2386,20 +2338,6 @@ int16 Screen::encodeShapeAndCalculateSize(uint8 *from, uint8 *to, int size_to) { return (to - toPtr); } -int Screen::getRectSize(int x, int y) { - if (x < 1) - x = 1; - else if (x > 40) - x = 40; - - if (y < 1) - y = 1; - else if (y > 200) - y = 200; - - return ((x*y) << 3); -} - void Screen::hideMouse() { debugC(9, kDebugLevelScreen, "Screen::hideMouse()"); ++_mouseLockCount; @@ -2416,6 +2354,11 @@ void Screen::showMouse() { _mouseLockCount--; } + +bool Screen::isMouseVisible() const { + return _mouseLockCount == 0; +} + void Screen::setShapePages(int page1, int page2) { debugC(9, kDebugLevelScreen, "Screen::setShapePages(%d, %d)", page1, page2); _shapePages[0] = _pagePtrs[page1]; @@ -2526,6 +2469,45 @@ byte Screen::getShapeFlag2(int x, int y) { return color; } +int Screen::getDrawLayer(int x, int y) { + debugC(9, kDebugLevelScreen, "Screen::getDrawLayer(%d, %d)", x, y); + int xpos = x - 8; + int ypos = y - 1; + int layer = 1; + + for (int curX = xpos; curX < xpos + 16; ++curX) { + int tempLayer = getShapeFlag2(curX, ypos); + + if (layer < tempLayer) + layer = tempLayer; + + if (layer >= 7) + return 7; + } + return layer; +} + +int Screen::getDrawLayer2(int x, int y, int height) { + debugC(9, kDebugLevelScreen, "Screen::getDrawLayer2(%d, %d, %d)", x, y, height); + int xpos = x - 8; + int ypos = y - 1; + int layer = 1; + + for (int useX = xpos; useX < xpos + 16; ++useX) { + for (int useY = ypos - height; useY < ypos; ++useY) { + int tempLayer = getShapeFlag2(useX, useY); + + if (tempLayer > layer) + layer = tempLayer; + + if (tempLayer >= 7) + return 7; + } + } + return layer; +} + + int Screen::setNewShapeHeight(uint8 *shape, int height) { debugC(9, kDebugLevelScreen, "Screen::setNewShapeHeight(%p, %d)", (const void *)shape, height); if (_vm->gameFlags().useAltShapeHeader) @@ -2546,81 +2528,6 @@ int Screen::resetShapeHeight(uint8 *shape) { return oldHeight; } -void Screen::addBitBlitRect(int x, int y, int w, int h) { - debugC(9, kDebugLevelScreen, "Screen::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h); - if (_bitBlitNum >= BITBLIT_RECTS) - error("too many bit blit rects"); - - _bitBlitRects[_bitBlitNum].x = x; - _bitBlitRects[_bitBlitNum].y = y; - _bitBlitRects[_bitBlitNum].x2 = w; - _bitBlitRects[_bitBlitNum].y2 = h; - ++_bitBlitNum; -} - -void Screen::bitBlitRects() { - debugC(9, kDebugLevelScreen, "Screen::bitBlitRects()"); - Rect *cur = _bitBlitRects; - while (_bitBlitNum) { - _bitBlitNum--; - copyRegion(cur->x, cur->y, cur->x, cur->y, cur->x2, cur->y2, 2, 0); - ++cur; - } -} - -void Screen::savePageToDisk(const char *file, int page) { - debugC(9, kDebugLevelScreen, "Screen::savePageToDisk('%s', %d)", file, page); - if (!_saveLoadPage[page/2]) { - _saveLoadPage[page/2] = new uint8[SCREEN_W * SCREEN_H]; - assert(_saveLoadPage[page/2]); - } - memcpy(_saveLoadPage[page/2], getPagePtr(page), SCREEN_W * SCREEN_H); - - if (_useOverlays) { - if (!_saveLoadPageOvl[page/2]) { - _saveLoadPageOvl[page/2] = new uint8[SCREEN_OVL_SJIS_SIZE]; - assert(_saveLoadPageOvl[page/2]); - } - - uint8 *srcPage = getOverlayPtr(page); - if (!srcPage) { - warning("trying to save unsupported overlay page %d", page); - return; - } - - memcpy(_saveLoadPageOvl[page/2], srcPage, SCREEN_OVL_SJIS_SIZE); - } -} - -void Screen::loadPageFromDisk(const char *file, int page) { - debugC(9, kDebugLevelScreen, "Screen::loadPageFromDisk('%s', %d)", file, page); - copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]); - delete [] _saveLoadPage[page/2]; - - if (_saveLoadPageOvl[page/2]) { - uint8 *dstPage = getOverlayPtr(page); - if (!dstPage) { - warning("trying to restore unsupported overlay page %d", page); - return; - } - - memcpy(dstPage, _saveLoadPageOvl[page/2], SCREEN_OVL_SJIS_SIZE); - delete [] _saveLoadPageOvl[page/2]; - _saveLoadPageOvl[page/2] = 0; - } _saveLoadPage[page/2] = 0; -} - -void Screen::deletePageFromDisk(int page) { - debugC(9, kDebugLevelScreen, "Screen::deletePageFromDisk(%d)", page); - delete [] _saveLoadPage[page/2]; - _saveLoadPage[page/2] = 0; - - if (_saveLoadPageOvl[page/2]) { - delete [] _saveLoadPageOvl[page/2]; - _saveLoadPageOvl[page/2] = 0; - } -} - void Screen::blockInRegion(int x, int y, int width, int height) { debugC(9, kDebugLevelScreen, "Screen::blockInRegion(%d, %d, %d, %d)", x, y, width, height); assert(_shapePages[0]); @@ -2657,90 +2564,6 @@ void Screen::rectClip(int &x, int &y, int w, int h) { y = 200 - h; } -int Screen::getDrawLayer(int x, int y) { - debugC(9, kDebugLevelScreen, "Screen::getDrawLayer(%d, %d)", x, y); - int xpos = x - 8; - int ypos = y - 1; - int layer = 1; - - for (int curX = xpos; curX < xpos + 16; ++curX) { - int tempLayer = getShapeFlag2(curX, ypos); - - if (layer < tempLayer) - layer = tempLayer; - - if (layer >= 7) - return 7; - } - return layer; -} - -int Screen::getDrawLayer2(int x, int y, int height) { - debugC(9, kDebugLevelScreen, "Screen::getDrawLayer2(%d, %d, %d)", x, y, height); - int xpos = x - 8; - int ypos = y - 1; - int layer = 1; - - for (int useX = xpos; useX < xpos + 16; ++useX) { - for (int useY = ypos - height; useY < ypos; ++useY) { - int tempLayer = getShapeFlag2(useX, useY); - - if (tempLayer > layer) - layer = tempLayer; - - if (tempLayer >= 7) - return 7; - } - } - return layer; -} - -void Screen::copyBackgroundBlock(int x, int page, int flag) { - debugC(9, kDebugLevelScreen, "Screen::copyBackgroundBlock(%d, %d, %d)", x, page, flag); - - if (x < 1) - return; - - int height = 128; - if (flag) - height += 8; - if (!(x & 1)) - ++x; - if (x == 19) - x = 17; - - uint8 *ptr1 = _unkPtr1; - uint8 *ptr2 = _unkPtr2; - int oldVideoPage = _curPage; - _curPage = page; - - int curX = x; - hideMouse(); - copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2); - for (int i = 0; i < 19; ++i) { - int tempX = curX + 1; - copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1); - copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2); - int newXPos = curX + x; - if (newXPos > 37) - newXPos = newXPos % 38; - - tempX = newXPos + 1; - copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2); - copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1); - curX += x*2; - if (curX > 37) { - curX = curX % 38; - } - } - showMouse(); - _curPage = oldVideoPage; -} - -void Screen::copyBackgroundBlock2(int x) { - copyBackgroundBlock(x, 4, 1); -} - void Screen::shakeScreen(int times) { debugC(9, kDebugLevelScreen, "Screen::shakeScreen(%d)", times); @@ -3217,5 +3040,305 @@ void Screen::drawCharSJIS(uint16 c, int x, int y) { } } +#pragma mark - + +uint8 *ScreenEx::generateOverlay(const uint8 *palette, uint8 *buffer, int startColor, uint16 factor) { + if (!palette || !buffer) + return buffer; + + factor = MIN<uint16>(255, factor); + factor >>= 1; + factor &= 0xFF; + + const byte col1 = palette[startColor * 3 + 0]; + const byte col2 = palette[startColor * 3 + 1]; + const byte col3 = palette[startColor * 3 + 2]; + + uint8 *dst = buffer; + *dst++ = 0; + + for (int i = 1; i != 255; ++i) { + uint8 processedPalette[3]; + const uint8 *src = palette + i*3; + byte col; + + col = *src++; + col -= ((((col - col1) * factor) << 1) >> 8) & 0xFF; + processedPalette[0] = col; + + col = *src++; + col -= ((((col - col2) * factor) << 1) >> 8) & 0xFF; + processedPalette[1] = col; + + col = *src++; + col -= ((((col - col3) * factor) << 1) >> 8) & 0xFF; + processedPalette[2] = col; + + *dst++ = findLeastDifferentColor(processedPalette, palette+3, 255)+1; + } + + return buffer; +} + +void ScreenEx::applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay) { + if (pageNum == 0 || pageNum == 1) + addDirtyRect(x, y, w, h); + + uint8 *dst = getPagePtr(pageNum) + y * 320 + x; + while (h--) { + for (int wi = 0; wi < w; ++wi) { + uint8 index = *dst; + *dst++ = overlay[index]; + } + dst += 320 - w; + } +} + +int ScreenEx::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors) { + int m = 0x7fff; + int r = 0x101; + + for (int i = 0; i < numColors; i++) { + int v = paletteEntry[0] - *palette++; + int c = v * v; + v = paletteEntry[1] - *palette++; + c += (v * v); + v = paletteEntry[2] - *palette++; + c += (v * v); + + if (c <= m) { + m = c; + r = i; + } + } + + return r; +} + +void ScreenEx::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, + int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) { + uint8 *dstPtr = getPagePtr(_curPage); + uint8 *origDst = dstPtr; + + const ScreenDim *dim = getScreenDim(dimState); + int dimX1 = dim->sx << 3; + int dimX2 = dim->w << 3; + dimX2 += dimX1; + + int dimY1 = dim->sy; + int dimY2 = dim->h; + dimY2 += dimY1; + + int temp = y - dimY1; + if (temp < 0) { + if ((temp += h) <= 0) + return; + else { + SWAP(temp, h); + y += temp - h; + src += (temp - h) * w; + } + } + + temp = dimY2 - y; + if (temp <= 0) + return; + + if (temp < h) + h = temp; + + int srcOffset = 0; + temp = x - dimX1; + if (temp < 0) { + temp = -temp; + srcOffset = temp; + x += temp; + w -= temp; + } + + int srcAdd = 0; + + temp = dimX2 - x; + if (temp <= 0) + return; + + if (temp < w) { + SWAP(w, temp); + temp -= w; + srcAdd = temp; + } + + dstPtr += y * SCREEN_W + x; + uint8 *dst = dstPtr; + + if (_curPage == 0 || _curPage == 1) + addDirtyRect(x, y, w, h); + + clearOverlayRect(_curPage, x, y, w, h); + + temp = h; + while (h--) { + src += srcOffset; + int cW = w; + + switch (plotFunc) { + case 0: + memcpy(dst, src, cW); + dst += cW; src += cW; + break; + + case 1: + while (cW--) { + uint8 d = *src++; + uint8 t = unkPtr1[d]; + if (t != 0xFF) + d = unkPtr2[*dst + (t << 8)]; + *dst++ = d; + } + break; + + case 4: + while (cW--) { + uint8 d = *src++; + if (d) + *dst = d; + ++dst; + } + break; + + case 5: + while (cW--) { + uint8 d = *src++; + if (d) { + uint8 t = unkPtr1[d]; + if (t != 0xFF) + d = unkPtr2[*dst + (t << 8)]; + *dst = d; + } + ++dst; + } + break; + + case 8: + case 9: + while (cW--) { + uint8 d = *src++; + uint8 t = _shapePages[0][dst - origDst] & 7; + if (unk1 < t) + d = _shapePages[1][dst - origDst]; + *dst++ = d; + } + break; + + case 12: + case 13: + while (cW--) { + uint8 d = *src++; + if (d) { + uint8 t = _shapePages[0][dst - origDst] & 7; + if (unk1 < t) + d = _shapePages[1][dst - origDst]; + *dst++ = d; + } else { + d = _shapePages[1][dst - origDst]; + *dst++ = d; + } + } + break; + + default: + break; + } + + dst = (dstPtr += SCREEN_W); + src += srcAdd; + } +} + +const uint8 *ScreenEx::getPtrToShape(const uint8 *shpFile, int shape) { + debugC(9, kDebugLevelScreen, "ScreenEx::getPtrToShape(%p, %d)", (const void *)shpFile, shape); + uint16 shapes = READ_LE_UINT16(shpFile); + + if (shapes <= shape) + return 0; + + uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); + + return shpFile + offset + 2; +} + +uint8 *ScreenEx::getPtrToShape(uint8 *shpFile, int shape) { + debugC(9, kDebugLevelScreen, "ScreenEx::getPtrToShape(%p, %d)", (void *)shpFile, shape); + uint16 shapes = READ_LE_UINT16(shpFile); + + if (shapes <= shape) + return 0; + + uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); + + return shpFile + offset + 2; +} + +int ScreenEx::getShapeScaledWidth(const uint8 *shpFile, int scale) { + int width = READ_LE_UINT16(shpFile+3); + return (width * scale) >> 8; +} + +int ScreenEx::getShapeScaledHeight(const uint8 *shpFile, int scale) { + int height = shpFile[2]; + return (height * scale) >> 8; +} + +uint16 ScreenEx::getShapeSize(const uint8 *shp) { + debugC(9, kDebugLevelScreen, "ScreenEx::getShapeSize(%p)", (const void *)shp); + + return READ_LE_UINT16(shp+6); +} + +uint8 *ScreenEx::makeShapeCopy(const uint8 *src, int index) { + debugC(9, kDebugLevelScreen, "ScreenEx::makeShapeCopy(%p, %d)", (const void *)src, index); + + const uint8 *shape = getPtrToShape(src, index); + int size = getShapeSize(shape); + + uint8 *copy = new uint8[size]; + assert(copy); + memcpy(copy, shape, size); + + return copy; +} + +int ScreenEx::getLayer(int x, int y) { + if (x < 0) + x = 0; + else if (x >= 320) + x = 319; + if (y < 0) + y = 0; + else if (y >= 144) + y = 143; + + uint8 pixel = *(getCPagePtr(5) + y * 320 + x); + pixel &= 0x7F; + pixel >>= 3; + + if (pixel < 1) + pixel = 1; + else if (pixel > 15) + pixel = 15; + return pixel; +} + +int ScreenEx::getRectSize(int w, int h) { + if (w > 320 || h > 200) + return 0; + return w*h; +} + +void ScreenEx::setTextColorMap(const uint8 *cmap) { + debugC(9, kDebugLevelScreen, "ScreenEx::setTextColorMap(%p)", (const void *)cmap); + setTextColor(cmap, 0, 15); +} + } // End of namespace Kyra diff --git a/engines/kyra/screen.h b/engines/kyra/screen.h index 9db5a7b44a..58f24e72bc 100644 --- a/engines/kyra/screen.h +++ b/engines/kyra/screen.h @@ -98,7 +98,7 @@ public: Screen(KyraEngine *vm, OSystem *system); virtual ~Screen(); - bool init(); + virtual bool init(); void updateScreen(); @@ -165,11 +165,13 @@ public: void printText(const char *str, int x, int y, uint8 color1, uint8 color2); - void setTextColorMap(const uint8 *cmap); + virtual void setTextColorMap(const uint8 *cmap) = 0; void setTextColor(const uint8 *cmap, int a, int b); - virtual void setScreenDim(int dim); - virtual const ScreenDim *getScreenDim(int dim); + virtual void setScreenDim(int dim) = 0; + virtual const ScreenDim *getScreenDim(int dim) = 0; + + const ScreenDim *_curDim; // shape handling uint8 *encodeShape(int x, int y, int w, int h, int flags); @@ -179,65 +181,17 @@ public: void drawShape(uint8 pageNum, const uint8 *shapeData, int x, int y, int sd, int flags, ...); - int drawShapeMarginNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt); - int drawShapeMarginNoScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt); - int drawShapeMarginScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt); - int drawShapeMarginScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt); - int drawShapeSkipScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt); - int drawShapeSkipScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt); - void drawShapeProcessLineNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); - void drawShapeProcessLineNoScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); - void drawShapeProcessLineScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); - void drawShapeProcessLineScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); - - void drawShapePlotType0(uint8 *dst, uint8 cmd); - void drawShapePlotType4(uint8 *dst, uint8 cmd); - void drawShapePlotType8(uint8 *dst, uint8 cmd); - void drawShapePlotType9(uint8 *dst, uint8 cmd); - void drawShapePlotType11_15(uint8 *dst, uint8 cmd); - void drawShapePlotType12(uint8 *dst, uint8 cmd); - void drawShapePlotType13(uint8 *dst, uint8 cmd); - void drawShapePlotType14(uint8 *dst, uint8 cmd); - - typedef int (Screen::*DsMarginSkipFunc)(uint8 *&dst, const uint8 *&src, int &cnt); - typedef void (Screen::*DsLineFunc)(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); - typedef void (Screen::*DsPlotFunc)(uint8 *dst, uint8 cmd); - - DsMarginSkipFunc _dsProcessMargin; - DsMarginSkipFunc _dsScaleSkip; - DsLineFunc _dsProcessLine; - DsPlotFunc _dsPlot; - - const uint8 *_dsTable; - int _dsTableLoopCount; - const uint8 *_dsTable2; - int _dsDrawLayer; - uint8 *_dsDstPage; - int _dsTmpWidth; - int _dsOffscreenLeft; - int _dsOffscreenRight; - int _dsScaleW; - int _dsScaleH; - int _dsOffscreenScaleVal1; - int _dsOffscreenScaleVal2; - int _drawShapeVar1; - int _drawShapeVar3; - int _drawShapeVar4; - int _drawShapeVar5; - // mouse handling void hideMouse(); void showMouse(); + bool isMouseVisible() const; void setMouseCursor(int x, int y, byte *shape); // rect handling - virtual int getRectSize(int w, int h); + virtual int getRectSize(int w, int h) = 0; void rectClip(int &x, int &y, int w, int h); - void addBitBlitRect(int x, int y, int w, int h); - void bitBlitRects(); - // misc void loadBitmap(const char *filename, int tempPage, int dstPage, uint8 *palData); @@ -251,20 +205,12 @@ public: byte getShapeFlag1(int x, int y); byte getShapeFlag2(int x, int y); - void savePageToDisk(const char *file, int page); - void loadPageFromDisk(const char *file, int page); - void deletePageFromDisk(int page); + int getDrawLayer(int x, int y); + int getDrawLayer2(int x, int y, int height); void blockInRegion(int x, int y, int width, int height); void blockOutRegion(int x, int y, int width, int height); - void copyBackgroundBlock(int x, int page, int flag); - void copyBackgroundBlock2(int x); - - // kyra1 specific? - int getDrawLayer(int x, int y); - int getDrawLayer2(int x, int y, int height); - int _charWidth; int _charOffset; int _curPage; @@ -273,11 +219,6 @@ public: FontId _currentFont; bool _disableScreen; - const ScreenDim *_curDim; - - static const ScreenDim _screenDimTable[]; - static const int _screenDimTableCount; - // decoding functions static void decodeFrame3(const uint8 *src, uint8 *dst, uint32 size); static uint decodeFrame4(const uint8 *src, uint8 *dst, uint32 dstSize); @@ -329,9 +270,6 @@ protected: uint8 *_sjisTempPage2; uint8 *_sjisSourceChar; - uint8 *_saveLoadPage[8]; - uint8 *_saveLoadPageOvl[8]; - uint8 *_screenPalette; uint8 *_palettes[6]; @@ -346,10 +284,6 @@ protected: int _mouseLockCount; - Rect *_bitBlitRects; - int _bitBlitNum; - uint8 *_unkPtr1, *_unkPtr2; - enum { kMaxDirtyRects = 50 }; @@ -363,6 +297,53 @@ protected: OSystem *_system; KyraEngine *_vm; + // shape + int drawShapeMarginNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt); + int drawShapeMarginNoScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt); + int drawShapeMarginScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt); + int drawShapeMarginScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt); + int drawShapeSkipScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt); + int drawShapeSkipScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt); + void drawShapeProcessLineNoScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); + void drawShapeProcessLineNoScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); + void drawShapeProcessLineScaleUpwind(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); + void drawShapeProcessLineScaleDownwind(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); + + void drawShapePlotType0(uint8 *dst, uint8 cmd); + void drawShapePlotType4(uint8 *dst, uint8 cmd); + void drawShapePlotType8(uint8 *dst, uint8 cmd); + void drawShapePlotType9(uint8 *dst, uint8 cmd); + void drawShapePlotType11_15(uint8 *dst, uint8 cmd); + void drawShapePlotType12(uint8 *dst, uint8 cmd); + void drawShapePlotType13(uint8 *dst, uint8 cmd); + void drawShapePlotType14(uint8 *dst, uint8 cmd); + + typedef int (Screen::*DsMarginSkipFunc)(uint8 *&dst, const uint8 *&src, int &cnt); + typedef void (Screen::*DsLineFunc)(uint8 *&dst, const uint8 *&src, int &cnt, int scaleState); + typedef void (Screen::*DsPlotFunc)(uint8 *dst, uint8 cmd); + + DsMarginSkipFunc _dsProcessMargin; + DsMarginSkipFunc _dsScaleSkip; + DsLineFunc _dsProcessLine; + DsPlotFunc _dsPlot; + + const uint8 *_dsTable; + int _dsTableLoopCount; + const uint8 *_dsTable2; + int _dsDrawLayer; + uint8 *_dsDstPage; + int _dsTmpWidth; + int _dsOffscreenLeft; + int _dsOffscreenRight; + int _dsScaleW; + int _dsScaleH; + int _dsOffscreenScaleVal1; + int _dsOffscreenScaleVal2; + int _drawShapeVar1; + int _drawShapeVar3; + int _drawShapeVar4; + int _drawShapeVar5; + // init virtual void setResolution(); @@ -370,6 +351,41 @@ protected: bool _debugEnabled; }; +class ScreenEx : public Screen { +public: + ScreenEx(KyraEngine *vm, OSystem *system) : Screen(vm, system) {} + + // screen page handling + void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, + int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2); + + // palette handling + uint8 *generateOverlay(const uint8 *palette, uint8 *buffer, int color, uint16 factor); + void applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay); + int findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors); + + // shape handling + uint8 *getPtrToShape(uint8 *shpFile, int shape); + const uint8 *getPtrToShape(const uint8 *shpFile, int shape); + + int getShapeScaledWidth(const uint8 *shpFile, int scale); + int getShapeScaledHeight(const uint8 *shpFile, int scale); + + uint16 getShapeSize(const uint8 *shp); + + uint8 *makeShapeCopy(const uint8 *src, int index); + + // rect handling + int getRectSize(int w, int h); + + // text display + void setTextColorMap(const uint8 *cmap); + + // layer handling + virtual int getLayer(int x, int y); +protected: +}; + } // End of namespace Kyra #endif diff --git a/engines/kyra/screen_v1.cpp b/engines/kyra/screen_v1.cpp index c18ad430ce..9454418fd5 100644 --- a/engines/kyra/screen_v1.cpp +++ b/engines/kyra/screen_v1.cpp @@ -28,12 +28,61 @@ namespace Kyra { +#define BITBLIT_RECTS 10 + Screen_v1::Screen_v1(KyraEngine_v1 *vm, OSystem *system) : Screen(vm, system) { _vm = vm; } Screen_v1::~Screen_v1() { + delete [] _bitBlitRects; + + for (int i = 0; i < ARRAYSIZE(_saveLoadPage); ++i) { + delete [] _saveLoadPage[i]; + _saveLoadPage[i] = 0; + } + + for (int i = 0; i < ARRAYSIZE(_saveLoadPageOvl); ++i) { + delete [] _saveLoadPageOvl[i]; + _saveLoadPageOvl[i] = 0; + } + + delete [] _unkPtr1; + delete [] _unkPtr2; +} + +bool Screen_v1::init() { + if (!Screen::init()) + return false; + + _bitBlitRects = new Rect[BITBLIT_RECTS]; + assert(_bitBlitRects); + memset(_bitBlitRects, 0, sizeof(Rect)*BITBLIT_RECTS); + _bitBlitNum = 0; + memset(_saveLoadPage, 0, sizeof(_saveLoadPage)); + memset(_saveLoadPageOvl, 0, sizeof(_saveLoadPageOvl)); + + _unkPtr1 = new uint8[getRectSize(1, 144)]; + assert(_unkPtr1); + memset(_unkPtr1, 0, getRectSize(1, 144)); + _unkPtr2 = new uint8[getRectSize(1, 144)]; + assert(_unkPtr2); + memset(_unkPtr2, 0, getRectSize(1, 144)); + + return true; +} + +void Screen_v1::setScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_v1::setScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + _curDim = &_screenDimTable[dim]; +} + +const ScreenDim *Screen_v1::getScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_v1::getScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + return &_screenDimTable[dim]; } void Screen_v1::fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime) { @@ -50,4 +99,145 @@ void Screen_v1::fadeSpecialPalette(int palIndex, int startIndex, int size, int f _system->updateScreen(); } +void Screen_v1::addBitBlitRect(int x, int y, int w, int h) { + debugC(9, kDebugLevelScreen, "Screen_v1::addBitBlitRects(%d, %d, %d, %d)", x, y, w, h); + if (_bitBlitNum >= BITBLIT_RECTS) + error("too many bit blit rects"); + + _bitBlitRects[_bitBlitNum].x = x; + _bitBlitRects[_bitBlitNum].y = y; + _bitBlitRects[_bitBlitNum].x2 = w; + _bitBlitRects[_bitBlitNum].y2 = h; + ++_bitBlitNum; +} + +void Screen_v1::bitBlitRects() { + debugC(9, kDebugLevelScreen, "Screen_v1::bitBlitRects()"); + Rect *cur = _bitBlitRects; + while (_bitBlitNum) { + _bitBlitNum--; + copyRegion(cur->x, cur->y, cur->x, cur->y, cur->x2, cur->y2, 2, 0); + ++cur; + } +} + +void Screen_v1::savePageToDisk(const char *file, int page) { + debugC(9, kDebugLevelScreen, "Screen_v1::savePageToDisk('%s', %d)", file, page); + if (!_saveLoadPage[page/2]) { + _saveLoadPage[page/2] = new uint8[SCREEN_W * SCREEN_H]; + assert(_saveLoadPage[page/2]); + } + memcpy(_saveLoadPage[page/2], getPagePtr(page), SCREEN_W * SCREEN_H); + + if (_useOverlays) { + if (!_saveLoadPageOvl[page/2]) { + _saveLoadPageOvl[page/2] = new uint8[SCREEN_OVL_SJIS_SIZE]; + assert(_saveLoadPageOvl[page/2]); + } + + uint8 *srcPage = getOverlayPtr(page); + if (!srcPage) { + warning("trying to save unsupported overlay page %d", page); + return; + } + + memcpy(_saveLoadPageOvl[page/2], srcPage, SCREEN_OVL_SJIS_SIZE); + } +} + +void Screen_v1::loadPageFromDisk(const char *file, int page) { + debugC(9, kDebugLevelScreen, "Screen_v1::loadPageFromDisk('%s', %d)", file, page); + copyBlockToPage(page, 0, 0, SCREEN_W, SCREEN_H, _saveLoadPage[page/2]); + delete [] _saveLoadPage[page/2]; + + if (_saveLoadPageOvl[page/2]) { + uint8 *dstPage = getOverlayPtr(page); + if (!dstPage) { + warning("trying to restore unsupported overlay page %d", page); + return; + } + + memcpy(dstPage, _saveLoadPageOvl[page/2], SCREEN_OVL_SJIS_SIZE); + delete [] _saveLoadPageOvl[page/2]; + _saveLoadPageOvl[page/2] = 0; + } _saveLoadPage[page/2] = 0; +} + +void Screen_v1::deletePageFromDisk(int page) { + debugC(9, kDebugLevelScreen, "Screen_v1::deletePageFromDisk(%d)", page); + delete [] _saveLoadPage[page/2]; + _saveLoadPage[page/2] = 0; + + if (_saveLoadPageOvl[page/2]) { + delete [] _saveLoadPageOvl[page/2]; + _saveLoadPageOvl[page/2] = 0; + } +} + +void Screen_v1::copyBackgroundBlock(int x, int page, int flag) { + debugC(9, kDebugLevelScreen, "Screen_v1::copyBackgroundBlock(%d, %d, %d)", x, page, flag); + + if (x < 1) + return; + + int height = 128; + if (flag) + height += 8; + if (!(x & 1)) + ++x; + if (x == 19) + x = 17; + + uint8 *ptr1 = _unkPtr1; + uint8 *ptr2 = _unkPtr2; + int oldVideoPage = _curPage; + _curPage = page; + + int curX = x; + hideMouse(); + copyRegionToBuffer(_curPage, 8, 8, 8, height, ptr2); + for (int i = 0; i < 19; ++i) { + int tempX = curX + 1; + copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr1); + copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr2); + int newXPos = curX + x; + if (newXPos > 37) + newXPos = newXPos % 38; + + tempX = newXPos + 1; + copyRegionToBuffer(_curPage, tempX<<3, 8, 8, height, ptr2); + copyBlockToPage(_curPage, tempX<<3, 8, 8, height, ptr1); + curX += x*2; + if (curX > 37) { + curX = curX % 38; + } + } + showMouse(); + _curPage = oldVideoPage; +} + +void Screen_v1::copyBackgroundBlock2(int x) { + debugC(9, kDebugLevelScreen, "Screen_v1::copyBackgroundBlock2(%d)", x); + copyBackgroundBlock(x, 4, 1); +} + +void Screen_v1::setTextColorMap(const uint8 *cmap) { + debugC(9, kDebugLevelScreen, "Screen_v1::setTextColorMap(%p)", (const void *)cmap); + setTextColor(cmap, 0, 11); +} + +int Screen_v1::getRectSize(int x, int y) { + if (x < 1) + x = 1; + else if (x > 40) + x = 40; + + if (y < 1) + y = 1; + else if (y > 200) + y = 200; + + return ((x*y) << 3); +} + } // end of namespace Kyra diff --git a/engines/kyra/screen_v1.h b/engines/kyra/screen_v1.h index 5354e870fa..10219ae6b5 100644 --- a/engines/kyra/screen_v1.h +++ b/engines/kyra/screen_v1.h @@ -37,10 +37,39 @@ public: Screen_v1(KyraEngine_v1 *vm, OSystem *system); virtual ~Screen_v1(); + bool init(); + + int getRectSize(int w, int h); + + void setScreenDim(int dim); + const ScreenDim *getScreenDim(int dim); + + void setTextColorMap(const uint8 *cmap); + void fadeSpecialPalette(int palIndex, int startIndex, int size, int fadeTime); + void savePageToDisk(const char *file, int page); + void loadPageFromDisk(const char *file, int page); + void deletePageFromDisk(int page); + + void copyBackgroundBlock(int x, int page, int flag); + void copyBackgroundBlock2(int x); + + void addBitBlitRect(int x, int y, int w, int h); + void bitBlitRects(); + protected: KyraEngine_v1 *_vm; + + static const ScreenDim _screenDimTable[]; + static const int _screenDimTableCount; + + Rect *_bitBlitRects; + int _bitBlitNum; + uint8 *_unkPtr1, *_unkPtr2; + + uint8 *_saveLoadPage[8]; + uint8 *_saveLoadPageOvl[8]; }; } // end of namespace Kyra diff --git a/engines/kyra/screen_v2.cpp b/engines/kyra/screen_v2.cpp index 9604657b85..f3eb840ca2 100644 --- a/engines/kyra/screen_v2.cpp +++ b/engines/kyra/screen_v2.cpp @@ -31,7 +31,7 @@ namespace Kyra { Screen_v2::Screen_v2(KyraEngine_v2 *vm, OSystem *system) - : Screen(vm, system) { + : ScreenEx(vm, system) { _vm = vm; _wsaFrameAnimBuffer = new uint8[1024]; } @@ -42,24 +42,14 @@ Screen_v2::~Screen_v2() { void Screen_v2::setScreenDim(int dim) { debugC(9, kDebugLevelScreen, "Screen_v2::setScreenDim(%d)", dim); - if (_vm->game() == GI_KYRA2) { - assert(dim < _screenDimTableCount); - _curDim = &_screenDimTable[dim]; - } else { - assert(dim < _screenDimTableCountK3); - _curDim = &_screenDimTableK3[dim]; - } + assert(dim < _screenDimTableCount); + _curDim = &_screenDimTable[dim]; } const ScreenDim *Screen_v2::getScreenDim(int dim) { debugC(9, kDebugLevelScreen, "Screen_v2::getScreenDim(%d)", dim); - if (_vm->game() == GI_KYRA2) { - assert(dim < _screenDimTableCount); - return &_screenDimTable[dim]; - } else { - assert(dim < _screenDimTableCountK3); - return &_screenDimTableK3[dim]; - } + assert(dim < _screenDimTableCount); + return &_screenDimTable[dim]; } void Screen_v2::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag) { @@ -84,79 +74,6 @@ void Screen_v2::generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int grayOverlay[i] = findLeastDifferentColor(tmpPal + 3 * i, srcPal, lastColor); } -uint8 *Screen_v2::generateOverlay(const uint8 *palette, uint8 *buffer, int startColor, uint16 factor) { - if (!palette || !buffer) - return buffer; - - factor = MIN<uint16>(255, factor); - factor >>= 1; - factor &= 0xFF; - - const byte col1 = palette[startColor * 3 + 0]; - const byte col2 = palette[startColor * 3 + 1]; - const byte col3 = palette[startColor * 3 + 2]; - - uint8 *dst = buffer; - *dst++ = 0; - - for (int i = 1; i != 255; ++i) { - uint8 processedPalette[3]; - const uint8 *src = palette + i*3; - byte col; - - col = *src++; - col -= ((((col - col1) * factor) << 1) >> 8) & 0xFF; - processedPalette[0] = col; - - col = *src++; - col -= ((((col - col2) * factor) << 1) >> 8) & 0xFF; - processedPalette[1] = col; - - col = *src++; - col -= ((((col - col3) * factor) << 1) >> 8) & 0xFF; - processedPalette[2] = col; - - *dst++ = findLeastDifferentColor(processedPalette, palette+3, 255)+1; - } - - return buffer; -} - -void Screen_v2::applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay) { - if (pageNum == 0 || pageNum == 1) - addDirtyRect(x, y, w, h); - - uint8 *dst = getPagePtr(pageNum) + y * 320 + x; - while (h--) { - for (int wi = 0; wi < w; ++wi) { - uint8 index = *dst; - *dst++ = overlay[index]; - } - dst += 320 - w; - } -} - -int Screen_v2::findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors) { - int m = 0x7fff; - int r = 0x101; - - for (int i = 0; i < numColors; i++) { - int v = paletteEntry[0] - *palette++; - int c = v * v; - v = paletteEntry[1] - *palette++; - c += (v * v); - v = paletteEntry[2] - *palette++; - c += (v * v); - - if (c <= m) { - m = c; - r = i; - } - } - - return r; -} - void Screen_v2::wsaFrameAnimationStep(int x1, int y1, int x2, int y2, int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim) { @@ -358,234 +275,5 @@ bool Screen_v2::calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, i return (w1 == -1) ? false : true; } -void Screen_v2::copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, - int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2) { - uint8 *dstPtr = getPagePtr(_curPage); - uint8 *origDst = dstPtr; - - const ScreenDim *dim = getScreenDim(dimState); - int dimX1 = dim->sx << 3; - int dimX2 = dim->w << 3; - dimX2 += dimX1; - - int dimY1 = dim->sy; - int dimY2 = dim->h; - dimY2 += dimY1; - - int temp = y - dimY1; - if (temp < 0) { - if ((temp += h) <= 0) - return; - else { - SWAP(temp, h); - y += temp - h; - src += (temp - h) * w; - } - } - - temp = dimY2 - y; - if (temp <= 0) - return; - - if (temp < h) - h = temp; - - int srcOffset = 0; - temp = x - dimX1; - if (temp < 0) { - temp = -temp; - srcOffset = temp; - x += temp; - w -= temp; - } - - int srcAdd = 0; - - temp = dimX2 - x; - if (temp <= 0) - return; - - if (temp < w) { - SWAP(w, temp); - temp -= w; - srcAdd = temp; - } - - dstPtr += y * SCREEN_W + x; - uint8 *dst = dstPtr; - - if (_curPage == 0 || _curPage == 1) - addDirtyRect(x, y, w, h); - - clearOverlayRect(_curPage, x, y, w, h); - - temp = h; - while (h--) { - src += srcOffset; - int cW = w; - - switch (plotFunc) { - case 0: - memcpy(dst, src, cW); - dst += cW; src += cW; - break; - - case 1: - while (cW--) { - uint8 d = *src++; - uint8 t = unkPtr1[d]; - if (t != 0xFF) - d = unkPtr2[*dst + (t << 8)]; - *dst++ = d; - } - break; - - case 4: - while (cW--) { - uint8 d = *src++; - if (d) - *dst = d; - ++dst; - } - break; - - case 5: - while (cW--) { - uint8 d = *src++; - if (d) { - uint8 t = unkPtr1[d]; - if (t != 0xFF) - d = unkPtr2[*dst + (t << 8)]; - *dst = d; - } - ++dst; - } - break; - - case 8: - case 9: - while (cW--) { - uint8 d = *src++; - uint8 t = _shapePages[0][dst - origDst] & 7; - if (unk1 < t) - d = _shapePages[1][dst - origDst]; - *dst++ = d; - } - break; - - case 12: - case 13: - while (cW--) { - uint8 d = *src++; - if (d) { - uint8 t = _shapePages[0][dst - origDst] & 7; - if (unk1 < t) - d = _shapePages[1][dst - origDst]; - *dst++ = d; - } else { - d = _shapePages[1][dst - origDst]; - *dst++ = d; - } - } - break; - - default: - break; - } - - dst = (dstPtr += SCREEN_W); - src += srcAdd; - } -} - -const uint8 *Screen_v2::getPtrToShape(const uint8 *shpFile, int shape) { - debugC(9, kDebugLevelScreen, "Screen_v2::getPtrToShape(%p, %d)", (const void *)shpFile, shape); - uint16 shapes = READ_LE_UINT16(shpFile); - - if (shapes <= shape) - return 0; - - uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); - - return shpFile + offset + 2; -} - -uint8 *Screen_v2::getPtrToShape(uint8 *shpFile, int shape) { - debugC(9, kDebugLevelScreen, "Screen_v2::getPtrToShape(%p, %d)", (void *)shpFile, shape); - uint16 shapes = READ_LE_UINT16(shpFile); - - if (shapes <= shape) - return 0; - - uint32 offset = READ_LE_UINT32(shpFile + (shape << 2) + 2); - - return shpFile + offset + 2; -} - -int Screen_v2::getShapeScaledWidth(const uint8 *shpFile, int scale) { - int width = READ_LE_UINT16(shpFile+3); - return (width * scale) >> 8; -} - -int Screen_v2::getShapeScaledHeight(const uint8 *shpFile, int scale) { - int height = shpFile[2]; - return (height * scale) >> 8; -} - -uint16 Screen_v2::getShapeSize(const uint8 *shp) { - debugC(9, kDebugLevelScreen, "Screen_v2::getShapeSize(%p)", (const void *)shp); - - return READ_LE_UINT16(shp+6); -} - -uint8 *Screen_v2::makeShapeCopy(const uint8 *src, int index) { - debugC(9, kDebugLevelScreen, "Screen_v2::makeShapeCopy(%p, %d)", (const void *)src, index); - - const uint8 *shape = getPtrToShape(src, index); - int size = getShapeSize(shape); - - uint8 *copy = new uint8[size]; - assert(copy); - memcpy(copy, shape, size); - - return copy; -} - -int Screen_v2::getRectSize(int w, int h) { - if (w > 320 || h > 200) - return 0; - return w*h; -} - -int Screen_v2::getLayer(int x, int y) { - if (x < 0) - x = 0; - else if (x >= 320) - x = 319; - if (y < 0) - y = 0; - else if (y >= 144) - y = 143; - - uint8 pixel = *(getCPagePtr(5) + y * 320 + x); - pixel &= 0x7F; - pixel >>= 3; - - if (pixel < 1) - pixel = 1; - else if (pixel > 15) - pixel = 15; - return pixel; -} - -bool Screen_v2::isMouseVisible() const { - return _mouseLockCount == 0; -} - -void Screen_v2::setTextColorMap(const uint8 *cmap) { - debugC(9, kDebugLevelScreen, "Screen_v2::setTextColorMap(%p)", (const void *)cmap); - setTextColor(cmap, 0, 15); -} - } // end of namespace Kyra diff --git a/engines/kyra/screen_v2.h b/engines/kyra/screen_v2.h index 5173375f61..665f71ace4 100644 --- a/engines/kyra/screen_v2.h +++ b/engines/kyra/screen_v2.h @@ -32,53 +32,22 @@ namespace Kyra { class KyraEngine_v2; -class Screen_v2 : public Screen { +class Screen_v2 : public ScreenEx { friend class Debugger_v2; public: Screen_v2(KyraEngine_v2 *vm, OSystem *system); virtual ~Screen_v2(); virtual void setScreenDim(int dim); - const ScreenDim *getScreenDim(int dim); + virtual const ScreenDim *getScreenDim(int dim); // sequence player void generateGrayOverlay(const uint8 *srcPal, uint8 *grayOverlay, int factor, int addR, int addG, int addB, int lastColor, bool flag); - int findLeastDifferentColor(const uint8 *paletteEntry, const uint8 *palette, uint16 numColors); bool calcBounds(int w0, int h0, int &x1, int &y1, int &w1, int &h1, int &x2, int &y2, int &w2); void wsaFrameAnimationStep(int x1, int y1, int x2, int y2, int w1, int h1, int w2, int h2, int srcPage, int dstPage, int dim); void cmpFadeFrameStep(int srcPage, int srcW, int srcH, int srcX, int srcY, int dstPage, int dstW, int dstH, int dstX, int dstY, int cmpW, int cmpH, int cmpPage); void copyPageMemory(int srcPage, int srcPos, int dstPage, int dstPos, int numBytes); void copyRegionEx(int srcPage, int srcW, int srcH, int dstPage, int dstX,int dstY, int dstW, int dstH, const ScreenDim *d, bool flag = false); - - // screen page handling - void copyWsaRect(int x, int y, int w, int h, int dimState, int plotFunc, const uint8 *src, - int unk1, const uint8 *unkPtr1, const uint8 *unkPtr2); - - uint8 *generateOverlay(const uint8 *palette, uint8 *buffer, int color, uint16 factor); - void applyOverlay(int x, int y, int w, int h, int pageNum, const uint8 *overlay); - - // shape handling - uint8 *getPtrToShape(uint8 *shpFile, int shape); - const uint8 *getPtrToShape(const uint8 *shpFile, int shape); - - int getShapeScaledWidth(const uint8 *shpFile, int scale); - int getShapeScaledHeight(const uint8 *shpFile, int scale); - - uint16 getShapeSize(const uint8 *shp); - - uint8 *makeShapeCopy(const uint8 *src, int index); - - // rect handling - virtual int getRectSize(int w, int h); - - // layer handling - int getLayer(int x, int y); - - // mouse handling - bool isMouseVisible() const; - - // text display - void setTextColorMap(const uint8 *cmap); private: KyraEngine_v2 *_vm; @@ -86,10 +55,6 @@ private: static const int _screenDimTableCount; uint8 *_wsaFrameAnimBuffer; - - // maybe subclass screen for kyra3 - static const ScreenDim _screenDimTableK3[]; - static const int _screenDimTableCountK3; }; } // End of namespace Kyra diff --git a/engines/kyra/screen_v3.cpp b/engines/kyra/screen_v3.cpp new file mode 100644 index 0000000000..5c43b4b7e1 --- /dev/null +++ b/engines/kyra/screen_v3.cpp @@ -0,0 +1,50 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#include "kyra/screen_v3.h" + +#include "kyra/kyra_v3.h" + +namespace Kyra { + +Screen_v3::Screen_v3(KyraEngine_v3 *vm, OSystem *system) : ScreenEx(vm, system) { +} + +Screen_v3::~Screen_v3() { +} + +void Screen_v3::setScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_v3::setScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + _curDim = &_screenDimTable[dim]; +} + +const ScreenDim *Screen_v3::getScreenDim(int dim) { + debugC(9, kDebugLevelScreen, "Screen_v3::getScreenDim(%d)", dim); + assert(dim < _screenDimTableCount); + return &_screenDimTable[dim]; +} + +} // end of namespace Kyra
\ No newline at end of file diff --git a/engines/kyra/screen_v3.h b/engines/kyra/screen_v3.h new file mode 100644 index 0000000000..f72ff88b68 --- /dev/null +++ b/engines/kyra/screen_v3.h @@ -0,0 +1,49 @@ +/* ScummVM - Graphic Adventure Engine + * + * ScummVM is the legal property of its developers, whose names + * are too numerous to list here. Please refer to the COPYRIGHT + * file distributed with this source distribution. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * + * $URL$ + * $Id$ + * + */ + +#ifndef KYRA_SCREEN_V3_H +#define KYRA_SCREEN_V3_H + +#include "kyra/screen.h" + +namespace Kyra { + +class KyraEngine_v3; + +class Screen_v3 : public ScreenEx { +public: + Screen_v3(KyraEngine_v3 *vm, OSystem *system); + virtual ~Screen_v3(); + + virtual void setScreenDim(int dim); + virtual const ScreenDim *getScreenDim(int dim); +private: + static const ScreenDim _screenDimTable[]; + static const int _screenDimTableCount; +}; + +} // end of namespace Kyra + +#endif diff --git a/engines/kyra/sequences_v2.cpp b/engines/kyra/sequences_v2.cpp index a757559fc9..d717da5c21 100644 --- a/engines/kyra/sequences_v2.cpp +++ b/engines/kyra/sequences_v2.cpp @@ -351,7 +351,7 @@ int KyraEngine_v2::seq_introTitle(WSAMovieV2 *wsaObj, int x, int y, int frm) { int cp = _screen->setCurPage(0); _screen->showMouse(); _system->updateScreen(); - _menuChoice = gui_handleMainMenu() + 1; + _menuChoice = _menu->handle(11) + 1; _seqEndTime = 0; _seqSubframePlaying = false; if (_menuChoice == 4) @@ -2044,7 +2044,7 @@ void KyraEngine_v2::seq_loadNestedSequence(int wsaNum, int seqNum) { NestedSequence s = _sequences->seqn[seqNum]; if (!_activeWSA[wsaNum].movie) { - _activeWSA[wsaNum].movie = new WSAMovieV2(this); + _activeWSA[wsaNum].movie = new WSAMovieV2(this, _screen); assert(_activeWSA[wsaNum].movie); } @@ -2572,7 +2572,7 @@ void KyraEngine_v2::seq_scrollPage() { } void KyraEngine_v2::seq_showStarcraftLogo() { - WSAMovieV2 *ci = new WSAMovieV2(this); + WSAMovieV2 *ci = new WSAMovieV2(this, _screen); assert(ci); _screen->clearPage(2); _res->loadPakFile("INTROGEN.PAK"); @@ -2614,7 +2614,7 @@ void KyraEngine_v2::seq_showStarcraftLogo() { void KyraEngine_v2::seq_init() { _seqProcessedString = new char[200]; - _seqWsa = new WSAMovieV2(this); + _seqWsa = new WSAMovieV2(this, _screen); _activeWSA = new ActiveWSA[8]; _activeText = new ActiveText[10]; @@ -2636,6 +2636,15 @@ void KyraEngine_v2::seq_init() { _defaultShapeTable[numShp] = _screen->getPtrToShape(_newShapeFiledata, numShp); } while (_defaultShapeTable[numShp]); } + + MainMenu::StaticData data = { + { _sequenceStrings[97], _sequenceStrings[96], _sequenceStrings[95], _sequenceStrings[98] }, + { 0x01, 0x04, 0x0C, 0x04, 0x00, 0xd7, 0xd6, 0x00, 0x01, 0x02, 0x03 }, + { 0xd8, 0xda, 0xd9, 0xd8 }, + 0xd7, 0xd6 + }; + _menu = new MainMenu(this); + _menu->init(data, MainMenu::Animation()); } void KyraEngine_v2::seq_uninit() { @@ -2658,6 +2667,9 @@ void KyraEngine_v2::seq_uninit() { _staticres->unloadId(k2SeqplayShapeAnimData); memset(&_defaultShapeTable, 0, sizeof(_defaultShapeTable)); + + delete _menu; + _menu = 0; } #pragma mark - diff --git a/engines/kyra/staticres.cpp b/engines/kyra/staticres.cpp index c7ee6a6b58..f96ad9928c 100644 --- a/engines/kyra/staticres.cpp +++ b/engines/kyra/staticres.cpp @@ -31,6 +31,9 @@ #include "kyra/kyra_v2.h" #include "kyra/kyra_v3.h" #include "kyra/screen.h" +#include "kyra/screen_v1.h" +#include "kyra/screen_v2.h" +#include "kyra/screen_v3.h" #include "kyra/resource.h" #include "kyra/gui_v1.h" @@ -1259,7 +1262,7 @@ void KyraEngine_v2::initStaticResource() { _callbackN = (_flags.isDemo && !_flags.isTalkie) ? hofDemoNestedSequenceCallbacks : hofNestedSequenceCallbacks; } -const ScreenDim Screen::_screenDimTable[] = { +const ScreenDim Screen_v1::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0x0F, 0x0C, 0x00, 0x00 }, { 0x08, 0x48, 0x18, 0x38, 0x0F, 0x0C, 0x00, 0x00 }, { 0x01, 0x08, 0x26, 0x80, 0x0F, 0x0C, 0x00, 0x00 }, @@ -1273,7 +1276,7 @@ const ScreenDim Screen::_screenDimTable[] = { { 0x03, 0x28, 0x22, 0x46, 0x0F, 0x0D, 0x00, 0x00 } }; -const int Screen::_screenDimTableCount = ARRAYSIZE(Screen::_screenDimTable); +const int Screen_v1::_screenDimTableCount = ARRAYSIZE(Screen_v1::_screenDimTable); const ScreenDim Screen_v2::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0xC7, 0xCF, 0x00, 0x00 }, @@ -1292,14 +1295,14 @@ const ScreenDim Screen_v2::_screenDimTable[] = { const int Screen_v2::_screenDimTableCount = ARRAYSIZE(Screen_v2::_screenDimTable); -const ScreenDim Screen_v2::_screenDimTableK3[] = { +const ScreenDim Screen_v3::_screenDimTable[] = { { 0x00, 0x00, 0x28, 0xC8, 0xFF, 0xF0, 0x00, 0x00 }, { 0x08, 0x48, 0x18, 0x38, 0xFF, 0xF0, 0x00, 0x00 }, { 0x00, 0x00, 0x28, 0xBC, 0xFF, 0xF0, 0x00, 0x00 }, { 0x0A, 0x96, 0x14, 0x30, 0x19, 0xF0, 0x00, 0x00 } }; -const int Screen_v2::_screenDimTableCountK3 = ARRAYSIZE(Screen_v2::_screenDimTableK3); +const int Screen_v3::_screenDimTableCount = ARRAYSIZE(Screen_v3::_screenDimTable); const int8 KyraEngine::_addXPosTable[] = { 4, 4, 0, -4, -4, -4, 0, 4 @@ -1480,7 +1483,7 @@ const int KyraEngine_v1::_dosTrackMapSize = ARRAYSIZE(KyraEngine_v1::_dosTrackMa // Kyra 2 and 3 main menu -const char *KyraEngine_v2::_mainMenuStrings[] = { +const char *KyraEngine_v3::_mainMenuStrings[] = { "Start a new game", "Introduction", "Load a game", diff --git a/engines/kyra/wsamovie.cpp b/engines/kyra/wsamovie.cpp index 222f4016a4..a8ffafb355 100644 --- a/engines/kyra/wsamovie.cpp +++ b/engines/kyra/wsamovie.cpp @@ -341,7 +341,7 @@ void WSAMovieAmiga::processFrame(int frameNum, uint8 *dst) { #pragma mark - -WSAMovieV2::WSAMovieV2(KyraEngine_v2 *vm) : WSAMovieV1(vm), _vm(vm), _xAdd(0), _yAdd(0), _oldOff(false) {} +WSAMovieV2::WSAMovieV2(KyraEngine *vm, ScreenEx *screen) : WSAMovieV1(vm), _screen(screen), _xAdd(0), _yAdd(0) {} int WSAMovieV2::open(const char *filename, int unk1, uint8 *palBuf) { debugC(9, kDebugLevelMovie, "WSAMovieV2::open('%s', %d, %p)", filename, unk1, (const void *)palBuf); @@ -437,7 +437,7 @@ void WSAMovieV2::displayFrame(int frameNum, ...) { if (_flags & WF_OFFSCREEN_DECODE) dst = _offscreenBuffer; else - dst = _vm->screen()->getPageRect(_drawPage, _x, _y, _width, _height); + dst = _screen->getPageRect(_drawPage, _x, _y, _width, _height); if (_currentFrame == _numFrames) { if (!(_flags & WF_NO_FIRST_FRAME)) { @@ -489,32 +489,23 @@ void WSAMovieV2::displayFrame(int frameNum, ...) { // display _currentFrame = frameNum; if (_flags & WF_OFFSCREEN_DECODE) { - if (_oldOff) { - // Kyrandia 1 offscreen buffer -> screen copy method of Kyrandia 1, needs to be present - // for our Kyrandia 3 menu code - _vm->screen()->copyBlockToPage(_drawPage, _x, _y, _width, _height, _offscreenBuffer); - } else { - // This is the offscreen buffer -> screen copy method of Kyrandia 2 as it's implemented - // in the original - Screen_v2 *screen = _vm->screen_v2(); - int pageBackUp = screen->_curPage; - screen->_curPage = _drawPage; - - va_list args; - va_start(args, frameNum); - - int copyParam = va_arg(args, int); - int plotFunc = (copyParam & 0xFF00) >> 12; - int unk1 = copyParam & 0xFF; - - const uint8 *unkPtr1 = va_arg(args, const uint8*); - const uint8 *unkPtr2 = va_arg(args, const uint8*); - va_end(args); - - screen->copyWsaRect(_x, _y, _width, _height, 0, plotFunc, _offscreenBuffer, unk1, unkPtr1, unkPtr2); - - screen->_curPage = pageBackUp; - } + int pageBackUp = _screen->_curPage; + _screen->_curPage = _drawPage; + + va_list args; + va_start(args, frameNum); + + int copyParam = va_arg(args, int); + int plotFunc = (copyParam & 0xFF00) >> 12; + int unk1 = copyParam & 0xFF; + + const uint8 *unkPtr1 = va_arg(args, const uint8*); + const uint8 *unkPtr2 = va_arg(args, const uint8*); + va_end(args); + + _screen->copyWsaRect(_x, _y, _width, _height, 0, plotFunc, _offscreenBuffer, unk1, unkPtr1, unkPtr2); + + _screen->_curPage = pageBackUp; } } diff --git a/engines/kyra/wsamovie.h b/engines/kyra/wsamovie.h index 5e97e1a5fb..ad577f7029 100644 --- a/engines/kyra/wsamovie.h +++ b/engines/kyra/wsamovie.h @@ -35,7 +35,7 @@ class SoundHandle; namespace Kyra { class KyraEngine; -class KyraEngine_v2; +class ScreenEx; class Movie { public: @@ -111,7 +111,7 @@ private: class WSAMovieV2 : public WSAMovieV1 { public: - WSAMovieV2(KyraEngine_v2 *vm); + WSAMovieV2(KyraEngine *vm, ScreenEx *scren); int open(const char *filename, int unk1, uint8 *palette); @@ -128,15 +128,11 @@ public: void setWidth(int w) { _width = w; } void setHeight(int h) { _height = h; } - - // HACK for our intro code - void flagOldOff(bool enabled) { _oldOff = enabled; } protected: - KyraEngine_v2 *_vm; + ScreenEx *_screen; int16 _xAdd; int16 _yAdd; - bool _oldOff; // old offscreen copy, HACK for our intro code }; } // end of namespace Kyra |