1 // Cave hardware sprites
2 #include "cave.h"
3
4 INT32 CaveSpriteVisibleXOffset;
5
6 UINT8* CaveSpriteROM = NULL;
7 UINT8* CaveSpriteRAM = NULL;
8
9 INT32 nCaveSpriteBank;
10 INT32 nCaveSpriteBankDelay;
11
12 static INT32 nSpriteAddressMask;
13
14 struct CaveSprite {
15 INT8 flip;
16 INT8 priority;
17 INT16 palette;
18 INT32 x; INT32 y;
19 INT32 xsize; INT32 ysize;
20 INT32 xzoom; INT32 yzoom;
21 INT32 address;
22 };
23
24 static CaveSprite* pSpriteList = NULL;
25
26 INT32 (*CaveSpriteBuffer)();
27
28 static UINT8* pRow;
29 static UINT8* pPixel;
30 static UINT32* pSpriteData;
31 static UINT32* pSpritePalette;
32
33 static UINT16* pZBuffer = NULL;
34 static UINT16* pZRow;
35 static UINT16* pZPixel;
36
37 static INT32 nSpriteRow, nSpriteRowSize;
38 static INT32 nXPos, nYPos, nZPos;
39 static INT32 nXSize, nYSize;
40 static INT32 nSpriteXZoomSize, nSpriteYZoomSize;
41 static INT32 nSpriteXOffset, nSpriteYOffset;
42
43 static INT32 nFirstSprite[4], nLastSprite[4];
44
45 static INT32 nTopSprite;
46 static INT32 nZOffset;
47
48 typedef void (*RenderSpriteFunction)();
49 static RenderSpriteFunction* RenderSprite;
50
51 // Include the sprite rendering functions
52 #include "cave_sprite_func.h"
53
CaveSpriteRender(INT32 nLowPriority,INT32 nHighPriority)54 INT32 CaveSpriteRender(INT32 nLowPriority, INT32 nHighPriority)
55 {
56 static INT32 nMaskLeft, nMaskRight, nMaskTop, nMaskBottom;
57 CaveSprite* pBuffer;
58
59 INT32 nPriorityMask = 0;
60 INT32 nMaxZPos = -1;
61 INT32 nCurrentZPos = 0x00010000;
62 INT32 nUseBuffer = 0x00010000;
63 INT32 nFunction;
64
65 if (nLowPriority == 0) {
66 nZPos = -1;
67 nTopSprite = -1;
68
69 nMaskLeft = nMaskTop = 9999;
70 nMaskRight = nMaskBottom = -1;
71 }
72
73 if ((nBurnLayer & 1) == 0) {
74 return 0;
75 }
76
77 if (nHighPriority < 3) {
78 for (INT32 i = nHighPriority + 1; i < 4; i++) {
79 if (nUseBuffer > nFirstSprite[i]) {
80 nUseBuffer = nFirstSprite[i];
81 }
82 }
83 }
84
85 for (INT32 i = nLowPriority; i <= nHighPriority; i++) {
86 if (nCurrentZPos > nFirstSprite[i]) {
87 nCurrentZPos = nFirstSprite[i];
88 }
89 if (nMaxZPos < nLastSprite[i]) {
90 nMaxZPos = nLastSprite[i];
91 }
92 nPriorityMask |= 8 >> i;
93 }
94
95 nPriorityMask &= nSpriteEnable;
96 if (nPriorityMask == 0) {
97 return 0;
98 }
99
100 for (pBuffer = pSpriteList + nCurrentZPos; nCurrentZPos <= nMaxZPos; pBuffer++, nCurrentZPos++) {
101
102 if ((pBuffer->priority & nPriorityMask) == 0) {
103 continue;
104 }
105
106 nXPos = pBuffer->x;
107 nYPos = pBuffer->y;
108
109 pSpriteData = (UINT32*)(CaveSpriteROM + ((pBuffer->address << 8) & nSpriteAddressMask));
110 pSpritePalette = CavePalette + pBuffer->palette;
111
112 nXSize = pBuffer->xsize;
113 nYSize = pBuffer->ysize;
114
115 if (pBuffer->xzoom == 0x0100 && pBuffer->yzoom == 0x0100) { // This sprite doesn't use zooming
116
117 nSpriteRowSize = pBuffer->xsize >> 2;
118
119 if (pBuffer->flip & 1) { // Y Flip
120 pSpriteData += nSpriteRowSize * (nYSize - 1);
121 nSpriteRowSize = -nSpriteRowSize;
122 }
123
124 if (nYPos >= 0x0200) {
125 nYPos -= 0x0400;
126 }
127
128 if (nYPos < 0) {
129 pSpriteData += nSpriteRowSize * -nYPos;
130 nYSize += nYPos;
131 nYPos = 0;
132 }
133
134 if ((nYPos + nYSize) > nCaveYSize) {
135 nYSize -= (nYPos + nYSize) - nCaveYSize;
136 }
137
138 if (nXPos >= 0x0200) {
139 nXPos -= 0x0400;
140 }
141
142 if (nXPos < 0) {
143 if ((pBuffer->flip & 2) == 0) {
144 pSpriteData += (-nXPos >> 4) << 2;
145 }
146 nXSize -= -nXPos & 0xFFF0;
147 nXPos += -nXPos & 0xFFF0;
148 }
149
150 if (nXPos + nXSize >= nCaveXSize) {
151 if (pBuffer->flip & 2) {
152 pSpriteData += ((nXPos + nXSize - nCaveXSize) >> 4) << 2;
153 }
154 nXSize -= (nXPos + nXSize - nCaveXSize) & 0xFFF0;
155 }
156
157 pRow = pBurnDraw + (nYPos * nBurnPitch) + (nXPos * nBurnBpp);
158
159 nFunction = (pBuffer->flip & 2) << 1; // X Flip
160
161 if (nTopSprite > nCurrentZPos) { // Test ZBuffer
162 if (nXPos < nMaskRight && (nXPos + nXSize) >= nMaskLeft && nYPos < nMaskBottom && (nYPos + nYSize) >= nMaskTop) {
163 nFunction |= 1;
164 }
165 }
166
167 if (nUseBuffer < nCurrentZPos) { // Write ZBuffer
168 nFunction |= 2;
169
170 if (nXPos < nMaskLeft) {
171 nMaskLeft = nXPos;
172 }
173 if ((nXPos + nXSize) > nMaskRight) {
174 nMaskRight = nXPos + nXSize;
175 }
176 if (nYPos < nMaskTop) {
177 nMaskTop = nYPos;
178 }
179 if ((nYPos + nYSize) > nMaskBottom) {
180 nMaskBottom = nYPos + nYSize;
181 }
182 }
183
184 if (nFunction & 3) {
185 pZRow = pZBuffer + (nYPos * 320) + nXPos;
186 nZPos = nCurrentZPos + nZOffset;
187 }
188
189 nXSize = nXSize >> 2;
190
191 RenderSprite[nFunction]();
192 } else { // This sprite uses zooming
193 nSpriteXZoomSize = 0x01000000; // * zoom factor = size of each screen pixel
194
195 nXSize *= pBuffer->xzoom;
196 nXSize >>= 8; // Round to multiple of whole pixel
197 if (nXSize < 1) { // Make sure the sprite is at least one pixel wide
198 nXSize = 1;
199 } else {
200 nSpriteXZoomSize /= pBuffer->xzoom;
201 }
202 if (nSpriteXZoomSize > (pBuffer->xsize << 16)) {
203 nSpriteXZoomSize = pBuffer->xsize << 16;
204 }
205 nSpriteXOffset = nSpriteXZoomSize >> 1; // Make certain the pixels displayed are centered
206
207 if (pBuffer->flip & 2) { // X Flip
208 nXPos += pBuffer->xsize - nXSize;
209
210 nSpriteXOffset = (pBuffer->xsize << 16) - nSpriteXOffset;
211 nSpriteXZoomSize = -nSpriteXZoomSize;
212 }
213
214 if (nXPos >= 0x0200) {
215 nXPos -= 0x0400;
216 }
217
218 if (nXPos < 0) {
219 if (nXPos + nXSize <= 0) {
220 continue;
221 }
222 nXPos = -nXPos;
223 nSpriteXOffset += nXPos * nSpriteXZoomSize;
224 nXSize -= nXPos;
225 nXPos = 0;
226 }
227
228 if (nXPos + nXSize >= nCaveXSize) {
229 if (nXPos >= nCaveXSize) {
230 continue;
231 }
232 nXSize = nCaveXSize - nXPos;
233 }
234
235 nSpriteRowSize = pBuffer->xsize; // Size of each sprite row in memory
236 nSpriteYZoomSize = 0x01000000; // * zoom factor = size of each screen pixel
237
238 nYSize *= pBuffer->yzoom;
239 nYSize >>= 8; // Round to multiple of whole pixel
240 if (nYSize < 1) { // Make certain the sprite is at least one pixel high
241 nYSize = 1;
242 } else {
243 nSpriteYZoomSize /= pBuffer->yzoom;
244 }
245 if (nSpriteYZoomSize > (pBuffer->ysize << 16)) {
246 nSpriteYZoomSize = pBuffer->ysize << 16;
247 }
248 nSpriteYOffset = nSpriteYZoomSize >> 1; // Make certain the pixels displayed are centered
249
250 if (pBuffer->flip & 1) { // Y Flip
251 nYPos += pBuffer->ysize - nYSize;
252
253 nSpriteYOffset = (pBuffer->ysize << 16) - nSpriteYOffset;
254 nSpriteYZoomSize = -nSpriteYZoomSize;
255 }
256
257 if (nYPos >= 0x0200) {
258 nYPos -= 0x0400;
259 }
260
261 if (nYPos < 0) {
262 if (nYPos + nYSize <= 0) {
263 continue;
264 }
265 nYPos = -nYPos;
266 nSpriteYOffset += nYPos * nSpriteYZoomSize;
267 nYSize -= nYPos;
268 nYPos = 0;
269 }
270
271 if (nYPos + nYSize >= nCaveYSize) {
272 if (nYPos >= nCaveYSize) {
273 continue;
274 }
275 nYSize = nCaveYSize - nYPos;
276 }
277
278 pRow = pBurnDraw + (nYPos * nBurnPitch) + (nXPos * nBurnBpp);
279
280 nFunction = 8;
281
282 if (pBuffer->xzoom > 0x0100 || pBuffer->yzoom > 0x0100) {
283 nFunction |= 4;
284 }
285
286 if (nTopSprite > nCurrentZPos) { // Test ZBuffer
287 if (nXPos < nMaskRight && nXPos + nXSize >= nMaskLeft && nYPos < nMaskBottom && nYPos + nYSize >= nMaskTop) {
288 nFunction |= 1;
289 }
290 }
291
292 if (nUseBuffer < nCurrentZPos) { // Write ZBuffer
293 nFunction |= 2;
294
295 if (nXPos < nMaskLeft) {
296 nMaskLeft = nXPos;
297 }
298 if (nXPos + nXSize > nMaskRight) {
299 nMaskRight = nXPos + nXSize;
300 }
301 if (nYPos < nMaskTop) {
302 nMaskTop = nYPos;
303 }
304 if (nYPos + nYSize > nMaskBottom) {
305 nMaskBottom = nYPos + nYSize;
306 }
307 }
308
309 if (nFunction & 3) {
310 pZRow = pZBuffer + (nYPos * nCaveXSize) + nXPos;
311 nZPos = nCurrentZPos + nZOffset;
312 }
313
314 nXSize <<= 16;
315 nYSize <<= 16;
316
317 RenderSprite[nFunction]();
318 }
319 }
320
321 if (nMaxZPos > nTopSprite) {
322 nTopSprite = nMaxZPos;
323 }
324
325 if (nHighPriority == 3) {
326 if (nZPos >= 0) {
327 nZOffset += nTopSprite;
328 if (nZOffset > 0xFC00) {
329 memset(pZBuffer, 0, nCaveXSize * nCaveYSize * sizeof(UINT16));
330 nZOffset = 0;
331 }
332 }
333 }
334
335 return 0;
336 }
337
338 // Donpachi/DoDonpachi sprite format (no zooming)
CaveSpriteBuffer_NoZoom()339 static INT32 CaveSpriteBuffer_NoZoom()
340 {
341 UINT16* pSprite = (UINT16*)(CaveSpriteRAM + (nCaveSpriteBank << 14));
342 CaveSprite* pBuffer = pSpriteList;
343 INT32 nPriority;
344
345 nFirstSprite[0] = 0x00010000;
346 nFirstSprite[1] = 0x00010000;
347 nFirstSprite[2] = 0x00010000;
348 nFirstSprite[3] = 0x00010000;
349
350 nLastSprite[0] = -1;
351 nLastSprite[1] = -1;
352 nLastSprite[2] = -1;
353 nLastSprite[3] = -1;
354
355 INT16 word;
356 INT32 x, y, xs, ys;
357
358 for (INT32 i = 0, z = 0; i < 0x0400; i++, pSprite += 8) {
359
360 word = BURN_ENDIAN_SWAP_INT16(pSprite[4]);
361
362 xs = (word >> 4) & 0x01F0;
363 ys = (word << 4) & 0x01F0;
364 if (ys == 0 || xs == 0) {
365 continue;
366 }
367
368 #if 0
369 x = (BURN_ENDIAN_SWAP_INT16(pSprite[2]) + nCaveExtraXOffset) & 0x03FF;
370 #else
371 x = (BURN_ENDIAN_SWAP_INT16(pSprite[2]) + CaveSpriteVisibleXOffset) & 0x03FF;
372 #endif
373 if (x >= 320) {
374 if (x + xs <= 0x0400) {
375 continue;
376 }
377 }
378
379 #if 0
380 y = (BURN_ENDIAN_SWAP_INT16(pSprite[3]) + nCaveExtraYOffset) & 0x03FF;
381 #else
382 y = BURN_ENDIAN_SWAP_INT16(pSprite[3]) & 0x03FF;
383 #endif
384 if (y >= 240) {
385 if (y + ys <= 0x0400) {
386 continue;
387 }
388 }
389
390 // Sprite is both active and onscreen, so add it to the buffer
391
392 word = BURN_ENDIAN_SWAP_INT16(pSprite[0]);
393
394 nPriority = (word >> 4) & 0x03;
395 if (nLastSprite[nPriority] == -1) {
396 nFirstSprite[nPriority] = z;
397 }
398 nLastSprite[nPriority] = z;
399
400 pBuffer->priority = 8 >> nPriority;
401
402 pBuffer->flip = (word >> 2) & 0x03;
403 pBuffer->palette = word & 0x3F00;
404
405 pBuffer->address = BURN_ENDIAN_SWAP_INT16(pSprite[1]) | ((word & 3) << 16);
406
407 pBuffer->x = x;
408 pBuffer->y = y;
409
410 pBuffer->xsize = xs;
411 pBuffer->ysize = ys;
412
413 pBuffer++;
414 z++;
415 }
416
417 return 0;
418 }
419
420 // Normal sprite format (zooming)
CaveSpriteBuffer_ZoomA()421 static INT32 CaveSpriteBuffer_ZoomA()
422 {
423 UINT16* pSprite = (UINT16*)(CaveSpriteRAM + (nCaveSpriteBank << 14));
424 CaveSprite* pBuffer = pSpriteList;
425 INT32 nPriority;
426
427 nFirstSprite[0] = 0x00010000;
428 nFirstSprite[1] = 0x00010000;
429 nFirstSprite[2] = 0x00010000;
430 nFirstSprite[3] = 0x00010000;
431
432 nLastSprite[0] = -1;
433 nLastSprite[1] = -1;
434 nLastSprite[2] = -1;
435 nLastSprite[3] = -1;
436
437 INT16 word;
438 INT32 x, y, xs, ys;
439
440 for (INT32 i = 0, z = 0; i < 0x0400; i++, pSprite += 8) {
441
442 word = BURN_ENDIAN_SWAP_INT16(pSprite[6]);
443
444 xs = (word >> 4) & 0x01F0;
445 ys = (word << 4) & 0x01F0;
446 if (ys == 0 || xs == 0) {
447 continue;
448 }
449
450 word = BURN_ENDIAN_SWAP_INT16(pSprite[2]);
451
452 nPriority = (word >> 4) & 0x03;
453
454 x = ((BURN_ENDIAN_SWAP_INT16(pSprite[0]) >> 6) + CaveSpriteVisibleXOffset) & 0x03FF;
455 #if 0
456 y = ((BURN_ENDIAN_SWAP_INT16(pSprite[1]) >> 6) + nCaveExtraYOffset) & 0x03FF;
457 #else
458 y = (BURN_ENDIAN_SWAP_INT16(pSprite[1]) >> 6) & 0x03FF;
459 #endif
460
461 if (BURN_ENDIAN_SWAP_INT16(pSprite[4]) <= 0x0100 && BURN_ENDIAN_SWAP_INT16(pSprite[5]) <= 0x0100) {
462 if (x >= 320) {
463 if (x + xs <= 0x0400) {
464 continue;
465 }
466 }
467 if (y >= 240) {
468 if (y + ys <= 0x0400) {
469 continue;
470 }
471 }
472 }
473
474 // Sprite is active and most likely on screen, so add it to the buffer
475
476 if (nLastSprite[nPriority] == -1) {
477 nFirstSprite[nPriority] = z;
478 }
479 nLastSprite[nPriority] = z;
480
481 pBuffer->priority = 8 >> nPriority;
482
483 pBuffer->xzoom = BURN_ENDIAN_SWAP_INT16(pSprite[4]);
484 pBuffer->yzoom = BURN_ENDIAN_SWAP_INT16(pSprite[5]);
485
486 pBuffer->xsize = xs;
487 pBuffer->ysize = ys;
488
489 pBuffer->x = x;
490 pBuffer->y = y;
491
492 pBuffer->flip = (word >> 2) & 0x03;
493 pBuffer->palette = word & 0x3F00;
494
495 pBuffer->address = BURN_ENDIAN_SWAP_INT16(pSprite[3]) | ((word & 3) << 16);
496
497 pBuffer++;
498 z++;
499 }
500
501 return 0;
502 }
503
504 // Normal sprite format (zooming, alternate position handling)
CaveSpriteBuffer_ZoomB()505 static INT32 CaveSpriteBuffer_ZoomB()
506 {
507 UINT16* pSprite = (UINT16*)(CaveSpriteRAM + (nCaveSpriteBank << 14));
508 CaveSprite* pBuffer = pSpriteList;
509 INT32 nPriority;
510
511 nFirstSprite[0] = 0x00010000;
512 nFirstSprite[1] = 0x00010000;
513 nFirstSprite[2] = 0x00010000;
514 nFirstSprite[3] = 0x00010000;
515
516 nLastSprite[0] = -1;
517 nLastSprite[1] = -1;
518 nLastSprite[2] = -1;
519 nLastSprite[3] = -1;
520
521 INT16 word;
522 INT32 x, y, xs, ys;
523
524 for (INT32 i = 0, z = 0; i < 0x0400; i++, pSprite += 8) {
525
526 word = BURN_ENDIAN_SWAP_INT16(pSprite[6]);
527
528 xs = (word >> 4) & 0x01F0;
529 ys = (word << 4) & 0x01F0;
530 if (ys == 0 || xs == 0) {
531 continue;
532 }
533
534 word = BURN_ENDIAN_SWAP_INT16(pSprite[2]);
535
536 nPriority = (word >> 4) & 0x03;
537
538 #if 0
539 x = (BURN_ENDIAN_SWAP_INT16(pSprite[0]) + nCaveExtraXOffset) & 0x03FF;
540 # else
541 x = (BURN_ENDIAN_SWAP_INT16(pSprite[0]) + CaveSpriteVisibleXOffset) & 0x03FF;
542 #endif
543 #if 0
544 y = (BURN_ENDIAN_SWAP_INT16(pSprite[1]) + nCaveExtraYOffset) & 0x03FF;
545 #else
546 y = BURN_ENDIAN_SWAP_INT16(pSprite[1]) & 0x03FF;
547 #endif
548
549 if (BURN_ENDIAN_SWAP_INT16(pSprite[4]) <= 0x0100 && BURN_ENDIAN_SWAP_INT16(pSprite[5]) <= 0x0100) {
550 if (x >= nCaveXSize) {
551 if (x + xs <= 0x0400) {
552 continue;
553 }
554 }
555 if (y >= nCaveYSize) {
556 if (y + ys <= 0x0400) {
557 continue;
558 }
559 }
560 }
561
562 // Sprite is active and most likely on screen, so add it to the buffer
563
564 if (nLastSprite[nPriority] == -1) {
565 nFirstSprite[nPriority] = z;
566 }
567 nLastSprite[nPriority] = z;
568
569 pBuffer->priority = 8 >> nPriority;
570
571 pBuffer->xzoom = BURN_ENDIAN_SWAP_INT16(pSprite[4]);
572 pBuffer->yzoom = BURN_ENDIAN_SWAP_INT16(pSprite[5]);
573
574 pBuffer->xsize = xs;
575 pBuffer->ysize = ys;
576
577 pBuffer->x = x;
578 pBuffer->y = y;
579
580 pBuffer->flip = (word >> 2) & 0x03;
581 pBuffer->palette = word & 0x3F00;
582
583 pBuffer->address = BURN_ENDIAN_SWAP_INT16(pSprite[3]) | ((word & 3) << 16);
584
585 pBuffer++;
586 z++;
587 }
588
589 return 0;
590 }
591
592 // Power Instinct 2 sprite format (no zooming)
CaveSpriteBuffer_PowerInstinct()593 static INT32 CaveSpriteBuffer_PowerInstinct()
594 {
595 UINT16* pSprite = (UINT16*)(CaveSpriteRAM + (nCaveSpriteBank << 14));
596 CaveSprite* pBuffer = pSpriteList;
597 INT32 nPriority;
598
599 nFirstSprite[0] = 0x00010000;
600 nFirstSprite[1] = 0x00010000;
601 nFirstSprite[2] = 0x00010000;
602 nFirstSprite[3] = 0x00010000;
603
604 nLastSprite[0] = -1;
605 nLastSprite[1] = -1;
606 nLastSprite[2] = -1;
607 nLastSprite[3] = -1;
608
609 INT16 word;
610 INT32 x, y, xs, ys;
611
612 for (INT32 i = 0, z = 0; i < 0x0400; i++, pSprite += 8) {
613
614 word = BURN_ENDIAN_SWAP_INT16(pSprite[4]);
615
616 xs = (word >> 4) & 0x01F0;
617 ys = (word << 4) & 0x01F0;
618 if (ys == 0 || xs == 0) {
619 continue;
620 }
621
622 x = (BURN_ENDIAN_SWAP_INT16(pSprite[2]) + nCaveExtraXOffset) & 0x03FF;
623 if (x >= 320) {
624 if (x + xs <= 0x0400) {
625 continue;
626 }
627 }
628
629 y = (BURN_ENDIAN_SWAP_INT16(pSprite[3]) + nCaveExtraYOffset) & 0x03FF;
630 if (y >= 240) {
631 if (y + ys <= 0x0400) {
632 continue;
633 }
634 }
635
636 // Sprite is both active and onscreen, so add it to the buffer
637
638 word = BURN_ENDIAN_SWAP_INT16(pSprite[0]);
639
640 nPriority = ((word >> 4) & 0x01) | 2;
641 if (nLastSprite[nPriority] == -1) {
642 nFirstSprite[nPriority] = z;
643 }
644 nLastSprite[nPriority] = z;
645
646 pBuffer->priority = 8 >> nPriority;
647
648 pBuffer->flip = (word >> 2) & 0x03;
649 pBuffer->palette = ((word >> 4) & 0x03F0) + ((word << 5) & 0xC00);
650
651 pBuffer->address = BURN_ENDIAN_SWAP_INT16(pSprite[1]) | ((word & 3) << 16);
652
653 pBuffer->x = x;
654 pBuffer->y = y;
655
656 pBuffer->xsize = xs;
657 pBuffer->ysize = ys;
658
659 pBuffer++;
660 z++;
661 }
662
663 return 0;
664 }
665
CaveSpriteExit()666 void CaveSpriteExit()
667 {
668 BurnFree(pSpriteList);
669 BurnFree(pZBuffer);
670
671 CaveSpriteVisibleXOffset = 0;
672
673 return;
674 }
675
CaveSpriteInit(INT32 nType,INT32 nROMSize)676 INT32 CaveSpriteInit(INT32 nType, INT32 nROMSize)
677 {
678 if (pSpriteList) {
679 BurnFree(pSpriteList);
680 }
681 pSpriteList = (CaveSprite*)BurnMalloc(0x0401 * sizeof(CaveSprite));
682 if (pSpriteList == NULL) {
683 CaveSpriteExit();
684 return 1;
685 }
686
687 for (INT32 i = 0; i < 0x0400; i++) {
688 pSpriteList[i].xzoom = 0x0100;
689 pSpriteList[i].yzoom = 0x0100;
690 }
691 for (INT32 i = 0; i < 4; i++) {
692 nFirstSprite[i] = 0x00010000;
693 nLastSprite[i] = -1;
694 }
695
696 if (pZBuffer) {
697 BurnFree(pZBuffer);
698 }
699 pZBuffer = (UINT16*)BurnMalloc(nCaveXSize * nCaveYSize * sizeof(UINT16));
700 if (pZBuffer == NULL) {
701 CaveSpriteExit();
702 return 1;
703 }
704
705 memset(pZBuffer, 0, nCaveXSize * nCaveYSize * sizeof(UINT16));
706 nZOffset = 0;
707
708 for (nSpriteAddressMask = 1; nSpriteAddressMask < nROMSize; nSpriteAddressMask <<= 1) {}
709 nSpriteAddressMask--;
710
711 switch (nType) {
712 case 0:
713 CaveSpriteBuffer = &CaveSpriteBuffer_NoZoom;
714 break;
715 case 1:
716 CaveSpriteBuffer = &CaveSpriteBuffer_ZoomA;
717 break;
718 case 2:
719 CaveSpriteBuffer = &CaveSpriteBuffer_ZoomB;
720 break;
721 case 3:
722 CaveSpriteBuffer = &CaveSpriteBuffer_PowerInstinct;
723 break;
724 default:
725 CaveSpriteExit();
726 return 1;
727 }
728
729 nCaveSpriteBank = 0;
730 nCaveSpriteBankDelay = 0;
731
732 RenderSprite = RenderSprite_ROT0[(nCaveXSize == 320) ? 0 : 1];
733
734 return 0;
735 }
736