dfxvideo: add bgr888->rgb565 converter for maemo port
[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
378
379 // Texture window size is determined by the least bit set of the relevant 5 bits
380
381 if (gdata & 0x001)
382 TWin.Position.x1 = 8; // xxxx1
383 else if (gdata & 0x002)
384 TWin.Position.x1 = 16; // xxx10
385 else if (gdata & 0x004)
386 TWin.Position.x1 = 32; // xx100
387 else if (gdata & 0x008)
388 TWin.Position.x1 = 64; // x1000
389 else if (gdata & 0x010)
390 TWin.Position.x1 = 128; // 10000
391 else
392 TWin.Position.x1 = 256; // 00000
393
394 // Re-calculate the bit field, because we can't trust what is passed in the data
395
396
397 YAlign = (uint32_t)(32 - (TWin.Position.y1 >> 3));
398 XAlign = (uint32_t)(32 - (TWin.Position.x1 >> 3));
399
400 // Absolute position of the start of the texture window
401
402 TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);
403 TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);
404
405 if((TWin.Position.x0 == 0 && // tw turned off
406 TWin.Position.y0 == 0 &&
407 TWin.Position.x1 == 0 &&
408 TWin.Position.y1 == 0) ||
409 (TWin.Position.x1 == 256 &&
410 TWin.Position.y1 == 256))
411 {
412 bUsingTWin = FALSE; // -> just do it
413 }
414 else // otherwise
415 {
416 bUsingTWin = TRUE; // -> tw turned on
417 }
418}
419
420////////////////////////////////////////////////////////////////////////
421// cmd: start of drawing area... primitives will be clipped inside
422////////////////////////////////////////////////////////////////////////
423
424
425
a96a5eb2 426static void cmdDrawAreaStart(unsigned char * baseAddr)
ef79bbde
P
427{
428 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
429
430 drawX = gdata & 0x3ff; // for soft drawing
431
ef79bbde
P
432 lGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;
433 drawY = (gdata>>10)&0x3ff;
434 if(drawY>=512) drawY=511; // some security
ef79bbde
P
435}
436
437////////////////////////////////////////////////////////////////////////
438// cmd: end of drawing area... primitives will be clipped inside
439////////////////////////////////////////////////////////////////////////
440
a96a5eb2 441static void cmdDrawAreaEnd(unsigned char * baseAddr)
ef79bbde
P
442{
443 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
444
445 drawW = gdata & 0x3ff; // for soft drawing
446
ef79bbde
P
447 lGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;
448 drawH = (gdata>>10)&0x3ff;
449 if(drawH>=512) drawH=511; // some security
ef79bbde
P
450}
451
452////////////////////////////////////////////////////////////////////////
453// cmd: draw offset... will be added to prim coords
454////////////////////////////////////////////////////////////////////////
455
a96a5eb2 456static void cmdDrawOffset(unsigned char * baseAddr)
ef79bbde
P
457{
458 uint32_t gdata = GETLE32(&((uint32_t*)baseAddr)[0]);
459
460 PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);
461
ef79bbde
P
462 lGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;
463 PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);
ef79bbde
P
464
465 PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);
466 PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);
467}
468
469////////////////////////////////////////////////////////////////////////
470// cmd: load image to vram
471////////////////////////////////////////////////////////////////////////
472
a96a5eb2 473static void primLoadImage(unsigned char * baseAddr)
ef79bbde
P
474{
475 unsigned short *sgpuData = ((unsigned short *) baseAddr);
476
477 VRAMWrite.x = GETLEs16(&sgpuData[2])&0x3ff;
a96a5eb2 478 VRAMWrite.y = GETLEs16(&sgpuData[3])&511;
ef79bbde
P
479 VRAMWrite.Width = GETLEs16(&sgpuData[4]);
480 VRAMWrite.Height = GETLEs16(&sgpuData[5]);
481
482 DataWriteMode = DR_VRAMTRANSFER;
483
484 VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;
485 VRAMWrite.RowsRemaining = VRAMWrite.Width;
486 VRAMWrite.ColsRemaining = VRAMWrite.Height;
487}
488
489////////////////////////////////////////////////////////////////////////
490// cmd: vram -> psx mem
491////////////////////////////////////////////////////////////////////////
492
a96a5eb2 493static void primStoreImage(unsigned char * baseAddr)
ef79bbde
P
494{
495 unsigned short *sgpuData = ((unsigned short *) baseAddr);
496
497 VRAMRead.x = GETLEs16(&sgpuData[2])&0x03ff;
a96a5eb2 498 VRAMRead.y = GETLEs16(&sgpuData[3])&511;
ef79bbde
P
499 VRAMRead.Width = GETLEs16(&sgpuData[4]);
500 VRAMRead.Height = GETLEs16(&sgpuData[5]);
501
502 VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;
503 VRAMRead.RowsRemaining = VRAMRead.Width;
504 VRAMRead.ColsRemaining = VRAMRead.Height;
505
506 DataReadMode = DR_VRAMTRANSFER;
507
508 lGPUstatusRet |= GPUSTATUS_READYFORVRAM;
509}
510
511////////////////////////////////////////////////////////////////////////
512// cmd: blkfill - NO primitive! Doesn't care about draw areas...
513////////////////////////////////////////////////////////////////////////
514
a96a5eb2 515static void primBlkFill(unsigned char * baseAddr)
ef79bbde
P
516{
517 uint32_t *gpuData = ((uint32_t *) baseAddr);
518 short *sgpuData = ((short *) baseAddr);
519
520 short sX = GETLEs16(&sgpuData[2]);
521 short sY = GETLEs16(&sgpuData[3]);
522 short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
523 short sH = GETLEs16(&sgpuData[5]) & 0x3ff;
524
525 sW = (sW+15) & ~15;
526
527 // Increase H & W if they are one short of full values, because they never can be full values
528 if (sH >= 1023) sH=1024;
529 if (sW >= 1023) sW=1024;
530
531 // x and y of end pos
532 sW+=sX;
533 sH+=sY;
534
535 FillSoftwareArea(sX, sY, sW, sH, BGR24to16(GETLE32(&gpuData[0])));
536
537 bDoVSyncUpdate=TRUE;
538}
539
540////////////////////////////////////////////////////////////////////////
541// cmd: move image vram -> vram
542////////////////////////////////////////////////////////////////////////
543
a96a5eb2 544static void primMoveImage(unsigned char * baseAddr)
ef79bbde
P
545{
546 short *sgpuData = ((short *) baseAddr);
547
548 short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;
549
550 imageX0 = GETLEs16(&sgpuData[2])&0x03ff;
a96a5eb2 551 imageY0 = GETLEs16(&sgpuData[3])&511;
ef79bbde 552 imageX1 = GETLEs16(&sgpuData[4])&0x03ff;
a96a5eb2 553 imageY1 = GETLEs16(&sgpuData[5])&511;
ef79bbde
P
554 imageSX = GETLEs16(&sgpuData[6]);
555 imageSY = GETLEs16(&sgpuData[7]);
556
557 if((imageX0 == imageX1) && (imageY0 == imageY1)) return;
558 if(imageSX<=0) return;
559 if(imageSY<=0) return;
560
a96a5eb2 561 if((imageY0+imageSY)>512 ||
ef79bbde 562 (imageX0+imageSX)>1024 ||
a96a5eb2 563 (imageY1+imageSY)>512 ||
ef79bbde
P
564 (imageX1+imageSX)>1024)
565 {
566 int i,j;
567 for(j=0;j<imageSY;j++)
568 for(i=0;i<imageSX;i++)
a96a5eb2 569 psxVuw [(1024*((imageY1+j)&511))+((imageX1+i)&0x3ff)]=
570 psxVuw[(1024*((imageY0+j)&511))+((imageX0+i)&0x3ff)];
ef79bbde
P
571
572 bDoVSyncUpdate=TRUE;
573
574 return;
575 }
576
577 if(imageSX&1) // not dword aligned? slower func
578 {
579 unsigned short *SRCPtr, *DSTPtr;
580 unsigned short LineOffset;
581
582 SRCPtr = psxVuw + (1024*imageY0) + imageX0;
583 DSTPtr = psxVuw + (1024*imageY1) + imageX1;
584
585 LineOffset = 1024 - imageSX;
586
587 for(j=0;j<imageSY;j++)
588 {
589 for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;
590 SRCPtr += LineOffset;
591 DSTPtr += LineOffset;
592 }
593 }
594 else // dword aligned
595 {
596 uint32_t *SRCPtr, *DSTPtr;
597 unsigned short LineOffset;
598 int dx=imageSX>>1;
599
600 SRCPtr = (uint32_t *)(psxVuw + (1024*imageY0) + imageX0);
601 DSTPtr = (uint32_t *)(psxVuw + (1024*imageY1) + imageX1);
602
603 LineOffset = 512 - dx;
604
605 for(j=0;j<imageSY;j++)
606 {
607 for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;
608 SRCPtr += LineOffset;
609 DSTPtr += LineOffset;
610 }
611 }
612
613 imageSX+=imageX1;
614 imageSY+=imageY1;
615
ef79bbde
P
616 bDoVSyncUpdate=TRUE;
617}
618
619////////////////////////////////////////////////////////////////////////
620// cmd: draw free-size Tile
621////////////////////////////////////////////////////////////////////////
622
a96a5eb2 623static void primTileS(unsigned char * baseAddr)
ef79bbde
P
624{
625 uint32_t *gpuData = ((uint32_t*)baseAddr);
626 short *sgpuData = ((short *) baseAddr);
627 short sW = GETLEs16(&sgpuData[4]) & 0x3ff;
a96a5eb2 628 short sH = GETLEs16(&sgpuData[5]) & 511; // mmm... limit tiles to 0x1ff or height?
ef79bbde
P
629
630 lx0 = GETLEs16(&sgpuData[2]);
631 ly0 = GETLEs16(&sgpuData[3]);
632
633 if(!(dwActFixes&8)) AdjustCoord1();
634
635 // x and y of start
636 ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
637 ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
638 lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
639 lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
640
641 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
642
ef79bbde
P
643 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
644 BGR24to16(GETLE32(&gpuData[0])));
645
646 bDoVSyncUpdate=TRUE;
647}
648
649////////////////////////////////////////////////////////////////////////
650// cmd: draw 1 dot Tile (point)
651////////////////////////////////////////////////////////////////////////
652
a96a5eb2 653static void primTile1(unsigned char * baseAddr)
ef79bbde
P
654{
655 uint32_t *gpuData = ((uint32_t*)baseAddr);
656 short *sgpuData = ((short *) baseAddr);
657 short sH = 1;
658 short sW = 1;
659
660 lx0 = GETLEs16(&sgpuData[2]);
661 ly0 = GETLEs16(&sgpuData[3]);
662
663 if(!(dwActFixes&8)) AdjustCoord1();
664
665 // x and y of start
666 ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
667 ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
668 lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
669 lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
670
671 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
672
673 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
674 BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
675
676 bDoVSyncUpdate=TRUE;
677}
678
679////////////////////////////////////////////////////////////////////////
680// cmd: draw 8 dot Tile (small rect)
681////////////////////////////////////////////////////////////////////////
682
a96a5eb2 683static void primTile8(unsigned char * baseAddr)
ef79bbde
P
684{
685 uint32_t *gpuData = ((uint32_t*)baseAddr);
686 short *sgpuData = ((short *) baseAddr);
687 short sH = 8;
688 short sW = 8;
689
690 lx0 = GETLEs16(&sgpuData[2]);
691 ly0 = GETLEs16(&sgpuData[3]);
692
693 if(!(dwActFixes&8)) AdjustCoord1();
694
695 // x and y of start
696 ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
697 ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
698 lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
699 lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
700
701 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
702
703 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
704 BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
705
706 bDoVSyncUpdate=TRUE;
707}
708
709////////////////////////////////////////////////////////////////////////
710// cmd: draw 16 dot Tile (medium rect)
711////////////////////////////////////////////////////////////////////////
712
a96a5eb2 713static void primTile16(unsigned char * baseAddr)
ef79bbde
P
714{
715 uint32_t *gpuData = ((uint32_t*)baseAddr);
716 short *sgpuData = ((short *) baseAddr);
717 short sH = 16;
718 short sW = 16;
719
720 lx0 = GETLEs16(&sgpuData[2]);
721 ly0 = GETLEs16(&sgpuData[3]);
722
723 if(!(dwActFixes&8)) AdjustCoord1();
724
725 // x and y of start
726 ly2 = ly3 = ly0+sH +PSXDisplay.DrawOffset.y;
727 ly0 = ly1 = ly0 +PSXDisplay.DrawOffset.y;
728 lx1 = lx2 = lx0+sW +PSXDisplay.DrawOffset.x;
729 lx0 = lx3 = lx0 +PSXDisplay.DrawOffset.x;
730
731 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
732
733 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
734 BGR24to16(GETLE32(&gpuData[0]))); // Takes Start and Offset
735
736 bDoVSyncUpdate=TRUE;
737}
738
739////////////////////////////////////////////////////////////////////////
740// cmd: small sprite (textured rect)
741////////////////////////////////////////////////////////////////////////
742
a96a5eb2 743static void primSprt8(unsigned char * baseAddr)
ef79bbde
P
744{
745 uint32_t *gpuData = ((uint32_t *) baseAddr);
746 short *sgpuData = ((short *) baseAddr);
747
748 lx0 = GETLEs16(&sgpuData[2]);
749 ly0 = GETLEs16(&sgpuData[3]);
750
751 if(!(dwActFixes&8)) AdjustCoord1();
752
753 SetRenderMode(GETLE32(&gpuData[0]));
754
755 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);
756 else
757 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,8,8);
758 else DrawSoftwareSprite(baseAddr,8,8,
759 baseAddr[8],
760 baseAddr[9]);
761
762 bDoVSyncUpdate=TRUE;
763}
764
765////////////////////////////////////////////////////////////////////////
766// cmd: medium sprite (textured rect)
767////////////////////////////////////////////////////////////////////////
768
a96a5eb2 769static void primSprt16(unsigned char * baseAddr)
ef79bbde
P
770{
771 uint32_t *gpuData = ((uint32_t *) baseAddr);
772 short *sgpuData = ((short *) baseAddr);
773
774 lx0 = GETLEs16(&sgpuData[2]);
775 ly0 = GETLEs16(&sgpuData[3]);
776
777 if(!(dwActFixes&8)) AdjustCoord1();
778
779 SetRenderMode(GETLE32(&gpuData[0]));
780
781 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);
782 else
783 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,16,16);
784 else DrawSoftwareSprite(baseAddr,16,16,
785 baseAddr[8],
786 baseAddr[9]);
787
788 bDoVSyncUpdate=TRUE;
789}
790
791////////////////////////////////////////////////////////////////////////
792// cmd: free-size sprite (textured rect)
793////////////////////////////////////////////////////////////////////////
794
795// func used on texture coord wrap
a96a5eb2 796static void primSprtSRest(unsigned char * baseAddr,unsigned short type)
ef79bbde
P
797{
798 uint32_t *gpuData = ((uint32_t *) baseAddr);
799 short *sgpuData = ((short *) baseAddr);
800 unsigned short sTypeRest=0;
801
802 short s;
803 short sX = GETLEs16(&sgpuData[2]);
804 short sY = GETLEs16(&sgpuData[3]);
805 short sW = GETLEs16(&sgpuData[6]) & 0x3ff;
806 short sH = GETLEs16(&sgpuData[7]) & 0x1ff;
807 short tX = baseAddr[8];
808 short tY = baseAddr[9];
809
810 switch(type)
811 {
812 case 1:
813 s=256-baseAddr[8];
814 sW-=s;
815 sX+=s;
816 tX=0;
817 break;
818 case 2:
819 s=256-baseAddr[9];
820 sH-=s;
821 sY+=s;
822 tY=0;
823 break;
824 case 3:
825 s=256-baseAddr[8];
826 sW-=s;
827 sX+=s;
828 tX=0;
829 s=256-baseAddr[9];
830 sH-=s;
831 sY+=s;
832 tY=0;
833 break;
834 case 4:
835 s=512-baseAddr[8];
836 sW-=s;
837 sX+=s;
838 tX=0;
839 break;
840 case 5:
841 s=512-baseAddr[9];
842 sH-=s;
843 sY+=s;
844 tY=0;
845 break;
846 case 6:
847 s=512-baseAddr[8];
848 sW-=s;
849 sX+=s;
850 tX=0;
851 s=512-baseAddr[9];
852 sH-=s;
853 sY+=s;
854 tY=0;
855 break;
856 }
857
858 SetRenderMode(GETLE32(&gpuData[0]));
859
860 if(tX+sW>256) {sW=256-tX;sTypeRest+=1;}
861 if(tY+sH>256) {sH=256-tY;sTypeRest+=2;}
862
863 lx0 = sX;
864 ly0 = sY;
865
866 if(!(dwActFixes&8)) AdjustCoord1();
867
868 DrawSoftwareSprite(baseAddr,sW,sH,tX,tY);
869
870 if(sTypeRest && type<4)
871 {
872 if(sTypeRest&1 && type==1) primSprtSRest(baseAddr,4);
873 if(sTypeRest&2 && type==2) primSprtSRest(baseAddr,5);
874 if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);
875 }
876
877}
878
879////////////////////////////////////////////////////////////////////////
880
a96a5eb2 881static void primSprtS(unsigned char * baseAddr)
ef79bbde
P
882{
883 uint32_t *gpuData = ((uint32_t *) baseAddr);
884 short *sgpuData = ((short *) baseAddr);
885 short sW,sH;
886
887 lx0 = GETLEs16(&sgpuData[2]);
888 ly0 = GETLEs16(&sgpuData[3]);
889
890 if(!(dwActFixes&8)) AdjustCoord1();
891
892 sW = GETLEs16(&sgpuData[6]) & 0x3ff;
893 sH = GETLEs16(&sgpuData[7]) & 0x1ff;
894
895 SetRenderMode(GETLE32(&gpuData[0]));
896
897 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sW,sH);
898 else
899 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sW,sH);
900 else
901 {
902 unsigned short sTypeRest=0;
903 short tX=baseAddr[8];
904 short tY=baseAddr[9];
905
906 if(tX+sW>256) {sW=256-tX;sTypeRest+=1;}
907 if(tY+sH>256) {sH=256-tY;sTypeRest+=2;}
908
909 DrawSoftwareSprite(baseAddr,sW,sH,tX,tY);
910
911 if(sTypeRest)
912 {
913 if(sTypeRest&1) primSprtSRest(baseAddr,1);
914 if(sTypeRest&2) primSprtSRest(baseAddr,2);
915 if(sTypeRest==3) primSprtSRest(baseAddr,3);
916 }
917
918 }
919
920 bDoVSyncUpdate=TRUE;
921}
922
923////////////////////////////////////////////////////////////////////////
924// cmd: flat shaded Poly4
925////////////////////////////////////////////////////////////////////////
926
a96a5eb2 927static void primPolyF4(unsigned char *baseAddr)
ef79bbde
P
928{
929 uint32_t *gpuData = ((uint32_t *) baseAddr);
930 short *sgpuData = ((short *) baseAddr);
931
932 lx0 = GETLEs16(&sgpuData[2]);
933 ly0 = GETLEs16(&sgpuData[3]);
934 lx1 = GETLEs16(&sgpuData[4]);
935 ly1 = GETLEs16(&sgpuData[5]);
936 lx2 = GETLEs16(&sgpuData[6]);
937 ly2 = GETLEs16(&sgpuData[7]);
938 lx3 = GETLEs16(&sgpuData[8]);
939 ly3 = GETLEs16(&sgpuData[9]);
940
941 if(!(dwActFixes&8))
942 {
943 AdjustCoord4();
944 if(CheckCoord4()) return;
945 }
946
947 offsetPSX4();
948 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
949
950 drawPoly4F(GETLE32(&gpuData[0]));
951
952 bDoVSyncUpdate=TRUE;
953}
954
955////////////////////////////////////////////////////////////////////////
956// cmd: smooth shaded Poly4
957////////////////////////////////////////////////////////////////////////
958
a96a5eb2 959static void primPolyG4(unsigned char * baseAddr)
ef79bbde
P
960{
961 uint32_t *gpuData = (uint32_t *)baseAddr;
962 short *sgpuData = ((short *) baseAddr);
963
964 lx0 = GETLEs16(&sgpuData[2]);
965 ly0 = GETLEs16(&sgpuData[3]);
966 lx1 = GETLEs16(&sgpuData[6]);
967 ly1 = GETLEs16(&sgpuData[7]);
968 lx2 = GETLEs16(&sgpuData[10]);
969 ly2 = GETLEs16(&sgpuData[11]);
970 lx3 = GETLEs16(&sgpuData[14]);
971 ly3 = GETLEs16(&sgpuData[15]);
972
973 if(!(dwActFixes&8))
974 {
975 AdjustCoord4();
976 if(CheckCoord4()) return;
977 }
978
979 offsetPSX4();
980 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
981
982 drawPoly4G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]),
983 GETLE32(&gpuData[4]), GETLE32(&gpuData[6]));
984
985 bDoVSyncUpdate=TRUE;
986}
987
988////////////////////////////////////////////////////////////////////////
989// cmd: flat shaded Texture3
990////////////////////////////////////////////////////////////////////////
991
a96a5eb2 992static void primPolyFT3(unsigned char * baseAddr)
ef79bbde
P
993{
994 uint32_t *gpuData = ((uint32_t *) baseAddr);
995 short *sgpuData = ((short *) baseAddr);
996
997 lx0 = GETLEs16(&sgpuData[2]);
998 ly0 = GETLEs16(&sgpuData[3]);
999 lx1 = GETLEs16(&sgpuData[6]);
1000 ly1 = GETLEs16(&sgpuData[7]);
1001 lx2 = GETLEs16(&sgpuData[10]);
1002 ly2 = GETLEs16(&sgpuData[11]);
1003
1004 lLowerpart=GETLE32(&gpuData[4])>>16;
1005 UpdateGlobalTP((unsigned short)lLowerpart);
1006
1007 if(!(dwActFixes&8))
1008 {
1009 AdjustCoord3();
1010 if(CheckCoord3()) return;
1011 }
1012
1013 offsetPSX3();
1014 SetRenderMode(GETLE32(&gpuData[0]));
1015
1016 drawPoly3FT(baseAddr);
1017
1018 bDoVSyncUpdate=TRUE;
1019}
1020
1021////////////////////////////////////////////////////////////////////////
1022// cmd: flat shaded Texture4
1023////////////////////////////////////////////////////////////////////////
1024
a96a5eb2 1025static void primPolyFT4(unsigned char * baseAddr)
ef79bbde
P
1026{
1027 uint32_t *gpuData = ((uint32_t *) baseAddr);
1028 short *sgpuData = ((short *) baseAddr);
1029
1030 lx0 = GETLEs16(&sgpuData[2]);
1031 ly0 = GETLEs16(&sgpuData[3]);
1032 lx1 = GETLEs16(&sgpuData[6]);
1033 ly1 = GETLEs16(&sgpuData[7]);
1034 lx2 = GETLEs16(&sgpuData[10]);
1035 ly2 = GETLEs16(&sgpuData[11]);
1036 lx3 = GETLEs16(&sgpuData[14]);
1037 ly3 = GETLEs16(&sgpuData[15]);
1038
1039 lLowerpart=GETLE32(&gpuData[4])>>16;
1040 UpdateGlobalTP((unsigned short)lLowerpart);
1041
1042 if(!(dwActFixes&8))
1043 {
1044 AdjustCoord4();
1045 if(CheckCoord4()) return;
1046 }
1047
1048 offsetPSX4();
1049
1050 SetRenderMode(GETLE32(&gpuData[0]));
1051
1052 drawPoly4FT(baseAddr);
1053
1054 bDoVSyncUpdate=TRUE;
1055}
1056
1057////////////////////////////////////////////////////////////////////////
1058// cmd: smooth shaded Texture3
1059////////////////////////////////////////////////////////////////////////
1060
a96a5eb2 1061static void primPolyGT3(unsigned char *baseAddr)
ef79bbde
P
1062{
1063 uint32_t *gpuData = ((uint32_t *) baseAddr);
1064 short *sgpuData = ((short *) baseAddr);
1065
1066 lx0 = GETLEs16(&sgpuData[2]);
1067 ly0 = GETLEs16(&sgpuData[3]);
1068 lx1 = GETLEs16(&sgpuData[8]);
1069 ly1 = GETLEs16(&sgpuData[9]);
1070 lx2 = GETLEs16(&sgpuData[14]);
1071 ly2 = GETLEs16(&sgpuData[15]);
1072
1073 lLowerpart=GETLE32(&gpuData[5])>>16;
1074 UpdateGlobalTP((unsigned short)lLowerpart);
1075
1076 if(!(dwActFixes&8))
1077 {
1078 AdjustCoord3();
1079 if(CheckCoord3()) return;
1080 }
1081
1082 offsetPSX3();
1083 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1084
1085 if(SHADETEXBIT(GETLE32(&gpuData[0])))
1086 {
1087 gpuData[0] = (gpuData[0]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1088 gpuData[3] = (gpuData[3]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1089 gpuData[6] = (gpuData[6]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1090 }
1091
1092 drawPoly3GT(baseAddr);
1093
1094 bDoVSyncUpdate=TRUE;
1095}
1096
1097////////////////////////////////////////////////////////////////////////
1098// cmd: smooth shaded Poly3
1099////////////////////////////////////////////////////////////////////////
1100
a96a5eb2 1101static void primPolyG3(unsigned char *baseAddr)
ef79bbde
P
1102{
1103 uint32_t *gpuData = ((uint32_t *) baseAddr);
1104 short *sgpuData = ((short *) baseAddr);
1105
1106 lx0 = GETLEs16(&sgpuData[2]);
1107 ly0 = GETLEs16(&sgpuData[3]);
1108 lx1 = GETLEs16(&sgpuData[6]);
1109 ly1 = GETLEs16(&sgpuData[7]);
1110 lx2 = GETLEs16(&sgpuData[10]);
1111 ly2 = GETLEs16(&sgpuData[11]);
1112
1113 if(!(dwActFixes&8))
1114 {
1115 AdjustCoord3();
1116 if(CheckCoord3()) return;
1117 }
1118
1119 offsetPSX3();
1120 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1121
1122 drawPoly3G(GETLE32(&gpuData[0]), GETLE32(&gpuData[2]), GETLE32(&gpuData[4]));
1123
1124 bDoVSyncUpdate=TRUE;
1125}
1126
1127////////////////////////////////////////////////////////////////////////
1128// cmd: smooth shaded Texture4
1129////////////////////////////////////////////////////////////////////////
1130
a96a5eb2 1131static void primPolyGT4(unsigned char *baseAddr)
ef79bbde
P
1132{
1133 uint32_t *gpuData = ((uint32_t *) baseAddr);
1134 short *sgpuData = ((short *) baseAddr);
1135
1136 lx0 = GETLEs16(&sgpuData[2]);
1137 ly0 = GETLEs16(&sgpuData[3]);
1138 lx1 = GETLEs16(&sgpuData[8]);
1139 ly1 = GETLEs16(&sgpuData[9]);
1140 lx2 = GETLEs16(&sgpuData[14]);
1141 ly2 = GETLEs16(&sgpuData[15]);
1142 lx3 = GETLEs16(&sgpuData[20]);
1143 ly3 = GETLEs16(&sgpuData[21]);
1144
1145 lLowerpart=GETLE32(&gpuData[5])>>16;
1146 UpdateGlobalTP((unsigned short)lLowerpart);
1147
1148 if(!(dwActFixes&8))
1149 {
1150 AdjustCoord4();
1151 if(CheckCoord4()) return;
1152 }
1153
1154 offsetPSX4();
1155 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1156
1157 if(SHADETEXBIT(GETLE32(&gpuData[0])))
1158 {
1159 gpuData[0] = (gpuData[0]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1160 gpuData[3] = (gpuData[3]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1161 gpuData[6] = (gpuData[6]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1162 gpuData[9] = (gpuData[9]&HOST2LE32(0xff000000))|HOST2LE32(0x00808080);
1163 }
1164
1165 drawPoly4GT(baseAddr);
1166
1167 bDoVSyncUpdate=TRUE;
1168}
1169
1170////////////////////////////////////////////////////////////////////////
1171// cmd: smooth shaded Poly3
1172////////////////////////////////////////////////////////////////////////
1173
a96a5eb2 1174static void primPolyF3(unsigned char *baseAddr)
ef79bbde
P
1175{
1176 uint32_t *gpuData = ((uint32_t *) baseAddr);
1177 short *sgpuData = ((short *) baseAddr);
1178
1179 lx0 = GETLEs16(&sgpuData[2]);
1180 ly0 = GETLEs16(&sgpuData[3]);
1181 lx1 = GETLEs16(&sgpuData[4]);
1182 ly1 = GETLEs16(&sgpuData[5]);
1183 lx2 = GETLEs16(&sgpuData[6]);
1184 ly2 = GETLEs16(&sgpuData[7]);
1185
1186 if(!(dwActFixes&8))
1187 {
1188 AdjustCoord3();
1189 if(CheckCoord3()) return;
1190 }
1191
1192 offsetPSX3();
1193 SetRenderMode(GETLE32(&gpuData[0]));
1194
1195 drawPoly3F(GETLE32(&gpuData[0]));
1196
1197 bDoVSyncUpdate=TRUE;
1198}
1199
1200////////////////////////////////////////////////////////////////////////
1201// cmd: skipping shaded polylines
1202////////////////////////////////////////////////////////////////////////
1203
a96a5eb2 1204static void primLineGSkip(unsigned char *baseAddr)
ef79bbde
P
1205{
1206 uint32_t *gpuData = ((uint32_t *) baseAddr);
1207 int iMax=255;
1208 int i=2;
1209
1210 ly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
1211 lx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
1212
1213 while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=4))
1214 {
1215 i++;
1216 ly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
1217 lx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
1218 i++;if(i>iMax) break;
1219 }
1220}
1221
1222////////////////////////////////////////////////////////////////////////
1223// cmd: shaded polylines
1224////////////////////////////////////////////////////////////////////////
1225
a96a5eb2 1226static void primLineGEx(unsigned char *baseAddr)
ef79bbde
P
1227{
1228 uint32_t *gpuData = ((uint32_t *) baseAddr);
1229 int iMax=255;
1230 uint32_t lc0,lc1;
1231 short slx0,slx1,sly0,sly1;int i=2;BOOL bDraw=TRUE;
1232
1233 sly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
1234 slx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
1235
1236 if(!(dwActFixes&8))
1237 {
1238 slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
1239 sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
1240 }
1241
1242 lc1 = gpuData[0] & 0xffffff;
1243
1244 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1245
1246 while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=4))
1247 {
1248 sly0=sly1; slx0=slx1; lc0=lc1;
1249 lc1=GETLE32(&gpuData[i]) & 0xffffff;
1250
1251 i++;
1252
1253 // no check needed on gshaded polyline positions
1254 // if((gpuData[i] & 0xF000F000) == 0x50005000) break;
1255
1256 sly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
1257 slx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
1258
1259 if(!(dwActFixes&8))
1260 {
1261 slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
1262 sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
1263 if(CheckCoordL(slx0,sly0,slx1,sly1)) bDraw=FALSE; else bDraw=TRUE;
1264 }
1265
1266 if ((lx0 != lx1) || (ly0 != ly1))
1267 {
1268 ly0=sly0;
1269 lx0=slx0;
1270 ly1=sly1;
1271 lx1=slx1;
1272
1273 offsetPSX2();
1274 if(bDraw) DrawSoftwareLineShade(lc0, lc1);
1275 }
1276 i++;
1277 if(i>iMax) break;
1278 }
1279
1280 bDoVSyncUpdate=TRUE;
1281}
1282
1283////////////////////////////////////////////////////////////////////////
1284// cmd: shaded polyline2
1285////////////////////////////////////////////////////////////////////////
1286
a96a5eb2 1287static void primLineG2(unsigned char *baseAddr)
ef79bbde
P
1288{
1289 uint32_t *gpuData = ((uint32_t *) baseAddr);
1290 short *sgpuData = ((short *) baseAddr);
1291
1292 lx0 = GETLEs16(&sgpuData[2]);
1293 ly0 = GETLEs16(&sgpuData[3]);
1294 lx1 = GETLEs16(&sgpuData[6]);
1295 ly1 = GETLEs16(&sgpuData[7]);
1296
1297 if(!(dwActFixes&8))
1298 {
1299 AdjustCoord2();
1300 if(CheckCoord2()) return;
1301 }
1302
1303 if((lx0 == lx1) && (ly0 == ly1)) {lx1++;ly1++;}
1304
1305 DrawSemiTrans = (SEMITRANSBIT(GETLE32(&gpuData[0]))) ? TRUE : FALSE;
1306 offsetPSX2();
1307 DrawSoftwareLineShade(GETLE32(&gpuData[0]),GETLE32(&gpuData[2]));
1308
1309 bDoVSyncUpdate=TRUE;
1310}
1311
1312////////////////////////////////////////////////////////////////////////
1313// cmd: skipping flat polylines
1314////////////////////////////////////////////////////////////////////////
1315
a96a5eb2 1316static void primLineFSkip(unsigned char *baseAddr)
ef79bbde
P
1317{
1318 uint32_t *gpuData = ((uint32_t *) baseAddr);
1319 int i=2,iMax=255;
1320
1321 ly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
1322 lx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
1323
1324 while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=3))
1325 {
1326 ly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
1327 lx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
1328 i++;if(i>iMax) break;
1329 }
1330}
1331
1332////////////////////////////////////////////////////////////////////////
1333// cmd: drawing flat polylines
1334////////////////////////////////////////////////////////////////////////
1335
a96a5eb2 1336static void primLineFEx(unsigned char *baseAddr)
ef79bbde
P
1337{
1338 uint32_t *gpuData = ((uint32_t *) baseAddr);
1339 int iMax;
1340 short slx0,slx1,sly0,sly1;int i=2;BOOL bDraw=TRUE;
1341
1342 iMax=255;
1343
1344 sly1 = (short)((GETLE32(&gpuData[1])>>16) & 0xffff);
1345 slx1 = (short)(GETLE32(&gpuData[1]) & 0xffff);
1346 if(!(dwActFixes&8))
1347 {
1348 slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
1349 sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
1350 }
1351
1352 SetRenderMode(GETLE32(&gpuData[0]));
1353
1354 while(!(((GETLE32(&gpuData[i]) & 0xF000F000) == 0x50005000) && i>=3))
1355 {
1356 sly0 = sly1;slx0=slx1;
1357 sly1 = (short)((GETLE32(&gpuData[i])>>16) & 0xffff);
1358 slx1 = (short)(GETLE32(&gpuData[i]) & 0xffff);
1359 if(!(dwActFixes&8))
1360 {
1361 slx1=(short)(((int)slx1<<SIGNSHIFT)>>SIGNSHIFT);
1362 sly1=(short)(((int)sly1<<SIGNSHIFT)>>SIGNSHIFT);
1363
1364 if(CheckCoordL(slx0,sly0,slx1,sly1)) bDraw=FALSE; else bDraw=TRUE;
1365 }
1366
1367 ly0=sly0;
1368 lx0=slx0;
1369 ly1=sly1;
1370 lx1=slx1;
1371
1372 offsetPSX2();
1373 if(bDraw) DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
1374
1375 i++;if(i>iMax) break;
1376 }
1377
1378 bDoVSyncUpdate=TRUE;
1379}
1380
1381////////////////////////////////////////////////////////////////////////
1382// cmd: drawing flat polyline2
1383////////////////////////////////////////////////////////////////////////
1384
a96a5eb2 1385static void primLineF2(unsigned char *baseAddr)
ef79bbde
P
1386{
1387 uint32_t *gpuData = ((uint32_t *) baseAddr);
1388 short *sgpuData = ((short *) baseAddr);
1389
1390 lx0 = GETLEs16(&sgpuData[2]);
1391 ly0 = GETLEs16(&sgpuData[3]);
1392 lx1 = GETLEs16(&sgpuData[4]);
1393 ly1 = GETLEs16(&sgpuData[5]);
1394
1395 if(!(dwActFixes&8))
1396 {
1397 AdjustCoord2();
1398 if(CheckCoord2()) return;
1399 }
1400
1401 if((lx0 == lx1) && (ly0 == ly1)) {lx1++;ly1++;}
1402
1403 offsetPSX2();
1404 SetRenderMode(GETLE32(&gpuData[0]));
1405
1406 DrawSoftwareLineFlat(GETLE32(&gpuData[0]));
1407
1408 bDoVSyncUpdate=TRUE;
1409}
1410
1411////////////////////////////////////////////////////////////////////////
1412// cmd: well, easiest command... not implemented
1413////////////////////////////////////////////////////////////////////////
1414
a96a5eb2 1415static void primNI(unsigned char *bA)
ef79bbde
P
1416{
1417}
1418
1419////////////////////////////////////////////////////////////////////////
1420// cmd func ptr table
1421////////////////////////////////////////////////////////////////////////
1422
1423
1424void (*primTableJ[256])(unsigned char *) =
1425{
1426 // 00
1427 primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
1428 // 08
1429 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1430 // 10
1431 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1432 // 18
1433 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1434 // 20
1435 primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3,
1436 // 28
1437 primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4,
1438 // 30
1439 primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3,
1440 // 38
1441 primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4,
1442 // 40
1443 primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI,
1444 // 48
1445 primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,
1446 // 50
1447 primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI,
1448 // 58
1449 primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,
1450 // 60
1451 primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS,
1452 // 68
1453 primTile1,primTile1,primTile1,primTile1,primNI,primNI,primNI,primNI,
1454 // 70
1455 primTile8,primTile8,primTile8,primTile8,primSprt8,primSprt8,primSprt8,primSprt8,
1456 // 78
1457 primTile16,primTile16,primTile16,primTile16,primSprt16,primSprt16,primSprt16,primSprt16,
1458 // 80
1459 primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1460 // 88
1461 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1462 // 90
1463 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1464 // 98
1465 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1466 // a0
1467 primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1468 // a8
1469 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1470 // b0
1471 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1472 // b8
1473 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1474 // c0
1475 primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1476 // c8
1477 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1478 // d0
1479 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1480 // d8
1481 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1482 // e0
1483 primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
1484 // e8
1485 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1486 // f0
1487 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1488 // f8
1489 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
1490};
1491
1492////////////////////////////////////////////////////////////////////////
1493// cmd func ptr table for skipping
1494////////////////////////////////////////////////////////////////////////
1495
1496void (*primTableSkip[256])(unsigned char *) =
1497{
1498 // 00
1499 primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
1500 // 08
1501 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1502 // 10
1503 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1504 // 18
1505 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1506 // 20
1507 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1508 // 28
1509 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1510 // 30
1511 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1512 // 38
1513 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1514 // 40
1515 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1516 // 48
1517 primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,
1518 // 50
1519 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1520 // 58
1521 primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,
1522 // 60
1523 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1524 // 68
1525 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1526 // 70
1527 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1528 // 78
1529 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1530 // 80
1531 primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1532 // 88
1533 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1534 // 90
1535 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1536 // 98
1537 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1538 // a0
1539 primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1540 // a8
1541 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1542 // b0
1543 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1544 // b8
1545 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1546 // c0
1547 primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1548 // c8
1549 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1550 // d0
1551 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1552 // d8
1553 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1554 // e0
1555 primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
1556 // e8
1557 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1558 // f0
1559 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
1560 // f8
1561 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
1562};