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