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