/* 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 KYRA_SCREEN_EOB_SEGACD_H #define KYRA_SCREEN_EOB_SEGACD_H #ifdef ENABLE_EOB #define SEGA_PERFORMANCE true #define SEGA_USE_MEMPOOL true #include "kyra/graphics/screen_eob.h" #if SEGA_USE_MEMPOOL #include "common/memorypool.h" #endif namespace Kyra { class SegaRenderer { public: enum Plane { kPlaneA = 0, kPlaneB = 1, kWindowPlane = 2 }; enum WindowMode { kWinToLeft = 0, kWinToTop = 0, kWinToRight = 1, kWinToBottom = 1 }; enum HScrollMode { kHScrollFullScreen = 0, kHScroll8PixelRows, kHScroll1PixelRows }; enum VScrollMode { kVScrollFullScreen = 0, kVScroll16PixelStrips }; public: SegaRenderer(Screen_EoB *screen); ~SegaRenderer(); void setResolution(int w, int h); void setPlaneTableLocation(int plane, uint16 addr); // The hardware allows/demands separate modification of the vertical and horizontal properties. // To allow this without making another function the w/h parameters can be set to -1 which will // keep the existing value for that property. void setupPlaneAB(int pixelWidth, int pixelHeigth); // The hardware allows/demands separate modification of the vertical and horizontal properties. // To allow this without making another function the blockX/Y parameters can be set to -1 which // will keep the existing value for that property. void setupWindowPlane(int blockX, int blockY, int horizontalMode, int verticalMode); void setHScrollTableLocation(int addr); void setSpriteTableLocation(int addr); void setPitch(int pitch); void setHScrollMode(int mode); void setVScrollMode(int mode); void loadToVRAM(const void *data, uint16 dataSize, uint16 addr); void loadStreamToVRAM(Common::SeekableReadStream *in, uint16 addr, bool compressedData = false); void memsetVRAM(int addr, uint8 val, int len); void fillRectWithTiles(int vramArea, int x, int y, int w, int h, uint16 nameTblEntry, bool incr = false, bool topToBottom = false, const uint16 *patternTable = 0); void writeUint16VSRAM(int addr, uint16 value); void writeUint8VRAM(int addr, uint8 value); void writeUint16VRAM(int addr, uint16 value); void clearPlanes(); void render(int destPageNum, int renderLeft = -1, int renderTop = -1, int renderWidth = -1, int renderHeight = -1, bool spritesOnly = false); private: void renderPlanePart(int plane, uint8 *dstBuffer, int x1, int y1, int x2, int y2); void renderPlaneTile(uint8 *dst, int destX, const uint16 *nameTable, int vScrollLSBStart, int vScrollLSBEnd, int hScrollTableIndex, uint16 pitch); void renderSpriteTile(uint8 *dst, uint8 *mask, int x, int y, uint16 tile, uint8 pal, bool vflip, bool hflip, bool prio); #if SEGA_PERFORMANCE template void renderLineFragmentM(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal); template void renderLineFragmentD(uint8 *dst, const uint8 *src, int start, int end, uint8 pal); typedef void(SegaRenderer::*renderFuncM)(uint8*, uint8*, const uint8*, int, int, uint8); typedef void(SegaRenderer::*renderFuncD)(uint8*, const uint8*, int, int, uint8); const renderFuncM *_renderLineFragmentM; const renderFuncD *_renderLineFragmentD; #else template void renderLineFragment(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal); #endif void initPrioRenderTask(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal, bool hflip); void clearPrioChain(); struct SegaPlane { SegaPlane() : blockX(0), blockY(0), w(0), h(0), mod(0), nameTable(0), nameTableSize(0) {} int blockX, blockY; uint16 w, h, mod; uint16 *nameTable; uint16 nameTableSize; }; SegaPlane _planes[3]; uint8 *_vram; uint16 *_vsram; uint16 *_hScrollTable; uint16 *_spriteTable; uint8 *_spriteMask; uint8 _hScrollMode; uint8 _vScrollMode; uint16 _pitch; uint16 _numSpritesMax; struct PrioTileRenderObj { PrioTileRenderObj(PrioTileRenderObj *chainEnd, uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal, bool hflip) : _pred(chainEnd), _next(0), _dst(dst), _mask(mask), _src(src), _start(start), _end(end), _pal(pal), _hflip(hflip) { if (_pred) _pred->_next = this; } uint8 *_dst; uint8 *_mask; const uint8 *_src; int _start; int _end; uint8 _pal; bool _hflip; PrioTileRenderObj *_pred; PrioTileRenderObj *_next; }; #if SEGA_USE_MEMPOOL Common::ObjectPool _prioRenderMemPool; #endif PrioTileRenderObj *_prioChainStart, *_prioChainEnd; uint16 _screenW, _screenH, _blocksW, _blocksH; Screen_EoB *_screen; }; class SegaAnimator { public: SegaAnimator(SegaRenderer *renderer); ~SegaAnimator(); void initSprite(int id, int16 x, int16 y, uint16 nameTbl, uint16 hw); void clearSprites(); void moveMorphSprite(int id, uint16 nameTbl, int16 addX, int16 addY); void moveSprites(int id, uint16 num, int16 addX, int16 addY); void moveSprites2(int id, uint16 num, int16 addX, int16 addY); void update(); private: struct Sprite { int16 x; int16 y; uint16 nameTbl; uint16 hw; }; uint16 *_tempBuffer; Sprite *_sprites; SegaRenderer *_renderer; bool _needUpdate; }; class ScrollManager { public: ScrollManager(SegaRenderer *renderer); ~ScrollManager(); void setVScrollTimers(uint16 destA, int incrA, int delayA, uint16 destB, int incrB, int delayB); void setHScrollTimers(uint16 destA, int incrA, int delayA, uint16 destB, int incrB, int delayB); void updateScrollTimers(); void fastForward(); private: struct ScrollTimer { ScrollTimer() : _offsCur(0), _offsDest(0), _incr(0), _delay(0), _timer(0) {} int16 _offsCur; int16 _offsDest; int16 _incr; int16 _delay; int16 _timer; }; ScrollTimer *_vScrollTimers; ScrollTimer *_hScrollTimers; SegaRenderer *_renderer; }; } // End of namespace Kyra #endif // ENABLE_EOB #endif