/* 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 .
*
*/
#ifndef ASYLUM_RESOURCES_ENCOUNTERS_H
#define ASYLUM_RESOURCES_ENCOUNTERS_H
#include "common/array.h"
#include "common/serializer.h"
#include "asylum/eventhandler.h"
#include "asylum/shared.h"
namespace Asylum {
class AsylumEngine;
struct EncounterItem : public Common::Serializable {
uint32 speechResourceId;
ResourceId scriptResourceId;
int16 keywords[50];
byte variable2;
EncounterItem() {
speechResourceId = 0;
scriptResourceId = kResourceNone;
memset(&keywords, 0, sizeof(keywords));
variable2 = 0;
}
virtual ~EncounterItem() {}
// Serializable
void saveLoadWithSerializer(Common::Serializer &s) {
s.syncAsSint32LE(speechResourceId);
s.syncAsSint32LE(scriptResourceId);
for (int32 i = 0; i < ARRAYSIZE(keywords); i++)
s.syncAsSint16LE(keywords[i]);
s.syncAsByte(variable2);
}
};
class EncounterVariables : public Common::Array, public Common::Serializable {
public:
virtual ~EncounterVariables() {}
// Serializable
void saveLoadWithSerializer(Common::Serializer &s) {
for (uint i = 0; i < _size; i++)
s.syncAsSint16LE(_storage[i]);
}
};
class EncounterItems : public Common::Array, public Common::Serializable {
public:
virtual ~EncounterItems() {}
// Serializable
void saveLoadWithSerializer(Common::Serializer &s) {
for (uint i = 0; i < _size; i++)
_storage[i].saveLoadWithSerializer(s);
}
};
class Encounter : public EventHandler {
public:
Encounter(AsylumEngine *engine);
virtual ~Encounter() {};
void run(int32 encounterIndex, ObjectId objectId1, ObjectId objectId2, ActorIndex actorIndex);
bool handleEvent(const AsylumEvent &evt);
void drawScreen();
void setShouldEnablePlayer(bool state) { _shouldEnablePlayer = state; }
bool shouldEnablePlayer() { return _shouldEnablePlayer; }
// Accessors (for saving game)
EncounterItems *items() { return &_items; }
EncounterVariables *variables() { return &_variables; }
private:
AsylumEngine *_vm;
//////////////////////////////////////////////////////////////////////////
// Data
enum KeywordOptions {
kKeywordOptionsDisabled = 0x20,
kKeywordOptionsUnknown = 0x40,
kKeywordOptionsVisible = 0x80
};
struct EncounterGraphic {
uint32 frameIndex;
uint32 frameCount;
Common::Rect rect;
ResourceId resourceId;
int32 transTableNum;
int32 transTableMax;
int32 speech0;
int32 speech1;
int32 speech2;
int32 speech3;
EncounterGraphic() {
frameIndex = 0;
frameCount = 0;
resourceId = kResourceNone;
transTableNum = 0;
transTableMax = 0;
speech0 = 0;
speech1 = 0;
speech2 = 0;
speech3 = 0;
}
};
struct EncounterDrawingStruct {
Common::Point point1;
Common::Point point2;
uint32 frameIndex;
int32 transTableNum;
int32 status;
ResourceId resourceId;
EncounterDrawingStruct() {
frameIndex = 0;
transTableNum = -1;
status = 0;
resourceId = kResourceNone;
}
};
EncounterVariables _variables;
EncounterItems _items;
EncounterDrawingStruct _drawingStructs[2];
int32 _keywordIndexes[50];
// Background & portrait
EncounterGraphic _background;
EncounterGraphic _portrait1;
EncounterGraphic _portrait2;
Common::Point _point;
int32 _rectIndex;
// Running encounter data
int32 _index;
int32 _speechResourceId;
ResourceId _soundResourceId;
EncounterItem *_item;
ObjectId _objectId1;
ObjectId _objectId2;
ObjectId _objectId3;
ActorIndex _actorIndex;
int16 _value1;
uint32 _tick;
// Internal data
int32 _data_455B14;
int16 _data_455B3C;
int16 _data_455B70;
bool _data_455BCC;
bool _isDialogOpen;
bool _shouldCloseDialog;
bool _data_455BD8;
bool _data_455BDC;
bool _data_455BE0;
bool _shouldCloseBackground;
bool _data_455BE8;
int16 _data_455BF0;
uint32 _data_455BF4;
uint32 _keywordStartIndex;
uint32 _keywordsOffset;
// Internal flags
bool _shouldEnablePlayer;
bool _wasPlayerDisabled;
bool _isClosing;
bool _isScriptRunning;
//////////////////////////////////////////////////////////////////////////
// Data
void load();
void initData();
void initBackground();
void initPortraits();
void initDrawStructs();
//////////////////////////////////////////////////////////////////////////
// Message handling
bool init();
bool update();
bool mouse(const AsylumEvent &evt);
bool cancel(const AsylumEvent &evt);
//////////////////////////////////////////////////////////////////////////
// Variables
void setVariable(uint32 index, int16 val);
int16 getVariable(uint32 index);
int16 getVariableInv(int16 index);
/////////////////////////////////////////////////////////////////////////
// Actions
uint32 findKeyword(EncounterItem *item, int16 keyword) const;
int32 getKeywordIndex();
void choose(int32 keywordIndex);
bool checkKeywords() const;
bool checkKeywords2() const;
void updateFromRect(int32 rectIndex);
//////////////////////////////////////////////////////////////////////////
// Speech
void resetSpeech(int16 a1, int16 a2);
void setupPortraits();
void setupSpeechText();
void setupSpeechData(char val, EncounterGraphic *encounterGraphic) const;
void setupSpeech(ResourceId textResourceId, ResourceId fontResourceId);
bool setupSpeechTest(ResourceId id);
bool isSpeaking();
//////////////////////////////////////////////////////////////////////////
// Drawing
bool drawBackground();
bool drawPortraits();
void drawStructs();
void drawDialogOptions();
void drawSubtitle(char *text, ResourceId font, int16 y);
//////////////////////////////////////////////////////////////////////////
// Misc
void exitEncounter();
void setupEntities(bool type4);
int32 findRect();
void updateDrawingStatus();
void updateDrawingStatus1(int32 rectIndex);
void updateDrawingStatus2(int32 rectIndex);
bool updateScreen();
void updatePalette1();
void updatePalette2();
bool isKeywordVisible(int16 keyword) const { return (bool)(BYTE1(keyword) & kKeywordOptionsVisible); }
bool isKeywordDisabled(int16 keyword) const { return (bool)(BYTE1(keyword) & kKeywordOptionsDisabled); }
//////////////////////////////////////////////////////////////////////////
// Scripts
enum EncounterOpcode {
kOpcodeEncounterReturn = 0,
kOpcodeSetScriptVariable = 1,
kOpcodeSetCounterFromVars = 2,
kOpcodeSetOffset = 3,
kOpcodeSetOffsetIfCounterNegative = 4,
kOpcodeSetOffsetIfCounterNegativeOrNull = 5,
kOpcodeSetOffsetIfCounterIsNull = 6,
kOpcodeSetOffsetIfCounterIsNotNull = 7,
kOpcodeSetOffsetIfCounterPositiveOrNull = 8,
kOpcodeSetOffsetIfCounterPositive = 9,
kOpcodeSetCurrentItemOptions = 10,
kOpcodeClearCurrentItemOptions = 11,
kOpcodeSetItemOptions = 12,
kOpcodeCloseDialog = 13,
kOpcodeResetSpeech = 14,
kOpcodeSetVariable = 15,
kOpcodeIncrementScriptVariable = 16,
kOpcodeProcessVariable3 = 17,
kOpcodeAddRemoveInventoryItem = 18,
kOpcodeSetCounterIfInventoryOmits = 21,
kOpcodePrepareMovie = 23,
kOpcodeSetClearGameFlag = 24,
kOpcodeSetCounterFromGameFlag = 25
};
struct ScriptEntry {
byte opcode;
byte param1;
uint16 param2;
ScriptEntry(byte *data) {
opcode = *data;
param1 = *(data + 1);
param2 = READ_LE_UINT16(data + 2);
}
Common::String toString();
};
struct ScriptData {
int32 vars[40];
uint32 offset;
int32 counter;
ResourceId resourceId;
ScriptData() {
reset(kResourceNone);
}
void reset(ResourceId id) {
memset(&vars, 0, sizeof(vars));
offset = 0;
counter = 0;
resourceId = id;
}
};
ScriptData _scriptData;
void initScript(ResourceId resourceId);
ScriptEntry getScriptEntry(ResourceId resourceId, uint32 offset);
void runScript();
friend class Console;
};
} // end of namespace Asylum
#endif // ASYLUM_RESOURCES_ENCOUNTERS_H