aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/kyra/debugger.cpp5
-rw-r--r--engines/kyra/gui.cpp193
-rw-r--r--engines/kyra/gui.h51
-rw-r--r--engines/kyra/gui_v1.cpp18
-rw-r--r--engines/kyra/gui_v1.h3
-rw-r--r--engines/kyra/gui_v2.cpp195
-rw-r--r--engines/kyra/kyra.h4
-rw-r--r--engines/kyra/kyra_v1.cpp2
-rw-r--r--engines/kyra/kyra_v2.cpp8
-rw-r--r--engines/kyra/kyra_v2.h14
-rw-r--r--engines/kyra/kyra_v3.cpp340
-rw-r--r--engines/kyra/kyra_v3.h51
-rw-r--r--engines/kyra/module.mk1
-rw-r--r--engines/kyra/resource.cpp3
-rw-r--r--engines/kyra/screen.cpp567
-rw-r--r--engines/kyra/screen.h168
-rw-r--r--engines/kyra/screen_v1.cpp190
-rw-r--r--engines/kyra/screen_v1.h29
-rw-r--r--engines/kyra/screen_v2.cpp322
-rw-r--r--engines/kyra/screen_v2.h39
-rw-r--r--engines/kyra/screen_v3.cpp50
-rw-r--r--engines/kyra/screen_v3.h49
-rw-r--r--engines/kyra/sequences_v2.cpp20
-rw-r--r--engines/kyra/staticres.cpp13
-rw-r--r--engines/kyra/wsamovie.cpp47
-rw-r--r--engines/kyra/wsamovie.h10
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