274 lines
7.9 KiB
C++
274 lines
7.9 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 "got/gfx/image.h"
|
|
#include "common/memstream.h"
|
|
#include "got/events.h"
|
|
#include "got/got.h"
|
|
#include "got/utils/file.h"
|
|
#include "got/vars.h"
|
|
|
|
namespace Got {
|
|
|
|
static void createSurface(Graphics::ManagedSurface &s, const byte *src) {
|
|
s.create(16, 16);
|
|
|
|
// Both 0 and 15 are transparent colors, so as we load the
|
|
// surface, standard on a single color
|
|
byte *dest = (byte *)s.getPixels();
|
|
for (int i = 0; i < 16 * 16; ++i, ++src, ++dest)
|
|
*dest = (*src == 15) ? 0 : *src;
|
|
|
|
s.setTransparentColor(0);
|
|
}
|
|
|
|
void setupActor(Actor *actor, const char num, const char dir, const int x, const int y) {
|
|
actor->_nextFrame = 0; // Next frame to be shown
|
|
actor->_frameCount = actor->_frameSpeed;
|
|
actor->_dir = dir; // Direction of travel
|
|
actor->_lastDir = dir; // Last direction of travel
|
|
if (actor->_directions == 1)
|
|
actor->_dir = 0;
|
|
if (actor->_directions == 2)
|
|
actor->_dir &= 1;
|
|
if (actor->_directions == 4 && actor->_framesPerDirection == 1) {
|
|
actor->_dir = 0;
|
|
actor->_nextFrame = dir;
|
|
}
|
|
|
|
actor->_x = x; // Actual X coordinates
|
|
actor->_y = y; // Actual Y coordinates
|
|
actor->_width = 16; // Actual X coordinates
|
|
actor->_height = 16; // Actual Y coordinates
|
|
actor->_center = 0; // Center of object
|
|
actor->_lastX[0] = x; // Last X coordinates on each page
|
|
actor->_lastX[1] = x;
|
|
actor->_lastY[0] = y; // Last Y coordinates on each page
|
|
actor->_lastY[1] = y;
|
|
actor->_active = true; // true=active, false=not active
|
|
actor->_moveCountdown = 8; // Count down to movement
|
|
actor->_vulnerableCountdown = STAMINA; // Count down to vulnerability
|
|
actor->_shotCountdown = 20; // Count down to another shot
|
|
actor->_currNumShots = 0; // # of shots currently on screen
|
|
actor->_creator = 0; // which actor # created this actor
|
|
actor->_unpauseCountdown = 0; // Pause must be 0 to move
|
|
actor->_show = 0;
|
|
actor->_actorNum = num;
|
|
actor->_counter = 0;
|
|
actor->_moveCounter = 0;
|
|
actor->_edgeCounter = 20;
|
|
actor->_hitThor = false;
|
|
actor->_rand = g_engine->getRandomNumber(99);
|
|
actor->_temp1 = 0;
|
|
actor->_initHealth = actor->_health;
|
|
}
|
|
|
|
void make_actor_surface(Actor *actor) {
|
|
assert(actor->_directions <= 4 && actor->_framesPerDirection <= 4);
|
|
for (int d = 0; d < actor->_directions; d++) {
|
|
for (int f = 0; f < actor->_framesPerDirection; f++) {
|
|
Graphics::ManagedSurface &s = actor->pic[d][f];
|
|
const byte *src = &_G(tmpBuff[256 * ((d * 4) + f)]);
|
|
createSurface(s, src);
|
|
}
|
|
}
|
|
}
|
|
|
|
int loadStandardActors() {
|
|
loadActor(0, 100 + _G(thorInfo)._armor); // Load Thor
|
|
_G(actor[0]).loadFixed(_G(tmpBuff) + 5120);
|
|
setupActor(&_G(actor[0]), 0, 0, 100, 100);
|
|
_G(thor) = &_G(actor[0]);
|
|
|
|
make_actor_surface(&_G(actor[0]));
|
|
|
|
_G(thorX1) = _G(thor)->_x + 2;
|
|
_G(thorY1) = _G(thor)->_y + 2;
|
|
_G(thorX2) = _G(thor)->_x + 14;
|
|
_G(thorY2) = _G(thor)->_y + 14;
|
|
|
|
loadActor(0, 103 + _G(thorInfo)._armor); // Load hammer
|
|
_G(actor[1]).loadFixed(_G(tmpBuff) + 5120);
|
|
setupActor(&_G(actor[1]), 1, 0, 100, 100);
|
|
_G(actor[1])._active = false;
|
|
_G(hammer) = &_G(actor[1]);
|
|
|
|
make_actor_surface(&_G(actor[1]));
|
|
|
|
// Load sparkle
|
|
loadActor(0, 106);
|
|
_G(sparkle).loadFixed(_G(tmpBuff) + 5120);
|
|
setupActor(&_G(sparkle), 20, 0, 100, 100);
|
|
_G(sparkle)._active = false;
|
|
make_actor_surface(&_G(sparkle));
|
|
|
|
// Load explosion
|
|
loadActor(0, 107);
|
|
_G(explosion).loadFixed(_G(tmpBuff) + 5120);
|
|
setupActor(&_G(explosion), 21, 0, 100, 100);
|
|
_G(explosion)._active = false;
|
|
make_actor_surface(&_G(explosion));
|
|
|
|
// Load tornado
|
|
loadActor(0, 108);
|
|
_G(magicItem[0]).loadFixed((const byte *)_G(tmpBuff) + 5120);
|
|
Common::copy(_G(tmpBuff), _G(tmpBuff) + 1024, _G(magicPic[0]));
|
|
|
|
setupActor(&_G(magicItem[0]), 20, 0, 0, 0);
|
|
_G(magicItem[0])._active = false;
|
|
|
|
// Load shield
|
|
loadActor(0, 109);
|
|
_G(magicItem[1]).loadFixed((const byte *)_G(tmpBuff) + 5120);
|
|
Common::copy(_G(tmpBuff), _G(tmpBuff) + 1024, _G(magicPic[1]));
|
|
|
|
setupActor(&_G(magicItem[1]), 20, 0, 0, 0);
|
|
_G(magicItem[1])._active = false;
|
|
|
|
_G(actor[2])._active = false;
|
|
|
|
make_actor_surface(&_G(magicItem[0]));
|
|
|
|
return 1;
|
|
}
|
|
|
|
void showEnemies() {
|
|
for (int i = 3; i < MAX_ACTORS; i++)
|
|
_G(actor[i])._active = false;
|
|
|
|
for (int i = 0; i < MAX_ENEMIES; i++)
|
|
_G(enemyType[i]) = 0;
|
|
|
|
for (int i = 0; i < MAX_ENEMIES; i++) {
|
|
if (_G(scrn)._actorType[i] > 0) {
|
|
const int id = loadEnemy(_G(scrn)._actorType[i]);
|
|
if (id >= 0) {
|
|
_G(actor[i + 3]) = _G(enemy[id]);
|
|
|
|
const int d = _G(scrn)._actorDir[i];
|
|
|
|
setupActor(&_G(actor[i + 3]), i + 3, d, (_G(scrn)._actorLoc[i] % 20) * 16,
|
|
(_G(scrn)._actorLoc[i] / 20) * 16);
|
|
_G(actor[i + 3])._initDir = _G(scrn)._actorDir[i];
|
|
_G(actor[i + 3])._passValue = _G(scrn)._actorValue[i];
|
|
|
|
if (_G(actor[i + 3])._moveType == 23) {
|
|
// Spinball
|
|
if (_G(actor[i + 3])._passValue & 1)
|
|
_G(actor[i + 3])._moveType = 24;
|
|
}
|
|
|
|
if (_G(scrn)._actorInvis[i])
|
|
_G(actor[i + 3])._active = false;
|
|
}
|
|
|
|
_G(etype[i]) = id;
|
|
}
|
|
}
|
|
}
|
|
|
|
int loadEnemy(const int type) {
|
|
for (int i = 0; i < MAX_ENEMIES; i++) {
|
|
if (_G(enemyType[i]) == type)
|
|
return i;
|
|
}
|
|
|
|
if (!loadActor(1, type)) {
|
|
return -1;
|
|
}
|
|
|
|
int e = -1;
|
|
for (int i = 0; i < MAX_ENEMIES; i++) {
|
|
if (!_G(enemyType[i])) {
|
|
e = i;
|
|
break;
|
|
}
|
|
}
|
|
if (e == -1)
|
|
return -1;
|
|
|
|
Common::MemoryReadStream inf(_G(tmpBuff) + 5120, 40);
|
|
_G(enemy[e]).loadFixed(&inf);
|
|
|
|
make_actor_surface(&_G(enemy[e]));
|
|
_G(enemyType[e]) = type;
|
|
_G(enemy[e])._shotType = 0;
|
|
|
|
if (_G(enemy[e])._numShotsAllowed) {
|
|
_G(enemy[e])._shotType = e + 1;
|
|
|
|
// Set up shot info
|
|
_G(shot[e]).loadFixed(_G(tmpBuff) + 5160);
|
|
|
|
// Loop to set up graphics
|
|
for (int d = 0; d < _G(shot[e])._directions; d++) {
|
|
for (int f = 0; f < _G(shot[e])._framesPerDirection; f++) {
|
|
if (_G(shot[e])._directions < _G(shot[e])._framesPerDirection) {
|
|
Graphics::ManagedSurface &s = _G(shot[e]).pic[d][f];
|
|
const byte *src = &_G(tmpBuff[4096 + (256 * ((d * 4) + f))]);
|
|
createSurface(s, src);
|
|
} else {
|
|
Graphics::ManagedSurface &s = _G(shot[e]).pic[f][d];
|
|
const byte *src = &_G(tmpBuff[4096 + (256 * ((f * 4) + d))]);
|
|
createSurface(s, src);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return e;
|
|
}
|
|
|
|
int actorVisible(const int invisNum) {
|
|
for (int i = 0; i < MAX_ENEMIES; i++) {
|
|
if (_G(scrn)._actorInvis[i] == invisNum) {
|
|
const int etype = _G(etype[i]);
|
|
if (etype >= 0 && !_G(actor[i + 3])._active) {
|
|
_G(actor[i + 3]) = _G(enemy[etype]);
|
|
|
|
int d = _G(scrn)._actorDir[i];
|
|
setupActor(&_G(actor[i + 3]), i + 3, d, (_G(scrn)._actorLoc[i] % 20) * 16,
|
|
(_G(scrn)._actorLoc[i] / 20) * 16);
|
|
_G(actor[i + 3])._initDir = _G(scrn)._actorDir[i];
|
|
_G(actor[i + 3])._passValue = _G(scrn)._actorValue[i];
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
void setupMagicItem(const int item) {
|
|
for (int i = 0; i < 4; i++) {
|
|
createSurface(_G(magicItem[item]).pic[i / 4][i % 4], &_G(magicPic[item][256 * i]));
|
|
}
|
|
}
|
|
|
|
void loadNewThor() {
|
|
loadActor(0, 100 + _G(thorInfo)._armor); // Load Thor
|
|
|
|
make_actor_surface(&_G(actor[0]));
|
|
}
|
|
|
|
} // namespace Got
|