ADL: Implement hires5 time machine animation
This commit is contained in:
parent
25614c60c8
commit
2e00dfd47c
3 changed files with 80 additions and 7 deletions
|
@ -471,7 +471,7 @@ void AdlEngine::bell(uint count) const {
|
|||
playTones(tones, false);
|
||||
}
|
||||
|
||||
void AdlEngine::playTones(const Tones &tones, bool isMusic) const {
|
||||
bool AdlEngine::playTones(const Tones &tones, bool isMusic, bool allowSkip) const {
|
||||
Audio::SoundHandle handle;
|
||||
Audio::AudioStream *stream = new Sound(tones);
|
||||
|
||||
|
@ -480,8 +480,17 @@ void AdlEngine::playTones(const Tones &tones, bool isMusic) const {
|
|||
while (!g_engine->shouldQuit() && g_system->getMixer()->isSoundHandleActive(handle)) {
|
||||
Common::Event event;
|
||||
pollEvent(event);
|
||||
|
||||
if (allowSkip && event.type == Common::EVENT_KEYDOWN) {
|
||||
// FIXME: Preserve this event
|
||||
g_system->getMixer()->stopHandle(handle);
|
||||
return true;
|
||||
}
|
||||
|
||||
g_system->delayMillis(16);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
const Region &AdlEngine::getRegion(uint i) const {
|
||||
|
@ -904,7 +913,7 @@ byte AdlEngine::convertKey(uint16 ascii) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
Common::String AdlEngine::getLine() const {
|
||||
Common::String AdlEngine::getLine() {
|
||||
// Original engine uses a global here, which isn't reset between
|
||||
// calls and may not match actual mode
|
||||
bool textMode = false;
|
||||
|
|
|
@ -252,6 +252,7 @@ protected:
|
|||
virtual Common::String getItemDescription(const Item &item) const;
|
||||
void delay(uint32 ms) const;
|
||||
|
||||
virtual Common::String getLine();
|
||||
Common::String inputString(byte prompt = 0) const;
|
||||
byte inputKey(bool showCursor = true) const;
|
||||
void getInput(uint &verb, uint &noun);
|
||||
|
@ -312,7 +313,7 @@ protected:
|
|||
|
||||
// Sound
|
||||
void bell(uint count = 1) const;
|
||||
void playTones(const Tones &tones, bool isMusic) const;
|
||||
bool playTones(const Tones &tones, bool isMusic, bool allowSkip = false) const;
|
||||
|
||||
// Game state functions
|
||||
const Region &getRegion(uint i) const;
|
||||
|
@ -413,7 +414,6 @@ private:
|
|||
|
||||
// Text input
|
||||
byte convertKey(uint16 ascii) const;
|
||||
Common::String getLine() const;
|
||||
Common::String getWord(const Common::String &line, uint &index) const;
|
||||
|
||||
Console *_console;
|
||||
|
|
|
@ -38,7 +38,8 @@ namespace Adl {
|
|||
class HiRes5Engine : public AdlEngine_v4 {
|
||||
public:
|
||||
HiRes5Engine(OSystem *syst, const AdlGameDescription *gd) :
|
||||
AdlEngine_v4(syst, gd) { }
|
||||
AdlEngine_v4(syst, gd),
|
||||
_doAnimation(false) { }
|
||||
|
||||
private:
|
||||
// AdlEngine
|
||||
|
@ -48,22 +49,27 @@ private:
|
|||
void initGameState();
|
||||
void applyRegionWorkarounds();
|
||||
void applyRoomWorkarounds(byte roomNr);
|
||||
Common::String getLine();
|
||||
|
||||
// AdlEngine_v4
|
||||
bool isInventoryFull();
|
||||
|
||||
void loadSong(Common::ReadStream &stream);
|
||||
void drawLight(uint index, byte color) const;
|
||||
void animateLights() const;
|
||||
|
||||
int o_checkItemTimeLimits(ScriptEnv &e);
|
||||
int o_startAnimation(ScriptEnv &e);
|
||||
int o_winGame(ScriptEnv &e);
|
||||
|
||||
static const uint kClock = 1022727; // Apple II CPU clock rate
|
||||
static const uint kRegions = 41;
|
||||
static const uint kItems = 69;
|
||||
|
||||
Common::Array<byte> _itemTimeLimits;
|
||||
Common::String _itemTimeLimitMsg;
|
||||
Tones _song;
|
||||
bool _doAnimation;
|
||||
|
||||
struct {
|
||||
Common::String itemTimeLimit;
|
||||
|
@ -71,6 +77,63 @@ private:
|
|||
} _gameStrings;
|
||||
};
|
||||
|
||||
Common::String HiRes5Engine::getLine() {
|
||||
if (_doAnimation) {
|
||||
animateLights();
|
||||
_doAnimation = false;
|
||||
}
|
||||
|
||||
return AdlEngine_v4::getLine();
|
||||
}
|
||||
|
||||
void HiRes5Engine::drawLight(uint index, byte color) const {
|
||||
const byte xCoord[5] = { 189, 161, 133, 105, 77 };
|
||||
const byte yCoord = 72;
|
||||
|
||||
assert(index < 5);
|
||||
|
||||
for (int yDelta = 0; yDelta < 4; ++yDelta)
|
||||
for (int xDelta = 0; xDelta < 7; ++xDelta)
|
||||
_display->putPixel(Common::Point(xCoord[index] + xDelta, yCoord + yDelta), color);
|
||||
|
||||
_display->updateHiResScreen();
|
||||
}
|
||||
|
||||
void HiRes5Engine::animateLights() const {
|
||||
int index;
|
||||
byte color = 0x2a;
|
||||
|
||||
for (index = 4; index >= 0; --index)
|
||||
drawLight(index, color);
|
||||
|
||||
index = 4;
|
||||
|
||||
while (!g_engine->shouldQuit()) {
|
||||
drawLight(index, color ^ 0x7f);
|
||||
|
||||
// There's a delay here in the original engine. We leave it out as
|
||||
// we're already slower than the original without any delay.
|
||||
|
||||
const uint kLoopCycles = 25;
|
||||
const byte period = (index + 1) << 4;
|
||||
const double freq = kClock / 2.0 / (period * kLoopCycles);
|
||||
const double len = 128 * period * kLoopCycles * 1000 / (double)kClock;
|
||||
|
||||
Tones tone;
|
||||
tone.push_back(Tone(freq, len));
|
||||
|
||||
if (playTones(tone, false, true))
|
||||
break;
|
||||
|
||||
drawLight(index, color ^ 0xff);
|
||||
|
||||
if (--index < 0) {
|
||||
index = 4;
|
||||
color ^= 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typedef Common::Functor1Mem<ScriptEnv &, int, HiRes5Engine> OpcodeH5;
|
||||
#define SetOpcodeTable(x) table = &x;
|
||||
#define Opcode(x) table->push_back(new OpcodeH5(this, &HiRes5Engine::x))
|
||||
|
@ -173,7 +236,6 @@ void HiRes5Engine::loadSong(Common::ReadStream &stream) {
|
|||
if (stream.err() || stream.eos())
|
||||
error("Error loading song");
|
||||
|
||||
const uint kClock = 1022727; // Apple II CPU clock rate
|
||||
const uint kLoopCycles = 20; // Delay loop cycles
|
||||
|
||||
double freq = 0.0;
|
||||
|
@ -219,7 +281,7 @@ int HiRes5Engine::o_checkItemTimeLimits(ScriptEnv &e) {
|
|||
int HiRes5Engine::o_startAnimation(ScriptEnv &e) {
|
||||
OP_DEBUG_0("\tSTART_ANIMATION()");
|
||||
|
||||
// TODO: sets a flag that triggers an animation
|
||||
_doAnimation = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -341,6 +403,8 @@ void HiRes5Engine::initGameState() {
|
|||
|
||||
loadRegion(1);
|
||||
_state.room = 5;
|
||||
|
||||
_doAnimation = false;
|
||||
}
|
||||
|
||||
void HiRes5Engine::applyRegionWorkarounds() {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue