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// 24// Render Surface Shape Display include file 25// 26 27// 28// Macros to define before including this: 29// 30// #define NO_CLIPPING to disable shape clipping 31// 32// #define FLIP_SHAPES to flip rendering 33// 34// #define FLIP_CONDITIONAL to an argument of the function so FLIPPING can be 35// enabled/disabled with a bool 36// 37// #define XFORM_SHAPES to enable XFORMing 38// 39// #define XFORM_CONDITIONAL to an argument of the function so XFORM can be 40// enabled/disabled with a bool 41// 42// #define BLEND_SHAPES(src,dst) to an a specified blend function. 43// 44// #define BLEND_CONDITIONAL to an argument of the function so BLEND 45// painting can be enabled/disabled with a bool 46// 47 48// 49// Macros defined by this file: 50// 51// NOT_CLIPPED_Y - Does Y Clipping check per line 52// 53// NOT_CLIPPED_X - Does X Clipping check per Pixel 54// 55// LINE_END_ASSIGN - Calcuates the line_end pointer required for X clipping 56// 57// XNEG - Negates X values if doing shape flipping 58// 59// USE_XFORM_FUNC - Checks to see if we want to use XForm Blending for this pixel 60// 61// CUSTOM_BLEND - Final Blend for invisiblity 62// 63 64// 65// XForm = TRUE 66// 67#ifdef XFORM_SHAPES 68 69#ifdef XFORM_CONDITIONAL 70#define USE_XFORM_FUNC ((XFORM_CONDITIONAL) && xform_pal[*srcpix]) 71#else 72#define USE_XFORM_FUNC (xform_pal[*srcpix]) 73#endif 74 75// 76// XForm = FALSE 77// 78#else 79#define USE_XFORM_FUNC 0 80#endif 81 82 83// 84// Flipping = TRUE 85// 86#ifdef FLIP_SHAPES 87 88#ifdef FLIP_CONDITIONAL 89const int32 neg = (FLIP_CONDITIONAL)?-1:0; 90#define XNEG(x) (((x)+neg)^neg) 91#else 92#define XNEG(x) (-(x)) 93#endif 94 95// Flipping = FALSE 96#else 97#define XNEG(x)(+(x)) 98#endif 99 100 101// 102// No Clipping = TRUE 103// 104#ifdef NO_CLIPPING 105 106#define LINE_END_ASSIGN // 107#define NOT_CLIPPED_X (1) 108#define NOT_CLIPPED_Y (1) 109#define OFFSET_PIXELS (_pixels) 110 111// 112// No Clipping = FALSE 113// 114#else 115 116 const int scrn_width = _clipWindow.width(); 117 const int scrn_height = _clipWindow.height(); 118 119#define LINE_END_ASSIGN const uintX *dst_line_end = dst_line_start + scrn_width 120#define NOT_CLIPPED_X (dstpix >= dst_line_start && dstpix < dst_line_end) 121#define NOT_CLIPPED_Y (line >= 0 && line < scrn_height) 122#define OFFSET_PIXELS (off_pixels) 123 124 uint8 *off_pixels = _pixels + _clipWindow.left * sizeof(uintX) + _clipWindow.top * _pitch; 125 x -= _clipWindow.left; 126 y -= _clipWindow.top; 127 128#endif 129 130 131// 132// Invisilibity = TRUE 133// 134#ifdef BLEND_SHAPES 135 136#ifdef BLEND_CONDITIONAL 137#define CUSTOM_BLEND(src) static_cast<uintX>((BLEND_CONDITIONAL)?BLEND_SHAPES(src,*dstpix):src) 138#else 139#define CUSTOM_BLEND(src) static_cast<uintX>(BLEND_SHAPES(src,*dstpix)) 140#endif 141 142// 143// Invisilibity = FALSE 144// 145#else 146 147#define CUSTOM_BLEND(src) static_cast<uintX>(src) 148 149#endif 150 151// 152// Destination Alpha Masking 153// 154#ifdef DESTALPHA_MASK 155 156#define NOT_DESTINATION_MASKED (*pixptr & RenderSurface::_format.aMask) 157 158#else 159 160#define NOT_DESTINATION_MASKED (1) 161 162#endif 163 164// 165// The Function 166// 167 168 // Sanity check 169 if (framenum >= s->frameCount()) 170 return; 171 if (s->getPalette() == 0) 172 return; 173 174 const ShapeFrame *frame = s->getFrame(framenum); 175 if (!frame) 176 return; 177 const uint8 *srcpixels = frame->_pixels; 178 const uint8 *srcmask = frame->_mask; 179 const uint32 *pal = untformed_pal ? 180 s->getPalette()->_native_untransformed: 181 s->getPalette()->_native; 182 183#ifdef XFORM_SHAPES 184 const uint32 *xform_pal = untformed_pal ? 185 s->getPalette()->_xform_untransformed: 186 s->getPalette()->_xform; 187#endif 188 189 const int32 width_ = frame->_width; 190 const int32 height_ = frame->_height; 191 x -= XNEG(frame->_xoff); 192 y -= frame->_yoff; 193 194 assert(_pixels00 && _pixels && srcpixels && srcmask); 195 196 for (int i = 0; i < height_; i++) { 197 const int line = y + i; 198 199 if (NOT_CLIPPED_Y) { 200 const uint8 *srcline = srcpixels + i * width_; 201 const uint8 *srcmaskline = srcmask + i * width_; 202 uintX *dst_line_start = reinterpret_cast<uintX *>(OFFSET_PIXELS + _pitch * line); 203 LINE_END_ASSIGN; 204 205 for (int xpos = 0; xpos < width_; xpos++) { 206 if (srcmaskline[xpos] == 0) 207 continue; 208 209 uintX *dstpix = dst_line_start + x + XNEG(xpos); 210 211 if (NOT_CLIPPED_X && NOT_DESTINATION_MASKED) { 212 const uint8 *srcpix = srcline + xpos; 213 #ifdef XFORM_SHAPES 214 if (USE_XFORM_FUNC) { 215 *dstpix = CUSTOM_BLEND(BlendPreModulated(xform_pal[*srcpix], *dstpix)); 216 } 217 else 218 #endif 219 { 220 *dstpix = CUSTOM_BLEND(pal[*srcpix]); 221 } 222 } 223 } 224 } 225 } 226 227#undef NOT_DESTINATION_MASKED 228#undef OFFSET_PIXELS 229#undef CUSTOM_BLEND 230#undef LINE_END_ASSIGN 231#undef NOT_CLIPPED_X 232#undef NOT_CLIPPED_Y 233#undef XNEG 234#undef USE_XFORM_FUNC 235