Initial commit
This commit is contained in:
2
engines/griffon/POTFILES
Normal file
2
engines/griffon/POTFILES
Normal file
@@ -0,0 +1,2 @@
|
||||
engines/griffon/griffon.cpp
|
||||
engines/griffon/metaengine.cpp
|
||||
1032
engines/griffon/combat.cpp
Normal file
1032
engines/griffon/combat.cpp
Normal file
File diff suppressed because it is too large
Load Diff
3
engines/griffon/configure.engine
Normal file
3
engines/griffon/configure.engine
Normal file
@@ -0,0 +1,3 @@
|
||||
# This file is included from the main "configure" script
|
||||
# add_engine [name] [desc] [build-by-default] [subengines] [base games] [deps] [components]
|
||||
add_engine griffon "The Griffon Legend" yes "" "" "16bit"
|
||||
66
engines/griffon/console.cpp
Normal file
66
engines/griffon/console.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
/* 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 "gui/debugger.h"
|
||||
|
||||
#include "griffon/console.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
Console::Console() {
|
||||
_godMode = kGodModeNone;
|
||||
registerCmd("godmode", WRAP_METHOD(Console, Cmd_godMode));
|
||||
registerCmd("nodamage", WRAP_METHOD(Console, Cmd_noDamage));
|
||||
}
|
||||
|
||||
bool Console::Cmd_godMode(int argc, const char** argv) {
|
||||
if (argc != 1) {
|
||||
debugPrintf("Usage: %s\n", argv[0]);
|
||||
debugPrintf("Enables/Disables invincibility and megadamage\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_godMode != kGodModeNone)
|
||||
_godMode = kGodModeNone;
|
||||
else
|
||||
_godMode = kGodModeAll;
|
||||
|
||||
debugPrintf("God mode is now %s\n", _godMode == kGodModeAll ? "Invincibility/Damage" : "Disabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Console::Cmd_noDamage(int argc, const char** argv) {
|
||||
if (argc != 1) {
|
||||
debugPrintf("Usage: %s\n", argv[0]);
|
||||
debugPrintf("Enables/Disables invincibility\n");
|
||||
return true;
|
||||
}
|
||||
|
||||
if (_godMode != kGodModeNone)
|
||||
_godMode = kGodModeNone;
|
||||
else
|
||||
_godMode = kGodModeNoDamage;
|
||||
|
||||
debugPrintf("God mode is now %s\n", _godMode ? "Invincibility" : "Disabled");
|
||||
return true;
|
||||
}
|
||||
|
||||
} // End of namespace Griffon
|
||||
47
engines/griffon/console.h
Normal file
47
engines/griffon/console.h
Normal file
@@ -0,0 +1,47 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRIFFON_CONSOLE_H
|
||||
#define GRIFFON_CONSOLE_H
|
||||
|
||||
#include "gui/debugger.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
enum {
|
||||
kGodModeNone = 0,
|
||||
kGodModeAll = 1,
|
||||
kGodModeNoDamage = 2
|
||||
};
|
||||
|
||||
class Console : public GUI::Debugger {
|
||||
public:
|
||||
int _godMode;
|
||||
|
||||
explicit Console();
|
||||
~Console(void) override {}
|
||||
|
||||
bool Cmd_godMode(int argc, const char** argv);
|
||||
bool Cmd_noDamage(int argc, const char** argv);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
3
engines/griffon/credits.pl
Normal file
3
engines/griffon/credits.pl
Normal file
@@ -0,0 +1,3 @@
|
||||
begin_section("Griffon");
|
||||
add_person("Eugene Sandulenko", "sev", "");
|
||||
end_section();
|
||||
601
engines/griffon/cutscenes.cpp
Normal file
601
engines/griffon/cutscenes.cpp
Normal file
@@ -0,0 +1,601 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*
|
||||
* 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 "common/config-manager.h"
|
||||
#include "common/text-to-speech.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
#define POLL_AND_CHECK_QUIT() if (g_system->getEventManager()->pollEvent(_event)) { \
|
||||
if (_event.type == Common::EVENT_QUIT || _event.type == Common::EVENT_RETURN_TO_LAUNCHER) { \
|
||||
_shouldQuit = true; \
|
||||
return; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define CHECK_QUIT() if (_event.type == Common::EVENT_QUIT || _event.type == Common::EVENT_RETURN_TO_LAUNCHER) { \
|
||||
_shouldQuit = true; \
|
||||
return; \
|
||||
}
|
||||
|
||||
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."
|
||||
};
|
||||
|
||||
int textToSpeech(int nextparagraph, const char *storyVariable[], int arraysize) {
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled") && storyVariable[nextparagraph][0] != 0) {
|
||||
Common::String paragraph;
|
||||
while (nextparagraph < arraysize && storyVariable[nextparagraph][0] != ' ') {
|
||||
if (!paragraph.empty())
|
||||
paragraph += " ";
|
||||
paragraph += storyVariable[nextparagraph++];
|
||||
}
|
||||
while (nextparagraph < arraysize && storyVariable[nextparagraph][0] == ' ') {
|
||||
nextparagraph += 1;
|
||||
}
|
||||
ttsMan->say(paragraph, Common::TextToSpeechManager::QUEUE_NO_REPEAT);
|
||||
}
|
||||
return nextparagraph;
|
||||
}
|
||||
|
||||
void GriffonEngine::showLogos() {
|
||||
_ticks = g_system->getMillis();
|
||||
int ticks1 = _ticks;
|
||||
|
||||
do {
|
||||
float y = 255.0;
|
||||
if (_ticks < ticks1 + 1000) {
|
||||
y = 255.0 * ((float)(_ticks - ticks1) / 1000.0);
|
||||
y = CLIP<float>(y, 0.0, 255.0);
|
||||
}
|
||||
|
||||
if (_ticks > ticks1 + 3000) {
|
||||
y = 255.0 - 255.0 * ((float)(_ticks - ticks1 - 3000.0) / 1000.0);
|
||||
y = CLIP<float>(y, 0.0, 255.0);
|
||||
}
|
||||
|
||||
_videoBuffer->fillRect(Common::Rect(0, 0, 320, 240), 0);
|
||||
_logosImg->blendBlitTo(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, nullptr, MS_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();
|
||||
|
||||
if (g_system->getEventManager()->pollEvent(_event)) {
|
||||
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START && _event.customType == kGriffonMenu)
|
||||
return;
|
||||
|
||||
CHECK_QUIT();
|
||||
}
|
||||
|
||||
_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() {
|
||||
_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->blendBlitTo(*_videoBuffer3);
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer2);
|
||||
|
||||
_fpsr = 0.0;
|
||||
int y = 140;
|
||||
|
||||
if (config.music) {
|
||||
haltSoundChannel(-1);
|
||||
_musicChannel = playSound(_musicEndOfGame, true);
|
||||
setChannelVolume(_musicChannel, 0);
|
||||
}
|
||||
|
||||
_secsInGame = 0;
|
||||
_secStart = 0;
|
||||
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
|
||||
bool ldStop = false;
|
||||
bool speedUp = false;
|
||||
int cnt = 0;
|
||||
float xofs = 0.0;
|
||||
float ld = 0.0;
|
||||
int nextparagraph = 0;
|
||||
|
||||
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->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
rc.left = -xofs + 320;
|
||||
rc.top = 0;
|
||||
|
||||
_titleImg->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
if (++cnt >= 6) {
|
||||
cnt = 0;
|
||||
y--;
|
||||
}
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(story); i++) {
|
||||
int yy = y + i * 10;
|
||||
|
||||
if (i == nextparagraph)
|
||||
nextparagraph = textToSpeech(nextparagraph, story, ARRAYSIZE(story));
|
||||
|
||||
if (yy > -8 && yy < 240) {
|
||||
int x = 160 - strlen(story[i]) * 4;
|
||||
drawString(_videoBuffer, story[i], x, yy, 4);
|
||||
}
|
||||
|
||||
if (yy < 10 && i == ARRAYSIZE(story) - 1) {
|
||||
if (ttsMan == nullptr || ttsMan->isSpeaking() == false)
|
||||
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;
|
||||
}
|
||||
|
||||
float add = 0.5 * _fpsr;
|
||||
if (add > 1)
|
||||
add = 1;
|
||||
xofs += add;
|
||||
if (xofs >= 320)
|
||||
xofs -= 320;
|
||||
|
||||
if (g_system->getEventManager()->pollEvent(_event)) {
|
||||
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
|
||||
if (_event.customType == kGriffonCutsceneSpeedUp) {
|
||||
speedUp = true;
|
||||
cnt = 6;
|
||||
}
|
||||
else if (_event.customType == kGriffonMenu) {
|
||||
if (ttsMan != nullptr)
|
||||
ttsMan->stop();
|
||||
return;
|
||||
}
|
||||
} else if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
|
||||
if (_event.customType == kGriffonCutsceneSpeedUp) {
|
||||
speedUp = false;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_QUIT();
|
||||
} else if (speedUp)
|
||||
cnt = 6;
|
||||
|
||||
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(_musicEndOfGame, true);
|
||||
setChannelVolume(_musicChannel, 0);
|
||||
}
|
||||
|
||||
int ticks1 = _ticks;
|
||||
int ya = 0;
|
||||
|
||||
float ld = 0;
|
||||
bool ldstop = false; // CHECKME: Check if actually used
|
||||
int nextparagraph = 0;
|
||||
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
|
||||
do {
|
||||
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;
|
||||
ya = CLIP(ya, 0, 255);
|
||||
} else
|
||||
break;
|
||||
|
||||
_videoBuffer2->fillRect(Common::Rect(0, 0, _videoBuffer2->w, _videoBuffer2->h), 0);
|
||||
_videoBuffer->surfacePtr()->setAlpha(255 - ya);
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer2);
|
||||
|
||||
g_system->copyRectToScreen(_videoBuffer2->getPixels(), _videoBuffer2->pitch, 0, 0, _videoBuffer2->w, _videoBuffer2->h);
|
||||
|
||||
POLL_AND_CHECK_QUIT();
|
||||
|
||||
g_system->updateScreen();
|
||||
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->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
rc.left = -xofs + 320;
|
||||
rc.top = 0;
|
||||
|
||||
_titleImg->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
y = y - spd * _fpsr;
|
||||
|
||||
for (int i = 0; i < ARRAYSIZE(story2); i++) {
|
||||
int yy = y + i * 10;
|
||||
|
||||
if (i == nextparagraph)
|
||||
nextparagraph = textToSpeech(nextparagraph, story2, ARRAYSIZE(story2));
|
||||
|
||||
if (yy > -8 && yy < 240) {
|
||||
int x = 160 - strlen(story2[i]) * 4;
|
||||
drawString(_videoBuffer, story2[i], x, yy, 4);
|
||||
}
|
||||
|
||||
if (yy < 10 && i == ARRAYSIZE(story2)-1) {
|
||||
if (ttsMan == nullptr || ttsMan->isSpeaking() == false)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ya = 255;
|
||||
if (_ticks < ticks1 + 1000) {
|
||||
ya = 255 * (_ticks - ticks1) / 1000;
|
||||
ya = CLIP(ya, 0, 255);
|
||||
}
|
||||
|
||||
_videoBuffer->surfacePtr()->setAlpha(ya);
|
||||
g_system->copyRectToScreen(_videoBuffer->getPixels(), _videoBuffer->pitch, 0, 0, _videoBuffer->w, _videoBuffer->h);
|
||||
|
||||
_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 += add;
|
||||
if (xofs >= 320)
|
||||
xofs -= 320;
|
||||
|
||||
if (g_system->getEventManager()->pollEvent(_event)) {
|
||||
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
|
||||
if (_event.customType == kGriffonCutsceneSpeedUp)
|
||||
spd = 1.0f;
|
||||
else if (_event.customType == kGriffonMenu) {
|
||||
if (ttsMan != nullptr)
|
||||
ttsMan->stop();
|
||||
break;
|
||||
}
|
||||
} else if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
|
||||
if (_event.customType == kGriffonCutsceneSpeedUp)
|
||||
spd = 0.2f;
|
||||
}
|
||||
|
||||
CHECK_QUIT();
|
||||
}
|
||||
|
||||
g_system->updateScreen();
|
||||
g_system->delayMillis(10);
|
||||
} 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;
|
||||
y1 = CLIP(y1, 0, 255);
|
||||
} else
|
||||
break;
|
||||
|
||||
_videoBuffer->fillRect(Common::Rect(0, 0, _videoBuffer->w, _videoBuffer->h), 0);
|
||||
|
||||
_videoBuffer->surfacePtr()->setAlpha(y1);
|
||||
_videoBuffer2->blendBlitTo(*_videoBuffer3);
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer3);
|
||||
|
||||
g_system->copyRectToScreen(_videoBuffer3->getPixels(), _videoBuffer3->pitch, 0, 0, _videoBuffer3->w, _videoBuffer3->h);
|
||||
g_system->updateScreen();
|
||||
|
||||
POLL_AND_CHECK_QUIT();
|
||||
|
||||
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;
|
||||
y1 = CLIP(y1, 0, 255);
|
||||
}
|
||||
|
||||
_videoBuffer->surfacePtr()->setAlpha(y1);
|
||||
|
||||
_videoBuffer2->fillRect(Common::Rect(0, 0, _videoBuffer2->w, _videoBuffer2->h), 0);
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer2);
|
||||
|
||||
g_system->copyRectToScreen(_videoBuffer2->getPixels(), _videoBuffer2->pitch, 0, 0, _videoBuffer2->w, _videoBuffer2->h);
|
||||
|
||||
g_system->updateScreen();
|
||||
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;
|
||||
}
|
||||
|
||||
if (g_system->getEventManager()->pollEvent(_event)) {
|
||||
CHECK_QUIT();
|
||||
|
||||
if ((_event.type == Common::EVENT_KEYDOWN || _event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) && 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].framesLeft = 0;
|
||||
_floatIcon[i].framesLeft = 0;
|
||||
}
|
||||
|
||||
for (float y = 0; y < 100; y += _fpsr) {
|
||||
_videoBuffer2->fillRect(Common::Rect(0, 0, _videoBuffer2->w, _videoBuffer2->h), 0);
|
||||
_videoBuffer->surfacePtr()->setAlpha((int)((100.0 - y) / 100 * 255));
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer2);
|
||||
|
||||
g_system->copyRectToScreen(_videoBuffer2->getPixels(), _videoBuffer2->pitch, 0, 0, _videoBuffer2->w, _videoBuffer2->h);
|
||||
g_system->updateScreen();
|
||||
|
||||
POLL_AND_CHECK_QUIT();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace Griffon
|
||||
74
engines/griffon/detection.cpp
Normal file
74
engines/griffon/detection.cpp
Normal file
@@ -0,0 +1,74 @@
|
||||
/* 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 "base/plugins.h"
|
||||
#include "engines/advancedDetector.h"
|
||||
|
||||
#include "common/text-to-speech.h"
|
||||
|
||||
#include "griffon/detection.h"
|
||||
|
||||
static const PlainGameDescriptor griffonGames[] = {
|
||||
{"griffon", "The Griffon Legend"},
|
||||
{nullptr, nullptr}
|
||||
};
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
static const ADGameDescription gameDescriptions[] = {
|
||||
{
|
||||
"griffon",
|
||||
nullptr,
|
||||
AD_ENTRY1s("objectdb.dat", "ec5371da28f01ccf88980b32d9de2232", 27754),
|
||||
Common::EN_ANY,
|
||||
Common::kPlatformWindows,
|
||||
ADGF_DROPPLATFORM,
|
||||
#ifdef USE_TTS
|
||||
GUIO2(GUIO_NOMIDI, GAMEOPTION_TTS_NARRATOR)
|
||||
#else
|
||||
GUIO1(GUIO_NOMIDI)
|
||||
#endif
|
||||
},
|
||||
|
||||
AD_TABLE_END_MARKER
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
class GriffonMetaEngineDetection: public AdvancedMetaEngineDetection<ADGameDescription> {
|
||||
public:
|
||||
GriffonMetaEngineDetection() : AdvancedMetaEngineDetection(Griffon::gameDescriptions, griffonGames) {
|
||||
}
|
||||
|
||||
const char *getName() const override {
|
||||
return "griffon";
|
||||
}
|
||||
|
||||
const char *getEngineName() const override {
|
||||
return "Griffon Engine";
|
||||
}
|
||||
|
||||
const char *getOriginalCopyright() const override {
|
||||
return "The Griffon Legend (c) 2005 Syn9 (Daniel Kennedy)";
|
||||
}
|
||||
};
|
||||
|
||||
REGISTER_PLUGIN_STATIC(GRIFFON_DETECTION, PLUGIN_TYPE_ENGINE_DETECTION, GriffonMetaEngineDetection);
|
||||
27
engines/griffon/detection.h
Normal file
27
engines/griffon/detection.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRIFFON_DETECTION_H
|
||||
#define GRIFFON_DETECTION_H
|
||||
|
||||
#define GAMEOPTION_TTS_NARRATOR GUIO_GAMEOPTIONS1
|
||||
|
||||
#endif
|
||||
874
engines/griffon/dialogs.cpp
Normal file
874
engines/griffon/dialogs.cpp
Normal file
@@ -0,0 +1,874 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*
|
||||
* 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 "common/config-manager.h"
|
||||
|
||||
#include "griffon/griffon.h"
|
||||
|
||||
#include "common/text-to-speech.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
#define MINCURSEL 7
|
||||
#define MAXCURSEL 16
|
||||
#define SY 25
|
||||
|
||||
void GriffonEngine::title(int mode) {
|
||||
const char *optionTitles[4] = {
|
||||
"new game/save/load",
|
||||
"options",
|
||||
"quit game",
|
||||
"return"
|
||||
};
|
||||
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
|
||||
float xofs = 0;
|
||||
_itemyloc = 0;
|
||||
bool exitTitle = false;
|
||||
|
||||
rcSrc.left = 0;
|
||||
rcSrc.top = 0;
|
||||
rcSrc.setWidth(320);
|
||||
rcSrc.setHeight(240);
|
||||
|
||||
_videoBuffer2->fillRect(rcSrc, 0);
|
||||
_videoBuffer3->fillRect(rcSrc, 0);
|
||||
|
||||
_ticks = g_system->getMillis();
|
||||
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer3);
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer2);
|
||||
|
||||
int cursel = 0;
|
||||
int ticks1 = _ticks;
|
||||
|
||||
if (config.music) {
|
||||
setChannelVolume(_musicChannel, 0);
|
||||
pauseSoundChannel(_musicChannel);
|
||||
|
||||
_menuChannel = playSound(_musicMenu, true);
|
||||
setChannelVolume(_menuChannel, config.musicVol);
|
||||
_pmenu = true;
|
||||
}
|
||||
|
||||
bool ldstop = false;
|
||||
|
||||
float ld = 0;
|
||||
do {
|
||||
Common::Rect rc;
|
||||
|
||||
ld += 4.0 * _fpsr;
|
||||
if (ld > config.musicVol)
|
||||
ld = config.musicVol;
|
||||
if (!ldstop) {
|
||||
setChannelVolume(_menuChannel, (int)ld);
|
||||
if ((int)ld == config.musicVol)
|
||||
ldstop = true;
|
||||
}
|
||||
|
||||
rc.left = -xofs;
|
||||
rc.top = 0;
|
||||
|
||||
_titleImg->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
rc.left = -xofs + 320.0;
|
||||
rc.top = 0;
|
||||
|
||||
_titleImg->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
rc.left = 0;
|
||||
rc.top = 0;
|
||||
|
||||
_titleImg2->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
int y = 172;
|
||||
int x = 160 - 14 * 4;
|
||||
|
||||
drawString(_videoBuffer, optionTitles[0], x, y, 4);
|
||||
drawString(_videoBuffer, optionTitles[1], x, y + 16, 4);
|
||||
drawString(_videoBuffer, optionTitles[2], x, y + 32, 4);
|
||||
|
||||
if (mode == 1)
|
||||
drawString(_videoBuffer, optionTitles[3], x, y + 48, 4);
|
||||
else
|
||||
drawString(_videoBuffer, "(c) 2005 by Daniel 'Syn9' Kennedy", 28, 224, 4);
|
||||
|
||||
rc.left = (int16)(x - 16 - 4 * cos(2 * M_PI * _itemyloc / 16));
|
||||
rc.top = (int16)(y - 4 + 16 * cursel);
|
||||
|
||||
_itemImg[15]->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
float yf = 255.0;
|
||||
if (_ticks < ticks1 + 1000) {
|
||||
yf = 255.0 * ((float)(_ticks - ticks1) / 1000.0);
|
||||
yf = CLIP<float>(yf, 0.0, 255.0);
|
||||
}
|
||||
|
||||
_videoBuffer->surfacePtr()->setAlpha((int)yf);
|
||||
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;
|
||||
}
|
||||
|
||||
float add = 0.5 * _fpsr;
|
||||
if (add > 1)
|
||||
add = 1;
|
||||
|
||||
xofs += add;
|
||||
if (xofs >= 320.0)
|
||||
xofs -= 320.0;
|
||||
|
||||
_itemyloc += 0.75 * _fpsr;
|
||||
|
||||
while (_itemyloc >= 16)
|
||||
_itemyloc = _itemyloc - 16;
|
||||
|
||||
if (g_system->getEventManager()->pollEvent(_event)) {
|
||||
if (_event.type == Common::EVENT_QUIT || _event.type == Common::EVENT_RETURN_TO_LAUNCHER)
|
||||
_shouldQuit = true;
|
||||
|
||||
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
|
||||
|
||||
switch(_event.customType) {
|
||||
case kGriffonMenu:
|
||||
if (mode == 1)
|
||||
exitTitle = true;
|
||||
break;
|
||||
case kGriffonUp:
|
||||
cursel--;
|
||||
if (cursel < 0)
|
||||
cursel = (mode == 1 ? 3 : 2);
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
|
||||
ttsMan->say(optionTitles[cursel]);
|
||||
break;
|
||||
case kGriffonDown:
|
||||
cursel++;
|
||||
if (cursel >= (mode == 1 ? 4 : 3))
|
||||
cursel = 0;
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
|
||||
ttsMan->say(optionTitles[cursel]);
|
||||
break;
|
||||
case kGriffonConfirm:
|
||||
if (ttsMan != nullptr)
|
||||
ttsMan->stop();
|
||||
switch(cursel) {
|
||||
case 0:
|
||||
_ticks = g_system->getMillis();
|
||||
ticks1 = _ticks;
|
||||
|
||||
saveLoadNew();
|
||||
|
||||
if (_gameMode == kGameModeNewGame || _gameMode == kGameModeLoadGame) {
|
||||
exitTitle = true;
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
configMenu();
|
||||
_ticks = g_system->getMillis();
|
||||
ticks1 = _ticks;
|
||||
break;
|
||||
case 2:
|
||||
_shouldQuit = true;
|
||||
break;
|
||||
case 3:
|
||||
exitTitle = true;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
g_system->delayMillis(10);
|
||||
} while (!_shouldQuit && !exitTitle && _gameMode != kGameModeNewGame && _gameMode != kGameModeLoadGame);
|
||||
|
||||
_itemTicks = _ticks + 210;
|
||||
|
||||
if (config.music) {
|
||||
haltSoundChannel(_menuChannel);
|
||||
resumeSoundChannel(_musicChannel);
|
||||
setChannelVolume(_musicChannel, config.musicVol);
|
||||
_pmenu = false;
|
||||
}
|
||||
}
|
||||
|
||||
static Common::String formatPercent(int val) {
|
||||
val = val / 2.55;
|
||||
return Common::String::format("%d percent", val - val % 10);
|
||||
}
|
||||
|
||||
static void speakMenuItem(int mapTitles, int mapValues, const char *mapTitleText[], const char *mapValueText[]) {
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled")) {
|
||||
Common::TextToSpeechManager::Action valueAction = Common::TextToSpeechManager::INTERRUPT;
|
||||
if (mapTitles != 0) {
|
||||
ttsMan->say(mapTitleText[mapTitles]);
|
||||
valueAction = Common::TextToSpeechManager::QUEUE;
|
||||
}
|
||||
if (mapValues != 0)
|
||||
ttsMan->say(mapValueText[mapValues], valueAction);
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::configMenu() {
|
||||
static const char *optionTitles[25] = {
|
||||
"", "",
|
||||
"", "", "", "",
|
||||
"", "", "",
|
||||
"Music:", "", "",
|
||||
"Sound Effects:", "", "",
|
||||
"Text to Speech:", "", "",
|
||||
"Music Volume:", "",
|
||||
"Effects Volume:", "", "", "", ""
|
||||
};
|
||||
static const char *optionValues[25] = {
|
||||
"", "",
|
||||
"", "", "", "",
|
||||
"", "", "",
|
||||
"On", "Off", "",
|
||||
"On", "Off", "",
|
||||
"On", "Off", "",
|
||||
"[----------]", "",
|
||||
"[----------]", "",
|
||||
"Exit + Save", "",
|
||||
"Exit"
|
||||
};
|
||||
static const int curselMapTitles[MAXCURSEL+1] = {
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 9, 9, 12,
|
||||
12, 15, 15, 18, 20,
|
||||
0, 0
|
||||
};
|
||||
static const int curselMapValues[MAXCURSEL+1] = {
|
||||
0, 0, 0, 0, 0,
|
||||
0, 0, 9, 10, 12,
|
||||
13, 15, 16, 0, 0,
|
||||
22, 24
|
||||
};
|
||||
|
||||
int cursel = MINCURSEL;
|
||||
bool exitMenu = false;
|
||||
|
||||
_ticks = g_system->getMillis();
|
||||
|
||||
Graphics::ManagedSurface *configwindow = loadImage("art/configwindow.bmp", true);
|
||||
configwindow->surfacePtr()->setAlpha(160, true);
|
||||
|
||||
int ticks1 = _ticks;
|
||||
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
|
||||
do {
|
||||
_videoBuffer->fillRect(Common::Rect(0, 0, _videoBuffer->w, _videoBuffer->h), 0);
|
||||
_videoBuffer2->fillRect(Common::Rect(0, 0, _videoBuffer2->w, _videoBuffer2->h), 0);
|
||||
|
||||
rcDest.left = 256 + 256 * cos(M_PI / 180 * _cloudAngle * 40);
|
||||
rcDest.top = 192 + 192 * sin(M_PI / 180 * _cloudAngle * 40);
|
||||
rcDest.setWidth(320);
|
||||
rcDest.setHeight(240);
|
||||
|
||||
_cloudImg->blendBlitTo(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, &rcDest, MS_ARGB(128, 255, 255, 255));
|
||||
|
||||
rcDest.left = 256;
|
||||
rcDest.top = 192;
|
||||
rcDest.setWidth(320);
|
||||
rcDest.setHeight(240);
|
||||
|
||||
_cloudImg->blendBlitTo(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, &rcDest, MS_ARGB(128, 255, 255, 255));
|
||||
|
||||
configwindow->blendBlitTo(*_videoBuffer);
|
||||
|
||||
int sy = SY;
|
||||
|
||||
for (int i = 0; i <= 24; i++) {
|
||||
static char line[24];
|
||||
|
||||
int destColumn = 3;
|
||||
if (i == 9 && config.music)
|
||||
destColumn = 0;
|
||||
else if (i == 10 && !config.music)
|
||||
destColumn = 0;
|
||||
else if (i == 12 && config.effects)
|
||||
destColumn = 0;
|
||||
else if (i == 13 && !config.effects)
|
||||
destColumn = 0;
|
||||
else if (i == 15 && ConfMan.getBool("tts_enabled"))
|
||||
destColumn = 0;
|
||||
else if (i == 16 && !ConfMan.getBool("tts_enabled"))
|
||||
destColumn = 0;
|
||||
else if (i == 18|| i == 20) {
|
||||
int vol = (i ==18 ? config.musicVol : config.effectsVol) * 9 / 255;
|
||||
vol = CLIP(vol, 0, 9);
|
||||
|
||||
Common::strcpy_s(line, "[----------]");
|
||||
line[vol + 1] = 'X';
|
||||
optionValues[i] = line;
|
||||
} else if (i > 21)
|
||||
destColumn = 0;
|
||||
|
||||
drawString(_videoBuffer, optionTitles[i], 156 - 8 * strlen(optionTitles[i]), sy + i * 8, 0);
|
||||
drawString(_videoBuffer, optionValues[i], 164, sy + i * 8, destColumn);
|
||||
}
|
||||
|
||||
int curselt = cursel + 2;
|
||||
if (cursel > 8)
|
||||
curselt += 1;
|
||||
if (cursel > 10)
|
||||
curselt += 1;
|
||||
if (cursel > 12)
|
||||
curselt += 1;
|
||||
if (cursel > 13)
|
||||
curselt += 1;
|
||||
if (cursel > 14)
|
||||
curselt += 1;
|
||||
if (cursel > 15)
|
||||
curselt += 1;
|
||||
|
||||
Common::Rect rc;
|
||||
rc.left = 148 + 3 * cos(2 * M_PI * _itemyloc / 16.0);
|
||||
rc.top = sy + 8 * curselt - 4;
|
||||
|
||||
_itemImg[15]->blendBlitTo(*_videoBuffer, rc.left, rc.top);
|
||||
|
||||
if (_ticks < ticks1 + 1000) {
|
||||
float yy = 255.0 * ((float)(_ticks - ticks1) / 1000.0);
|
||||
yy = CLIP<float>(yy, 0.0, 255.0);
|
||||
|
||||
_videoBuffer->surfacePtr()->setAlpha((uint8)yy);
|
||||
}
|
||||
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer2);
|
||||
g_system->copyRectToScreen(_videoBuffer2->getPixels(), _videoBuffer2->pitch, 0, 0, _videoBuffer2->w, _videoBuffer2->h);
|
||||
|
||||
_ticksPassed = _ticks;
|
||||
_ticks = g_system->getMillis();
|
||||
|
||||
_ticksPassed = _ticks - _ticksPassed;
|
||||
_fpsr = (float)_ticksPassed / 24;
|
||||
|
||||
_fp++;
|
||||
if (_ticks > _nextTicks) {
|
||||
_nextTicks = _ticks + 1000;
|
||||
_fps = _fp;
|
||||
_fp = 0;
|
||||
}
|
||||
|
||||
_itemyloc += 0.75 * _fpsr;
|
||||
while (_itemyloc >= 16)
|
||||
_itemyloc -= 16;
|
||||
|
||||
while (g_system->getEventManager()->pollEvent(_event)) {
|
||||
switch (_event.type) {
|
||||
case Common::EVENT_QUIT:
|
||||
case Common::EVENT_RETURN_TO_LAUNCHER:
|
||||
_shouldQuit = true;
|
||||
break;
|
||||
|
||||
case Common::EVENT_CUSTOM_ENGINE_ACTION_START:
|
||||
switch (_event.customType) {
|
||||
case kGriffonMenu:
|
||||
exitMenu = true;
|
||||
break;
|
||||
|
||||
case kGriffonLeft:
|
||||
if (cursel == 13) {
|
||||
config.musicVol = CLIP(config.musicVol - 25, 0, 255);
|
||||
setChannelVolume(_musicChannel, config.musicVol);
|
||||
setChannelVolume(_menuChannel, config.musicVol);
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
|
||||
ttsMan->say(formatPercent(config.musicVol));
|
||||
} else if (cursel == 14) {
|
||||
config.effectsVol = CLIP(config.effectsVol - 25, 0, 255);
|
||||
|
||||
setChannelVolume(-1, config.effectsVol);
|
||||
setChannelVolume(_musicChannel, config.musicVol);
|
||||
setChannelVolume(_menuChannel, config.musicVol);
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
|
||||
ttsMan->say(formatPercent(config.effectsVol));
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndDoor]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kGriffonRight:
|
||||
if (cursel == 13) {
|
||||
config.musicVol = CLIP(config.musicVol + 25, 0, 255);
|
||||
setChannelVolume(_musicChannel, config.musicVol);
|
||||
setChannelVolume(_menuChannel, config.musicVol);
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
|
||||
ttsMan->say(formatPercent(config.musicVol));
|
||||
} else if (cursel == 14) {
|
||||
config.effectsVol = CLIP(config.effectsVol + 25, 0, 255);
|
||||
setChannelVolume(-1, config.effectsVol);
|
||||
setChannelVolume(_musicChannel, config.musicVol);
|
||||
setChannelVolume(_menuChannel, config.musicVol);
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
|
||||
ttsMan->say(formatPercent(config.effectsVol));
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndDoor]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case kGriffonUp:
|
||||
cursel--;
|
||||
if (cursel < MINCURSEL)
|
||||
cursel = MAXCURSEL;
|
||||
speakMenuItem(curselMapTitles[cursel], curselMapValues[cursel], optionTitles, optionValues);
|
||||
break;
|
||||
|
||||
case kGriffonDown:
|
||||
++cursel;
|
||||
if (cursel > MAXCURSEL)
|
||||
cursel = MINCURSEL;
|
||||
speakMenuItem(curselMapTitles[cursel], curselMapValues[cursel], optionTitles, optionValues);
|
||||
break;
|
||||
|
||||
case kGriffonConfirm:
|
||||
switch (cursel) {
|
||||
case 7:
|
||||
if (!config.music) {
|
||||
config.music = true;
|
||||
_menuChannel = playSound(_musicMenu, true);
|
||||
setChannelVolume(_menuChannel, config.musicVol);
|
||||
}
|
||||
break;
|
||||
case 8:
|
||||
if (config.music) {
|
||||
config.music = false;
|
||||
haltSoundChannel(_musicChannel);
|
||||
haltSoundChannel(_menuChannel);
|
||||
}
|
||||
break;
|
||||
case 9:
|
||||
if (!config.effects) {
|
||||
config.effects = true;
|
||||
int snd = playSound(_sfx[kSndDoor]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
break;
|
||||
case 10:
|
||||
if (config.effects)
|
||||
config.effects = false;
|
||||
break;
|
||||
case 11:
|
||||
if (!ConfMan.getBool("tts_enabled")) {
|
||||
ConfMan.setBool("tts_enabled", true);
|
||||
}
|
||||
break;
|
||||
case 12:
|
||||
if (ConfMan.getBool("tts_enabled")) {
|
||||
ConfMan.setBool("tts_enabled", false);
|
||||
}
|
||||
break;
|
||||
case 15:
|
||||
saveConfig();
|
||||
// fall through
|
||||
case 16:
|
||||
if (ttsMan != nullptr)
|
||||
ttsMan->stop();
|
||||
exitMenu = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
_cloudAngle += 0.01 * _fpsr;
|
||||
while (_cloudAngle >= 360)
|
||||
_cloudAngle -= 360;
|
||||
|
||||
g_system->updateScreen();
|
||||
g_system->delayMillis(10);
|
||||
} while (!_shouldQuit && !exitMenu && _gameMode != kGameModeNewGame && _gameMode != kGameModeLoadGame);
|
||||
|
||||
|
||||
configwindow->free();
|
||||
_itemTicks = _ticks + 210;
|
||||
}
|
||||
|
||||
void GriffonEngine::renderSaveStates() {
|
||||
_videoBuffer2->fillRect(Common::Rect(0, 0, _videoBuffer2->w, _videoBuffer2->h), 0);
|
||||
|
||||
for (int ff = 0; ff <= 3; ff++) {
|
||||
loadPlayer(ff);
|
||||
|
||||
if (_playera.level > 0) {
|
||||
int sx = 8;
|
||||
int sy = 57 + ff * 48;
|
||||
|
||||
// time
|
||||
int ase = _asecstart;
|
||||
int h = ((ase - (ase % 3600)) / 3600);
|
||||
ase = (ase - h * 3600);
|
||||
int m = ((ase - (ase % 60)) / 60);
|
||||
int s = (ase - m * 60);
|
||||
|
||||
char line[256];
|
||||
Common::sprintf_s(line, "Game Time: %02i:%02i:%02i", h, m, s);
|
||||
drawString(_videoBuffer2, line, 160 - strlen(line) * 4, sy, 0);
|
||||
|
||||
sx = 12;
|
||||
sy += 11;
|
||||
int cc = 0;
|
||||
|
||||
Common::sprintf_s(line, "Health: %i/%i", _playera.hp, _playera.maxHp);
|
||||
drawString(_videoBuffer2, line, sx, sy, cc);
|
||||
|
||||
if (_playera.level == 22)
|
||||
Common::strcpy_s(line, "Level: MAX");
|
||||
else
|
||||
Common::sprintf_s(line, "Level: %i", _playera.level);
|
||||
|
||||
drawString(_videoBuffer2, line, sx, sy + 11, 0);
|
||||
|
||||
rcSrc.left = sx + 15 * 8 + 24;
|
||||
rcSrc.top = sy + 1;
|
||||
|
||||
int ss = (_playera.sword - 1) * 3;
|
||||
if (_playera.sword == 3)
|
||||
ss = 18;
|
||||
_itemImg[ss]->blendBlitTo(*_videoBuffer2, rcSrc.left, rcSrc.top);
|
||||
|
||||
rcSrc.left += 16;
|
||||
ss = (_playera.shield - 1) * 3 + 1;
|
||||
if (_playera.shield == 3)
|
||||
ss = 19;
|
||||
_itemImg[ss]->blendBlitTo(*_videoBuffer2, rcSrc.left, rcSrc.top);
|
||||
|
||||
rcSrc.left += 16;
|
||||
ss = (_playera.armour - 1) * 3 + 2;
|
||||
if (_playera.armour == 3)
|
||||
ss = 20;
|
||||
_itemImg[ss]->blendBlitTo(*_videoBuffer2, rcSrc.left, rcSrc.top);
|
||||
|
||||
int nx = rcSrc.left + 13 + 3 * 8;
|
||||
rcSrc.left = nx - 17;
|
||||
|
||||
if (_playera.foundSpell[0]) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
rcSrc.left += 17;
|
||||
if (_playera.foundSpell[i])
|
||||
_itemImg[7 + i]->blendBlitTo(*_videoBuffer2, rcSrc.left, rcSrc.top);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int sy = 57 + ff * 48;
|
||||
drawString(_videoBuffer2, "Empty", 160 - 5 * 4, sy, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::saveLoadNew() {
|
||||
const char *optionTitles[4] = {
|
||||
"new game", "", "load", "return",
|
||||
};
|
||||
|
||||
_cloudAngle = 0;
|
||||
|
||||
int curRow = 0;
|
||||
int curCol = 0;
|
||||
|
||||
bool lowerLock = false;
|
||||
|
||||
_ticks = g_system->getMillis();
|
||||
int ticks1 = _ticks;
|
||||
int tickPause = _ticks + 150;
|
||||
|
||||
|
||||
renderSaveStates();
|
||||
|
||||
delete _saveLoadImg;
|
||||
|
||||
_saveLoadImg = loadImage("art/saveloadnew.bmp", true);
|
||||
if (_gameMode == kGameModeIntro) {
|
||||
uint32 color = *(uint32 *)_saveLoadImg->getBasePtr(120, 10);
|
||||
_saveLoadImg->fillRect(Common::Rect(125, 15, 160, 33), color);
|
||||
}
|
||||
_saveLoadImg->surfacePtr()->setAlpha(192, true);
|
||||
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
|
||||
// Main menu loop
|
||||
do {
|
||||
_videoBuffer->fillRect(Common::Rect(0, 0, _videoBuffer->w, _videoBuffer->h), 0);
|
||||
|
||||
rcDest.left = 256 + 256 * cos(M_PI / 180 * _cloudAngle * 40);
|
||||
rcDest.top = 192 + 192 * sin(M_PI / 180 * _cloudAngle * 40);
|
||||
rcDest.setWidth(320);
|
||||
rcDest.setHeight(240);
|
||||
|
||||
_cloudImg->blendBlitTo(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, &rcDest, MS_ARGB(128, 255, 255, 255));
|
||||
|
||||
rcDest.left = 256;
|
||||
rcDest.top = 192;
|
||||
rcDest.setWidth(320);
|
||||
rcDest.setHeight(240);
|
||||
|
||||
_cloudImg->blendBlitTo(*_videoBuffer, 0, 0, Graphics::FLIP_NONE, &rcDest, MS_ARGB(128, 255, 255, 255));
|
||||
|
||||
_saveLoadImg->blendBlitTo(*_videoBuffer);
|
||||
|
||||
if (g_system->getEventManager()->pollEvent(_event)) {
|
||||
if (_event.type == Common::EVENT_QUIT || _event.type == Common::EVENT_RETURN_TO_LAUNCHER) {
|
||||
_shouldQuit = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tickPause < _ticks && _event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
|
||||
_itemTicks = _ticks + 220;
|
||||
|
||||
if (_event.customType == kGriffonConfirm) {
|
||||
if (curRow == 0) {
|
||||
if (curCol == 0) {
|
||||
// NEW GAME
|
||||
if (ttsMan != nullptr)
|
||||
ttsMan->stop();
|
||||
_gameMode = kGameModeNewGame;
|
||||
|
||||
return;
|
||||
} else if (curCol == 1) {
|
||||
// SAVE GAME
|
||||
lowerLock = true;
|
||||
curRow = 1 + _saveSlot;
|
||||
tickPause = _ticks + 125;
|
||||
} else if (curCol == 2) {
|
||||
// LOAD GAME
|
||||
lowerLock = true;
|
||||
curRow = 1;
|
||||
tickPause = _ticks + 125;
|
||||
} else if (curCol == 3) {
|
||||
if (ttsMan != nullptr)
|
||||
ttsMan->stop();
|
||||
// RETURN
|
||||
return;
|
||||
} else if (curCol == 4) {
|
||||
// QUIT - non existent :)
|
||||
_shouldQuit = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (lowerLock && tickPause < _ticks) {
|
||||
if ((curCol == 1) && saveGameState(curRow - 1, "", false).getCode() == Common::kNoError) {
|
||||
_secStart += _secsInGame;
|
||||
_secsInGame = 0;
|
||||
lowerLock = false;
|
||||
_saveSlot = curRow - 1;
|
||||
curRow = 0;
|
||||
|
||||
renderSaveStates();
|
||||
} else if ((curCol == 2) && loadGameState(curRow - 1).getCode() == Common::kNoError) {
|
||||
|
||||
return;
|
||||
}
|
||||
tickPause = _ticks + 125;
|
||||
}
|
||||
}
|
||||
|
||||
switch (_event.customType) {
|
||||
case kGriffonMenu:
|
||||
if (curRow == 0)
|
||||
return;
|
||||
lowerLock = false;
|
||||
curRow = 0;
|
||||
tickPause = _ticks + 125;
|
||||
break;
|
||||
case kGriffonDown:
|
||||
if (lowerLock) {
|
||||
++curRow;
|
||||
if (curRow == 5)
|
||||
curRow = 1;
|
||||
tickPause = _ticks + 125;
|
||||
}
|
||||
break;
|
||||
|
||||
case kGriffonUp:
|
||||
if (lowerLock) {
|
||||
--curRow;
|
||||
if (curRow == 0)
|
||||
curRow = 4;
|
||||
tickPause = _ticks + 125;
|
||||
}
|
||||
break;
|
||||
|
||||
case kGriffonLeft:
|
||||
if (!lowerLock) {
|
||||
--curCol;
|
||||
if (curCol == -1)
|
||||
curCol = 3;
|
||||
|
||||
if (curCol == 1 && _gameMode == kGameModeIntro)
|
||||
curCol = 0;
|
||||
|
||||
tickPause = _ticks + 125;
|
||||
}
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
|
||||
ttsMan -> say(optionTitles[curCol]);
|
||||
break;
|
||||
|
||||
case kGriffonRight:
|
||||
if (!lowerLock) {
|
||||
++curCol;
|
||||
if (curCol == 4)
|
||||
curCol = 0;
|
||||
|
||||
if (curCol == 1 && _gameMode == kGameModeIntro)
|
||||
curCol = 2;
|
||||
|
||||
tickPause = _ticks + 125;
|
||||
}
|
||||
if (ttsMan != nullptr && ConfMan.getBool("tts_enabled"))
|
||||
ttsMan -> say(optionTitles[curCol]);
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Render savestates
|
||||
_videoBuffer2->blendBlitTo(*_videoBuffer);
|
||||
|
||||
// ------------------------------------------
|
||||
|
||||
if (curRow == 0) {
|
||||
rcDest.top = 18;
|
||||
switch(curCol) {
|
||||
case 0:
|
||||
rcDest.left = 10;
|
||||
break;
|
||||
case 1:
|
||||
rcDest.left = 108;
|
||||
break;
|
||||
case 2:
|
||||
rcDest.left = 170;
|
||||
break;
|
||||
case 3:
|
||||
rcDest.left = 230;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
rcDest.left += (int16)(2 + 2 * sin(2 * M_PI * _itemyloc / 16));
|
||||
}
|
||||
|
||||
if (curRow > 0) {
|
||||
rcDest.left = (int16)(0 + 2 * sin(2 * M_PI * _itemyloc / 16));
|
||||
rcDest.top = (int16)(53 + (curRow - 1) * 48);
|
||||
}
|
||||
|
||||
_itemImg[15]->blendBlitTo(*_videoBuffer, rcDest.left, rcDest.top);
|
||||
|
||||
if (curRow != 0) {
|
||||
rcDest.top = 18;
|
||||
if (curCol == 1)
|
||||
rcDest.left = 108;
|
||||
else if (curCol == 2)
|
||||
rcDest.left = 170;
|
||||
|
||||
_itemImg[15]->blendBlitTo(*_videoBuffer, rcDest.left, rcDest.top);
|
||||
}
|
||||
|
||||
if (_ticks < ticks1 + 1000) {
|
||||
int yy = 255 * (_ticks - ticks1) / 1000;
|
||||
yy = CLIP(yy, 0, 255);
|
||||
|
||||
_videoBuffer->surfacePtr()->setAlpha((uint8)yy);
|
||||
}
|
||||
|
||||
_videoBuffer3->fillRect(Common::Rect(0, 0, _videoBuffer3->w, _videoBuffer3->h), 0);
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer3);
|
||||
|
||||
g_system->copyRectToScreen(_videoBuffer3->getPixels(), _videoBuffer3->pitch, 0, 0, _videoBuffer3->w, _videoBuffer3->h);
|
||||
g_system->updateScreen();
|
||||
|
||||
_ticksPassed = _ticks;
|
||||
_ticks = g_system->getMillis();
|
||||
|
||||
_ticksPassed = _ticks - _ticksPassed;
|
||||
_fpsr = (float)_ticksPassed / 24;
|
||||
|
||||
_fp++;
|
||||
if (_ticks > _nextTicks) {
|
||||
_nextTicks = _ticks + 1000;
|
||||
_fps = _fp;
|
||||
_fp = 0;
|
||||
}
|
||||
|
||||
_cloudAngle += 0.01 * _fpsr;
|
||||
while (_cloudAngle >= 360)
|
||||
_cloudAngle -= 360;
|
||||
|
||||
_itemyloc += 0.6 * _fpsr;
|
||||
while (_itemyloc >= 16)
|
||||
_itemyloc -= 16;
|
||||
|
||||
g_system->delayMillis(10);
|
||||
} while (!_shouldQuit);
|
||||
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace Griffon
|
||||
1212
engines/griffon/draw.cpp
Normal file
1212
engines/griffon/draw.cpp
Normal file
File diff suppressed because it is too large
Load Diff
340
engines/griffon/engine.cpp
Normal file
340
engines/griffon/engine.cpp
Normal file
@@ -0,0 +1,340 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*
|
||||
* 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 "griffon/griffon.h"
|
||||
#include "griffon/console.h"
|
||||
|
||||
#include "common/system.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
void Player::reset() {
|
||||
px = 0;
|
||||
py = 0;
|
||||
opx = 0;
|
||||
opy = 0;
|
||||
walkDir = 0;
|
||||
walkFrame = 0;
|
||||
walkSpeed = 0;
|
||||
attackFrame = 0;
|
||||
attackSpeed = 0;
|
||||
hp = 0;
|
||||
maxHp = 0;
|
||||
hpflash = 0;
|
||||
hpflashb = 0;
|
||||
level = 0;
|
||||
maxLevel = 0;
|
||||
sword = 0;
|
||||
shield = 0;
|
||||
armour = 0;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
foundSpell[i] = 0;
|
||||
spellCharge[i] = 0;
|
||||
inventory[i] = 0;
|
||||
}
|
||||
attackStrength = 0;
|
||||
itemselshade = 0;
|
||||
spellDamage = 0;
|
||||
swordDamage = 0;
|
||||
exp = 0;
|
||||
nextLevel = 0;
|
||||
}
|
||||
|
||||
// copypaste from hRnd_CRT()
|
||||
float GriffonEngine::RND() {
|
||||
/* return between 0 and 1 (but never 1) */
|
||||
return (float)_rnd->getRandomNumber(32767) * (1.0f / 32768.0f);
|
||||
}
|
||||
|
||||
void GriffonEngine::mainLoop() {
|
||||
swash();
|
||||
|
||||
if (_pmenu) {
|
||||
haltSoundChannel(_menuChannel);
|
||||
_pmenu = false;
|
||||
}
|
||||
|
||||
_gameMode = kGameModePlay;
|
||||
|
||||
do {
|
||||
if (!_forcePause) {
|
||||
updateAnims();
|
||||
updateNPCs();
|
||||
}
|
||||
|
||||
checkTrigger();
|
||||
checkInputs();
|
||||
|
||||
if (!_forcePause)
|
||||
handleWalking();
|
||||
|
||||
updateY();
|
||||
drawView();
|
||||
|
||||
updateMusic();
|
||||
updateEngine();
|
||||
} while (!_shouldQuit && _gameMode == kGameModePlay);
|
||||
}
|
||||
|
||||
void GriffonEngine::updateEngine() {
|
||||
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;
|
||||
_secsInGame = _secsInGame + 1;
|
||||
}
|
||||
|
||||
if (_attacking) {
|
||||
_player.attackFrame += _player.attackSpeed * _fpsr;
|
||||
if (_player.attackFrame >= 16) {
|
||||
_attacking = false;
|
||||
_player.attackFrame = 0;
|
||||
_player.walkFrame = 0;
|
||||
}
|
||||
|
||||
int pa = (int)(_player.attackFrame);
|
||||
|
||||
for (int i = 0; i <= pa; i++) {
|
||||
if (!_playerAttackOfs[_player.walkDir][i].completed) {
|
||||
_playerAttackOfs[_player.walkDir][i].completed = true;
|
||||
|
||||
float opx = _player.px;
|
||||
float opy = _player.py;
|
||||
|
||||
_player.px += _playerAttackOfs[_player.walkDir][i].x;
|
||||
_player.py += _playerAttackOfs[_player.walkDir][i].y;
|
||||
|
||||
int sx = (int)(_player.px / 2 + 6);
|
||||
int sy = (int)(_player.py / 2 + 10);
|
||||
uint32 *temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
||||
uint32 bgc = *temp;
|
||||
if (bgc > 0) {
|
||||
_player.px = opx;
|
||||
_player.py = opy;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_player.opx = _player.px;
|
||||
_player.opy = _player.py;
|
||||
|
||||
checkHit();
|
||||
|
||||
if (_gameMode != kGameModePlay)
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < kMaxFloat; i++) {
|
||||
if (_floatText[i].framesLeft > 0) {
|
||||
float spd = 0.5 * _fpsr;
|
||||
_floatText[i].framesLeft -= spd;
|
||||
_floatText[i].y -= spd;
|
||||
if (_floatText[i].framesLeft < 0)
|
||||
_floatText[i].framesLeft = 0;
|
||||
}
|
||||
|
||||
if (_floatIcon[i].framesLeft > 0) {
|
||||
float spd = 0.5 * _fpsr;
|
||||
_floatIcon[i].framesLeft -= spd;
|
||||
_floatIcon[i].y -= spd;
|
||||
if (_floatIcon[i].framesLeft < 0)
|
||||
_floatIcon[i].framesLeft = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (_player.level == _player.maxLevel)
|
||||
_player.exp = 0;
|
||||
|
||||
if (_player.exp >= _player.nextLevel) {
|
||||
_player.level = _player.level + 1;
|
||||
addFloatText("LEVEL UP!", _player.px + 16 - 36, _player.py + 16, 3);
|
||||
_player.exp = _player.exp - _player.nextLevel;
|
||||
_player.nextLevel = _player.nextLevel * 3 / 2; // 1.5
|
||||
_player.maxHp = _player.maxHp + _player.level * 3;
|
||||
if (_player.maxHp > 999)
|
||||
_player.maxHp = 999;
|
||||
_player.hp = _player.maxHp;
|
||||
|
||||
_player.swordDamage = _player.level * 14 / 10;
|
||||
_player.spellDamage = _player.level * 13 / 10;
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndPowerUp]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
}
|
||||
|
||||
_clipBg->copyRectToSurface(_clipBg2->getPixels(), _clipBg2->pitch, 0, 0, _clipBg2->w, _clipBg2->h);
|
||||
|
||||
Common::Rect rc;
|
||||
|
||||
rc.left = _player.px - 2;
|
||||
rc.top = _player.py - 2;
|
||||
rc.setWidth(5);
|
||||
rc.setHeight(5);
|
||||
|
||||
_clipBg->fillRect(rc, 1000);
|
||||
|
||||
if (!_forcePause) {
|
||||
for (int i = 0; i < 5; i++) {
|
||||
if (_player.foundSpell[i])
|
||||
_player.spellCharge[i] += 1 * _player.level * 0.01 * _fpsr;
|
||||
if (_player.spellCharge[i] > 100)
|
||||
_player.spellCharge[i] = 100;
|
||||
}
|
||||
|
||||
if (_player.foundSpell[0]) {
|
||||
_player.spellStrength += 3 * _player.level * .01 * _fpsr;
|
||||
}
|
||||
|
||||
_player.attackStrength += (30 + 3 * (float)_player.level) / 50 * _fpsr;
|
||||
}
|
||||
|
||||
if (_player.attackStrength > 100)
|
||||
_player.attackStrength = 100;
|
||||
|
||||
if (_player.spellStrength > 100)
|
||||
_player.spellStrength = 100;
|
||||
|
||||
_itemyloc += 0.75 * _fpsr;
|
||||
while (_itemyloc >= 16)
|
||||
_itemyloc -= 16;
|
||||
|
||||
if (_player.hp <= 0) {
|
||||
theEnd();
|
||||
|
||||
_gameMode = kGameModeIntro;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (_roomLock) {
|
||||
_roomLock = false;
|
||||
for (int i = 1; i <= _lastNpc; i++)
|
||||
if (_npcInfo[i].hp > 0)
|
||||
_roomLock = true;
|
||||
}
|
||||
|
||||
_cloudAngle += 0.1 * _fpsr;
|
||||
while (_cloudAngle >= 360)
|
||||
_cloudAngle = _cloudAngle - 360;
|
||||
|
||||
_player.hpflash = _player.hpflash + 0.1 * _fpsr;
|
||||
if (_player.hpflash >= 2) {
|
||||
_player.hpflash = 0;
|
||||
_player.hpflashb = _player.hpflashb + 1;
|
||||
if (_player.hpflashb == 2)
|
||||
_player.hpflashb = 0;
|
||||
if (config.effects && _player.hpflashb == 0 && _player.hp < _player.maxHp / 4) {
|
||||
int snd = playSound(_sfx[kSndBeep]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
}
|
||||
|
||||
// _cloudsOn = false
|
||||
|
||||
if (_itemSelOn)
|
||||
_player.itemselshade = _player.itemselshade + 2 * _fpsr;
|
||||
if (_player.itemselshade > 24)
|
||||
_player.itemselshade = 24;
|
||||
|
||||
for (int i = 0; i <= 4; i++)
|
||||
if (_player.inventory[i] > 9)
|
||||
_player.inventory[i] = 9;
|
||||
}
|
||||
|
||||
void GriffonEngine::newGame() {
|
||||
intro();
|
||||
|
||||
if (_shouldQuit)
|
||||
return;
|
||||
|
||||
_player.reset();
|
||||
_playera.reset();
|
||||
|
||||
memset(_scriptFlag, 0, sizeof(_scriptFlag));
|
||||
memset(_objectMapFull, 0, sizeof(_objectMapFull));
|
||||
memset(_roomLocks, 0, sizeof(_roomLocks));
|
||||
|
||||
_roomLocks[66] = 2;
|
||||
_roomLocks[24] = 2;
|
||||
_roomLocks[17] = 1;
|
||||
_roomLocks[34] = 1;
|
||||
_roomLocks[50] = 1;
|
||||
_roomLocks[73] = 1;
|
||||
_roomLocks[82] = 2;
|
||||
|
||||
_player.walkSpeed = 1.1f;
|
||||
_animSpeed = 0.5f;
|
||||
_attacking = false;
|
||||
_player.attackSpeed = 1.5f;
|
||||
|
||||
_player.sword = 1;
|
||||
_player.level = 1;
|
||||
_player.maxLevel = 22;
|
||||
_player.nextLevel = 50;
|
||||
_player.shield = 1;
|
||||
_player.armour = 1;
|
||||
_player.hp = 14;
|
||||
_player.maxHp = _player.hp;
|
||||
|
||||
_player.swordDamage = _player.level * 2;
|
||||
_player.spellDamage = _player.level * 3 / 2;
|
||||
|
||||
_player.px = 15 * 16 - 4;
|
||||
_player.py = 6 * 16 - 4;
|
||||
_player.walkDir = 1;
|
||||
|
||||
_playingGardens = false;
|
||||
_playingBoss = false;
|
||||
|
||||
_player.spellStrength = 0;
|
||||
|
||||
loadMap(2);
|
||||
|
||||
mainLoop();
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace Griffon
|
||||
170
engines/griffon/gfx.cpp
Normal file
170
engines/griffon/gfx.cpp
Normal file
@@ -0,0 +1,170 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*
|
||||
* 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"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
void GriffonEngine::addFloatIcon(int ico, float xloc, float yloc) {
|
||||
for (int i = 0; i < kMaxFloat; i++) {
|
||||
if (ABS(_floatIcon[i].framesLeft) < kEpsilon) {
|
||||
_floatIcon[i].framesLeft = 32;
|
||||
_floatIcon[i].x = xloc;
|
||||
_floatIcon[i].y = yloc;
|
||||
_floatIcon[i].ico = ico;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::addFloatText(const char *stri, float xloc, float yloc, int col) {
|
||||
for (int i = 0; i < kMaxFloat; i++) {
|
||||
if (ABS(_floatText[i].framesLeft) < kEpsilon) {
|
||||
_floatText[i].framesLeft = 32;
|
||||
_floatText[i].x = xloc;
|
||||
_floatText[i].y = yloc;
|
||||
_floatText[i].col = col;
|
||||
Common::strcpy_s(_floatText[i].text, 64, stri);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::eventText(const char *stri) {
|
||||
_videoBuffer2->fillRect(Common::Rect(0, 0, _videoBuffer2->w, _videoBuffer2->h), 0);
|
||||
_videoBuffer3->fillRect(Common::Rect(0, 0, _videoBuffer3->w, _videoBuffer3->h), 0);
|
||||
|
||||
int x = 160 - 4 * strlen(stri);
|
||||
|
||||
_ticks = g_system->getMillis();
|
||||
int pause_ticks = _ticks + 500;
|
||||
int b_ticks = _ticks;
|
||||
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer3);
|
||||
_videoBuffer->blendBlitTo(*_videoBuffer2);
|
||||
|
||||
do {
|
||||
g_system->getEventManager()->pollEvent(_event);
|
||||
|
||||
if ((_event.type == Common::EVENT_KEYDOWN || _event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) && pause_ticks < _ticks)
|
||||
break;
|
||||
_videoBuffer2->blendBlitTo(*_videoBuffer);
|
||||
|
||||
int fr = 192;
|
||||
|
||||
if (pause_ticks > _ticks)
|
||||
fr = 192 * (_ticks - b_ticks) / 500;
|
||||
if (fr > 192)
|
||||
fr = 192;
|
||||
|
||||
_windowImg->surfacePtr()->setAlpha(fr, true);
|
||||
|
||||
_windowImg->blendBlitTo(*_videoBuffer);
|
||||
if (pause_ticks < _ticks)
|
||||
drawString(_videoBuffer, stri, x, 15, 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;
|
||||
}
|
||||
|
||||
g_system->delayMillis(10);
|
||||
} while (1);
|
||||
|
||||
_videoBuffer3->blendBlitTo(*_videoBuffer);
|
||||
|
||||
_itemTicks = _ticks + 210;
|
||||
}
|
||||
|
||||
void GriffonEngine::drawLine(Graphics::ManagedSurface *buffer, int x1, int y1, int x2, int y2, int col) {
|
||||
int xdif = x2 - x1;
|
||||
int ydif = y2 - y1;
|
||||
|
||||
if (xdif == 0) {
|
||||
for (int y = y1; y <= y2; y++) {
|
||||
uint32 *temp = (uint32 *)buffer->getBasePtr(x1, y);
|
||||
*temp = col;
|
||||
}
|
||||
}
|
||||
|
||||
if (ydif == 0) {
|
||||
for (int x = x1; x <= x2; x++) {
|
||||
uint32 *temp = (uint32 *)buffer->getBasePtr(x, y1);
|
||||
*temp = col;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::drawString(Graphics::ManagedSurface *buffer, const char *stri, int xloc, int yloc, int col) {
|
||||
int l = strlen(stri);
|
||||
|
||||
for (int i = 0; i < l; i++) {
|
||||
rcDest.left = xloc + i * 8;
|
||||
rcDest.top = yloc;
|
||||
|
||||
_fontChr[stri[i] - 32][col]->blendBlitTo(*buffer, rcDest.left, rcDest.top);
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::drawProgress(int w, int wm) {
|
||||
long ccc = _videoBuffer->format.RGBToColor(0, 255, 0);
|
||||
|
||||
rcDest.setWidth(w * 74 / wm);
|
||||
_videoBuffer->fillRect(rcDest, ccc);
|
||||
|
||||
g_system->copyRectToScreen(_videoBuffer->getPixels(), _videoBuffer->pitch, 0, 0, _videoBuffer->w, _videoBuffer->h);
|
||||
g_system->updateScreen();
|
||||
|
||||
g_system->getEventManager()->pollEvent(_event);
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace Griffon
|
||||
208
engines/griffon/griffon.cpp
Normal file
208
engines/griffon/griffon.cpp
Normal file
@@ -0,0 +1,208 @@
|
||||
/* 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/>.
|
||||
*
|
||||
* 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/config-manager.h"
|
||||
#include "common/debug.h"
|
||||
#include "common/debug-channels.h"
|
||||
#include "common/error.h"
|
||||
#include "common/file.h"
|
||||
#include "common/fs.h"
|
||||
#include "common/system.h"
|
||||
#include "common/translation.h"
|
||||
#include "graphics/pixelformat.h"
|
||||
|
||||
#include "common/text-to-speech.h"
|
||||
|
||||
#include "engines/util.h"
|
||||
|
||||
#include "griffon/griffon.h"
|
||||
#include "griffon/console.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
GriffonEngine::GriffonEngine(OSystem *syst) : Engine(syst) {
|
||||
const Common::FSNode gameDataDir(ConfMan.getPath("path"));
|
||||
SearchMan.addSubDirectoryMatching(gameDataDir, "sound");
|
||||
|
||||
_rnd = new Common::RandomSource("griffon");
|
||||
|
||||
_console = nullptr;
|
||||
_mixer = nullptr;
|
||||
|
||||
_shouldQuit = false;
|
||||
_gameMode = kGameModeIntro;
|
||||
|
||||
_musicChannel = -1;
|
||||
_menuChannel = -1;
|
||||
|
||||
_cloudAngle = 0.0f;
|
||||
|
||||
_dontDrawOver = false;
|
||||
|
||||
_firsty = 0;
|
||||
_lasty = 0;
|
||||
_saveSlot = 0;
|
||||
|
||||
_ticks = g_system->getMillis();
|
||||
_ticksAtPauseStart = 0;
|
||||
|
||||
for (int i = 0; i < 33; ++i) {
|
||||
for (int j = 0; j < 6; ++j) {
|
||||
_objectInfo[i].nFrames = 0;
|
||||
_objectInfo[i].xTiles = 0;
|
||||
_objectInfo[i].yTiles = 0;
|
||||
_objectInfo[i].speed = 0;
|
||||
_objectInfo[i].type = 0;
|
||||
_objectInfo[i].script = 0;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < 256; ++i) {
|
||||
_objectFrame[i][0] = 0;
|
||||
_objectFrame[i][1] = 0;
|
||||
}
|
||||
|
||||
// Synchronize the sound settings from ScummVM
|
||||
syncSoundSettings();
|
||||
}
|
||||
|
||||
GriffonEngine::~GriffonEngine() {
|
||||
delete _rnd;
|
||||
//delete _console; Debugger is deleted by Engine
|
||||
}
|
||||
|
||||
void GriffonEngine::syncSoundSettings() {
|
||||
Engine::syncSoundSettings();
|
||||
|
||||
bool mute = false;
|
||||
config.music = config.effects = false;
|
||||
|
||||
if (ConfMan.hasKey("mute"))
|
||||
mute = ConfMan.getBool("mute");
|
||||
|
||||
if (!mute) {
|
||||
config.music = !ConfMan.getBool("music_mute");
|
||||
config.effects = !ConfMan.getBool("sfx_mute");
|
||||
}
|
||||
|
||||
config.musicVol = ConfMan.getInt("music_volume");
|
||||
config.effectsVol = ConfMan.getInt("sfx_volume");
|
||||
}
|
||||
|
||||
void GriffonEngine::saveConfig() {
|
||||
ConfMan.setBool("mute", !(config.music || config.effectsVol));
|
||||
ConfMan.setBool("music_mute", !config.music);
|
||||
ConfMan.setBool("sfx_mute", !config.effects);
|
||||
ConfMan.setInt("music_volume", config.musicVol);
|
||||
ConfMan.setInt("sfx_volume", config.effectsVol);
|
||||
|
||||
ConfMan.flushToDisk();
|
||||
}
|
||||
|
||||
Common::Error GriffonEngine::run() {
|
||||
Common::TextToSpeechManager *ttsMan = g_system->getTextToSpeechManager();
|
||||
if (ttsMan != nullptr) {
|
||||
ttsMan->setLanguage("en");
|
||||
ttsMan->enable(ConfMan.getBool("tts_enabled"));
|
||||
}
|
||||
|
||||
Graphics::PixelFormat pixelFormat(4, 8, 8, 8, 8, 24, 16, 8, 0);
|
||||
initGraphics(320, 240, &pixelFormat);
|
||||
|
||||
_mixer = g_system->getMixer();
|
||||
|
||||
_console = new Console();
|
||||
setDebugger(_console);
|
||||
|
||||
initialize();
|
||||
|
||||
if (ConfMan.hasKey("save_slot")) {
|
||||
_saveSlot = ConfMan.getInt("save_slot");
|
||||
loadGameState(_saveSlot);
|
||||
|
||||
_gameMode = kGameModeLoadGame;
|
||||
} else {
|
||||
showLogos();
|
||||
_gameMode = kGameModeIntro;
|
||||
}
|
||||
|
||||
if (_shouldQuit)
|
||||
return Common::kNoError;
|
||||
|
||||
while (!_shouldQuit) {
|
||||
switch (_gameMode) {
|
||||
case kGameModeIntro:
|
||||
case kGameModePlay:
|
||||
title(0);
|
||||
break;
|
||||
|
||||
case kGameModeNewGame:
|
||||
newGame();
|
||||
break;
|
||||
|
||||
case kGameModeLoadGame:
|
||||
_player.walkSpeed = 1.1f;
|
||||
_animSpeed = 0.5f;
|
||||
_attacking = false;
|
||||
_player.attackSpeed = 1.5f;
|
||||
|
||||
_playingGardens = false;
|
||||
_playingBoss = false;
|
||||
|
||||
haltSoundChannel(-1);
|
||||
|
||||
_secsInGame = 0;
|
||||
loadMap(_curMap);
|
||||
mainLoop();
|
||||
break;
|
||||
|
||||
default:
|
||||
error("Bad game mode: %d", _gameMode);
|
||||
}
|
||||
}
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
void GriffonEngine::pauseEngineIntern(bool pause) {
|
||||
if (pause) {
|
||||
_ticksAtPauseStart = _ticks;
|
||||
} else {
|
||||
uint32 diff = _system->getMillis() - _ticksAtPauseStart;
|
||||
_ticks += diff;
|
||||
_nextTicks += diff;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
582
engines/griffon/griffon.h
Normal file
582
engines/griffon/griffon.h
Normal file
@@ -0,0 +1,582 @@
|
||||
/* 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/>.
|
||||
*
|
||||
* 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
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef GRIFFON_GRIFFON_H
|
||||
#define GRIFFON_GRIFFON_H
|
||||
|
||||
#include "common/scummsys.h"
|
||||
#include "common/error.h"
|
||||
#include "common/events.h"
|
||||
#include "common/random.h"
|
||||
#include "engines/engine.h"
|
||||
|
||||
#include "audio/mixer.h"
|
||||
|
||||
#include "graphics/managed_surface.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
class Console;
|
||||
|
||||
#define kSoundHandles 16
|
||||
#define kMaxNPC 32
|
||||
#define kMaxFloat 32
|
||||
#define kMaxSpell 32
|
||||
|
||||
// spells
|
||||
enum {
|
||||
kSpellIce = 0,
|
||||
kSpellSteel,
|
||||
kSpellWood,
|
||||
kSpellRock,
|
||||
kSpellFire
|
||||
};
|
||||
|
||||
// inventory items
|
||||
enum {
|
||||
kInvFlask = 0,
|
||||
kInvDoubleFlask,
|
||||
kInvShock,
|
||||
kInvNormalKey,
|
||||
kInvMasterKey
|
||||
};
|
||||
|
||||
enum {
|
||||
kSndBite = 0,
|
||||
kSndCrystal,
|
||||
kSndDoor,
|
||||
kSndEnemyHit,
|
||||
kSndIce,
|
||||
kSndLever,
|
||||
kSndLightning,
|
||||
kSndMetalHit,
|
||||
kSndPowerUp,
|
||||
kSndRocks,
|
||||
kSndSwordHit,
|
||||
kSndThrow,
|
||||
kSndChest,
|
||||
kSndFire,
|
||||
kSndBeep
|
||||
};
|
||||
|
||||
// in game scripts
|
||||
enum {
|
||||
kScriptFlask = 0, // get flask
|
||||
kScriptMasterKey = 2, // find master key
|
||||
kScriptFindCrystal = 3, // find crystal
|
||||
kScriptFindShield = 4, // find shield - obj 8
|
||||
kScriptFindSword = 5, // find sword - obj 9
|
||||
kScriptKeyChest = 6, // regular key chest
|
||||
kScriptBlueFlask = 7, // blue flask
|
||||
kScriptGardenMasterKey = 8, // garden's master key
|
||||
kScriptLightningBomb = 9, // lightning bomb
|
||||
kScriptBlueFlaskChest = 10, // blue flask chest
|
||||
kScriptLightningChest = 11, // lightning chest
|
||||
kScriptArmourChest = 12, // armour chest
|
||||
kScriptCitadelMasterKey = 13, // citadel master key
|
||||
kScriptEndOfGame = 14, // end of game
|
||||
kScriptGetSword3 = 15, // get sword3
|
||||
kScriptShield3 = 16, // shield3
|
||||
kScriptArmour3 = 17, // armour3
|
||||
kScriptKeyChest1 = 20, // key chest 1
|
||||
kScriptLever = 60 // lever
|
||||
};
|
||||
|
||||
// monsters
|
||||
enum {
|
||||
kMonsterBabyDragon = 1, // baby dragon
|
||||
kMonsterOneWing = 2, // one wing
|
||||
kMonsterBoss1 = 3, // boss 1
|
||||
kMonsterBlackKnight = 4, // black knight
|
||||
kMonsterFireHydra = 5, // fire hydra
|
||||
kMonsterRedDragon = 6, // red dragon
|
||||
kMonsterPriest = 7, // priest
|
||||
kMonsterYellowDragon = 8, // yellow fire dragon
|
||||
kMonsterTwoWing = 9, // two wing
|
||||
kMonsterDragon2 = 10, // dragon2
|
||||
kMonsterFinalBoss = 11, // final boss
|
||||
kMonsterBatKitty = 12 // bat kitty
|
||||
};
|
||||
|
||||
// engine actions
|
||||
enum GriffonActions {
|
||||
kGriffonLeft,
|
||||
kGriffonRight,
|
||||
kGriffonUp,
|
||||
kGriffonDown,
|
||||
kGriffonAttack,
|
||||
kGriffonInventory,
|
||||
kGriffonMenu,
|
||||
kGriffonConfirm,
|
||||
kGriffonCutsceneSpeedUp
|
||||
};
|
||||
|
||||
#define kEpsilon 0.001
|
||||
|
||||
struct Player {
|
||||
float px;
|
||||
float py;
|
||||
float opx;
|
||||
float opy;
|
||||
int walkDir;
|
||||
float walkFrame;
|
||||
float walkSpeed;
|
||||
float attackFrame;
|
||||
float attackSpeed;
|
||||
|
||||
int hp;
|
||||
int maxHp;
|
||||
float hpflash;
|
||||
int hpflashb;
|
||||
int level;
|
||||
int maxLevel;
|
||||
int sword;
|
||||
int shield;
|
||||
int armour;
|
||||
int foundSpell[5];
|
||||
float spellCharge[5];
|
||||
int inventory[5];
|
||||
float attackStrength;
|
||||
float spellStrength;
|
||||
int spellDamage;
|
||||
int swordDamage;
|
||||
|
||||
int exp;
|
||||
int nextLevel;
|
||||
|
||||
int pause;
|
||||
|
||||
float itemselshade;
|
||||
int ysort;
|
||||
|
||||
void reset();
|
||||
};
|
||||
|
||||
struct BodySection {
|
||||
float x;
|
||||
float y;
|
||||
int parentID;
|
||||
int isbase;
|
||||
int sprite;
|
||||
int bonelength; // the 'bone' that connects the body sections
|
||||
};
|
||||
|
||||
struct NPC {
|
||||
float x;
|
||||
float y;
|
||||
int spriteset;
|
||||
int x1; // patrol area
|
||||
int y1;
|
||||
int x2;
|
||||
int y2;
|
||||
int attitude;
|
||||
int hp;
|
||||
|
||||
int maxhp;
|
||||
int item1;
|
||||
int item2;
|
||||
int item3;
|
||||
int script;
|
||||
float frame;
|
||||
float frame2; // end boss specific
|
||||
int cframe;
|
||||
bool onMap; // is this npc set to be genned in the mapfile
|
||||
|
||||
int ticks;
|
||||
int pause;
|
||||
int shake;
|
||||
|
||||
int movementmode;
|
||||
int walkdir;
|
||||
float walkspd;
|
||||
int movingdir;
|
||||
bool moving;
|
||||
|
||||
bool attacking;
|
||||
float attackframe;
|
||||
int cattackframe;
|
||||
float attackspd;
|
||||
int attackdelay;
|
||||
int attacknext;
|
||||
int attackattempt;
|
||||
|
||||
int spellDamage;
|
||||
int attackDamage;
|
||||
|
||||
|
||||
// one wing and firehydra specific
|
||||
BodySection bodysection[31];
|
||||
float swayAngle;
|
||||
float swaySpeed;
|
||||
float headTargetX[4];
|
||||
float headTargetY[4];
|
||||
int castPause;
|
||||
|
||||
// firehydra specific
|
||||
int attacknext2[4];
|
||||
bool attacking2[4];
|
||||
int attackframe2[4];
|
||||
|
||||
// dragon2 specific
|
||||
float floating;
|
||||
};
|
||||
|
||||
struct Spell {
|
||||
int spellnum;
|
||||
float homex;
|
||||
float homey;
|
||||
float enemyx;
|
||||
float enemyy;
|
||||
|
||||
float frame;
|
||||
|
||||
int damagewho; // 0 = npc, 1 = player
|
||||
|
||||
// for earthslide
|
||||
float rocky[9]; // CHECKME: Looks unused
|
||||
int rockimg[9];
|
||||
int rockdeflect[9];
|
||||
|
||||
float strength;
|
||||
|
||||
// fire
|
||||
int legalive[5];
|
||||
|
||||
// spell 6 specific
|
||||
float fireballs[7][4]; // x,y,targetx, targety
|
||||
int nfballs;
|
||||
int ballon[7];
|
||||
|
||||
int npc;
|
||||
};
|
||||
|
||||
struct AnimSet {
|
||||
int x; // xyloc on spriteimageset
|
||||
int y;
|
||||
int xofs; // the actual place to paste the sprite in reference to the bodypart loc on screen
|
||||
int yofs;
|
||||
int w; // w/h of the sprite in the imageset
|
||||
int h;
|
||||
};
|
||||
|
||||
struct DataChunk {
|
||||
byte *data;
|
||||
int size;
|
||||
};
|
||||
|
||||
struct FloatTextStruct {
|
||||
float framesLeft;
|
||||
float x;
|
||||
float y;
|
||||
int col;
|
||||
char *text;
|
||||
};
|
||||
|
||||
struct FloatIconStruct {
|
||||
float framesLeft;
|
||||
float x;
|
||||
float y;
|
||||
int ico;
|
||||
};
|
||||
|
||||
struct AttackOffsetStruct {
|
||||
float x;
|
||||
float y;
|
||||
bool completed;
|
||||
};
|
||||
|
||||
struct Config {
|
||||
bool music;
|
||||
int musicVol;
|
||||
bool effects;
|
||||
int effectsVol;
|
||||
};
|
||||
|
||||
struct ObjectInfoStruct {
|
||||
int nFrames;
|
||||
int xTiles;
|
||||
int yTiles;
|
||||
int speed;
|
||||
int type;
|
||||
int script;
|
||||
};
|
||||
|
||||
enum {
|
||||
kGameModeIntro,
|
||||
kGameModePlay,
|
||||
kGameModeNewGame,
|
||||
kGameModeLoadGame
|
||||
};
|
||||
|
||||
class GriffonEngine : public Engine {
|
||||
public:
|
||||
GriffonEngine(OSystem *syst);
|
||||
~GriffonEngine() override;
|
||||
|
||||
Common::Error run() override;
|
||||
void syncSoundSettings() override;
|
||||
|
||||
private:
|
||||
Common::RandomSource *_rnd;
|
||||
bool _shouldQuit;
|
||||
int _gameMode;
|
||||
|
||||
Console *_console;
|
||||
|
||||
private:
|
||||
|
||||
// combat.cpp
|
||||
void attack();
|
||||
void castSpell(int spellnum, float homex, float homey, float enemyx, float enemyy, int damagewho);
|
||||
void checkHit();
|
||||
void damageNPC(int npcnum, int damage, int spell);
|
||||
void damagePlayer(int damage);
|
||||
|
||||
// cutscenes.cpp
|
||||
void showLogos();
|
||||
void intro();
|
||||
void endOfGame();
|
||||
void theEnd();
|
||||
|
||||
// dialogs.cpp
|
||||
void title(int mode);
|
||||
void configMenu();
|
||||
void saveLoadNew();
|
||||
void renderSaveStates();
|
||||
|
||||
// draw.cpp
|
||||
void drawAnims(int Layer);
|
||||
void drawHud();
|
||||
void drawNPCs(int mode);
|
||||
void drawOver(int modx, int mody);
|
||||
void drawPlayer();
|
||||
void drawView();
|
||||
void swash();
|
||||
|
||||
// engine.cpp
|
||||
float RND();
|
||||
|
||||
void mainLoop();
|
||||
void updateEngine();
|
||||
void newGame();
|
||||
|
||||
// gfx.cpp
|
||||
void addFloatIcon(int ico, float xloc, float yloc);
|
||||
void addFloatText(const char *stri, float xloc, float yloc, int col);
|
||||
void eventText(const char *stri);
|
||||
void drawLine(Graphics::ManagedSurface *buffer, int x1, int y1, int x2, int y2, int col);
|
||||
void drawString(Graphics::ManagedSurface *buffer, const char *stri, int xloc, int yloc, int col);
|
||||
void drawProgress(int w, int wm);
|
||||
|
||||
// input.cpp
|
||||
void checkInputs();
|
||||
void handleWalking();
|
||||
void checkTrigger();
|
||||
void processTrigger(int trignum);
|
||||
|
||||
// logic.cpp
|
||||
void updateAnims();
|
||||
void updateY();
|
||||
void updateNPCs();
|
||||
void updateSpells();
|
||||
void updateSpellsUnder();
|
||||
|
||||
// resources.cpp
|
||||
void initialize();
|
||||
Graphics::ManagedSurface *loadImage(const char *name, bool colorkey = false);
|
||||
void loadMap(int mapnum);
|
||||
void loadAnims();
|
||||
void loadFont();
|
||||
void loadItemImgs();
|
||||
void loadTiles();
|
||||
void loadTriggers();
|
||||
void loadObjectDB();
|
||||
|
||||
// saveload.cpp
|
||||
Common::String getSaveStateName(int slot) const override;
|
||||
int loadPlayer(int slotnum);
|
||||
Common::Error loadGameState(int slot) override;
|
||||
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave = false) override;
|
||||
Common::Error loadGameStream(Common::SeekableReadStream *file) override;
|
||||
Common::Error saveGameStream(Common::WriteStream *file, bool isAutosave) override;
|
||||
|
||||
// sound.cpp
|
||||
void setChannelVolume(int channel, int volume);
|
||||
int getSoundHandle();
|
||||
int playSound(DataChunk *chunk, bool looped = false);
|
||||
void pauseSoundChannel(int channel);
|
||||
void haltSoundChannel(int channel);
|
||||
void resumeSoundChannel(int channel);
|
||||
bool isSoundChannelPlaying(int channel);
|
||||
void setupAudio();
|
||||
void updateMusic();
|
||||
|
||||
// Common engine overrides
|
||||
void pauseEngineIntern(bool pause) override;
|
||||
bool canLoadGameStateCurrently(Common::U32String *msg = nullptr) override { return true; }
|
||||
bool canSaveGameStateCurrently(Common::U32String *msg = nullptr) override { return _gameMode == kGameModePlay; }
|
||||
int getAutosaveSlot() const override { return 4; }
|
||||
bool hasFeature(EngineFeature f) const override;
|
||||
|
||||
private:
|
||||
Graphics::ManagedSurface *_video, *_videoBuffer, *_videoBuffer2, *_videoBuffer3;
|
||||
|
||||
// system
|
||||
Graphics::ManagedSurface *_titleImg, *_titleImg2, *_inventoryImg;
|
||||
Graphics::ManagedSurface *_logosImg, *_theEndImg;
|
||||
Common::Event _event;
|
||||
|
||||
Graphics::ManagedSurface *_mapBg, *_clipBg, *_clipBg2;
|
||||
unsigned int _clipSurround[4][4];
|
||||
|
||||
float _animSpeed; // CHECKME: it seems to always be 0.5
|
||||
int _rampData[40][24];
|
||||
|
||||
int _curMap;
|
||||
Graphics::ManagedSurface *_fontChr[224][5]; // 256 - 32
|
||||
Graphics::ManagedSurface *_itemImg[21], *_windowImg;
|
||||
Graphics::ManagedSurface *_spellImg;
|
||||
|
||||
bool _itemSelOn;
|
||||
int _curItem, _itemTicks;
|
||||
float _itemyloc;
|
||||
bool _selEnemyOn;
|
||||
int _curEnemy;
|
||||
bool _forcePause;
|
||||
bool _roomLock; // set to disable any room jumps while in the room
|
||||
int _scriptFlag[100][10], _saveSlot; // script, flag
|
||||
|
||||
// timer related - move to local later
|
||||
int _ticks, _ticksPassed, _nextTicks, _ticksAtPauseStart;
|
||||
float _fp, _fps, _fpsr; // CHECKME: _fp and _fps seems to be integers
|
||||
int _secsInGame, _secStart;
|
||||
|
||||
Graphics::ManagedSurface *mapImg[4];
|
||||
|
||||
Common::Rect rcSrc, rcDest;
|
||||
|
||||
// -----------special case
|
||||
bool _dontDrawOver; // used in map24 so that the candles don't draw over the boss, default set to 0
|
||||
|
||||
// saveload info
|
||||
Graphics::ManagedSurface *_saveLoadImg;
|
||||
|
||||
// post info
|
||||
float _postInfo[21][3];
|
||||
int _postInfoNbr;
|
||||
|
||||
// cloud info
|
||||
Graphics::ManagedSurface *_cloudImg;
|
||||
float _cloudAngle;
|
||||
int _cloudsOn;
|
||||
|
||||
// spell info
|
||||
Spell _spellInfo[kMaxSpell];
|
||||
|
||||
// player info
|
||||
Player _player;
|
||||
Player _playera;
|
||||
bool _movingUp, _movingDown, _movingLeft, _movingRight;
|
||||
bool _attacking;
|
||||
int _asecstart;
|
||||
|
||||
// tile info
|
||||
Graphics::ManagedSurface *_tiles[4];
|
||||
int _tileinfo[3][40][24][3]; // maplayer, x, y, tiledata (tile, tilelayer)
|
||||
|
||||
// animation info
|
||||
Graphics::ManagedSurface *_anims[100];
|
||||
// id number 0&1 = players
|
||||
Graphics::ManagedSurface *_animsAttack[100];
|
||||
// attack anims
|
||||
AttackOffsetStruct _playerAttackOfs[4][16];
|
||||
|
||||
FloatTextStruct _floatText[kMaxFloat];
|
||||
FloatIconStruct _floatIcon[kMaxFloat];
|
||||
|
||||
// special for animset2
|
||||
AnimSet _animSet2[7], _animSet9[7];
|
||||
|
||||
// object info
|
||||
float _objectFrame[256][2];
|
||||
int _lastObj;
|
||||
// frame!, curframe
|
||||
ObjectInfoStruct _objectInfo[33];
|
||||
|
||||
int _objectTile[33][9][3][3][2];
|
||||
// [objnum] [frame] [x] [y] [tile/layer]
|
||||
int _objectMap[21][15];
|
||||
|
||||
int _objectMapFull[1000][21][15];
|
||||
// [mapnum] x, y set to 1 to make this objmap spot stay at -1
|
||||
|
||||
// trigger info
|
||||
int _triggers[10000][9];
|
||||
// [map#][index], [var]
|
||||
// map#,x,y
|
||||
int _triggerLoc[320][240], _triggerNbr;
|
||||
|
||||
// npc info
|
||||
NPC _npcInfo[kMaxNPC];
|
||||
int _lastNpc;
|
||||
|
||||
// music info
|
||||
DataChunk *_musicGardens1, *_musicGardens2, *_musicGardens3, *_musicGardens4, *_musicBoss, *_musicMenu, *_musicEndOfGame;
|
||||
int _musicChannel, _menuChannel;
|
||||
bool _playingBoss, _playingGardens;
|
||||
|
||||
DataChunk *_sfx[15];
|
||||
Audio::SoundHandle _handles[kSoundHandles];
|
||||
Audio::Mixer *_mixer;
|
||||
|
||||
// set to 1 for normal key, set to 2 for master, set to 0 if unlocked
|
||||
int _roomLocks[201], _lockType;
|
||||
int _roomToUnlock;
|
||||
|
||||
bool _canUseKey;
|
||||
bool _saidLocked;
|
||||
bool _saidJammed;
|
||||
|
||||
// ysort
|
||||
int _ysort[2401], _lasty, _firsty;
|
||||
|
||||
bool _pmenu;
|
||||
|
||||
Config config;
|
||||
void saveConfig();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // GRIFFON_GRIFFON_H
|
||||
691
engines/griffon/input.cpp
Normal file
691
engines/griffon/input.cpp
Normal file
@@ -0,0 +1,691 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*
|
||||
* 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/console.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
void GriffonEngine::checkInputs() {
|
||||
int ntickdelay = 175;
|
||||
bool _keyPressed = false;
|
||||
|
||||
if (g_system->getEventManager()->pollEvent(_event))
|
||||
_keyPressed = true;
|
||||
|
||||
_postInfoNbr = 0;
|
||||
|
||||
for (int i = 0; i <= 20; i++) {
|
||||
_postInfo[i][0] = 0;
|
||||
_postInfo[i][1] = 0;
|
||||
}
|
||||
|
||||
for (int x = 0; x <= 19; x++) {
|
||||
for (int y = 0; y <= 14; y++) {
|
||||
int o = _objectMap[x][y];
|
||||
if (_objectInfo[o].type == 3) {
|
||||
_postInfo[_postInfoNbr][0] = x * 16;
|
||||
_postInfo[_postInfoNbr][1] = y * 16;
|
||||
_postInfoNbr = _postInfoNbr + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_attacking || (_forcePause && !_itemSelOn))
|
||||
return;
|
||||
|
||||
if (_event.type == Common::EVENT_QUIT || _event.type == Common::EVENT_RETURN_TO_LAUNCHER) {
|
||||
_shouldQuit = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
|
||||
if (_event.customType == kGriffonMenu) {
|
||||
if (_itemTicks < _ticks)
|
||||
title(1);
|
||||
} else if (_event.customType == kGriffonAttack) {
|
||||
if (!_itemSelOn && (_itemTicks < _ticks))
|
||||
attack();
|
||||
|
||||
if (_itemSelOn && _itemTicks < _ticks) {
|
||||
if (_curItem == 0 && _player.inventory[kInvFlask] > 0) {
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
|
||||
int heal = 50;
|
||||
int maxh = _player.maxHp - _player.hp;
|
||||
|
||||
if (heal > maxh)
|
||||
heal = maxh;
|
||||
|
||||
_player.hp = _player.hp + heal;
|
||||
|
||||
char text[256];
|
||||
Common::sprintf_s(text, "+%i", heal);
|
||||
addFloatText(text, _player.px + 16 - 4 * strlen(text), _player.py + 16, 5);
|
||||
|
||||
_player.inventory[kInvFlask]--;
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndPowerUp]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
|
||||
_itemSelOn = false;
|
||||
_forcePause = false;
|
||||
}
|
||||
|
||||
if (_curItem == 1 && _player.inventory[kInvDoubleFlask] > 0) {
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
|
||||
int heal = 200;
|
||||
int maxHeal = _player.maxHp - _player.hp;
|
||||
|
||||
if (heal > maxHeal)
|
||||
heal = maxHeal;
|
||||
|
||||
_player.hp += heal;
|
||||
|
||||
char text[256];
|
||||
Common::sprintf_s(text, "+%i", heal);
|
||||
addFloatText(text, _player.px + 16 - 4 * strlen(text), _player.py + 16, 5);
|
||||
|
||||
_player.inventory[kInvDoubleFlask]--;
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndPowerUp]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
|
||||
_itemSelOn = false;
|
||||
_forcePause = false;
|
||||
}
|
||||
|
||||
if (_curItem == 2 && _player.inventory[kInvShock] > 0) {
|
||||
castSpell(8, _player.px, _player.py, _npcInfo[_curEnemy].x, _npcInfo[_curEnemy].y, 0);
|
||||
|
||||
_forcePause = true;
|
||||
|
||||
_player.inventory[kInvShock]--;
|
||||
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
_selEnemyOn = false;
|
||||
_itemSelOn = false;
|
||||
|
||||
}
|
||||
|
||||
if (_curItem == 3 && _player.inventory[kInvNormalKey] > 0 && _canUseKey && _lockType == 1) {
|
||||
_roomLocks[_roomToUnlock] = 0;
|
||||
eventText("UnLocked!");
|
||||
|
||||
_player.inventory[kInvNormalKey]--;
|
||||
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
_selEnemyOn = false;
|
||||
_itemSelOn = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_curItem == 4 && _player.inventory[kInvMasterKey] > 0 && _canUseKey && _lockType == 2) {
|
||||
_roomLocks[_roomToUnlock] = 0;
|
||||
eventText("UnLocked!");
|
||||
|
||||
_player.inventory[kInvMasterKey]--;
|
||||
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
_selEnemyOn = false;
|
||||
_itemSelOn = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (_curItem == 5 && _player.spellCharge[0] == 100) {
|
||||
castSpell(5, _player.px, _player.py, _npcInfo[_curEnemy].x, _npcInfo[_curEnemy].y, 0);
|
||||
|
||||
_player.spellCharge[0] = 0;
|
||||
|
||||
_forcePause = true;
|
||||
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
_selEnemyOn = false;
|
||||
_itemSelOn = false;
|
||||
}
|
||||
|
||||
if (_curItem > 5 && _selEnemyOn) {
|
||||
if (_curEnemy <= _lastNpc) {
|
||||
castSpell(_curItem - 6, _player.px, _player.py, _npcInfo[_curEnemy].x, _npcInfo[_curEnemy].y, 0);
|
||||
} else {
|
||||
int pst = _curEnemy - _lastNpc - 1;
|
||||
castSpell(_curItem - 6, _player.px, _player.py, _postInfo[pst][0], _postInfo[pst][1], 0);
|
||||
}
|
||||
|
||||
_player.spellCharge[_curItem - 5] = 0;
|
||||
|
||||
_player.spellStrength = 0;
|
||||
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
_selEnemyOn = false;
|
||||
_itemSelOn = false;
|
||||
_forcePause = false;
|
||||
}
|
||||
|
||||
if (_curItem > 5 && !_selEnemyOn && _itemSelOn) {
|
||||
if (ABS(_player.spellCharge[_curItem - 5] - 100) < kEpsilon) {
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
|
||||
_selEnemyOn = true;
|
||||
|
||||
int i = 0;
|
||||
do {
|
||||
if (_npcInfo[i].hp > 0) {
|
||||
_curEnemy = i;
|
||||
goto __exit_do;
|
||||
}
|
||||
i = i + 1;
|
||||
if (i == _lastNpc + 1) {
|
||||
_selEnemyOn = false;
|
||||
goto __exit_do;
|
||||
}
|
||||
} while (1);
|
||||
__exit_do:
|
||||
|
||||
if (_postInfoNbr > 0 && !_selEnemyOn) {
|
||||
_selEnemyOn = true;
|
||||
_curEnemy = _lastNpc + 1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else if (_event.customType == kGriffonInventory) {
|
||||
if (_itemTicks < _ticks) {
|
||||
_selEnemyOn = false;
|
||||
if (_itemSelOn) {
|
||||
_itemSelOn = false;
|
||||
_itemTicks = _ticks + 220;
|
||||
_forcePause = false;
|
||||
} else {
|
||||
_itemSelOn = true;
|
||||
_itemTicks = _ticks + 220;
|
||||
_forcePause = true;
|
||||
_player.itemselshade = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!_itemSelOn) {
|
||||
_movingUp = false;
|
||||
_movingDown = false;
|
||||
_movingLeft = false;
|
||||
_movingRight = false;
|
||||
// We continue moving even after the key has been released until we receive a different event
|
||||
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START || _event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_END) {
|
||||
if (_event.customType == kGriffonUp)
|
||||
_movingUp = true;
|
||||
if (_event.customType == kGriffonDown)
|
||||
_movingDown = true;
|
||||
if (_event.customType == kGriffonLeft)
|
||||
_movingLeft = true;
|
||||
if (_event.customType == kGriffonRight)
|
||||
_movingRight = true;
|
||||
}
|
||||
} else {
|
||||
_movingUp = false;
|
||||
_movingDown = false;
|
||||
_movingLeft = false;
|
||||
_movingRight = false;
|
||||
|
||||
if (_selEnemyOn) {
|
||||
if (_itemTicks < _ticks) {
|
||||
if (_event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
|
||||
if (_event.customType == kGriffonLeft) {
|
||||
int origin = _curEnemy;
|
||||
do {
|
||||
_curEnemy = _curEnemy - 1;
|
||||
if (_curEnemy < 1)
|
||||
_curEnemy = _lastNpc + _postInfoNbr;
|
||||
if (_curEnemy == origin)
|
||||
break;
|
||||
if (_curEnemy <= _lastNpc && _npcInfo[_curEnemy].hp > 0)
|
||||
break;
|
||||
if (_curEnemy > _lastNpc)
|
||||
break;
|
||||
} while (1);
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
}
|
||||
if (_event.customType == kGriffonRight) {
|
||||
int origin = _curEnemy;
|
||||
do {
|
||||
_curEnemy = _curEnemy + 1;
|
||||
if (_curEnemy > _lastNpc + _postInfoNbr)
|
||||
_curEnemy = 1;
|
||||
if (_curEnemy == origin)
|
||||
break;
|
||||
if (_curEnemy <= _lastNpc && _npcInfo[_curEnemy].hp > 0)
|
||||
break;
|
||||
if (_curEnemy > _lastNpc)
|
||||
break;
|
||||
} while (1);
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
}
|
||||
}
|
||||
|
||||
if (_curEnemy > _lastNpc + _postInfoNbr)
|
||||
_curEnemy = 1;
|
||||
if (_curEnemy < 1)
|
||||
_curEnemy = _lastNpc + _postInfoNbr;
|
||||
}
|
||||
} else {
|
||||
if (_keyPressed && _event.type == Common::EVENT_CUSTOM_ENGINE_ACTION_START) {
|
||||
if (_event.customType == kGriffonUp) {
|
||||
_curItem = _curItem - 1;
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
if (_curItem == 4)
|
||||
_curItem = 9;
|
||||
if (_curItem == -1)
|
||||
_curItem = 4;
|
||||
}
|
||||
if (_event.customType == kGriffonDown) {
|
||||
_curItem = _curItem + 1;
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
if (_curItem == 5)
|
||||
_curItem = 0;
|
||||
if (_curItem == 10)
|
||||
_curItem = 5;
|
||||
}
|
||||
if (_event.customType == kGriffonLeft) {
|
||||
_curItem = _curItem - 5;
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
}
|
||||
if (_event.customType == kGriffonRight) {
|
||||
_curItem = _curItem + 5;
|
||||
_itemTicks = _ticks + ntickdelay;
|
||||
}
|
||||
}
|
||||
|
||||
if (_curItem > 9)
|
||||
_curItem = _curItem - 10;
|
||||
if (_curItem < 0)
|
||||
_curItem = _curItem + 10;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::handleWalking() {
|
||||
int xmax = 20 * 16 - 25;
|
||||
int ymax = 15 * 16 - 25;
|
||||
|
||||
float px = _player.px;
|
||||
float py = _player.py;
|
||||
float opx = px;
|
||||
float opy = py;
|
||||
|
||||
float spd = _player.walkSpeed * _fpsr;
|
||||
|
||||
float nx = (px / 2 + 6);
|
||||
float ny = (py / 2 + 10);
|
||||
|
||||
float npx = px + 12;
|
||||
float npy = py + 20;
|
||||
int lx = (int)npx / 16;
|
||||
int ly = (int)npy / 16;
|
||||
|
||||
int ramp = _rampData[lx][ly];
|
||||
if (ramp == 1 && _movingUp)
|
||||
spd *= 2;
|
||||
if (ramp == 1 && _movingDown)
|
||||
spd *= 2;
|
||||
|
||||
if (ramp == 2 && _movingLeft)
|
||||
_movingUp = true;
|
||||
if (ramp == 2 && _movingRight)
|
||||
_movingDown = true;
|
||||
|
||||
if (ramp == 3 && _movingRight)
|
||||
_movingUp = true;
|
||||
if (ramp == 3 && _movingLeft)
|
||||
_movingDown = true;
|
||||
|
||||
uint32 *temp/*, c*/, bgc;
|
||||
|
||||
for (int x = -1; x <= 1; x++) {
|
||||
for (int y = -1; y <= 1; y++) {
|
||||
int sx = nx + x;
|
||||
int sy = ny + y;
|
||||
|
||||
_clipSurround[x + 1][y + 1] = 0;
|
||||
if (sx > -1 && sx < 320 && sy > -1 && sy < 192) {
|
||||
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
||||
_clipSurround[x + 1][y + 1] = *temp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_movingUp)
|
||||
_player.walkDir = 0;
|
||||
if (_movingDown)
|
||||
_player.walkDir = 1;
|
||||
if (_movingLeft)
|
||||
_player.walkDir = 2;
|
||||
if (_movingRight)
|
||||
_player.walkDir = 3;
|
||||
|
||||
if (_movingUp && _clipSurround[1][0] == 0) {
|
||||
py -= spd;
|
||||
_player.walkDir = 0;
|
||||
} else if (_movingUp && _clipSurround[1][0] > 0) {
|
||||
// move upleft
|
||||
if (!_movingRight && _clipSurround[0][0] == 0) {
|
||||
py -= spd;
|
||||
px -= spd;
|
||||
}
|
||||
|
||||
// move upright
|
||||
if (!_movingLeft && _clipSurround[2][0] == 0) {
|
||||
py -= spd;
|
||||
px += spd;
|
||||
}
|
||||
}
|
||||
if (_movingDown && _clipSurround[1][2] == 0) {
|
||||
py += spd;
|
||||
_player.walkDir = 1;
|
||||
} else if (_movingDown && _clipSurround[1][2] > 0) {
|
||||
// move downleft
|
||||
if (_movingRight == 0 && _clipSurround[0][2] == 0) {
|
||||
py += spd;
|
||||
px -= spd;
|
||||
}
|
||||
|
||||
// move downright
|
||||
if (_movingLeft == 0 && _clipSurround[2][2] == 0) {
|
||||
py += spd;
|
||||
px += spd;
|
||||
}
|
||||
}
|
||||
if (_movingLeft && _clipSurround[0][1] == 0) {
|
||||
px -= spd;
|
||||
_player.walkDir = 2;
|
||||
} else if (_movingLeft && _clipSurround[0][1] > 0) {
|
||||
// move leftup
|
||||
if (!_movingDown && _clipSurround[0][0] == 0) {
|
||||
py -= spd;
|
||||
px -= spd;
|
||||
}
|
||||
|
||||
// move leftdown
|
||||
if (!_movingUp && _clipSurround[0][2] == 0) {
|
||||
py += spd;
|
||||
px -= spd;
|
||||
}
|
||||
}
|
||||
if (_movingRight && _clipSurround[2][1] == 0) {
|
||||
px += spd;
|
||||
_player.walkDir = 3;
|
||||
} else if (_movingRight && _clipSurround[2][1] > 0) {
|
||||
// move rightup
|
||||
if (!_movingDown && _clipSurround[2][0] == 0) {
|
||||
px += spd;
|
||||
py -= spd;
|
||||
}
|
||||
|
||||
// move rightdown
|
||||
if (!_movingUp && _clipSurround[2][2] == 0) {
|
||||
py += spd;
|
||||
px += spd;
|
||||
}
|
||||
}
|
||||
|
||||
if (px < -8)
|
||||
px = -8;
|
||||
if (px > xmax)
|
||||
px = xmax;
|
||||
if (py < -8)
|
||||
py = -8;
|
||||
if (py > ymax)
|
||||
py = ymax;
|
||||
|
||||
int pass = 1;
|
||||
|
||||
int sx = (px / 2 + 6);
|
||||
int sy = (py / 2 + 10);
|
||||
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
||||
bgc = *temp;
|
||||
if (bgc > 0 && bgc != 1000) {
|
||||
px = opx;
|
||||
py = opy;
|
||||
pass = 0;
|
||||
}
|
||||
|
||||
// push npc
|
||||
if (pass == 1) {
|
||||
for (int i = 1; i <= _lastNpc; i++) {
|
||||
if (_npcInfo[i].hp > 0) {
|
||||
npx = _npcInfo[i].x;
|
||||
npy = _npcInfo[i].y;
|
||||
|
||||
opx = npx;
|
||||
opy = npy;
|
||||
|
||||
int xdif = _player.px - npx;
|
||||
int ydif = _player.py - npy;
|
||||
|
||||
if (_player.walkDir == 0) {
|
||||
if (ABS(xdif) <= 8 && ydif > 0 && ydif < 8)
|
||||
_npcInfo[i].y -= spd;
|
||||
} else if (_player.walkDir == 1) {
|
||||
if (ABS(xdif) <= 8 && ydif < 0 && ydif > -8)
|
||||
_npcInfo[i].y += spd;
|
||||
} else if (_player.walkDir == 2) {
|
||||
if (ABS(ydif) <= 8 && xdif > 0 && xdif < 8)
|
||||
_npcInfo[i].x -= spd;
|
||||
} else if (_player.walkDir == 3) {
|
||||
if (ABS(ydif) <= 8 && xdif < 0 && xdif > -8)
|
||||
_npcInfo[i].x += spd;
|
||||
}
|
||||
|
||||
npx = _npcInfo[i].x;
|
||||
npy = _npcInfo[i].y;
|
||||
|
||||
sx = (int)(npx / 2 + 6);
|
||||
sy = (int)(npy / 2 + 10);
|
||||
temp = (uint32 *)_clipBg->getBasePtr(sx, sy);
|
||||
bgc = *temp;
|
||||
|
||||
if (bgc > 0) {
|
||||
_npcInfo[i].x = opx;
|
||||
_npcInfo[i].y = opy;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_player.opx = _player.px;
|
||||
_player.opy = _player.py;
|
||||
_player.px = px;
|
||||
_player.py = py;
|
||||
|
||||
if (_player.px != _player.opx || _player.py != _player.opy)
|
||||
_player.walkFrame += _animSpeed * _fpsr;
|
||||
if (_player.walkFrame >= 16)
|
||||
_player.walkFrame -= 16;
|
||||
|
||||
// walking over items to pickup :::
|
||||
int o = _objectMap[lx][ly];
|
||||
|
||||
if (o > -1) {
|
||||
// fsk
|
||||
if (_objectInfo[o].type == 2 && _player.inventory[kInvFlask] < 9) {
|
||||
_objectMap[lx][ly] = -1;
|
||||
|
||||
_player.inventory[kInvFlask]++;
|
||||
addFloatIcon(6, lx * 16, ly * 16);
|
||||
|
||||
_objectMapFull[_curMap][lx][ly] = 1;
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndPowerUp]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
}
|
||||
|
||||
if (_objectInfo[o].script == 7 && _player.inventory[kInvDoubleFlask] < 9) {
|
||||
_objectMap[lx][ly] = -1;
|
||||
|
||||
_player.inventory[kInvDoubleFlask]++;
|
||||
addFloatIcon(12, lx * 16, ly * 16);
|
||||
|
||||
_objectMapFull[_curMap][lx][ly] = 1;
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndPowerUp]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
}
|
||||
|
||||
if (_objectInfo[o].script == 9 && _player.inventory[kInvShock] < 9 && (_curMap == 41 && _scriptFlag[kScriptLightningBomb][1] == 0)) {
|
||||
_objectMap[lx][ly] = -1;
|
||||
|
||||
_player.inventory[kInvShock]++;
|
||||
addFloatIcon(17, lx * 16, ly * 16);
|
||||
|
||||
_objectMapFull[_curMap][lx][ly] = 1;
|
||||
if (_curMap == 41)
|
||||
_scriptFlag[kScriptLightningBomb][1] = 1;
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndPowerUp]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (_objectInfo[o].script == 9 && _player.inventory[kInvShock] < 9) {
|
||||
_objectMap[lx][ly] = -1;
|
||||
|
||||
_player.inventory[kInvShock]++;
|
||||
addFloatIcon(17, lx * 16, ly * 16);
|
||||
|
||||
_objectMapFull[_curMap][lx][ly] = 1;
|
||||
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndPowerUp]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::checkTrigger() {
|
||||
int npx = _player.px + 12;
|
||||
int npy = _player.py + 20;
|
||||
|
||||
int lx = (int)npx / 16;
|
||||
int ly = (int)npy / 16;
|
||||
|
||||
_canUseKey = false;
|
||||
|
||||
if (_triggerLoc[lx][ly] > -1)
|
||||
processTrigger(_triggerLoc[lx][ly]);
|
||||
}
|
||||
|
||||
void GriffonEngine::processTrigger(int trignum) {
|
||||
int trigtype = _triggers[trignum][0];
|
||||
|
||||
if (_roomLock)
|
||||
return;
|
||||
|
||||
// map jump------------------------------
|
||||
if (trigtype == 0) {
|
||||
int tx = _triggers[trignum][1];
|
||||
int ty = _triggers[trignum][2];
|
||||
int tmap = _triggers[trignum][3];
|
||||
int tjumpstyle = _triggers[trignum][4];
|
||||
|
||||
if (_roomLocks[tmap] > 0) {
|
||||
if (!_saidLocked)
|
||||
eventText("Locked");
|
||||
_saidLocked = true;
|
||||
_canUseKey = true;
|
||||
_lockType = _roomLocks[tmap];
|
||||
_roomToUnlock = tmap;
|
||||
return;
|
||||
}
|
||||
|
||||
if (tmap == 1) {
|
||||
if (!_saidJammed)
|
||||
eventText("Door Jammed!");
|
||||
_saidJammed = true;
|
||||
return;
|
||||
}
|
||||
|
||||
_saidLocked = false;
|
||||
_saidJammed = false;
|
||||
|
||||
// loc-sxy+oldmaploc
|
||||
if (tjumpstyle == 0) {
|
||||
|
||||
int tsx = _triggers[trignum][5];
|
||||
int tsy = _triggers[trignum][6];
|
||||
|
||||
_player.px += (tx - tsx) * 16;
|
||||
_player.py += (ty - tsy) * 16;
|
||||
|
||||
// HACKFIX
|
||||
if (_player.px < 0)
|
||||
_player.px = 0;
|
||||
if (_player.py < 0)
|
||||
_player.py = 0;
|
||||
|
||||
if (tmap > 0) {
|
||||
if (config.effects) {
|
||||
int snd = playSound(_sfx[kSndDoor]);
|
||||
setChannelVolume(snd, config.effectsVol);
|
||||
}
|
||||
|
||||
loadMap(tmap);
|
||||
swash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < kMaxFloat; i++) {
|
||||
_floatText[i].framesLeft = 0;
|
||||
_floatIcon[i].framesLeft = 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace Griffon
|
||||
2354
engines/griffon/logic.cpp
Normal file
2354
engines/griffon/logic.cpp
Normal file
File diff suppressed because it is too large
Load Diff
172
engines/griffon/metaengine.cpp
Normal file
172
engines/griffon/metaengine.cpp
Normal file
@@ -0,0 +1,172 @@
|
||||
/* 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 "base/plugins.h"
|
||||
#include "common/config-manager.h"
|
||||
#include "common/translation.h"
|
||||
#include "engines/advancedDetector.h"
|
||||
|
||||
#include "backends/keymapper/action.h"
|
||||
#include "backends/keymapper/keymap.h"
|
||||
#include "backends/keymapper/standard-actions.h"
|
||||
|
||||
#include "griffon/griffon.h"
|
||||
#include "griffon/detection.h"
|
||||
|
||||
#ifdef USE_TTS
|
||||
|
||||
static const ADExtraGuiOptionsMap optionsList[] = {
|
||||
{
|
||||
GAMEOPTION_TTS_NARRATOR,
|
||||
{
|
||||
_s("Enable Text to Speech"),
|
||||
_s("Use TTS to read the descriptions (if TTS is available)"),
|
||||
"tts_enabled",
|
||||
false,
|
||||
0,
|
||||
0
|
||||
}
|
||||
},
|
||||
AD_EXTRA_GUI_OPTIONS_TERMINATOR
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class GriffonMetaEngine: public AdvancedMetaEngine<ADGameDescription> {
|
||||
public:
|
||||
const char *getName() const override {
|
||||
return "griffon";
|
||||
}
|
||||
|
||||
#ifdef USE_TTS
|
||||
const ADExtraGuiOptionsMap *getAdvancedExtraGuiOptions() const override {
|
||||
return optionsList;
|
||||
}
|
||||
#endif
|
||||
|
||||
int getMaximumSaveSlot() const override {
|
||||
return ConfMan.getInt("autosave_period") ? 4 : 3;
|
||||
}
|
||||
|
||||
Common::Error createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const override;
|
||||
|
||||
int getAutosaveSlot() const override {
|
||||
return 4;
|
||||
}
|
||||
Common::String getSavegameFile(int saveGameIdx, const char *target = nullptr) const override;
|
||||
|
||||
Common::KeymapArray initKeymaps(const char *target) const override;
|
||||
|
||||
};
|
||||
|
||||
Common::String GriffonMetaEngine::getSavegameFile(int saveGameIdx, const char *target) const {
|
||||
if (saveGameIdx == kSavegameFilePattern) {
|
||||
// Pattern requested
|
||||
return Common::String::format("%s.s##", target == nullptr ? getName() : target);
|
||||
} else {
|
||||
// Specific filename requested
|
||||
return Common::String::format("%s.s%02d", target == nullptr ? getName() : target, saveGameIdx);
|
||||
}
|
||||
}
|
||||
|
||||
bool Griffon::GriffonEngine::hasFeature(EngineFeature f) const {
|
||||
return
|
||||
(f == kSupportsReturnToLauncher) ||
|
||||
(f == kSupportsLoadingDuringRuntime) ||
|
||||
(f == kSupportsSavingDuringRuntime);
|
||||
}
|
||||
|
||||
Common::Error GriffonMetaEngine::createInstance(OSystem *syst, Engine **engine, const ADGameDescription *desc) const {
|
||||
*engine = new Griffon::GriffonEngine(syst);
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
Common::KeymapArray GriffonMetaEngine::initKeymaps(const char *target) const {
|
||||
using namespace Common;
|
||||
|
||||
Keymap *engineKeyMap = new Keymap(Keymap::kKeymapTypeGame, "griffon", "The Griffon Legend");
|
||||
|
||||
Action *act;
|
||||
|
||||
act = new Action(kStandardActionSkip, _("Menu / Skip"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonMenu);
|
||||
act->addDefaultInputMapping("ESCAPE");
|
||||
act->addDefaultInputMapping("JOY_Y");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
act = new Action("RETURN", _("Confirm"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonConfirm);
|
||||
act->addDefaultInputMapping("RETURN");
|
||||
act->addDefaultInputMapping("JOY_X");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
act = new Action(kStandardActionMoveUp, _("Up"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonUp);
|
||||
act->addDefaultInputMapping("UP");
|
||||
act->addDefaultInputMapping("JOY_UP");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
act = new Action(kStandardActionMoveDown, _("Down"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonDown);
|
||||
act->addDefaultInputMapping("DOWN");
|
||||
act->addDefaultInputMapping("JOY_DOWN");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
act = new Action(kStandardActionMoveLeft, _("Left"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonLeft);
|
||||
act->addDefaultInputMapping("LEFT");
|
||||
act->addDefaultInputMapping("JOY_LEFT");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
act = new Action(kStandardActionMoveRight, _("Right"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonRight);
|
||||
act->addDefaultInputMapping("RIGHT");
|
||||
act->addDefaultInputMapping("JOY_RIGHT");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
act = new Action("ATTACK", _("Attack"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonAttack);
|
||||
act->addDefaultInputMapping("LCTRL");
|
||||
act->addDefaultInputMapping("RCTRL");
|
||||
act->addDefaultInputMapping("JOY_A");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
act = new Action("INVENTORY", _("Inventory"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonInventory);
|
||||
act->addDefaultInputMapping("LALT");
|
||||
act->addDefaultInputMapping("RALT");
|
||||
act->addDefaultInputMapping("JOY_B");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
act = new Action("SPEEDUP", _("Speed up cutscene"));
|
||||
act->setCustomEngineActionEvent(Griffon::kGriffonCutsceneSpeedUp);
|
||||
act->addDefaultInputMapping("LSHIFT");
|
||||
act->addDefaultInputMapping("RSHIFT");
|
||||
engineKeyMap->addAction(act);
|
||||
|
||||
return Keymap::arrayOf(engineKeyMap);
|
||||
}
|
||||
|
||||
#if PLUGIN_ENABLED_DYNAMIC(GRIFFON)
|
||||
REGISTER_PLUGIN_DYNAMIC(GRIFFON, PLUGIN_TYPE_ENGINE, GriffonMetaEngine);
|
||||
#else
|
||||
REGISTER_PLUGIN_STATIC(GRIFFON, PLUGIN_TYPE_ENGINE, GriffonMetaEngine);
|
||||
#endif
|
||||
31
engines/griffon/module.mk
Normal file
31
engines/griffon/module.mk
Normal file
@@ -0,0 +1,31 @@
|
||||
MODULE := engines/griffon
|
||||
|
||||
MODULE_OBJS := \
|
||||
combat.o \
|
||||
console.o \
|
||||
cutscenes.o \
|
||||
dialogs.o \
|
||||
draw.o \
|
||||
engine.o \
|
||||
gfx.o \
|
||||
griffon.o \
|
||||
input.o \
|
||||
logic.o \
|
||||
metaengine.o \
|
||||
resources.o \
|
||||
saveload.o \
|
||||
sound.o
|
||||
|
||||
MODULE_DIRS += \
|
||||
engines/griffon
|
||||
|
||||
# This module can be built as a plugin
|
||||
ifeq ($(ENABLE_GRIFFON), DYNAMIC_PLUGIN)
|
||||
PLUGIN := 1
|
||||
endif
|
||||
|
||||
# Include common rules
|
||||
include $(srcdir)/rules.mk
|
||||
|
||||
# Detection objects
|
||||
DETECT_OBJS += $(MODULE)/detection.o
|
||||
1189
engines/griffon/resources.cpp
Normal file
1189
engines/griffon/resources.cpp
Normal file
File diff suppressed because it is too large
Load Diff
258
engines/griffon/saveload.cpp
Normal file
258
engines/griffon/saveload.cpp
Normal file
@@ -0,0 +1,258 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*
|
||||
* 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 "griffon/griffon.h"
|
||||
|
||||
#include "common/savefile.h"
|
||||
#include "engines/metaengine.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
#define PRINT(A,B) \
|
||||
do { \
|
||||
char line[256]; \
|
||||
Common::sprintf_s(line, A "\n", B); \
|
||||
file->write(line, strlen(line)); \
|
||||
} while(0)
|
||||
|
||||
#define INPUT(A, B) \
|
||||
do { \
|
||||
Common::String line; \
|
||||
line = file->readLine(); \
|
||||
sscanf(line.c_str(), A, B); \
|
||||
} while(0)
|
||||
|
||||
Common::String GriffonEngine::getSaveStateName(int slot) const {
|
||||
return (_targetName + Common::String::format(".s%02d", slot));
|
||||
}
|
||||
|
||||
Common::Error GriffonEngine::loadGameState(int slot) {
|
||||
Common::Error result = Engine::loadGameState(slot);
|
||||
if (result.getCode() == Common::kNoError) {
|
||||
_saveSlot = slot;
|
||||
_gameMode = kGameModeLoadGame;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Common::Error GriffonEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
|
||||
Common::String saveDesc = Common::String::format("Level: %d Map: %d", _player.level, _curMap);
|
||||
return Engine::saveGameState(slot, isAutosave ? desc : saveDesc, isAutosave);
|
||||
}
|
||||
|
||||
Common::Error GriffonEngine::loadGameStream(Common::SeekableReadStream *file) {
|
||||
INPUT("%i", &_player.level);
|
||||
|
||||
if (_player.level > 0) {
|
||||
char temp[256];
|
||||
|
||||
INPUT("%i", &_secStart);
|
||||
INPUT("%s", temp);
|
||||
|
||||
INPUT("%f", &_player.px);
|
||||
INPUT("%f", &_player.py);
|
||||
INPUT("%f", &_player.opx);
|
||||
INPUT("%f", &_player.opy);
|
||||
INPUT("%i", &_player.walkDir);
|
||||
INPUT("%f", &_player.walkFrame);
|
||||
INPUT("%f", &_player.walkSpeed);
|
||||
INPUT("%f", &_player.attackFrame);
|
||||
INPUT("%f", &_player.attackSpeed);
|
||||
INPUT("%i", &_player.hp);
|
||||
INPUT("%i", &_player.maxHp);
|
||||
INPUT("%f", &_player.hpflash);
|
||||
INPUT("%i", &_player.level);
|
||||
INPUT("%i", &_player.maxLevel);
|
||||
INPUT("%i", &_player.sword);
|
||||
INPUT("%i", &_player.shield);
|
||||
INPUT("%i", &_player.armour);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
INPUT("%i", &_player.foundSpell[i]);
|
||||
INPUT("%f", &_player.spellCharge[i]);
|
||||
}
|
||||
for (int a = 0; a < 5; a++) {
|
||||
INPUT("%i", &_player.inventory[a]);
|
||||
}
|
||||
INPUT("%f", &_player.attackStrength);
|
||||
INPUT("%i", &_player.spellDamage);
|
||||
INPUT("%i", &_player.swordDamage);
|
||||
INPUT("%i", &_player.exp);
|
||||
INPUT("%i", &_player.nextLevel);
|
||||
for (int a = 0; a <= 99; a++) {
|
||||
for (int b = 0; b <= 9; b++) {
|
||||
INPUT("%i", &_scriptFlag[a][b]);
|
||||
}
|
||||
}
|
||||
INPUT("%i", &_curMap);
|
||||
|
||||
for (int a = 0; a <= 999; a++) {
|
||||
for (int b = 0; b <= 20; b++) {
|
||||
for (int c = 0; c <= 14; c++) {
|
||||
INPUT("%i", &_objectMapFull[a][b][c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a <= 200; a++) {
|
||||
INPUT("%i", &_roomLocks[a]);
|
||||
}
|
||||
|
||||
INPUT("%f", &_player.spellStrength);
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
return Common::kReadingFailed;
|
||||
}
|
||||
|
||||
/* fill PLAYERTYPE _playera; */
|
||||
int GriffonEngine::loadPlayer(int slotnum) {
|
||||
Common::String filename = getSaveStateName(slotnum);
|
||||
Common::InSaveFile *file;
|
||||
|
||||
_playera.level = 0;
|
||||
|
||||
if (!(file = _saveFileMan->openForLoading(filename)))
|
||||
return 0;
|
||||
|
||||
INPUT("%i", &_playera.level);
|
||||
|
||||
if (_playera.level > 0) {
|
||||
char temp[256];
|
||||
|
||||
INPUT("%i", &_asecstart);
|
||||
INPUT("%s", temp);
|
||||
|
||||
INPUT("%f", &_playera.px);
|
||||
INPUT("%f", &_playera.py);
|
||||
INPUT("%f", &_playera.opx);
|
||||
INPUT("%f", &_playera.opy);
|
||||
INPUT("%i", &_playera.walkDir);
|
||||
INPUT("%f", &_playera.walkFrame);
|
||||
INPUT("%f", &_playera.walkSpeed);
|
||||
INPUT("%f", &_playera.attackFrame);
|
||||
INPUT("%f", &_playera.attackSpeed);
|
||||
INPUT("%i", &_playera.hp);
|
||||
INPUT("%i", &_playera.maxHp);
|
||||
INPUT("%f", &_playera.hpflash);
|
||||
INPUT("%i", &_playera.level);
|
||||
INPUT("%i", &_playera.maxLevel);
|
||||
INPUT("%i", &_playera.sword);
|
||||
INPUT("%i", &_playera.shield);
|
||||
INPUT("%i", &_playera.armour);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
INPUT("%i", &_playera.foundSpell[i]);
|
||||
INPUT("%f", &_playera.spellCharge[i]);
|
||||
}
|
||||
for (int a = 0; a < 5; a++) {
|
||||
INPUT("%i", &_playera.inventory[a]);
|
||||
}
|
||||
INPUT("%f", &_playera.attackStrength);
|
||||
INPUT("%i", &_playera.spellDamage);
|
||||
INPUT("%i", &_playera.swordDamage);
|
||||
INPUT("%i", &_playera.exp);
|
||||
INPUT("%i", &_playera.nextLevel);
|
||||
|
||||
return 1; // success
|
||||
}
|
||||
|
||||
return 0; // fail
|
||||
}
|
||||
|
||||
Common::Error GriffonEngine::saveGameStream(Common::WriteStream *file, bool) {
|
||||
PRINT("%i", _player.level);
|
||||
|
||||
if (_player.level > 0) {
|
||||
PRINT("%i", (_secStart + _secsInGame));
|
||||
PRINT("%s", "a");
|
||||
|
||||
PRINT("%f", _player.px);
|
||||
PRINT("%f", _player.py);
|
||||
PRINT("%f", _player.opx);
|
||||
PRINT("%f", _player.opy);
|
||||
PRINT("%i", _player.walkDir);
|
||||
PRINT("%f", _player.walkFrame);
|
||||
PRINT("%f", _player.walkSpeed);
|
||||
PRINT("%f", _player.attackFrame);
|
||||
PRINT("%f", _player.attackSpeed);
|
||||
PRINT("%i", _player.hp);
|
||||
PRINT("%i", _player.maxHp);
|
||||
PRINT("%f", _player.hpflash);
|
||||
PRINT("%i", _player.level);
|
||||
PRINT("%i", _player.maxLevel);
|
||||
PRINT("%i", _player.sword);
|
||||
PRINT("%i", _player.shield);
|
||||
PRINT("%i", _player.armour);
|
||||
for (int i = 0; i < 5; i++) {
|
||||
PRINT("%i", _player.foundSpell[i]);
|
||||
PRINT("%f", _player.spellCharge[i]);
|
||||
}
|
||||
for (int a = 0; a < 5; a++) {
|
||||
PRINT("%i", _player.inventory[a]);
|
||||
}
|
||||
PRINT("%f", _player.attackStrength);
|
||||
PRINT("%i", _player.spellDamage);
|
||||
PRINT("%i", _player.swordDamage);
|
||||
PRINT("%i", _player.exp);
|
||||
PRINT("%i", _player.nextLevel);
|
||||
for (int a = 0; a <= 99; a++) {
|
||||
for (int b = 0; b <= 9; b++) {
|
||||
PRINT("%i", _scriptFlag[a][b]);
|
||||
}
|
||||
}
|
||||
PRINT("%i", _curMap);
|
||||
|
||||
for (int a = 0; a <= 999; a++) {
|
||||
for (int b = 0; b <= 20; b++) {
|
||||
for (int c = 0; c <= 14; c++) {
|
||||
PRINT("%i", _objectMapFull[a][b][c]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int a = 0; a <= 200; a++) {
|
||||
PRINT("%i", _roomLocks[a]);
|
||||
}
|
||||
|
||||
PRINT("%f", _player.spellStrength);
|
||||
}
|
||||
|
||||
drawView();
|
||||
|
||||
return Common::kNoError;
|
||||
}
|
||||
|
||||
} // end of namespace Griffon
|
||||
249
engines/griffon/sound.cpp
Normal file
249
engines/griffon/sound.cpp
Normal file
@@ -0,0 +1,249 @@
|
||||
/* 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/>.
|
||||
*
|
||||
*
|
||||
* 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 "audio/audiostream.h"
|
||||
#include "audio/decoders/vorbis.h"
|
||||
#include "common/memstream.h"
|
||||
|
||||
#include "common/file.h"
|
||||
#include "common/system.h"
|
||||
|
||||
#include "griffon/griffon.h"
|
||||
|
||||
namespace Griffon {
|
||||
|
||||
void GriffonEngine::setChannelVolume(int channel, int volume) {
|
||||
if (channel >= 0 && channel < kSoundHandles)
|
||||
_mixer->setChannelVolume(_handles[channel], volume);
|
||||
}
|
||||
|
||||
int GriffonEngine::getSoundHandle() {
|
||||
for (uint i = 0; i < kSoundHandles; i++) {
|
||||
if (!_mixer->isSoundHandleActive(_handles[i])) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int GriffonEngine::playSound(DataChunk *chunk, bool looped) {
|
||||
int ch = -1;
|
||||
|
||||
#ifdef USE_VORBIS
|
||||
if ((ch = getSoundHandle()) != -1) {
|
||||
Audio::SeekableAudioStream *audioStream = Audio::makeVorbisStream(new Common::MemoryReadStream(chunk->data, chunk->size), DisposeAfterUse::YES);
|
||||
|
||||
if (looped) {
|
||||
Audio::AudioStream *loopingStream = new Audio::LoopingAudioStream(audioStream, 0, DisposeAfterUse::YES);
|
||||
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handles[ch], loopingStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES, false, false);
|
||||
|
||||
} else {
|
||||
_mixer->playStream(Audio::Mixer::kSFXSoundType, &_handles[ch], audioStream, -1, Audio::Mixer::kMaxChannelVolume, 0, DisposeAfterUse::YES, false, false);
|
||||
}
|
||||
}
|
||||
#endif // USE_VORBIS
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
void GriffonEngine::pauseSoundChannel(int channel) {
|
||||
if (channel >= 0 && channel < kSoundHandles)
|
||||
_mixer->pauseHandle(_handles[channel], true);
|
||||
}
|
||||
|
||||
void GriffonEngine::haltSoundChannel(int channel) {
|
||||
if (channel == -1) {
|
||||
for (int i = 0; i < kSoundHandles; i++)
|
||||
_mixer->stopHandle(_handles[i]);
|
||||
} else if (channel >= 0 && channel < kSoundHandles) {
|
||||
_mixer->stopHandle(_handles[channel]);
|
||||
}
|
||||
}
|
||||
|
||||
void GriffonEngine::resumeSoundChannel(int channel) {
|
||||
if (channel >= 0 && channel < kSoundHandles)
|
||||
_mixer->pauseHandle(_handles[channel], false);
|
||||
}
|
||||
|
||||
bool GriffonEngine::isSoundChannelPlaying(int channel) {
|
||||
return (channel >= 0 && channel < kSoundHandles) ? _mixer->isSoundHandleActive(_handles[channel]) : false;
|
||||
}
|
||||
|
||||
DataChunk *cacheSound(const char *name) {
|
||||
Common::File file;
|
||||
DataChunk *res = new DataChunk;
|
||||
|
||||
file.open(name);
|
||||
if (!file.isOpen())
|
||||
error("Cannot open file %s", name);
|
||||
|
||||
res->size = file.size();
|
||||
res->data = (byte *)malloc(res->size);
|
||||
|
||||
file.read(res->data, res->size);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void GriffonEngine::setupAudio() {
|
||||
const char *stri = "Loading...";
|
||||
drawString(_videoBuffer, stri, 160 - 4 * strlen(stri), 116, 0);
|
||||
|
||||
Graphics::ManagedSurface *loadimg = loadImage("art/load.bmp", true);
|
||||
|
||||
rcSrc.left = 0;
|
||||
rcSrc.top = 0;
|
||||
rcSrc.setWidth(88);
|
||||
rcSrc.setHeight(32);
|
||||
|
||||
rcDest.left = 160 - 44;
|
||||
rcDest.top = 116 + 12;
|
||||
|
||||
loadimg->blendBlitTo(*_videoBuffer, rcDest.left, rcDest.top, Graphics::FLIP_NONE, &rcSrc, MS_ARGB(160, 255, 255, 255));
|
||||
|
||||
g_system->copyRectToScreen(_videoBuffer->getPixels(), _videoBuffer->pitch, 0, 0, _videoBuffer->w, _videoBuffer->h);
|
||||
g_system->updateScreen();
|
||||
|
||||
rcDest.left = 160 - 44 + 7;
|
||||
rcDest.top = 116 + 12 + 12;
|
||||
rcDest.setHeight(8);
|
||||
|
||||
_musicBoss = cacheSound("music/boss.ogg");
|
||||
drawProgress(1, 21);
|
||||
_musicGardens1 = cacheSound("music/gardens.ogg");
|
||||
drawProgress(2, 21);
|
||||
_musicGardens2 = cacheSound("music/gardens2.ogg");
|
||||
drawProgress(3, 21);
|
||||
_musicGardens3 = cacheSound("music/gardens3.ogg");
|
||||
drawProgress(4, 21);
|
||||
_musicGardens4 = cacheSound("music/gardens4.ogg");
|
||||
drawProgress(5, 21);
|
||||
_musicEndOfGame = cacheSound("music/endofgame.ogg");
|
||||
drawProgress(6, 21);
|
||||
_musicMenu = cacheSound("music/menu.ogg");
|
||||
drawProgress(7, 21);
|
||||
|
||||
_sfx[kSndBite] = cacheSound("sfx/bite.ogg");
|
||||
drawProgress(8, 21);
|
||||
_sfx[kSndCrystal] = cacheSound("sfx/crystal.ogg");
|
||||
drawProgress(9, 21);
|
||||
_sfx[kSndDoor] = cacheSound("sfx/door.ogg");
|
||||
drawProgress(10, 21);
|
||||
_sfx[kSndEnemyHit] = cacheSound("sfx/enemyhit.ogg");
|
||||
drawProgress(11, 21);
|
||||
_sfx[kSndIce] = cacheSound("sfx/ice.ogg");
|
||||
drawProgress(12, 21);
|
||||
_sfx[kSndLever] = cacheSound("sfx/lever.ogg");
|
||||
drawProgress(13, 21);
|
||||
_sfx[kSndLightning] = cacheSound("sfx/lightning.ogg");
|
||||
drawProgress(14, 21);
|
||||
_sfx[kSndMetalHit] = cacheSound("sfx/metalhit.ogg");
|
||||
drawProgress(15, 21);
|
||||
_sfx[kSndPowerUp] = cacheSound("sfx/powerup.ogg");
|
||||
drawProgress(16, 21);
|
||||
_sfx[kSndRocks] = cacheSound("sfx/rocks.ogg");
|
||||
drawProgress(17, 21);
|
||||
_sfx[kSndSwordHit] = cacheSound("sfx/swordhit.ogg");
|
||||
drawProgress(18, 21);
|
||||
_sfx[kSndThrow] = cacheSound("sfx/throw.ogg");
|
||||
drawProgress(19, 21);
|
||||
_sfx[kSndChest] = cacheSound("sfx/chest.ogg");
|
||||
drawProgress(20, 21);
|
||||
_sfx[kSndFire] = cacheSound("sfx/fire.ogg");
|
||||
drawProgress(21, 21);
|
||||
_sfx[kSndBeep] = cacheSound("sfx/beep.ogg");
|
||||
}
|
||||
|
||||
void GriffonEngine::updateMusic() {
|
||||
static int loopseta = 0;
|
||||
|
||||
DataChunk *iplaysound = nullptr;
|
||||
|
||||
if (config.music) {
|
||||
// if(_curmap > 5 && _curmap < 42) iplaysound = macademy;
|
||||
// if(_curmap > 47) iplaysound = _mgardens;
|
||||
iplaysound = _musicGardens1;
|
||||
if (_roomLock)
|
||||
iplaysound = _musicBoss;
|
||||
|
||||
if (iplaysound == _musicBoss && _playingBoss)
|
||||
iplaysound = nullptr;
|
||||
if (iplaysound == _musicGardens1 && _playingGardens)
|
||||
iplaysound = nullptr;
|
||||
|
||||
if (iplaysound != nullptr) {
|
||||
haltSoundChannel(_musicChannel);
|
||||
|
||||
_playingBoss = (iplaysound == _musicBoss);
|
||||
_playingGardens = (iplaysound == _musicGardens1);
|
||||
|
||||
_musicChannel = playSound(iplaysound, true);
|
||||
setChannelVolume(_musicChannel, config.musicVol);
|
||||
} else {
|
||||
if (!isSoundChannelPlaying(_musicChannel)) {
|
||||
loopseta += 1;
|
||||
if (loopseta == 4)
|
||||
loopseta = 0;
|
||||
|
||||
if (_playingGardens) {
|
||||
haltSoundChannel(_musicChannel);
|
||||
if (_playingGardens) {
|
||||
switch (loopseta) {
|
||||
case 0:
|
||||
playSound(_musicGardens1);
|
||||
break;
|
||||
case 1:
|
||||
playSound(_musicGardens2);
|
||||
break;
|
||||
case 2:
|
||||
playSound(_musicGardens3);
|
||||
break;
|
||||
case 3:
|
||||
playSound(_musicGardens4);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
setChannelVolume(_musicChannel, config.musicVol);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
} // end of namespace Griffon
|
||||
Reference in New Issue
Block a user