1 // license:BSD-3-Clause
2 // copyright-holders:David Haywood
3 
4 // k053247
5 
6 #include "tiles_generic.h"
7 #include "konamiic.h"
8 
9 #define K053247_CUSTOMSHADOW	0x20000000
10 #define K053247_SHDSHIFT		20
11 
12 static UINT8  K053246Regs[8];
13 static UINT8  K053246_OBJCHA_line;
14 UINT8 *K053247Ram;
15 static UINT16 K053247Regs[16];
16 
17 static UINT8 *K053246Gfx;
18 static UINT32   K053246Mask;
19 static UINT8 *K053246GfxExp;
20 static UINT32   K053246MaskExp;
21 
22 static INT32 K053247_dx;
23 static INT32 K053247_dy;
24 static INT32 K053247_wraparound;
25 
26 static INT32 nBpp = 4;
27 
28 static INT32 K053247Flags;
29 
30 void (*K053247Callback)(INT32 *code, INT32 *color, INT32 *priority);
31 
K053247Reset()32 void K053247Reset()
33 {
34 	memset (K053247Ram,  0, 0x1000);
35 	memset (K053247Regs, 0, 16 * sizeof (UINT16));
36 	memset (K053246Regs, 0, 8);
37 
38 	K053246_OBJCHA_line = 0; // clear
39 }
40 
K053247Scan(INT32 nAction)41 void K053247Scan(INT32 nAction)
42 {
43 	struct BurnArea ba;
44 
45 	if (nAction & ACB_MEMORY_RAM) {
46 		memset(&ba, 0, sizeof(ba));
47 		ba.Data	  = K053247Ram;
48 		ba.nLen	  = 0x1000;
49 		ba.szName = "K053247 Ram";
50 		BurnAcb(&ba);
51 
52 		ba.Data	  = K053247Regs;
53 		ba.nLen	  = 0x0010 * sizeof(UINT16);
54 		ba.szName = "K053247 Regs";
55 		BurnAcb(&ba);
56 
57 		ba.Data	  = K053246Regs;
58 		ba.nLen	  = 0x0008;
59 		ba.szName = "K053246 Regs";
60 		BurnAcb(&ba);
61 
62 		SCAN_VAR(K053246_OBJCHA_line);
63 		SCAN_VAR(K053247_wraparound);
64 	}
65 }
66 
K053247Init(UINT8 * gfxrom,UINT8 * gfxromexp,INT32 gfxlen,void (* Callback)(INT32 * code,INT32 * color,INT32 * priority),INT32 flags)67 void K053247Init(UINT8 *gfxrom, UINT8 *gfxromexp, INT32 gfxlen, void (*Callback)(INT32 *code, INT32 *color, INT32 *priority), INT32 flags)
68 {
69 	K053247Ram = (UINT8*)BurnMalloc(0x1000);
70 
71 	K053246Gfx = gfxrom;
72 	K053246Mask = gfxlen;
73 
74 	K053246GfxExp = gfxromexp;
75 	K053246MaskExp = ((gfxlen * 2) + 1) / 0x100;
76 
77 	K053247Callback = Callback;
78 
79 	K053247_dx = 0;
80 	K053247_dy = 0;
81 	K053247_wraparound = 1;
82 
83 	KonamiAllocateBitmaps();
84 
85 	K053247Flags = flags; // 0x02 highlight, 0x01 shadow
86 
87 	KonamiIC_K053247InUse = 1;
88 
89 	nBpp = 4;
90 }
91 
K053247SetBpp(INT32 bpp)92 void K053247SetBpp(INT32 bpp)
93 {
94 	nBpp = bpp;
95 }
96 
K053247Exit()97 void K053247Exit()
98 {
99 	BurnFree (K053247Ram);
100 
101 	K053247Flags = 0;
102 
103 	memset (K053247Regs, 0, 16 * sizeof(UINT16));
104 }
105 
K053247Export(UINT8 ** ram,UINT8 ** gfx,void (** callback)(INT32 *,INT32 *,INT32 *),INT32 * dx,INT32 * dy)106 void K053247Export(UINT8 **ram, UINT8 **gfx, void (**callback)(INT32 *, INT32 *, INT32 *), INT32 *dx, INT32 *dy)
107 {
108 	if (ram) *ram = K053247Ram;
109 	if (gfx) *gfx = K053246Gfx;
110 
111 	if (dx)	*dx = K053247_dx;
112 	if (dy)	*dy = K053247_dy;
113 
114 	if(callback) *callback = K053247Callback;
115 }
116 
K053247GfxDecode(UINT8 * src,UINT8 * dst,INT32 len)117 void K053247GfxDecode(UINT8 *src, UINT8 *dst, INT32 len) // 16x16
118 {
119 	for (INT32 i = 0; i < len; i++)
120 	{
121 		INT32 t = src[i^1];
122 		dst[(i << 1) + 0] = t >> 4;
123 		dst[(i << 1) + 1] = t & 0x0f;
124 	}
125 }
126 
K053247SetSpriteOffset(INT32 offsx,INT32 offsy)127 void K053247SetSpriteOffset(INT32 offsx, INT32 offsy)
128 {
129 	K053247_dx = offsx;
130 	K053247_dy = offsy;
131 }
132 
K053247WrapEnable(INT32 status)133 void K053247WrapEnable(INT32 status)
134 {
135 	K053247_wraparound = status;
136 }
137 
K053247Read(INT32 offset)138 UINT8 K053247Read(INT32 offset)
139 {
140 	return K053247Ram[offset & 0xfff];
141 }
142 
K053247ReadWord(INT32 offset)143 UINT16 K053247ReadWord(INT32 offset)
144 {
145 	return *((UINT16*)(K053247Ram + (offset & 0xffe)));
146 }
147 
K053247WriteWord(INT32 offset,UINT16 data)148 void K053247WriteWord(INT32 offset, UINT16 data)
149 {
150 	*((UINT16*)(K053247Ram + (offset & 0xffe))) = BURN_ENDIAN_SWAP_INT16(data);
151 }
152 
K053247Write(INT32 offset,INT32 data)153 void K053247Write(INT32 offset, INT32 data)
154 {
155 	if (data & 0x10000) { // use word
156 		*((UINT16*)(K053247Ram + (offset & 0xffe))) = BURN_ENDIAN_SWAP_INT16(data);
157 	} else {
158 		K053247Ram[offset & 0xfff] = data;
159 	}
160 }
161 
K053247WriteRegsByte(INT32 offset,UINT8 data)162 void K053247WriteRegsByte(INT32 offset, UINT8 data)
163 {
164 	UINT8 *regs = (UINT8*)&K053247Regs;
165 
166 	regs[(offset & 0x1f)^1] = data;
167 }
168 
K053247WriteRegsWord(INT32 offset,UINT16 data)169 void K053247WriteRegsWord(INT32 offset, UINT16 data)
170 {
171 	K053247Regs[(offset & 0x1e) / 2] = data;
172 }
173 
K053247ReadRegs(INT32 offset)174 UINT16 K053247ReadRegs(INT32 offset)
175 {
176 	return K053247Regs[offset & 0xf];
177 }
178 
K053246ReadRegs(INT32 offset)179 UINT16 K053246ReadRegs(INT32 offset)
180 {
181 	return K053246Regs[offset & 7];
182 }
183 
K053246Read(INT32 offset)184 UINT8 K053246Read(INT32 offset)
185 {
186 	if (K053246_OBJCHA_line) // assert_line
187 	{
188 		INT32 addr;
189 
190 		addr = (K053246Regs[6] << 17) | (K053246Regs[7] << 9) | (K053246Regs[4] << 1) | ((offset & 1) ^ 1);
191 		addr &= K053246Mask;
192 
193 		return K053246Gfx[addr];
194 	}
195 	else
196 	{
197 		return 0;
198 	}
199 }
200 
K053246Write(INT32 offset,INT32 data)201 void K053246Write(INT32 offset, INT32 data)
202 {
203 	if (data & 0x10000) { // handle it as a word
204 		*((UINT16*)(K053246Regs + (offset & 6))) = BURN_ENDIAN_SWAP_INT16(data);
205 	} else {
206 		K053246Regs[offset & 7] = data;
207 	}
208 }
209 
K053246_set_OBJCHA_line(INT32 state)210 void K053246_set_OBJCHA_line(INT32 state)
211 {
212 	K053246_OBJCHA_line = state;
213 }
214 
K053246_is_IRQ_enabled()215 INT32 K053246_is_IRQ_enabled()
216 {
217 	return K053246Regs[5] & 0x10;
218 }
219 
K053247SpritesRender()220 void K053247SpritesRender()
221 {
222 #define NUM_SPRITES 256
223 
224 
225 	UINT8 dtable[256];
226 	UINT8 stable[256];
227 	UINT8 *wtable;
228 
229 	memset(dtable, 1, 256);
230 	dtable[0] = 0;
231 	memset(stable, 2, 256);
232 	stable[0] = 0;
233 
234 	static const INT32 xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
235 	static const INT32 yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
236 
237 	INT32 sortedlist[NUM_SPRITES];
238 	INT32 offs,zcode;
239 	INT32 ox,oy,color,code,size,w,h,x,y,xa,ya,flipx,flipy,mirrorx,mirrory,shadow,zoomx,zoomy,primask;
240 	INT32 nozoom,count,temp,shdmask;
241 
242 	INT32 flipscreenx = K053246Regs[5] & 0x01;
243 	INT32 flipscreeny = K053246Regs[5] & 0x02;
244 	INT32 offx = (INT16)((K053246Regs[0] << 8) | K053246Regs[1]);
245 	INT32 offy = (INT16)((K053246Regs[2] << 8) | K053246Regs[3]);
246 
247 	UINT16 *SprRam = (UINT16*)K053247Ram;
248 
249 	UINT8 *gfxbase = K053246GfxExp;
250 
251 	INT32 screen_width = nScreenWidth-1;
252 
253 	if (K053247Flags & 1) {
254 		if (K053247Flags & 2) {
255 			shdmask = 3;
256 		} else {
257 			shdmask = 0;
258 		}
259 	} else {
260 		shdmask = -1;
261 	}
262 
263 	// Prebuild a sorted table by descending Z-order.
264 	zcode = K05324xZRejection;
265 	offs = count = 0;
266 
267 	if (zcode == -1)
268 	{
269 		for (; offs<0x800; offs+=8)
270 			if (BURN_ENDIAN_SWAP_INT16(SprRam[offs]) & 0x8000) sortedlist[count++] = offs;
271 	}
272 	else
273 	{
274 		for (; offs<0x800; offs+=8)
275 			if ((BURN_ENDIAN_SWAP_INT16(SprRam[offs]) & 0x8000) && ((BURN_ENDIAN_SWAP_INT16(SprRam[offs]) & 0xff) != zcode)) sortedlist[count++] = offs;
276 	}
277 
278 	w = count;
279 	count--;
280 	h = count;
281 
282 	if (!(K053247Regs[0xc/2] & 0x10))
283 	{
284 		// sort objects in decending order(smaller z closer) when OPSET PRI is clear
285 		for (y=0; y<h; y++)
286 		{
287 			offs = sortedlist[y];
288 			zcode = BURN_ENDIAN_SWAP_INT16(SprRam[offs]) & 0xff;
289 			for (x=y+1; x<w; x++)
290 			{
291 				temp = sortedlist[x];
292 				code = BURN_ENDIAN_SWAP_INT16(SprRam[temp]) & 0xff;
293 				if (zcode <= code) { zcode = code; sortedlist[x] = offs; sortedlist[y] = offs = temp; }
294 			}
295 		}
296 	}
297 	else
298 	{
299 		// sort objects in ascending order(bigger z closer) when OPSET PRI is set
300 		for (y=0; y<h; y++)
301 		{
302 			offs = sortedlist[y];
303 			zcode = BURN_ENDIAN_SWAP_INT16(SprRam[offs]) & 0xff;
304 			for (x=y+1; x<w; x++)
305 			{
306 				temp = sortedlist[x];
307 				code = BURN_ENDIAN_SWAP_INT16(SprRam[temp]) & 0xff;
308 				if (zcode >= code) { zcode = code; sortedlist[x] = offs; sortedlist[y] = offs = temp; }
309 			}
310 		}
311 	}
312 
313 	for (INT32 i = count; i >= 0; i--)
314 	{
315 		offs = sortedlist[i];
316 
317 		code = BURN_ENDIAN_SWAP_INT16(SprRam[offs+1]);
318 		shadow = color = BURN_ENDIAN_SWAP_INT16(SprRam[offs+6]);
319 		primask = 0;
320 
321 		(*K053247Callback)(&code,&color,&primask);
322 
323 		temp = BURN_ENDIAN_SWAP_INT16(SprRam[offs]);
324 
325 		size = (temp & 0x0f00) >> 8;
326 		w = 1 << (size & 0x03);
327 		h = 1 << ((size >> 2) & 0x03);
328 
329 		/* the sprite can start at any point in the 8x8 grid. We have to */
330 		/* adjust the offsets to draw it correctly. Simpsons does this all the time. */
331 		xa = 0;
332 		ya = 0;
333 		if (code & 0x01) xa += 1;
334 		if (code & 0x02) ya += 1;
335 		if (code & 0x04) xa += 2;
336 		if (code & 0x08) ya += 2;
337 		if (code & 0x10) xa += 4;
338 		if (code & 0x20) ya += 4;
339 		code &= ~0x3f;
340 
341 		oy = (INT16)BURN_ENDIAN_SWAP_INT16(SprRam[offs+2]);
342 		ox = (INT16)BURN_ENDIAN_SWAP_INT16(SprRam[offs+3]);
343 
344 		ox += K053247_dx;
345 		oy -= K053247_dy;
346 
347 		if (K053247_wraparound)
348 		{
349 			offx &= 0x3ff;
350 			offy &= 0x3ff;
351 			oy &= 0x3ff;
352 			ox &= 0x3ff;
353 		}
354 
355 		y = zoomy = BURN_ENDIAN_SWAP_INT16(SprRam[offs+4]) & 0x3ff;
356 		if (zoomy) zoomy = (0x400000+(zoomy>>1)) / zoomy; else zoomy = 0x800000;
357 		if (!(temp & 0x4000))
358 		{
359 			x = zoomx = BURN_ENDIAN_SWAP_INT16(SprRam[offs+5]) & 0x3ff;
360 			if (zoomx) zoomx = (0x400000+(zoomx>>1)) / zoomx;
361 			else zoomx = 0x800000;
362 		}
363 		else { zoomx = zoomy; x = y; }
364 
365 		if ( K053246Regs[5] & 0x08 ) // Check only "Bit #3 is '1'?" (NOTE: good guess)
366 		{
367 			zoomx >>= 1;		// Fix sprite width to HALF size
368 			ox = (ox >> 1) + 1;	// Fix sprite draw position
369 			if (flipscreenx) ox += screen_width;
370 			nozoom = 0;
371 		}
372 		else
373 			nozoom = (x == 0x40 && y == 0x40);
374 
375 		flipx = temp & 0x1000;
376 		flipy = temp & 0x2000;
377 		mirrorx = shadow & 0x4000;
378 		if (mirrorx) flipx = 0; // documented and confirmed
379 		mirrory = shadow & 0x8000;
380 
381 		INT32 highlight = 0;
382 
383 		wtable = dtable;
384 
385 		if (color == -1)
386 		{
387 			// drop the entire sprite to shadow unconditionally
388 			if (shdmask < 0) continue;
389 			color = 0;
390 			shadow = -1;
391 
392 			wtable = stable;
393 		}
394 		else
395 		{
396 			if (shdmask >= 0)
397 			{
398 				shadow = (color & 0x20000000) ? (color >> 20) : (shadow >> 10);
399 
400 				if (shadow &= 3) {
401 					if (((shadow-1) & shdmask) == 1) highlight = 1;
402 				}
403 			}
404 			else
405 				shadow = 0;
406 		}
407 
408 		color &= 0xffff; // strip attribute flags
409 
410 		if (flipscreenx)
411 		{
412 			ox = -ox;
413 			if (!mirrorx) flipx = !flipx;
414 		}
415 		if (flipscreeny)
416 		{
417 			oy = -oy;
418 			if (!mirrory) flipy = !flipy;
419 		}
420 
421 		// apply wrapping and global offsets
422 		if (K053247_wraparound)
423 		{
424 			ox = ( ox - offx) & 0x3ff;
425 			oy = (-oy - offy) & 0x3ff;
426 			if (ox >= 0x300) ox -= 0x400;
427 			if (oy >= 0x280) oy -= 0x400;
428 		}
429 		else
430 		{
431 			ox =  ox - offx;
432 			oy = -oy - offy;
433 		}
434 
435 		// apply global and display window offsets
436 
437 		/* the coordinates given are for the *center* of the sprite */
438 		ox -= (zoomx * w) >> 13;
439 		oy -= (zoomy * h) >> 13;
440 
441 		dtable[15] = shadow ? 2 : 1;
442 
443 		for (y = 0;y < h;y++)
444 		{
445 			INT32 sx,sy,zw,zh;
446 
447 			sy = oy + ((zoomy * y + (1<<11)) >> 12);
448 			zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
449 
450 			for (x = 0;x < w;x++)
451 			{
452 				INT32 c,fx,fy;
453 
454 				sx = ox + ((zoomx * x + (1<<11)) >> 12);
455 				zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
456 				c = code;
457 				if (mirrorx)
458 				{
459 					if ((flipx == 0) ^ ((x<<1) < w))
460 					{
461 						/* mirror left/right */
462 						c += xoffset[(w-1-x+xa)&7];
463 						fx = 1;
464 					}
465 					else
466 					{
467 						c += xoffset[(x+xa)&7];
468 						fx = 0;
469 					}
470 				}
471 				else
472 				{
473 					if (flipx) c += xoffset[(w-1-x+xa)&7];
474 					else c += xoffset[(x+xa)&7];
475 					fx = flipx;
476 				}
477 
478 				if (mirrory)
479 				{
480 					if ((flipy == 0) ^ ((y<<1) >= h))
481 					{
482 						/* mirror top/bottom */
483 						c += yoffset[(h-1-y+ya)&7];
484 						fy = 1;
485 					}
486 					else
487 					{
488 						c += yoffset[(y+ya)&7];
489 						fy = 0;
490 					}
491 				}
492 				else
493 				{
494 					if (flipy) c += yoffset[(h-1-y+ya)&7];
495 					else c += yoffset[(y+ya)&7];
496 					fy = flipy;
497 				}
498 
499 				c &= K053246MaskExp;
500 
501 				if (shadow || wtable == stable) {
502 					if (mirrory && h == 1)
503 						konami_render_zoom_shadow_tile(gfxbase, c, nBpp, color, sx, sy, fx, !fy, 16, 16, zw << 12, zh << 12, primask, highlight);
504 
505 					konami_render_zoom_shadow_tile(gfxbase, c, nBpp, color, sx, sy, fx, fy, 16, 16, zw << 12, zh << 12, primask, highlight);
506 					continue;
507 				}
508 
509 				if (mirrory && h == 1)
510 				{
511 					if (nozoom) {
512 						konami_draw_16x16_prio_tile(gfxbase, c, nBpp, color, sx, sy, fx, !fy, primask);
513 					} else {
514 						konami_draw_16x16_priozoom_tile(gfxbase, c, nBpp, color, 0, sx, sy, fx, !fy, 16, 16, zw<<12, zh<<12, primask);
515 					}
516 				}
517 
518 				if (nozoom) {
519 					konami_draw_16x16_prio_tile(gfxbase, c, nBpp, color, sx, sy, fx, fy, primask);
520 				} else {
521 					konami_draw_16x16_priozoom_tile(gfxbase, c, nBpp, color, 0, sx, sy, fx, fy, 16, 16, zw<<12, zh<<12, primask);
522 				}
523 			} // end of X loop
524 		} // end of Y loop
525 
526 	} // end of sprite-list loop
527 #undef NUM_SPRITES
528 }
529 
alpha_blend_r32(UINT32 d,UINT32 s,UINT32 p)530 static inline UINT32 alpha_blend_r32(UINT32 d, UINT32 s, UINT32 p)
531 {
532 	if (p == 0) return d;
533 
534 	INT32 a = 256 - p;
535 
536 	return (((((s & 0xff00ff) * p) + ((d & 0xff00ff) * a)) & 0xff00ff00) |
537 		((((s & 0x00ff00) * p) + ((d & 0x00ff00) * a)) & 0x00ff0000)) >> 8;
538 }
539 
shadow_blend_338(UINT32 d,INT32 shadow_bank)540 static inline UINT32 shadow_blend_338(UINT32 d, INT32 shadow_bank) // for k054338
541 {
542 	INT32 r = ((d&0xff0000) >> 16) + m_shd_rgb[0 + (shadow_bank * 3)];
543 	if (r > 0xff) r = 0xff;
544 	if (r < 0) r = 0;
545 	r = r << 16;
546 
547 	INT32 g = ((d&0x00ff00) >> 8) + m_shd_rgb[1 + (shadow_bank * 3)];
548 	if (g > 0xff) g = 0xff;
549 	if (g < 0) g = 0;
550 	g = g << 8;
551 
552 	INT32 b = ((d&0x0000ff) >> 0) + m_shd_rgb[2 + (shadow_bank * 3)];
553 	if (b > 0xff) b = 0xff;
554 	if (b < 0) b = 0;
555 	return r|g|b;
556 }
557 
shadow_blend(UINT32 d,INT32 shadow_bank)558 static inline UINT32 shadow_blend(UINT32 d, INT32 shadow_bank)
559 {
560 	if (KonamiIC_K054338InUse) return shadow_blend_338(d, shadow_bank);
561 	return ((((d & 0xff00ff) * 0x9d) & 0xff00ff00) + (((d & 0x00ff00) * 0x9d) & 0x00ff0000)) / 0x100;
562 }
563 
highlight_blend(UINT32 d)564 static inline UINT32 highlight_blend(UINT32 d)
565 {
566 	INT32 r = ((d&0xff0000)+0x220000);
567 	if (r > 0xff0000) r = 0xff0000;
568 
569 	INT32 g = ((d&0x00ff00)+0x002200);
570 	if (g > 0x00ff00) g = 0x00ff00;
571 
572 	INT32 b = ((d&0x0000ff)+0x000022);
573 	if (b > 0x0000ff) b = 0x0000ff;
574 	return r|g|b;
575 }
576 
577 #define GX_ZBUFW     512
578 #define GX_ZBUFH     256
579 
zdrawgfxzoom32GP(UINT32 code,UINT32 color,INT32 flipx,INT32 flipy,INT32 sx,INT32 sy,INT32 scalex,INT32 scaley,INT32 alpha,INT32 drawmode,INT32 zcode,INT32 pri,UINT8 * gx_objzbuf,UINT8 * gx_shdzbuf)580 void zdrawgfxzoom32GP(UINT32 code, UINT32 color, INT32 flipx, INT32 flipy, INT32 sx, INT32 sy,
581 		INT32 scalex, INT32 scaley, INT32 alpha, INT32 drawmode, INT32 zcode, INT32 pri, UINT8* gx_objzbuf, UINT8* gx_shdzbuf)
582 {
583 #define FP     19
584 #define FPONE  (1<<FP)
585 #define FPHALF (1<<(FP-1))
586 #define FPENT  0
587 
588 	// inner loop
589 	const UINT8  *src_ptr;
590 	INT32 src_x;
591 	INT32 eax, ecx;
592 	INT32 src_fx, src_fdx;
593 	INT32 shdpen;
594 	UINT8  z8 = 0, p8 = 0;
595 	UINT8  *ozbuf_ptr;
596 	UINT8  *szbuf_ptr;
597 	const UINT32 *pal_base;
598 	const UINT32 *shd_base;
599 	UINT32 *dst_ptr;
600 
601 	// outter loop
602 	INT32 src_fby, src_fdy, src_fbx;
603 	const UINT8 *src_base;
604 	INT32 dst_w, dst_h;
605 
606 	// one-time
607 	INT32 nozoom, granularity;
608 	INT32 src_fw, src_fh;
609 	INT32 dst_minx, dst_maxx, dst_miny, dst_maxy;
610 	INT32 dst_skipx, dst_skipy, dst_x, dst_y, dst_lastx, dst_lasty;
611 	INT32 src_pitch, dst_pitch;
612 
613 	INT32 highlight_enable = (drawmode >> 4) && (K053247Flags & 2);// for fba
614 	if (highlight_enable) highlight_enable = (drawmode >> 4) & 0x7;
615 	//INT32 highlight_enable = drawmode >> 4;// for fba
616 	drawmode &= 0xf;
617 
618 	// cull illegal and transparent objects
619 	if (!scalex || !scaley) return;
620 
621 	// find shadow pens and cull invisible shadows
622 	granularity = shdpen = ((1 << nBpp) /*- 1*/);
623 	shdpen--;
624 
625 	if (zcode >= 0)
626 	{
627 		if (drawmode == 5) { drawmode = 4; shdpen = 1; }
628 	}
629 	else
630 		if (drawmode >= 4) return;
631 
632 	// alpha blend necessary?
633 	if (drawmode & 2)
634 	{
635 		if (alpha <= 0) return;
636 		if (alpha >= 255) drawmode &= ~2;
637 	}
638 
639 	// fill internal data structure with default values
640 	ozbuf_ptr  = gx_objzbuf;
641 	szbuf_ptr  = gx_shdzbuf;
642 
643 	src_pitch = 16;
644 	src_fw    = 16;
645 	src_fh    = 16;
646 	src_base  = K053246GfxExp + (code * 0x100);
647 
648 	pal_base  = konami_palette32 + (color << nBpp);
649 	shd_base  = konami_palette32; // m_palette->shadow_table(); // iq_132
650 
651 	dst_ptr   = konami_bitmap32;
652 	dst_pitch = nScreenWidth;
653 	dst_minx  = 0;
654 	dst_maxx  = (nScreenWidth - 1);
655 	dst_miny  = 0;
656 	dst_maxy  = (nScreenHeight - 1);
657 	dst_x     = sx;
658 	dst_y     = sy;
659 
660 	// cull off-screen objects
661 	if (dst_x > dst_maxx || dst_y > dst_maxy) return;
662 	nozoom = (scalex == 0x10000 && scaley == 0x10000);
663 	if (nozoom)
664 	{
665 		dst_h = dst_w = 16;
666 		src_fdy = src_fdx = 1;
667 	}
668 	else
669 	{
670 		dst_w = ((scalex<<4)+0x8000)>>16;
671 		dst_h = ((scaley<<4)+0x8000)>>16;
672 		if (!dst_w || !dst_h) return;
673 
674 		src_fw <<= FP;
675 		src_fh <<= FP;
676 		src_fdx = src_fw / dst_w;
677 		src_fdy = src_fh / dst_h;
678 	}
679 	dst_lastx = dst_x + dst_w - 1;
680 	if (dst_lastx < dst_minx) return;
681 	dst_lasty = dst_y + dst_h - 1;
682 	if (dst_lasty < dst_miny) return;
683 
684 	// clip destination
685 	dst_skipx = 0;
686 	eax = dst_minx;  if ((eax -= dst_x) > 0) { dst_skipx = eax;  dst_w -= eax;  dst_x = dst_minx; }
687 	eax = dst_lastx; if ((eax -= dst_maxx) > 0) dst_w -= eax;
688 	dst_skipy = 0;
689 	eax = dst_miny;  if ((eax -= dst_y) > 0) { dst_skipy = eax;  dst_h -= eax;  dst_y = dst_miny; }
690 	eax = dst_lasty; if ((eax -= dst_maxy) > 0) dst_h -= eax;
691 
692 	// calculate zoom factors and clip source
693 	if (nozoom)
694 	{
695 		if (!flipx) src_fbx = 0; else { src_fbx = src_fw - 1; src_fdx = -src_fdx; }
696 		if (!flipy) src_fby = 0; else { src_fby = src_fh - 1; src_fdy = -src_fdy; src_pitch = -src_pitch; }
697 	}
698 	else
699 	{
700 		if (!flipx) src_fbx = FPENT; else { src_fbx = src_fw - FPENT - 1; src_fdx = -src_fdx; }
701 		if (!flipy) src_fby = FPENT; else { src_fby = src_fh - FPENT - 1; src_fdy = -src_fdy; }
702 	}
703 	src_fbx += dst_skipx * src_fdx;
704 	src_fby += dst_skipy * src_fdy;
705 
706 	// adjust insertion points and pre-entry constants
707 	eax = (dst_y - dst_miny) * GX_ZBUFW + (dst_x - dst_minx) + dst_w;
708 	z8 = (UINT8)zcode;
709 	p8 = (UINT8)pri;
710 	ozbuf_ptr += eax;
711 	szbuf_ptr += eax << 1;
712 	dst_ptr += dst_y * dst_pitch + dst_x + dst_w;
713 	dst_w = -dst_w;
714 
715 	if (!nozoom)
716 	{
717 		ecx = src_fby;   src_fby += src_fdy;
718 		ecx >>= FP;      src_fx = src_fbx;
719 		src_x = src_fbx; src_fx += src_fdx;
720 		ecx <<= 4;       src_ptr = src_base;
721 		src_x >>= FP;    src_ptr += ecx;
722 		ecx = dst_w;
723 
724 		if (zcode < 0) // no shadow and z-buffering
725 		{
726 			do {
727 				do {
728 					eax = src_ptr[src_x];
729 					src_x = src_fx;
730 					src_fx += src_fdx;
731 					src_x >>= FP;
732 					if (!eax || eax >= shdpen) continue;
733 					dst_ptr [ecx] = pal_base[eax];
734 				}
735 				while (++ecx);
736 
737 				ecx = src_fby;   src_fby += src_fdy;
738 				dst_ptr += dst_pitch;
739 				ecx >>= FP;      src_fx = src_fbx;
740 				src_x = src_fbx; src_fx += src_fdx;
741 				ecx <<= 4;       src_ptr = src_base;
742 				src_x >>= FP;    src_ptr += ecx;
743 				ecx = dst_w;
744 			}
745 			while (--dst_h);
746 		}
747 		else
748 		{
749 			switch (drawmode)
750 			{
751 				case 0: // all pens solid
752 					do {
753 						do {
754 							eax = src_ptr[src_x];
755 							src_x = src_fx;
756 							src_fx += src_fdx;
757 							src_x >>= FP;
758 							if (!eax || ozbuf_ptr[ecx] < z8) continue;
759 							eax = pal_base[eax];
760 							ozbuf_ptr[ecx] = z8;
761 							dst_ptr [ecx] = eax;
762 						}
763 						while (++ecx);
764 
765 						ecx = src_fby;   src_fby += src_fdy;
766 						ozbuf_ptr += GX_ZBUFW;
767 						dst_ptr += dst_pitch;
768 						ecx >>= FP;      src_fx = src_fbx;
769 						src_x = src_fbx; src_fx += src_fdx;
770 						ecx <<= 4;       src_ptr = src_base;
771 						src_x >>= FP;    src_ptr += ecx;
772 						ecx = dst_w;
773 					}
774 					while (--dst_h);
775 					break;
776 
777 				case 1: // solid pens only
778 					do {
779 						do {
780 							eax = src_ptr[src_x];
781 							src_x = src_fx;
782 							src_fx += src_fdx;
783 							src_x >>= FP;
784 							if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
785 							eax = pal_base[eax];
786 							ozbuf_ptr[ecx] = z8;
787 							dst_ptr [ecx] = eax;
788 						}
789 						while (++ecx);
790 
791 						ecx = src_fby;   src_fby += src_fdy;
792 						ozbuf_ptr += GX_ZBUFW;
793 						dst_ptr += dst_pitch;
794 						ecx >>= FP;      src_fx = src_fbx;
795 						src_x = src_fbx; src_fx += src_fdx;
796 						ecx <<= 4;       src_ptr = src_base;
797 						src_x >>= FP;    src_ptr += ecx;
798 						ecx = dst_w;
799 					}
800 					while (--dst_h);
801 					break;
802 
803 				case 2: // all pens solid with alpha blending
804 					do {
805 						do {
806 							eax = src_ptr[src_x];
807 							src_x = src_fx;
808 							src_fx += src_fdx;
809 							src_x >>= FP;
810 							if (!eax || ozbuf_ptr[ecx] < z8) continue;
811 							ozbuf_ptr[ecx] = z8;
812 
813 							dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
814 						}
815 						while (++ecx);
816 
817 						ecx = src_fby;   src_fby += src_fdy;
818 						ozbuf_ptr += GX_ZBUFW;
819 						dst_ptr += dst_pitch;
820 						ecx >>= FP;      src_fx = src_fbx;
821 						src_x = src_fbx; src_fx += src_fdx;
822 						ecx <<= 4;       src_ptr = src_base;
823 						src_x >>= FP;    src_ptr += ecx;
824 						ecx = dst_w;
825 					}
826 					while (--dst_h);
827 					break;
828 
829 				case 3: // solid pens only with alpha blending
830 					do {
831 						do {
832 							eax = src_ptr[src_x];
833 							src_x = src_fx;
834 							src_fx += src_fdx;
835 							src_x >>= FP;
836 							if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
837 							ozbuf_ptr[ecx] = z8;
838 
839 							dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
840 						}
841 						while (++ecx);
842 
843 						ecx = src_fby;   src_fby += src_fdy;
844 						ozbuf_ptr += GX_ZBUFW;
845 						dst_ptr += dst_pitch;
846 						ecx >>= FP;      src_fx = src_fbx;
847 						src_x = src_fbx; src_fx += src_fdx;
848 						ecx <<= 4;       src_ptr = src_base;
849 						src_x >>= FP;    src_ptr += ecx;
850 						ecx = dst_w;
851 					}
852 					while (--dst_h);
853 					break;
854 
855 				case 4: // shadow pens only
856 					do {
857 						do {
858 							eax = src_ptr[src_x];
859 							src_x = src_fx;
860 							src_fx += src_fdx;
861 							src_x >>= FP;
862 							if (eax < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
863 							//UINT32 pix = dst_ptr[ecx];
864 							szbuf_ptr[ecx*2] = z8;
865 							szbuf_ptr[ecx*2+1] = p8;
866 
867 							// the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck!
868 							if (highlight_enable) {
869 								dst_ptr[ecx] = highlight_blend(dst_ptr[ecx]);
870 							} else {
871 								dst_ptr[ecx] = shadow_blend(dst_ptr[ecx], highlight_enable); //shd_base[pix.as_rgb15()];
872 							}
873 							//dst_ptr[ecx] =(eax>>3&0x001f);lend_r32( eax, 0x00000000, 128);
874 						}
875 						while (++ecx);
876 
877 						ecx = src_fby;   src_fby += src_fdy;
878 						szbuf_ptr += (GX_ZBUFW<<1);
879 						dst_ptr += dst_pitch;
880 						ecx >>= FP;      src_fx = src_fbx;
881 						src_x = src_fbx; src_fx += src_fdx;
882 						ecx <<= 4;       src_ptr = src_base;
883 						src_x >>= FP;    src_ptr += ecx;
884 						ecx = dst_w;
885 					}
886 					while (--dst_h);
887 					break;
888 			}   // switch (drawmode)
889 		}   // if (zcode < 0)
890 	}   // if (!nozoom)
891 	else
892 	{
893 		src_ptr = src_base + (src_fby<<4) + src_fbx;
894 		src_fdy = src_fdx * dst_w + src_pitch;
895 		ecx = dst_w;
896 
897 		if (zcode < 0) // no shadow and z-buffering
898 		{
899 			do {
900 				do {
901 					eax = *src_ptr;
902 					src_ptr += src_fdx;
903 					if (!eax || eax >= shdpen) continue;
904 					dst_ptr[ecx] = pal_base[eax];
905 				}
906 				while (++ecx);
907 
908 				src_ptr += src_fdy;
909 				dst_ptr += dst_pitch;
910 				ecx = dst_w;
911 			}
912 			while (--dst_h);
913 		}
914 		else
915 		{
916 			switch (drawmode)
917 			{
918 				case 0: // all pens solid
919 					do {
920 						do {
921 							eax = *src_ptr;
922 							src_ptr += src_fdx;
923 							if (!eax || ozbuf_ptr[ecx] < z8) continue;
924 							eax = pal_base[eax];
925 							ozbuf_ptr[ecx] = z8;
926 							dst_ptr[ecx] = eax;
927 						}
928 						while (++ecx);
929 
930 						src_ptr += src_fdy;
931 						ozbuf_ptr += GX_ZBUFW;
932 						dst_ptr += dst_pitch;
933 						ecx = dst_w;
934 					}
935 					while (--dst_h);
936 					break;
937 
938 				case 1:  // solid pens only
939 					do {
940 						do {
941 							eax = *src_ptr;
942 							src_ptr += src_fdx;
943 							if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
944 							eax = pal_base[eax];
945 							ozbuf_ptr[ecx] = z8;
946 							dst_ptr[ecx] = eax;
947 						}
948 						while (++ecx);
949 
950 						src_ptr += src_fdy;
951 						ozbuf_ptr += GX_ZBUFW;
952 						dst_ptr += dst_pitch;
953 						ecx = dst_w;
954 					}
955 					while (--dst_h);
956 					break;
957 
958 				case 2: // all pens solid with alpha blending
959 					do {
960 						do {
961 							eax = *src_ptr;
962 							src_ptr += src_fdx;
963 							if (!eax || ozbuf_ptr[ecx] < z8) continue;
964 							ozbuf_ptr[ecx] = z8;
965 
966 							dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
967 						}
968 						while (++ecx);
969 
970 						src_ptr += src_fdy;
971 						ozbuf_ptr += GX_ZBUFW;
972 						dst_ptr += dst_pitch;
973 						ecx = dst_w;
974 					}
975 					while (--dst_h);
976 					break;
977 
978 				case 3: // solid pens only with alpha blending
979 					do {
980 						do {
981 							eax = *src_ptr;
982 							src_ptr += src_fdx;
983 							if (!eax || eax >= shdpen || ozbuf_ptr[ecx] < z8) continue;
984 							ozbuf_ptr[ecx] = z8;
985 
986 							dst_ptr[ecx] = alpha_blend_r32(pal_base[eax], dst_ptr[ecx], alpha);
987 						}
988 						while (++ecx);
989 
990 						src_ptr += src_fdy;
991 						ozbuf_ptr += GX_ZBUFW;
992 						dst_ptr += dst_pitch;
993 						ecx = dst_w;
994 					}
995 					while (--dst_h);
996 					break;
997 
998 				case 4: // shadow pens only
999 					do {
1000 						do {
1001 							eax = *src_ptr;
1002 							src_ptr += src_fdx;
1003 							if (eax < shdpen || szbuf_ptr[ecx*2] < z8 || szbuf_ptr[ecx*2+1] <= p8) continue;
1004 							//UINT32 pix = dst_ptr[ecx];
1005 							szbuf_ptr[ecx*2] = z8;
1006 							szbuf_ptr[ecx*2+1] = p8;
1007 
1008 							// the shadow tables are 15-bit lookup tables which accept RGB15... lossy, nasty, yuck!
1009 							if (highlight_enable) {
1010 								dst_ptr[ecx] = highlight_blend(dst_ptr[ecx]);
1011 							} else {
1012 								dst_ptr[ecx] = shadow_blend(dst_ptr[ecx], highlight_enable); //shd_base[pix.as_rgb15()];
1013 							}
1014 						}
1015 						while (++ecx);
1016 
1017 						src_ptr += src_fdy;
1018 						szbuf_ptr += (GX_ZBUFW<<1);
1019 						dst_ptr += dst_pitch;
1020 						ecx = dst_w;
1021 					}
1022 					while (--dst_h);
1023 					break;
1024 			}
1025 		}
1026 	}
1027 #undef FP
1028 #undef FPONE
1029 #undef FPHALF
1030 #undef FPENT
1031 }
1032 
1033 
1034 
1035 
1036 
k053247_draw_yxloop_gx(INT32 code,INT32 color,INT32 height,INT32 width,INT32 zoomx,INT32 zoomy,INT32 flipx,INT32 flipy,INT32 ox,INT32 oy,INT32 xa,INT32 ya,INT32 mirrorx,INT32 mirrory,INT32 nozoom,INT32 pri,INT32 zcode,INT32 alpha,INT32 drawmode,UINT8 * gx_objzbuf,UINT8 * gx_shdzbuf,INT32,UINT8 *)1037 void k053247_draw_yxloop_gx(
1038 		INT32 code,
1039 		INT32 color,
1040 		INT32 height, INT32 width,
1041 		INT32 zoomx, INT32 zoomy, INT32 flipx, INT32 flipy,
1042 		INT32 ox, INT32 oy,
1043 		INT32 xa, INT32 ya,
1044 		INT32 mirrorx, INT32 mirrory,
1045 		INT32 nozoom,
1046 		/* gx specifics */
1047 		INT32 pri,
1048 		INT32 zcode, INT32 alpha, INT32 drawmode,
1049 		UINT8* gx_objzbuf, UINT8* gx_shdzbuf,
1050 		/* non-gx specifics */
1051 		INT32 /*primask*/,
1052 		UINT8* /*whichtable*/
1053 		)
1054 	{
1055 		static const INT32 xoffset[8] = { 0, 1, 4, 5, 16, 17, 20, 21 };
1056 		static const INT32 yoffset[8] = { 0, 2, 8, 10, 32, 34, 40, 42 };
1057 		INT32 zw,zh;
1058 		INT32  fx, fy, sx, sy;
1059 		INT32 tempcode;
1060 
1061 		for (INT32 y=0; y<height; y++)
1062 		{
1063 			sy = oy + ((zoomy * y + (1<<11)) >> 12);
1064 			zh = (oy + ((zoomy * (y+1) + (1<<11)) >> 12)) - sy;
1065 
1066 			for (INT32 x=0; x<width; x++)
1067 			{
1068 				sx = ox + ((zoomx * x + (1<<11)) >> 12);
1069 				zw = (ox + ((zoomx * (x+1) + (1<<11)) >> 12)) - sx;
1070 				tempcode = code;
1071 
1072 				if (mirrorx)
1073 				{
1074 					if ((!flipx)^((x<<1)<width))
1075 					{
1076 						/* mirror left/right */
1077 						tempcode += xoffset[(width-1-x+xa)&7];
1078 						fx = 1;
1079 					}
1080 					else
1081 					{
1082 						tempcode += xoffset[(x+xa)&7];
1083 						fx = 0;
1084 					}
1085 				}
1086 				else
1087 				{
1088 					if (flipx) tempcode += xoffset[(width-1-x+xa)&7];
1089 					else tempcode += xoffset[(x+xa)&7];
1090 					fx = flipx;
1091 				}
1092 
1093 				if (mirrory)
1094 				{
1095 					if ((!flipy)^((y<<1)>=height))
1096 					{
1097 						/* mirror top/bottom */
1098 						tempcode += yoffset[(height-1-y+ya)&7];
1099 						fy = 1;
1100 					}
1101 					else
1102 					{
1103 						tempcode += yoffset[(y+ya)&7];
1104 						fy = 0;
1105 					}
1106 				}
1107 				else
1108 				{
1109 					if (flipy) tempcode += yoffset[(height-1-y+ya)&7];
1110 					else tempcode += yoffset[(y+ya)&7];
1111 					fy = flipy;
1112 				}
1113 
1114 				{
1115 					if (nozoom) { zw = zh = 0x10; }
1116 
1117 					zdrawgfxzoom32GP(
1118 							tempcode,
1119 							color,
1120 							fx,fy,
1121 							sx,sy,
1122 							zw << 12, zh << 12, alpha, drawmode, zcode, pri,
1123 							gx_objzbuf, gx_shdzbuf
1124 							);
1125 
1126 				}
1127 			} // end of X loop
1128 		} // end of Y loop
1129 	}
1130 
1131 
1132 
1133 
k053247_draw_single_sprite_gxcore(UINT8 * gx_objzbuf,UINT8 * gx_shdzbuf,INT32 code,UINT16 * gx_spriteram,INT32 offs,INT32 color,INT32 alpha,INT32 drawmode,INT32 zcode,INT32 pri,INT32,INT32,UINT8 *,UINT8 *,INT32)1134 void k053247_draw_single_sprite_gxcore(UINT8 *gx_objzbuf, UINT8 *gx_shdzbuf, INT32 code, UINT16 *gx_spriteram, INT32 offs,
1135 		INT32 color, INT32 alpha, INT32 drawmode, INT32 zcode, INT32 pri,
1136 		INT32 /*primask*/, INT32 /*shadow*/, UINT8 */*drawmode_table*/, UINT8 */*shadowmode_table*/, INT32 /*shdmask*/)
1137 	{
1138 		INT32 xa,ya,ox,oy,flipx,flipy,mirrorx,mirrory,zoomx,zoomy,scalex,scaley,nozoom;
1139 		INT32 temp, temp4;
1140 		INT32 flipscreenx = K053246Regs[5] & 0x01;
1141 		INT32 flipscreeny = K053246Regs[5] & 0x02;
1142 
1143 		xa = ya = 0;
1144 		if (code & 0x01) xa += 1;
1145 		if (code & 0x02) ya += 1;
1146 		if (code & 0x04) xa += 2;
1147 		if (code & 0x08) ya += 2;
1148 		if (code & 0x10) xa += 4;
1149 		if (code & 0x20) ya += 4;
1150 		code &= ~0x3f;
1151 
1152 		temp4 = gx_spriteram[offs];
1153 
1154 		// mask off the upper 6 bits of coordinate and zoom registers
1155 		oy = gx_spriteram[offs+2] & 0x3ff;
1156 		ox = gx_spriteram[offs+3] & 0x3ff;
1157 
1158 		scaley = zoomy = gx_spriteram[offs+4] & 0x3ff;
1159 		if (zoomy) zoomy = (0x400000+(zoomy>>1)) / zoomy;
1160 		else zoomy = 0x800000;
1161 		if (!(temp4 & 0x4000))
1162 		{
1163 			scalex = zoomx = gx_spriteram[offs+5] & 0x3ff;
1164 			if (zoomx) zoomx = (0x400000+(zoomx>>1)) / zoomx;
1165 			else zoomx = 0x800000;
1166 		}
1167 		else { zoomx = zoomy; scalex = scaley; }
1168 
1169 		nozoom = (scalex == 0x40 && scaley == 0x40);
1170 
1171 		flipx = temp4 & 0x1000;
1172 		flipy = temp4 & 0x2000;
1173 
1174 		temp = gx_spriteram[offs+6];
1175 		mirrorx = temp & 0x4000;
1176 		if (mirrorx) flipx = 0; // only applies to x mirror, proven
1177 		mirrory = temp & 0x8000;
1178 
1179 		INT32 objset1 = K053246ReadRegs(5);
1180 		// for Escape Kids (GX975)
1181 		if ( objset1 & 8 ) // Check only "Bit #3 is '1'?"
1182 		{
1183 			INT32 screenwidth = nScreenWidth-1;
1184 
1185 			zoomx = zoomx>>1; // Fix sprite width to HALF size
1186 			ox = (ox>>1) + 1; // Fix sprite draw position
1187 
1188 			if (flipscreenx) ox += screenwidth;
1189 			nozoom = 0;
1190 		}
1191 
1192 		if (flipscreenx) { ox = -ox; if (!mirrorx) flipx = !flipx; }
1193 		if (flipscreeny) { oy = -oy; if (!mirrory) flipy = !flipy; }
1194 
1195 		INT32 k053247_opset = K053247ReadRegs(0xc/2);
1196 		INT32 wrapsize, xwraplim, ywraplim;
1197 		if (k053247_opset & 0x40)
1198 		{
1199 			wrapsize = 512;
1200 			xwraplim = 512 - 64;
1201 			ywraplim = 512 - 128;
1202 		}
1203 		else
1204 		{
1205 			wrapsize  = 1024;
1206 			xwraplim  = 1024 - 384;
1207 			ywraplim  = 1024 - 512;
1208 		}
1209 
1210 		// get "display window" offsets
1211 		INT32 offx = (INT16)((K053246Regs[0] << 8) | K053246Regs[1]);
1212 		INT32 offy = (INT16)((K053246Regs[2] << 8) | K053246Regs[3]);
1213 
1214 		// apply wrapping and global offsets
1215 		temp = wrapsize-1;
1216 
1217 		ox += K053247_dx;
1218 		oy -= K053247_dy;
1219 
1220 		ox = ( ox - offx) & temp;
1221 		oy = (-oy - offy) & temp;
1222 		if (ox >= xwraplim) ox -= wrapsize;
1223 		if (oy >= ywraplim) oy -= wrapsize;
1224 
1225 		temp = temp4>>8 & 0x0f;
1226 		INT32 width = 1 << (temp & 3);
1227 		INT32 height = 1 << (temp>>2 & 3);
1228 
1229 		ox -= (zoomx * width) >> 13;
1230 		oy -= (zoomy * height) >> 13;
1231 
1232 			k053247_draw_yxloop_gx(	code,
1233 				color,
1234 				height, width,
1235 				zoomx, zoomy, flipx, flipy,
1236 				ox, oy,
1237 				xa, ya,
1238 				mirrorx, mirrory,
1239 				nozoom,
1240 				pri,
1241 				zcode, alpha, drawmode,
1242 				gx_objzbuf, gx_shdzbuf,
1243 				0,NULL
1244 				);
1245 	}
1246