1 /* ScummVM - Graphic Adventure Engine 2 * 3 * ScummVM is the legal property of its developers, whose names 4 * are too numerous to list here. Please refer to the COPYRIGHT 5 * file distributed with this source distribution. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 20 * 21 */ 22 23 #ifndef KYRA_SCREEN_EOB_SEGACD_H 24 #define KYRA_SCREEN_EOB_SEGACD_H 25 26 #ifdef ENABLE_EOB 27 28 #define SEGA_PERFORMANCE true 29 #define SEGA_USE_MEMPOOL true 30 31 #include "kyra/graphics/screen_eob.h" 32 33 #if SEGA_USE_MEMPOOL 34 #include "common/memorypool.h" 35 #endif 36 37 namespace Kyra { 38 39 class SegaRenderer { 40 public: 41 enum Plane { 42 kPlaneA = 0, 43 kPlaneB = 1, 44 kWindowPlane = 2 45 }; 46 47 enum WindowMode { 48 kWinToLeft = 0, 49 kWinToTop = 0, 50 kWinToRight = 1, 51 kWinToBottom = 1 52 }; 53 54 enum HScrollMode { 55 kHScrollFullScreen = 0, 56 kHScroll8PixelRows, 57 kHScroll1PixelRows 58 }; 59 60 enum VScrollMode { 61 kVScrollFullScreen = 0, 62 kVScroll16PixelStrips 63 }; 64 65 public: 66 SegaRenderer(Screen_EoB *screen); 67 ~SegaRenderer(); 68 69 void setResolution(int w, int h); 70 void setPlaneTableLocation(int plane, uint16 addr); 71 // The hardware allows/demands separate modification of the vertical and horizontal properties. 72 // To allow this without making another function the w/h parameters can be set to -1 which will 73 // keep the existing value for that property. 74 void setupPlaneAB(int pixelWidth, int pixelHeigth); 75 // The hardware allows/demands separate modification of the vertical and horizontal properties. 76 // To allow this without making another function the blockX/Y parameters can be set to -1 which 77 // will keep the existing value for that property. 78 void setupWindowPlane(int blockX, int blockY, int horizontalMode, int verticalMode); 79 void setHScrollTableLocation(int addr); 80 void setSpriteTableLocation(int addr); 81 void setPitch(int pitch); 82 void setHScrollMode(int mode); 83 void setVScrollMode(int mode); 84 85 void loadToVRAM(const void *data, uint16 dataSize, uint16 addr); 86 void loadStreamToVRAM(Common::SeekableReadStream *in, uint16 addr, bool compressedData = false); 87 void memsetVRAM(int addr, uint8 val, int len); 88 void fillRectWithTiles(int vramArea, int x, int y, int w, int h, uint16 nameTblEntry, bool incr = false, bool topToBottom = false, const uint16 *patternTable = 0); 89 void writeUint16VSRAM(int addr, uint16 value); 90 void writeUint8VRAM(int addr, uint8 value); 91 void writeUint16VRAM(int addr, uint16 value); 92 void clearPlanes(); 93 94 void render(int destPageNum, int renderLeft = -1, int renderTop = -1, int renderWidth = -1, int renderHeight = -1, bool spritesOnly = false); 95 private: 96 void renderPlanePart(int plane, uint8 *dstBuffer, int x1, int y1, int x2, int y2); 97 void renderPlaneTile(uint8 *dst, int destX, const uint16 *nameTable, int vScrollLSBStart, int vScrollLSBEnd, int hScrollTableIndex, uint16 pitch); 98 void renderSpriteTile(uint8 *dst, uint8 *mask, int x, int y, uint16 tile, uint8 pal, bool vflip, bool hflip, bool prio); 99 #if SEGA_PERFORMANCE 100 template<bool hflip, bool oddStart, bool oddEnd> void renderLineFragmentM(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal); 101 template<bool hflip, bool oddStart, bool oddEnd> void renderLineFragmentD(uint8 *dst, const uint8 *src, int start, int end, uint8 pal); 102 typedef void(SegaRenderer::*renderFuncM)(uint8*, uint8*, const uint8*, int, int, uint8); 103 typedef void(SegaRenderer::*renderFuncD)(uint8*, const uint8*, int, int, uint8); 104 const renderFuncM *_renderLineFragmentM; 105 const renderFuncD *_renderLineFragmentD; 106 #else 107 template<bool hflip> void renderLineFragment(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal); 108 #endif 109 110 void initPrioRenderTask(uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal, bool hflip); 111 void clearPrioChain(); 112 113 struct SegaPlane { SegaPlaneSegaPlane114 SegaPlane() : blockX(0), blockY(0), w(0), h(0), mod(0), nameTable(0), nameTableSize(0) {} 115 int blockX, blockY; 116 uint16 w, h, mod; 117 uint16 *nameTable; 118 uint16 nameTableSize; 119 }; 120 121 SegaPlane _planes[3]; 122 uint8 *_vram; 123 uint16 *_vsram; 124 uint16 *_hScrollTable; 125 uint16 *_spriteTable; 126 uint8 *_spriteMask; 127 uint8 _hScrollMode; 128 uint8 _vScrollMode; 129 uint16 _pitch; 130 uint16 _numSpritesMax; 131 132 struct PrioTileRenderObj { PrioTileRenderObjPrioTileRenderObj133 PrioTileRenderObj(PrioTileRenderObj *chainEnd, uint8 *dst, uint8 *mask, const uint8 *src, int start, int end, uint8 pal, bool hflip) : 134 _pred(chainEnd), _next(0), _dst(dst), _mask(mask), _src(src), _start(start), _end(end), _pal(pal), _hflip(hflip) { 135 if (_pred) 136 _pred->_next = this; 137 } 138 uint8 *_dst; 139 uint8 *_mask; 140 const uint8 *_src; 141 int _start; 142 int _end; 143 uint8 _pal; 144 bool _hflip; 145 PrioTileRenderObj *_pred; 146 PrioTileRenderObj *_next; 147 }; 148 149 #if SEGA_USE_MEMPOOL 150 Common::ObjectPool<PrioTileRenderObj> _prioRenderMemPool; 151 #endif 152 PrioTileRenderObj *_prioChainStart, *_prioChainEnd; 153 uint16 _screenW, _screenH, _blocksW, _blocksH; 154 Screen_EoB *_screen; 155 }; 156 157 class SegaAnimator { 158 public: 159 SegaAnimator(SegaRenderer *renderer); 160 ~SegaAnimator(); 161 162 void initSprite(int id, int16 x, int16 y, uint16 nameTbl, uint16 hw); 163 void clearSprites(); 164 void moveMorphSprite(int id, uint16 nameTbl, int16 addX, int16 addY); 165 void moveSprites(int id, uint16 num, int16 addX, int16 addY); 166 void moveSprites2(int id, uint16 num, int16 addX, int16 addY); 167 168 void update(); 169 170 private: 171 struct Sprite { 172 int16 x; 173 int16 y; 174 uint16 nameTbl; 175 uint16 hw; 176 }; 177 178 uint16 *_tempBuffer; 179 Sprite *_sprites; 180 SegaRenderer *_renderer; 181 bool _needUpdate; 182 }; 183 184 class ScrollManager { 185 public: 186 ScrollManager(SegaRenderer *renderer); 187 ~ScrollManager(); 188 189 void setVScrollTimers(uint16 destA, int incrA, int delayA, uint16 destB, int incrB, int delayB); 190 void setHScrollTimers(uint16 destA, int incrA, int delayA, uint16 destB, int incrB, int delayB); 191 void updateScrollTimers(); 192 void fastForward(); 193 194 private: 195 struct ScrollTimer { ScrollTimerScrollTimer196 ScrollTimer() : _offsCur(0), _offsDest(0), _incr(0), _delay(0), _timer(0) {} 197 int16 _offsCur; 198 int16 _offsDest; 199 int16 _incr; 200 int16 _delay; 201 int16 _timer; 202 }; 203 204 ScrollTimer *_vScrollTimers; 205 ScrollTimer *_hScrollTimers; 206 SegaRenderer *_renderer; 207 }; 208 209 } // End of namespace Kyra 210 211 #endif // ENABLE_EOB 212 213 #endif 214