scummvm/engines/illusions/duckman/duckman_credits.cpp
2021-12-26 18:48:43 +01:00

197 lines
6.6 KiB
C++

/* 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 3 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, see <http://www.gnu.org/licenses/>.
*
*/
#include "illusions/duckman/illusions_duckman.h"
#include "illusions/duckman/duckman_credits.h"
#include "illusions/actor.h"
#include "illusions/dictionary.h"
#include "illusions/resources/fontresource.h"
#include "illusions/resources/scriptresource.h"
#include "illusions/textdrawer.h"
#include "illusions/time.h"
#include "illusions/updatefunctions.h"
#include "engines/util.h"
namespace Illusions {
// Duckman_SpecialCode
DuckmanCredits::DuckmanCredits(IllusionsEngine_Duckman *vm)
: _vm(vm) {
}
DuckmanCredits::~DuckmanCredits() {
}
void DuckmanCredits::start() {
static const struct { uint32 objectId; int scrollPosY; } kCreditsItems[] = {
{0x40136, 0}, {0x40137, 16}, {0x40138, 32}, {0x40139, 48},
{0x4013A, 64}, {0x4013B, 80}, {0x4013C, 96}, {0x4013D, 112}
};
_currText = (char*)_vm->_resSys->getResource(0x190052)->_data;
_creditsItems.clear();
for (uint i = 0; i < ARRAYSIZE(kCreditsItems); ++i) {
DCreditsItem creditsItem;
creditsItem.objectId = kCreditsItems[i].objectId;
creditsItem.scrollPosY = kCreditsItems[i].scrollPosY;
creditsItem.scrollPosIndex = 0;
creditsItem.active = false;
_creditsItems.push_back(creditsItem);
}
uint32 currSceneId = _vm->getCurrentScene();
_vm->_updateFunctions->add(0, currSceneId, new Common::Functor1Mem<uint, int, DuckmanCredits>(this, &DuckmanCredits::update));
_nextUpdateTicks = getCurrentTime();
_lastUpdateTicks = _nextUpdateTicks - 4;
}
int DuckmanCredits::update(uint flags) {
if (_vm->_pauseCtr > 0) {
_nextUpdateTicks = getCurrentTime() + 4;
return 1;
}
if (flags & 1) {
_vm->_scriptResource->_properties.set(0x000E0096, true);
_lastItemIndex = -1;
_endReached = false;
return 2;
}
if (!isTimerExpired(_lastUpdateTicks, _nextUpdateTicks)) {
return 1;
}
bool creditsRunning = false;
int index = 0;
for (DCreditsItems::iterator it = _creditsItems.begin(); it != _creditsItems.end(); ++it, ++index) {
DCreditsItem &creditsItem = *it;
Control *control = _vm->getObjectControl(creditsItem.objectId);
if (!creditsItem.active && creditsItem.scrollPosY == 0 && !_endReached) {
creditsItem.active = true;
creditsItem.scrollPosIndex = 0;
control->fillActor(0);
char *text = readNextLine();
if (!strncmp(text, "&&&END", 6)) {
creditsItem.active = false;
_endReached = true;
} else {
uint16 wtext[128];
charToWChar(text, wtext, ARRAYSIZE(wtext));
FontResource *font = _vm->_dict->findFont(0x120001);
TextDrawer textDrawer;
WidthHeight dimensions;
uint16 *outText;
control->getActorFrameDimensions(dimensions);
textDrawer.wrapText(font, wtext, &dimensions, Common::Point(0, 0), 2, outText);
textDrawer.drawText(_vm->_screen, control->_actor->_surface, 0, 0);
control->_actor->_flags |= Illusions::ACTOR_FLAG_4000;
_lastItemIndex = index;
}
}
if (creditsItem.active) {
if (_endReached && _creditsItems[_lastItemIndex].scrollPosIndex > 53) {
creditsItem.active = false;
creditsItem.scrollPosY = -1;
} else {
creditsRunning = true;
control->_actor->_position = getItemPosition(creditsItem.scrollPosIndex);
++creditsItem.scrollPosIndex;
if (getItemPosition(creditsItem.scrollPosIndex).x < 0)
creditsItem.active = false;
}
}
if (creditsItem.scrollPosY > 0)
--creditsItem.scrollPosY;
}
_lastUpdateTicks = _nextUpdateTicks;
_nextUpdateTicks = getCurrentTime() + 4;
if (!creditsRunning) {
_vm->_scriptResource->_properties.set(0x000E0096, true);
_lastItemIndex = -1;
_endReached = false;
return 2;
}
return 1;
}
char *DuckmanCredits::readNextLine() {
static char line[256];
char *dest = line;
char *src = _currText;
do {
if (*src == 10 || *src == 13) {
src += 2;
*dest = 0;
break;
}
*dest++ = *src++;
} while (1);
_currText = src;
return line;
}
Common::Point DuckmanCredits::getItemPosition(int index) {
static const struct { int16 x, y; } kCreditsItemsPoints[] = {
{159, 200}, {158, 195}, {157, 190}, {156, 185}, {156, 180}, {157, 176},
{158, 172}, {159, 168}, {161, 164}, {162, 161}, {163, 158}, {163, 155},
{162, 152}, {161, 149}, {159, 147}, {158, 144}, {157, 142}, {156, 140},
{156, 138}, {157, 136}, {158, 134}, {159, 132}, {161, 130}, {162, 128},
{163, 127}, {163, 126}, {162, 125}, {161, 124}, {159, 123}, {158, 122},
{157, 121}, {156, 120}, {156, 119}, {157, 118}, {158, 117}, {159, 116},
{161, 115}, {162, 114}, {163, 113}, {163, 112}, {162, 111}, {161, 110},
{159, 109}, {158, 108}, {157, 107}, {156, 106}, {156, 105}, {157, 104},
{158, 103}, {159, 102}, {161, 101}, {162, 100}, {163, 99}, {163, 98},
{162, 97}, {161, 96}, {159, 95}, {158, 94}, {157, 93}, {156, 92},
{156, 91}, {157, 90}, {158, 89}, {159, 88}, {161, 87}, {162, 86},
{163, 85}, {163, 84}, {162, 83}, {161, 82}, {159, 81}, {158, 80},
{157, 79}, {156, 78}, {156, 77}, {157, 76}, {158, 75}, {159, 74},
{161, 73}, {162, 72}, {163, 71}, {163, 70}, {162, 69}, {161, 68},
{159, 67}, {158, 66}, {157, 64}, {156, 62}, {156, 60}, {157, 58},
{158, 56}, {159, 54}, {161, 52}, {162, 50}, {163, 40}, {163, 40},
{162, 40}, {161, 40}, {159, 40}, {158, 40}, {157, 40}, {156, 40},
{156, 40}, {157, 40}, {158, 40}, {159, 40}, {161, 40}, {162, 40},
{163, 40}, {163, 40}, {162, 40}, {161, 40}, {159, 40}, {158, 40},
{157, 40}, {156, 40}, {156, 40}, {157, 40}, {158, 40}, {159, 40},
{161, 40}, {162, 40}, {163, 40}, {163, 40}, {162, 40}, {161, 40},
{159, 40}, {158, 40}, { -1, -1}
};
if (index < 0 || index >= ARRAYSIZE(kCreditsItemsPoints))
return Common::Point(-1, -1);
return Common::Point(kCreditsItemsPoints[index].x, kCreditsItemsPoints[index].y);
}
void DuckmanCredits::charToWChar(char *text, uint16 *wtext, uint size) {
while (*text != 0 && size > 1) {
*wtext++ = (byte)*text++;
--size;
}
*wtext++ = 0;
}
} // End of namespace Illusions