scummvm/engines/griffon/cutscenes.cpp
2019-11-13 22:07:08 +01:00

558 lines
13 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 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.
*
*
* Originally written by Syn9 in FreeBASIC with SDL
* http://syn9.thehideoutgames.com/index_backup.php
*
* Ported to plain C for GCW-Zero handheld by Dmitry Smagin
* http://github.com/dmitrysmagin/griffon_legend
*
*
* Programming/Graphics: Daniel "Syn9" Kennedy
* Music/Sound effects: David Turner
*
* Beta testing and gameplay design help:
* Deleter, Cha0s, Aether Fox, and Kiz
*
*/
#include "common/system.h"
#include "griffon/griffon.h"
#include "griffon/config.h"
namespace Griffon {
const char *story[48] = {
"The Griffon Legend",
"http://syn9.thehideoutgames.com/",
"",
"Programming/Graphics: Daniel Kennedy",
"Music/Sound effects: David Turner",
"",
"Porting to GCW-Zero: Dmitry Smagin",
"",
"",
"Story",
"Ever since I was a child",
"I remember being told the",
"Legend of the Griffon Knights,",
"who rid the world of the",
"Dragon Empire. These great",
"heroes inspired us to become",
"knights as well.",
" ",
"Now, 500 years after the war",
"ended, the Dragons have",
"returned. Cities are falling",
"from the lack of knights to",
"protect them.",
" ",
"We never saw it coming.",
" ",
"And now, here I am, making",
"my way into the lower town",
"of Fidelis, a small city on",
"the main continent. The rest",
"of my men have died over",
"the last couple days from",
"aerial attacks.",
" ",
"We believed we could find",
"shelter here, only to find",
"every last griffon dead,",
"the town burned to the ground,",
"and transformed into a garrison",
"for the Dragon forces.",
" ",
"In these dark times, I try to",
"draw strength from the stories",
"of those knights that risked",
"everything to protect their homeland,",
" ",
"and hope that I can die",
"with that honor as well."
};
const char *story2[27] = {
"After the fall of Margrave Gradius,",
"All the dragons, struck with panic,",
"evacuated the city immediately.",
" ",
"It\'s funny how without a leader",
"everyone is so weak.",
" ",
" ",
"But yet another leader will rise,",
"and another city will fall.",
" ",
" ",
"I should return home to Asherton",
"It\'s time to leave this place",
"and cleanse this blood stained",
"life of mine.",
" ",
"No one should have to see as much",
"death as I have.",
" ",
" ",
"Before, I said that I wanted",
"to die an honorable death.",
" ",
"Now I say that I have lived an",
"honorable life,",
"and I am free to die as I please."
};
void GriffonEngine::showLogos() {
float y;
int _ticks1;
_ticks = g_system->getMillis();
_ticks1 = _ticks;
y = 0.0;
do {
y = 255.0;
if (_ticks < _ticks1 + 1000) {
y = 255.0 * ((float)(_ticks - _ticks1) / 1000.0);
if (y < 0.0)
y = 0.0;
if (y > 255.0)
y = 255.0;
}
if (_ticks > _ticks1 + 3000) {
y = 255.0 - 255.0 * ((float)(_ticks - _ticks1 - 3000.0) / 1000.0);
if (y < 0.0)
y = 0.0;
if (y > 255.0)
y = 255.0;
}
_videobuffer->fillRect(Common::Rect(0, 0, 320, 240), 0);
_logosimg->blit(*_videobuffer, 0, 0, Graphics::FLIP_NONE, nullptr, TS_ARGB((int)y, (int)y, (int)y, (int)y));
g_system->copyRectToScreen(_videobuffer->getPixels(), _videobuffer->pitch, 0, 0, _videobuffer->w, _videobuffer->h);
g_system->updateScreen();
g_system->getEventManager()->pollEvent(_event);
if (_event.type == Common::EVENT_QUIT)
_shouldQuit = true;
_tickspassed = _ticks;
_ticks = g_system->getMillis();
_tickspassed = _ticks - _tickspassed;
_fpsr = (float)_tickspassed / 24;
_fp++;
if (_ticks > _nextticks) {
_nextticks = _ticks + 1000;
_fps = _fp;
_fp = 0;
}
g_system->delayMillis(10);
if (_ticks > _ticks1 + 4000)
break;
} while (!_shouldQuit);
}
void GriffonEngine::intro() {
float xofs = 0;
float ld = 0, add;
int cnt = 0;
_videobuffer2->fillRect(Common::Rect(0, 0, _videobuffer2->w, _videobuffer2->h), 0);
_videobuffer3->fillRect(Common::Rect(0, 0, _videobuffer3->w, _videobuffer3->h), 0);
_ticks = g_system->getMillis();
_videobuffer->blit(*_videobuffer3);
_videobuffer->blit(*_videobuffer2);
_fpsr = 0.0;
int y = 140;
if (config.music) {
haltSoundChannel(-1);
_musicchannel = playSound(_mendofgame, true);
setChannelVolume(_musicchannel, 0);
}
_secsingame = 0;
_secstart = 0;
bool ldstop = false;
do {
Common::Rect rc;
ld += 4 * _fpsr;
if ((int)ld > config.musicvol)
ld = config.musicvol;
if (!ldstop) {
setChannelVolume(_musicchannel, (int)ld);
if ((int)ld == config.musicvol)
ldstop = true;
}
rc.left = -xofs;
rc.top = 0;
_titleimg->blit(*_videobuffer, rc.left, rc.top);
rc.left = -xofs + 320;
rc.top = 0;
_titleimg->blit(*_videobuffer, rc.left, rc.top);
if (++cnt >= 6) {
cnt = 0;
y--;
}
for (int i = 0; i <= 37; i++) {
int yy, x;
yy = y + i * 10;
if (yy > -8 && yy < 240) {
x = 160 - strlen(story[i]) * 4;
drawString(_videobuffer, story[i], x, yy, 4);
}
if (yy < 10 && i == 47)
return;
}
g_system->copyRectToScreen(_videobuffer->getPixels(), _videobuffer->pitch, 0, 0, _videobuffer->w, _videobuffer->h);
g_system->updateScreen();
_tickspassed = _ticks;
_ticks = g_system->getMillis();
_tickspassed = _ticks - _tickspassed;
_fpsr = (float)_tickspassed / 24.0;
_fp++;
if (_ticks > _nextticks) {
_nextticks = _ticks + 1000;
_fps = _fp;
_fp = 0;
}
add = 0.5 * _fpsr;
if (add > 1)
add = 1;
xofs += add;
if (xofs >= 320)
xofs = xofs - 320;
g_system->getEventManager()->pollEvent(_event);
if (_event.type == Common::EVENT_KEYDOWN)
cnt = 6;
if (_event.kbd.keycode == Common::KEYCODE_ESCAPE)
return;
if (_event.type == Common::EVENT_QUIT)
_shouldQuit = true;
g_system->delayMillis(10);
} while (!_shouldQuit);
}
void GriffonEngine::endOfGame() {
float xofs = 0;
_ticks = g_system->getMillis();
float spd = 0.2f;
if (config.music) {
haltSoundChannel(-1);
_musicchannel = playSound(_mendofgame, true);
setChannelVolume(_musicchannel, 0);
}
int _ticks1 = _ticks;
int ya = 0;
_videobuffer2->fillRect(Common::Rect(0, 0, _videobuffer2->w, _videobuffer2->h), 0);
_videobuffer3->fillRect(Common::Rect(0, 0, _videobuffer3->w, _videobuffer3->h), 0);
_videobuffer2->copyRectToSurface(_videobuffer->getPixels(), _videobuffer->pitch, 0, 0, _videobuffer->w, _videobuffer->h);
float ld = 0;
bool ldstop = false; // CHECKME: Check if actually used
do {
ld = ld + 4 * _fpsr;
if (ld > config.musicvol)
ld = config.musicvol;
if (!ldstop) {
setChannelVolume(_musicchannel, (int)ld);
if ((int)ld == config.musicvol)
ldstop = true;
}
ya = 0;
if (_ticks < _ticks1 + 1500) {
ya = (255 * (_ticks - _ticks1)) / 1500;
if (ya < 0)
ya = 0;
if (ya > 255)
ya = 255;
} else {
break;
}
_videobuffer->fillRect(Common::Rect(0, 0, _videobuffer->w, _videobuffer->h), 0);
_videobuffer->setAlpha(ya);
_videobuffer3->copyRectToSurface(_videobuffer2->getPixels(), _videobuffer2->pitch, 0, 0, _videobuffer2->w, _videobuffer2->h);
_videobuffer3->copyRectToSurface(_videobuffer->getPixels(), _videobuffer->pitch, 0, 0, _videobuffer->w, _videobuffer->h);
g_system->copyRectToScreen(_videobuffer3->getPixels(), _videobuffer3->pitch, 0, 0, _videobuffer3->w, _videobuffer3->h);
g_system->updateScreen();
g_system->getEventManager()->pollEvent(_event);
g_system->delayMillis(10);
_tickspassed = _ticks;
_ticks = g_system->getMillis();
_tickspassed = _ticks - _tickspassed;
_fpsr = (float)_tickspassed / 24;
_fp++;
if (_ticks > _nextticks) {
_nextticks = _ticks + 1000;
_fps = _fp;
_fp = 0;
}
} while (1);
_ticks1 = _ticks;
ya = 0;
float y = 140;
do {
Common::Rect rc;
rc.left = -xofs;
rc.top = 0;
_titleimg->blit(*_videobuffer, rc.left, rc.top);
rc.left = -xofs + 320;
rc.top = 0;
_titleimg->blit(*_videobuffer, rc.left, rc.top);
y = y - spd * _fpsr;
for (int i = 0; i <= 26; i++) {
int yy = y + i * 10;
if (yy > -8 && yy < 240) {
int x = 160 - strlen(story2[i]) * 4;
drawString(_videobuffer, story2[i], x, yy, 4);
}
if (yy < 10 && i == 25)
break;
}
ya = 255;
if (_ticks < _ticks1 + 1000) {
ya = 255 * (_ticks - _ticks1) / 1000;
if (ya < 0)
ya = 0;
if (ya > 255)
ya = 255;
}
_videobuffer->setAlpha(ya);
g_system->copyRectToScreen(_videobuffer->getPixels(), _videobuffer->pitch, 0, 0, _videobuffer->w, _videobuffer->h);
g_system->updateScreen();
g_system->getEventManager()->pollEvent(_event);
g_system->delayMillis(10);
_tickspassed = _ticks;
_ticks = g_system->getMillis();
_tickspassed = _ticks - _tickspassed;
_fpsr = (float)_tickspassed / 24;
_fp++;
if (_ticks > _nextticks) {
_nextticks = _ticks + 1000;
_fps = _fp;
_fp = 0;
}
float add = 0.5 * _fpsr;
if (add > 1)
add = 1;
xofs = xofs + add;
if (xofs >= 320)
xofs = xofs - 320;
if (_event.type == Common::EVENT_KEYDOWN)
spd = 1.0f;
if (_event.type == Common::EVENT_KEYUP)
spd = 0.2f;
if (_event.kbd.keycode == Common::KEYCODE_ESCAPE)
break;
} while (1);
_ticks1 = _ticks;
int y1 = 0;
_videobuffer2->copyRectToSurface(_videobuffer->getPixels(), _videobuffer->pitch, 0, 0, _videobuffer->w, _videobuffer->h);
do {
if (_ticks < _ticks1 + 1500) {
y1 = 255 * (_ticks - _ticks1) / 1500;
if (y1 < 0)
y1 = 0;
if (y1 > 255)
y1 = 255;
else
break;
}
_videobuffer->fillRect(Common::Rect(0, 0, _videobuffer->w, _videobuffer->h), 0);
_videobuffer->setAlpha(y1);
_videobuffer2->blit(*_videobuffer3);
_videobuffer->blit(*_videobuffer3);
g_system->copyRectToScreen(_videobuffer3->getPixels(), _videobuffer3->pitch, 0, 0, _videobuffer3->w, _videobuffer3->h);
g_system->updateScreen();
g_system->getEventManager()->pollEvent(_event);
g_system->delayMillis(10);
_tickspassed = _ticks;
_ticks = g_system->getMillis();
_tickspassed = _ticks - _tickspassed;
_fpsr = (float)_tickspassed / 24;
_fp++;
if (_ticks > _nextticks) {
_nextticks = _ticks + 1000;
_fps = _fp;
_fp = 0;
}
} while (1);
int keywait = 2000 + _ticks;
_ticks1 = _ticks;
y1 = 0;
do {
_videobuffer->copyRectToSurface(_theendimg->getPixels(), _theendimg->pitch, 0, 0, _theendimg->w, _theendimg->h);
y1 = 255;
if (_ticks < _ticks1 + 1000) {
y1 = 255 * (_ticks - _ticks1) / 1000;
if (y1 < 0)
y1 = 0;
if (y1 > 255)
y1 = 255;
}
_videobuffer->setAlpha(y1);
g_system->copyRectToScreen(_videobuffer->getPixels(), _videobuffer->pitch, 0, 0, _videobuffer->w, _videobuffer->h);
g_system->updateScreen();
g_system->getEventManager()->pollEvent(_event);
g_system->delayMillis(10);
_tickspassed = _ticks;
_ticks = g_system->getMillis();
_tickspassed = _ticks - _tickspassed;
_fpsr = (float)_tickspassed / 24;
_fp++;
if (_ticks > _nextticks) {
_nextticks = _ticks + 1000;
_fps = _fp;
_fp = 0;
}
g_system->getEventManager()->pollEvent(_event);
if (_event.type == Common::EVENT_KEYDOWN && keywait < _ticks)
break;
} while (1);
_videobuffer2->fillRect(Common::Rect(0, 0, _videobuffer2->w, _videobuffer2->h), 0);
_videobuffer3->fillRect(Common::Rect(0, 0, _videobuffer3->w, _videobuffer3->h), 0);
theEnd();
}
void GriffonEngine::theEnd() {
for (int i = 0; i < kMaxFloat; i++) {
_floattext[i][0] = 0;
_floaticon[i][0] = 0;
}
for (float y = 0; y < 100; y += _fpsr) {
_videobuffer->setAlpha((int)y);
_videobuffer->fillRect(Common::Rect(0, 0, _videobuffer->w, _videobuffer->h), 0);
g_system->copyRectToScreen(_videobuffer->getPixels(), _videobuffer->pitch, 0, 0, _videobuffer->w, _videobuffer->h);
g_system->updateScreen();
g_system->getEventManager()->pollEvent(_event);
g_system->delayMillis(10);
_tickspassed = _ticks;
_ticks = g_system->getMillis();
_tickspassed = _ticks - _tickspassed;
_fpsr = (float)_tickspassed / 24.0;
_fp++;
if (_ticks > _nextticks) {
_nextticks = _ticks + 1000;
_fps = _fp;
_fp = 0;
}
}
title(0);
}
} // end of namespace Griffon