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