/* 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. * */ #ifndef VOYEUR_FILES_H #define VOYEUR_FILES_H #include "common/scummsys.h" #include "common/file.h" #include "common/rect.h" #include "common/str.h" #include "voyeur/screen.h" namespace Voyeur { class VoyeurEngine; class BoltFile; class BoltGroup; class BoltEntry; class RectResource; class PictureResource; class ViewPortResource; class ViewPortListResource; class FontResource; class CMapResource; class VInitCycleResource; class PtrResource; class ControlResource; class StateResource; class ThreadResource; #define DECOMPRESS_SIZE 0x7000 class ResolveEntry { public: uint32 _id; byte **_p; ResolveEntry(uint32 id, byte **p) { _id = id; _p = p; } }; class BoltFilesState { public: VoyeurEngine *_vm; BoltFile *_curLibPtr; BoltGroup *_curGroupPtr; BoltEntry *_curMemberPtr; int _bufferEnd; int _bufferBegin; int _bytesLeft; int _bufSize; byte *_bufStart; byte *_bufPos; byte _decompressBuf[DECOMPRESS_SIZE]; int _historyIndex; byte _historyBuffer[0x200]; int _runLength; bool _decompState; int _runType; int _runValue; int _runOffset; Common::File *_curFd; Common::Array<ResolveEntry> _resolves; byte *_boltPageFrame; public: BoltFilesState(VoyeurEngine *vm); byte *decompress(byte *buf, int size, int mode); void nextBlock(); }; class BoltFile { private: Common::Array<BoltGroup> _groups; protected: BoltFilesState &_state; virtual void initResource(int resType) = 0; void initDefault(); private: void resolveAll(); byte *getBoltMember(uint32 id); public: Common::File _file; BoltFile(const Common::String &filename, BoltFilesState &state); virtual ~BoltFile(); BoltGroup *getBoltGroup(uint16 id); void freeBoltGroup(uint16 id); void freeBoltMember(uint32 id); byte *memberAddr(uint32 id); byte *memberAddrOffset(uint32 id); void resolveIt(uint32 id, byte **p); void resolveFunction(uint32 id, ScreenMethodPtr *fn); BoltEntry &boltEntry(uint16 id); BoltEntry &getBoltEntryFromLong(uint32 id); PictureResource *getPictureResource(uint32 id); CMapResource *getCMapResource(uint32 id); }; class BVoyBoltFile: public BoltFile { private: // initType method table void sInitRect(); void sInitPic(); void vInitCMap(); void vInitCycl(); void initViewPort(); void initViewPortList(); void initFontInfo(); void initFont(); void initSoundMap(); protected: virtual void initResource(int resType); public: BVoyBoltFile(BoltFilesState &state); }; class StampBoltFile: public BoltFile { private: void initThread(); void initState(); void initPtr(); void initControl(); protected: virtual void initResource(int resType); public: StampBoltFile(BoltFilesState &state); }; class BoltGroup { private: Common::SeekableReadStream *_file; public: bool _loaded; bool _processed; int _count; int _fileOffset; Common::Array<BoltEntry> _entries; public: BoltGroup(Common::SeekableReadStream *f); virtual ~BoltGroup(); void load(uint16 groupId); void unload(); }; class BoltEntry { private: Common::SeekableReadStream *_file; public: uint16 _id; byte _mode; byte _initMethod; int _fileOffset; int _size; byte *_data; // bvoy.blt resource types RectResource *_rectResource; PictureResource *_picResource; ViewPortResource *_viewPortResource; ViewPortListResource *_viewPortListResource; FontResource *_fontResource; FontInfoResource *_fontInfoResource; CMapResource *_cMapResource; VInitCycleResource *_vInitCycleResource; // stampblt.blt resource types PtrResource *_ptrResource; ControlResource *_controlResource; StateResource *_stateResource; ThreadResource *_threadResource; public: BoltEntry(Common::SeekableReadStream *f, uint16 id); virtual ~BoltEntry(); void load(); bool hasResource() const; }; class FilesManager { public: BoltFilesState *_boltFilesState; BoltFile *_curLibPtr; public: FilesManager(VoyeurEngine *vm); ~FilesManager(); bool openBoltLib(const Common::String &filename, BoltFile *&boltFile); byte *fload(const Common::String &filename, int *size); }; class RectEntry: public Common::Rect { public: int _arrIndex; int _count; RectEntry(int x1, int y1, int x2, int y2, int arrIndex, int count); }; class RectResource: public Common::Rect { public: Common::Array<RectEntry> _entries; public: RectResource(const byte *src, int size, bool isExtendedRects); RectResource(int xp, int yp, int width, int height); virtual ~RectResource() {} }; /* bvoy.blt resource types */ enum PictureFlag { PICFLAG_2 = 2, PICFLAG_PIC_OFFSET = 8, PICFLAG_CLEAR_SCREEN = 0x10, PICFLAG_20 = 0x20, PICFLAG_HFLIP = 0x40, PICFLAG_VFLIP = 0x80, PICFLAG_100 = 0x100, PICFLAG_CLEAR_SCREEN00 = 0x1000 }; enum DisplayFlag { DISPFLAG_1 = 1, DISPFLAG_2 = 2, DISPFLAG_4 = 4, DISPFLAG_8 = 8, DISPFLAG_10 = 0x10, DISPFLAG_20 = 0x20, DISPFLAG_40 = 0x40, DISPFLAG_80 = 0x80, DISPFLAG_100 = 0x100, DISPFLAG_200 = 0x200, DISPFLAG_400 = 0x400, DISPFLAG_800 = 0x800, DISPFLAG_1000 = 0x1000, DISPFLAG_2000 = 0x2000, DISPFLAG_4000 = 0x4000, DISPFLAG_VIEWPORT = 0x8000, DISPFLAG_CURSOR = 0x10000, DISPFLAG_NONE = 0}; class DisplayResource { private: VoyeurEngine *_vm; public: uint32 _flags; public: DisplayResource(); DisplayResource(VoyeurEngine *vm); /** * Fill a box of the given size at the current _drawPtr location */ void sFillBox(int width, int height); /** * Draw text at the current pen position */ int drawText(const Common::String &msg); /** * Return the width of a given text in the current font */ int textWidth(const Common::String &msg); /** * Clip the given rectangle by the currently viewable area */ bool clipRect(Common::Rect &rect); }; class PictureResource: public DisplayResource { private: /** * Flip the image data horizontally */ void flipHorizontal(const byte *data); /** * Flip the image data vertically */ void flipVertical(const byte *data); public: byte _select; byte _pick; byte _onOff; Common::Rect _bounds; uint32 _maskData; uint _planeSize; byte _keyColor; /** * Image data for the picture */ byte *_imgData; /** * Flag to indicate whether to free the image data */ DisposeAfterUse::Flag _freeImgData; public: PictureResource(BoltFilesState &state, const byte *src); PictureResource(int flags, int select, int pick, int onOff, const Common::Rect &bounds, int maskData, byte *imgData, int planeSize); PictureResource(Graphics::Surface *surface); PictureResource(); virtual ~PictureResource(); }; typedef void (ViewPortResource::*ViewPortMethodPtr)(); class ViewPortResource: public DisplayResource { private: BoltFilesState &_state; private: void setupViewPort(PictureResource *page, Common::Rect *clippingRect, ViewPortSetupPtr setupFn, ViewPortAddPtr addFn, ViewPortRestorePtr restoreFn); public: ViewPortResource *_parent; ViewPortSetupPtr _setupFn; int _pageCount; ViewPortAddPtr _addFn; int _pageIndex; ViewPortRestorePtr _restoreFn; int _lastPage; ScreenMethodPtr _fn1; Common::Rect _bounds; PictureResource *_currentPic; PictureResource *_activePage; PictureResource *_pages[2]; // Rect lists and counts. Note that _rectListCount values of '-1' seem to have // special significance, which is why I'm not making them redundant in favor // of the arrays' .size() method Common::Array<Common::Rect> *_rectListPtr[3]; int _rectListCount[3]; Common::Rect _clipRect; Common::Rect _fontRect; public: ViewPortResource(BoltFilesState &state, const byte *src); virtual ~ViewPortResource(); void setupViewPort(); void setupViewPort(PictureResource *pic, Common::Rect *clippingRect = NULL); void addSaveRect(int pageIndex, const Common::Rect &r); void fillPic(byte onOff); void drawIfaceTime(); void drawPicPerm(PictureResource *pic, const Common::Point &pt); }; class ViewPortPalEntry { public: uint16 _rEntry, _gEntry, _bEntry; uint16 _rChange, _gChange, _bChange; uint16 _palIndex; public: ViewPortPalEntry(const byte *src); }; class ViewPortListResource { public: Common::Array<ViewPortPalEntry> _palette; Common::Array<ViewPortResource *> _entries; int _palIndex; ViewPortListResource(BoltFilesState &state, const byte *src); virtual ~ViewPortListResource() {} }; class FontResource { public: int _minChar, _maxChar; int _fontDepth; int _padding; int _fontHeight; int _topPadding; int *_charWidth; byte *_charOffsets; byte *_charImages; FontResource(BoltFilesState &state, byte *src); virtual ~FontResource(); }; enum FontJustify { ALIGN_LEFT = 0, ALIGN_CENTER = 1, ALIGN_RIGHT = 2 }; class FontInfoResource { public: FontResource *_curFont; byte _picFlags; byte _picSelect; byte _picPick; byte _picOnOff; byte _fontFlags; FontJustify _justify; int _fontSaveBack; Common::Point _pos; int _justifyWidth; int _justifyHeight; Common::Point _shadow; int _foreColor; int _backColor; int _shadowColor; public: FontInfoResource(BoltFilesState &state, const byte *src); FontInfoResource(); FontInfoResource(byte picFlags, byte picSelect, byte picPick, byte picOnOff, byte fontFlags, FontJustify justify, int fontSaveBack, const Common::Point &pos, int justifyWidth, int justifyHeight, const Common::Point &shadow, int foreColor, int backColor, int shadowColor); }; class CMapResource { private: VoyeurEngine *_vm; public: int _steps; int _fadeStatus; int _start; int _end; byte *_entries; public: CMapResource(BoltFilesState &state, const byte *src); virtual ~CMapResource(); void startFade(); }; class VInitCycleResource { private: BoltFilesState &_state; public: int _type[4]; byte *_ptr[4]; public: VInitCycleResource(BoltFilesState &state, const byte *src); virtual ~VInitCycleResource() {} void vStartCycle(); void vStopCycle(); }; /* stampblt.blt resources */ class PtrResource { public: Common::Array<BoltEntry *> _entries; PtrResource(BoltFilesState &state, const byte *src); virtual ~PtrResource() {} }; class ControlResource { public: int _memberIds[8]; byte *_entries[8]; int _stateId; StateResource *_state; ControlResource(BoltFilesState &state, const byte *src); virtual ~ControlResource() {} }; /** * Stores data about the intended victim */ class StateResource { public: int _vals[4]; int &_victimIndex; int &_victimEvidenceIndex; int &_victimMurderIndex; StateResource(BoltFilesState &state, const byte *src); virtual ~StateResource() {} /** * Synchronizes the game data */ void synchronize(Common::Serializer &s); }; class ThreadResource { public: static int _useCount[8]; static void initUseCount(); static void unloadAllStacks(VoyeurEngine *vm); static void init(); private: VoyeurEngine *_vm; Common::Point _aptPos; private: bool getStateInfo(); byte *getDataOffset(); void getButtonsText(); void getButtonsFlags(); void performOpenCard(); const byte *getRecordOffset(const byte *p); const byte *getNextRecord(const byte *p); const byte *getSTAMPCard(int cardId); int getStateFromID(uint32 id); uint32 getSID(int sid); void cardAction(const byte *p); void doSTAMPCardAction(); bool goToStateID(int stackId, int id); const byte *cardPerform(const byte *card); bool cardPerform2(const byte *p, int cardCmdId); void savePrevious(); void setButtonFlag(int idx, byte bits); void clearButtonFlag(int idx, byte bits); /** * Frees the apartment screen data */ void freeTheApt(); /** * Does any necessary animation at the start or end of showing the apartment. */ void doAptAnim(int mode); /** * Updates the mansion scroll position if ncessary, and returns true if it * has been changed. */ bool checkMansionScroll(); public: int _stateId; int _stackId; int _savedStateId; int _savedStackId; int _newStateId; int _newStackId; int _stateFlags; int _stateCount; int _parseCount; uint32 _nextStateId; byte *_threadInfoPtr; byte _buttonFlags[64]; byte _buttonIds[64]; byte *_ctlPtr; byte *_playCommandsPtr; /** * Loads the specified stack */ bool loadAStack(int stackId); /** * Unloads the specified stack */ void unloadAStack(int stackId); /** * Initializes data for the thread based on the current state */ bool doState(); public: ThreadResource(BoltFilesState &state, const byte *src); virtual ~ThreadResource() {} /** * Initialize the thread */ void initThreadStruct(int idx, int id); /** * Go to a new state and/or stack */ bool goToState(int stackId, int stateId); bool chooseSTAMPButton(int buttonId); /** * Parses the script commands from the currently active stack */ void parsePlayCommands(); /** * Do the camera view looking at the mansion */ int doInterface(); /** * Do the display of a room that has one or more evidence hotspots * available for display */ void doRoom(); /** * Shows the apartment screen */ int doApt(); /** * Loads data needed for displaying the initial apartment screen */ void loadTheApt(); /** * Synchronizes the game data */ void synchronize(Common::Serializer &s); }; } // End of namespace Voyeur #endif /* VOYEUR_FILES_H */