/* 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 AGI_GRAPHICS_H #define AGI_GRAPHICS_H #include "agi/font.h" namespace Agi { #define SCRIPT_WIDTH 160 #define SCRIPT_HEIGHT 168 #define VISUAL_WIDTH 160 #define VISUAL_HEIGHT 200 #define DISPLAY_DEFAULT_WIDTH 320 #define DISPLAY_DEFAULT_HEIGHT 200 enum GfxScreenUpscaledMode { DISPLAY_UPSCALED_DISABLED = 0, DISPLAY_UPSCALED_640x400 = 1 }; class AgiEngine; enum GfxScreenMasks { GFX_SCREEN_MASK_VISUAL = 1, GFX_SCREEN_MASK_PRIORITY = 2, GFX_SCREEN_MASK_ALL = GFX_SCREEN_MASK_VISUAL | GFX_SCREEN_MASK_PRIORITY }; struct MouseCursorData { const byte *bitmapData; byte *bitmapDataAllocated; uint16 width; uint16 height; int hotspotX; int hotspotY; }; class GfxMgr { private: AgiBase *_vm; GfxFont *_font; uint8 _paletteGfxMode[256 * 3]; uint8 _paletteTextMode[256 * 3]; uint8 _agipalPalette[16 * 3]; int _agipalFileNum; public: GfxMgr(AgiBase *vm, GfxFont *font); int initVideo(); int deinitVideo(); void initPalette(uint8 *destPalette, const uint8 *paletteData, uint colorCount = 16, uint fromBits = 6, uint toBits = 8); void initPaletteCLUT(uint8 *destPalette, const uint16 *paletteCLUTData, uint colorCount = 16); void setAGIPal(int); int getAGIPalFileNum(); void setPalette(bool GfxModePalette); void initMouseCursor(MouseCursorData *mouseCursor, const byte *bitmapData, uint16 width, uint16 height, int hotspotX, int hotspotY); void setMouseCursor(bool busy = false); void setRenderStartOffset(uint16 offsetY); uint16 getRenderStartDisplayOffsetY(); void translateGamePosToDisplayScreen(int16 &x, int16 &y); void translateVisualPosToDisplayScreen(int16 &x, int16 &y); void translateDisplayPosToGameScreen(int16 &x, int16 &y); void translateVisualDimensionToDisplayScreen(int16 &width, int16 &height); void translateDisplayDimensionToVisualScreen(int16 &width, int16 &height); void translateGameRectToDisplayScreen(int16 &x, int16 &y, int16 &width, int16 &height); void translateVisualRectToDisplayScreen(int16 &x, int16 &y, int16 &width, int16 &height); void translateDisplayRectToVisualScreen(int16 &x, int16 &y, int16 &width, int16 &height); uint32 getDisplayOffsetToGameScreenPos(int16 x, int16 y); uint32 getDisplayOffsetToVisualScreenPos(int16 x, int16 y); void copyDisplayRectToScreen(int16 x, int16 y, int16 width, int16 height); void copyDisplayRectToScreen(int16 x, int16 adjX, int16 y, int16 adjY, int16 width, int16 adjWidth, int16 height, int16 adjHeight); void copyDisplayRectToScreenUsingGamePos(int16 x, int16 y, int16 width, int16 height); void copyDisplayRectToScreenUsingVisualPos(int16 x, int16 y, int16 width, int16 height); void copyDisplayToScreen(); void translateFontPosToDisplayScreen(int16 &x, int16 &y); void translateDisplayPosToFontScreen(int16 &x, int16 &y); void translateFontDimensionToDisplayScreen(int16 &width, int16 &height); void translateFontRectToDisplayScreen(int16 &x, int16 &y, int16 &width, int16 &height); Common::Rect getFontRectForDisplayScreen(int16 column, int16 row, int16 width, int16 height); private: uint _pixels; uint _displayPixels; byte *_activeScreen; byte *_gameScreen; // 160x168 - screen, where the actual game content is drawn to (actual graphics, not including status line, prompt, etc.) byte *_priorityScreen; // 160x168 - screen contains priority information of the game screen // the term "visual screen" is effectively the display screen, but at 160x200 resolution. Used for coordinate translation byte *_displayScreen; // 320x200 or 640x400 - screen, that the game is rendered to and which is then copied to framebuffer uint16 _displayScreenWidth; uint16 _displayScreenHeight; uint16 _displayFontWidth; uint16 _displayFontHeight; uint16 _displayWidthMulAdjust; uint16 _displayHeightMulAdjust; /** * This variable defines, if upscaled hires is active and what upscaled mode * is used. */ GfxScreenUpscaledMode _upscaledHires; bool _priorityTableSet; uint8 _priorityTable[SCRIPT_HEIGHT]; /**< priority table */ MouseCursorData _mouseCursor; MouseCursorData _mouseCursorBusy; uint16 _renderStartVisualOffsetY; uint16 _renderStartDisplayOffsetY; public: uint16 getDisplayScreenWidth() { return _displayScreenWidth; } uint16 getDisplayFontWidth() { return _displayFontWidth; } uint16 getDisplayFontHeight() { return _displayFontHeight; } GfxScreenUpscaledMode getUpscaledHires() { return _upscaledHires; } void debugShowMap(int mapNr); void clear(byte color, byte priority); void clearDisplay(byte color, bool copyToScreen = true); void putPixel(int16 x, int16 y, byte drawMask, byte color, byte priority); void putPixelOnDisplay(int16 x, int16 y, byte color); void putPixelOnDisplay(int16 x, int16 adjX, int16 y, int16 adjY, byte color); void putFontPixelOnDisplay(int16 baseX, int16 baseY, int16 addX, int16 addY, byte color, bool isHires); byte getColor(int16 x, int16 y); byte getPriority(int16 x, int16 y); bool checkControlPixel(int16 x, int16 y, byte newPriority); byte getCGAMixtureColor(byte color); void render_Block(int16 x, int16 y, int16 width, int16 height, bool copyToScreen = true); bool render_Clip(int16 &x, int16 &y, int16 &width, int16 &height, int16 clipAgainstWidth = SCRIPT_WIDTH, int16 clipAgainstHeight = SCRIPT_HEIGHT); private: void render_BlockEGA(int16 x, int16 y, int16 width, int16 height, bool copyToScreen); void render_BlockCGA(int16 x, int16 y, int16 width, int16 height, bool copyToScreen); void render_BlockHercules(int16 x, int16 y, int16 width, int16 height, bool copyToScreen); public: void transition_Amiga(); void transition_AtariSt(); void block_save(int16 x, int16 y, int16 width, int16 height, byte *bufferPtr); void block_restore(int16 x, int16 y, int16 width, int16 height, byte *bufferPtr); void drawBox(int16 x, int16 y, int16 width, int16 height, byte backgroundColor, byte lineColor); void drawDisplayRect(int16 x, int16 y, int16 width, int16 height, byte color, bool copyToScreen = true); void drawDisplayRect(int16 x, int16 adjX, int16 y, int16 adjY, int16 width, int16 adjWidth, int16 height, int16 adjHeight, byte color, bool copyToScreen = true); private: void drawDisplayRectEGA(int16 x, int16 y, int16 width, int16 height, byte color); void drawDisplayRectCGA(int16 x, int16 y, int16 width, int16 height, byte color); public: void drawCharacter(int16 row, int16 column, byte character, byte foreground, byte background, bool disabledLook); void drawStringOnDisplay(int16 x, int16 y, const char *text, byte foreground, byte background); void drawStringOnDisplay(int16 x, int16 adjX, int16 y, int16 adjY, const char *text, byte foregroundColor, byte backgroundColor); void drawCharacterOnDisplay(int16 x, int16 y, byte character, byte foreground, byte background, byte transformXOR = 0, byte transformOR = 0); void shakeScreen(int16 repeatCount); void updateScreen(); void initPriorityTable(); void createDefaultPriorityTable(uint8 *priorityTable); void setPriorityTable(int16 priorityBase); bool saveLoadWasPriorityTableModified(); int16 saveLoadGetPriority(int16 yPos); void saveLoadSetPriorityTableModifiedBool(bool wasModified); void saveLoadSetPriority(int16 yPos, int16 priority); void saveLoadFigureOutPriorityTableModifiedBool(); int16 priorityToY(int16 priority); int16 priorityFromY(int16 yPos); }; } // End of namespace Agi #endif /* AGI_GRAPHICS_H */