FS2_Open
Open source remastering of the Freespace 2 engine
decoder8.cpp
Go to the documentation of this file.
1 
2 
3 #include "globalincs/pstypes.h"
4 
5 
6 extern int g_width, g_height;
7 extern void *g_vBackBuf1, *g_vBackBuf2;
8 
9 static void dispatchDecoder8(ubyte **pFrame, ubyte codeType, ubyte **pData, int *pDataRemain, int *curXb, int *curYb);
10 
11 void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
12 {
13  int i, j;
14  int xb, yb;
15 
16  xb = g_width >> 3;
17  yb = g_height >> 3;
18 
19  for (j = 0; j < yb; j++) {
20  for (i = 0; i < (xb / 2); i++) {
21  dispatchDecoder8(&pFrame, (*pMap) & 0xf, &pData, &dataRemain, &i, &j);
22 
23  dispatchDecoder8(&pFrame, (*pMap) >> 4, &pData, &dataRemain, &i, &j);
24 
25  pMap++;
26  mapRemain--;
27  }
28 
29  pFrame += 7*g_width;
30  }
31 }
32 
33 static void relClose(int i, int *x, int *y)
34 {
35  int ma, mi;
36 
37  ma = i >> 4;
38  mi = i & 0xf;
39 
40  *x = mi - 8;
41  *y = ma - 8;
42 }
43 
44 static void relFar(int i, int sign, int *x, int *y)
45 {
46  if (i < 56) {
47  *x = sign * (8 + (i % 7));
48  *y = sign * (i / 7);
49  } else {
50  *x = sign * (-14 + (i - 56) % 29);
51  *y = sign * (8 + (i - 56) / 29);
52  }
53 }
54 
55 /* copies an 8x8 block from pSrc to pDest.
56  pDest and pSrc are both g_width bytes wide */
57 static void copyFrame(ubyte *pDest, ubyte *pSrc)
58 {
59  int i;
60 
61  for (i = 0; i < 8; i++) {
62  memcpy(pDest, pSrc, 8);
63  pDest += g_width;
64  pSrc += g_width;
65  }
66 }
67 
68 // Fill in the next eight bytes with p[0], p[1], p[2], or p[3],
69 // depending on the corresponding two-bit value in pat0 and pat1
70 static void patternRow4Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte *p)
71 {
72  ushort mask = 0x0003;
73  ushort shift = 0;
74  ushort pattern = (pat1 << 8) | pat0;
75 
76  while (mask != 0) {
77  *pFrame++ = p[(mask & pattern) >> shift];
78  mask <<= 2;
79  shift += 2;
80  }
81 }
82 
83 // Fill in the next four 2x2 pixel blocks with p[0], p[1], p[2], or p[3],
84 // depending on the corresponding two-bit value in pat0.
85 static void patternRow4Pixels2(ubyte *pFrame, ubyte pat0, ubyte *p)
86 {
87  ubyte mask = 0x03;
88  ubyte shift = 0;
89  ubyte pel;
90 
91  while (mask != 0) {
92  pel = p[(mask & pat0) >> shift];
93  pFrame[0] = pel;
94  pFrame[1] = pel;
95  pFrame[g_width + 0] = pel;
96  pFrame[g_width + 1] = pel;
97  pFrame += 2;
98  mask <<= 2;
99  shift += 2;
100  }
101 }
102 
103 // Fill in the next four 2x1 pixel blocks with p[0], p[1], p[2], or p[3],
104 // depending on the corresponding two-bit value in pat.
105 static void patternRow4Pixels2x1(ubyte *pFrame, ubyte pat, ubyte *p)
106 {
107  ubyte mask = 0x03;
108  ubyte shift = 0;
109  ubyte pel;
110 
111  while (mask != 0) {
112  pel = p[(mask & pat) >> shift];
113  pFrame[0] = pel;
114  pFrame[1] = pel;
115  pFrame += 2;
116  mask <<= 2;
117  shift += 2;
118  }
119 }
120 
121 // Fill in the next 4x4 pixel block with p[0], p[1], p[2], or p[3],
122 // depending on the corresponding two-bit value in pat0, pat1, pat2, and pat3.
123 static void patternQuadrant4Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte pat2, ubyte pat3, ubyte *p)
124 {
125  unsigned long mask = 0x00000003UL;
126  int shift=0;
127  int i;
128  unsigned long pat = (pat3 << 24) | (pat2 << 16) | (pat1 << 8) | pat0;
129 
130  for (i = 0; i < 16; i++) {
131  pFrame[i&3] = p[(pat & mask) >> shift];
132 
133  if ( (i & 3) == 3 )
134  pFrame += g_width;
135 
136  mask <<= 2;
137  shift += 2;
138  }
139 }
140 
141 // fills the next 8 pixels with either p[0] or p[1], depending on pattern
142 static void patternRow2Pixels(ubyte *pFrame, ubyte pat, ubyte *p)
143 {
144  ubyte mask=0x01;
145 
146  while (mask != 0) {
147  *pFrame++ = p[(mask & pat) ? 1 : 0];
148  mask <<= 1;
149  }
150 }
151 
152 // fills the next four 2 x 2 pixel boxes with either p[0] or p[1], depending on pattern
153 static void patternRow2Pixels2(ubyte *pFrame, ubyte pat, ubyte *p)
154 {
155  ubyte pel;
156  ubyte mask=0x1;
157 
158  while (mask != 0x10) {
159  pel = p[(mask & pat) ? 1 : 0];
160 
161  pFrame[0] = pel; // upper-left
162  pFrame[1] = pel; // upper-right
163  pFrame[g_width + 0] = pel; // lower-left
164  pFrame[g_width + 1] = pel; // lower-right
165  pFrame += 2;
166 
167  mask <<= 1;
168  }
169 }
170 
171 // fills pixels in the next 4 x 4 pixel boxes with either p[0] or p[1], depending on pat0 and pat1.
172 static void patternQuadrant2Pixels(ubyte *pFrame, ubyte pat0, ubyte pat1, ubyte *p)
173 {
174  ubyte pel;
175  ushort mask = 0x0001;
176  int i, j;
177  ushort pat = (pat1 << 8) | pat0;
178 
179  for (i = 0; i < 4; i++) {
180  for (j = 0; j < 4; j++) {
181  pel = p[(pat & mask) ? 1 : 0];
182 
183  pFrame[j + i * g_width] = pel;
184 
185  mask <<= 1;
186  }
187  }
188 }
189 
190 static void dispatchDecoder8(ubyte **pFrame, ubyte codeType, ubyte **pData, int *pDataRemain, int *curXb, int *curYb)
191 {
192  ubyte p[4];
193  ubyte pat[16];
194  int i, j, k;
195  int x, y;
196 
197  switch(codeType) {
198  case 0x0:
199  copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1));
200  *pFrame += 8;
201  break;
202 
203  case 0x1:
204  *pFrame += 8;
205  break;
206 
207  case 0x2:
208  relFar(*(*pData)++, 1, &x, &y);
209  copyFrame(*pFrame, *pFrame + x + y*g_width);
210  *pFrame += 8;
211  (*pDataRemain)--;
212  break;
213 
214  case 0x3:
215  relFar(*(*pData)++, -1, &x, &y);
216  copyFrame(*pFrame, *pFrame + x + y*g_width);
217  *pFrame += 8;
218  (*pDataRemain)--;
219  break;
220 
221  case 0x4:
222  relClose(*(*pData)++, &x, &y);
223  copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1) + x + y*g_width);
224  *pFrame += 8;
225  (*pDataRemain)--;
226  break;
227 
228  case 0x5:
229  x = (signed char)*(*pData)++;
230  y = (signed char)*(*pData)++;
231  copyFrame(*pFrame, *pFrame + ((ubyte *)g_vBackBuf2 - (ubyte *)g_vBackBuf1) + x + y*g_width);
232  *pFrame += 8;
233  *pDataRemain -= 2;
234  break;
235 
236  case 0x6:
237  for (i = 0; i < 2; i++) {
238  *pFrame += 16;
239 
240  if (++*curXb == (g_width >> 3)) {
241  *pFrame += 7*g_width;
242  *curXb = 0;
243 
244  if (++*curYb == (g_height >> 3))
245  return;
246  }
247  }
248  break;
249 
250  case 0x7:
251  p[0] = *(*pData)++;
252  p[1] = *(*pData)++;
253 
254  if (p[0] <= p[1]) {
255  for (i = 0; i < 8; i++) {
256  patternRow2Pixels(*pFrame, *(*pData)++, p);
257  *pFrame += g_width;
258  }
259  } else {
260  for (i = 0; i < 2; i++) {
261  patternRow2Pixels2(*pFrame, *(*pData) & 0xf, p);
262  *pFrame += 2*g_width;
263 
264  patternRow2Pixels2(*pFrame, *(*pData)++ >> 4, p);
265  *pFrame += 2*g_width;
266  }
267  }
268 
269  *pFrame -= (8*g_width - 8);
270  break;
271 
272  case 0x8:
273  if ( (*pData)[0] <= (*pData)[1] ) {
274  // four quadrant case
275  for (i = 0; i < 4; i++) {
276  p[0] = *(*pData)++;
277  p[1] = *(*pData)++;
278  pat[0] = *(*pData)++;
279  pat[1] = *(*pData)++;
280  patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
281 
282  // alternate between moving down and moving up and right
283  if (i & 1)
284  *pFrame += 4 - 4*g_width; // up and right
285  else
286  *pFrame += 4*g_width; // down
287  }
288  } else if ( (*pData)[6] <= (*pData)[7] ) {
289  // split horizontal
290  for (i = 0; i < 4; i++) {
291  if ((i & 1) == 0) {
292  p[0] = *(*pData)++;
293  p[1] = *(*pData)++;
294  }
295 
296  pat[0] = *(*pData)++;
297  pat[1] = *(*pData)++;
298  patternQuadrant2Pixels(*pFrame, pat[0], pat[1], p);
299 
300  if (i & 1)
301  *pFrame -= (4*g_width - 4);
302  else
303  *pFrame += 4*g_width;
304  }
305  } else {
306  // split vertical
307  for (i = 0; i < 8; i++) {
308  if ((i & 3) == 0) {
309  p[0] = *(*pData)++;
310  p[1] = *(*pData)++;
311  }
312 
313  patternRow2Pixels(*pFrame, *(*pData)++, p);
314  *pFrame += g_width;
315  }
316 
317  *pFrame -= (8*g_width - 8);
318  }
319  break;
320 
321  case 0x9:
322  if ( (*pData)[0] <= (*pData)[1] ) {
323  if ( (*pData)[2] <= (*pData)[3] ) {
324  p[0] = *(*pData)++;
325  p[1] = *(*pData)++;
326  p[2] = *(*pData)++;
327  p[3] = *(*pData)++;
328 
329  for (i = 0; i < 8; i++) {
330  pat[0] = *(*pData)++;
331  pat[1] = *(*pData)++;
332 
333  patternRow4Pixels(*pFrame, pat[0], pat[1], p);
334  *pFrame += g_width;
335  }
336 
337  *pFrame -= (8*g_width - 8);
338  } else {
339  p[0] = *(*pData)++;
340  p[1] = *(*pData)++;
341  p[2] = *(*pData)++;
342  p[3] = *(*pData)++;
343 
344  patternRow4Pixels2(*pFrame, *(*pData)++, p);
345  *pFrame += 2*g_width;
346 
347  patternRow4Pixels2(*pFrame, *(*pData)++, p);
348  *pFrame += 2*g_width;
349 
350  patternRow4Pixels2(*pFrame, *(*pData)++, p);
351  *pFrame += 2*g_width;
352 
353  patternRow4Pixels2(*pFrame, *(*pData)++, p);
354  *pFrame -= (6*g_width - 8);
355  }
356  } else {
357  if ( (*pData)[2] <= (*pData)[3] ) {
358  // draw 2x1 strips
359  p[0] = *(*pData)++;
360  p[1] = *(*pData)++;
361  p[2] = *(*pData)++;
362  p[3] = *(*pData)++;
363 
364  for (i = 0; i < 8; i++) {
365  pat[0] = *(*pData)++;
366 
367  patternRow4Pixels2x1(*pFrame, pat[0], p);
368  *pFrame += g_width;
369  }
370 
371  *pFrame -= (8*g_width - 8);
372  } else {
373  // draw 1x2 strips
374  p[0] = *(*pData)++;
375  p[1] = *(*pData)++;
376  p[2] = *(*pData)++;
377  p[3] = *(*pData)++;
378 
379  for (i = 0; i < 4; i++) {
380  pat[0] = *(*pData)++;
381  pat[1] = *(*pData)++;
382 
383  patternRow4Pixels(*pFrame, pat[0], pat[1], p);
384  *pFrame += g_width;
385 
386  patternRow4Pixels(*pFrame, pat[0], pat[1], p);
387  *pFrame += g_width;
388  }
389 
390  *pFrame -= (8*g_width - 8);
391  }
392  }
393  break;
394 
395  case 0xa:
396  if ( (*pData)[0] <= (*pData)[1] ) {
397  for (i = 0; i < 4; i++) {
398  p[0] = *(*pData)++;
399  p[1] = *(*pData)++;
400  p[2] = *(*pData)++;
401  p[3] = *(*pData)++;
402  pat[0] = *(*pData)++;
403  pat[1] = *(*pData)++;
404  pat[2] = *(*pData)++;
405  pat[3] = *(*pData)++;
406 
407  patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
408 
409  if (i & 1)
410  *pFrame -= (4*g_width - 4);
411  else
412  *pFrame += 4*g_width;
413  }
414  } else {
415  if ( (*pData)[12] <= (*pData)[13] ) {
416  // split vertical
417  for (i = 0; i < 4; i++) {
418  if ((i&1) == 0) {
419  p[0] = *(*pData)++;
420  p[1] = *(*pData)++;
421  p[2] = *(*pData)++;
422  p[3] = *(*pData)++;
423  }
424 
425  pat[0] = *(*pData)++;
426  pat[1] = *(*pData)++;
427  pat[2] = *(*pData)++;
428  pat[3] = *(*pData)++;
429 
430  patternQuadrant4Pixels(*pFrame, pat[0], pat[1], pat[2], pat[3], p);
431 
432  if (i & 1)
433  *pFrame -= (4*g_width - 4);
434  else
435  *pFrame += 4*g_width;
436  }
437  } else {
438  // split horizontal
439  for (i = 0; i < 8; i++) {
440  if ((i&3) == 0) {
441  p[0] = *(*pData)++;
442  p[1] = *(*pData)++;
443  p[2] = *(*pData)++;
444  p[3] = *(*pData)++;
445  }
446 
447  pat[0] = *(*pData)++;
448  pat[1] = *(*pData)++;
449 
450  patternRow4Pixels(*pFrame, pat[0], pat[1], p);
451  *pFrame += g_width;
452  }
453 
454  *pFrame -= (8*g_width - 8);
455  }
456  }
457  break;
458 
459  case 0xb:
460  for (i = 0; i < 8; i++) {
461  memcpy(*pFrame, *pData, 8);
462  *pFrame += g_width;
463  *pData += 8;
464  *pDataRemain -= 8;
465  }
466 
467  *pFrame -= (8*g_width - 8);
468  break;
469 
470  case 0xc:
471  for (i = 0; i < 4; i++) {
472  for (j = 0; j < 2; j++) {
473  for (k = 0; k < 4; k++) {
474  (*pFrame)[2*k] = (*pData)[k];
475  (*pFrame)[2*k+1] = (*pData)[k];
476  }
477 
478  *pFrame += g_width;
479  }
480 
481  *pData += 4;
482  *pDataRemain -= 4;
483  }
484 
485  *pFrame -= (8*g_width - 8);
486  break;
487 
488  case 0xd:
489  for (i = 0; i < 2; i++) {
490  for (j = 0; j < 4; j++) {
491  for (k = 0; k < 4; k++) {
492  (*pFrame)[k*g_width+j] = (*pData)[0];
493  (*pFrame)[k*g_width+j+4] = (*pData)[1];
494  }
495  }
496 
497  *pFrame += 4*g_width;
498  *pData += 2;
499  *pDataRemain -= 2;
500  }
501 
502  *pFrame -= (8*g_width - 8);
503  break;
504 
505  case 0xe:
506  for (i = 0; i < 8; i++) {
507  memset(*pFrame, **pData, 8);
508  *pFrame += g_width;
509  }
510 
511  (*pData)++;
512  (*pDataRemain)--;
513  *pFrame -= (8*g_width - 8);
514  break;
515 
516  case 0xf:
517  for (i = 0; i < 8; i++) {
518  for (j = 0; j < 8; j++) {
519  (*pFrame)[j] = (*pData)[(i+j)&1];
520  }
521 
522  *pFrame += g_width;
523  }
524 
525  *pData += 2;
526  *pDataRemain -= 2;
527  *pFrame -= (8*g_width - 8);
528  break;
529 
530  default:
531  break;
532  }
533 }
int i
Definition: multi_pxo.cpp:466
T sign(T t)
Definition: sexp.cpp:8941
void * g_vBackBuf2
Definition: mveplayer.cpp:66
void decodeFrame8(ubyte *pFrame, ubyte *pMap, int mapRemain, ubyte *pData, int dataRemain)
Definition: decoder8.cpp:11
GLint GLint GLint GLint GLint x
Definition: Glext.h:5182
unsigned char ubyte
Definition: pstypes.h:62
void * g_vBackBuf1
Definition: mveplayer.cpp:66
unsigned short ushort
Definition: pstypes.h:63
GLfloat GLfloat p
Definition: Glext.h:8373
int g_height
Definition: mveplayer.cpp:64
int g_width
Definition: mveplayer.cpp:64
GLubyte * pattern
Definition: Glext.h:7344
GLenum GLint GLuint mask
Definition: Glext.h:5605
GLint y
Definition: Gl.h:1505