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