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 * aint32 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 * Based on the original sources
23 * Faery Tale II -- The Halls of the Dead
24 * (c) 1993-1996 The Wyrmkeep Entertainment Co.
25 */
26
27 #include "common/debug.h"
28 #include "common/memstream.h"
29 #include "graphics/surface.h"
30
31 #include "saga2/saga2.h"
32 #include "saga2/gdraw.h"
33
34 namespace Saga2 {
35
_BltPixels(uint8 * srcPtr,uint32 srcMod,uint8 * dstPtr,uint32 dstMod,uint32 width,uint32 height)36 void _BltPixels(uint8 *srcPtr, uint32 srcMod, uint8 *dstPtr, uint32 dstMod, uint32 width, uint32 height) {
37 for (uint y = 0; y < height; y++) {
38 uint8 *src = srcPtr + srcMod * y;
39 uint8 *dst = dstPtr + dstMod * y;
40 for (uint x = 0; x < width; x++) {
41 *dst++ = *src++;
42 }
43 }
44 }
45
_BltPixelsT(uint8 * srcPtr,uint32 srcMod,uint8 * dstPtr,uint32 dstMod,uint32 width,uint32 height)46 void _BltPixelsT(uint8 *srcPtr, uint32 srcMod, uint8 *dstPtr, uint32 dstMod, uint32 width, uint32 height) {
47 for (uint y = 0; y < height; y++) {
48 uint8 *src = srcPtr + srcMod * y;
49 uint8 *dst = dstPtr + dstMod * y;
50 for (uint x = 0; x < width; x++) {
51 byte c = *src++;
52
53 if (c == 0)
54 dst++;
55 else
56 *dst++ = c;
57 }
58 }
59 }
60
_FillRect(uint8 * dstPtr,uint32 dstMod,uint32 width,uint32 height,uint32 color)61 void _FillRect(uint8 *dstPtr, uint32 dstMod, uint32 width, uint32 height, uint32 color) {
62 for (uint y = 0; y < height; y++) {
63 memset(dstPtr, color, width);
64
65 dstPtr += dstMod;
66 }
67 }
68
_HLine(uint8 * dstPtr,uint32 width,uint32 color)69 void _HLine(uint8 *dstPtr, uint32 width, uint32 color) {
70 memset(dstPtr, color, width);
71 }
72
unpackImage(gPixelMap & map,int16 width,int16 rowCount,int8 * srcData)73 void unpackImage(gPixelMap &map, int16 width, int16 rowCount, int8 *srcData) {
74 int8 *dest = (int8 *)map.data;
75 int16 bytecount = (width + 1) & ~1;
76 int16 rowMod = map.size.x - bytecount;
77
78 while (rowCount--) {
79 for (int16 k = 0; k < bytecount;) {
80 int16 p = *srcData++;
81
82 if (p == -128)
83 continue;
84 else if (p >= 0) {
85 p++;
86 k += p;
87 while (p--)
88 *dest++ = *srcData++;
89 } else {
90 p = 1 - p;
91 k += p;
92 while (p--)
93 *dest++ = *srcData;
94 srcData++;
95 }
96 }
97
98 if (bytecount & 1)
99 srcData++;
100 dest += rowMod;
101 }
102 }
103
unpackImage(gPixelMap * map,int32 width,int32 rowCount,int8 * srcData)104 void unpackImage(gPixelMap *map, int32 width, int32 rowCount, int8 *srcData) {
105 unpackImage(*map, (int16)width, (int16)rowCount, srcData);
106 }
107
108 #define DEBUGPACK 0
109
unpackSprite(gPixelMap * map,uint8 * sprData,uint32 dataSize)110 void unpackSprite(gPixelMap *map, uint8 *sprData, uint32 dataSize) {
111 byte *dst = map->data;
112 int bytes = map->size.x * map->size.y;
113 bool fail = false;
114
115 if (!sprData) {
116 warning("unpackSprite(): empty sprData");
117 return;
118 }
119
120 Common::MemoryReadStream stream(sprData, dataSize);
121
122 while (true) {
123 byte trans = stream.readByte();
124
125 if (stream.eos()) {
126 warning("unpackSprite: premature end of data");
127 fail = true;
128 break;
129 }
130
131 if (bytes < trans) {
132 #if DEBUGPACK
133 warning("unpackSprite: too many trans %d < %d for %dx%d (src %d bytes)", bytes, trans, map->size.x, map->size.y, dataSize);
134 #endif
135 fail = true;
136 break;
137 }
138 memset(dst, 0, trans);
139 dst += trans;
140 bytes -= trans;
141
142 if (bytes < 0)
143 break;
144
145 byte fill = stream.readByte();
146
147 if (stream.eos()) {
148 warning("unpackSprite: premature end of data");
149 fail = true;
150 break;
151 }
152 if (bytes < fill) {
153 #if DEBUGPACK
154 warning("unpackSprite: too many fill %d < %d for %dx%d (src %d bytes)", bytes, fill, map->size.x, map->size.y, dataSize);
155 #endif
156 fill = bytes;
157 fail = true;
158 }
159 if (stream.read(dst, fill) != fill) {
160 warning("unpackSprite: premature end of data");
161 fail = true;
162 break;
163 }
164 dst += fill;
165 bytes -= fill;
166
167 if (bytes <= 0)
168 break;
169 }
170
171 if (!stream.eos()) {
172 #if DEBUGPACK
173 warning("unpackSprite: %d bytes left", stream.size() - stream.pos());
174 #endif
175 fail = true;
176 }
177
178 if (fail) {
179 #if DEBUGPACK
180 Graphics::Surface surf;
181 surf.w = map->size.x;
182 surf.h = map->size.y;
183 surf.pitch = map->size.x;
184 surf.format = Graphics::PixelFormat::createFormatCLUT8();
185
186 surf.setPixels(map->data);
187
188 surf.debugPrint();
189 #endif
190 }
191 }
192
drawTile(gPixelMap * map,int32 x,int32 y,int32 height,uint8 * srcData,bool mask)193 void drawTile(gPixelMap *map, int32 x, int32 y, int32 height, uint8 *srcData, bool mask) {
194 const byte *tilePointer;
195 const byte *readPointer;
196 byte *drawPointer;
197 Point32 drawPoint;
198 int widthCount;
199 int row, col, count, lowBound;
200 int bgRunCount;
201 int fgRunCount;
202 const int32 SAGA_ISOTILE_WIDTH = 64;
203 Point16 point(x - 32, y);
204
205 if (point.x + SAGA_ISOTILE_WIDTH < 0)
206 return;
207
208 if (point.x - SAGA_ISOTILE_WIDTH >= map->size.x)
209 return;
210
211 tilePointer = srcData;
212
213 drawPoint = point;
214
215 drawPoint.y -= height;
216
217 if (drawPoint.y >= map->size.y)
218 return;
219
220 readPointer = tilePointer;
221 lowBound = MIN((int)(drawPoint.y + height), (int)map->size.y);
222 for (row = drawPoint.y; row < lowBound; row++) {
223 widthCount = 0;
224 if (row >= 0) {
225 drawPointer = map->data + drawPoint.x + (row * map->size.x);
226 col = drawPoint.x;
227 for (;;) {
228 bgRunCount = *readPointer++;
229 widthCount += bgRunCount;
230 if (widthCount >= SAGA_ISOTILE_WIDTH)
231 break;
232
233 drawPointer += bgRunCount;
234 col += bgRunCount;
235 fgRunCount = *readPointer++;
236 widthCount += fgRunCount;
237
238 count = 0;
239 int colDiff = - col;
240 if (colDiff > 0) {
241 if (colDiff > fgRunCount)
242 colDiff = fgRunCount;
243
244 count = colDiff;
245 col += colDiff;
246 }
247
248 colDiff = map->size.x - col;
249 if (colDiff > 0) {
250 int countDiff = fgRunCount - count;
251 if (colDiff > countDiff)
252 colDiff = countDiff;
253
254 if (colDiff > 0) {
255 byte *dst = (byte *)(drawPointer + count);
256 if (mask)
257 memset(dst, 0, colDiff);
258 else
259 memcpy(dst, (readPointer + count), colDiff);
260 col += colDiff;
261 }
262 }
263
264 readPointer += fgRunCount;
265 drawPointer += fgRunCount;
266 }
267 } else {
268 for (;;) {
269 bgRunCount = *readPointer++;
270 widthCount += bgRunCount;
271 if (widthCount >= SAGA_ISOTILE_WIDTH)
272 break;
273
274 fgRunCount = *readPointer++;
275 widthCount += fgRunCount;
276
277 readPointer += fgRunCount;
278 }
279 }
280 }
281
282 // Compute dirty rect
283 int rectX = MAX<int>(drawPoint.x, 0);
284 int rectY = MAX<int>(drawPoint.y, 0);
285 int rectX2 = MIN<int>(drawPoint.x + SAGA_ISOTILE_WIDTH, map->size.x);
286 int rectY2 = lowBound;
287 debugC(3, kDebugTiles, "Rect = (%d,%d,%d,%d)", rectX, rectY, rectX2, rectY2);
288
289 #if 0
290 Graphics::Surface sur;
291 sur.create(map->size.x, map->size.y, Graphics::PixelFormat::createFormatCLUT8());
292 sur.setPixels(map->data);
293 //sur.debugPrint();
294 g_system->copyRectToScreen(sur.getPixels(), sur.pitch, 0, 0, sur.w, sur.h);
295 g_system->updateScreen();
296 #endif
297 }
298
299
maskTile(gPixelMap * map,int32 x,int32 y,int32 height,uint8 * srcData)300 void maskTile(gPixelMap *map, int32 x, int32 y, int32 height, uint8 *srcData) {
301 drawTile(map, x, y, height, srcData, true);
302 }
303
TBlit(gPixelMap * dstMap,gPixelMap * srcMap,int32 xpos,int32 ypos)304 void TBlit(gPixelMap *dstMap, gPixelMap *srcMap, int32 xpos, int32 ypos) {
305 int16 w = srcMap->size.x;
306 int16 h = srcMap->size.y;
307 int32 offset = 0;
308
309 if (ypos < 0) {
310 h += ypos;
311 offset -= (ypos * w);
312 ypos = 0;
313 }
314
315 if (xpos < 0) {
316 w += xpos;
317 offset -= xpos;
318 xpos = 0;
319 }
320
321 if (w > dstMap->size.x - xpos)
322 w = dstMap->size.x - xpos;
323 if (h > dstMap->size.y - ypos)
324 h = dstMap->size.y - ypos;
325 if (w < 0 || h < 0)
326 return;
327
328 int16 dstMod = dstMap->size.x - w;
329 int16 srcMod = srcMap->size.x - w;
330
331 byte *srcPtr = srcMap->data + offset;
332 byte *dstPtr = dstMap->data + xpos + ypos * dstMap->size.x;
333
334 for (int16 y = 0; y < h; y++) {
335 for (int16 x = 0; x < w; x++) {
336 byte c = *srcPtr++;
337
338 if (c == 0)
339 dstPtr++;
340 else
341 *dstPtr++ = c;
342 }
343 dstPtr += dstMod;
344 srcPtr += srcMod;
345 }
346 }
347
TBlit4(gPixelMap * d,gPixelMap * s,int32 x,int32 y)348 void TBlit4(gPixelMap *d, gPixelMap *s, int32 x, int32 y) {
349 TBlit(d, s, x, y);
350 }
351
compositePixels(gPixelMap * compMap,gPixelMap * sprMap,int32 xpos,int32 ypos,byte * lookup)352 void compositePixels(gPixelMap *compMap, gPixelMap *sprMap, int32 xpos, int32 ypos, byte *lookup) {
353 byte *srcPtr = sprMap->data;
354 byte *dstPtr = compMap->data + xpos + ypos * compMap->size.x;
355 int16 rowMod = compMap->size.x - sprMap->size.x;
356
357 for (int16 y = 0; y < sprMap->size.y; y++) {
358 for (int16 x = 0; x < sprMap->size.x; x++) {
359 byte c = *srcPtr++;
360
361 if (c == 0)
362 dstPtr++;
363 else
364 *dstPtr++ = lookup[ c ];
365 }
366 dstPtr += rowMod;
367 }
368 }
369
compositePixelsRvs(gPixelMap * compMap,gPixelMap * sprMap,int32 xpos,int32 ypos,byte * lookup)370 void compositePixelsRvs(gPixelMap *compMap, gPixelMap *sprMap, int32 xpos, int32 ypos, byte *lookup) {
371 byte *srcPtr = sprMap->data + sprMap->bytes();
372 byte *dstPtr = compMap->data + xpos + (ypos + sprMap->size.y) * compMap->size.x;
373
374 int16 rowMod = compMap->size.x + sprMap->size.x;
375
376 for (int16 y = 0; y < sprMap->size.y; y++) {
377 dstPtr -= rowMod;
378
379 for (int16 x = 0; x < sprMap->size.x; x++) {
380 byte c = *--srcPtr;
381
382 if (c == 0)
383 dstPtr++;
384 else
385 *dstPtr++ = lookup[c];
386 }
387 }
388 }
389
initGraphics(void)390 bool initGraphics(void) {
391 warning("STUB: initGraphics()");
392 return false;
393 }
394
initProcessResources(void)395 bool initProcessResources(void) {
396 return true;
397 }
398
termProcessResources(void)399 void termProcessResources(void) {
400 }
401
402 } // end of namespace Saga2
403