diff options
Diffstat (limited to 'engines/sci/graphics/frameout.h')
-rw-r--r-- | engines/sci/graphics/frameout.h | 554 |
1 files changed, 437 insertions, 117 deletions
diff --git a/engines/sci/graphics/frameout.h b/engines/sci/graphics/frameout.h index d1a706e8de..5323a2ad04 100644 --- a/engines/sci/graphics/frameout.h +++ b/engines/sci/graphics/frameout.h @@ -23,86 +23,190 @@ #ifndef SCI_GRAPHICS_FRAMEOUT_H #define SCI_GRAPHICS_FRAMEOUT_H -namespace Sci { +#include "sci/graphics/plane32.h" +#include "sci/graphics/screen_item32.h" -class GfxPicture; +namespace Sci { +// TODO: Don't do this this way +int splitRects(Common::Rect r, const Common::Rect &other, Common::Rect(&outRects)[4]); -struct PlaneLineEntry { - reg_t hunkId; - Common::Point startPoint; - Common::Point endPoint; - byte color; - byte priority; - byte control; +// TODO: Verify display styles and adjust names appropriately for +// types 1 through 12 & 15 (others are correct) +// Names should be: +// * VShutterIn, VShutterOut +// * HShutterIn, HShutterOut +// * WipeLeft, WipeRight, WipeDown, WipeUp +// * PixelDissolve +// * ShutDown and Kill? (and Plain and Fade?) +enum ShowStyleType /* : uint8 */ { + kShowStyleNone = 0, + kShowStyleHShutterOut = 1, + kShowStyleHShutterIn = 2, + kShowStyleVShutterOut = 3, + kShowStyleVShutterIn = 4, + kShowStyleWipeLeft = 5, + kShowStyleWipeRight = 6, + kShowStyleWipeUp = 7, + kShowStyleWipeDown = 8, + kShowStyleIrisOut = 9, + kShowStyleIrisIn = 10, + kShowStyle11 = 11, + kShowStyle12 = 12, + kShowStyleFadeOut = 13, + kShowStyleFadeIn = 14, + // TODO: Only in SCI3 + kShowStyleUnknown = 15 }; -typedef Common::List<PlaneLineEntry> PlaneLineList; - -struct PlaneEntry { - reg_t object; - int16 priority; - int16 lastPriority; - int16 planeOffsetX; - int16 planeOffsetY; - GuiResourceId pictureId; - Common::Rect planeRect; - Common::Rect planeClipRect; - Common::Rect upscaledPlaneRect; - Common::Rect upscaledPlaneClipRect; - bool planePictureMirrored; - byte planeBack; - PlaneLineList lines; -}; +/** + * Show styles represent transitions applied to draw planes. + * One show style per plane can be active at a time. + */ +struct ShowStyleEntry { + /** + * The ID of the plane this show style belongs to. + * In SCI2.1mid (at least SQ6), per-plane transitions + * were removed and a single plane ID is used. + */ + reg_t plane; -typedef Common::List<PlaneEntry> PlaneList; - -struct FrameoutEntry { - uint16 givenOrderNr; - reg_t object; - GuiResourceId viewId; - int16 loopNo; - int16 celNo; - int16 x, y, z; - int16 priority; - uint16 signal; - uint16 scaleSignal; - int16 scaleX; - int16 scaleY; - Common::Rect celRect; - GfxPicture *picture; - int16 picStartX; - int16 picStartY; - bool visible; -}; + /** + * The type of the transition. + */ + ShowStyleType type; -typedef Common::List<FrameoutEntry *> FrameoutList; + // TODO: This name is probably incorrect + bool fadeUp; -struct PlanePictureEntry { - reg_t object; - int16 startX; - int16 startY; - GuiResourceId pictureId; - GfxPicture *picture; - FrameoutEntry *pictureCels; // temporary -}; + /** + * The number of steps for the show style. + */ + int16 divisions; -typedef Common::List<PlanePictureEntry> PlanePictureList; + // NOTE: This property exists from SCI2 through at least + // SCI2.1mid but is never used in the actual processing + // of the styles? + int unknownC; -struct ScrollTextEntry { - reg_t bitmapHandle; - reg_t kWindow; - uint16 x; - uint16 y; -}; + /** + * The colour used by transitions that draw CelObjColor + * screen items. -1 for transitions that do not draw + * screen items. + */ + int16 color; + + // TODO: Probably uint32 + // TODO: This field probably should be used in order to + // provide time-accurate processing of show styles. In the + // actual SCI engine (at least 2–2.1mid) it appears that + // style transitions are drawn “as fast as possible”, one + // step per loop, even though this delay field exists + int delay; + + // TODO: Probably bool, but never seems to be true? + int animate; + + /** + * The wall time at which the next step of the animation + * should execute. + */ + uint32 nextTick; + + /** + * During playback of the show style, the current step + * (out of divisions). + */ + int currentStep; + + /** + * The next show style. + */ + ShowStyleEntry *next; + + /** + * Whether or not this style has finished running and + * is ready for disposal. + */ + bool processed; + + // + // Engine-specific properties for SCI2 through 2.1early + // + + // TODO: Could union this stuff to save literally + // several bytes of memory. + + /** + * The width of the plane. Used to determine the correct + * size of screen items for wipes. + */ + int width; + + /** + * The height of the plane. Used to determine the correct + * size of screen items for wipes. + */ + int height; + + /** + * The number of edges that a transition operates on. + * Slide wipe: 1 edge + * Reveal wipe: 2 edges + * Iris wipe: 4 edges + */ + // TODO: I have no idea why SCI engine stores this instead + // of a screenItems count + int edgeCount; + + /** + * Used by transition types 1 through 10. + * One screen item per division per edge. + */ + ScreenItemList screenItems; + + /** + * Used by transition types 11 and 12. A copy of the + * visible frame buffer. + */ + // TODO: This is a reg_t in SCI engine; not sure if + // we can avoid allocation through SegMan or not. + reg_t bitmapMemId; + + /** + * Used by transition types 11 and 12. A screen item + * used to display the associated bitmap data. + */ + ScreenItem *bitmapScreenItem; -typedef Common::Array<ScrollTextEntry> ScrollTextList; + /** + * A number used to pick pixels to dissolve by types + * 11 and 12. + */ + int dissolveSeed; + int unknown3A; + // max? + int dissolveInitial; -enum ViewScaleSignals32 { - kScaleSignalDoScaling32 = 0x0001, // enables scaling when drawing that cel (involves scaleX and scaleY) - kScaleSignalUnk1 = 0x0002, // unknown - kScaleSignalDisableGlobalScaling32 = 0x0004 + // + // Engine specific properties for SCI2.1mid through SCI3 + // + + /** + * The number of entries in the fadeColorRanges array. + */ + uint8 fadeColorRangesCount; + + /** + * A pointer to an dynamically sized array of palette + * indexes, in the order [ fromColor, toColor, ... ]. + * Only colors within this range are transitioned. + */ + uint16 *fadeColorRanges; }; +typedef Common::Array<DrawList> ScreenItemListList; +typedef Common::Array<RectList> EraseListList; + class GfxCache; class GfxCoordAdjuster32; class GfxPaint32; @@ -114,69 +218,285 @@ class GfxScreen; * Roughly equivalent to GraphicsMgr in the actual SCI engine. */ class GfxFrameout { +private: + bool _isHiRes; + GfxCache *_cache; + GfxCoordAdjuster32 *_coordAdjuster; + GfxPalette32 *_palette; + ResourceManager *_resMan; + GfxScreen *_screen; + SegManager *_segMan; + GfxPaint32 *_paint32; + public: GfxFrameout(SegManager *segMan, ResourceManager *resMan, GfxCoordAdjuster *coordAdjuster, GfxCache *cache, GfxScreen *screen, GfxPalette32 *palette, GfxPaint32 *paint32); ~GfxFrameout(); - void kernelAddPlane(reg_t object); - void kernelUpdatePlane(reg_t object); - void kernelDeletePlane(reg_t object); - void applyGlobalScaling(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 celHeight); - void kernelAddScreenItem(reg_t object); - void kernelUpdateScreenItem(reg_t object); - void kernelDeleteScreenItem(reg_t object); - void deletePlaneItems(reg_t planeObject); - FrameoutEntry *findScreenItem(reg_t object); - int16 kernelGetHighPlanePri(); - void kernelAddPicAt(reg_t planeObj, GuiResourceId pictureId, int16 pictureX, int16 pictureY); - void kernelFrameout(); - - void addPlanePicture(reg_t object, GuiResourceId pictureId, uint16 startX, uint16 startY = 0); - void deletePlanePictures(reg_t object); - reg_t addPlaneLine(reg_t object, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control); - void updatePlaneLine(reg_t object, reg_t hunkId, Common::Point startPoint, Common::Point endPoint, byte color, byte priority, byte control); - void deletePlaneLine(reg_t object, reg_t hunkId); void clear(); + void run(); - // Scroll text functions - void addScrollTextEntry(Common::String &text, reg_t kWindow, uint16 x, uint16 y, bool replace); - void showCurrentScrollText(); - void initScrollText(uint16 maxItems) { _maxScrollTexts = maxItems; } - void clearScrollTexts(); - void firstScrollText() { if (_scrollTexts.size() > 0) _curScrollText = 0; } - void lastScrollText() { if (_scrollTexts.size() > 0) _curScrollText = _scrollTexts.size() - 1; } - void prevScrollText() { if (_curScrollText > 0) _curScrollText--; } - void nextScrollText() { if (_curScrollText + 1 < (uint16)_scrollTexts.size()) _curScrollText++; } - void toggleScrollText(bool show) { _showScrollText = show; } +#pragma mark - +#pragma mark Screen items +private: + void deleteScreenItem(ScreenItem *screenItem, const reg_t plane); - void printPlaneList(Console *con); - void printPlaneItemList(Console *con, reg_t planeObject); +public: + void kernelAddScreenItem(const reg_t object); + void kernelUpdateScreenItem(const reg_t object); + void kernelDeleteScreenItem(const reg_t object); +#pragma mark - +#pragma mark Planes private: - bool _isHiRes; + /** + * The list of planes (i.e. layers) that have been added + * to the screen. + * + * @note This field is on `GraphicsMgr.screen` in SCI + * engine. + */ + PlaneList _planes; - void showVideo(); - void createPlaneItemList(reg_t planeObject, FrameoutList &itemList); - bool isPictureOutOfView(FrameoutEntry *itemEntry, Common::Rect planeRect, int16 planeOffsetX, int16 planeOffsetY); - void drawPicture(FrameoutEntry *itemEntry, int16 planeOffsetX, int16 planeOffsetY, bool planePictureMirrored); + /** + * Creates and adds a new plane to the plane list, or + * cancels deletion and updates an already-existing + * plane if a plane matching the given plane VM object + * already exists within the current plane list. + * + * @note This method is on Screen in SCI engine, but it + * is only ever called on `GraphicsMgr.screen`. + */ + void addPlane(Plane &plane); - SegManager *_segMan; - ResourceManager *_resMan; - GfxCoordAdjuster32 *_coordAdjuster; - GfxCache *_cache; - GfxPalette32 *_palette; - GfxScreen *_screen; - GfxPaint32 *_paint32; + /** + * Updates an existing plane with properties from the + * given VM object. + */ + void updatePlane(Plane &plane); - FrameoutList _screenItems; - PlaneList _planes; - PlanePictureList _planePictures; - ScrollTextList _scrollTexts; - int16 _curScrollText; - bool _showScrollText; - uint16 _maxScrollTexts; +public: + const PlaneList &getPlanes() const { + return _planes; + } + void kernelAddPlane(const reg_t object); + void kernelUpdatePlane(const reg_t object); + void kernelDeletePlane(const reg_t object); + int16 kernelGetHighPlanePri(); + +#pragma mark - +#pragma mark Pics +public: + void kernelAddPicAt(const reg_t planeObject, const GuiResourceId pictureId, const int16 pictureX, const int16 pictureY, const bool mirrorX); + +#pragma mark - + + // TODO: Remap-related? + void kernelSetPalStyleRange(const uint8 fromColor, const uint8 toColor); + +#pragma mark - +#pragma mark Transitions +private: + int *_dissolveSequenceSeeds; + int16 *_defaultDivisions; + int16 *_defaultUnknownC; + + /** + * TODO: Documentation + */ + ShowStyleEntry *_showStyles; + + inline ShowStyleEntry *findShowStyleForPlane(const reg_t planeObj) const; + inline ShowStyleEntry *deleteShowStyleInternal(ShowStyleEntry *const showStyle); + void processShowStyles(); + bool processShowStyleNone(ShowStyleEntry *showStyle); + bool processShowStyleMorph(ShowStyleEntry *showStyle); + bool processShowStyleFade(const int direction, ShowStyleEntry *showStyle); +#if 0 + bool processShowStyleWipe(const int direction, ShowStyleEntry *const showStyle); +#endif + +public: + // NOTE: This signature is taken from SCI3 Phantasmagoria 2 + // and is valid for all implementations of SCI32 + void kernelSetShowStyle(const uint16 argc, const reg_t &planeObj, const ShowStyleType type, const int16 seconds, const int16 direction, const int16 priority, const int16 animate, const int16 frameOutNow, const reg_t &pFadeArray, const int16 divisions, const int16 blackScreen); + +#pragma mark - +#pragma mark Rendering +private: + /** + * TODO: Documentation + */ + int8 _styleRanges[256]; + + /** + * The internal display pixel buffer. During frameOut, + * this buffer is drawn into according to the draw and + * erase rects calculated by `calcLists`, then drawn out + * to the hardware surface according to the `_showList` + * rects (which are also calculated by `calcLists`). + */ + Buffer _currentBuffer; + + // TODO: In SCI2.1/SQ6, priority map pixels are not allocated + // by default. In SCI2/GK1, pixels are allocated, but not used + // anywhere except within CelObj::Draw in seemingly the same + // way they are used in SCI2.1/SQ6: that is, never read, only + // written. + Buffer _priorityMap; + + /** + * TODO: Documentation + */ + bool _remapOccurred; - void sortPlanes(); + /** + * Whether or not the data in the current buffer is what + * is visible to the user. During rendering updates, + * this flag is set to false. + */ + bool _frameNowVisible; + + /** + * TODO: Document + * TODO: Depending upon if the engine ever modifies this + * rect, it may be stupid to store it separately instead + * of just getting width/height from GfxScreen. + * + * @note This field is on `GraphicsMgr.screen` in SCI + * engine. + */ + Common::Rect _screenRect; + + /** + * A list of rectangles, in display coordinates, that + * represent portions of the internal screen buffer that + * should be drawn to the hardware display surface. + * + * @note This field is on `GraphicsMgr.screen` in SCI + * engine. + */ + RectList _showList; + + /** + * The amount of extra overdraw that is acceptable when + * merging two show list rectangles together into a + * single larger rectangle. + * + * @note This field is on `GraphicsMgr.screen` in SCI + * engine. + */ + int _overdrawThreshold; + + /** + * A list of planes that are currently drawn to the + * hardware display surface. Used to calculate + * differences in plane properties between the last + * frame and current frame. + * + * @note This field is on `GraphicsMgr.visibleScreen` in + * SCI engine. + */ + PlaneList _visiblePlanes; + + /** + * Calculates the location and dimensions of dirty rects + * over the entire screen for rendering the next frame. + * The draw and erase lists in `drawLists` and + * `eraseLists` each represent one plane on the screen. + */ + void calcLists(ScreenItemListList &drawLists, EraseListList &eraseLists, const Common::Rect &calcRect); + + /** + * Erases the areas in the given erase list from the + * visible screen buffer by filling them with the color + * from the corresponding plane. This is an optimisation + * for coloured-type planes only; other plane types have + * to be redrawn from pixel data. + */ + void drawEraseList(const RectList &eraseList, const Plane &plane); + + /** + * Draws all screen items from the given draw list to + * the visible screen buffer. + */ + void drawScreenItemList(const DrawList &screenItemList); + + /** + * Updates the internal screen buffer for the next + * frame. If `shouldShowBits` is true, also sends the + * buffer to hardware. + */ + void frameOut(const bool shouldShowBits, const Common::Rect &rect); + + /** + * Adds a new rectangle to the list of regions to write + * out to the hardware. The provided rect may be merged + * into an existing rectangle to reduce the number of + * blit operations. + */ + void mergeToShowList(const Common::Rect &drawRect, RectList &showList, const int overdrawThreshold); + + /** + * TODO: Documentation + */ + void palMorphFrameOut(const int8 *styleRanges, const ShowStyleEntry *showStyle); + + /** + * Writes the internal frame buffer out to hardware and + * clears the show list. + */ + void showBits(); + +public: + /** + * TODO: Document + * This is used by CelObj::Draw. + */ + bool _hasRemappedScreenItem; + + /** + * Whether palMorphFrameOut should be used instead of + * frameOut for rendering. Used by kMorphOn to + * explicitly enable palMorphFrameOut for one frame. + */ + bool _palMorphIsOn; + + inline Buffer &getCurrentBuffer() { + return _currentBuffer; + } + + void kernelFrameout(const bool showBits); + + /** + * Modifies the raw pixel data for the next frame with + * new palette indexes based on matched style ranges. + */ + void alterVmap(const Palette &palette1, const Palette &palette2, const int8 style, const int8 *const styleRanges); + + // TODO: SCI2 engine never uses priority map? + inline Buffer &getPriorityMap() { + return _priorityMap; + } + + // NOTE: This function is used within ScreenItem subsystem and assigned + // to various booleanish fields that seem to represent the state of the + // screen item (created, updated, deleted). In GK1/DOS, Phant1/m68k, + // SQ6/DOS, SQ6/Win, and Phant2/Win, this function simply returns 1. If + // you know of any game/environment where this function returns some + // value other than 1, or if you used to work at Sierra and can explain + // why this is a thing (and if anyone needs to care about it), please + // open a ticket!! + inline int getScreenCount() const { + return 1; + }; + +#pragma mark - +#pragma mark Debugging +public: + void printPlaneList(Console *con) const; + void printVisiblePlaneList(Console *con) const; + void printPlaneListInternal(Console *con, const PlaneList &planeList) const; + void printPlaneItemList(Console *con, const reg_t planeObject) const; }; } // End of namespace Sci |