1 /*
2  *  This program is free software; you can redistribute it and/or modify
3  *  it under the terms of the GNU General Public License as published by
4  *  the Free Software Foundation; either version 2 of the License, or
5  *  (at your option) any later version.
6  *
7  *  This program is distributed in the hope that it will be useful,
8  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
9  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  *  GNU Library General Public License for more details.
11  *
12  *  You should have received a copy of the GNU General Public License
13  *  along with this program; if not, write to the Free Software
14  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
15  */
16 
17 #include "sprite.h"
18 
19 #include "utils.h"
20 
21 UChar BGONSwitch = 1;
22 // do we have to draw background ?
23 
24 UChar SPONSwitch = 1;
25 // Do we have to draw sprites ?
26 
27 UInt32 spr_init_pos[1024];
28 // cooked initial position of sprite
29 
30 void (*RefreshSprite) (int Y1, int Y2, UChar bg);
31 
32 int ScrollYDiff;
33 int oldScrollX;
34 int oldScrollY;
35 int oldScrollYDiff;
36 
37 #if defined(NEW_GFX_ENGINE)
38 // Actual memory area where the gfx functions are drawing sprites and tiles
39 UChar SPM_raw[XBUF_WIDTH * XBUF_HEIGHT];
40 static UChar *SPM = SPM_raw + XBUF_WIDTH * 64 + 32;
41 #else
42 UChar SPM[WIDTH * HEIGHT];
43 #endif
44 
45 int frame = 0;
46 // number of frame displayed
47 
48 
49 /*
50 	Hit Chesk Sprite#0 and others
51 */
52 SInt32
CheckSprites(void)53 CheckSprites (void)
54 {
55   int i, x0, y0, w0, h0, x, y, w, h;
56   SPR *spr;
57 
58   spr = (SPR *) SPRAM;
59   x0 = spr->x;
60   y0 = spr->y;
61   w0 = (((spr->atr >> 8) & 1) + 1) * 16;
62   h0 = (((spr->atr >> 12) & 3) + 1) * 16;
63   spr++;
64   for (i = 1; i < 64; i++, spr++)
65     {
66       x = spr->x;
67       y = spr->y;
68       w = (((spr->atr >> 8) & 1) + 1) * 16;
69       h = (((spr->atr >> 12) & 3) + 1) * 16;
70       if ((x < x0 + w0) && (x + w > x0) && (y < y0 + h0) && (y + h > y0))
71 	return TRUE;
72     }
73   return FALSE;
74 }
75 
76 /*****************************************************************************
77 
78     Function:  plane2pixel
79 
80     Description: convert a PCE coded tile into a linear one
81     Parameters:int no, the number of the tile to convert
82     Return:nothing, but updates VRAM2
83 
84 *****************************************************************************/
85 static void
plane2pixel(int no)86 plane2pixel (int no)
87 {
88   unsigned long M;
89   UChar *C = VRAM + no * 32;
90   UInt32 L;
91   UChar *C2 = VRAM2 + no * 8 * 4;
92   int j;
93 #ifdef GFX_DEBUG
94   Log ("Planing tile %d\n", no);
95 #endif
96   for (j = 0; j < 8; j++, C += 2, C2 += 4)
97     {
98       M = C[0];
99 #ifdef GFX_DEBUG
100       Log ("C[0]=%02X\n", M);
101 #endif
102       L =
103 	((M & 0x88) >> 3) | ((M & 0x44) << 6) | ((M & 0x22) << 15) |
104 	((M & 0x11) << 24);
105       M = C[1];
106 #ifdef GFX_DEBUG
107       Log ("C[1]=%02X\n", M);
108 #endif
109       L |=
110 	((M & 0x88) >> 2) | ((M & 0x44) << 7) | ((M & 0x22) << 16) |
111 	((M & 0x11) << 25);
112       M = C[16];
113 #ifdef GFX_DEBUG
114       Log ("C[16]=%02X\n", M);
115 #endif
116       L |=
117 	((M & 0x88) >> 1) | ((M & 0x44) << 8) | ((M & 0x22) << 17) |
118 	((M & 0x11) << 26);
119       M = C[17];
120 #ifdef GFX_DEBUG
121       Log ("C[17]=%02X\n", M);
122 #endif
123       L |=
124 	((M & 0x88)) | ((M & 0x44) << 9) | ((M & 0x22) << 18) | ((M & 0x11) <<
125 								 27);
126       /* C2[0] = L;             //37261504 */
127       C2[0] = L & 0xff;
128       C2[1] = (L >> 8) & 0xff;
129       C2[2] = (L >> 16) & 0xff;
130       C2[3] = (L >> 24) & 0xff;
131 #ifdef GFX_DEBUG
132       Log ("L=%04X\n", L);
133 #endif
134 
135     }
136 }
137 
138 /*****************************************************************************
139 
140     Function:  sp2pixel
141 
142     Description:convert a PCE coded sprite into a linear one
143     Parameters:int no,the number of the sprite to convert
144     Return:nothing but update VRAMS
145 
146 *****************************************************************************/
147 
148 
149 static void
sp2pixel(int no)150 sp2pixel (int no)
151 {
152   UChar M;
153   UChar *C;
154   UChar *C2;
155   int i;
156   C = &VRAM[no * 128];
157   C2 = &VRAMS[no * 32 * 4];
158   // 2 longs -> 16 nibbles => 32 loops for a 16*16 spr
159   for (i = 0; i < 32; i++, C++, C2 += 4)
160     {
161       long L;
162       M = C[0];
163       L =
164 	((M & 0x88) >> 3) | ((M & 0x44) << 6) | ((M & 0x22) << 15) |
165 	((M & 0x11) << 24);
166       M = C[32];
167       L |=
168 	((M & 0x88) >> 2) | ((M & 0x44) << 7) | ((M & 0x22) << 16) |
169 	((M & 0x11) << 25);
170       M = C[64];
171       L |=
172 	((M & 0x88) >> 1) | ((M & 0x44) << 8) | ((M & 0x22) << 17) |
173 	((M & 0x11) << 26);
174       M = C[96];
175       L |=
176 	((M & 0x88)) | ((M & 0x44) << 9) | ((M & 0x22) << 18) | ((M & 0x11) <<
177 								 27);
178       /* C2[0] = L; */
179       C2[0] = L & 0xff;
180       C2[1] = (L >> 8) & 0xff;
181       C2[2] = (L >> 16) & 0xff;
182       C2[3] = (L >> 24) & 0xff;
183     }
184 }
185 
186 #define	FC_W	io.screen_w
187 #define	FC_H	256
188 
189 /*****************************************************************************
190 
191     Function: RefreshLine
192 
193     Description: draw tiles on screen
194     Parameters: int Y1,int Y2 (lines to draw between)
195     Return: nothing
196 
197 *****************************************************************************/
198 void
RefreshLine(int Y1,int Y2)199 RefreshLine (int Y1, int Y2)
200 {
201   int X1, XW, Line;
202   int x, y, h, offset, Shift;
203 
204   UChar *PP;
205   Y2++;
206 
207 #if defined(GFX_DEBUG)
208   if (Y1 == 0)
209     {
210       gfx_debug_printf
211 	("= %d =================================================", frame);
212     }
213   gfx_debug_printf ("Rendering lines %3d - %3d\tScroll: (%3d,%3d,%3d)", Y1,
214 		    Y2, ScrollX, ScrollY, ScrollYDiff);
215 #endif
216 
217 #if defined(NEW_GFX_ENGINE)
218   PP = osd_gfx_buffer + XBUF_WIDTH * Y1;
219 #else
220   PP = osd_gfx_buffer + WIDTH * (HEIGHT - FC_H) / 2 + (WIDTH - FC_W) / 2 +
221     WIDTH * (Y1 + 0);
222 #endif
223 
224   if (ScreenON && BGONSwitch)
225     {
226       y = Y1 + ScrollY - ScrollYDiff;
227       offset = y & 7;
228       h = 8 - offset;
229       if (h > Y2 - Y1)
230 	h = Y2 - Y1;
231       y >>= 3;
232       PP -= ScrollX & 7;
233       XW = io.screen_w / 8 + 1;
234       Shift = ScrollX & 7;
235 
236       for (Line = Y1; Line < Y2; y++)
237 	{
238 	  x = ScrollX / 8;
239 	  y &= io.bg_h - 1;
240 	  for (X1 = 0; X1 < XW; X1++, x++, PP += 8)
241 	    {
242 	      UChar *R, *P, *C;
243 	      UChar *C2;
244 	      int no, i;
245 	      x &= io.bg_w - 1;
246 #if defined(WORDS_BIGENDIAN)
247 	      no =
248 		VRAM[(x + y * io.bg_w) << 1] +
249 		(VRAM[((x + y * io.bg_w) << 1) + 1] << 8);
250 #else
251 	      no = ((UInt16 *) VRAM)[x + y * io.bg_w];
252 #endif
253 
254 	      R = &Pal[(no >> 12) * 16];
255 
256 #if defined(GFX_DEBUG)
257 	      // Old code was only no &= 0xFFF
258 	      if ((no & 0xFFF) > 0x800)
259 		{
260 		  fprintf (stderr,
261 			   "Access to an invalid VRAM area (tile pattern 0x%04x).\n",
262 			   no);
263 		}
264 #endif
265 	      no &= 0x7FF;
266 
267 	      if (vchange[no])
268 		{
269 		  vchange[no] = 0;
270 		  plane2pixel (no);
271 		}
272 	      C2 = (VRAM2 + (no * 8 + offset) * 4);
273 	      C = VRAM + (no * 32 + offset * 2);
274 	      P = PP;
275 #if defined(NEW_GFX_ENGINE)
276 	      for (i = 0; i < h; i++, P += XBUF_WIDTH, C2 += 4, C += 2)
277 #else
278 	      for (i = 0; i < h; i++, P += WIDTH, C2 += 4, C += 2)
279 #endif
280 		{
281 		  unsigned long L;
282 		  UChar J;
283 		  J = (C[0] | C[1] | C[16] | C[17]);
284 		  if (!J)
285 		    continue;
286 		  L = C2[0] + (C2[1] << 8) + (C2[2] << 16) + (C2[3] << 24);
287 		  if (J & 0x80)
288 		    P[0] = PAL ((L >> 4) & 15);
289 		  if (J & 0x40)
290 		    P[1] = PAL ((L >> 12) & 15);
291 		  if (J & 0x20)
292 		    P[2] = PAL ((L >> 20) & 15);
293 		  if (J & 0x10)
294 		    P[3] = PAL ((L >> 28));
295 		  if (J & 0x08)
296 		    P[4] = PAL ((L) & 15);
297 		  if (J & 0x04)
298 		    P[5] = PAL ((L >> 8) & 15);
299 		  if (J & 0x02)
300 		    P[6] = PAL ((L >> 16) & 15);
301 		  if (J & 0x01)
302 		    P[7] = PAL ((L >> 24) & 15);
303 		}
304 	    }
305 	  Line += h;
306 #if defined(NEW_GFX_ENGINE)
307 	  PP += XBUF_WIDTH * h - XW * 8;
308 #else
309 	  PP += WIDTH * h - XW * 8;
310 #endif
311 	  offset = 0;
312 	  h = Y2 - Line;
313 	  if (h > 8)
314 	    h = 8;
315 	}
316     }
317 }
318 
319 #define	V_FLIP	0x8000
320 #define	H_FLIP	0x0800
321 #define	SPBG	0x80
322 #define	CGX	0x100
323 
324 /*****************************************************************************
325 
326     Function: PutSprite
327 
328     Description: convert a sprite from VRAM to normal format
329     Parameters: UChar *P (the place where to draw i.e. XBuf[...])
330                 UChar *C (the buffer toward the sprite to draw)
331                 unsigned long *C2 (the buffer of precalculated sprite)
332                 UChar *R (address of the palette of this sprite [in PAL] )
333                 int h (the number of line to draw)
334                 int inc (the value to increment the sprite buffer)
335     Return: nothing
336 
337 *****************************************************************************/
338 void
PutSprite(UChar * P,UChar * C,UChar * C2,UChar * R,int h,int inc)339 PutSprite (UChar * P, UChar * C, UChar * C2, UChar * R, int h, int inc)
340 {
341   int i, J;
342   UInt32 L;
343 #if defined(NEW_GFX_ENGINE)
344   for (i = 0; i < h; i++, C += inc, C2 += inc * 4, P += XBUF_WIDTH)
345 #else
346   for (i = 0; i < h; i++, C += inc, C2 += inc * 4, P += WIDTH)
347 #endif
348     {
349 
350 #if defined(WORDS_BIGENDIAN)
351       J = (C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] + (C[65] << 8)) | (C[96] + (C[97] << 8));
352 #else
353       J = ((UInt16 *) C)[0] | ((UInt16 *) C)[16] | ((UInt16 *) C)[32] | ((UInt16 *)C)[48];
354 #endif
355 
356       if (!J)
357 	continue;
358       L = C2[4] + (C2[5] << 8) + (C2[6] << 16) + (C2[7] << 24);	//sp2pixel(C+1);
359       if (J & 0x8000)
360 	P[0] = PAL ((L >> 4) & 15);
361       if (J & 0x4000)
362 	P[1] = PAL ((L >> 12) & 15);
363       if (J & 0x2000)
364 	P[2] = PAL ((L >> 20) & 15);
365       if (J & 0x1000)
366 	P[3] = PAL ((L >> 28));
367       if (J & 0x0800)
368 	P[4] = PAL ((L) & 15);
369       if (J & 0x0400)
370 	P[5] = PAL ((L >> 8) & 15);
371       if (J & 0x0200)
372 	P[6] = PAL ((L >> 16) & 15);
373       if (J & 0x0100)
374 	P[7] = PAL ((L >> 24) & 15);
375 
376       L = C2[0] + (C2[1] << 8) + (C2[2] << 16) + (C2[3] << 24);	//sp2pixel(C);
377       if (J & 0x80)
378 	P[8] = PAL ((L >> 4) & 15);
379       if (J & 0x40)
380 	P[9] = PAL ((L >> 12) & 15);
381       if (J & 0x20)
382 	P[10] = PAL ((L >> 20) & 15);
383       if (J & 0x10)
384 	P[11] = PAL ((L >> 28));
385       if (J & 0x08)
386 	P[12] = PAL ((L) & 15);
387       if (J & 0x04)
388 	P[13] = PAL ((L >> 8) & 15);
389       if (J & 0x02)
390 	P[14] = PAL ((L >> 16) & 15);
391       if (J & 0x01)
392 	P[15] = PAL ((L >> 24) & 15);
393     }
394 }
395 
396 void
PutSpriteHandleFull(UChar * P,UChar * C,unsigned long * C2,UChar * R,int h,int inc)397 PutSpriteHandleFull (UChar * P, UChar * C, unsigned long *C2, UChar * R,
398 		     int h, int inc)
399 {
400   int i, J;
401   unsigned long L;
402 #if defined(NEW_GFX_ENGINE)
403   for (i = 0; i < h; i++, C += inc, C2 += inc, P += XBUF_WIDTH)
404 #else
405   for (i = 0; i < h; i++, C += inc, C2 += inc, P += WIDTH)
406 #endif
407     {
408 
409       J =
410 	(C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] +
411 							 (C[65] << 8)) |
412 	(C[96] + (C[97] << 8));
413       /*
414          J =
415          ((UInt16 *) C)[0] | ((UInt16 *) C)[16] | ((UInt16 *) C)[32] | ((UInt16 *)
416          C)[48];
417        */
418       if (!J)
419 	continue;
420       if (J == 65535)
421 	{
422 	  L = C2[1];		//sp2pixel(C+1);
423 	  P[0] = PAL ((L >> 4) & 15);
424 	  P[1] = PAL ((L >> 12) & 15);
425 	  P[2] = PAL ((L >> 20) & 15);
426 	  P[3] = PAL ((L >> 28));
427 	  P[4] = PAL ((L) & 15);
428 	  P[5] = PAL ((L >> 8) & 15);
429 	  P[6] = PAL ((L >> 16) & 15);
430 	  P[7] = PAL ((L >> 24) & 15);
431 	  L = C2[0];		//sp2pixel(C);
432 	  P[8] = PAL ((L >> 4) & 15);
433 	  P[9] = PAL ((L >> 12) & 15);
434 	  P[10] = PAL ((L >> 20) & 15);
435 	  P[11] = PAL ((L >> 28));
436 	  P[12] = PAL ((L) & 15);
437 	  P[13] = PAL ((L >> 8) & 15);
438 	  P[14] = PAL ((L >> 16) & 15);
439 	  P[15] = PAL ((L >> 24) & 15);
440 
441 	  return;
442 
443 	}
444 
445 
446       L = C2[1];		//sp2pixel(C+1);
447       if (J & 0x8000)
448 	P[0] = PAL ((L >> 4) & 15);
449       if (J & 0x4000)
450 	P[1] = PAL ((L >> 12) & 15);
451       if (J & 0x2000)
452 	P[2] = PAL ((L >> 20) & 15);
453       if (J & 0x1000)
454 	P[3] = PAL ((L >> 28));
455       if (J & 0x0800)
456 	P[4] = PAL ((L) & 15);
457       if (J & 0x0400)
458 	P[5] = PAL ((L >> 8) & 15);
459       if (J & 0x0200)
460 	P[6] = PAL ((L >> 16) & 15);
461       if (J & 0x0100)
462 	P[7] = PAL ((L >> 24) & 15);
463       L = C2[0];		//sp2pixel(C);
464       if (J & 0x80)
465 	P[8] = PAL ((L >> 4) & 15);
466       if (J & 0x40)
467 	P[9] = PAL ((L >> 12) & 15);
468       if (J & 0x20)
469 	P[10] = PAL ((L >> 20) & 15);
470       if (J & 0x10)
471 	P[11] = PAL ((L >> 28));
472       if (J & 0x08)
473 	P[12] = PAL ((L) & 15);
474       if (J & 0x04)
475 	P[13] = PAL ((L >> 8) & 15);
476       if (J & 0x02)
477 	P[14] = PAL ((L >> 16) & 15);
478       if (J & 0x01)
479 	P[15] = PAL ((L >> 24) & 15);
480     }
481 }
482 
483 
484 static void
PutSpriteHflip(UChar * P,UChar * C,unsigned long * C2,UChar * R,int h,int inc)485 PutSpriteHflip (UChar * P, UChar * C, unsigned long *C2, UChar * R, int h,
486 		int inc)
487 {
488   int i, J;
489   unsigned long L;
490 #if defined(NEW_GFX_ENGINE)
491   for (i = 0; i < h; i++, C += inc, C2 += inc, P += XBUF_WIDTH)
492 #else
493   for (i = 0; i < h; i++, C += inc, C2 += inc, P += WIDTH)
494 #endif
495     {
496       J =
497 	(C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] +
498 							 (C[65] << 8)) |
499 	(C[96] + (C[97] << 8));
500       /*
501          J =
502          ((UInt16 *) C)[0] | ((UInt16 *) C)[16] | ((UInt16 *) C)[32] | ((UInt16 *)
503          C)[48];
504        */
505       if (!J)
506 	continue;
507       L = C2[1];		//sp2pixel(C+1);
508       if (J & 0x8000)
509 	P[15] = PAL ((L >> 4) & 15);
510       if (J & 0x4000)
511 	P[14] = PAL ((L >> 12) & 15);
512       if (J & 0x2000)
513 	P[13] = PAL ((L >> 20) & 15);
514       if (J & 0x1000)
515 	P[12] = PAL ((L >> 28));
516       if (J & 0x0800)
517 	P[11] = PAL ((L) & 15);
518       if (J & 0x0400)
519 	P[10] = PAL ((L >> 8) & 15);
520       if (J & 0x0200)
521 	P[9] = PAL ((L >> 16) & 15);
522       if (J & 0x0100)
523 	P[8] = PAL ((L >> 24) & 15);
524       L = C2[0];		//sp2pixel(C);
525       if (J & 0x80)
526 	P[7] = PAL ((L >> 4) & 15);
527       if (J & 0x40)
528 	P[6] = PAL ((L >> 12) & 15);
529       if (J & 0x20)
530 	P[5] = PAL ((L >> 20) & 15);
531       if (J & 0x10)
532 	P[4] = PAL ((L >> 28));
533       if (J & 0x08)
534 	P[3] = PAL ((L) & 15);
535       if (J & 0x04)
536 	P[2] = PAL ((L >> 8) & 15);
537       if (J & 0x02)
538 	P[1] = PAL ((L >> 16) & 15);
539       if (J & 0x01)
540 	P[0] = PAL ((L >> 24) & 15);
541     }
542 }
543 
544 /*****************************************************************************
545 
546     Function:  PutSpriteM
547 
548     Description: Display a sprite considering priority
549     Parameters:
550 	    UChar *P : A Pointer in the buffer where we got to draw the sprite
551 		 UChar *C : A pointer in the video mem where data are available
552 		 unsigned long *C2 : A pointer in the VRAMS mem
553 		 UChar *R	: A pointer to the current palette
554 		 int h : height of the sprite
555 		 int inc : value of the incrementation for the data
556 		 UChar* M :
557     Return:
558 
559 *****************************************************************************/
560 
561 
562 void
PutSpriteM(UChar * P,UChar * C,UChar * C2,UChar * R,int h,int inc,UChar * M,UChar pr)563 PutSpriteM (UChar * P, UChar * C, UChar * C2, UChar * R, int h, int inc,
564 	    UChar * M, UChar pr)
565 {
566   int i, J;
567   unsigned long L;
568 #if defined(NEW_GFX_ENGINE)
569   for (i = 0; i < h;
570        i++, C += inc, C2 += inc * 4, P += XBUF_WIDTH, M += XBUF_WIDTH)
571 #else
572   for (i = 0; i < h; i++, C += inc, C2 += inc * 4, P += WIDTH, M += WIDTH)
573 #endif
574     {
575       J =
576 	(C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] +
577 							 (C[65] << 8)) |
578 	(C[96] + (C[97] << 8));
579       /*
580          J =
581          ((UInt16 *) C)[0] | ((UInt16 *) C)[16] | ((UInt16 *) C)[32] | ((UInt16 *)
582          C)[48];
583        */
584       //fprintf(stderr,"Masked : %lX\n",J);
585       if (!J)
586 	continue;
587       /* L = C2[1];     *///sp2pixel(C+1);
588       L = C2[4] + (C2[5] << 8) + (C2[6] << 16) + (C2[7] << 24);
589 
590       if ((J & 0x8000) && M[0] <= pr)
591 	P[0] = PAL ((L >> 4) & 15);
592       if ((J & 0x4000) && M[1] <= pr)
593 	P[1] = PAL ((L >> 12) & 15);
594       if ((J & 0x2000) && M[2] <= pr)
595 	P[2] = PAL ((L >> 20) & 15);
596       if ((J & 0x1000) && M[3] <= pr)
597 	P[3] = PAL ((L >> 28));
598       if ((J & 0x0800) && M[4] <= pr)
599 	P[4] = PAL ((L) & 15);
600       if ((J & 0x0400) && M[5] <= pr)
601 	P[5] = PAL ((L >> 8) & 15);
602       if ((J & 0x0200) && M[6] <= pr)
603 	P[6] = PAL ((L >> 16) & 15);
604       if ((J & 0x0100) && M[7] <= pr)
605 	P[7] = PAL ((L >> 24) & 15);
606       /* L = C2[0];     *///sp2pixel(C);
607       L = C2[0] + (C2[1] << 8) + (C2[2] << 16) + (C2[3] << 24);
608       if ((J & 0x80) && M[8] <= pr)
609 	P[8] = PAL ((L >> 4) & 15);
610       if ((J & 0x40) && M[9] <= pr)
611 	P[9] = PAL ((L >> 12) & 15);
612       if ((J & 0x20) && M[10] <= pr)
613 	P[10] = PAL ((L >> 20) & 15);
614       if ((J & 0x10) && M[11] <= pr)
615 	P[11] = PAL ((L >> 28));
616       if ((J & 0x08) && M[12] <= pr)
617 	P[12] = PAL ((L) & 15);
618       if ((J & 0x04) && M[13] <= pr)
619 	P[13] = PAL ((L >> 8) & 15);
620       if ((J & 0x02) && M[14] <= pr)
621 	P[14] = PAL ((L >> 16) & 15);
622       if ((J & 0x01) && M[15] <= pr)
623 	P[15] = PAL ((L >> 24) & 15);
624     }
625 }
626 
627 static void
PutSpriteHflipM(UChar * P,UChar * C,UChar * C2,UChar * R,int h,int inc,UChar * M,UChar pr)628 PutSpriteHflipM (UChar * P, UChar * C, UChar * C2, UChar * R, int h,
629 		 int inc, UChar * M, UChar pr)
630 {
631   int i, J;
632   unsigned long L;
633 #if defined(NEW_GFX_ENGINE)
634   for (i = 0; i < h;
635        i++, C += inc, C2 += inc * 4, P += XBUF_WIDTH, M += XBUF_WIDTH)
636 #else
637   for (i = 0; i < h; i++, C += inc, C2 += inc * 4, P += WIDTH, M += WIDTH)
638 #endif
639     {
640       J =
641 	(C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] +
642 							 (C[65] << 8)) |
643 	(C[96] + (C[97] << 8));
644       /*
645          J =
646          ((UInt16 *) C)[0] | ((UInt16 *) C)[16] | ((UInt16 *) C)[32] | ((UInt16 *)
647          C)[48];
648        */
649       if (!J)
650 	continue;
651       /* L = C2[1];     *///sp2pixel(C+1);
652       L = C2[4] + (C2[5] << 8) + (C2[6] << 16) + (C2[7] << 24);
653       if ((J & 0x8000) && M[15] <= pr)
654 	P[15] = PAL ((L >> 4) & 15);
655       if ((J & 0x4000) && M[14] <= pr)
656 	P[14] = PAL ((L >> 12) & 15);
657       if ((J & 0x2000) && M[13] <= pr)
658 	P[13] = PAL ((L >> 20) & 15);
659       if ((J & 0x1000) && M[12] <= pr)
660 	P[12] = PAL ((L >> 28));
661       if ((J & 0x0800) && M[11] <= pr)
662 	P[11] = PAL ((L) & 15);
663       if ((J & 0x0400) && M[10] <= pr)
664 	P[10] = PAL ((L >> 8) & 15);
665       if ((J & 0x0200) && M[9] <= pr)
666 	P[9] = PAL ((L >> 16) & 15);
667       if ((J & 0x0100) && M[8] <= pr)
668 	P[8] = PAL ((L >> 24) & 15);
669       /* L = C2[0];     *///sp2pixel(C);
670       L = C2[0] + (C2[1] << 8) + (C2[2] << 16) + (C2[3] << 24);
671       if ((J & 0x80) && M[7] <= pr)
672 	P[7] = PAL ((L >> 4) & 15);
673       if ((J & 0x40) && M[6] <= pr)
674 	P[6] = PAL ((L >> 12) & 15);
675       if ((J & 0x20) && M[5] <= pr)
676 	P[5] = PAL ((L >> 20) & 15);
677       if ((J & 0x10) && M[4] <= pr)
678 	P[4] = PAL ((L >> 28));
679       if ((J & 0x08) && M[3] <= pr)
680 	P[3] = PAL ((L) & 15);
681       if ((J & 0x04) && M[2] <= pr)
682 	P[2] = PAL ((L >> 8) & 15);
683       if ((J & 0x02) && M[1] <= pr)
684 	P[1] = PAL ((L >> 16) & 15);
685       if ((J & 0x01) && M[0] <= pr)
686 	P[0] = PAL ((L >> 24) & 15);
687     }
688 }
689 
690 void
PutSpriteMakeMask(UChar * P,UChar * C,UChar * C2,UChar * R,int h,int inc,UChar * M,UChar pr)691 PutSpriteMakeMask (UChar * P, UChar * C, UChar * C2, UChar * R, int h,
692 		   int inc, UChar * M, UChar pr)
693 {
694   int i;
695   UInt16 J;
696   unsigned long L;
697 #if defined(NEW_GFX_ENGINE)
698   for (i = 0; i < h;
699        i++, C += inc, C2 += inc * 4, P += XBUF_WIDTH, M += XBUF_WIDTH)
700 #else
701   for (i = 0; i < h; i++, C += inc, C2 += inc * 4, P += WIDTH, M += WIDTH)
702 #endif
703     {
704       /*
705          J =
706          ((UInt16 *) C)[0] | ((UInt16 *) C)[16] | ((UInt16 *) C)[32] | ((UInt16 *)
707          C)[48];
708        */
709 
710       J =
711 	(C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] +
712 							 (C[65] << 8)) |
713 	(C[96] + (C[97] << 8));
714 
715       /*
716          if ((UInt16)J != (UInt16)((C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] + (C[65] << 8)) | (C[92] + (C[93] << 8))))
717          {
718          Log("J != ... ( 0x%x != 0x%x )\n", J, (C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] + (C[65] << 8)) | (C[92] + (C[93] << 8)));
719          Log("((UInt16 *) C)[0] = %x\t(C[0] + (C[1] << 8)) = %x\n", ((UInt16 *) C)[0], (C[0] + (C[1] << 8)));
720          Log("((UInt16 *) C)[16] = %x\t(C[32] + (C[33] << 8)) = %x\n", ((UInt16 *) C)[16], (C[32] + (C[33] << 8)));
721          Log("((UInt16 *) C)[32] = %x\t(C[64] + (C[65] << 8)) = %x\n", ((UInt16 *) C)[32], (C[64] + (C[65] << 8)));
722          Log("((UInt16 *) C)[48] = %x\t(C[92] + (C[93] << 8)) = %x\n", ((UInt16 *) C)[48], (C[92] + (C[93] << 8)));
723          Log("& ((UInt16 *) C)[48] = %p\t&C[92] = %p\n", & ((UInt16 *) C)[48], & C[92] );
724          }
725        */
726 
727       if (!J)
728 	continue;
729       /* L = C2[1];     *///sp2pixel(C+1);
730       L = C2[4] + (C2[5] << 8) + (C2[6] << 16) + (C2[7] << 24);
731       if (J & 0x8000)
732 	{
733 	  P[0] = PAL ((L >> 4) & 15);
734 	  M[0] = pr;
735 	}
736       if (J & 0x4000)
737 	{
738 	  P[1] = PAL ((L >> 12) & 15);
739 	  M[1] = pr;
740 	}
741       if (J & 0x2000)
742 	{
743 	  P[2] = PAL ((L >> 20) & 15);
744 	  M[2] = pr;
745 	}
746       if (J & 0x1000)
747 	{
748 	  P[3] = PAL ((L >> 28));
749 	  M[3] = pr;
750 	}
751       if (J & 0x0800)
752 	{
753 	  P[4] = PAL ((L) & 15);
754 	  M[4] = pr;
755 	}
756       if (J & 0x0400)
757 	{
758 	  P[5] = PAL ((L >> 8) & 15);
759 	  M[5] = pr;
760 	}
761       if (J & 0x0200)
762 	{
763 	  P[6] = PAL ((L >> 16) & 15);
764 	  M[6] = pr;
765 	}
766       if (J & 0x0100)
767 	{
768 	  P[7] = PAL ((L >> 24) & 15);
769 	  M[7] = pr;
770 	}
771       /* L = C2[0];     *///sp2pixel(C);
772       L = C2[0] + (C2[1] << 8) + (C2[2] << 16) + (C2[3] << 24);
773       if (J & 0x80)
774 	{
775 	  P[8] = PAL ((L >> 4) & 15);
776 	  M[8] = pr;
777 	}
778       if (J & 0x40)
779 	{
780 	  P[9] = PAL ((L >> 12) & 15);
781 	  M[9] = pr;
782 	}
783       if (J & 0x20)
784 	{
785 	  P[10] = PAL ((L >> 20) & 15);
786 	  M[10] = pr;
787 	}
788       if (J & 0x10)
789 	{
790 	  P[11] = PAL ((L >> 28));
791 	  M[11] = pr;
792 	}
793       if (J & 0x08)
794 	{
795 	  P[12] = PAL ((L) & 15);
796 	  M[12] = pr;
797 	}
798       if (J & 0x04)
799 	{
800 	  P[13] = PAL ((L >> 8) & 15);
801 	  M[13] = pr;
802 	}
803       if (J & 0x02)
804 	{
805 	  P[14] = PAL ((L >> 16) & 15);
806 	  M[14] = pr;
807 	}
808       if (J & 0x01)
809 	{
810 	  P[15] = PAL ((L >> 24) & 15);
811 	  M[15] = pr;
812 	}
813     }
814 }
815 
816 static void
PutSpriteHflipMakeMask(UChar * P,UChar * C,UChar * C2,UChar * R,int h,int inc,UChar * M,UChar pr)817 PutSpriteHflipMakeMask (UChar * P, UChar * C, UChar * C2, UChar * R,
818 			int h, int inc, UChar * M, UChar pr)
819 {
820   int i, J;
821   unsigned long L;
822 #if defined(NEW_GFX_ENGINE)
823   for (i = 0; i < h;
824        i++, C += inc, C2 += inc * 4, P += XBUF_WIDTH, M += XBUF_WIDTH)
825 #else
826   for (i = 0; i < h; i++, C += inc, C2 += inc * 4, P += WIDTH, M += WIDTH)
827 #endif
828     {
829       J =
830 	(C[0] + (C[1] << 8)) | (C[32] + (C[33] << 8)) | (C[64] +
831 							 (C[65] << 8)) |
832 	(C[96] + (C[97] << 8));
833       /*
834          J =
835          ((UInt16 *) C)[0] | ((UInt16 *) C)[16] | ((UInt16 *) C)[32] | ((UInt16 *)
836          C)[48];
837        */
838       if (!J)
839 	continue;
840       L = C2[4] + (C2[5] << 8) + (C2[6] << 16) + (C2[7] << 24);	//sp2pixel(C+1);
841       if (J & 0x8000)
842 	{
843 	  P[15] = PAL ((L >> 4) & 15);
844 	  M[15] = pr;
845 	}
846       if (J & 0x4000)
847 	{
848 	  P[14] = PAL ((L >> 12) & 15);
849 	  M[14] = pr;
850 	}
851       if (J & 0x2000)
852 	{
853 	  P[13] = PAL ((L >> 20) & 15);
854 	  M[13] = pr;
855 	}
856       if (J & 0x1000)
857 	{
858 	  P[12] = PAL ((L >> 28));
859 	  M[12] = pr;
860 	}
861       if (J & 0x0800)
862 	{
863 	  P[11] = PAL ((L) & 15);
864 	  M[11] = pr;
865 	}
866       if (J & 0x0400)
867 	{
868 	  P[10] = PAL ((L >> 8) & 15);
869 	  M[10] = pr;
870 	}
871       if (J & 0x0200)
872 	{
873 	  P[9] = PAL ((L >> 16) & 15);
874 	  M[9] = pr;
875 	}
876       if (J & 0x0100)
877 	{
878 	  P[8] = PAL ((L >> 24) & 15);
879 	  M[8] = pr;
880 	}
881       /* L = C2[0];             *///sp2pixel(C);
882       L = C2[0] + (C2[1] << 8) + (C2[2] << 16) + (C2[3] << 24);
883       if (J & 0x80)
884 	{
885 	  P[7] = PAL ((L >> 4) & 15);
886 	  M[7] = pr;
887 	}
888       if (J & 0x40)
889 	{
890 	  P[6] = PAL ((L >> 12) & 15);
891 	  M[6] = pr;
892 	}
893       if (J & 0x20)
894 	{
895 	  P[5] = PAL ((L >> 20) & 15);
896 	  M[5] = pr;
897 	}
898       if (J & 0x10)
899 	{
900 	  P[4] = PAL ((L >> 28));
901 	  M[4] = pr;
902 	}
903       if (J & 0x08)
904 	{
905 	  P[3] = PAL ((L) & 15);
906 	  M[3] = pr;
907 	}
908       if (J & 0x04)
909 	{
910 	  P[2] = PAL ((L >> 8) & 15);
911 	  M[2] = pr;
912 	}
913       if (J & 0x02)
914 	{
915 	  P[1] = PAL ((L >> 16) & 15);
916 	  M[1] = pr;
917 	}
918       if (J & 0x01)
919 	{
920 	  P[0] = PAL ((L >> 24) & 15);
921 	  M[0] = pr;
922 	}
923     }
924 }
925 
926 /*****************************************************************************
927 
928     Function: RefreshSpriteExact
929 
930     Description: draw all sprites between two lines, with the normal method
931     Parameters: int Y1, int Y2 (the 'ordonee' to draw between), UChar bg (do we draw fg or bg sprites)
932     Return: absolutly nothing
933 
934 *****************************************************************************/
935 
936 void
RefreshSpriteExact(int Y1,int Y2,UChar bg)937 RefreshSpriteExact (int Y1, int Y2, UChar bg)
938 {
939   int n;
940   SPR *spr;
941   static int usespbg = 0;
942 
943   /* TEST */
944   Y2++;
945 
946   spr = (SPR *) SPRAM + 63;
947 
948   if (bg == 0)
949     usespbg = 0;
950 
951   for (n = 0; n < 64; n++, spr--)
952     {
953       int x, y, no, atr, inc, cgx, cgy;
954       UChar *R, *C;
955       UChar *C2;
956       int pos;
957       int h, t, i, j;
958       int y_sum;
959       int spbg;
960 
961       atr = spr->atr;
962       spbg = (atr >> 7) & 1;
963       if (spbg != bg)
964 	continue;
965       y = (spr->y & 1023) - 64;
966       x = (spr->x & 1023) - 32;
967 
968       no = spr->no & 2047;
969       // 4095 is for supergraphx only
970       // no = (unsigned int)(spr->no & 4095);
971 
972 #if defined(GFX_DEBUG)
973       /*
974          Log("Sprite 0x%02X : X = %d, Y = %d, atr = 0x%04X, no = 0x%03X\n",
975          n,
976          x,
977          y,
978          atr,
979          (unsigned long)no);
980        */
981 #endif
982 
983       cgx = (atr >> 8) & 1;
984       cgy = (atr >> 12) & 3;
985       cgy |= cgy >> 1;
986       no = (no >> 1) & ~(cgy * 2 + cgx);
987       if (y >= Y2 || y + (cgy + 1) * 16 < Y1 || x >= FC_W
988 	  || x + (cgx + 1) * 16 < 0)
989 	continue;
990 
991       R = &SPal[(atr & 15) * 16];
992       for (i = 0; i < cgy * 2 + cgx + 1; i++)
993 	{
994 	  if (vchanges[no + i])
995 	    {
996 	      vchanges[no + i] = 0;
997 	      sp2pixel (no + i);
998 	    }
999 	  if (!cgx)
1000 	    i++;
1001 	}
1002       C = VRAM + (no * 128);
1003       C2 = VRAMS + (no * 32) * 4;	/* TEST */
1004 #if defined(NEW_GFX_ENGINE)
1005       pos = XBUF_WIDTH * (y + 0) + x;
1006 #else
1007       pos =
1008 	WIDTH * (HEIGHT - FC_H) / 2 + (WIDTH - FC_W) / 2 + WIDTH * (y + 0) +
1009 	x;
1010 #endif
1011       inc = 2;
1012       if (atr & V_FLIP)
1013 	{
1014 	  inc = -2;
1015 	  C += 15 * 2 + cgy * 256;
1016 	  C2 += (15 * 2 + cgy * 64) * 4;
1017 	}
1018       y_sum = 0;
1019 
1020       for (i = 0; i <= cgy; i++)
1021 	{
1022 	  t = Y1 - y - y_sum;
1023 	  h = 16;
1024 	  if (t > 0)
1025 	    {
1026 	      C += t * inc;
1027 	      C2 += (t * inc) * 4;
1028 	      h -= t;
1029 #if defined(NEW_GFX_ENGINE)
1030 	      pos += t * XBUF_WIDTH;
1031 #else
1032 	      pos += t * WIDTH;
1033 #endif
1034 
1035 	    }
1036 	  if (h > Y2 - y - y_sum)
1037 	    h = Y2 - y - y_sum;
1038 	  if (spbg == 0)
1039 	    {
1040 	      usespbg = 1;
1041 	      if (atr & H_FLIP)
1042 		{
1043 		  for (j = 0; j <= cgx; j++)
1044 		    PutSpriteHflipMakeMask (osd_gfx_buffer + pos +
1045 					    (cgx - j) * 16, C + j * 128,
1046 					    C2 + j * 32 * 4, R, h, inc,
1047 					    SPM + pos + (cgx - j) * 16, n);
1048 		}
1049 	      else
1050 		{
1051 		  for (j = 0; j <= cgx; j++)
1052 		    PutSpriteMakeMask (osd_gfx_buffer + pos + (j) * 16,
1053 				       C + j * 128, C2 + j * 32 * 4, R, h,
1054 				       inc, SPM + pos + j * 16, n);
1055 		}
1056 	    }
1057 	  else if (usespbg)
1058 	    {
1059 	      if (atr & H_FLIP)
1060 		{
1061 		  for (j = 0; j <= cgx; j++)
1062 		    PutSpriteHflipM (osd_gfx_buffer + pos + (cgx - j) * 16,
1063 				     C + j * 128, C2 + j * 32 * 4, R, h, inc,
1064 				     SPM + pos + (cgx - j) * 16, n);
1065 		}
1066 	      else
1067 		{
1068 		  for (j = 0; j <= cgx; j++)
1069 		    PutSpriteM (osd_gfx_buffer + pos + (j) * 16, C + j * 128,
1070 				C2 + j * 32 * 4, R, h, inc,
1071 				SPM + pos + j * 16, n);
1072 
1073 		}
1074 	    }
1075 	  else
1076 	    {
1077 	      if (atr & H_FLIP)
1078 		{
1079 		  for (j = 0; j <= cgx; j++)
1080 		    PutSpriteHflip (osd_gfx_buffer + pos + (cgx - j) * 16,
1081 				    C + j * 128, C2 + j * 32 * 4, R, h, inc);
1082 		}
1083 	      else
1084 		{
1085 		  for (j = 0; j <= cgx; j++)
1086 		    PutSprite (osd_gfx_buffer + pos + (j) * 16, C + j * 128,
1087 			       C2 + j * 32 * 4, R, h, inc);
1088 		}
1089 	    }
1090 #if defined(NEW_GFX_ENGINE)
1091 	  pos += h * XBUF_WIDTH;
1092 #else
1093 	  pos += h * WIDTH;
1094 #endif
1095 	  C += h * inc + 16 * 7 * inc;
1096 	  C2 += (h * inc + 16 * inc) * 4;
1097 	  y_sum += 16;
1098 	}
1099     }
1100   return;
1101 }
1102 
1103 char tmp_str[10];
1104 extern int vheight;
1105 extern char *sbuf[];
1106 
1107 /*****************************************************************************
1108 
1109     Function: RefreshScreen
1110 
1111     Description: refresh screen
1112     Parameters: none
1113     Return: nothing
1114 
1115 *****************************************************************************/
1116 void
RefreshScreen(void)1117 RefreshScreen (void)
1118 {
1119 
1120   frame += UPeriod + 1;
1121 
1122   HCD_handle_subtitle ();
1123   /*
1124      {
1125      char* spr = SPRAM;
1126      UInt32 CRC = -1;
1127      int index;
1128      for (index = 0; index < 64 * sizeof(SPR); index++)
1129      {
1130      spr[index] ^= CRC;
1131      CRC >>= 8;
1132      CRC ^= TAB_CONST[spr[index]];
1133      }
1134      Log("frame %d : CRC = %X\n", frame, CRC);
1135      }
1136 
1137      {
1138      char* spr = ((UInt16*)VRAM) + 2048;
1139      UInt32 CRC = -1;
1140      int index;
1141      for (index = 0; index < 64 * sizeof(SPR); index++)
1142      {
1143      char tmp = spr[index];
1144      tmp ^= CRC;
1145      CRC >>= 8;
1146      CRC ^= TAB_CONST[tmp];
1147      }
1148      Log("frame %d : CRC VRAM[2048-] = %X\n", frame, CRC);
1149      }
1150    */
1151   (*osd_gfx_driver_list[video_driver].draw) ();
1152 
1153   if (!silent)
1154     (*update_sound[sound_driver]) ();
1155 
1156 #if defined(GFX_DEBUG)
1157   /*
1158      Log("VRAM: %02x%02x%02x%02x %02x%02x%02x%02x\n",
1159      VRAM[0],
1160      VRAM[1],
1161      VRAM[2],
1162      VRAM[3],
1163      VRAM[4],
1164      VRAM[5],
1165      VRAM[6],
1166      VRAM[7]);
1167    */
1168 
1169   {
1170     int index;
1171     unsigned char tmp_data;
1172     unsigned int CRC = 0xFFFFFFFF;
1173 
1174     for (index = 0; index < 0x10000; index++)
1175       {
1176 	tmp_data = VRAM2[index];
1177 	tmp_data ^= CRC;
1178 	CRC >>= 8;
1179 	CRC ^= TAB_CONST[tmp_data];
1180       }
1181     Log ("VRAM2 CRC = %08x\n", ~CRC);
1182 
1183     for (index = 0; index < 0x10000; index++)
1184       {
1185 	if (VRAM2[index] != 0)
1186 	  Log ("%04X:%08X\n", index, VRAM2[index]);
1187       }
1188   }
1189 
1190   /*
1191      {
1192      int index;
1193      unsigned char tmp_data;
1194      unsigned int CRC = 0xFFFFFFFF;
1195 
1196      for (index = 0; index < 256; index++)
1197      {
1198      tmp_data = zp_base[index];
1199      tmp_data ^= CRC;
1200      CRC >>= 8;
1201      CRC ^= TAB_CONST[tmp_data];
1202      }
1203      Log("ZP CRC = %08x\n", ~CRC);
1204      }
1205    */
1206 #endif
1207 
1208 #if defined(NEW_GFX_ENGINE)
1209   memset (osd_gfx_buffer, Pal[0], 240 * XBUF_WIDTH);	// We don't clear the part out of reach of the screen blitter
1210   memset (SPM, 0, 240 * XBUF_WIDTH);
1211 #else
1212   memset (osd_gfx_buffer + MinLine * WIDTH, Pal[0],
1213 	  (MaxLine - MinLine) * WIDTH);
1214   memset (SPM + MinLine * WIDTH, 0, (MaxLine - MinLine) * WIDTH);
1215 #endif
1216 
1217 }
1218