aboutsummaryrefslogtreecommitdiff
path: root/engines/m4/scene.cpp
diff options
context:
space:
mode:
authorFilippos Karapetis2008-04-20 14:47:37 +0000
committerFilippos Karapetis2008-04-20 14:47:37 +0000
commit7ca439f410ac1c46a387567b30271ae4e4a2ed30 (patch)
tree4d4154169b074293581ad6a11ee821290418f4fb /engines/m4/scene.cpp
parentd0590a09eac68d5cde64d37fb2e5bbd1471a676a (diff)
downloadscummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.tar.gz
scummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.tar.bz2
scummvm-rg350-7ca439f410ac1c46a387567b30271ae4e4a2ed30.zip
Initial import of the work in progress M4 engine
svn-id: r31600
Diffstat (limited to 'engines/m4/scene.cpp')
-rw-r--r--engines/m4/scene.cpp669
1 files changed, 669 insertions, 0 deletions
diff --git a/engines/m4/scene.cpp b/engines/m4/scene.cpp
new file mode 100644
index 0000000000..787b8dd8eb
--- /dev/null
+++ b/engines/m4/scene.cpp
@@ -0,0 +1,669 @@
+/* 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 "common/system.h"
+
+#include "m4/globals.h"
+#include "m4/scene.h"
+#include "m4/events.h"
+#include "m4/graphics.h"
+#include "m4/rails.h"
+#include "m4/font.h"
+#include "m4/m4_views.h"
+#include "m4/compression.h"
+
+namespace M4 {
+
+Scene::Scene(M4Engine *vm): View(vm, Common::Rect(0, 0, vm->_screen->width(), vm->_screen->height())) {
+ _screenType = VIEWID_SCENE;
+
+ _sceneResources.hotspots = new HotSpotList();
+ _sceneResources.parallax = new HotSpotList();
+ _sceneResources.props = new HotSpotList();
+ _backgroundSurface = new M4Surface();
+ _codeSurface = new M4Surface();
+ _madsInterfaceSurface = new M4Surface();
+ _sceneSprites = NULL;
+ _palData = NULL;
+ _interfacePal = NULL;
+ _inverseColorTable = NULL;
+ strcpy(_statusText, "");
+ _vm->_rails->setCodeSurface(_codeSurface);
+}
+
+Scene::~Scene() {
+ _sceneResources.hotspots->clear();
+ _sceneResources.parallax->clear();
+ _sceneResources.props->clear();
+
+ delete _sceneResources.hotspots;
+ delete _sceneResources.parallax;
+ delete _sceneResources.props;
+
+ delete _backgroundSurface;
+ delete _codeSurface;
+ delete _madsInterfaceSurface;
+
+ if (_sceneSprites)
+ delete _sceneSprites;
+
+ _vm->_palette->deleteAllRanges();
+
+ if (_palData)
+ delete _palData;
+
+ if (_interfacePal)
+ delete _interfacePal;
+
+ if (_inverseColorTable)
+ delete[] _inverseColorTable;
+
+}
+
+void Scene::loadScene(int sceneNumber) {
+ _currentScene = sceneNumber;
+
+ // Close the menu if it's active
+ if (!_vm->isM4()) {
+ View *mainMenu = _vm->_viewManager->getView(VIEWID_MAINMENU);
+ if (mainMenu != NULL) {
+ _vm->_viewManager->deleteView(mainMenu);
+ }
+ }
+
+ // TODO: Check if we were loading a game
+
+
+ // Load scene background and set palette
+ if (_palData) {
+ _vm->_palette->deleteRange(_palData);
+ delete _palData;
+ }
+
+ if (_interfacePal) {
+ _vm->_palette->deleteRange(_interfacePal);
+ delete _interfacePal;
+ }
+
+ if (_vm->isM4()) {
+ _backgroundSurface->loadBackground(sceneNumber);
+ _palData = NULL;
+ } else {
+ _backgroundSurface->loadBackground(sceneNumber, &_palData);
+ _vm->_palette->addRange(_palData);
+ _backgroundSurface->translate(_palData);
+
+ if (sceneNumber < 900) {
+ /*_backgroundSurface->fillRect(Common::Rect(0, MADS_SURFACE_HEIGHT,
+ _backgroundSurface->width(), _backgroundSurface->height()),
+ _vm->_palette->BLACK);*/
+ // TODO: interface palette
+ _madsInterfaceSurface->madsloadInterface(0, &_interfacePal);
+ _vm->_palette->addRange(_interfacePal);
+ _madsInterfaceSurface->translate(_interfacePal);
+ _backgroundSurface->copyFrom(_madsInterfaceSurface, Common::Rect(0, 0, 320, 44), 0, 200 - 44);
+ }
+ }
+
+ if (_vm->getGameType() == GType_Burger &&
+ sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER)
+ _vm->_interfaceView->setStatusText("");
+
+ // Load scene def file (*.CHK)
+ if (_vm->isM4()) {
+ loadSceneResources(sceneNumber);
+ loadSceneInverseColorTable(sceneNumber);
+ } else {
+ // Don't load other screen resources for system screens
+ if (sceneNumber >= 900)
+ return;
+
+ loadSceneHotSpotsMads(sceneNumber);
+ }
+
+ // TODO: set walker scaling
+ // TODO: destroy woodscript buffer
+
+ // Load scene walk path file (*.COD/*.WW?)
+ loadSceneCodes(sceneNumber);
+
+ // Load inverse color table file (*.IPL)
+ loadSceneInverseColorTable(sceneNumber);
+
+ if (_vm->isM4()) {
+
+ if (_vm->getGameType() != GType_Burger) {
+ // Load scene sprites file (*.SSB)
+ loadSceneSprites(sceneNumber);
+
+ // Load scene sprite codes file (*.SSC)
+ loadSceneSpriteCodes(sceneNumber);
+ }
+
+
+ if (sceneNumber != TITLE_SCENE_BURGER && sceneNumber != MAINMENU_SCENE_BURGER) {
+ _vm->_interfaceView->show();
+ showSprites();
+ }
+ }
+
+ // Purge resources
+ _vm->res()->purge();
+}
+
+void Scene::loadSceneResources(int sceneNumber) {
+ char filename[kM4MaxFilenameSize];
+ int i = 0, x = 0, y = 0;
+ sprintf(filename, "%i.chk", sceneNumber);
+
+ Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
+
+ if (sceneS != NULL) {
+ sceneS->read(_sceneResources.artBase, MAX_CHK_FILENAME_SIZE);
+ sceneS->read(_sceneResources.pictureBase, MAX_CHK_FILENAME_SIZE);
+ _sceneResources.hotspotCount = sceneS->readUint32LE();
+ _sceneResources.parallaxCount = sceneS->readUint32LE();
+ _sceneResources.propsCount = sceneS->readUint32LE();
+ _sceneResources.frontY = sceneS->readUint32LE();
+ _sceneResources.backY = sceneS->readUint32LE();
+ _sceneResources.frontScale = sceneS->readUint32LE();
+ _sceneResources.backScale = sceneS->readUint32LE();
+ for (i = 0; i < 16; i++)
+ _sceneResources.depthTable[i] = sceneS->readUint16LE();
+ _sceneResources.railNodeCount = sceneS->readUint32LE();
+
+ // Clear rails from previous scene
+ _vm->_rails->clearRails();
+
+ for (i = 0; i < _sceneResources.railNodeCount; i++) {
+ x = sceneS->readUint32LE();
+ y = sceneS->readUint32LE();
+ if (_vm->_rails->addRailNode(x, y, true) < 0) {
+ warning("Too many rail nodes defined for scene");
+ }
+ }
+
+ // Clear current hotspot lists
+ _sceneResources.hotspots->clear();
+ _sceneResources.parallax->clear();
+ _sceneResources.props->clear();
+
+ _sceneResources.hotspots->loadHotSpotsM4(sceneS, _sceneResources.hotspotCount);
+ _sceneResources.parallax->loadHotSpotsM4(sceneS, _sceneResources.parallaxCount);
+ _sceneResources.props->loadHotSpotsM4(sceneS, _sceneResources.propsCount);
+
+ // Note that toss() deletes the MemoryReadStream
+ _vm->res()->toss(filename);
+ }
+}
+
+void Scene::loadSceneHotSpotsMads(int sceneNumber) {
+ char filename[kM4MaxFilenameSize];
+ sprintf(filename, "rm%i.hh", sceneNumber);
+ MadsPack hotSpotData(filename, _vm);
+ Common::SeekableReadStream *hotspotStream = hotSpotData.getItemStream(0);
+
+ int hotspotCount = hotspotStream->readUint16LE();
+ delete hotspotStream;
+
+ HotSpotList *hotspotList = _sceneResources.hotspots;
+ _sceneResources.hotspotCount = hotspotCount;
+
+ hotspotStream = hotSpotData.getItemStream(1);
+
+ // Clear current hotspot lists
+ _sceneResources.hotspots->clear();
+
+ _sceneResources.hotspots->loadHotSpotsMads(hotspotStream, _sceneResources.hotspotCount);
+
+ delete hotspotStream;
+}
+
+void Scene::loadSceneCodes(int sceneNumber, int index) {
+ char filename[kM4MaxFilenameSize];
+ Common::SeekableReadStream *sceneS;
+
+ if (_vm->isM4()) {
+ sprintf(filename, "%i.cod", sceneNumber);
+ sceneS = _vm->res()->openFile(filename);
+ _codeSurface->loadCodesM4(sceneS);
+ _vm->res()->toss(filename);
+ } else if (_vm->getGameType() == GType_Phantom || _vm->getGameType() == GType_DragonSphere) {
+ sprintf(filename, "rm%i.ww%i", sceneNumber, index);
+ MadsPack walkData(filename, _vm);
+ sceneS = walkData.getItemStream(0);
+ _codeSurface->loadCodesMads(sceneS);
+ _vm->res()->toss(filename);
+ } else if (_vm->getGameType() == GType_RexNebular) {
+ // TODO
+ return;
+ }
+}
+
+void Scene::loadSceneInverseColorTable(int sceneNumber) {
+ char filename[kM4MaxFilenameSize];
+ Common::SeekableReadStream *iplS;
+
+ if (_vm->isM4()) {
+ sprintf(filename, "%i.ipl", sceneNumber);
+ iplS = _vm->res()->openFile(filename);
+ if (_inverseColorTable)
+ delete[] _inverseColorTable;
+ _inverseColorTable = new byte[iplS->size()];
+ iplS->read(_inverseColorTable, iplS->size());
+ _vm->res()->toss(filename);
+ } else {
+ // TODO?
+ return;
+ }
+
+}
+
+
+void Scene::loadSceneSprites(int sceneNumber) {
+ char filename[kM4MaxFilenameSize];
+ sprintf(filename, "%i.ssb", sceneNumber);
+
+ Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
+ _sceneSprites = new SpriteAsset(_vm, sceneS, sceneS->size(), filename);
+ _vm->res()->toss(filename);
+
+ printf("Scene has %d sprites, each one having %d colors\n", _sceneSprites->getCount(), _sceneSprites->getColorCount());
+}
+
+void Scene::loadSceneSpriteCodes(int sceneNumber) {
+ char filename[kM4MaxFilenameSize];
+ sprintf(filename, "%i.ssc", sceneNumber);
+
+ Common::SeekableReadStream *sceneS = _vm->res()->get(filename);
+
+ // TODO
+
+ if (sceneS != NULL) {
+ SpriteAsset* _sceneSpriteCodes = new SpriteAsset(_vm, sceneS, sceneS->size(), filename);
+ int colorCount = _sceneSpriteCodes->getColorCount();
+// RGB8* spritePalette = _sceneSpriteCodes->getPalette();
+ //_vm->_palette->setPalette(spritePalette, 0, colorCount);
+
+ printf("Scene has %d sprite codes, each one having %d colors\n", _sceneSpriteCodes->getCount(), colorCount);
+
+ // Note that toss() deletes the MemoryReadStream
+ _vm->res()->toss(filename);
+ }
+}
+
+void Scene::showSprites() {
+ // TODO: This is all experimental code, it needs heavy restructuring
+ // and cleanup
+
+ // taken from set_walker_scaling() in adv_walk.cpp. A proper implementation will need
+ // to store these in global variables
+ int minScaling = FixedDiv(_sceneResources.backScale << 16, 100 << 16);
+ int maxScaling = FixedDiv(_sceneResources.frontScale << 16, 100 << 16);
+ int scaler;
+
+ _vm->_actor->setWalkerDirection(kFacingSouthEast);
+ //_vm->_actor->setWalkerPalette();
+
+ // taken from set_walker_scaling() in adv_walk.cpp
+ if (_sceneResources.frontY == _sceneResources.backY)
+ scaler = 0;
+ else
+ scaler = FixedDiv(maxScaling - minScaling,
+ (_sceneResources.frontY << 16) - (_sceneResources.backY << 16));
+
+ // FIXME: For now, we (incorrectly) scale the walker to 50% of the scene's max scaling
+ _vm->_actor->setWalkerScaling(scaler / 2);
+ // Test code to display the protagonist
+ _vm->_actor->placeWalkerSpriteAt(0, 320, 200);
+
+ // Test code to display scene sprites
+ // TODO
+}
+
+void Scene::checkHotspotAtMousePos(int x, int y) {
+ if (_vm->getGameType() == GType_Riddle)
+ return;
+
+ // TODO: loads of things to do here, only the mouse cursor and the status
+ // text is changed for now
+
+ // Only scene hotspots are checked for now, not parallax/props, as the
+ // latter ones are not used by Orion Burger
+ HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
+ if (currentHotSpot != NULL && currentHotSpot->getActive()) {
+ if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
+ _vm->_mouse->getCursorNum() != CURSOR_TAKE &&
+ _vm->_mouse->getCursorNum() != CURSOR_USE &&
+ _vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
+ _vm->_mouse->setCursorNum(currentHotSpot->getCursor());
+ }
+ _vm->_interfaceView->setStatusText(currentHotSpot->getPrep());
+ } else {
+ if (_vm->_mouse->getCursorNum() != CURSOR_LOOK &&
+ _vm->_mouse->getCursorNum() != CURSOR_TAKE &&
+ _vm->_mouse->getCursorNum() != CURSOR_USE &&
+ _vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
+ _vm->_mouse->setCursorNum(0);
+ } else {
+
+ }
+ }
+}
+
+void Scene::checkHotspotAtMousePosMads(int x, int y) {
+ HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
+ if (currentHotSpot != NULL) {
+ _vm->_mouse->setCursorNum(currentHotSpot->getCursor());
+
+ // This is the "easy" interface, which updates the status text when the mouse is moved
+ // TODO: toggle this code for easy/normal interface mode
+ char statusText[50];
+ if (currentHotSpot->getVerbID() != 0) {
+ sprintf(statusText, "%s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
+ } else {
+ sprintf(statusText, "%s %s\n", _vm->_globals->getVocab(kVerbWalkTo), currentHotSpot->getVocab());
+ }
+
+ statusText[0] = toupper(statusText[0]); // capitalize first letter
+ setMADSStatusText(statusText);
+ } else {
+ _vm->_mouse->setCursorNum(0);
+ setMADSStatusText("");
+ }
+}
+
+// Test function, shows all scene hotspots
+void Scene::showHotSpots() {
+ int i = 0;
+ HotSpot *currentHotSpot;
+ // hotspots (green)
+ for (i = 0; i < _sceneResources.hotspotCount; i++) {
+ currentHotSpot = _sceneResources.hotspots->get(i);
+ _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->GREEN);
+ }
+ if (_vm->isM4()) {
+ // parallax (yellow)
+ for (i = 0; i < _sceneResources.parallaxCount; i++) {
+ currentHotSpot = _sceneResources.parallax->get(i);
+ _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->YELLOW);
+ }
+ // props (red)
+ for (i = 0; i < _sceneResources.propsCount; i++) {
+ currentHotSpot = _sceneResources.props->get(i);
+ _backgroundSurface->frameRect(currentHotSpot->getRect(), _vm->_palette->RED);
+ }
+ }
+}
+
+// Test function, shows all scene codes
+void Scene::showCodes() {
+ uint8 *pixelData = (uint8*)_codeSurface->pixels;
+ for (int i = 0; i < _codeSurface->w * _codeSurface->h; i++)
+ if (pixelData[i] & 0x10)
+ pixelData[i] = 0xFF;
+ else
+ pixelData[i] = 0;
+
+ byte colors[256 * 4];
+ memset(colors, 0, sizeof(colors));
+ colors[255 * 4 + 0] = 255;
+ colors[255 * 4 + 1] = 255;
+ colors[255 * 4 + 2] = 255;
+ _vm->_palette->setPalette(colors, 0, 256);
+
+ _backgroundSurface->copyFrom(_codeSurface, Common::Rect(0, 0, 640, 480), 0, 0);
+ //_system->copyRectToScreen((byte *)codes->pixels, codes->w, 0, 0, codes->w, codes->h);
+}
+
+void Scene::playIntro() {
+
+}
+
+void Scene::update() {
+ // TODO: Needs a proper implementation
+ // NOTE: Don't copy the background when in M4 mode or WoodScript anims won't be shown
+ if (!_vm->isM4()) {
+ _backgroundSurface->copyTo(this);
+
+ if (_statusText[0]) {
+ // Text colors are inverted in Dragonsphere
+ if (_vm->getGameType() == GType_DragonSphere)
+ _vm->_font->setColors(_vm->_palette->BLACK, _vm->_palette->WHITE, _vm->_palette->BLACK);
+ else
+ _vm->_font->setColors(_vm->_palette->WHITE, _vm->_palette->BLACK, _vm->_palette->BLACK);
+
+ _vm->_font->setFont(FONT_MAIN_MADS);
+ _vm->_font->writeString(this, _statusText, (width() - _vm->_font->getWidth(_statusText)) / 2, 142, 0);
+ }
+ }
+}
+
+void Scene::onRefresh(RectList *rects, M4Surface *destSurface) {
+ update();
+ View::onRefresh(rects, destSurface);
+}
+
+bool Scene::onEvent(M4EventType eventType, int param1, int x, int y, bool &captureEvents) {
+ //if (_vm->getGameType() != GType_Burger)
+ // return false;
+
+ // If the game is currently paused, don't do any scene processing
+ if (_vm->_kernel->paused)
+ return false;
+
+ switch (eventType) {
+ case MEVENT_LEFT_CLICK:
+ {
+ if (_vm->getGameType() == GType_Burger) {
+ // Place a Wilbur sprite with the correct facing
+ HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
+ if (currentHotSpot != NULL && currentHotSpot->getActive()) {
+ update();
+ _vm->_actor->setWalkerDirection(currentHotSpot->getFacing());
+ int posX = currentHotSpot->getFeetX();
+ int posY = currentHotSpot->getFeetY() -
+ scaleValue(_vm->_actor->getWalkerHeight(), _vm->_actor->getWalkerScaling(), 0);
+ //_vm->_actor->placeWalkerSpriteAt(0, posX, posY);
+
+ // Player said.... (for scene scripts)
+ printf("Player said: %s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
+
+ // FIXME: This should be moved somewhere else, and is incomplete
+ if (_vm->_interfaceView->_inventory.getSelectedIndex() == -1) {
+ if (_vm->_mouse->getVerb() == NULL) {
+ strcpy(_vm->_player->verb, currentHotSpot->getVerb());
+ } else {
+ strcpy(_vm->_player->verb, _vm->_mouse->getVerb());
+ }
+ } else {
+ strcpy(_vm->_player->verb, _vm->_interfaceView->_inventory.getSelectedObjectName());
+ }
+ strcpy(_vm->_player->noun, currentHotSpot->getVocab());
+ strcpy(_vm->_player->object, "");
+ _vm->_player->commandReady = true;
+
+ printf("## Player said: %s %s\n", _vm->_player->verb, _vm->_player->noun);
+
+ }
+ }
+
+ if (!_vm->isM4()) {
+ HotSpot *currentHotSpot = _sceneResources.hotspots->findByXY(x, y);
+ if (currentHotSpot != NULL) {
+ char statusText[50];
+ if (currentHotSpot->getVerbID() != 0) {
+ sprintf(statusText, "%s %s\n", currentHotSpot->getVerb(), currentHotSpot->getVocab());
+ } else {
+ sprintf(statusText, "%s %s\n", _vm->_globals->getVocab(kVerbWalkTo), currentHotSpot->getVocab());
+ }
+
+ statusText[0] = toupper(statusText[0]); // capitalize first letter
+ setMADSStatusText(statusText);
+ }
+ }
+ }
+ break;
+ case MEVENT_RIGHT_CLICK:
+ if (_vm->getGameType() == GType_Burger) {
+ nextCommonCursor();
+ _vm->_interfaceView->_inventory.clearSelected();
+ }
+ break;
+ case MEVENT_MOVE:
+ if (_vm->isM4())
+ checkHotspotAtMousePos(x, y);
+ else
+ checkHotspotAtMousePosMads(x, y);
+ break;
+ default:
+ return false;
+ }
+
+ return true;
+}
+
+void Scene::nextCommonCursor() {
+ int cursorIndex = _vm->_mouse->getCursorNum();
+
+ switch (cursorIndex) {
+ case CURSOR_ARROW:
+ cursorIndex = CURSOR_LOOK;
+ break;
+ case CURSOR_LOOK:
+ cursorIndex = CURSOR_TAKE;
+ break;
+ case CURSOR_TAKE:
+ cursorIndex = CURSOR_USE;
+ break;
+ case CURSOR_USE:
+ cursorIndex = CURSOR_ARROW;
+ break;
+ default:
+ cursorIndex = CURSOR_ARROW;
+ }
+
+ _vm->_mouse->setCursorNum(cursorIndex);
+}
+
+enum boxSprites {
+ topLeft = 0,
+ topRight = 1,
+ bottomLeft = 2,
+ bottomRight = 3,
+ left = 4,
+ right = 5,
+ top = 6,
+ bottom = 7,
+ topMiddle = 8,
+ filler1 = 9,
+ filler2 = 10
+ // TODO: finish this
+};
+
+// TODO: calculate width and height, show text, show face if it exists
+// TODO: this has been tested with Dragonsphere only, there are some differences
+// in the sprites used in Phantom
+void Scene::showMADSV2TextBox(char *text, int x, int y, char *faceName) {
+ int repeatX = 40; // FIXME: this is hardcoded
+ int repeatY = 30; // FIXME: this is hardcoded
+ int curX = x, curY = y;
+ int topRightX = x; // TODO: this is probably not needed
+ Common::SeekableReadStream *data = _vm->res()->get("box.ss");
+ SpriteAsset *boxSprites = new SpriteAsset(_vm, data, data->size(), "box.ss");
+ _vm->res()->toss("box.ss");
+
+ RGBList *palData = new RGBList(boxSprites->getColorCount(), boxSprites->getPalette(), true);
+ _vm->_palette->addRange(palData);
+
+ for (int i = 0; i < boxSprites->getCount(); i++)
+ boxSprites->getFrame(i)->translate(palData); // sprite pixel translation
+
+ // Top left corner
+ boxSprites->getFrame(topLeft)->copyTo(_backgroundSurface, x, curY);
+ curX += boxSprites->getFrame(topLeft)->width();
+
+ // Top line
+ for (int i = 0; i < repeatX; i++) {
+ boxSprites->getFrame(top)->copyTo(_backgroundSurface, curX, curY + 3);
+ curX += boxSprites->getFrame(top)->width();
+ }
+
+ // Top right corner
+ boxSprites->getFrame(topRight)->copyTo(_backgroundSurface, curX, curY);
+ topRightX = curX;
+
+ // Top middle
+ // FIXME: the transparent color for this is also the black border color
+ boxSprites->getFrame(topMiddle)->copyTo(_backgroundSurface,
+ x + (curX - x) / 2 - boxSprites->getFrame(topMiddle)->width() / 2,
+ curY - 5, 167);
+ curX = x;
+ curY += boxSprites->getFrame(topLeft)->height();
+
+ // -----------------------------------------------------------------------------------------------
+
+ // Draw contents
+ for (int i = 0; i < repeatY; i++) {
+ for (int j = 0; j < repeatX; j++) {
+ if (j == 0) {
+ boxSprites->getFrame(left)->copyTo(_backgroundSurface, curX + 3, curY);
+ curX += boxSprites->getFrame(left)->width();
+ } else if (j == repeatX - 1) {
+ curX = topRightX - 2;
+ boxSprites->getFrame(right)->copyTo(_backgroundSurface, curX + 3, curY + 1);
+ } else {
+ // TODO: the background of the contents follows a pattern which is not understood yet
+ if (j % 2 == 0) {
+ boxSprites->getFrame(filler1)->copyTo(_backgroundSurface, curX + 3, curY);
+ curX += boxSprites->getFrame(filler1)->width();
+ } else {
+ boxSprites->getFrame(filler2)->copyTo(_backgroundSurface, curX + 3, curY);
+ curX += boxSprites->getFrame(filler2)->width();
+ }
+ }
+ } // for j
+ curX = x;
+ curY += boxSprites->getFrame(left)->height();
+ } // for i
+
+ // -----------------------------------------------------------------------------------------------
+ curX = x;
+
+ // Bottom left corner
+ boxSprites->getFrame(bottomLeft)->copyTo(_backgroundSurface, curX, curY);
+ curX += boxSprites->getFrame(bottomLeft)->width();
+
+ // Bottom line
+ for (int i = 0; i < repeatX; i++) {
+ boxSprites->getFrame(bottom)->copyTo(_backgroundSurface, curX, curY + 1);
+ curX += boxSprites->getFrame(bottom)->width();
+ }
+
+ // Bottom right corner
+ boxSprites->getFrame(bottomRight)->copyTo(_backgroundSurface, curX, curY + 1);
+}
+
+} // End of namespace M4