From ae8853d80bc9e4d6a7f952a76271ad06dd9a3970 Mon Sep 17 00:00:00 2001 From: Paul Gilbert Date: Thu, 25 Mar 2010 12:46:06 +0000 Subject: Added preliminary logic for showing loaded sprite frames svn-id: r48401 --- engines/m4/mads_menus.cpp | 30 +++++++-------- engines/m4/mads_menus.h | 1 - engines/m4/mads_scene.h | 1 - engines/m4/mads_views.cpp | 96 ++++++++++++++++++++++++++++++++++++++++++----- engines/m4/mads_views.h | 43 +++++++++++++++++---- engines/m4/sprite.cpp | 4 +- engines/m4/sprite.h | 12 ++++++ 7 files changed, 148 insertions(+), 39 deletions(-) diff --git a/engines/m4/mads_menus.cpp b/engines/m4/mads_menus.cpp index 8b34d2c139..bcfeb55dd7 100644 --- a/engines/m4/mads_menus.cpp +++ b/engines/m4/mads_menus.cpp @@ -609,7 +609,7 @@ void RexDialogView::initialiseLines() { _totalTextEntries = 0; // Set up a default sprite slot entry - _spriteSlotsStart = 1; + _spriteSlots.startIndex = 1; _spriteSlots[0].spriteId = -2; _spriteSlots[0].timerIndex = -1; } @@ -637,9 +637,6 @@ RexDialogView::~RexDialogView() { _madsVm->_palette->deleteRange(_bgPalData); delete _bgPalData; delete _backgroundSurface; - _madsVm->_palette->deleteRange(_spritesPalData); - delete _spritesPalData; - delete _menuSprites; } void RexDialogView::loadBackground() { @@ -677,14 +674,7 @@ void RexDialogView::loadBackground() { void RexDialogView::loadMenuSprites() { const char *SPRITES_NAME = "*MENU.SS"; - Common::SeekableReadStream *data = _vm->res()->get(SPRITES_NAME); - _menuSprites = new SpriteAsset(_vm, data, data->size(), SPRITES_NAME); - _vm->res()->toss(SPRITES_NAME); - - // Slot it into available palette space - _spritesPalData = _menuSprites->getRgbList(); - _vm->_palette->addRange(_spritesPalData); - _menuSprites->translate(_spritesPalData, true); + _spriteSlots.addSprites(SPRITES_NAME); } @@ -708,14 +698,15 @@ void RexDialogView::onRefresh(RectList *rects, M4Surface *destSurface) { } void RexDialogView::setFrame(int frameNumber, int depth) { - int slotIndex = getSpriteSlotsIndex(); + int slotIndex = _spriteSlots.getIndex(); _spriteSlots[slotIndex].spriteId = 1; _spriteSlots[slotIndex].timerIndex = 1; _spriteSlots[slotIndex].spriteListIndex = 0; //_menuSpritesIndex; _spriteSlots[slotIndex].frameNumber = frameNumber; - M4Sprite *spr = _menuSprites->getFrame(0); - _spriteSlots[slotIndex].width = spr->width(); - _spriteSlots[slotIndex].height = spr->height(); + + M4Sprite *spr = _spriteSlots.getSprite(0).getFrame(0); + _spriteSlots[slotIndex].xp = spr->x; + _spriteSlots[slotIndex].yp = spr->y; _spriteSlots[slotIndex].depth = depth; _spriteSlots[slotIndex].scale = 100; } @@ -890,6 +881,11 @@ RexGameMenuDialog::RexGameMenuDialog(): RexDialogView() { setFrame(1, 2); initVars(); + // TODO: Replace with proper palette setting + uint32 c = 0xffffff; + for (int i = 9; i <= 15; ++i) + _vm->_palette->setPalette((const byte *)&c, i, 1); + _vm->_font->setFont(FONT_CONVERSATION_MADS); addLines(); setClickableLines(); @@ -897,7 +893,7 @@ RexGameMenuDialog::RexGameMenuDialog(): RexDialogView() { void RexGameMenuDialog::addLines() { // Add the title - int top = (height() - MADS_SURFACE_HEIGHT) / 2 + -((((_vm->_font->getHeight() + 2) * 6) >> 1) - 78); + int top = MADS_Y_OFFSET - ((((_vm->_font->getHeight() + 2) * 6) >> 1) - 78); addQuote(_vm->_font, ALIGN_CENTER, 0, top, 10); diff --git a/engines/m4/mads_menus.h b/engines/m4/mads_menus.h index d732723fcf..44e2c0d358 100644 --- a/engines/m4/mads_menus.h +++ b/engines/m4/mads_menus.h @@ -124,7 +124,6 @@ protected: M4Surface *_backgroundSurface; RGBList *_bgPalData; SpriteAsset *_menuSprites; - RGBList *_spritesPalData; Common::Array _dialogText; Common::StringArray _textLines; diff --git a/engines/m4/mads_scene.h b/engines/m4/mads_scene.h index b4cdbafd80..f8709c4bc5 100644 --- a/engines/m4/mads_scene.h +++ b/engines/m4/mads_scene.h @@ -31,7 +31,6 @@ namespace M4 { #define INTERFACE_HEIGHT 106 -#define MADS_SURFACE_HEIGHT 156 struct SpriteSlot { int16 spriteId; diff --git a/engines/m4/mads_views.cpp b/engines/m4/mads_views.cpp index 32328f8a13..66968527da 100644 --- a/engines/m4/mads_views.cpp +++ b/engines/m4/mads_views.cpp @@ -32,6 +32,8 @@ #include "m4/m4.h" #include "m4/staticres.h" +#include "common/algorithm.h" + namespace M4 { static const int INV_ANIM_FRAME_SPEED = 8; @@ -41,6 +43,86 @@ static const int SCROLLER_DELAY = 200; //-------------------------------------------------------------------------- +int MadsSpriteSlots::getIndex() { + return startIndex++; +} + +void MadsSpriteSlots::addSprites(const char *resName) { + // Get the sprite set + Common::SeekableReadStream *data = _vm->res()->get(resName); + SpriteAsset *spriteSet = new SpriteAsset(_vm, data, data->size(), resName); + spriteSet->translate(_madsVm->_palette); + + _sprites.push_back(SpriteList::value_type(spriteSet)); + _vm->res()->toss(resName); + + // Translate the sprite set to the current palette +} + +class DepthEntry { +public: + int depth; + int index; + + DepthEntry(int depthAmt, int indexVal) { depth = depthAmt; index = indexVal; } +}; + +bool sortHelper(const DepthEntry &entry1, const DepthEntry &entry2) { + return entry1.depth < entry2.depth; +} + +typedef Common::List DepthList; + +void MadsSpriteSlots::draw(View *view) { + DepthList depthList; + + // Get a list of sprite object depths for active objects + for (int i = 0; i < startIndex; ++i) { + if (_entries[i].spriteId >= 0) { + DepthEntry rec(_entries[i].depth, i); + depthList.push_back(rec); + } + } + + // Sort the list in order of the depth + Common::sort(depthList.begin(), depthList.end(), sortHelper); + + // Loop through each of the objectes + DepthList::iterator i; + for (i = depthList.begin(); i != depthList.end(); ++i) { + DepthEntry &de = *i; + MadsSpriteSlot &slot = _entries[de.index]; + assert(slot.spriteListIndex < (int)_sprites.size()); + SpriteAsset &spriteSet = *_sprites[slot.spriteListIndex].get(); + + if (slot.scale < 100) { + // Minimalised drawing + assert(slot.spriteListIndex < (int)_sprites.size()); + M4Sprite *spr = spriteSet.getFrame(slot.frameNumber - 1); + spr->draw(view, slot.scale, slot.depth, slot.xp, MADS_Y_OFFSET + slot.yp); + } else { + int xp, yp; + M4Sprite *spr = spriteSet.getFrame(slot.frameNumber - 1); + + if (slot.scale == -1) { + xp = slot.xp; // - widthAdjust; + yp = slot.yp; // - heightAdjust; + } else { + xp = slot.xp - (spr->width() / 2); // - widthAdjust; + yp = slot.yp - spr->height() + 1; // - heightAdjust; + } + + if (slot.depth > 1) { + spr->draw2(view, slot.depth, xp, MADS_Y_OFFSET + yp); + } else { + spr->draw3(view, xp, MADS_Y_OFFSET + yp); + } + } + } +} + +//-------------------------------------------------------------------------- + MadsTextDisplay::MadsTextDisplay() { for (int i = 0; i < TEXT_DISPLAY_SIZE; ++i) { MadsTextDisplayEntry rec; @@ -132,12 +214,9 @@ int ScreenObjects::scan(int xp, int yp, int layer) { } int ScreenObjects::scanBackwards(int xp, int yp, int layer) { - for (uint i = _entries.size() - 1; ; --i) { + for (int i = (int)_entries.size() - 1; i >= 0; --i) { if (_entries[i].active && _entries[i].bounds.contains(xp, yp) && (_entries[i].layer == layer)) return i + 1; - - if (i == 0) - break; } // Entry not found @@ -154,18 +233,15 @@ void ScreenObjects::setActive(int category, int idx, bool active) { //-------------------------------------------------------------------------- MadsView::MadsView(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent): View(vm, viewBounds, transparent) { - _spriteSlotsStart = 0; } MadsView::MadsView(MadsM4Engine *vm, int x, int y, bool transparent): View(vm, x, y, transparent) { - _spriteSlotsStart = 0; -} - -int MadsView::getSpriteSlotsIndex() { - return _spriteSlotsStart++; } void MadsView::onRefresh(RectList *rects, M4Surface *destSurface) { + // Draw any sprites + _spriteSlots.draw(this); + // Draw text elements onto the view _textDisplay.draw(this); diff --git a/engines/m4/mads_views.h b/engines/m4/mads_views.h index 98219e04bb..d2aba31c88 100644 --- a/engines/m4/mads_views.h +++ b/engines/m4/mads_views.h @@ -34,14 +34,19 @@ namespace M4 { +#define MADS_SURFACE_HEIGHT 156 +#define MADS_SCREEN_HEIGHT 200 +#define MADS_Y_OFFSET ((MADS_SCREEN_HEIGHT - MADS_SURFACE_HEIGHT) / 2) + + class MadsSpriteSlot { public: int spriteId; int timerIndex; int spriteListIndex; int frameNumber; - int width; - int height; + int xp; + int yp; int depth; int scale; @@ -50,6 +55,32 @@ public: #define SPRITE_SLOTS_SIZE 50 +typedef public Common::Array> SpriteList; + +class MadsSpriteSlots { +private: + MadsSpriteSlot _entries[SPRITE_SLOTS_SIZE]; + SpriteList _sprites; +public: + int startIndex; + + MadsSpriteSlots() { startIndex = 0; } + + MadsSpriteSlot &operator[](int idx) { + assert(idx < SPRITE_SLOTS_SIZE); + return _entries[idx]; + } + SpriteAsset &getSprite(int idx) { + assert(idx < (int)_sprites.size()); + return *_sprites[idx].get(); + } + + int getIndex(); + void addSprites(const char *resName); + + void draw(View *view); +}; + class MadsTextDisplayEntry { public: bool active; @@ -97,8 +128,6 @@ public: ScreenObjectEntry() { active = false; } }; -#define SCREEN_OBJECTS_SIZE - class ScreenObjects { private: Common::Array _entries; @@ -119,14 +148,12 @@ public: }; + class MadsView: public View { protected: - MadsSpriteSlot _spriteSlots[SPRITE_SLOTS_SIZE]; + MadsSpriteSlots _spriteSlots; MadsTextDisplay _textDisplay; - int _spriteSlotsStart; ScreenObjects _screenObjects; - - int getSpriteSlotsIndex(); public: MadsView(MadsM4Engine *vm, const Common::Rect &viewBounds, bool transparent = false); MadsView(MadsM4Engine *vm, int x = 0, int y = 0, bool transparent = false); diff --git a/engines/m4/sprite.cpp b/engines/m4/sprite.cpp index d8d21bc34d..0ff4bec855 100644 --- a/engines/m4/sprite.cpp +++ b/engines/m4/sprite.cpp @@ -54,8 +54,8 @@ M4Sprite::M4Sprite(Common::SeekableReadStream* source, int xOfs, int yOfs, int w loadMadsSprite(source); } - xOffset = xOfs; - yOffset = yOfs; + x = xOffset = xOfs; + y = yOffset = yOfs; } diff --git a/engines/m4/sprite.h b/engines/m4/sprite.h index 49a96a6c4a..ee985c958b 100644 --- a/engines/m4/sprite.h +++ b/engines/m4/sprite.h @@ -115,6 +115,18 @@ public: void loadDeltaRle(Common::SeekableReadStream* rleData, int destX, int destY); void loadMadsSprite(Common::SeekableReadStream* source); + void draw(M4Surface *destSurface, int scale, int depth, int xp, int yp) { + // TODO: Properly implement drawing + copyTo(destSurface, xp, yp); + } + void draw2(M4Surface *destSurface, int depth, int xp, int yp) { + // TODO: Properly implement drawing + copyTo(destSurface, xp, yp); + } + void draw3(M4Surface *destSurface, int xp, int yp) { + // TODO: Properly implement drawing + copyTo(destSurface, xp, yp); + } byte getTransparentColor() const; protected: }; -- cgit v1.2.3