MADS: Transformed ImageInterEntries to be User Interface UISlots
This commit is contained in:
parent
d57d4b876e
commit
0c8a3a47e2
16 changed files with 383 additions and 330 deletions
|
@ -403,7 +403,7 @@ void Animation::update() {
|
||||||
|
|
||||||
for (uint idx = 0; idx < scene._spriteSlots.size(); ++idx) {
|
for (uint idx = 0; idx < scene._spriteSlots.size(); ++idx) {
|
||||||
if (scene._spriteSlots[idx]._seqIndex >= 0x80)
|
if (scene._spriteSlots[idx]._seqIndex >= 0x80)
|
||||||
scene._spriteSlots[idx]._spriteType = ST_EXPIRED;
|
scene._spriteSlots[idx]._SlotType = ST_EXPIRED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the current frame
|
// Validate the current frame
|
||||||
|
@ -445,7 +445,7 @@ void Animation::update() {
|
||||||
if (paChanged) {
|
if (paChanged) {
|
||||||
newIndex = scene._spriteSlots.add();
|
newIndex = scene._spriteSlots.add();
|
||||||
scene._spriteSlots[newIndex]._seqIndex = -1;
|
scene._spriteSlots[newIndex]._seqIndex = -1;
|
||||||
scene._spriteSlots[newIndex]._spriteType = ST_FULL_SCREEN_REFRESH;
|
scene._spriteSlots[newIndex]._SlotType = ST_FULL_SCREEN_REFRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main frame animation loop - frames get animated by being placed, as necessary, into the
|
// Main frame animation loop - frames get animated by being placed, as necessary, into the
|
||||||
|
@ -463,7 +463,7 @@ void Animation::update() {
|
||||||
int seqIndex = _frameEntries[_oldFrameEntry]._seqIndex - scene._spriteSlots[index]._seqIndex;
|
int seqIndex = _frameEntries[_oldFrameEntry]._seqIndex - scene._spriteSlots[index]._seqIndex;
|
||||||
if (seqIndex == 0x80) {
|
if (seqIndex == 0x80) {
|
||||||
if (scene._spriteSlots[index] == _frameEntries[_oldFrameEntry]._spriteSlot) {
|
if (scene._spriteSlots[index] == _frameEntries[_oldFrameEntry]._spriteSlot) {
|
||||||
scene._spriteSlots[index]._spriteType = ST_NONE;
|
scene._spriteSlots[index]._SlotType = ST_NONE;
|
||||||
spriteSlotIndex = -1;
|
spriteSlotIndex = -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -479,7 +479,7 @@ void Animation::update() {
|
||||||
|
|
||||||
SpriteAsset &spriteSet = *scene._sprites[
|
SpriteAsset &spriteSet = *scene._sprites[
|
||||||
scene._spriteSlots[slotIndex]._spritesIndex];
|
scene._spriteSlots[slotIndex]._spritesIndex];
|
||||||
slot._spriteType = spriteSet.isBackground() ? ST_BACKGROUND : ST_FOREGROUND;
|
slot._SlotType = spriteSet.isBackground() ? ST_BACKGROUND : ST_FOREGROUND;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -235,7 +235,12 @@ void Game::sectionLoop() {
|
||||||
_player._priorTimer = _scene._frameStartTime + _player._ticksAmount;
|
_player._priorTimer = _scene._frameStartTime + _player._ticksAmount;
|
||||||
_player.idle();
|
_player.idle();
|
||||||
|
|
||||||
warning("TODO: _selectedObject IF block");
|
if (_scene._userInterface._selectedInvIndex >= 0) {
|
||||||
|
_scene._userInterface.loadInventoryAnim(
|
||||||
|
_objects._inventoryList[_scene._userInterface._selectedInvIndex]);
|
||||||
|
} else {
|
||||||
|
_scene._userInterface.noInventoryAnim();
|
||||||
|
}
|
||||||
|
|
||||||
_v1 = 5;
|
_v1 = 5;
|
||||||
_scene._roomChanged = false;
|
_scene._roomChanged = false;
|
||||||
|
|
|
@ -197,7 +197,7 @@ void Scene201::enter() {
|
||||||
_scene->_sequences.addSubEntry(_globals._spriteIndexes[21], SM_FRAME_INDEX, 12, 70);
|
_scene->_sequences.addSubEntry(_globals._spriteIndexes[21], SM_FRAME_INDEX, 12, 70);
|
||||||
_scene->_sequences.setDepth(_globals._spriteIndexes[21], 1);
|
_scene->_sequences.setDepth(_globals._spriteIndexes[21], 1);
|
||||||
_globals._frameTime = 0;
|
_globals._frameTime = 0;
|
||||||
_game._player.sub7E53C(Common::Point(157, 143), 8);
|
_game._player.startWalking(Common::Point(157, 143), 8);
|
||||||
_vm->_palette->setEntry(252, 45, 63, 45);
|
_vm->_palette->setEntry(252, 45, 63, 45);
|
||||||
_vm->_palette->setEntry(253, 20, 45, 20);
|
_vm->_palette->setEntry(253, 20, 45, 20);
|
||||||
_scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 2, 0, 120, _game.getQuote(90));
|
_scene->_kernelMessages.add(Common::Point(0, 0), 0x1110, 2, 0, 120, _game.getQuote(90));
|
||||||
|
|
|
@ -246,7 +246,7 @@ void Player::update() {
|
||||||
if (_forceRefresh || (_visible != _priorVisible)) {
|
if (_forceRefresh || (_visible != _priorVisible)) {
|
||||||
int slotIndex = getSpriteSlot();
|
int slotIndex = getSpriteSlot();
|
||||||
if (slotIndex >= 0)
|
if (slotIndex >= 0)
|
||||||
scene._spriteSlots[slotIndex]._spriteType = ST_EXPIRED;
|
scene._spriteSlots[slotIndex]._SlotType = ST_EXPIRED;
|
||||||
|
|
||||||
int newDepth = 1;
|
int newDepth = 1;
|
||||||
int yp = MAX(_playerPos.y, (int16)(MADS_SCENE_HEIGHT - 1));
|
int yp = MAX(_playerPos.y, (int16)(MADS_SCENE_HEIGHT - 1));
|
||||||
|
@ -264,7 +264,7 @@ void Player::update() {
|
||||||
if (_visible) {
|
if (_visible) {
|
||||||
// Player sprite needs to be rendered
|
// Player sprite needs to be rendered
|
||||||
SpriteSlot slot;
|
SpriteSlot slot;
|
||||||
slot._spriteType = ST_FOREGROUND;
|
slot._SlotType = ST_FOREGROUND;
|
||||||
slot._seqIndex = PLAYER_SEQ_INDEX;
|
slot._seqIndex = PLAYER_SEQ_INDEX;
|
||||||
slot._spritesIndex = _spritesStart + _spritesIdx;
|
slot._spritesIndex = _spritesStart + _spritesIdx;
|
||||||
slot._frameNumber = _frameOffset + _frameNum;
|
slot._frameNumber = _frameOffset + _frameNum;
|
||||||
|
@ -285,7 +285,7 @@ void Player::update() {
|
||||||
|
|
||||||
if (equal)
|
if (equal)
|
||||||
// Undo the prior expiry of the player sprite
|
// Undo the prior expiry of the player sprite
|
||||||
s2._spriteType = ST_NONE;
|
s2._SlotType = ST_NONE;
|
||||||
else
|
else
|
||||||
slotIndex = -1;
|
slotIndex = -1;
|
||||||
}
|
}
|
||||||
|
@ -359,6 +359,16 @@ void Player::setDest(const Common::Point &pt, int facing) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::startWalking(const Common::Point &pos, int direction) {
|
||||||
|
Scene &scene = _vm->_game->_scene;
|
||||||
|
|
||||||
|
reset();
|
||||||
|
scene._action._startWalkFlag = true;
|
||||||
|
scene._action._walkFlag = true;
|
||||||
|
scene._destPos = pos;
|
||||||
|
scene._destFacing = direction;
|
||||||
|
}
|
||||||
|
|
||||||
void Player::nextFrame() {
|
void Player::nextFrame() {
|
||||||
Scene &scene = _vm->_game->_scene;
|
Scene &scene = _vm->_game->_scene;
|
||||||
|
|
||||||
|
@ -528,7 +538,7 @@ int Player::getSpriteSlot() {
|
||||||
|
|
||||||
for (uint idx = 0; idx < spriteSlots.size(); ++idx) {
|
for (uint idx = 0; idx < spriteSlots.size(); ++idx) {
|
||||||
if (spriteSlots[idx]._seqIndex == PLAYER_SEQ_INDEX &&
|
if (spriteSlots[idx]._seqIndex == PLAYER_SEQ_INDEX &&
|
||||||
spriteSlots[idx]._spriteType >= ST_NONE)
|
spriteSlots[idx]._SlotType >= ST_NONE)
|
||||||
return idx;
|
return idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,13 +747,4 @@ void Player::startMovement() {
|
||||||
_v8452E = -_v84530;
|
_v8452E = -_v84530;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Player::sub7E53C(Common::Point pos, int direction) {
|
|
||||||
Scene &scene = _vm->_game->_scene;
|
|
||||||
|
|
||||||
reset();
|
|
||||||
scene._action._startWalkFlag = true;
|
|
||||||
scene._action._walkFlag = true;
|
|
||||||
scene._destPos = pos;
|
|
||||||
scene._destFacing = direction;
|
|
||||||
}
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -152,9 +152,9 @@ public:
|
||||||
|
|
||||||
void setDest(const Common::Point &pt, int facing);
|
void setDest(const Common::Point &pt, int facing);
|
||||||
|
|
||||||
void nextFrame();
|
void startWalking(const Common::Point &pos, int direction);
|
||||||
|
|
||||||
void sub7E53C(Common::Point pos, int direction);
|
void nextFrame();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -379,7 +379,7 @@ void Scene::doFrame() {
|
||||||
_kernelMessages.update();
|
_kernelMessages.update();
|
||||||
}
|
}
|
||||||
|
|
||||||
_imageInterEntries.call(_vm->_game->_abortTimers2 == kTransitionFadeIn ? 0xff : 0,
|
_userInterface._uiSlots.call(_vm->_game->_abortTimers2 == kTransitionFadeIn ? 0xff : 0,
|
||||||
_vm->_game->_abortTimers2);
|
_vm->_game->_abortTimers2);
|
||||||
|
|
||||||
// Write any text needed by the interface
|
// Write any text needed by the interface
|
||||||
|
|
|
@ -90,7 +90,6 @@ public:
|
||||||
int _textSpacing;
|
int _textSpacing;
|
||||||
Hotspots _hotspots;
|
Hotspots _hotspots;
|
||||||
ScreenObjects _screenObjects;
|
ScreenObjects _screenObjects;
|
||||||
ImageInterEntries _imageInterEntries;
|
|
||||||
DirtyAreas _dirtyAreas;
|
DirtyAreas _dirtyAreas;
|
||||||
int _v1;
|
int _v1;
|
||||||
SceneInfo *_sceneInfo;
|
SceneInfo *_sceneInfo;
|
||||||
|
|
|
@ -136,173 +136,11 @@ void ScreenObjects::proc1() {
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
MADSEngine *DirtyArea::_vm = nullptr;
|
void SceneNode::load(Common::SeekableReadStream *f) {
|
||||||
|
_walkPos.x = f->readSint16LE();
|
||||||
DirtyArea::DirtyArea() {
|
_walkPos.y = f->readSint16LE();
|
||||||
_active = false;
|
for (int i = 0; i < MAX_ROUTE_NODES; ++i)
|
||||||
_textActive = false;
|
_indexes[i] = f->readUint16LE();
|
||||||
}
|
|
||||||
|
|
||||||
void DirtyArea::setArea(int width, int height, int maxWidth, int maxHeight) {
|
|
||||||
if (_bounds.left % 2) {
|
|
||||||
--_bounds.left;
|
|
||||||
++width;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (_bounds.left < 0)
|
|
||||||
_bounds.left = 0;
|
|
||||||
else if (_bounds.left > maxWidth)
|
|
||||||
_bounds.left = maxWidth;
|
|
||||||
int right = _bounds.left + width;
|
|
||||||
if (right < 0)
|
|
||||||
right = 0;
|
|
||||||
if (right > maxWidth)
|
|
||||||
right = maxWidth;
|
|
||||||
|
|
||||||
_bounds.right = right;
|
|
||||||
_bounds2.left = _bounds.width() / 2;
|
|
||||||
_bounds2.right = _bounds.left + (_bounds.width() + 1) / 2 - 1;
|
|
||||||
|
|
||||||
if (_bounds.top < 0)
|
|
||||||
_bounds.top = 0;
|
|
||||||
else if (_bounds.top > maxHeight)
|
|
||||||
_bounds.top = maxHeight;
|
|
||||||
int bottom = _bounds.top + height;
|
|
||||||
if (bottom < 0)
|
|
||||||
bottom = 0;
|
|
||||||
if (bottom > maxHeight)
|
|
||||||
bottom = maxHeight;
|
|
||||||
|
|
||||||
_bounds.bottom = bottom;
|
|
||||||
_bounds2.top = _bounds.height() / 2;
|
|
||||||
_bounds2.bottom = _bounds.top + (_bounds.height() + 1) / 2 - 1;
|
|
||||||
|
|
||||||
_active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void DirtyArea::setSpriteSlot(const SpriteSlot *spriteSlot) {
|
|
||||||
int width, height;
|
|
||||||
Scene &scene = _vm->_game->_scene;
|
|
||||||
|
|
||||||
if (spriteSlot->_spriteType == ST_FULL_SCREEN_REFRESH) {
|
|
||||||
// Special entry to refresh the entire screen
|
|
||||||
_bounds.left = 0;
|
|
||||||
_bounds.top = 0;
|
|
||||||
width = MADS_SCREEN_WIDTH;
|
|
||||||
height = MADS_SCENE_HEIGHT;
|
|
||||||
} else {
|
|
||||||
// Standard sprite slots
|
|
||||||
_bounds.left = spriteSlot->_position.x - scene._posAdjust.x;
|
|
||||||
_bounds.top = spriteSlot->_position.y - scene._posAdjust.y;
|
|
||||||
|
|
||||||
SpriteAsset &spriteSet = *scene._sprites[spriteSlot->_spritesIndex];
|
|
||||||
MSprite *frame = spriteSet.getFrame(((spriteSlot->_frameNumber & 0x7fff) - 1) & 0x7f);
|
|
||||||
|
|
||||||
if (spriteSlot->_scale == -1) {
|
|
||||||
width = frame->w;
|
|
||||||
height = frame->h;
|
|
||||||
} else {
|
|
||||||
width = frame->w * spriteSlot->_scale / 100;
|
|
||||||
height = frame->h * spriteSlot->_scale / 100;
|
|
||||||
|
|
||||||
_bounds.left -= width / 2;
|
|
||||||
_bounds.top += -(height - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setArea(width, height, MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirtyArea::setTextDisplay(const TextDisplay *textDisplay) {
|
|
||||||
_bounds.left = textDisplay->_bounds.left;
|
|
||||||
_bounds.top = textDisplay->_bounds.top;
|
|
||||||
|
|
||||||
setArea(textDisplay->_bounds.width(), textDisplay->_bounds.height(),
|
|
||||||
MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
DirtyAreas::DirtyAreas(MADSEngine *vm) : _vm(vm) {
|
|
||||||
DirtyArea::_vm = vm;
|
|
||||||
|
|
||||||
for (int i = 0; i < DIRTY_AREAS_SIZE; ++i) {
|
|
||||||
DirtyArea rec;
|
|
||||||
rec._active = false;
|
|
||||||
push_back(rec);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirtyAreas::merge(int startIndex, int count) {
|
|
||||||
if (startIndex >= count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for (int outerCtr = startIndex - 1, idx = 0; idx < count; ++outerCtr, ++idx) {
|
|
||||||
if (!(*this)[outerCtr]._active)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (int innerCtr = outerCtr + 1; innerCtr < count; ++innerCtr) {
|
|
||||||
if (!(*this)[innerCtr]._active || !intersects(outerCtr, innerCtr))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if ((*this)[outerCtr]._textActive && (*this)[innerCtr]._textActive)
|
|
||||||
mergeAreas(outerCtr, innerCtr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if two dirty areas intersect
|
|
||||||
*/
|
|
||||||
bool DirtyAreas::intersects(int idx1, int idx2) {
|
|
||||||
return (*this)[idx1]._bounds2.intersects((*this)[idx2]._bounds2);
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirtyAreas::mergeAreas(int idx1, int idx2) {
|
|
||||||
DirtyArea &da1 = (*this)[idx1];
|
|
||||||
DirtyArea &da2 = (*this)[idx2];
|
|
||||||
|
|
||||||
da1._bounds.extend(da2._bounds);
|
|
||||||
|
|
||||||
da1._bounds2.left = da1._bounds.width() / 2;
|
|
||||||
da1._bounds2.right = da1._bounds.left + (da1._bounds.width() + 1) / 2 - 1;
|
|
||||||
da1._bounds2.top = da1._bounds.height() / 2;
|
|
||||||
da1._bounds2.bottom = da1._bounds.top + (da1._bounds.height() + 1) / 2 - 1;
|
|
||||||
|
|
||||||
da2._active = false;
|
|
||||||
da1._textActive = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust) {
|
|
||||||
for (uint i = 0; i < size(); ++i) {
|
|
||||||
const Common::Rect &srcBounds = (*this)[i]._bounds;
|
|
||||||
|
|
||||||
Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
|
|
||||||
srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
|
|
||||||
|
|
||||||
if ((*this)[i]._active && bounds.isValidRect()) {
|
|
||||||
srcSurface->copyTo(destSurface, bounds, Common::Point(bounds.left, bounds.top));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirtyAreas::copyToScreen(const Common::Point &posAdjust) {
|
|
||||||
for (uint i = 0; i < size(); ++i) {
|
|
||||||
const Common::Rect &srcBounds = (*this)[i]._bounds;
|
|
||||||
|
|
||||||
Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
|
|
||||||
srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
|
|
||||||
|
|
||||||
if ((*this)[i]._active && (*this)[i]._bounds.isValidRect()) {
|
|
||||||
_vm->_screen.copyRectToScreen(bounds);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void DirtyAreas::reset() {
|
|
||||||
for (uint i = 0; i < size(); ++i)
|
|
||||||
(*this)[i]._active = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
|
@ -108,61 +108,6 @@ public:
|
||||||
void check(bool scanFlag);
|
void check(bool scanFlag);
|
||||||
};
|
};
|
||||||
|
|
||||||
class DirtyArea {
|
|
||||||
private:
|
|
||||||
static MADSEngine *_vm;
|
|
||||||
friend class DirtyAreas;
|
|
||||||
public:
|
|
||||||
Common::Rect _bounds;
|
|
||||||
Common::Rect _bounds2;
|
|
||||||
bool _textActive;
|
|
||||||
bool _active;
|
|
||||||
|
|
||||||
DirtyArea();
|
|
||||||
|
|
||||||
void setArea(int width, int height, int maxWidth, int maxHeight);
|
|
||||||
|
|
||||||
void setSpriteSlot(const SpriteSlot *spriteSlot);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Set up a dirty area for a text display
|
|
||||||
*/
|
|
||||||
void setTextDisplay(const TextDisplay *textDisplay);
|
|
||||||
};
|
|
||||||
|
|
||||||
class DirtyAreas: public Common::Array<DirtyArea> {
|
|
||||||
private:
|
|
||||||
MADSEngine *_vm;
|
|
||||||
public:
|
|
||||||
DirtyAreas(MADSEngine *vm);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Merge together any designated dirty areas that overlap
|
|
||||||
* @param startIndex 1-based starting dirty area starting index
|
|
||||||
* @param count Number of entries to process
|
|
||||||
*/
|
|
||||||
void merge(int startIndex, int count);
|
|
||||||
|
|
||||||
bool intersects(int idx1, int idx2);
|
|
||||||
void mergeAreas(int idx1, int idx2);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Copy the data specified by the dirty rect list between surfaces
|
|
||||||
* @param srcSurface Source surface
|
|
||||||
* @param destSurface Dest surface
|
|
||||||
* @param posAdjust Position adjustment
|
|
||||||
*/
|
|
||||||
void copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use the lsit of dirty areas to copy areas of the screen surface to
|
|
||||||
* the physical screen
|
|
||||||
* @param posAdjust Position adjustment */
|
|
||||||
void copyToScreen(const Common::Point &posAdjust);
|
|
||||||
|
|
||||||
void reset();
|
|
||||||
};
|
|
||||||
|
|
||||||
class SceneLogic {
|
class SceneLogic {
|
||||||
protected:
|
protected:
|
||||||
MADSEngine *_vm;
|
MADSEngine *_vm;
|
||||||
|
|
|
@ -28,6 +28,179 @@
|
||||||
|
|
||||||
namespace MADS {
|
namespace MADS {
|
||||||
|
|
||||||
|
MADSEngine *DirtyArea::_vm = nullptr;
|
||||||
|
|
||||||
|
DirtyArea::DirtyArea() {
|
||||||
|
_active = false;
|
||||||
|
_textActive = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtyArea::setArea(int width, int height, int maxWidth, int maxHeight) {
|
||||||
|
if (_bounds.left % 2) {
|
||||||
|
--_bounds.left;
|
||||||
|
++width;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_bounds.left < 0)
|
||||||
|
_bounds.left = 0;
|
||||||
|
else if (_bounds.left > maxWidth)
|
||||||
|
_bounds.left = maxWidth;
|
||||||
|
int right = _bounds.left + width;
|
||||||
|
if (right < 0)
|
||||||
|
right = 0;
|
||||||
|
if (right > maxWidth)
|
||||||
|
right = maxWidth;
|
||||||
|
|
||||||
|
_bounds.right = right;
|
||||||
|
_bounds2.left = _bounds.width() / 2;
|
||||||
|
_bounds2.right = _bounds.left + (_bounds.width() + 1) / 2 - 1;
|
||||||
|
|
||||||
|
if (_bounds.top < 0)
|
||||||
|
_bounds.top = 0;
|
||||||
|
else if (_bounds.top > maxHeight)
|
||||||
|
_bounds.top = maxHeight;
|
||||||
|
int bottom = _bounds.top + height;
|
||||||
|
if (bottom < 0)
|
||||||
|
bottom = 0;
|
||||||
|
if (bottom > maxHeight)
|
||||||
|
bottom = maxHeight;
|
||||||
|
|
||||||
|
_bounds.bottom = bottom;
|
||||||
|
_bounds2.top = _bounds.height() / 2;
|
||||||
|
_bounds2.bottom = _bounds.top + (_bounds.height() + 1) / 2 - 1;
|
||||||
|
|
||||||
|
_active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void DirtyArea::setSpriteSlot(const SpriteSlot *spriteSlot) {
|
||||||
|
int width, height;
|
||||||
|
Scene &scene = _vm->_game->_scene;
|
||||||
|
|
||||||
|
if (spriteSlot->_SlotType == ST_FULL_SCREEN_REFRESH) {
|
||||||
|
// Special entry to refresh the entire screen
|
||||||
|
_bounds.left = 0;
|
||||||
|
_bounds.top = 0;
|
||||||
|
width = MADS_SCREEN_WIDTH;
|
||||||
|
height = MADS_SCENE_HEIGHT;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Standard sprite slots
|
||||||
|
_bounds.left = spriteSlot->_position.x - scene._posAdjust.x;
|
||||||
|
_bounds.top = spriteSlot->_position.y - scene._posAdjust.y;
|
||||||
|
|
||||||
|
SpriteAsset &spriteSet = *scene._sprites[spriteSlot->_spritesIndex];
|
||||||
|
MSprite *frame = spriteSet.getFrame(((spriteSlot->_frameNumber & 0x7fff) - 1) & 0x7f);
|
||||||
|
|
||||||
|
if (spriteSlot->_scale == -1) {
|
||||||
|
width = frame->w;
|
||||||
|
height = frame->h;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
width = frame->w * spriteSlot->_scale / 100;
|
||||||
|
height = frame->h * spriteSlot->_scale / 100;
|
||||||
|
|
||||||
|
_bounds.left -= width / 2;
|
||||||
|
_bounds.top += -(height - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setArea(width, height, MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtyArea::setTextDisplay(const TextDisplay *textDisplay) {
|
||||||
|
_bounds.left = textDisplay->_bounds.left;
|
||||||
|
_bounds.top = textDisplay->_bounds.top;
|
||||||
|
|
||||||
|
setArea(textDisplay->_bounds.width(), textDisplay->_bounds.height(),
|
||||||
|
MADS_SCREEN_WIDTH, MADS_SCENE_HEIGHT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
DirtyAreas::DirtyAreas(MADSEngine *vm) : _vm(vm) {
|
||||||
|
DirtyArea::_vm = vm;
|
||||||
|
|
||||||
|
for (int i = 0; i < DIRTY_AREAS_SIZE; ++i) {
|
||||||
|
DirtyArea rec;
|
||||||
|
rec._active = false;
|
||||||
|
push_back(rec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtyAreas::merge(int startIndex, int count) {
|
||||||
|
if (startIndex >= count)
|
||||||
|
return;
|
||||||
|
|
||||||
|
for (int outerCtr = startIndex - 1, idx = 0; idx < count; ++outerCtr, ++idx) {
|
||||||
|
if (!(*this)[outerCtr]._active)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (int innerCtr = outerCtr + 1; innerCtr < count; ++innerCtr) {
|
||||||
|
if (!(*this)[innerCtr]._active || !intersects(outerCtr, innerCtr))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((*this)[outerCtr]._textActive && (*this)[innerCtr]._textActive)
|
||||||
|
mergeAreas(outerCtr, innerCtr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns true if two dirty areas intersect
|
||||||
|
*/
|
||||||
|
bool DirtyAreas::intersects(int idx1, int idx2) {
|
||||||
|
return (*this)[idx1]._bounds2.intersects((*this)[idx2]._bounds2);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtyAreas::mergeAreas(int idx1, int idx2) {
|
||||||
|
DirtyArea &da1 = (*this)[idx1];
|
||||||
|
DirtyArea &da2 = (*this)[idx2];
|
||||||
|
|
||||||
|
da1._bounds.extend(da2._bounds);
|
||||||
|
|
||||||
|
da1._bounds2.left = da1._bounds.width() / 2;
|
||||||
|
da1._bounds2.right = da1._bounds.left + (da1._bounds.width() + 1) / 2 - 1;
|
||||||
|
da1._bounds2.top = da1._bounds.height() / 2;
|
||||||
|
da1._bounds2.bottom = da1._bounds.top + (da1._bounds.height() + 1) / 2 - 1;
|
||||||
|
|
||||||
|
da2._active = false;
|
||||||
|
da1._textActive = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtyAreas::copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust) {
|
||||||
|
for (uint i = 0; i < size(); ++i) {
|
||||||
|
const Common::Rect &srcBounds = (*this)[i]._bounds;
|
||||||
|
|
||||||
|
Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
|
||||||
|
srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
|
||||||
|
|
||||||
|
if ((*this)[i]._active && bounds.isValidRect()) {
|
||||||
|
srcSurface->copyTo(destSurface, bounds, Common::Point(bounds.left, bounds.top));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtyAreas::copyToScreen(const Common::Point &posAdjust) {
|
||||||
|
for (uint i = 0; i < size(); ++i) {
|
||||||
|
const Common::Rect &srcBounds = (*this)[i]._bounds;
|
||||||
|
|
||||||
|
Common::Rect bounds(srcBounds.left + posAdjust.x, srcBounds.top + posAdjust.y,
|
||||||
|
srcBounds.right + posAdjust.x, srcBounds.bottom + posAdjust.y);
|
||||||
|
|
||||||
|
if ((*this)[i]._active && (*this)[i]._bounds.isValidRect()) {
|
||||||
|
_vm->_screen.copyRectToScreen(bounds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DirtyAreas::reset() {
|
||||||
|
for (uint i = 0; i < size(); ++i)
|
||||||
|
(*this)[i]._active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
ScreenSurface::ScreenSurface() {
|
ScreenSurface::ScreenSurface() {
|
||||||
_dataP = nullptr;
|
_dataP = nullptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,6 +45,64 @@ enum ScreenTransition {
|
||||||
kVertTransition7, kCenterVertTransition
|
kVertTransition7, kCenterVertTransition
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class SpriteSlot;
|
||||||
|
class TextDisplay;
|
||||||
|
|
||||||
|
class DirtyArea {
|
||||||
|
private:
|
||||||
|
static MADSEngine *_vm;
|
||||||
|
friend class DirtyAreas;
|
||||||
|
public:
|
||||||
|
Common::Rect _bounds;
|
||||||
|
Common::Rect _bounds2;
|
||||||
|
bool _textActive;
|
||||||
|
bool _active;
|
||||||
|
|
||||||
|
DirtyArea();
|
||||||
|
|
||||||
|
void setArea(int width, int height, int maxWidth, int maxHeight);
|
||||||
|
|
||||||
|
void setSpriteSlot(const SpriteSlot *spriteSlot);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set up a dirty area for a text display
|
||||||
|
*/
|
||||||
|
void setTextDisplay(const TextDisplay *textDisplay);
|
||||||
|
};
|
||||||
|
|
||||||
|
class DirtyAreas : public Common::Array<DirtyArea> {
|
||||||
|
private:
|
||||||
|
MADSEngine *_vm;
|
||||||
|
public:
|
||||||
|
DirtyAreas(MADSEngine *vm);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Merge together any designated dirty areas that overlap
|
||||||
|
* @param startIndex 1-based starting dirty area starting index
|
||||||
|
* @param count Number of entries to process
|
||||||
|
*/
|
||||||
|
void merge(int startIndex, int count);
|
||||||
|
|
||||||
|
bool intersects(int idx1, int idx2);
|
||||||
|
void mergeAreas(int idx1, int idx2);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copy the data specified by the dirty rect list between surfaces
|
||||||
|
* @param srcSurface Source surface
|
||||||
|
* @param destSurface Dest surface
|
||||||
|
* @param posAdjust Position adjustment
|
||||||
|
*/
|
||||||
|
void copy(MSurface *srcSurface, MSurface *destSurface, const Common::Point &posAdjust);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use the lsit of dirty areas to copy areas of the screen surface to
|
||||||
|
* the physical screen
|
||||||
|
* @param posAdjust Position adjustment */
|
||||||
|
void copyToScreen(const Common::Point &posAdjust);
|
||||||
|
|
||||||
|
void reset();
|
||||||
|
};
|
||||||
|
|
||||||
class ScreenSurface : public MSurface {
|
class ScreenSurface : public MSurface {
|
||||||
private:
|
private:
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -178,7 +178,7 @@ void SequenceList::setSpriteSlot(int seqIndex, SpriteSlot &spriteSlot) {
|
||||||
SequenceEntry &timerEntry = _entries[seqIndex];
|
SequenceEntry &timerEntry = _entries[seqIndex];
|
||||||
SpriteAsset &spriteSet = *scene._sprites[timerEntry._spritesIndex];
|
SpriteAsset &spriteSet = *scene._sprites[timerEntry._spritesIndex];
|
||||||
|
|
||||||
spriteSlot._spriteType = spriteSet.isBackground() ? ST_BACKGROUND : ST_FOREGROUND;
|
spriteSlot._SlotType = spriteSet.isBackground() ? ST_BACKGROUND : ST_FOREGROUND;
|
||||||
spriteSlot._seqIndex = seqIndex;
|
spriteSlot._seqIndex = seqIndex;
|
||||||
spriteSlot._spritesIndex = timerEntry._spritesIndex;
|
spriteSlot._spritesIndex = timerEntry._spritesIndex;
|
||||||
spriteSlot._frameNumber = (timerEntry._flipped ? 0x8000 : 0) | timerEntry._frameIndex;
|
spriteSlot._frameNumber = (timerEntry._flipped ? 0x8000 : 0) | timerEntry._frameIndex;
|
||||||
|
|
|
@ -139,7 +139,7 @@ byte MSprite::getTransparencyIndex() const {
|
||||||
MADSEngine *SpriteSlot::_vm = nullptr;
|
MADSEngine *SpriteSlot::_vm = nullptr;
|
||||||
|
|
||||||
SpriteSlot::SpriteSlot() {
|
SpriteSlot::SpriteSlot() {
|
||||||
_spriteType = ST_NONE;
|
_SlotType = ST_NONE;
|
||||||
_seqIndex = 0;
|
_seqIndex = 0;
|
||||||
_spritesIndex = 0;
|
_spritesIndex = 0;
|
||||||
_frameNumber = 0;
|
_frameNumber = 0;
|
||||||
|
@ -147,8 +147,8 @@ SpriteSlot::SpriteSlot() {
|
||||||
_scale = 0;
|
_scale = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
SpriteSlot::SpriteSlot(SpriteType type, int seqIndex) {
|
SpriteSlot::SpriteSlot(SlotType type, int seqIndex) {
|
||||||
_spriteType = type;
|
_SlotType = type;
|
||||||
_seqIndex = seqIndex;
|
_seqIndex = seqIndex;
|
||||||
_spritesIndex = 0;
|
_spritesIndex = 0;
|
||||||
_frameNumber = 0;
|
_frameNumber = 0;
|
||||||
|
@ -208,11 +208,11 @@ void SpriteSlots::setDirtyAreas() {
|
||||||
Scene &scene = _vm->_game->_scene;
|
Scene &scene = _vm->_game->_scene;
|
||||||
|
|
||||||
for (uint i = 0; i < size(); ++i) {
|
for (uint i = 0; i < size(); ++i) {
|
||||||
if ((*this)[i]._spriteType >= ST_NONE) {
|
if ((*this)[i]._SlotType >= ST_NONE) {
|
||||||
scene._dirtyAreas[i].setSpriteSlot(&(*this)[i]);
|
scene._dirtyAreas[i].setSpriteSlot(&(*this)[i]);
|
||||||
|
|
||||||
scene._dirtyAreas[i]._textActive = ((*this)[i]._spriteType <= ST_NONE) ? 0 : 1;
|
scene._dirtyAreas[i]._textActive = ((*this)[i]._SlotType <= ST_NONE) ? 0 : 1;
|
||||||
(*this)[i]._spriteType = ST_NONE;
|
(*this)[i]._SlotType = ST_NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,14 +247,14 @@ void SpriteSlots::drawBackground() {
|
||||||
SpriteSlot &spriteSlot = (*this)[i];
|
SpriteSlot &spriteSlot = (*this)[i];
|
||||||
DirtyArea &dirtyArea = scene._dirtyAreas[i];
|
DirtyArea &dirtyArea = scene._dirtyAreas[i];
|
||||||
|
|
||||||
if (spriteSlot._spriteType >= ST_NONE) {
|
if (spriteSlot._SlotType >= ST_NONE) {
|
||||||
// Foreground sprite, so we can ignore it
|
// Foreground sprite, so we can ignore it
|
||||||
dirtyArea._active = false;
|
dirtyArea._active = false;
|
||||||
} else {
|
} else {
|
||||||
dirtyArea._active = true;
|
dirtyArea._active = true;
|
||||||
dirtyArea.setSpriteSlot(&spriteSlot);
|
dirtyArea.setSpriteSlot(&spriteSlot);
|
||||||
|
|
||||||
if (spriteSlot._spriteType == ST_BACKGROUND) {
|
if (spriteSlot._SlotType == ST_BACKGROUND) {
|
||||||
// Background object, so need to draw it
|
// Background object, so need to draw it
|
||||||
assert(spriteSlot._frameNumber > 0);
|
assert(spriteSlot._frameNumber > 0);
|
||||||
SpriteAsset *asset = scene._sprites[spriteSlot._spritesIndex];
|
SpriteAsset *asset = scene._sprites[spriteSlot._spritesIndex];
|
||||||
|
@ -304,7 +304,7 @@ void SpriteSlots::drawForeground(MSurface *s) {
|
||||||
// Get a list of sprite object depths for active objects
|
// Get a list of sprite object depths for active objects
|
||||||
for (uint i = 0; i < size(); ++i) {
|
for (uint i = 0; i < size(); ++i) {
|
||||||
SpriteSlot &spriteSlot = (*this)[i];
|
SpriteSlot &spriteSlot = (*this)[i];
|
||||||
if (spriteSlot._spriteType >= ST_NONE) {
|
if (spriteSlot._SlotType >= ST_NONE) {
|
||||||
DepthEntry rec(16 - spriteSlot._depth, i);
|
DepthEntry rec(16 - spriteSlot._depth, i);
|
||||||
depthList.push_back(rec);
|
depthList.push_back(rec);
|
||||||
}
|
}
|
||||||
|
@ -367,7 +367,7 @@ void SpriteSlots::drawForeground(MSurface *s) {
|
||||||
|
|
||||||
void SpriteSlots::cleanUp() {
|
void SpriteSlots::cleanUp() {
|
||||||
for (int i = (int)size() - 1; i >= 0; --i) {
|
for (int i = (int)size() - 1; i >= 0; --i) {
|
||||||
if ((*this)[i]._spriteType < ST_NONE)
|
if ((*this)[i]._SlotType < ST_NONE)
|
||||||
remove_at(i);
|
remove_at(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -391,6 +391,7 @@ int SpriteSets::add(SpriteAsset *asset, int idx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int SpriteSets::addSprites(const Common::String &resName, int flags) {
|
int SpriteSets::addSprites(const Common::String &resName, int flags) {
|
||||||
|
++_assetCount;
|
||||||
return add(new SpriteAsset(_vm, resName, flags));
|
return add(new SpriteAsset(_vm, resName, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,52 +399,17 @@ void SpriteSets::clear() {
|
||||||
for (uint i = 0; i < size(); ++i)
|
for (uint i = 0; i < size(); ++i)
|
||||||
delete (*this)[i];
|
delete (*this)[i];
|
||||||
|
|
||||||
|
_assetCount = 0;
|
||||||
Common::Array<SpriteAsset *>::clear();
|
Common::Array<SpriteAsset *>::clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
void SpriteSets::remove(int idx) {
|
||||||
|
if (idx >= 0) {
|
||||||
|
delete (*this)[idx];
|
||||||
|
(*this)[idx] = nullptr;
|
||||||
|
|
||||||
ImageInterEntry::ImageInterEntry() {
|
--_assetCount;
|
||||||
_field0 = 0;
|
}
|
||||||
_field2 = 0;
|
|
||||||
_field3 = 0;
|
|
||||||
_field4 = 0;
|
|
||||||
_field6 = 0;
|
|
||||||
_field8 = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
void ImageInterEntries::add(int v1, int v2) {
|
|
||||||
ImageInterEntry ie;
|
|
||||||
ie._field0 = -2;
|
|
||||||
ie._field2 = -1;
|
|
||||||
|
|
||||||
push_back(ie);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImageInterEntries::add(int v1, int v2, int v3, int v4) {
|
|
||||||
assert(size() < 50);
|
|
||||||
|
|
||||||
ImageInterEntry ie;
|
|
||||||
ie._field0 = -3;
|
|
||||||
ie._field2 = 201;
|
|
||||||
ie._field6 = v1;
|
|
||||||
ie._field8 = v2;
|
|
||||||
ie._field4 = v3;
|
|
||||||
ie._field3 = v4;
|
|
||||||
|
|
||||||
push_back(ie);
|
|
||||||
}
|
|
||||||
|
|
||||||
ImageInterEntry &ImageInterEntries::add() {
|
|
||||||
resize(size() + 1);
|
|
||||||
return (*this)[size() - 1];
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void ImageInterEntries::call(int v1, int v2) {
|
|
||||||
debug("TODO: ImageInterEntries::call");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -30,7 +30,7 @@
|
||||||
|
|
||||||
namespace MADS {
|
namespace MADS {
|
||||||
|
|
||||||
enum SpriteType {
|
enum SlotType {
|
||||||
ST_NONE = 0, ST_FOREGROUND = 1, ST_BACKGROUND = -4,
|
ST_NONE = 0, ST_FOREGROUND = 1, ST_BACKGROUND = -4,
|
||||||
ST_FULL_SCREEN_REFRESH = -2, ST_EXPIRED = -1
|
ST_FULL_SCREEN_REFRESH = -2, ST_EXPIRED = -1
|
||||||
};
|
};
|
||||||
|
@ -129,11 +129,11 @@ private:
|
||||||
static MADSEngine *_vm;
|
static MADSEngine *_vm;
|
||||||
friend class SpriteSlots;
|
friend class SpriteSlots;
|
||||||
public:
|
public:
|
||||||
SpriteType _spriteType;
|
SlotType _SlotType;
|
||||||
int _seqIndex;
|
int _seqIndex;
|
||||||
public:
|
public:
|
||||||
SpriteSlot();
|
SpriteSlot();
|
||||||
SpriteSlot(SpriteType type, int seqIndex);
|
SpriteSlot(SlotType type, int seqIndex);
|
||||||
|
|
||||||
void setup(int dirtyAreaIndex);
|
void setup(int dirtyAreaIndex);
|
||||||
bool operator==(const SpriteSlotSubset &other) const;
|
bool operator==(const SpriteSlotSubset &other) const;
|
||||||
|
@ -200,10 +200,12 @@ class SpriteSets : public Common::Array<SpriteAsset *> {
|
||||||
private:
|
private:
|
||||||
MADSEngine *_vm;
|
MADSEngine *_vm;
|
||||||
public:
|
public:
|
||||||
|
int _assetCount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
SpriteSets(MADSEngine *vm) : _vm(vm) {}
|
SpriteSets(MADSEngine *vm) : _vm(vm), _assetCount(0) {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destructor
|
* Destructor
|
||||||
|
@ -224,27 +226,11 @@ public:
|
||||||
* Adds a sprite asset to the list by name
|
* Adds a sprite asset to the list by name
|
||||||
*/
|
*/
|
||||||
int addSprites(const Common::String &resName, int flags = 0);
|
int addSprites(const Common::String &resName, int flags = 0);
|
||||||
};
|
|
||||||
|
|
||||||
class ImageInterEntry {
|
/**
|
||||||
public:
|
* Remove an asset from the list
|
||||||
int _field0;
|
*/
|
||||||
int _field2;
|
void remove(int idx);
|
||||||
int _field3;
|
|
||||||
int _field4;
|
|
||||||
int _field6;
|
|
||||||
int _field8;
|
|
||||||
|
|
||||||
ImageInterEntry();
|
|
||||||
};
|
|
||||||
|
|
||||||
class ImageInterEntries: public Common::Array<ImageInterEntry> {
|
|
||||||
public:
|
|
||||||
void add(int v1, int v2);
|
|
||||||
void add(int v1, int v2, int v3, int v4);
|
|
||||||
ImageInterEntry &add();
|
|
||||||
|
|
||||||
void call(int v1, int v2);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -27,16 +27,47 @@
|
||||||
|
|
||||||
namespace MADS {
|
namespace MADS {
|
||||||
|
|
||||||
void SceneNode::load(Common::SeekableReadStream *f) {
|
UISlot::UISlot() {
|
||||||
_walkPos.x = f->readSint16LE();
|
_slotType = ST_NONE;
|
||||||
_walkPos.y = f->readSint16LE();
|
_field2 = 0;
|
||||||
for (int i = 0; i < MAX_ROUTE_NODES; ++i)
|
_field3 = 0;
|
||||||
_indexes[i] = f->readUint16LE();
|
_field4 = 0;
|
||||||
|
_field6 = 0;
|
||||||
|
_field8 = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
void UISlots::fullRefresh() {
|
||||||
|
UISlot slot;
|
||||||
|
slot._slotType = ST_FULL_SCREEN_REFRESH;
|
||||||
|
slot._field2 = -1;
|
||||||
|
|
||||||
|
push_back(slot);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UISlots::add(int v1, int v2, int v3, int v4) {
|
||||||
|
assert(size() < 50);
|
||||||
|
|
||||||
|
UISlot ie;
|
||||||
|
ie._slotType = -3;
|
||||||
|
ie._field2 = 201;
|
||||||
|
ie._field6 = v1;
|
||||||
|
ie._field8 = v2;
|
||||||
|
ie._field4 = v3;
|
||||||
|
ie._field3 = v4;
|
||||||
|
|
||||||
|
push_back(ie);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UISlots::call(int v1, int v2) {
|
||||||
|
debug("TODO: UISlots::call");
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------*/
|
||||||
|
|
||||||
UserInterface::UserInterface(MADSEngine *vm) : _vm(vm) {
|
UserInterface::UserInterface(MADSEngine *vm) : _vm(vm) {
|
||||||
|
_invSpritesIndex = -1;
|
||||||
_category = CAT_NONE;
|
_category = CAT_NONE;
|
||||||
_screenObjectsCount = 0;
|
_screenObjectsCount = 0;
|
||||||
_inventoryTopIndex = 0;
|
_inventoryTopIndex = 0;
|
||||||
|
@ -99,8 +130,8 @@ void UserInterface::setup(int id) {
|
||||||
}
|
}
|
||||||
scene._screenObjects._v832EC = id;
|
scene._screenObjects._v832EC = id;
|
||||||
|
|
||||||
scene._imageInterEntries.clear();
|
scene._userInterface._uiSlots.clear();
|
||||||
scene._imageInterEntries.add(-2, 0xff);
|
scene._userInterface._uiSlots.fullRefresh();
|
||||||
_vm->_game->_ticksExpiry = _vm->_events->getFrameCounter();
|
_vm->_game->_ticksExpiry = _vm->_events->getFrameCounter();
|
||||||
_v1A = -1;
|
_v1A = -1;
|
||||||
_v1E = -1;
|
_v1E = -1;
|
||||||
|
@ -110,7 +141,7 @@ void UserInterface::setup(int id) {
|
||||||
copyTo(&_surface);
|
copyTo(&_surface);
|
||||||
|
|
||||||
if (_vm->_game->_v1 == 5)
|
if (_vm->_game->_v1 == 5)
|
||||||
scene._imageInterEntries.call(0, 0);
|
scene._userInterface._uiSlots.call(0, 0);
|
||||||
|
|
||||||
scene._action.clear();
|
scene._action.clear();
|
||||||
drawTextElements();
|
drawTextElements();
|
||||||
|
@ -400,5 +431,27 @@ void UserInterface::drawTalkList() {
|
||||||
warning("TODO: drawTalkList");
|
warning("TODO: drawTalkList");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UserInterface::loadInventoryAnim(int objectId) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInterface::noInventoryAnim() {
|
||||||
|
Scene &scene = _vm->_game->_scene;
|
||||||
|
|
||||||
|
if (_invSpritesIndex >= 0) {
|
||||||
|
scene._sprites.remove(_invSpritesIndex);
|
||||||
|
_vm->_game->_ticksExpiry = _vm->_events->getFrameCounter();
|
||||||
|
_invSpritesIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!scene._screenObjects._v832EC)
|
||||||
|
refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void UserInterface::refresh() {
|
||||||
|
Scene &scene = _vm->_game->_scene;
|
||||||
|
scene._userInterface._uiSlots.clear();
|
||||||
|
// scene._userInterface._uiSlots.new()
|
||||||
|
}
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
|
@ -36,9 +36,31 @@ enum ScrCategory {
|
||||||
CAT_12 = 12
|
CAT_12 = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class UISlot {
|
||||||
|
public:
|
||||||
|
int _slotType;
|
||||||
|
int _field2;
|
||||||
|
int _field3;
|
||||||
|
int _field4;
|
||||||
|
int _field6;
|
||||||
|
int _field8;
|
||||||
|
|
||||||
|
UISlot();
|
||||||
|
};
|
||||||
|
|
||||||
|
class UISlots : public Common::Array<UISlot> {
|
||||||
|
public:
|
||||||
|
void add(int v1, int v2, int v3, int v4);
|
||||||
|
void fullRefresh();
|
||||||
|
|
||||||
|
void call(int v1, int v2);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class UserInterface : public MSurface {
|
class UserInterface : public MSurface {
|
||||||
private:
|
private:
|
||||||
MADSEngine *_vm;
|
MADSEngine *_vm;
|
||||||
|
int _invSpritesIndex;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the elements of the user interface
|
* Loads the elements of the user interface
|
||||||
|
@ -84,6 +106,8 @@ private:
|
||||||
* Draw a UI textual element
|
* Draw a UI textual element
|
||||||
*/
|
*/
|
||||||
void writeVocab(ScrCategory category, int id);
|
void writeVocab(ScrCategory category, int id);
|
||||||
|
|
||||||
|
void refresh();
|
||||||
public:
|
public:
|
||||||
ScrCategory _category;
|
ScrCategory _category;
|
||||||
int _screenObjectsCount;
|
int _screenObjectsCount;
|
||||||
|
@ -99,6 +123,7 @@ public:
|
||||||
int _v1A;
|
int _v1A;
|
||||||
int _v1C;
|
int _v1C;
|
||||||
int _v1E;
|
int _v1E;
|
||||||
|
UISlots _uiSlots;
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
|
@ -120,6 +145,10 @@ public:
|
||||||
void drawTextElements();
|
void drawTextElements();
|
||||||
|
|
||||||
void setBounds(const Common::Rect &r);
|
void setBounds(const Common::Rect &r);
|
||||||
|
|
||||||
|
void loadInventoryAnim(int objectId);
|
||||||
|
|
||||||
|
void noInventoryAnim();
|
||||||
};
|
};
|
||||||
|
|
||||||
} // End of namespace MADS
|
} // End of namespace MADS
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue