Files
scummvm-cursorfix/engines/dgds/head.h
2026-02-02 04:50:13 +01:00

192 lines
5.0 KiB
C++

/* ScummVM - Graphic Adventure Engine
*
* ScummVM is the legal property of its developers, whose names
* are too numerous to list here. Please refer to the COPYRIGHT
* file distributed with this source distribution.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 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 DGDS_HEAD_H
#define DGDS_HEAD_H
#include "common/str.h"
#include "common/types.h"
#include "common/ptr.h"
#include "common/array.h"
#include "graphics/managed_surface.h"
#include "dgds/dgds_rect.h"
#include "dgds/image.h"
#include "dgds/ttm.h"
// Classes related to talking heads and conversations.
namespace Dgds {
class Image;
class SoundRaw;
class Dialog;
class TalkDataHeadFrame {
public:
TalkDataHeadFrame() : _xoff(0), _yoff(0), _frameNo(0), _flipFlags(0) {}
Common::String dump(const Common::String &indent) const;
uint16 _frameNo;
int16 _xoff;
int16 _yoff;
uint16 _flipFlags;
};
enum HeadFlags {
kHeadFlagNone = 0,
kHeadFlagFinished = 1,
kHeadFlag2 = 2,
kHeadFlag4 = 4,
kHeadFlag8 = 8,
kHeadFlag10 = 0x10,
kHeadFlagVisible = 0x20,
kHeadFlagOpening = 0x40,
kHeadFlag80 = 0x80,
};
class TalkData;
class TalkDataHead {
public:
TalkDataHead() : _num(0), _drawType(0), _drawCol(0), _flags(kHeadFlagNone) {}
Common::String dump(const Common::String &indent) const;
void clearHead();
void drawHead(Graphics::ManagedSurface &dst, const TalkData &data) const;
void drawHeadType1(Graphics::ManagedSurface &dst, const Image &img) const;
void drawHeadType2(Graphics::ManagedSurface &dst, const Image &img) const;
void drawHeadType3(Graphics::ManagedSurface &dst, const Image &img) const;
void drawHeadType3Beamish(Graphics::ManagedSurface &dst, const TalkData &data) const;
uint16 _num;
uint16 _drawType;
uint16 _drawCol;
DgdsRect _rect;
Common::Array<TalkDataHeadFrame> _headFrames;
Common::String _bmpFile;
HeadFlags _flags;
Common::SharedPtr<Image> _shape;
};
/** TDS talking head data from HOC+ */
class TalkData {
public:
TalkData() : _num(0), _val(0) {}
Common::String dump(const Common::String &indent) const;
uint16 _num;
Common::SharedPtr<Image> _shape;
Common::Array<TalkDataHead> _heads;
uint16 _val;
Common::String _bmpFile;
void clearVisibleHeads();
void drawAndUpdateVisibleHeads(Graphics::ManagedSurface &dst);
bool hasVisibleHead() const;
};
/**
* A TTM interpreter with customized opcode handling for the TTM bit of
* CDS files (Willy Beamish CD version conversation data)
*/
class CDSTTMInterpreter : public TTMInterpreter {
public:
CDSTTMInterpreter(DgdsEngine *vm);
Graphics::ManagedSurface &getStoredAreaBuffer() { return _storedAreaBuffer; }
protected:
virtual void handleOperation(TTMEnviro &env, TTMSeq &seq, uint16 op, byte count, const int16 *ivals, const Common::String &sval, const Common::Array<Common::Point> &pts) override;
Graphics::ManagedSurface _storedAreaBuffer;
};
class CDSTTMEnviro : public TTMEnviro {
public:
CDSTTMEnviro() : _cdsPlayedSound(false), _cdsFrame(-1), _cdsJumped(false), _cdsDelay(0),
_cdsDidStoreArea(false), TTMEnviro()
{}
bool _cdsPlayedSound;
int16 _cdsFrame; // The GOTO target to use in the CDS script (Willy Beamish talkie)
int16 _cdsDelay;
bool _cdsJumped;
bool _cdsDidStoreArea;
DgdsRect _storedAreaRect;
};
/** CDS data from Willy Beamish CD version talkie */
class Conversation {
public:
Conversation() : _thisFrameMs(0), _nextExecMs(0), _runTempFrame(-1), _tempFrameNum(0), _stopScript(false), _loadState(0),
_dlgNum(-1), _dlgFileNum(-1), _subNum(-1), _finished(false), _haveHeadData(false) {}
~Conversation();
void unloadData();
void runScript();
void loadData(uint16 num, uint16 num2, int16 sub, bool haveHeadData);
bool isForDlg(const Dialog *dlg) const;
bool isFinished() const { return _finished; }
void clear();
DgdsRect _drawRect;
static enum ImageFlipMode _lastHeadFrameFlipMode;
static int16 _lastHeadFrameX;
static int16 _lastHeadFrameY;
private:
Common::SharedPtr<CDSTTMInterpreter> _ttmScript;
Common::Array<Common::SharedPtr<TTMSeq>> _ttmSeqs;
CDSTTMEnviro _ttmEnv;
uint32 _nextExecMs;
bool runScriptFrame(int16 frameNum);
void checkAndRunScript();
void incrementFrame();
bool isScriptRunning();
void pumpMessages();
void runScriptExclusive();
void runScriptStep();
int16 _runTempFrame;
int16 _tempFrameNum;
uint32 _thisFrameMs;
bool _stopScript;
int16 _loadState;
int16 _dlgNum;
int16 _dlgFileNum;
int16 _subNum;
bool _finished;
bool _haveHeadData;
};
} // end namespace Dgds
#endif // DGDS_HEAD_H