drc: initial cop2/gte implementation (works, mostly)
[pcsx_rearmed.git] / plugins / dfxvideo / prim.c
CommitLineData
ef79bbde
P
1/***************************************************************************
2 prim.c - description
3 -------------------
4 begin : Sun Oct 28 2001
5 copyright : (C) 2001 by Pete Bernert
6 email : BlackDove@addcom.de
7 ***************************************************************************/
8/***************************************************************************
9 * *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. See also the license.txt file for *
14 * additional informations. *
15 * *
16 ***************************************************************************/
17
18#define _IN_PRIMDRAW
19
20#include "externals.h"
21#include "gpu.h"
22#include "draw.h"
23#include "soft.h"
24#include "swap.h"
25
26////////////////////////////////////////////////////////////////////////
27// globals
28////////////////////////////////////////////////////////////////////////
29
30BOOL bUsingTWin=FALSE;
31TWin_t TWin;
32//unsigned long clutid; // global clut
33unsigned short usMirror=0; // sprite mirror
34int iDither=0;
35int32_t drawX;
36int32_t drawY;
37int32_t drawW;
38int32_t drawH;
39uint32_t dwCfgFixes;
40uint32_t dwActFixes=0;
41uint32_t dwEmuFixes=0;
42int iUseFixes;
43int iUseDither=0;
44BOOL bDoVSyncUpdate=FALSE;
45
46////////////////////////////////////////////////////////////////////////
47// Some ASM color convertion by LEWPY
48////////////////////////////////////////////////////////////////////////
49
50#ifdef USE_NASM
51
52#define BGR24to16 i386_BGR24to16
53__inline unsigned short BGR24to16 (uint32_t BGR);
54
55#else
56
57__inline unsigned short BGR24to16 (uint32_t BGR)
58{
59 return (unsigned short)(((BGR>>3)&0x1f)|((BGR&0xf80000)>>9)|((BGR&0xf800)>>6));
60}
61
62#endif
63
64////////////////////////////////////////////////////////////////////////
65// Update global TP infos
66////////////////////////////////////////////////////////////////////////
67
68__inline void UpdateGlobalTP(unsigned short gdata)
69{
70 GlobalTextAddrX = (gdata << 6) & 0x3c0; // texture addr
71
72 if(iGPUHeight==1024)
73 {
74 if(dwGPUVersion==2)
75 {
76 GlobalTextAddrY =((gdata & 0x60 ) << 3);
77 GlobalTextIL =(gdata & 0x2000) >> 13;
78 GlobalTextABR = (unsigned short)((gdata >> 7) & 0x3);
79 GlobalTextTP = (gdata >> 9) & 0x3;
80 if(GlobalTextTP==3) GlobalTextTP=2;
81 usMirror =0;
82 lGPUstatusRet = (lGPUstatusRet & 0xffffe000 ) | (gdata & 0x1fff );
83
84 // tekken dithering? right now only if dithering is forced by user
85 if(iUseDither==2) iDither=2; else iDither=0;
86
87 return;
88 }
89 else
90 {
91 GlobalTextAddrY = (unsigned short)(((gdata << 4) & 0x100) | ((gdata >> 2) & 0x200));
92 }
93 }
94 else GlobalTextAddrY = (gdata << 4) & 0x100;
95
96 GlobalTextTP = (gdata >> 7) & 0x3; // tex mode (4,8,15)
97
98 if(GlobalTextTP==3) GlobalTextTP=2; // seen in Wild9 :(
99
100 GlobalTextABR = (gdata >> 5) & 0x3; // blend mode
101
102 lGPUstatusRet&=~0x000001ff; // Clear the necessary bits
103 lGPUstatusRet|=(gdata & 0x01ff); // set the necessary bits
104
105 switch(iUseDither)
106 {
107 case 0:
108 iDither=0;
109 break;
110 case 1:
111 if(lGPUstatusRet&0x0200) iDither=2;
112 else iDither=0;
113 break;
114 case 2:
115 iDither=2;
116 break;
117 }
118}
119
120////////////////////////////////////////////////////////////////////////
121
122__inline void SetRenderMode(uint32_t DrawAttributes)
123{
124 DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? TRUE : FALSE;
125
126 if(SHADETEXBIT(DrawAttributes))
127 {g_m1=g_m2=g_m3=128;}
128 else
129 {
130 if((dwActFixes&4) && ((DrawAttributes&0x00ffffff)==0))
131 DrawAttributes|=0x007f7f7f;
132
133 g_m1=(short)(DrawAttributes&0xff);
134 g_m2=(short)((DrawAttributes>>8)&0xff);
135 g_m3=(short)((DrawAttributes>>16)&0xff);
136 }
137}
138
139////////////////////////////////////////////////////////////////////////
140
141// oki, here are the psx gpu coord rules: poly coords are
142// 11 bit signed values (-1024...1023). If the x or y distance
143// exceeds 1024, the polygon will not be drawn.
144// Since quads are treated as two triangles by the real gpu,
145// this 'discard rule' applies to each of the quad's triangle
146// (so one triangle can be drawn, the other one discarded).
147// Also, y drawing is wrapped at 512 one time,
148// then it will get negative (and therefore not drawn). The
149// 'CheckCoord' funcs are a simple (not comlete!) approach to
150// do things right, I will add a better detection soon... the
151// current approach will be easier to do in hw/accel plugins, imho
152
153// 11 bit signed
154#define SIGNSHIFT 21
155#define CHKMAX_X 1024
156#define CHKMAX_Y 512
157
158void AdjustCoord4()
159{
160 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
161 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
162 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
163 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
164 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
165 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
166 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
167 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
168}
169
170void AdjustCoord3()
171{
172 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
173 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
174 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
175 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
176 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
177 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
178}
179
180void AdjustCoord2()
181{
182 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
183 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
184 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
185 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
186}
187
188void AdjustCoord1()
189{
190 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
191 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
192
193 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
194 lx0+=2048;
195
196 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
197 ly0+=2048;
198}
199
200////////////////////////////////////////////////////////////////////////
201// special checks... nascar, syphon filter 2, mgs
202////////////////////////////////////////////////////////////////////////
203
204// xenogears FT4: not removed correctly right now... the tri 0,1,2
205// should get removed, the tri 1,2,3 should stay... pfff
206
207// x -466 1023 180 1023
208// y 20 -228 222 -100
209
210// 0 __1
211// \ / \
212// 2___3
213
214__inline BOOL CheckCoord4()
215{
216 if(lx0<0)
217 {
218 if(((lx1-lx0)>CHKMAX_X) ||
219 ((lx2-lx0)>CHKMAX_X))
220 {
221 if(lx3<0)
222 {
223 if((lx1-lx3)>CHKMAX_X) return TRUE;
224 if((lx2-lx3)>CHKMAX_X) return TRUE;
225 }
226 }
227 }
228 if(lx1<0)
229 {
230 if((lx0-lx1)>CHKMAX_X) return TRUE;
231 if((lx2-lx1)>CHKMAX_X) return TRUE;
232 if((lx3-lx1)>CHKMAX_X) return TRUE;
233 }
234 if(lx2<0)
235 {
236 if((lx0-lx2)>CHKMAX_X) return TRUE;
237 if((lx1-lx2)>CHKMAX_X) return TRUE;
238 if((lx3-lx2)>CHKMAX_X) return TRUE;
239 }
240 if(lx3<0)
241 {
242 if(((lx1-lx3)>CHKMAX_X) ||
243 ((lx2-lx3)>CHKMAX_X))
244 {
245 if(lx0<0)
246 {
247 if((lx1-lx0)>CHKMAX_X) return TRUE;
248 if((lx2-lx0)>CHKMAX_X) return TRUE;
249 }
250 }
251 }
252
253
254 if(ly0<0)
255 {
256 if((ly1-ly0)>CHKMAX_Y) return TRUE;
257 if((ly2-ly0)>CHKMAX_Y) return TRUE;
258 }
259 if(ly1<0)
260 {
261 if((ly0-ly1)>CHKMAX_Y) return TRUE;
262 if((ly2-ly1)>CHKMAX_Y) return TRUE;
263 if((ly3-ly1)>CHKMAX_Y) return TRUE;
264 }
265 if(ly2<0)
266 {
267 if((ly0-ly2)>CHKMAX_Y) return TRUE;
268 if((ly1-ly2)>CHKMAX_Y) return TRUE;
269 if((ly3-ly2)>CHKMAX_Y) return TRUE;
270 }
271 if(ly3<0)
272 {
273 if((ly1-ly3)>CHKMAX_Y) return TRUE;
274 if((ly2-ly3)>CHKMAX_Y) return TRUE;
275 }
276
277 return FALSE;
278}
279
280__inline BOOL CheckCoord3()
281{
282 if(lx0<0)
283 {
284 if((lx1-lx0)>CHKMAX_X) return TRUE;
285 if((lx2-lx0)>CHKMAX_X) return TRUE;
286 }
287 if(lx1<0)
288 {
289 if((lx0-lx1)>CHKMAX_X) return TRUE;
290 if((lx2-lx1)>CHKMAX_X) return TRUE;
291 }
292 if(lx2<0)
293 {
294 if((lx0-lx2)>CHKMAX_X) return TRUE;
295 if((lx1-lx2)>CHKMAX_X) return TRUE;
296 }
297 if(ly0<0)
298 {
299 if((ly1-ly0)>CHKMAX_Y) return TRUE;
300 if((ly2-ly0)>CHKMAX_Y) return TRUE;
301 }
302 if(ly1<0)
303 {
304 if((ly0-ly1)>CHKMAX_Y) return TRUE;
305 if((ly2-ly1)>CHKMAX_Y) return TRUE;
306 }
307 if(ly2<0)
308 {
309 if((ly0-ly2)>CHKMAX_Y) return TRUE;
310 if((ly1-ly2)>CHKMAX_Y) return TRUE;
311 }
312
313 return FALSE;
314}
315
316
317__inline BOOL CheckCoord2()
318{
319 if(lx0<0)
320 {
321 if((lx1-lx0)>CHKMAX_X) return TRUE;
322 }
323 if(lx1<0)
324 {
325 if((lx0-lx1)>CHKMAX_X) return TRUE;
326 }
327 if(ly0<0)
328 {
329 if((ly1-ly0)>CHKMAX_Y) return TRUE;
330 }
331 if(ly1<0)
332 {
333 if((ly0-ly1)>CHKMAX_Y) return TRUE;
334 }
335
336 return FALSE;
337}
338
339__inline BOOL CheckCoordL(short slx0,short sly0,short slx1,short sly1)
340{
341 if(slx0<0)
342 {
343 if((slx1-slx0)>CHKMAX_X) return TRUE;
344 }
345 if(slx1<0)
346 {
347 if((slx0-slx1)>CHKMAX_X) return TRUE;
348 }
349 if(sly0<0)
350 {
351 if((sly1-sly0)>CHKMAX_Y) return TRUE;
352 }
353 if(sly1<0)
354 {
355 if((sly0-sly1)>CHKMAX_Y) return TRUE;
356 }
357
358 return FALSE;
359}
360
361
362////////////////////////////////////////////////////////////////////////
363// mask stuff... used in silent hill
364////////////////////////////////////////////////////////////////////////
365
366void cmdSTP(unsigned char * baseAddr)
367{
368 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
369
370 lGPUstatusRet&=~0x1800; // Clear the necessary bits
371 lGPUstatusRet|=((gdata & 0x03) << 11); // Set the necessary bits
372
373 if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;}
374 else {sSetMask=0; lSetMask=0; }
375
376 if(gdata&2) bCheckMask=TRUE;
377 else bCheckMask=FALSE;
378}
379
380////////////////////////////////////////////////////////////////////////
381// cmd: Set texture page infos
382////////////////////////////////////////////////////////////////////////
383
384void cmdTexturePage(unsigned char * baseAddr)
385{
386 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
387
388 lGPUstatusRet&=~0x000007ff;
389 lGPUstatusRet|=(gdata & 0x07ff);
390
391 usMirror=gdata&0x3000;
392
393 UpdateGlobalTP((unsigned short)gdata);
394 GlobalTextREST = (gdata&0x00ffffff)>>9;
395}
396
397////////////////////////////////////////////////////////////////////////
398// cmd: turn on/off texture window
399////////////////////////////////////////////////////////////////////////
400
401void cmdTextureWindow(unsigned char *baseAddr)
402{
403 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
404
405 uint32_t YAlign,XAlign;
406
407 lGPUInfoVals[INFO_TW]=gdata&0xFFFFF;
408
409 if(gdata & 0x020)
410 TWin.Position.y1 = 8; // xxxx1
411 else if (gdata & 0x040)
412 TWin.Position.y1 = 16; // xxx10
413 else if (gdata & 0x080)
414 TWin.Position.y1 = 32; // xx100
415 else if (gdata & 0x100)
416 TWin.Position.y1 = 64; // x1000
417 else if (gdata & 0x200)
418 TWin.Position.y1 = 128; // 10000
419 else
420 TWin.Position.y1 = 256; // 00000
421
422 // Texture window size is determined by the least bit set of the relevant 5 bits
423
424 if (gdata & 0x001)
425 TWin.Position.x1 = 8; // xxxx1
426 else if (gdata & 0x002)
427 TWin.Position.x1 = 16; // xxx10
428 else if (gdata & 0x004)
429 TWin.Position.x1 = 32; // xx100
430 else if (gdata & 0x008)
431 TWin.Position.x1 = 64; // x1000
432 else if (gdata & 0x010)
433 TWin.Position.x1 = 128; // 10000
434 else
435 TWin.Position.x1 = 256; // 00000
436
437 // Re-calculate the bit field, because we can't trust what is passed in the data
438
439
440 YAlign = (uint32_t)(32 - (TWin.Position.y1 >> 3));
441 XAlign = (uint32_t)(32 - (TWin.Position.x1 >> 3));
442
443 // Absolute position of the start of the texture window
444
445 TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);
446 TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);
447
448 if((TWin.Position.x0 == 0 && // tw turned off
449 TWin.Position.y0 == 0 &&
450 TWin.Position.x1 == 0 &&
451 TWin.Position.y1 == 0) ||
452 (TWin.Position.x1 == 256 &&
453 TWin.Position.y1 == 256))
454 {
455 bUsingTWin = FALSE; // -> just do it
456 }
457 else // otherwise
458 {
459 bUsingTWin = TRUE; // -> tw turned on
460 }
461}
462
463////////////////////////////////////////////////////////////////////////
464// cmd: start of drawing area... primitives will be clipped inside
465////////////////////////////////////////////////////////////////////////
466
467
468
469void cmdDrawAreaStart(unsigned char * baseAddr)
470{
471 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
472
473 drawX = gdata & 0x3ff; // for soft drawing
474
475 if(dwGPUVersion==2)
476 {
477 lGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF;
478 drawY = (gdata>>12)&0x3ff;
479 if(drawY>=1024) drawY=1023; // some security
480 }
481 else
482 {
483 lGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;
484 drawY = (gdata>>10)&0x3ff;
485 if(drawY>=512) drawY=511; // some security
486 }
487}
488
489////////////////////////////////////////////////////////////////////////
490// cmd: end of drawing area... primitives will be clipped inside
491////////////////////////////////////////////////////////////////////////
492
493void cmdDrawAreaEnd(unsigned char * baseAddr)
494{
495 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
496
497 drawW = gdata & 0x3ff; // for soft drawing
498
499 if(dwGPUVersion==2)
500 {
501 lGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF;
502 drawH = (gdata>>12)&0x3ff;
503 if(drawH>=1024) drawH=1023; // some security
504 }
505 else
506 {
507 lGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;
508 drawH = (gdata>>10)&0x3ff;
509 if(drawH>=512) drawH=511; // some security
510 }
511}
512
513////////////////////////////////////////////////////////////////////////
514// cmd: draw offset... will be added to prim coords
515////////////////////////////////////////////////////////////////////////
516
517void cmdDrawOffset(unsigned char * baseAddr)
518{
519 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
520
521 PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);
522
523 if(dwGPUVersion==2)
524 {
525 lGPUInfoVals[INFO_DRAWOFF]=gdata&0x7FFFFF;
526 PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff);
527 }
528 else
529 {
530 lGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;
531 PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);
532 }
533
534 PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);
535 PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);
536}
537
538////////////////////////////////////////////////////////////////////////
539// cmd: load image to vram
540////////////////////////////////////////////////////////////////////////
541
542void primLoadImage(unsigned char * baseAddr)
543{
544 unsigned short *sgpuData = ((unsigned short *) baseAddr);
545
546 VRAMWrite.x = GETLEs16(&sgpuData[2])&0x3ff;
547 VRAMWrite.y = GETLEs16(&sgpuData[3])&iGPUHeightMask;
548 VRAMWrite.Width = GETLEs16(&sgpuData[4]);
549 VRAMWrite.Height = GETLEs16(&sgpuData[5]);
550
551 DataWriteMode = DR_VRAMTRANSFER;
552
553 VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;
554 VRAMWrite.RowsRemaining = VRAMWrite.Width;
555 VRAMWrite.ColsRemaining = VRAMWrite.Height;
556}
557
558////////////////////////////////////////////////////////////////////////
559// cmd: vram -> psx mem
560////////////////////////////////////////////////////////////////////////
561
562void primStoreImage(unsigned char * baseAddr)
563{
564 unsigned short *sgpuData = ((unsigned short *) baseAddr);
565
566 VRAMRead.x = GETLEs16(&sgpuData[2])&0x03ff;
567 VRAMRead.y = GETLEs16(&sgpuData[3])&iGPUHeightMask;
568 VRAMRead.Width = GETLEs16(&sgpuData[4]);
569 VRAMRead.Height = GETLEs16(&sgpuData[5]);
570
571 VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;
572 VRAMRead.RowsRemaining = VRAMRead.Width;
573 VRAMRead.ColsRemaining = VRAMRead.Height;
574
575 DataReadMode = DR_VRAMTRANSFER;
576
577 lGPUstatusRet |= GPUSTATUS_READYFORVRAM;
578}
579
580////////////////////////////////////////////////////////////////////////
581// cmd: blkfill - NO primitive! Doesn't care about draw areas...
582////////////////////////////////////////////////////////////////////////
583
584void primBlkFill(unsigned char * baseAddr)
585{
586 uint32_t *gpuData = ((uint32_t *) baseAddr);
587 short *sgpuData = ((short *) baseAddr);
588
589 short sX = GETLEs16(&sgpuData[2]);
590 short sY = GETLEs16(&sgpuData[3]);
591 short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
592 short sH = GETLEs16(&sgpuData[5]) & 0x3ff;
593
594 sW = (sW+15) & ~15;
595
596 // Increase H & W if they are one short of full values, because they never can be full values
597 if (sH >= 1023) sH=1024;
598 if (sW >= 1023) sW=1024;
599
600 // x and y of end pos
601 sW+=sX;
602 sH+=sY;
603
604 FillSoftwareArea(sX, sY, sW, sH, BGR24to16(GETLE32(&gpuData[0])));
605
606 bDoVSyncUpdate=TRUE;
607}
608
609////////////////////////////////////////////////////////////////////////
610// cmd: move image vram -> vram
611////////////////////////////////////////////////////////////////////////
612
613void primMoveImage(unsigned char * baseAddr)
614{
615 short *sgpuData = ((short *) baseAddr);
616
617 short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;
618
619 imageX0 = GETLEs16(&sgpuData[2])&0x03ff;
620 imageY0 = GETLEs16(&sgpuData[3])&iGPUHeightMask;
621 imageX1 = GETLEs16(&sgpuData[4])&0x03ff;
622 imageY1 = GETLEs16(&sgpuData[5])&iGPUHeightMask;
623 imageSX = GETLEs16(&sgpuData[6]);
624 imageSY = GETLEs16(&sgpuData[7]);
625
626 if((imageX0 == imageX1) && (imageY0 == imageY1)) return;
627 if(imageSX<=0) return;
628 if(imageSY<=0) return;
629
630 // ZN SF2: screwed moves
631 //
632 // move sgpuData[2],sgpuData[3],sgpuData[4],sgpuData[5],sgpuData[6],sgpuData[7]
633 //
634 // move 365 182 32723 -21846 17219 15427
635 // move 127 160 147 -1 20817 13409
636 // move 141 165 16275 -21862 -32126 13442
637 // move 161 136 24620 -1 16962 13388
638 // move 168 138 32556 -13090 -29556 15500
639 //
640 // and here's the hack for it:
641
642 if(iGPUHeight==1024 && GETLEs16(&sgpuData[7])>1024) return;
643
644 if((imageY0+imageSY)>iGPUHeight ||
645 (imageX0+imageSX)>1024 ||
646 (imageY1+imageSY)>iGPUHeight ||
647 (imageX1+imageSX)>1024)
648 {
649 int i,j;
650 for(j=0;j<imageSY;j++)
651 for(i=0;i<imageSX;i++)
652 psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]=
653 psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)];
654
655 bDoVSyncUpdate=TRUE;
656
657 return;
658 }
659
660 if(imageSX&1) // not dword aligned? slower func
661 {
662 unsigned short *SRCPtr, *DSTPtr;
663 unsigned short LineOffset;
664
665 SRCPtr = psxVuw + (1024*imageY0) + imageX0;
666 DSTPtr = psxVuw + (1024*imageY1) + imageX1;
667
668 LineOffset = 1024 - imageSX;
669
670 for(j=0;j<imageSY;j++)
671 {
672 for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;
673 SRCPtr += LineOffset;
674 DSTPtr += LineOffset;
675 }
676 }
677 else // dword aligned
678 {
679 uint32_t *SRCPtr, *DSTPtr;
680 unsigned short LineOffset;
681 int dx=imageSX>>1;
682
683 SRCPtr = (uint32_t *)(psxVuw + (1024*imageY0) + imageX0);
684 DSTPtr = (uint32_t *)(psxVuw + (1024*imageY1) + imageX1);
685
686 LineOffset = 512 - dx;
687
688 for(j=0;j<imageSY;j++)
689 {
690 for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;
691 SRCPtr += LineOffset;
692 DSTPtr += LineOffset;
693 }
694 }
695
696 imageSX+=imageX1;
697 imageSY+=imageY1;
698
699/*
700 if(!PSXDisplay.Interlaced) // stupid frame skip stuff
701 {
702 if(UseFrameSkip &&
703 imageX1<PSXDisplay.DisplayEnd.x &&
704 imageSX>=PSXDisplay.DisplayPosition.x &&
705 imageY1<PSXDisplay.DisplayEnd.y &&
706 imageSY>=PSXDisplay.DisplayPosition.y)
707 updateDisplay();
708 }
709*/
710
711 bDoVSyncUpdate=TRUE;
712}
713
714////////////////////////////////////////////////////////////////////////
715// cmd: draw free-size Tile
716////////////////////////////////////////////////////////////////////////
717
718//#define SMALLDEBUG
719//#include <dbgout.h>
720
721void primTileS(unsigned char * baseAddr)
722{
723 uint32_t *gpuData = ((uint32_t*)baseAddr);
724 short *sgpuData = ((short *) baseAddr);
725 short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
726 short sH = GETLEs16(&sgpuData[5]) & iGPUHeightMask; // mmm... limit tiles to 0x1ff or height?
727
728 lx0 = GETLEs16(&sgpuData[2]);
729 ly0 = GETLEs16(&sgpuData[3]);
730
731 if(!(dwActFixes&8)) AdjustCoord1();
732
733 // x and y of start
734 ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
735 ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
736 lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
737 lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
738
739 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
740
741 if(!(iTileCheat && sH==32 && GETLE32(&gpuData[0])==0x60ffffff)) // special cheat for certain ZiNc games
742 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
743 BGR24to16(GETLE32(&gpuData[0])));
744
745 bDoVSyncUpdate=TRUE;
746}
747
748////////////////////////////////////////////////////////////////////////
749// cmd: draw 1 dot Tile (point)
750////////////////////////////////////////////////////////////////////////
751
752void primTile1(unsigned char * baseAddr)
753{
754 uint32_t *gpuData = ((uint32_t*)baseAddr);
755 short *sgpuData = ((short *) baseAddr);
756 short sH = 1;
757 short sW = 1;
758
759 lx0 = GETLEs16(&sgpuData[2]);
760 ly0 = GETLEs16(&sgpuData[3]);
761
762 if(!(dwActFixes&8)) AdjustCoord1();
763
764 // x and y of start
765 ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
766 ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
767 lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
768 lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
769
770 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
771
772 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
773 BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
774
775 bDoVSyncUpdate=TRUE;
776}
777
778////////////////////////////////////////////////////////////////////////
779// cmd: draw 8 dot Tile (small rect)
780////////////////////////////////////////////////////////////////////////
781
782void primTile8(unsigned char * baseAddr)
783{
784 uint32_t *gpuData = ((uint32_t*)baseAddr);
785 short *sgpuData = ((short *) baseAddr);
786 short sH = 8;
787 short sW = 8;
788
789 lx0 = GETLEs16(&sgpuData[2]);
790 ly0 = GETLEs16(&sgpuData[3]);
791
792 if(!(dwActFixes&8)) AdjustCoord1();
793
794 // x and y of start
795 ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
796 ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
797 lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
798 lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
799
800 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
801
802 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
803 BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
804
805 bDoVSyncUpdate=TRUE;
806}
807
808////////////////////////////////////////////////////////////////////////
809// cmd: draw 16 dot Tile (medium rect)
810////////////////////////////////////////////////////////////////////////
811
812void primTile16(unsigned char * baseAddr)
813{
814 uint32_t *gpuData = ((uint32_t*)baseAddr);
815 short *sgpuData = ((short *) baseAddr);
816 short sH = 16;
817 short sW = 16;
818
819 lx0 = GETLEs16(&sgpuData[2]);
820 ly0 = GETLEs16(&sgpuData[3]);
821
822 if(!(dwActFixes&8)) AdjustCoord1();
823
824 // x and y of start
825 ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
826 ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
827 lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
828 lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
829
830 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
831
832 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
833 BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
834
835 bDoVSyncUpdate=TRUE;
836}
837
838////////////////////////////////////////////////////////////////////////
839// cmd: small sprite (textured rect)
840////////////////////////////////////////////////////////////////////////
841
842void primSprt8(unsigned char * baseAddr)
843{
844 uint32_t *gpuData = ((uint32_t *) baseAddr);
845 short *sgpuData = ((short *) baseAddr);
846
847 lx0 = GETLEs16(&sgpuData[2]);
848 ly0 = GETLEs16(&sgpuData[3]);
849
850 if(!(dwActFixes&8)) AdjustCoord1();
851
852 SetRenderMode(GETLE32(&gpuData[0]));
853
854 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);
855 else
856 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,8,8);
857 else DrawSoftwareSprite(baseAddr,8,8,
858 baseAddr[8],
859 baseAddr[9]);
860
861 bDoVSyncUpdate=TRUE;
862}
863
864////////////////////////////////////////////////////////////////////////
865// cmd: medium sprite (textured rect)
866////////////////////////////////////////////////////////////////////////
867
868void primSprt16(unsigned char * baseAddr)
869{
870 uint32_t *gpuData = ((uint32_t *) baseAddr);
871 short *sgpuData = ((short *) baseAddr);
872
873 lx0 = GETLEs16(&sgpuData[2]);
874 ly0 = GETLEs16(&sgpuData[3]);
875
876 if(!(dwActFixes&8)) AdjustCoord1();
877
878 SetRenderMode(GETLE32(&gpuData[0]));
879
880 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);
881 else
882 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,16,16);
883 else DrawSoftwareSprite(baseAddr,16,16,
884 baseAddr[8],
885 baseAddr[9]);
886
887 bDoVSyncUpdate=TRUE;
888}
889
890////////////////////////////////////////////////////////////////////////
891// cmd: free-size sprite (textured rect)
892////////////////////////////////////////////////////////////////////////
893
894// func used on texture coord wrap
895void primSprtSRest(unsigned char * baseAddr,unsigned short type)
896{
897 uint32_t *gpuData = ((uint32_t *) baseAddr);
898 short *sgpuData = ((short *) baseAddr);
899 unsigned short sTypeRest=0;
900
901 short s;
902 short sX = GETLEs16(&sgpuData[2]);
903 short sY = GETLEs16(&sgpuData[3]);
904 short sW = GETLEs16(&sgpuData[6]) & 0x3ff;
905 short sH = GETLEs16(&sgpuData[7]) & 0x1ff;
906 short tX = baseAddr[8];
907 short tY = baseAddr[9];
908
909 switch(type)
910 {
911 case 1:
912 s=256-baseAddr[8];
913 sW-=s;
914 sX+=s;
915 tX=0;
916 break;
917 case 2:
918 s=256-baseAddr[9];
919 sH-=s;
920 sY+=s;
921 tY=0;
922 break;
923 case 3:
924 s=256-baseAddr[8];
925 sW-=s;
926 sX+=s;
927 tX=0;
928 s=256-baseAddr[9];
929 sH-=s;
930 sY+=s;
931 tY=0;
932 break;
933 case 4:
934 s=512-baseAddr[8];
935 sW-=s;
936 sX+=s;
937 tX=0;
938 break;
939 case 5:
940 s=512-baseAddr[9];
941 sH-=s;
942 sY+=s;
943 tY=0;
944 break;
945 case 6:
946 s=512-baseAddr[8];
947 sW-=s;
948 sX+=s;
949 tX=0;
950 s=512-baseAddr[9];
951 sH-=s;
952 sY+=s;
953 tY=0;
954 break;
955 }
956
957 SetRenderMode(GETLE32(&gpuData[0]));
958
959 if(tX+sW>256) {sW=256-tX;sTypeRest+=1;}
960 if(tY+sH>256) {sH=256-tY;sTypeRest+=2;}
961
962 lx0 = sX;
963 ly0 = sY;
964
965 if(!(dwActFixes&8)) AdjustCoord1();
966
967 DrawSoftwareSprite(baseAddr,sW,sH,tX,tY);
968
969 if(sTypeRest && type<4)
970 {
971 if(sTypeRest&1 && type==1) primSprtSRest(baseAddr,4);
972 if(sTypeRest&2 && type==2) primSprtSRest(baseAddr,5);
973 if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);
974 }
975
976}
977
978////////////////////////////////////////////////////////////////////////
979
980void primSprtS(unsigned char * baseAddr)
981{
982 uint32_t *gpuData = ((uint32_t *) baseAddr);
983 short *sgpuData = ((short *) baseAddr);
984 short sW,sH;
985
986 lx0 = GETLEs16(&sgpuData[2]);
987 ly0 = GETLEs16(&sgpuData[3]);
988
989 if(!(dwActFixes&8)) AdjustCoord1();
990
991 sW = GETLEs16(&sgpuData[6]) & 0x3ff;
992 sH = GETLEs16(&sgpuData[7]) & 0x1ff;
993
994 SetRenderMode(GETLE32(&gpuData[0]));
995
996 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sW,sH);
997 else
998 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sW,sH);
999 else
1000 {
1001 unsigned short sTypeRest=0;
1002 short tX=baseAddr[8];
1003 short tY=baseAddr[9];
1004
1005 if(tX+sW>256) {sW=256-tX;sTypeRest+=1;}
1006 if(tY+sH>256) {sH=256-tY;sTypeRest+=2;}
1007
1008 DrawSoftwareSprite(baseAddr,sW,sH,tX,tY);
1009
1010 if(sTypeRest)
1011 {
1012 if(sTypeRest&1) primSprtSRest(baseAddr,1);
1013 if(sTypeRest&2) primSprtSRest(baseAddr,2);
1014 if(sTypeRest==3) primSprtSRest(baseAddr,3);
1015 }
1016
1017 }
1018
1019 bDoVSyncUpdate=TRUE;
1020}
1021
1022////////////////////////////////////////////////////////////////////////
1023// cmd: flat shaded Poly4
1024////////////////////////////////////////////////////////////////////////
1025
1026void primPolyF4(unsigned char *baseAddr)
1027{
1028 uint32_t *gpuData = ((uint32_t *) baseAddr);
1029 short *sgpuData = ((short *) baseAddr);
1030
1031 lx0 = GETLEs16(&sgpuData[2]);
1032 ly0 = GETLEs16(&sgpuData[3]);
1033 lx1 = GETLEs16(&sgpuData[4]);
1034 ly1 = GETLEs16(&sgpuData[5]);
1035 lx2 = GETLEs16(&sgpuData[6]);
1036 ly2 = GETLEs16(&sgpuData[7]);
1037 lx3 = GETLEs16(&sgpuData[8]);
1038 ly3 = GETLEs16(&sgpuData[9]);
1039
1040 if(!(dwActFixes&8))
1041 {
1042 AdjustCoord4();
1043 if(CheckCoord4()) return;
1044 }
1045
1046 offsetPSX4();
1047 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1048
1049 drawPoly4F(GETLE32(&gpuData[0]));
1050
1051 bDoVSyncUpdate=TRUE;
1052}
1053
1054////////////////////////////////////////////////////////////////////////
1055// cmd: smooth shaded Poly4
1056////////////////////////////////////////////////////////////////////////
1057
1058void primPolyG4(unsigned char * baseAddr)
1059{
1060 uint32_t *gpuData = (uint32_t *)baseAddr;
1061 short *sgpuData = ((short *) baseAddr);
1062
1063 lx0 = GETLEs16(&sgpuData[2]);
1064 ly0 = GETLEs16(&sgpuData[3]);
1065 lx1 = GETLEs16(&sgpuData[6]);
1066 ly1 = GETLEs16(&sgpuData[7]);
1067 lx2 = GETLEs16(&sgpuData[10]);
1068 ly2 = GETLEs16(&sgpuData[11]);
1069 lx3 = GETLEs16(&sgpuData[14]);
1070 ly3 = GETLEs16(&sgpuData[15]);
1071
1072 if(!(dwActFixes&8))
1073 {
1074 AdjustCoord4();
1075 if(CheckCoord4()) return;
1076 }
1077
1078 offsetPSX4();
1079 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1080
1081 drawPoly4G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]),
1082 GETLE32(&gpuData[4]), GETLE32(&gpuData[6]));
1083
1084 bDoVSyncUpdate=TRUE;
1085}
1086
1087////////////////////////////////////////////////////////////////////////
1088// cmd: flat shaded Texture3
1089////////////////////////////////////////////////////////////////////////
1090
1091void primPolyFT3(unsigned char * baseAddr)
1092{
1093 uint32_t *gpuData = ((uint32_t *) baseAddr);
1094 short *sgpuData = ((short *) baseAddr);
1095
1096 lx0 = GETLEs16(&sgpuData[2]);
1097 ly0 = GETLEs16(&sgpuData[3]);
1098 lx1 = GETLEs16(&sgpuData[6]);
1099 ly1 = GETLEs16(&sgpuData[7]);
1100 lx2 = GETLEs16(&sgpuData[10]);
1101 ly2 = GETLEs16(&sgpuData[11]);
1102
1103 lLowerpart=GETLE32(&gpuData[4])>>16;
1104 UpdateGlobalTP((unsigned short)lLowerpart);
1105
1106 if(!(dwActFixes&8))
1107 {
1108 AdjustCoord3();
1109 if(CheckCoord3()) return;
1110 }
1111
1112 offsetPSX3();
1113 SetRenderMode(GETLE32(&gpuData[0]));
1114
1115 drawPoly3FT(baseAddr);
1116
1117 bDoVSyncUpdate=TRUE;
1118}
1119
1120////////////////////////////////////////////////////////////////////////
1121// cmd: flat shaded Texture4
1122////////////////////////////////////////////////////////////////////////
1123
1124void primPolyFT4(unsigned char * baseAddr)
1125{
1126 uint32_t *gpuData = ((uint32_t *) baseAddr);
1127 short *sgpuData = ((short *) baseAddr);
1128
1129 lx0 = GETLEs16(&sgpuData[2]);
1130 ly0 = GETLEs16(&sgpuData[3]);
1131 lx1 = GETLEs16(&sgpuData[6]);
1132 ly1 = GETLEs16(&sgpuData[7]);
1133 lx2 = GETLEs16(&sgpuData[10]);
1134 ly2 = GETLEs16(&sgpuData[11]);
1135 lx3 = GETLEs16(&sgpuData[14]);
1136 ly3 = GETLEs16(&sgpuData[15]);
1137
1138 lLowerpart=GETLE32(&gpuData[4])>>16;
1139 UpdateGlobalTP((unsigned short)lLowerpart);
1140
1141 if(!(dwActFixes&8))
1142 {
1143 AdjustCoord4();
1144 if(CheckCoord4()) return;
1145 }
1146
1147 offsetPSX4();
1148
1149 SetRenderMode(GETLE32(&gpuData[0]));
1150
1151 drawPoly4FT(baseAddr);
1152
1153 bDoVSyncUpdate=TRUE;
1154}
1155
1156////////////////////////////////////////////////////////////////////////
1157// cmd: smooth shaded Texture3
1158////////////////////////////////////////////////////////////////////////
1159
1160void primPolyGT3(unsigned char *baseAddr)
1161{
1162 uint32_t *gpuData = ((uint32_t *) baseAddr);
1163 short *sgpuData = ((short *) baseAddr);
1164
1165 lx0 = GETLEs16(&sgpuData[2]);
1166 ly0 = GETLEs16(&sgpuData[3]);
1167 lx1 = GETLEs16(&sgpuData[8]);
1168 ly1 = GETLEs16(&sgpuData[9]);
1169 lx2 = GETLEs16(&sgpuData[14]);
1170 ly2 = GETLEs16(&sgpuData[15]);
1171
1172 lLowerpart=GETLE32(&gpuData[5])>>16;
1173 UpdateGlobalTP((unsigned short)lLowerpart);
1174
1175 if(!(dwActFixes&8))
1176 {
1177 AdjustCoord3();
1178 if(CheckCoord3()) return;
1179 }
1180
1181 offsetPSX3();
1182 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1183
1184 if(SHADETEXBIT(GETLE32(&gpuData[0])))
1185 {
1186 gpuData[0] = (gpuData[0]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1187 gpuData[3] = (gpuData[3]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1188 gpuData[6] = (gpuData[6]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1189 }
1190
1191 drawPoly3GT(baseAddr);
1192
1193 bDoVSyncUpdate=TRUE;
1194}
1195
1196////////////////////////////////////////////////////////////////////////
1197// cmd: smooth shaded Poly3
1198////////////////////////////////////////////////////////////////////////
1199
1200void primPolyG3(unsigned char *baseAddr)
1201{
1202 uint32_t *gpuData = ((uint32_t *) baseAddr);
1203 short *sgpuData = ((short *) baseAddr);
1204
1205 lx0 = GETLEs16(&sgpuData[2]);
1206 ly0 = GETLEs16(&sgpuData[3]);
1207 lx1 = GETLEs16(&sgpuData[6]);
1208 ly1 = GETLEs16(&sgpuData[7]);
1209 lx2 = GETLEs16(&sgpuData[10]);
1210 ly2 = GETLEs16(&sgpuData[11]);
1211
1212 if(!(dwActFixes&8))
1213 {
1214 AdjustCoord3();
1215 if(CheckCoord3()) return;
1216 }
1217
1218 offsetPSX3();
1219 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1220
1221 drawPoly3G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]), GETLE32(&gpuData[4]));
1222
1223 bDoVSyncUpdate=TRUE;
1224}
1225
1226////////////////////////////////////////////////////////////////////////
1227// cmd: smooth shaded Texture4
1228////////////////////////////////////////////////////////////////////////
1229
1230void primPolyGT4(unsigned char *baseAddr)
1231{
1232 uint32_t *gpuData = ((uint32_t *) baseAddr);
1233 short *sgpuData = ((short *) baseAddr);
1234
1235 lx0 = GETLEs16(&sgpuData[2]);
1236 ly0 = GETLEs16(&sgpuData[3]);
1237 lx1 = GETLEs16(&sgpuData[8]);
1238 ly1 = GETLEs16(&sgpuData[9]);
1239 lx2 = GETLEs16(&sgpuData[14]);
1240 ly2 = GETLEs16(&sgpuData[15]);
1241 lx3 = GETLEs16(&sgpuData[20]);
1242 ly3 = GETLEs16(&sgpuData[21]);
1243
1244 lLowerpart=GETLE32(&gpuData[5])>>16;
1245 UpdateGlobalTP((unsigned short)lLowerpart);
1246
1247 if(!(dwActFixes&8))
1248 {
1249 AdjustCoord4();
1250 if(CheckCoord4()) return;
1251 }
1252
1253 offsetPSX4();
1254 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1255
1256 if(SHADETEXBIT(GETLE32(&gpuData[0])))
1257 {
1258 gpuData[0] = (gpuData[0]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1259 gpuData[3] = (gpuData[3]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1260 gpuData[6] = (gpuData[6]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1261 gpuData[9] = (gpuData[9]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1262 }
1263
1264 drawPoly4GT(baseAddr);
1265
1266 bDoVSyncUpdate=TRUE;
1267}
1268
1269////////////////////////////////////////////////////////////////////////
1270// cmd: smooth shaded Poly3
1271////////////////////////////////////////////////////////////////////////
1272
1273void primPolyF3(unsigned char *baseAddr)
1274{
1275 uint32_t *gpuData = ((uint32_t *) baseAddr);
1276 short *sgpuData = ((short *) baseAddr);
1277
1278 lx0 = GETLEs16(&sgpuData[2]);
1279 ly0 = GETLEs16(&sgpuData[3]);
1280 lx1 = GETLEs16(&sgpuData[4]);
1281 ly1 = GETLEs16(&sgpuData[5]);
1282 lx2 = GETLEs16(&sgpuData[6]);
1283 ly2 = GETLEs16(&sgpuData[7]);
1284
1285 if(!(dwActFixes&8))
1286 {
1287 AdjustCoord3();
1288 if(CheckCoord3()) return;
1289 }
1290
1291 offsetPSX3();
1292 SetRenderMode(GETLE32(&gpuData[0]));
1293
1294 drawPoly3F(GETLE32(&gpuData[0]));
1295
1296 bDoVSyncUpdate=TRUE;
1297}
1298
1299////////////////////////////////////////////////////////////////////////
1300// cmd: skipping shaded polylines
1301////////////////////////////////////////////////////////////////////////
1302
1303void primLineGSkip(unsigned char *baseAddr)
1304{
1305 uint32_t *gpuData = ((uint32_t *) baseAddr);
1306 int iMax=255;
1307 int i=2;
1308
1309 ly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
1310 lx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
1311
1312 while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=4))
1313 {
1314 i++;
1315 ly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
1316 lx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
1317 i++;if(i>iMax) break;
1318 }
1319}
1320
1321////////////////////////////////////////////////////////////////////////
1322// cmd: shaded polylines
1323////////////////////////////////////////////////////////////////////////
1324
1325void primLineGEx(unsigned char *baseAddr)
1326{
1327 uint32_t *gpuData = ((uint32_t *) baseAddr);
1328 int iMax=255;
1329 uint32_t lc0,lc1;
1330 short slx0,slx1,sly0,sly1;int i=2;BOOL bDraw=TRUE;
1331
1332 sly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
1333 slx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
1334
1335 if(!(dwActFixes&8))
1336 {
1337 slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
1338 sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
1339 }
1340
1341 lc1 = gpuData[0] & 0xffffff;
1342
1343 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1344
1345 while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=4))
1346 {
1347 sly0=sly1; slx0=slx1; lc0=lc1;
1348 lc1=GETLE32(&gpuData[i]) & 0xffffff;
1349
1350 i++;
1351
1352 // no check needed on gshaded polyline positions
1353 // if((gpuData[i] & 0xF000F000) == 0x50005000) break;
1354
1355 sly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
1356 slx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
1357
1358 if(!(dwActFixes&8))
1359 {
1360 slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
1361 sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
1362 if(CheckCoordL(slx0,sly0,slx1,sly1)) bDraw=FALSE; else bDraw=TRUE;
1363 }
1364
1365 if ((lx0 != lx1) || (ly0 != ly1))
1366 {
1367 ly0=sly0;
1368 lx0=slx0;
1369 ly1=sly1;
1370 lx1=slx1;
1371
1372 offsetPSX2();
1373 if(bDraw) DrawSoftwareLineShade(lc0, lc1);
1374 }
1375 i++;
1376 if(i>iMax) break;
1377 }
1378
1379 bDoVSyncUpdate=TRUE;
1380}
1381
1382////////////////////////////////////////////////////////////////////////
1383// cmd: shaded polyline2
1384////////////////////////////////////////////////////////////////////////
1385
1386void primLineG2(unsigned char *baseAddr)
1387{
1388 uint32_t *gpuData = ((uint32_t *) baseAddr);
1389 short *sgpuData = ((short *) baseAddr);
1390
1391 lx0 = GETLEs16(&sgpuData[2]);
1392 ly0 = GETLEs16(&sgpuData[3]);
1393 lx1 = GETLEs16(&sgpuData[6]);
1394 ly1 = GETLEs16(&sgpuData[7]);
1395
1396 if(!(dwActFixes&8))
1397 {
1398 AdjustCoord2();
1399 if(CheckCoord2()) return;
1400 }
1401
1402 if((lx0 == lx1) && (ly0 == ly1)) {lx1++;ly1++;}
1403
1404 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1405 offsetPSX2();
1406 DrawSoftwareLineShade(GETLE32(&gpuData[0]),GETLE32(&gpuData[2]));
1407
1408 bDoVSyncUpdate=TRUE;
1409}
1410
1411////////////////////////////////////////////////////////////////////////
1412// cmd: skipping flat polylines
1413////////////////////////////////////////////////////////////////////////
1414
1415void primLineFSkip(unsigned char *baseAddr)
1416{
1417 uint32_t *gpuData = ((uint32_t *) baseAddr);
1418 int i=2,iMax=255;
1419
1420 ly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
1421 lx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
1422
1423 while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=3))
1424 {
1425 ly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
1426 lx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
1427 i++;if(i>iMax) break;
1428 }
1429}
1430
1431////////////////////////////////////////////////////////////////////////
1432// cmd: drawing flat polylines
1433////////////////////////////////////////////////////////////////////////
1434
1435void primLineFEx(unsigned char *baseAddr)
1436{
1437 uint32_t *gpuData = ((uint32_t *) baseAddr);
1438 int iMax;
1439 short slx0,slx1,sly0,sly1;int i=2;BOOL bDraw=TRUE;
1440
1441 iMax=255;
1442
1443 sly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
1444 slx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
1445 if(!(dwActFixes&8))
1446 {
1447 slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
1448 sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
1449 }
1450
1451 SetRenderMode(GETLE32(&gpuData[0]));
1452
1453 while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=3))
1454 {
1455 sly0 = sly1;slx0=slx1;
1456 sly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
1457 slx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
1458 if(!(dwActFixes&8))
1459 {
1460 slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
1461 sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
1462
1463 if(CheckCoordL(slx0,sly0,slx1,sly1)) bDraw=FALSE; else bDraw=TRUE;
1464 }
1465
1466 ly0=sly0;
1467 lx0=slx0;
1468 ly1=sly1;
1469 lx1=slx1;
1470
1471 offsetPSX2();
1472 if(bDraw) DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
1473
1474 i++;if(i>iMax) break;
1475 }
1476
1477 bDoVSyncUpdate=TRUE;
1478}
1479
1480////////////////////////////////////////////////////////////////////////
1481// cmd: drawing flat polyline2
1482////////////////////////////////////////////////////////////////////////
1483
1484void primLineF2(unsigned char *baseAddr)
1485{
1486 uint32_t *gpuData = ((uint32_t *) baseAddr);
1487 short *sgpuData = ((short *) baseAddr);
1488
1489 lx0 = GETLEs16(&sgpuData[2]);
1490 ly0 = GETLEs16(&sgpuData[3]);
1491 lx1 = GETLEs16(&sgpuData[4]);
1492 ly1 = GETLEs16(&sgpuData[5]);
1493
1494 if(!(dwActFixes&8))
1495 {
1496 AdjustCoord2();
1497 if(CheckCoord2()) return;
1498 }
1499
1500 if((lx0 == lx1) && (ly0 == ly1)) {lx1++;ly1++;}
1501
1502 offsetPSX2();
1503 SetRenderMode(GETLE32(&gpuData[0]));
1504
1505 DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
1506
1507 bDoVSyncUpdate=TRUE;
1508}
1509
1510////////////////////////////////////////////////////////////////////////
1511// cmd: well, easiest command... not implemented
1512////////////////////////////////////////////////////////////////////////
1513
1514void primNI(unsigned char *bA)
1515{
1516}
1517
1518////////////////////////////////////////////////////////////////////////
1519// cmd func ptr table
1520////////////////////////////////////////////////////////////////////////
1521
1522
1523void (*primTableJ[256])(unsigned char *) =
1524{
1525 // 00
1526 primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
1527 // 08
1528 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1529 // 10
1530 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1531 // 18
1532 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1533 // 20
1534 primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3,
1535 // 28
1536 primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4,
1537 // 30
1538 primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3,
1539 // 38
1540 primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4,
1541 // 40
1542 primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI,
1543 // 48
1544 primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,
1545 // 50
1546 primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI,
1547 // 58
1548 primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,
1549 // 60
1550 primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS,
1551 // 68
1552 primTile1,primTile1,primTile1,primTile1,primNI,primNI,primNI,primNI,
1553 // 70
1554 primTile8,primTile8,primTile8,primTile8,primSprt8,primSprt8,primSprt8,primSprt8,
1555 // 78
1556 primTile16,primTile16,primTile16,primTile16,primSprt16,primSprt16,primSprt16,primSprt16,
1557 // 80
1558 primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1559 // 88
1560 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1561 // 90
1562 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1563 // 98
1564 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1565 // a0
1566 primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1567 // a8
1568 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1569 // b0
1570 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1571 // b8
1572 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1573 // c0
1574 primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1575 // c8
1576 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1577 // d0
1578 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1579 // d8
1580 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1581 // e0
1582 primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
1583 // e8
1584 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1585 // f0
1586 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1587 // f8
1588 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
1589};
1590
1591////////////////////////////////////////////////////////////////////////
1592// cmd func ptr table for skipping
1593////////////////////////////////////////////////////////////////////////
1594
1595void (*primTableSkip[256])(unsigned char *) =
1596{
1597 // 00
1598 primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
1599 // 08
1600 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1601 // 10
1602 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1603 // 18
1604 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1605 // 20
1606 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1607 // 28
1608 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1609 // 30
1610 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1611 // 38
1612 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1613 // 40
1614 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1615 // 48
1616 primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,
1617 // 50
1618 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1619 // 58
1620 primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,
1621 // 60
1622 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1623 // 68
1624 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1625 // 70
1626 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1627 // 78
1628 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1629 // 80
1630 primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1631 // 88
1632 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1633 // 90
1634 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1635 // 98
1636 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1637 // a0
1638 primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1639 // a8
1640 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1641 // b0
1642 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1643 // b8
1644 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1645 // c0
1646 primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1647 // c8
1648 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1649 // d0
1650 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1651 // d8
1652 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1653 // e0
1654 primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
1655 // e8
1656 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1657 // f0
1658 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1659 // f8
1660 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
1661};