1 // Video rendering module for Psikyo SH2 games
2 // Lots of code here and there ripped directly from MAME
3 // Thanks to David Haywood for the initial MAME driver
4 // as well as some other valuable pointers.
5
6 #include "tiles_generic.h" // nScreenWidth & nScreenHeight
7 #include "psikyosh_render.h" // contains loads of macros
8
9 UINT8 *pPsikyoshTiles;
10 UINT32 *pPsikyoshSpriteBuffer;
11 UINT32 *pPsikyoshBgRAM;
12 UINT32 *pPsikyoshVidRegs;
13 UINT32 *pPsikyoshPalRAM;
14 UINT32 *pPsikyoshZoomRAM;
15
16 static UINT8 *DrvTransTab;
17 static UINT8 alphatable[0x100];
18
19 static UINT16 *DrvPriBmp;
20 static UINT8 *DrvZoomBmp;
21 static INT32 nDrvZoomPrev = -1;
22 static UINT32 *DrvTmpDraw;
23 static UINT32 *DrvTmpDraw_ptr;
24
25 static INT32 nGraphicsMin0; // minimum tile number 4bpp
26 static INT32 nGraphicsMin1; // for 8bpp
27 static INT32 nGraphicsSize; // normal
28 static INT32 nGraphicsSize0; // for 4bpp
29 static INT32 nGraphicsSize1; // for 8bpp
30
31 //--------------------------------------------------------------------------------
32
alpha_blend(UINT32 d,UINT32 s,UINT32 p)33 static inline UINT32 alpha_blend(UINT32 d, UINT32 s, UINT32 p)
34 {
35 if (p == 0) return d;
36
37 INT32 a = 256 - p;
38
39 return (((((s & 0xff00ff) * p) + ((d & 0xff00ff) * a)) & 0xff00ff00) |
40 ((((s & 0x00ff00) * p) + ((d & 0x00ff00) * a)) & 0x00ff0000)) >> 8;
41 }
42
43 //--------------------------------------------------------------------------------
44
draw_blendy_tile(INT32 gfx,INT32 code,INT32 color,INT32 sx,INT32 sy,INT32 fx,INT32 fy,INT32 alpha,INT32 z)45 static void draw_blendy_tile(INT32 gfx, INT32 code, INT32 color, INT32 sx, INT32 sy, INT32 fx, INT32 fy, INT32 alpha, INT32 z)
46 {
47 color <<= 4;
48 UINT32 *pal = pBurnDrvPalette + color;
49
50 if (gfx == 0) {
51 code &= 0x7ffff;
52 code -= nGraphicsMin0;
53 if (code < 0 || code > nGraphicsSize0) return;
54
55 if (DrvTransTab[code >> 3] & (1 << (code & 7))) return;
56
57 UINT8 *src = pPsikyoshTiles + (code << 7);
58
59 INT32 inc = 8;
60 if (fy) {
61 inc = -8;
62 src += 0x78;
63 }
64
65 if (sx >= 0 && sx < (nScreenWidth-16) && sy >= 0 && sy <= (nScreenHeight-16)) {
66 if (z > 0) {
67 if (fx) {
68 if (alpha == 0xff) {
69 PUTPIXEL_4BPP_NORMAL_PRIO_FLIPX()
70 } else if (alpha >= 0) {
71 PUTPIXEL_4BPP_ALPHA_PRIO_FLIPX()
72 } else {
73 PUTPIXEL_4BPP_ALPHATAB_PRIO_FLIPX()
74 }
75 } else {
76 if (alpha == 0xff) {
77 PUTPIXEL_4BPP_NORMAL_PRIO()
78 } else if (alpha >= 0) {
79 PUTPIXEL_4BPP_ALPHA_PRIO()
80 } else {
81 PUTPIXEL_4BPP_ALPHATAB_PRIO()
82 }
83 }
84 } else {
85 if (fx) {
86 if (alpha == 0xff) {
87 PUTPIXEL_4BPP_NORMAL_FLIPX()
88 } else if (alpha >= 0) {
89 PUTPIXEL_4BPP_ALPHA_FLIPX()
90 } else {
91 PUTPIXEL_4BPP_ALPHATAB_FLIPX()
92 }
93 } else {
94 if (alpha == 0xff) {
95 PUTPIXEL_4BPP_NORMAL()
96 } else if (alpha >= 0) {
97 PUTPIXEL_4BPP_ALPHA()
98 } else {
99 PUTPIXEL_4BPP_ALPHATAB()
100 }
101 }
102 }
103 } else {
104 if (z > 0) {
105 if (fx) {
106 if (alpha == 0xff) {
107 PUTPIXEL_4BPP_NORMAL_PRIO_FLIPX_CLIP()
108 } else if (alpha >= 0) {
109 PUTPIXEL_4BPP_ALPHA_PRIO_FLIPX_CLIP()
110 } else {
111 PUTPIXEL_4BPP_ALPHATAB_PRIO_FLIPX_CLIP()
112 }
113 } else {
114 if (alpha == 0xff) {
115 PUTPIXEL_4BPP_NORMAL_PRIO_CLIP()
116 } else if (alpha >= 0) {
117 PUTPIXEL_4BPP_ALPHA_PRIO_CLIP()
118 } else {
119 PUTPIXEL_4BPP_ALPHATAB_PRIO_CLIP()
120 }
121 }
122 } else {
123 if (fx) {
124 if (alpha == 0xff) {
125 PUTPIXEL_4BPP_NORMAL_FLIPX_CLIP()
126 } else if (alpha >= 0) {
127 PUTPIXEL_4BPP_ALPHA_FLIPX_CLIP()
128 } else {
129 PUTPIXEL_4BPP_ALPHATAB_FLIPX_CLIP()
130 }
131 } else {
132 if (alpha == 0xff) {
133 PUTPIXEL_4BPP_NORMAL_CLIP()
134 } else if (alpha >= 0) {
135 PUTPIXEL_4BPP_ALPHA_CLIP()
136 } else {
137 PUTPIXEL_4BPP_ALPHATAB_CLIP()
138 }
139 }
140 }
141 }
142 } else {
143 code &= 0x3ffff;
144 code -= nGraphicsMin1;
145 if (code < 0 || code > nGraphicsSize0) return;
146
147 if (DrvTransTab[(code >> 3) + 0x10000] & (1 << (code & 7))) return;
148
149 UINT8 *src = pPsikyoshTiles + (code << 8);
150
151 INT32 inc = 16;
152 if (fy) {
153 inc = -16;
154 src += 0xf0;
155 }
156
157 if (sx >= 0 && sx < (nScreenWidth-16) && sy >= 0 && sy < (nScreenHeight-16)) {
158 if (z > 0) {
159 if (fx) {
160 if (alpha == 0xff) {
161 PUTPIXEL_8BPP_NORMAL_PRIO_FLIPX()
162 } else if (alpha >= 0) {
163 PUTPIXEL_8BPP_ALPHA_PRIO_FLIPX()
164 } else {
165 PUTPIXEL_8BPP_ALPHATAB_PRIO_FLIPX()
166 }
167 } else {
168 if (alpha == 0xff) {
169 PUTPIXEL_8BPP_NORMAL_PRIO()
170 } else if (alpha >= 0) {
171 PUTPIXEL_8BPP_ALPHA_PRIO()
172 } else {
173 PUTPIXEL_8BPP_ALPHATAB_PRIO()
174 }
175 }
176 } else {
177 if (fx) {
178 if (alpha == 0xff) {
179 PUTPIXEL_8BPP_NORMAL_FLIPX()
180 } else if (alpha >= 0) {
181 PUTPIXEL_8BPP_ALPHA_FLIPX()
182 } else {
183 PUTPIXEL_8BPP_ALPHATAB_FLIPX()
184 }
185 } else {
186 if (alpha == 0xff) {
187 PUTPIXEL_8BPP_NORMAL()
188 } else if (alpha >= 0) {
189 PUTPIXEL_8BPP_ALPHA()
190 } else {
191 PUTPIXEL_8BPP_ALPHATAB()
192 }
193 }
194 }
195 } else {
196 if (z > 0) {
197 if (fx) {
198 if (alpha == 0xff) {
199 PUTPIXEL_8BPP_NORMAL_PRIO_FLIPX_CLIP()
200 } else if (alpha >= 0) {
201 PUTPIXEL_8BPP_ALPHA_PRIO_FLIPX_CLIP()
202 } else {
203 PUTPIXEL_8BPP_ALPHATAB_PRIO_FLIPX_CLIP()
204 }
205 } else {
206 if (alpha == 0xff) {
207 PUTPIXEL_8BPP_NORMAL_PRIO_CLIP()
208 } else if (alpha >= 0) {
209 PUTPIXEL_8BPP_ALPHA_PRIO_CLIP()
210 } else {
211 PUTPIXEL_8BPP_ALPHATAB_PRIO_CLIP()
212 }
213 }
214 } else {
215 if (fx) {
216 if (alpha == 0xff) {
217 PUTPIXEL_8BPP_NORMAL_FLIPX_CLIP()
218 } else if (alpha >= 0) {
219 PUTPIXEL_8BPP_ALPHA_FLIPX_CLIP()
220 } else {
221 PUTPIXEL_8BPP_ALPHATAB_FLIPX_CLIP()
222 }
223 } else {
224 if (alpha == 0xff) {
225 PUTPIXEL_8BPP_NORMAL_CLIP()
226 } else if (alpha >= 0) {
227 PUTPIXEL_8BPP_ALPHA_CLIP()
228 } else {
229 PUTPIXEL_8BPP_ALPHATAB_CLIP()
230 }
231 }
232 }
233
234 }
235 }
236 }
237
draw_prezoom(INT32 gfx,INT32 code,INT32 high,INT32 wide)238 static void draw_prezoom(INT32 gfx, INT32 code, INT32 high, INT32 wide)
239 {
240 // these probably aren't the safest routines, but they should be pretty fast.
241
242 if (gfx) {
243 INT32 tileno = (code & 0x3ffff) - nGraphicsMin1;
244 if (tileno < 0 || tileno > nGraphicsSize1) tileno = 0;
245 if (nDrvZoomPrev == tileno) return;
246 nDrvZoomPrev = tileno;
247 UINT32 *gfxptr = (UINT32*)(pPsikyoshTiles + (tileno << 8));
248
249 for (INT32 ytile = 0; ytile < high; ytile++)
250 {
251 for (INT32 xtile = 0; xtile < wide; xtile++)
252 {
253 UINT32 *dest = (UINT32*)(DrvZoomBmp + (ytile << 12) + (xtile << 4));
254
255 for (INT32 ypixel = 0; ypixel < 16; ypixel++, gfxptr += 4) {
256
257 dest[0] = gfxptr[0];
258 dest[1] = gfxptr[1];
259 dest[2] = gfxptr[2];
260 dest[3] = gfxptr[3];
261
262 dest += 64;
263 }
264 }
265 }
266 } else {
267 INT32 tileno = (code & 0x7ffff) - nGraphicsMin0;
268 if (tileno < 0 || tileno > nGraphicsSize0) tileno = 0;
269 if (nDrvZoomPrev == tileno) return;
270 nDrvZoomPrev = tileno;
271 UINT8 *gfxptr = pPsikyoshTiles + (tileno << 7);
272 for (INT32 ytile = 0; ytile < high; ytile++)
273 {
274 for (INT32 xtile = 0; xtile < wide; xtile++)
275 {
276 UINT8 *dest = DrvZoomBmp + (ytile << 12) + (xtile << 4);
277
278 for (INT32 ypixel = 0; ypixel < 16; ypixel++, gfxptr += 8)
279 {
280 for (INT32 xpixel = 0; xpixel < 16; xpixel+=2)
281 {
282 INT32 c = gfxptr[xpixel>>1];
283 dest[xpixel ] = c >> 4;
284 dest[xpixel + 1] = c & 0x0f;
285 }
286
287 dest += 256;
288 }
289 }
290 }
291 }
292 }
293
psikyosh_drawgfxzoom(INT32 gfx,UINT32 code,INT32 color,INT32 flipx,INT32 flipy,INT32 offsx,INT32 offsy,INT32 alpha,INT32 zoomx,INT32 zoomy,INT32 wide,INT32 high,INT32 z)294 static void psikyosh_drawgfxzoom(INT32 gfx, UINT32 code, INT32 color, INT32 flipx, INT32 flipy, INT32 offsx,
295 INT32 offsy, INT32 alpha, INT32 zoomx, INT32 zoomy, INT32 wide, INT32 high, INT32 z)
296 {
297 if (~nBurnLayer & 8) return;
298 if (!zoomx || !zoomy) return;
299
300 if (zoomx == 0x400 && zoomy == 0x400)
301 {
302 INT32 xstart, ystart, xend, yend, xinc, yinc, code_offset = 0;
303
304 if (flipx) { xstart = wide-1; xend = -1; xinc = -1; }
305 else { xstart = 0; xend = wide; xinc = +1; }
306
307 if (flipy) { ystart = high-1; yend = -1; yinc = -1; }
308 else { ystart = 0; yend = high; yinc = +1; }
309
310 for (INT32 ytile = ystart; ytile != yend; ytile += yinc )
311 {
312 for (INT32 xtile = xstart; xtile != xend; xtile += xinc )
313 {
314 INT32 sx = offsx + (xtile << 4);
315 INT32 sy = offsy + (ytile << 4);
316
317 draw_blendy_tile(gfx, code + code_offset++, color, sx, sy, flipx, flipy, alpha, z);
318 }
319 }
320 }
321 else
322 {
323 draw_prezoom(gfx, code, high, wide);
324
325 {
326 UINT32 *pal = pBurnDrvPalette + (color << 4);
327
328 INT32 sprite_screen_height = ((high << 24) / zoomy + 0x200) >> 10;
329 INT32 sprite_screen_width = ((wide << 24) / zoomx + 0x200) >> 10;
330
331 if (sprite_screen_width && sprite_screen_height)
332 {
333 INT32 sx = offsx;
334 INT32 sy = offsy;
335 INT32 ex = sx + sprite_screen_width;
336 INT32 ey = sy + sprite_screen_height;
337
338 INT32 x_index_base;
339 INT32 y_index;
340
341 INT32 dx, dy;
342
343 if (flipx) { x_index_base = (sprite_screen_width-1)*zoomx; dx = -zoomx; }
344 else { x_index_base = 0; dx = zoomx; }
345
346 if (flipy) { y_index = (sprite_screen_height-1)*zoomy; dy = -zoomy; }
347 else { y_index = 0; dy = zoomy; }
348
349 {
350 if (sx < 0) {
351 INT32 pixels = 0-sx;
352 sx += pixels;
353 x_index_base += pixels*dx;
354 }
355 if (sy < 0 ) {
356 INT32 pixels = 0-sy;
357 sy += pixels;
358 y_index += pixels*dy;
359 }
360 if (ex > nScreenWidth) {
361 INT32 pixels = ex-(nScreenWidth-1)-1;
362 ex -= pixels;
363 }
364 if (ey > nScreenHeight) {
365 INT32 pixels = ey-(nScreenHeight-1)-1;
366 ey -= pixels;
367 }
368 }
369
370 if (ex > sx)
371 {
372 if (alpha == 0xff) {
373 if (z > 0) {
374 PUTPIXEL_ZOOM_NORMAL_PRIO()
375 } else {
376 PUTPIXEL_ZOOM_NORMAL()
377 }
378 } else if (alpha >= 0) {
379 if (z > 0) {
380 PUTPIXEL_ZOOM_ALPHA_PRIO()
381 } else {
382 PUTPIXEL_ZOOM_ALPHA()
383 }
384 } else {
385 if (z > 0) {
386 PUTPIXEL_ZOOM_ALPHATAB_PRIO()
387 } else {
388 PUTPIXEL_ZOOM_ALPHATAB()
389 }
390 }
391 }
392 }
393 }
394 }
395 }
396
draw_sprites(UINT8 req_pri)397 static void draw_sprites(UINT8 req_pri)
398 {
399 UINT32 *src = pPsikyoshSpriteBuffer;
400 UINT16 *list = (UINT16 *)src + 0x3800/2;
401 UINT16 listlen = 0x800/2;
402 UINT16 listcntr = 0;
403 UINT16 *zoom_table = (UINT16 *)pPsikyoshZoomRAM;
404 UINT8 *alpha_table = (UINT8 *)pPsikyoshVidRegs;
405
406 while (listcntr < listlen)
407 {
408 UINT32 xpos, ypos, high, wide, flpx, flpy, zoomx, zoomy, tnum, colr, dpth, pri;
409 INT32 alpha;
410
411 #ifdef LSB_FIRST
412 UINT32 listdat = list[listcntr ^ 1];
413 #else
414 UINT32 listdat = list[listcntr];
415 #endif
416 UINT32 sprnum = (listdat & 0x03ff) << 2;
417
418 pri = (src[sprnum+1] & 0x00003000) >> 12;
419 pri = (pPsikyoshVidRegs[2] << (pri << 2)) >> 28;
420
421 if (pri == req_pri)
422 {
423 ypos = (src[sprnum+0] & 0x03ff0000) >> 16;
424 xpos = (src[sprnum+0] & 0x000003ff);
425 high =((src[sprnum+1] & 0x0f000000) >> 24) + 1;
426 wide =((src[sprnum+1] & 0x00000f00) >> 8) + 1;
427 flpy = (src[sprnum+1] & 0x80000000) >> 31;
428 flpx = (src[sprnum+1] & 0x00008000) >> 15;
429 zoomy = (src[sprnum+1] & 0x00ff0000) >> 16;
430 zoomx = (src[sprnum+1] & 0x000000ff);
431 tnum = (src[sprnum+2] & 0x0007ffff);
432 dpth = (src[sprnum+2] & 0x00800000) >> 23;
433 colr = (src[sprnum+2] & 0xff000000) >> 24;
434 alpha = (src[sprnum+2] & 0x00700000) >> 20;
435
436 if (ypos & 0x200) ypos -= 0x400;
437 if (xpos & 0x200) xpos -= 0x400;
438
439 #ifdef LSB_FIRST
440 alpha = alpha_table[alpha ^ 3];
441 #else
442 alpha = alpha_table[alpha];
443 #endif
444
445 if (alpha & 0x80) {
446 alpha = -1;
447 } else {
448 alpha = alphatable[alpha | 0xc0];
449 }
450
451 #ifdef LSB_FIRST
452 if (zoom_table[zoomy ^ 1] && zoom_table[zoomx ^ 1])
453 #else
454 if (zoom_table[zoomy] && zoom_table[zoomx])
455 #endif
456 {
457 #ifdef LSB_FIRST
458 psikyosh_drawgfxzoom(dpth, tnum, colr, flpx, flpy, xpos, ypos, alpha,
459 (UINT32)zoom_table[zoomx ^ 1],(UINT32)zoom_table[zoomy ^ 1], wide, high, listcntr);
460 #else
461 psikyosh_drawgfxzoom(dpth, tnum, colr, flpx, flpy, xpos, ypos, alpha,
462 (UINT32)zoom_table[zoomx],(UINT32)zoom_table[zoomy], wide, high, listcntr);
463 #endif
464 }
465 }
466
467 listcntr++;
468 if (listdat & 0x4000) break;
469 }
470 }
471
draw_layer(INT32 layer,INT32 bank,INT32 alpha,INT32 scrollx,INT32 scrolly)472 static void draw_layer(INT32 layer, INT32 bank, INT32 alpha, INT32 scrollx, INT32 scrolly)
473 {
474 if ((bank < 0x0c) || (bank > 0x1f)) return;
475
476 if (alpha & 0x80) {
477 alpha = -1;
478 } else {
479 alpha = alphatable[alpha | 0xc0];
480 }
481
482 INT32 attr = pPsikyoshVidRegs[7] << (layer << 2);
483 INT32 gfx = attr & 0x00004000;
484 INT32 size =(attr & 0x00001000) ? 32 : 16;
485 INT32 wide = size * 16;
486
487 for (INT32 offs = 0; offs < size * 32; offs++) {
488 INT32 sx = (offs & 0x1f) << 4;
489 INT32 sy = (offs >> 5) << 4;
490
491 sx = (sx + scrollx) & 0x1ff;
492 sy = (sy + scrolly) & (wide-1);
493 if (sx >= nScreenWidth) sx -= 0x200;
494 if (sy >= nScreenHeight) sy -= wide;
495 if (sx < -15 || sy < -15) continue;
496
497 UINT32 code = pPsikyoshBgRAM[(bank*0x800)/4 + offs - 0x4000/4];
498
499 draw_blendy_tile(gfx, code & 0x7ffff, (code >> 24), sx, sy, 0, 0, alpha, 0);
500 }
501 }
502
draw_bglayer(INT32 layer)503 static void draw_bglayer(INT32 layer)
504 {
505 if (!(nBurnLayer & 1)) return;
506
507 INT32 scrollx, scrolly, bank, alpha;
508 INT32 scrollbank = ((pPsikyoshVidRegs[6] << (layer << 3)) >> 24) & 0x7f;
509 INT32 offset = (scrollbank == 0x0b) ? 0x200 : 0;
510
511 bank = (pPsikyoshBgRAM[0x17f0/4 + offset + layer] & 0x000000ff);
512 alpha = (pPsikyoshBgRAM[0x17f0/4 + offset + layer] & 0x0000bf00) >> 8;
513 scrollx = (pPsikyoshBgRAM[0x13f0/4 + offset + layer] & 0x000001ff);
514 scrolly = (pPsikyoshBgRAM[0x13f0/4 + offset + layer] & 0x03ff0000) >> 16;
515
516 if (scrollbank == 0x0d) scrollx += 0x08;
517
518 draw_layer(layer, bank, alpha, scrollx, scrolly);
519 }
520
draw_bglayertext(INT32 layer)521 static void draw_bglayertext(INT32 layer)
522 {
523 if (~nBurnLayer & 2) return;
524
525 INT32 scrollx, scrolly, bank, alpha;
526 INT32 scrollbank = ((pPsikyoshVidRegs[6] << (layer << 3)) >> 24) & 0x7f;
527
528 bank = (pPsikyoshBgRAM[(scrollbank*0x800)/4 + 0x0400/4 - 0x4000/4] & 0x000000ff);
529 alpha = (pPsikyoshBgRAM[(scrollbank*0x800)/4 + 0x0400/4 - 0x4000/4] & 0x0000bf00) >> 8;
530 scrollx = (pPsikyoshBgRAM[(scrollbank*0x800)/4 - 0x4000/4 ] & 0x000001ff);
531 scrolly = (pPsikyoshBgRAM[(scrollbank*0x800)/4 - 0x4000/4 ] & 0x03ff0000) >> 16;
532
533 draw_layer(layer, bank, alpha, scrollx, scrolly);
534
535 bank = (pPsikyoshBgRAM[(scrollbank*0x800)/4 + 0x0400/4 + 0x20/4 - 0x4000/4] & 0x000000ff);
536 alpha = (pPsikyoshBgRAM[(scrollbank*0x800)/4 + 0x0400/4 + 0x20/4 - 0x4000/4] & 0x0000bf00) >> 8;
537 scrollx = (pPsikyoshBgRAM[(scrollbank*0x800)/4 - 0x4000/4 + 0x20/4 ] & 0x000001ff);
538 scrolly = (pPsikyoshBgRAM[(scrollbank*0x800)/4 - 0x4000/4 + 0x20/4 ] & 0x03ff0000) >> 16;
539
540 draw_layer(layer, bank, alpha, scrollx, scrolly);
541 }
542
draw_bglayerscroll(INT32 layer)543 static void draw_bglayerscroll(INT32 layer)
544 {
545 if (!(nBurnLayer & 4)) return;
546
547 INT32 scrollx, bank, alpha;
548 INT32 scrollbank = ((pPsikyoshVidRegs[6] << (layer << 3)) >> 24) & 0x7f;
549
550 bank = (pPsikyoshBgRAM[(scrollbank*0x800)/4 + 0x0400/4 - 0x4000/4] & 0x000000ff);
551 alpha = (pPsikyoshBgRAM[(scrollbank*0x800)/4 + 0x0400/4 - 0x4000/4] & 0x0000bf00) >> 8;
552 scrollx = (pPsikyoshBgRAM[(scrollbank*0x800)/4 - 0x4000/4 ] & 0x000001ff);
553 // scrolly = (pPsikyoshBgRAM[(scrollbank*0x800)/4 - 0x4000/4 ] & 0x03ff0000) >> 16;
554
555 draw_layer(layer, bank, alpha, scrollx, 0);
556 }
557
draw_background(UINT8 req_pri)558 static void draw_background(UINT8 req_pri)
559 {
560 for (INT32 i = 0; i < 3; i++)
561 {
562 if (!((pPsikyoshVidRegs[7] << (i << 2)) & 0x8000))
563 continue;
564
565 INT32 bgtype = ((pPsikyoshVidRegs[6] << (i << 3)) >> 24) & 0x7f;
566
567 switch (bgtype)
568 {
569 case 0x0a: // Normal
570 if((pPsikyoshBgRAM[0x17f0/4 + (i*0x04)/4] >> 24) == req_pri)
571 draw_bglayer(i);
572 break;
573
574 case 0x0b: // Alt / Normal
575 if((pPsikyoshBgRAM[0x1ff0/4 + (i*0x04)/4] >> 24) == req_pri)
576 draw_bglayer(i);
577 break;
578
579 case 0x0c: // Using normal for now
580 case 0x0d: // Using normal for now
581 if((pPsikyoshBgRAM[(bgtype*0x800)/4 + 0x400/4 - 0x4000/4] >> 24) == req_pri)
582 draw_bglayertext(i);
583 break;
584
585 case 0x0e:
586 case 0x10: case 0x11: case 0x12: case 0x13:
587 case 0x14: case 0x15: case 0x16: case 0x17:
588 case 0x18: case 0x19: case 0x1a: case 0x1b:
589 case 0x1c: case 0x1d: case 0x1e: case 0x1f:
590 if((pPsikyoshBgRAM[(bgtype*0x800)/4 + 0x400/4 - 0x4000/4] >> 24) == req_pri)
591 draw_bglayerscroll(i);
592 break;
593 }
594 }
595 }
596
prelineblend()597 static void prelineblend()
598 {
599 UINT32 *linefill = pPsikyoshBgRAM;
600 UINT32 *destline = DrvTmpDraw;
601
602 for (INT32 y = 0; y < nScreenHeight; y++, destline+=nScreenWidth) {
603 if (linefill[y] & 0xff) {
604 for (INT32 x = 0; x < nScreenWidth; x++) {
605 destline[x] = linefill[y] >> 8;
606 }
607 }
608 }
609 }
610
postlineblend()611 static void postlineblend()
612 {
613 UINT32 *lineblend = pPsikyoshBgRAM + 0x0400/4;
614 UINT32 *destline = DrvTmpDraw;
615
616 for (INT32 y = 0; y < nScreenHeight; y++, destline+=nScreenWidth) {
617 if (lineblend[y] & 0x80) {
618 for (INT32 x = 0; x < nScreenWidth; x++) {
619 destline[x] = lineblend[y] >> 8;
620 }
621 }
622 else if (lineblend[y] & 0x7f) {
623 for (INT32 x = 0; x < nScreenWidth; x++) {
624 destline[x] = alpha_blend(destline[x], lineblend[y] >> 8, (lineblend[y] & 0x7f) << 1);
625 }
626 }
627 }
628 }
629
PsikyoshDraw()630 INT32 PsikyoshDraw()
631 {
632 {
633 for (INT32 i = 0; i < 0x5000 / 4; i++) {
634 pBurnDrvPalette[i] = pPsikyoshPalRAM[i] >> 8;
635 }
636 }
637
638 if (nBurnBpp == 4) {
639 DrvTmpDraw = (UINT32*)pBurnDraw;
640 } else {
641 DrvTmpDraw = DrvTmpDraw_ptr;
642 }
643
644 memset (DrvTmpDraw, 0, nScreenWidth * nScreenHeight * sizeof(UINT32));
645 memset (DrvPriBmp, 0, nScreenWidth * nScreenHeight * sizeof(INT16));
646
647 UINT32 *psikyosh_vidregs = pPsikyoshVidRegs;
648
649 prelineblend();
650
651 for (UINT32 i = 0; i < 8; i++) {
652 draw_sprites(i);
653 draw_background(i);
654 if ((psikyosh_vidregs[2] & 0x0f) == i) postlineblend();
655 }
656
657 if (nBurnBpp < 4) {
658 for (INT32 i = 0; i < nScreenWidth * nScreenHeight; i++) {
659 INT32 d = DrvTmpDraw[i];
660 PutPix(pBurnDraw + i * nBurnBpp, BurnHighCol(d>>16, d>>8, d, 0));
661 }
662 }
663
664 return 0;
665 }
666
fill_alphatable()667 static void fill_alphatable()
668 {
669 for (INT32 i = 0; i < 0xc0; i++)
670 alphatable[i] = 0xff;
671
672 for (INT32 i = 0; i < 0x40; i++) {
673 alphatable[i | 0xc0] = ((0x3f - i) * 0xff) / 0x3f;
674 }
675 }
676
calculate_transtab()677 static void calculate_transtab()
678 {
679 DrvTransTab = (UINT8*)BurnMalloc(0x18000);
680
681 memset (DrvTransTab, 0xff, 0x18000);
682
683 // first calculate all 4bpp tiles
684 for (INT32 i = 0; i < nGraphicsSize; i+= 0x80) {
685 for (INT32 j = 0; j < 0x80; j++) {
686 if (pPsikyoshTiles[i + j]) {
687 DrvTransTab[(i>>10) + 0x00000] &= ~(1 << ((i >> 7) & 7));
688 break;
689 }
690 }
691 }
692
693 // next, calculate all 8bpp tiles
694 for (INT32 i = 0; i < nGraphicsSize; i+= 0x100) {
695 for (INT32 j = 0; j < 0x100; j++) {
696 if (pPsikyoshTiles[i + j]) {
697 DrvTransTab[(i>>11) + 0x10000] &= ~(1 << ((i >> 8) & 7));
698 break;
699 }
700 }
701 }
702 }
703
PsikyoshVideoInit(INT32 gfx_max,INT32 gfx_min)704 void PsikyoshVideoInit(INT32 gfx_max, INT32 gfx_min)
705 {
706 DrvZoomBmp = (UINT8 *)BurnMalloc(16 * 16 * 16 * 16);
707 DrvPriBmp = (UINT16*)BurnMalloc(320 * 240 * sizeof(INT16));
708 DrvTmpDraw_ptr = (UINT32 *)BurnMalloc(320 * 240 * sizeof(UINT32));
709
710 if (BurnDrvGetFlags() & BDF_ORIENTATION_VERTICAL) {
711 BurnDrvGetVisibleSize(&nScreenHeight, &nScreenWidth);
712 } else {
713 BurnDrvGetVisibleSize(&nScreenWidth, &nScreenHeight);
714 }
715
716 nGraphicsSize = gfx_max - gfx_min;
717 nGraphicsMin0 = (gfx_min / 128);
718 nGraphicsMin1 = (gfx_min / 256);
719 nGraphicsSize0 = (nGraphicsSize / 128) - 1;
720 nGraphicsSize1 = (nGraphicsSize / 256) - 1;
721
722 calculate_transtab();
723 fill_alphatable();
724 }
725
PsikyoshVideoExit()726 void PsikyoshVideoExit()
727 {
728 BurnFree (DrvZoomBmp);
729 BurnFree (DrvPriBmp);
730 BurnFree (DrvTmpDraw_ptr);
731 DrvTmpDraw = NULL;
732 BurnFree (DrvTransTab);
733
734 nDrvZoomPrev = -1;
735 pPsikyoshTiles = NULL;
736 pPsikyoshSpriteBuffer = NULL;
737 pPsikyoshBgRAM = NULL;
738 pPsikyoshVidRegs = NULL;
739 pPsikyoshPalRAM = NULL;
740 pPsikyoshZoomRAM = NULL;
741 pBurnDrvPalette = NULL;
742
743 nScreenWidth = nScreenHeight = 0;
744 }
745