2013-06-18 17:52:25 +02:00
|
|
|
/* ScummVM - Graphic Adventure Engine
|
|
|
|
*
|
|
|
|
* ScummVM is the legal property of its developers, whose names
|
|
|
|
* are too numerous to list here. Please refer to the COPYRIGHT
|
|
|
|
* file distributed with this source distribution.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This code is based on the original source code of Lord Avalot d'Argent version 1.3.
|
|
|
|
* Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.
|
|
|
|
*/
|
|
|
|
|
2013-06-20 14:08:58 +02:00
|
|
|
#include "avalanche/avalanche.h"
|
|
|
|
|
2013-06-18 17:52:25 +02:00
|
|
|
#include "common/system.h"
|
|
|
|
#include "common/random.h"
|
|
|
|
#include "common/error.h"
|
|
|
|
#include "common/events.h"
|
|
|
|
#include "common/debug-channels.h"
|
|
|
|
#include "common/config-manager.h"
|
|
|
|
#include "common/textconsole.h"
|
2013-08-19 18:18:02 +02:00
|
|
|
#include "common/savefile.h"
|
|
|
|
|
2013-06-18 17:52:25 +02:00
|
|
|
#include "engines/util.h"
|
|
|
|
|
2013-08-19 21:14:21 +02:00
|
|
|
#include "gui/saveload.h"
|
2013-08-20 21:26:23 +02:00
|
|
|
#include "graphics/thumbnail.h"
|
2013-07-11 18:02:15 +02:00
|
|
|
|
|
|
|
|
2013-06-18 17:52:25 +02:00
|
|
|
namespace Avalanche {
|
|
|
|
|
2013-07-24 17:12:46 +02:00
|
|
|
AvalancheEngine *AvalancheEngine::s_Engine = 0;
|
|
|
|
|
|
|
|
AvalancheEngine::AvalancheEngine(OSystem *syst, const AvalancheGameDescription *gd) : Engine(syst), _gameDescription(gd) {
|
|
|
|
_system = syst;
|
2013-07-24 17:52:57 +02:00
|
|
|
s_Engine = this;
|
2013-07-24 17:12:46 +02:00
|
|
|
_console = new AvalancheConsole(this);
|
|
|
|
|
|
|
|
_rnd = new Common::RandomSource("avalanche");
|
|
|
|
_rnd->setSeed(42);
|
2013-07-24 17:52:57 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
AvalancheEngine::~AvalancheEngine() {
|
|
|
|
delete _console;
|
|
|
|
delete _rnd;
|
|
|
|
|
|
|
|
delete _graphics;
|
2013-07-27 21:36:07 +02:00
|
|
|
delete _parser;
|
2013-07-24 18:12:16 +02:00
|
|
|
|
|
|
|
delete _avalot;
|
2013-07-24 18:25:07 +02:00
|
|
|
delete _gyro;
|
2013-07-24 18:45:10 +02:00
|
|
|
delete _enhanced;
|
2013-07-24 18:47:33 +02:00
|
|
|
delete _logger;
|
2013-07-24 18:50:13 +02:00
|
|
|
delete _pingo;
|
2013-07-24 19:43:10 +02:00
|
|
|
delete _scrolls;
|
|
|
|
delete _visa;
|
|
|
|
delete _lucerna;
|
|
|
|
delete _enid;
|
|
|
|
delete _celer;
|
|
|
|
delete _sequence;
|
2013-07-24 18:50:13 +02:00
|
|
|
delete _timeout;
|
2013-07-24 19:43:10 +02:00
|
|
|
delete _trip;
|
|
|
|
delete _acci;
|
|
|
|
delete _dropdown;
|
|
|
|
delete _closing;
|
2013-07-24 17:52:57 +02:00
|
|
|
}
|
2013-07-24 17:12:46 +02:00
|
|
|
|
2013-07-24 17:52:57 +02:00
|
|
|
Common::ErrorCode AvalancheEngine::initialize() {
|
|
|
|
_graphics = new Graphics(this);
|
2013-07-27 21:36:07 +02:00
|
|
|
_parser = new Parser(this);
|
2013-07-24 17:12:46 +02:00
|
|
|
|
2013-07-24 18:12:16 +02:00
|
|
|
_avalot = new Avalot(this);
|
2013-07-24 18:25:07 +02:00
|
|
|
_gyro = new Gyro(this);
|
2013-07-24 18:45:10 +02:00
|
|
|
_enhanced = new Enhanced(this);
|
2013-07-24 18:47:33 +02:00
|
|
|
_logger = new Logger(this);
|
2013-07-24 18:50:13 +02:00
|
|
|
_pingo = new Pingo(this);
|
2013-07-24 19:43:10 +02:00
|
|
|
_scrolls = new Scrolls(this);
|
|
|
|
_visa = new Visa(this);
|
|
|
|
_lucerna = new Lucerna(this);
|
|
|
|
_enid = new Enid(this);
|
|
|
|
_celer = new Celer(this);
|
|
|
|
_sequence = new Sequence(this);
|
2013-07-24 18:42:41 +02:00
|
|
|
_timeout = new Timeout(this);
|
2013-07-24 19:43:10 +02:00
|
|
|
_trip = new Trip(this);
|
|
|
|
_acci = new Acci(this);
|
|
|
|
_dropdown = new Dropdown(this);
|
|
|
|
_closing = new Closing(this);
|
2013-07-24 16:43:34 +02:00
|
|
|
|
2013-07-24 17:52:57 +02:00
|
|
|
_graphics->init();
|
|
|
|
|
2013-07-24 19:43:10 +02:00
|
|
|
_scrolls->init();
|
|
|
|
_lucerna->init();
|
|
|
|
_acci->init();
|
2013-09-03 17:45:11 +02:00
|
|
|
_parser->init();
|
2013-07-24 17:52:57 +02:00
|
|
|
|
|
|
|
return Common::kNoError;
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
|
|
|
|
2013-07-24 17:52:57 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
GUI::Debugger *AvalancheEngine::getDebugger() {
|
|
|
|
return _console;
|
|
|
|
}
|
|
|
|
|
|
|
|
Common::Platform AvalancheEngine::getPlatform() const {
|
|
|
|
return _platform;
|
|
|
|
}
|
|
|
|
|
2013-07-24 18:14:10 +02:00
|
|
|
|
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
bool AvalancheEngine::hasFeature(EngineFeature f) const {
|
2013-08-18 15:08:32 +02:00
|
|
|
return (f == kSupportsSavingDuringRuntime) || (f == kSupportsLoadingDuringRuntime);
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
const char *AvalancheEngine::getCopyrightString() const {
|
|
|
|
return "Copyright (c) 1994-1995 Mike, Mark and Thomas Thurman.";
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-08-19 18:18:02 +02:00
|
|
|
void AvalancheEngine::synchronize(Common::Serializer &sz) {
|
|
|
|
//blockwrite(f, dna, sizeof(dna));
|
|
|
|
sz.syncAsByte(_gyro->dna.rw);
|
|
|
|
sz.syncAsByte(_gyro->dna.carrying);
|
|
|
|
for (byte i = 0; i < numobjs; i++)
|
|
|
|
sz.syncAsByte(_gyro->dna.obj[i]);
|
|
|
|
sz.syncAsSint16LE(_gyro->dna.score);
|
|
|
|
sz.syncAsSint32LE(_gyro->dna.pence);
|
|
|
|
sz.syncAsByte(_gyro->dna.room);
|
|
|
|
sz.syncAsByte(_gyro->dna.wearing);
|
|
|
|
sz.syncAsByte(_gyro->dna.swore);
|
|
|
|
sz.syncAsByte(_gyro->dna.saves);
|
|
|
|
sz.syncBytes(_gyro->dna.rooms, 100);
|
|
|
|
sz.syncAsByte(_gyro->dna.alcohol);
|
|
|
|
sz.syncAsByte(_gyro->dna.playednim);
|
|
|
|
sz.syncAsByte(_gyro->dna.wonnim);
|
|
|
|
sz.syncAsByte(_gyro->dna.winestate);
|
|
|
|
sz.syncAsByte(_gyro->dna.cwytalot_gone);
|
|
|
|
sz.syncAsByte(_gyro->dna.pass_num);
|
|
|
|
sz.syncAsByte(_gyro->dna.ayles_is_awake);
|
|
|
|
sz.syncAsByte(_gyro->dna.drawbridge_open);
|
|
|
|
sz.syncAsByte(_gyro->dna.avaricius_talk);
|
|
|
|
sz.syncAsByte(_gyro->dna.bought_onion);
|
|
|
|
sz.syncAsByte(_gyro->dna.rotten_onion);
|
|
|
|
sz.syncAsByte(_gyro->dna.onion_in_vinegar);
|
|
|
|
sz.syncAsByte(_gyro->dna.given2spludwick);
|
|
|
|
sz.syncAsByte(_gyro->dna.brummie_stairs);
|
|
|
|
sz.syncAsByte(_gyro->dna.cardiff_things);
|
|
|
|
sz.syncAsByte(_gyro->dna.cwytalot_in_herts);
|
|
|
|
sz.syncAsByte(_gyro->dna.avvy_is_awake);
|
|
|
|
sz.syncAsByte(_gyro->dna.avvy_in_bed);
|
|
|
|
sz.syncAsByte(_gyro->dna.user_moves_avvy);
|
|
|
|
sz.syncAsByte(_gyro->dna.dogfoodpos);
|
|
|
|
sz.syncAsByte(_gyro->dna.givenbadgetoiby);
|
|
|
|
sz.syncAsByte(_gyro->dna.friar_will_tie_you_up);
|
|
|
|
sz.syncAsByte(_gyro->dna.tied_up);
|
|
|
|
sz.syncAsByte(_gyro->dna.box_contents);
|
|
|
|
sz.syncAsByte(_gyro->dna.talked_to_crapulus);
|
|
|
|
sz.syncAsByte(_gyro->dna.jacques_awake);
|
|
|
|
sz.syncAsByte(_gyro->dna.ringing_bells);
|
|
|
|
sz.syncAsByte(_gyro->dna.standing_on_dais);
|
|
|
|
sz.syncAsByte(_gyro->dna.taken_pen);
|
|
|
|
sz.syncAsByte(_gyro->dna.arrow_triggered);
|
|
|
|
sz.syncAsByte(_gyro->dna.arrow_in_the_door);
|
|
|
|
|
|
|
|
if (sz.isSaving()) {
|
|
|
|
uint16 like2drinkSize = _gyro->dna.like2drink.size();
|
|
|
|
sz.syncAsUint16LE(like2drinkSize);
|
|
|
|
for (uint16 i = 0; i < like2drinkSize; i++) {
|
|
|
|
char actChr = _gyro->dna.like2drink[i];
|
|
|
|
sz.syncAsByte(actChr);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 favourite_songSize = _gyro->dna.favourite_song.size();
|
|
|
|
sz.syncAsUint16LE(favourite_songSize);
|
|
|
|
for (uint16 i = 0; i < favourite_songSize; i++) {
|
|
|
|
char actChr = _gyro->dna.favourite_song[i];
|
|
|
|
sz.syncAsByte(actChr);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 worst_place_on_earthSize = _gyro->dna.worst_place_on_earth.size();
|
|
|
|
sz.syncAsUint16LE(worst_place_on_earthSize);
|
|
|
|
for (uint16 i = 0; i < worst_place_on_earthSize; i++) {
|
|
|
|
char actChr = _gyro->dna.worst_place_on_earth[i];
|
|
|
|
sz.syncAsByte(actChr);
|
|
|
|
}
|
|
|
|
|
|
|
|
uint16 spare_eveningSize = _gyro->dna.spare_evening.size();
|
|
|
|
sz.syncAsUint16LE(spare_eveningSize);
|
|
|
|
for (uint16 i = 0; i < spare_eveningSize; i++) {
|
|
|
|
char actChr = _gyro->dna.spare_evening[i];
|
|
|
|
sz.syncAsByte(actChr);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (!_gyro->dna.like2drink.empty())
|
|
|
|
_gyro->dna.like2drink.clear();
|
|
|
|
uint16 like2drinkSize;
|
|
|
|
sz.syncAsUint16LE(like2drinkSize);
|
|
|
|
for (uint16 i = 0; i < like2drinkSize; i++) {
|
|
|
|
char actChr;
|
|
|
|
sz.syncAsByte(actChr);
|
|
|
|
_gyro->dna.like2drink += actChr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_gyro->dna.favourite_song.empty())
|
|
|
|
_gyro->dna.favourite_song.clear();
|
|
|
|
uint16 favourite_songSize;
|
|
|
|
sz.syncAsUint16LE(favourite_songSize);
|
|
|
|
for (uint16 i = 0; i < favourite_songSize; i++) {
|
|
|
|
char actChr;
|
|
|
|
sz.syncAsByte(actChr);
|
|
|
|
_gyro->dna.favourite_song += actChr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_gyro->dna.worst_place_on_earth.empty())
|
|
|
|
_gyro->dna.worst_place_on_earth.clear();
|
|
|
|
uint16 worst_place_on_earthSize;
|
|
|
|
sz.syncAsUint16LE(worst_place_on_earthSize);
|
|
|
|
for (uint16 i = 0; i < worst_place_on_earthSize; i++) {
|
|
|
|
char actChr;
|
|
|
|
sz.syncAsByte(actChr);
|
|
|
|
_gyro->dna.worst_place_on_earth += actChr;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!_gyro->dna.spare_evening.empty())
|
|
|
|
_gyro->dna.spare_evening.clear();
|
|
|
|
uint16 spare_eveningSize;
|
|
|
|
sz.syncAsUint16LE(spare_eveningSize);
|
|
|
|
for (uint16 i = 0; i < spare_eveningSize; i++) {
|
|
|
|
char actChr;
|
|
|
|
sz.syncAsByte(actChr);
|
|
|
|
_gyro->dna.spare_evening += actChr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
sz.syncAsSint32LE(_gyro->dna.total_time);
|
|
|
|
sz.syncAsByte(_gyro->dna.jumpstatus);
|
|
|
|
sz.syncAsByte(_gyro->dna.mushroom_growing);
|
|
|
|
sz.syncAsByte(_gyro->dna.spludwicks_here);
|
|
|
|
sz.syncAsByte(_gyro->dna.last_room);
|
|
|
|
sz.syncAsByte(_gyro->dna.last_room_not_map);
|
|
|
|
sz.syncAsByte(_gyro->dna.crapulus_will_tell);
|
|
|
|
sz.syncAsByte(_gyro->dna.enter_catacombs_from_lusties_room);
|
|
|
|
sz.syncAsByte(_gyro->dna.teetotal);
|
|
|
|
sz.syncAsByte(_gyro->dna.malagauche);
|
|
|
|
sz.syncAsByte(_gyro->dna.drinking);
|
|
|
|
sz.syncAsByte(_gyro->dna.entered_lusties_room_as_monk);
|
|
|
|
sz.syncAsByte(_gyro->dna.cat_x);
|
|
|
|
sz.syncAsByte(_gyro->dna.cat_y);
|
|
|
|
sz.syncAsByte(_gyro->dna.avvys_in_the_cupboard);
|
|
|
|
sz.syncAsByte(_gyro->dna.geida_follows);
|
|
|
|
sz.syncAsByte(_gyro->dna.geida_spin);
|
|
|
|
sz.syncAsByte(_gyro->dna.geida_time);
|
|
|
|
sz.syncAsByte(_gyro->dna.nextbell);
|
|
|
|
sz.syncAsByte(_gyro->dna.geida_given_potion);
|
|
|
|
sz.syncAsByte(_gyro->dna.lustie_is_asleep);
|
|
|
|
sz.syncAsByte(_gyro->dna.flip_to_where);
|
|
|
|
sz.syncAsByte(_gyro->dna.flip_to_ped);
|
|
|
|
sz.syncAsByte(_gyro->dna.been_tied_up);
|
|
|
|
sz.syncAsByte(_gyro->dna.sitting_in_pub);
|
|
|
|
sz.syncAsByte(_gyro->dna.spurge_talk);
|
|
|
|
sz.syncAsByte(_gyro->dna.met_avaroid);
|
|
|
|
sz.syncAsByte(_gyro->dna.taken_mushroom);
|
|
|
|
sz.syncAsByte(_gyro->dna.given_pen_to_ayles);
|
|
|
|
sz.syncAsByte(_gyro->dna.asked_dogfood_about_nim);
|
|
|
|
|
|
|
|
|
|
|
|
//for (byte groi = 0; groi < numtr; groi ++) {
|
|
|
|
// if (tr[groi].quick) {
|
|
|
|
// blockwrite(f, groi, 1);
|
|
|
|
// tr[groi].savedata(f);
|
|
|
|
// }
|
|
|
|
//}
|
2013-08-20 13:37:14 +02:00
|
|
|
|
|
|
|
byte spriteNum;
|
|
|
|
if (sz.isSaving()) {
|
|
|
|
spriteNum = 0;
|
|
|
|
for (byte i = 0; i < _trip->numtr; i++)
|
|
|
|
if (_trip->tr[i].quick)
|
|
|
|
spriteNum++;
|
|
|
|
}
|
|
|
|
sz.syncAsByte(spriteNum);
|
|
|
|
|
|
|
|
if (sz.isLoading())
|
|
|
|
for (byte i = 0; i < _trip->numtr; i++) { // Deallocate sprites.
|
|
|
|
if (_trip->tr[i].quick)
|
|
|
|
_trip->tr[i].done();
|
|
|
|
}
|
|
|
|
|
|
|
|
for (byte i = 0; i < spriteNum; i++) {
|
|
|
|
sz.syncAsByte(_trip->tr[i].whichsprite);
|
|
|
|
sz.syncAsByte(_trip->tr[i].check_me);
|
|
|
|
|
|
|
|
|
|
|
|
if (sz.isLoading()) {
|
|
|
|
_trip->tr[i].quick = true;
|
|
|
|
_trip->tr[i].init(_trip->tr[i].whichsprite, _trip->tr[i].check_me, _trip);
|
2013-08-19 18:18:02 +02:00
|
|
|
}
|
|
|
|
|
2013-08-20 13:37:14 +02:00
|
|
|
sz.syncAsByte(_trip->tr[i].ix);
|
|
|
|
sz.syncAsByte(_trip->tr[i].iy);
|
|
|
|
sz.syncAsByte(_trip->tr[i].face);
|
|
|
|
sz.syncAsByte(_trip->tr[i].step);
|
|
|
|
sz.syncAsByte(_trip->tr[i].visible);
|
|
|
|
sz.syncAsByte(_trip->tr[i].homing);
|
|
|
|
sz.syncAsByte(_trip->tr[i].count);
|
|
|
|
sz.syncAsByte(_trip->tr[i]._info.xw);
|
|
|
|
sz.syncAsByte(_trip->tr[i].xs);
|
|
|
|
sz.syncAsByte(_trip->tr[i].ys);
|
|
|
|
sz.syncAsByte(_trip->tr[i].totalnum);
|
|
|
|
sz.syncAsSint16LE(_trip->tr[i].hx);
|
|
|
|
sz.syncAsSint16LE(_trip->tr[i].hy);
|
|
|
|
sz.syncAsByte(_trip->tr[i].call_eachstep);
|
|
|
|
sz.syncAsByte(_trip->tr[i].eachstep);
|
|
|
|
sz.syncAsByte(_trip->tr[i].vanishifstill);
|
|
|
|
|
|
|
|
sz.syncAsSint16LE(_trip->tr[i].x);
|
|
|
|
sz.syncAsSint16LE(_trip->tr[i].y);
|
|
|
|
|
|
|
|
if (sz.isLoading() && _trip->tr[i].visible)
|
|
|
|
_trip->tr[i].appear(_trip->tr[i].x, _trip->tr[i].y, _trip->tr[i].face);
|
|
|
|
}
|
|
|
|
|
2013-08-19 18:18:02 +02:00
|
|
|
//groi = 177;
|
|
|
|
//blockwrite(f, groi, 1);
|
|
|
|
|
|
|
|
//blockwrite(f, times, sizeof(times)); // Timeout.times: Timers.
|
|
|
|
for (byte i = 0; i < 7; i++) {
|
|
|
|
sz.syncAsSint32LE(_timeout->times[i].time_left);
|
|
|
|
sz.syncAsByte(_timeout->times[i].then_where);
|
|
|
|
sz.syncAsByte(_timeout->times[i].what_for);
|
|
|
|
}
|
|
|
|
|
|
|
|
//blockwrite(f, seq, sizeof(seq)); // Sequencer information.
|
|
|
|
sz.syncBytes(_sequence->seq, _sequence->seq_length);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AvalancheEngine::canSaveGameStateCurrently() { // TODO: Refine these!!!
|
2013-08-25 13:25:50 +02:00
|
|
|
return (!_gyro->seescroll && _gyro->alive);
|
2013-08-18 15:08:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
Common::Error AvalancheEngine::saveGameState(int slot, const Common::String &desc) {
|
2013-08-19 18:18:02 +02:00
|
|
|
return (saveGame(slot, desc) ? Common::kNoError : Common::kWritingFailed);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AvalancheEngine::saveGame(const int16 slot, const Common::String &desc) {
|
2013-08-19 21:14:21 +02:00
|
|
|
Common::String fileName = getSaveFileName(slot);
|
2013-08-19 18:18:02 +02:00
|
|
|
Common::OutSaveFile *f = g_system->getSavefileManager()->openForSaving(fileName);
|
|
|
|
if (!f) {
|
|
|
|
warning("Can't create file '%s', game not saved.", fileName.c_str());
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-08-19 21:14:21 +02:00
|
|
|
char *signature = "AVAL";
|
|
|
|
f->write(signature, 4);
|
|
|
|
|
2013-08-20 21:26:23 +02:00
|
|
|
// Write version. We can't restore from obsolete versions.
|
|
|
|
f->writeByte(kSavegameVersion);
|
2013-08-19 21:14:21 +02:00
|
|
|
|
2013-08-20 21:26:23 +02:00
|
|
|
f->writeUint32LE(desc.size());
|
2013-08-19 21:14:21 +02:00
|
|
|
f->write(desc.c_str(), desc.size());
|
2013-08-20 21:26:23 +02:00
|
|
|
::Graphics::saveThumbnail(*f);
|
2013-08-19 21:14:21 +02:00
|
|
|
|
2013-08-20 19:23:24 +02:00
|
|
|
TimeDate t;
|
|
|
|
_system->getTimeAndDate(t);
|
|
|
|
f->writeSint16LE(t.tm_mday);
|
|
|
|
f->writeSint16LE(t.tm_mon);
|
|
|
|
f->writeSint16LE(t.tm_year);
|
|
|
|
|
2013-08-19 18:18:02 +02:00
|
|
|
Common::Serializer sz(NULL, f);
|
|
|
|
|
|
|
|
synchronize(sz);
|
|
|
|
|
|
|
|
f->finalize();
|
|
|
|
|
|
|
|
delete f;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-08-19 21:14:21 +02:00
|
|
|
Common::String AvalancheEngine::getSaveFileName(const int slot) {
|
|
|
|
Common::String upperName = _targetName;
|
|
|
|
upperName.toUppercase();
|
|
|
|
return upperName+ Common::String::format("-%02d.SAV", slot);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-08-19 18:18:02 +02:00
|
|
|
bool AvalancheEngine::canLoadGameStateCurrently() { // TODO: Refine these!!!
|
2013-08-20 13:37:14 +02:00
|
|
|
return (!_gyro->seescroll);
|
2013-08-18 15:08:32 +02:00
|
|
|
}
|
|
|
|
|
2013-08-19 21:14:21 +02:00
|
|
|
Common::Error AvalancheEngine::loadGameState(int slot) {
|
|
|
|
return (loadGame(slot) ? Common::kNoError : Common::kReadingFailed);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AvalancheEngine::loadGame(const int16 slot) {
|
|
|
|
Common::String fileName = getSaveFileName(slot);
|
|
|
|
Common::InSaveFile *f = g_system->getSavefileManager()->openForLoading(fileName);
|
|
|
|
if (!f)
|
|
|
|
return false;
|
2013-08-20 21:26:23 +02:00
|
|
|
|
2013-08-19 21:14:21 +02:00
|
|
|
// Check for our signature.
|
|
|
|
Common::String signature;
|
|
|
|
for (byte i = 0; i < 4; i++)
|
|
|
|
signature += f->readByte();
|
|
|
|
if (signature != "AVAL")
|
|
|
|
return false;
|
|
|
|
|
2013-08-20 21:26:23 +02:00
|
|
|
// Check version. We can't restore from obsolete versions.
|
|
|
|
byte saveVersion = f->readByte();
|
|
|
|
if (saveVersion != kSavegameVersion) {
|
|
|
|
warning("Savegame of incompatible version!");
|
|
|
|
delete f;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2013-08-20 19:23:24 +02:00
|
|
|
// Read the description.
|
2013-08-19 21:14:21 +02:00
|
|
|
uint32 descSize = f->readUint32LE();
|
2013-08-20 19:23:24 +02:00
|
|
|
Common::String description;
|
|
|
|
for (uint32 i = 0; i < descSize; i++) {
|
|
|
|
char actChar = f->readByte();
|
|
|
|
description += actChar;
|
|
|
|
}
|
|
|
|
description.toUppercase();
|
|
|
|
|
2013-08-20 21:26:23 +02:00
|
|
|
::Graphics::skipThumbnail(*f);
|
|
|
|
|
|
|
|
// Read the time the game was saved.
|
2013-08-20 19:23:24 +02:00
|
|
|
TimeDate t;
|
|
|
|
t.tm_mday = f->readSint16LE();
|
|
|
|
t.tm_mon = f->readSint16LE();
|
|
|
|
t.tm_year = f->readSint16LE();
|
2013-08-19 21:14:21 +02:00
|
|
|
|
|
|
|
Common::Serializer sz(f, NULL);
|
|
|
|
|
|
|
|
synchronize(sz);
|
|
|
|
|
|
|
|
delete f;
|
|
|
|
|
2013-08-21 13:45:22 +02:00
|
|
|
_gyro->isLoaded = true;
|
|
|
|
|
2013-08-20 13:37:14 +02:00
|
|
|
_gyro->seescroll = true; // This prevents display of the new sprites before the new picture is loaded.
|
|
|
|
|
|
|
|
if (_gyro->holdthedawn) {
|
|
|
|
_gyro->holdthedawn = false;
|
|
|
|
_lucerna->dawn();
|
|
|
|
}
|
|
|
|
|
2013-09-03 22:22:42 +02:00
|
|
|
_celer->forgetBackgroundSprites();
|
2013-08-20 13:37:14 +02:00
|
|
|
|
|
|
|
_lucerna->minor_redraw();
|
|
|
|
|
2013-08-20 19:23:24 +02:00
|
|
|
_dropdown->standard_bar();
|
|
|
|
|
2013-08-20 13:37:14 +02:00
|
|
|
_gyro->whereis[0] = _gyro->dna.room;
|
|
|
|
|
|
|
|
_gyro->alive = true;
|
|
|
|
|
|
|
|
_lucerna->objectlist();
|
|
|
|
|
|
|
|
_trip->newspeed();
|
|
|
|
|
|
|
|
_lucerna->showrw();
|
|
|
|
|
2013-08-20 19:23:24 +02:00
|
|
|
_gyro->ontoolbar = false;
|
|
|
|
_trip->trippancy_link();
|
|
|
|
|
2013-09-04 09:25:11 +02:00
|
|
|
_celer->updateBackgroundSprites();
|
2013-08-20 19:23:24 +02:00
|
|
|
|
|
|
|
_scrolls->display(Common::String(_scrolls->kControlItalic) + "Loaded: " + _scrolls->kControlRoman + description + ".ASG"
|
|
|
|
+ _scrolls->kControlCenter + _scrolls->kControlNewLine + _scrolls->kControlNewLine
|
|
|
|
+ _gyro->roomname + _scrolls->kControlNewLine + _scrolls->kControlNewLine
|
|
|
|
+ "saved on " + expandDate(t.tm_mday, t.tm_mon, t.tm_year) + '.');
|
|
|
|
|
|
|
|
if (_trip->tr[0].quick && _trip->tr[0].visible)
|
2013-08-20 21:26:23 +02:00
|
|
|
_trip->rwsp(0, _gyro->dna.rw); // We push Avvy in the right direction is he was moving.
|
2013-08-20 19:23:24 +02:00
|
|
|
|
2013-08-19 21:14:21 +02:00
|
|
|
return true;
|
2013-08-18 15:08:32 +02:00
|
|
|
}
|
|
|
|
|
2013-08-20 19:23:24 +02:00
|
|
|
Common::String AvalancheEngine::expandDate(int d, int m, int y) {
|
|
|
|
const Common::String months[12] = {
|
|
|
|
"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
|
|
|
|
};
|
|
|
|
|
|
|
|
Common::String month = months[m];
|
|
|
|
|
|
|
|
Common::String day = _gyro->strf(d);
|
|
|
|
|
|
|
|
if (((1 <= d) && (d <= 9)) || ((21 <= d) && (d <= 31)))
|
|
|
|
switch (d % 10) {
|
|
|
|
case 1:
|
|
|
|
day = day + "st";
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
day = day + "nd";
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
day = day + "rd";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
day = day + "th";
|
|
|
|
}
|
|
|
|
|
|
|
|
return day + ' ' + month + ' ' + _gyro->strf(y + 1900);
|
|
|
|
}
|
|
|
|
|
2013-08-18 15:08:32 +02:00
|
|
|
|
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
void AvalancheEngine::updateEvents() {
|
|
|
|
Common::Event event;
|
|
|
|
|
|
|
|
while (_eventMan->pollEvent(event)) {
|
|
|
|
switch (event.type) {
|
2013-08-16 23:02:53 +02:00
|
|
|
case Common::EVENT_LBUTTONDOWN:
|
2013-09-02 15:44:55 +02:00
|
|
|
_lucerna->holdLeftMouse = true; // Used in Lucerna::checkclick() and Dropdown::menu_link().
|
2013-08-16 23:02:53 +02:00
|
|
|
break;
|
|
|
|
case Common::EVENT_LBUTTONUP:
|
|
|
|
_lucerna->holdLeftMouse = false; // Same as above.
|
|
|
|
break;
|
2013-07-24 16:43:34 +02:00
|
|
|
case Common::EVENT_KEYDOWN:
|
2013-07-24 18:12:16 +02:00
|
|
|
_avalot->handleKeyDown(event);
|
2013-07-24 12:55:01 +02:00
|
|
|
}
|
|
|
|
}
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-07-02 15:59:27 +02:00
|
|
|
|
2013-08-06 01:13:25 +02:00
|
|
|
bool AvalancheEngine::getEvent(Common::Event &event) {
|
|
|
|
return _eventMan->pollEvent(event);
|
|
|
|
}
|
|
|
|
|
2013-08-16 17:29:22 +02:00
|
|
|
Common::Point AvalancheEngine::getMousePos() {
|
|
|
|
return _eventMan->getMousePos();
|
|
|
|
}
|
2013-07-02 15:59:27 +02:00
|
|
|
|
2013-06-19 16:59:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// From Bootstrp:
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
const char AvalancheEngine::kRuncodes[2][3] = {"et", "Go"};
|
2013-06-20 12:47:44 +02:00
|
|
|
|
2013-06-20 14:08:58 +02:00
|
|
|
|
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// The original ones were all commented out, so porbably there's no need
|
|
|
|
// of these two cursor functions at all. TODO: Remove later.
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::cursorOff() {
|
|
|
|
warning("STUB: cursorOff()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::cursorOn() {
|
|
|
|
warning("STUB: cursorOn()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// Needed later.
|
|
|
|
void AvalancheEngine::quit() {
|
2013-09-03 12:09:29 +02:00
|
|
|
cursorOn();
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// Needed in dos_shell(). TODO: Remove later.
|
2013-09-03 12:09:29 +02:00
|
|
|
Common::String AvalancheEngine::commandCom() {
|
|
|
|
warning("STUB: commandCom()");
|
|
|
|
return ("STUB: commandCom()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// Needed for run_avalot()'s errors. TODO: Remove later.
|
|
|
|
void AvalancheEngine::explain(byte error) {
|
|
|
|
warning("STUB: explain()");
|
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-06-20 10:58:39 +02:00
|
|
|
|
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
//TODO: Remove these (b_flight) functions later ( https://github.com/tthurman/avalot/wiki/B-Flight )
|
2013-06-20 10:58:39 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::bFlight() { /*interrupt;*/
|
|
|
|
_storage._skellern++;
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::bFlightOn() {
|
|
|
|
_storage._skellern = kReset;
|
2013-07-24 16:43:34 +02:00
|
|
|
// setintvec(0x1c, &b_flight);
|
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::bFlightOff() {
|
2013-07-24 16:43:34 +02:00
|
|
|
// setintvec(0x1c, old_1c);
|
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-06-20 10:58:39 +02:00
|
|
|
|
|
|
|
|
2013-09-03 15:35:09 +02:00
|
|
|
Common::String AvalancheEngine::elmToStr(Elm how) {
|
2013-07-24 16:43:34 +02:00
|
|
|
switch (how) {
|
2013-09-03 12:09:29 +02:00
|
|
|
case kNormal:
|
|
|
|
case kMusical:
|
|
|
|
return "jsb";
|
|
|
|
case kRegi:
|
|
|
|
return "REGI";
|
|
|
|
case kElmpoyten:
|
|
|
|
return "ELMPOYTEN";
|
2013-06-19 16:59:12 +02:00
|
|
|
}
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::run(Common::String what, bool withJsb, bool withBflight, Elm how) {
|
2013-07-24 16:43:34 +02:00
|
|
|
warning("STUB: run(%s)", what.c_str());
|
|
|
|
// Probably there'll be no need of this function, as all *.AVX-es will become classes.
|
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::getArguments() {
|
2013-07-24 16:43:34 +02:00
|
|
|
// This function should mess around with command line arguments,
|
|
|
|
// but I am not sure if there'll be use of these arguments at all...
|
2013-09-03 12:09:29 +02:00
|
|
|
warning("STUB: getArguments()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-20 12:47:44 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::getSlope() {
|
2013-07-24 16:43:34 +02:00
|
|
|
// Same as get_arguments()
|
2013-09-03 12:09:29 +02:00
|
|
|
warning("STUB: getSlope()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-20 12:47:44 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::callMenu() {
|
|
|
|
warning("STUB: callMenu()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-20 12:47:44 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::runDemo() {
|
|
|
|
warning("STUB: runDemo()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::dosShell() {
|
|
|
|
warning("STUB: dosShell()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// Getting used only in demo() / call_menu(). Going to be implemented at the same time with these.
|
2013-09-03 12:09:29 +02:00
|
|
|
bool AvalancheEngine::keyPressed() {
|
|
|
|
warning("STUB: keyPressed()");
|
2013-07-24 16:43:34 +02:00
|
|
|
return false;
|
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// Same as keypressed1().
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::flushBuffer() {
|
|
|
|
warning("STUB: flushBuffer()");
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// Same as keypressed1().
|
|
|
|
void AvalancheEngine::demo() {
|
|
|
|
warning("STUB: demo()");
|
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-06-20 12:47:44 +02:00
|
|
|
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-06-20 14:08:58 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
void AvalancheEngine::runAvalot() {
|
|
|
|
bFlightOn();
|
2013-06-20 14:08:58 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
_avalot->run(Common::String(kRuncodes[_firstTime]) + _arguments);
|
2013-07-24 16:43:34 +02:00
|
|
|
// TODO: Check if parameteres are ever used (probably not) and eventually remove them.
|
|
|
|
// If there's an error initalizing avalot, i'll handle it in there, not here
|
2013-07-10 13:26:49 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
_firstTime = false;
|
2013-07-24 16:43:34 +02:00
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
Common::Error AvalancheEngine::run() {
|
2013-07-24 17:52:57 +02:00
|
|
|
Common::ErrorCode err = initialize();
|
|
|
|
if (err != Common::kNoError)
|
|
|
|
return err;
|
2013-06-18 17:52:25 +02:00
|
|
|
|
2013-08-20 19:23:24 +02:00
|
|
|
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
// From bootstrp:
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
_firstTime = true;
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
getArguments();
|
|
|
|
getSlope();
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
_zoomy = true;
|
2013-07-24 16:43:34 +02:00
|
|
|
// Don't call the menu by default. Might be modified later, if get_slope() gets implemented,
|
|
|
|
// becouse zoomy's value is given there. Not sure yet what "zoomy" stands for.
|
2013-09-03 12:09:29 +02:00
|
|
|
if (!_zoomy)
|
|
|
|
callMenu(); /* Not run when zoomy. */
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 12:55:01 +02:00
|
|
|
|
2013-07-10 13:26:49 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
do {
|
2013-09-03 12:09:29 +02:00
|
|
|
runAvalot();
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
//if (dosexitcode != 77) quit(); /* Didn't stop for us. */
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-09-03 12:09:29 +02:00
|
|
|
switch (_storage._operation) {
|
|
|
|
case kRunShootemup:
|
|
|
|
run("seu.avx", kJsb, kBflight, kNormal);
|
2013-07-24 16:43:34 +02:00
|
|
|
break;
|
2013-09-03 12:09:29 +02:00
|
|
|
case kRunDosshell:
|
|
|
|
dosShell();
|
2013-07-24 16:43:34 +02:00
|
|
|
break;
|
2013-09-03 12:09:29 +02:00
|
|
|
case kRunGhostroom:
|
|
|
|
run("g-room.avx", kJsb, kNoBflight, kNormal);
|
2013-07-24 16:43:34 +02:00
|
|
|
break;
|
2013-09-03 12:09:29 +02:00
|
|
|
case kRunGolden:
|
|
|
|
run("golden.avx", kJsb, kBflight, kMusical);
|
2013-07-24 16:43:34 +02:00
|
|
|
break;
|
|
|
|
}
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-08-31 00:30:06 +02:00
|
|
|
} while (false);
|
2013-06-19 16:59:12 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
2013-07-24 16:43:34 +02:00
|
|
|
return Common::kNoError;
|
|
|
|
}
|
2013-06-18 17:52:25 +02:00
|
|
|
|
2013-06-19 16:59:12 +02:00
|
|
|
|
2013-06-18 17:52:25 +02:00
|
|
|
|
|
|
|
} // End of namespace Avalanche
|