aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--engines/neverhood/background.h1
-rw-r--r--engines/neverhood/gamemodule.cpp2
-rw-r--r--engines/neverhood/graphics.cpp7
-rw-r--r--engines/neverhood/module2200.cpp209
-rw-r--r--engines/neverhood/module2200.h24
-rw-r--r--engines/neverhood/neverhood.h1
-rw-r--r--engines/neverhood/palette.cpp2
-rw-r--r--engines/neverhood/screen.cpp122
-rw-r--r--engines/neverhood/screen.h3
9 files changed, 361 insertions, 10 deletions
diff --git a/engines/neverhood/background.h b/engines/neverhood/background.h
index 733f80b83d..8ac3581a51 100644
--- a/engines/neverhood/background.h
+++ b/engines/neverhood/background.h
@@ -38,6 +38,7 @@ public:
BaseSurface *getSurface() { return _surface; }
void createSurface(int surfacePriority, int16 width, int16 height);
void load(uint32 fileHash);
+ SpriteResource& getSpriteResource() { return _spriteResource; }
protected:
BaseSurface *_surface;
SpriteResource _spriteResource;
diff --git a/engines/neverhood/gamemodule.cpp b/engines/neverhood/gamemodule.cpp
index b987aa7c78..920893c650 100644
--- a/engines/neverhood/gamemodule.cpp
+++ b/engines/neverhood/gamemodule.cpp
@@ -242,7 +242,7 @@ void GameModule::startup() {
createModule2000(-1);
#endif
#if 1
- _vm->gameState().sceneNum = 6;
+ _vm->gameState().sceneNum = 7;
createModule2200(-1);
#endif
}
diff --git a/engines/neverhood/graphics.cpp b/engines/neverhood/graphics.cpp
index 204e38628d..900ad57d56 100644
--- a/engines/neverhood/graphics.cpp
+++ b/engines/neverhood/graphics.cpp
@@ -52,8 +52,11 @@ BaseSurface::~BaseSurface() {
void BaseSurface::draw() {
if (_surface && _visible && _drawRect.width > 0 && _drawRect.height > 0) {
- // TODO: _sysRect alternate drawing code (is that used?)
- _vm->_screen->drawSurface2(_surface, _drawRect, _clipRect, _transparent);
+ if (_sysRect.x == 0 && _sysRect.y == 0) {
+ _vm->_screen->drawSurface2(_surface, _drawRect, _clipRect, _transparent);
+ } else {
+ _vm->_screen->drawUnk(_surface, _drawRect, _sysRect, _clipRect, _transparent);
+ }
}
}
diff --git a/engines/neverhood/module2200.cpp b/engines/neverhood/module2200.cpp
index 67c3be8cec..2fb3eecc91 100644
--- a/engines/neverhood/module2200.cpp
+++ b/engines/neverhood/module2200.cpp
@@ -240,6 +240,11 @@ void Module2200::createScene2207(int which) {
}
void Module2200::createScene2208(int which) {
+ if (which >= 0)
+ _vm->gameState().which = _vm->gameState().sceneNum;
+ _vm->gameState().sceneNum = 7;
+ _childObject = new Scene2208(_vm, this, which);
+ SetUpdateHandler(&Module2200::updateScene2208);
}
void Module2200::createScene2209(int which) {
@@ -470,6 +475,15 @@ void Module2200::updateScene2207() {
}
void Module2200::updateScene2208() {
+ _childObject->handleUpdate();
+ if (_done) {
+ _done = false;
+ delete _childObject;
+ _childObject = NULL;
+ // TODO
+ createScene2206(2);
+ _childObject->handleUpdate();
+ }
}
void Module2200::updateScene2209() {
@@ -2414,4 +2428,199 @@ uint32 Scene2207::handleMessage2(int messageNum, const MessageParam &param, Enti
return messageResult;
}
+static const uint32 kScene2208FileHashes1[] = {
+ 0x041023CB,
+ 0x041020CB,
+ 0x041026CB,
+ 0x04102ACB,
+ 0x041032CB,
+ 0x041002CB
+};
+
+static const uint32 kScene2208FileHashes2[] = {
+ 0x091206C9,
+ 0x091406C9,
+ 0x091806C9,
+ 0x090006C9,
+ 0x093006C9,
+ 0x095006C9
+};
+
+Scene2208::Scene2208(NeverhoodEngine *vm, Module *parentModule, int which)
+ : Scene(vm, parentModule, true), _textResource(vm) {
+
+ SpriteResource spriteResource(_vm);
+ const char *textStart, *textEnd;
+
+ if (!getGlobalVar(0xC8C28808))
+ setGlobalVar(0xC8C28808, calcHash("stLineagex"));
+
+ _textResource.load(getGlobalVar(0xC8C28808));
+
+ textStart = _textResource.getString(getGlobalVar(0x48A68852), textEnd);
+ while (textStart < textEnd) {
+ _strings.push_back(textStart);
+ textStart += strlen(textStart) + 1;
+ }
+
+ _maxRowIndex = 8 + 10 * (3 - (getGlobalVar(0xC8C28808) == calcHash("stLineagex") ? 1 : 0));
+
+ _background = new Background(_vm, 0);
+ _background->createSurface(0, 640, 528);
+ _background->getSpriteResource().getPosition().y = 480;
+ addBackground(_background);
+
+ _palette = new Palette(_vm, 0x08100289);
+ _palette->usePalette();
+ addEntity(_palette); // Why?
+
+ _mouseCursor = addSprite(new Mouse435(_vm, 0x0028D089, 40, 600));
+
+ createFontSurface();
+
+ _backgroundSurface = new BaseSurface(_vm, 0, 640, 480);
+ spriteResource.load2(0x08100289);
+ _backgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0);
+
+ _topBackgroundSurface = new BaseSurface(_vm, 0, 640, 192);
+ spriteResource.load2(!getGlobalVar(0x4CE79018) ? kScene2208FileHashes1[getGlobalVar(0x48A68852) % 6] : getGlobalVar(0x4CE79018));
+ _topBackgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0);
+
+ _bottomBackgroundSurface = new BaseSurface(_vm, 0, 640, 192);
+ spriteResource.load2(kScene2208FileHashes2[getGlobalVar(0x48A68852) % 6]);
+ _bottomBackgroundSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0);
+
+ SetUpdateHandler(&Scene2208::update);
+ SetMessageHandler(&Scene2208::handleMessage);
+
+ _visibleRowsCount = 10;
+
+ _newRowIndex = (int16)getGlobalVar(0x49C40058);
+ if (_newRowIndex + _visibleRowsCount > _maxRowIndex)
+ _newRowIndex = _maxRowIndex - _visibleRowsCount;
+ if (_newRowIndex < 6)
+ _newRowIndex = 0;
+
+ _rowScrollY = 0;
+
+ _backgroundScrollY = 48 * _newRowIndex;
+
+ _currRowIndex = _newRowIndex;
+
+ for (int16 rowIndex = 0; rowIndex < _visibleRowsCount; rowIndex++)
+ drawRow(_newRowIndex + rowIndex);
+
+ _background->getSurface()->getSysRect().y = _backgroundScrollY;
+
+ // TODO Screen.yOffset = _backgroundScrollY;
+ // TODO Scene2208_sub409080 (creates background Sprites via the text, doesn't seem to be used?)
+
+}
+
+Scene2208::~Scene2208() {
+ delete _fontSurface;
+ delete _backgroundSurface;
+ delete _topBackgroundSurface;
+ delete _bottomBackgroundSurface;
+}
+
+void Scene2208::update() {
+
+ int16 mouseY = _vm->getMouseY();
+
+ if (mouseY < 48) {
+ if (_currRowIndex > 0)
+ _newRowIndex = _currRowIndex - 1;
+ } else if (mouseY > 432) {
+ if (_currRowIndex < _maxRowIndex - _visibleRowsCount)
+ _newRowIndex = _currRowIndex + 1;
+ } else {
+ if (_currRowIndex > _newRowIndex)
+ _newRowIndex = _currRowIndex;
+ }
+
+ if (_currRowIndex < _newRowIndex) {
+ if (_rowScrollY == 0) {
+ drawRow(_currRowIndex + _visibleRowsCount);
+ }
+ _backgroundScrollY += 4;
+ _rowScrollY += 4;
+ if (_rowScrollY == 48) {
+ _rowScrollY = 0;
+ _currRowIndex++;
+ }
+ _background->getSurface()->getSysRect().y = _backgroundScrollY;
+ } else if (_currRowIndex > _newRowIndex || _rowScrollY > 0) {
+ if (_rowScrollY == 0) {
+ drawRow(_currRowIndex - 1);
+ _currRowIndex--;
+ }
+ _backgroundScrollY -= 4;
+ if (_rowScrollY == 0)
+ _rowScrollY = 48;
+ _rowScrollY -= 4;
+ _background->getSurface()->getSysRect().y = _backgroundScrollY;
+ }
+
+ // TODO Screen.yOffset = _backgroundScrollY;
+ Scene::update();
+
+}
+
+uint32 Scene2208::handleMessage(int messageNum, const MessageParam &param, Entity *sender) {
+ uint32 messageResult = Scene::handleMessage(messageNum, param, sender);
+ switch (messageNum) {
+ case 0x0001:
+ if (param.asPoint().x <= 40 || param.asPoint().x >= 600) {
+ _parentModule->sendMessage(0x1009, 0, this);
+ }
+ break;
+ }
+ return messageResult;
+}
+
+void Scene2208::createFontSurface() {
+ DataResource fontData(_vm);
+ SpriteResource spriteResource(_vm);
+ fontData.load(calcHash("asRecFont"));
+ uint16 numRows = fontData.getPoint(calcHash("meNumRows")).x;
+ uint16 firstChar = fontData.getPoint(calcHash("meFirstChar")).x;
+ uint16 charWidth = fontData.getPoint(calcHash("meCharWidth")).x;
+ uint16 charHeight = fontData.getPoint(calcHash("meCharHeight")).x;
+ NPointArray *tracking = fontData.getPointArray(calcHash("meTracking"));
+ spriteResource.load2(0x0800090C);
+ _fontSurface = new FontSurface(_vm, tracking, numRows, firstChar, charWidth, charHeight);
+ _fontSurface->drawSpriteResourceEx(spriteResource, false, false, 0, 0);
+}
+
+void Scene2208::drawRow(int16 rowIndex) {
+ NDrawRect sourceRect;
+ int16 y = (rowIndex * 48) % 528;
+ if (rowIndex < 4) {
+ sourceRect.x = 0;
+ sourceRect.y = y;
+ sourceRect.width = 640;
+ sourceRect.height = 48;
+ _background->getSurface()->copyFrom(_topBackgroundSurface->getSurface(), 0, y, sourceRect, true);
+ } else if (rowIndex >= _maxRowIndex - 5) {
+ sourceRect.x = 0;
+ sourceRect.y = (rowIndex - _maxRowIndex + 4) * 48;
+ sourceRect.width = 640;
+ sourceRect.height = 48;
+ _background->getSurface()->copyFrom(_bottomBackgroundSurface->getSurface(), 0, y, sourceRect, true);
+ } else {
+ rowIndex -= 4;
+ sourceRect.x = 0;
+ sourceRect.y = (rowIndex * 48) % 480;
+ sourceRect.width = 640;
+ sourceRect.height = 48;
+ _background->getSurface()->copyFrom(_backgroundSurface->getSurface(), 0, y, sourceRect, true);
+ if (rowIndex < _strings.size()) {
+ const char *text = _strings[rowIndex];
+ // TODO/CHECKME: Use temporary string up to '{' character (see above)
+ _fontSurface->drawString(_background->getSurface(), 95, y, (const byte*)text);
+ }
+ }
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/module2200.h b/engines/neverhood/module2200.h
index cf53e698ee..7a75e128f3 100644
--- a/engines/neverhood/module2200.h
+++ b/engines/neverhood/module2200.h
@@ -27,6 +27,7 @@
#include "neverhood/module.h"
#include "neverhood/scene.h"
#include "neverhood/module1000.h"
+#include "neverhood/graphics.h"
namespace Neverhood {
@@ -424,6 +425,29 @@ protected:
uint32 handleMessage2(int messageNum, const MessageParam &param, Entity *sender);
};
+class Scene2208 : public Scene {
+public:
+ Scene2208(NeverhoodEngine *vm, Module *parentModule, int which);
+ ~Scene2208();
+protected:
+ FontSurface *_fontSurface;
+ BaseSurface *_backgroundSurface;
+ BaseSurface *_topBackgroundSurface;
+ BaseSurface *_bottomBackgroundSurface;
+ TextResource _textResource;
+ int16 _backgroundScrollY;
+ int16 _newRowIndex;
+ int16 _currRowIndex;
+ int16 _rowScrollY;
+ int16 _maxRowIndex;
+ int16 _visibleRowsCount;
+ Common::Array<const char*> _strings; // TODO: Move to TextResource
+ void update();
+ uint32 handleMessage(int messageNum, const MessageParam &param, Entity *sender);
+ void createFontSurface();
+ void drawRow(int16 rowIndex);
+};
+
} // End of namespace Neverhood
#endif /* NEVERHOOD_MODULE2200_H */
diff --git a/engines/neverhood/neverhood.h b/engines/neverhood/neverhood.h
index edb204c92d..b4bc333e98 100644
--- a/engines/neverhood/neverhood.h
+++ b/engines/neverhood/neverhood.h
@@ -49,6 +49,7 @@ struct NPoint;
struct GameState {
int sceneNum;
+ int which;
int field2;
};
diff --git a/engines/neverhood/palette.cpp b/engines/neverhood/palette.cpp
index 28fa81b87a..bd1d6b2c8d 100644
--- a/engines/neverhood/palette.cpp
+++ b/engines/neverhood/palette.cpp
@@ -114,7 +114,7 @@ void Palette::startFadeToWhite(int counter) {
}
void Palette::update() {
- debug("Palette::update() _status = %d", _status);
+ debug(2, "Palette::update() _status = %d", _status);
if (_status == 1) {
if (_palCounter > 1) {
for (int i = 0; i < 256; i++) {
diff --git a/engines/neverhood/screen.cpp b/engines/neverhood/screen.cpp
index a88491424c..351e51a3e9 100644
--- a/engines/neverhood/screen.cpp
+++ b/engines/neverhood/screen.cpp
@@ -125,7 +125,53 @@ void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect,
ddRect.y1 = 0;
}
- debug(2, "draw: x = %d; y = %d; (%d, %d, %d, %d)", destX, destY, ddRect.x1, ddRect.y1, ddRect.x2, ddRect.y2);
+ //debug(2, "draw: x = %d; y = %d; (%d, %d, %d, %d)", destX, destY, ddRect.x1, ddRect.y1, ddRect.x2, ddRect.y2);
+
+ blit(surface, destX, destY, ddRect, transparent);
+
+ // Useful for debugging
+ //_backScreen->frameRect(Common::Rect(clipRect.x1, clipRect.y1, clipRect.x2, clipRect.y2), 250);
+ //_backScreen->frameRect(Common::Rect(destX, destY, destX + ddRect.x2, destY + ddRect.y2), 255);
+ //_backScreen->frameRect(Common::Rect(drawRect.x, drawRect.y, drawRect.x + drawRect.width, drawRect.y + drawRect.height), 255);
+
+}
+
+void Screen::drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect, bool transparent) {
+
+ int16 destX, destY;
+ NRect ddRect;
+
+ if (x + drawRect.width >= clipRect.x2)
+ ddRect.x2 = clipRect.x2 - drawRect.x - x;
+ else
+ ddRect.x2 = drawRect.x + drawRect.width;
+
+ if (x < clipRect.x1) {
+ destX = clipRect.x1;
+ ddRect.x1 = clipRect.x1 + drawRect.x - x;
+ } else {
+ destX = x;
+ ddRect.x1 = drawRect.x;
+ }
+
+ if (y + drawRect.height >= clipRect.y2)
+ ddRect.y2 = clipRect.y2 + drawRect.y - y;
+ else
+ ddRect.y2 = drawRect.y + drawRect.height;
+
+ if (y < clipRect.y1) {
+ destY = clipRect.y1;
+ ddRect.y1 = clipRect.y1 + drawRect.y - y;
+ } else {
+ destY = y;
+ ddRect.y1 = drawRect.y;
+ }
+
+ blit(surface, destX, destY, ddRect, transparent);
+
+}
+
+void Screen::blit(const Graphics::Surface *surface, int16 destX, int16 destY, NRect &ddRect, bool transparent) {
const byte *source = (const byte*)surface->getBasePtr(ddRect.x1, ddRect.y1);
byte *dest = (byte*)_backScreen->getBasePtr(destX, destY);
@@ -151,11 +197,6 @@ void Screen::drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect,
}
}
- // Useful for debugging
- //_backScreen->frameRect(Common::Rect(clipRect.x1, clipRect.y1, clipRect.x2, clipRect.y2), 250);
- //_backScreen->frameRect(Common::Rect(destX, destY, destX + ddRect.x2, destY + ddRect.y2), 255);
- //_backScreen->frameRect(Common::Rect(drawRect.x, drawRect.y, drawRect.x + drawRect.width, drawRect.y + drawRect.height), 255);
-
}
void Screen::drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &drawRect) {
@@ -176,4 +217,73 @@ void Screen::drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &dra
}
+void Screen::drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDrawRect &sysRect, NRect &clipRect, bool transparent) {
+
+ int16 x, y;
+ bool xflag, yflag;
+ NDrawRect newDrawRect;
+
+ x = sysRect.x;
+ if (sysRect.width <= x || -sysRect.width >= x) {
+ x = x % sysRect.width;
+ }
+ if (x < 0)
+ x += sysRect.width;
+
+ y = sysRect.y;
+ if (y >= sysRect.height || -sysRect.height >= y) {
+ y = y % sysRect.height;
+ }
+ if (y < 0)
+ y += sysRect.height;
+
+ xflag = x <= 0;
+ yflag = y <= 0;
+
+ newDrawRect.x = x;
+ newDrawRect.width = sysRect.width - x;
+ if (drawRect.width < newDrawRect.width) {
+ xflag = true;
+ newDrawRect.width = drawRect.width;
+ }
+
+ newDrawRect.y = y;
+ newDrawRect.height = sysRect.height - y;
+ if (drawRect.height < newDrawRect.height) {
+ yflag = true;
+ newDrawRect.height = drawRect.height;
+ }
+
+ drawSurface3(surface, drawRect.x, drawRect.y, newDrawRect, clipRect, transparent);
+
+ if (!xflag) {
+ newDrawRect.x = 0;
+ newDrawRect.y = y;
+ newDrawRect.width = x + drawRect.width - sysRect.width;
+ newDrawRect.height = sysRect.height - y;
+ if (drawRect.height < newDrawRect.height)
+ newDrawRect.height = drawRect.height;
+ drawSurface3(surface, sysRect.width + drawRect.x - x, drawRect.y, newDrawRect, clipRect, transparent);
+ }
+
+ if (!yflag) {
+ newDrawRect.x = x;
+ newDrawRect.y = 0;
+ newDrawRect.width = sysRect.width - x;
+ newDrawRect.height = y + drawRect.height - sysRect.height;
+ if (drawRect.width < newDrawRect.width)
+ newDrawRect.width = drawRect.width;
+ drawSurface3(surface, drawRect.x, sysRect.height + drawRect.y - y, newDrawRect, clipRect, transparent);
+ }
+
+ if (!xflag && !yflag) {
+ newDrawRect.x = 0;
+ newDrawRect.y = 0;
+ newDrawRect.width = x + drawRect.width - sysRect.width;
+ newDrawRect.height = y + drawRect.height - sysRect.height;
+ drawSurface3(surface, sysRect.width + drawRect.x - x, sysRect.height + drawRect.y - y, newDrawRect, clipRect, transparent);
+ }
+
+}
+
} // End of namespace Neverhood
diff --git a/engines/neverhood/screen.h b/engines/neverhood/screen.h
index 922ad481f3..e813e63f20 100644
--- a/engines/neverhood/screen.h
+++ b/engines/neverhood/screen.h
@@ -43,7 +43,10 @@ public:
void updatePalette();
void clear();
void drawSurface2(const Graphics::Surface *surface, NDrawRect &drawRect, NRect &clipRect, bool transparent);
+ void drawSurface3(const Graphics::Surface *surface, int16 x, int16 y, NDrawRect &drawRect, NRect &clipRect, bool transparent);
+ void blit(const Graphics::Surface *surface, int16 destX, int16 destY, NRect &ddRect, bool transparent);
void drawDoubleSurface2(const Graphics::Surface *surface, NDrawRect &drawRect);
+ void drawUnk(const Graphics::Surface *surface, NDrawRect &drawRect, NDrawRect &sysRect, NRect &clipRect, bool transparent);
protected:
NeverhoodEngine *_vm;
Graphics::Surface *_backScreen;