dfxvideo: fill sanity check to prevent crashes
[pcsx_rearmed.git] / plugins / dfxvideo / soft.c
CommitLineData
ef79bbde
P
1/***************************************************************************
2 soft.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// switches for painting textured quads as 2 triangles (small glitches, but better shading!)
19// can be toggled by game fix 0x200 in version 1.17 anyway, so let the defines enabled!
ef79bbde
P
20#define POLYQUAD3
21#define POLYQUAD3GT
22
23// fast solid loops... a bit more additional code, of course
ef79bbde
P
24#define FASTSOLID
25
26// psx blending mode 3 with 25% incoming color (instead 50% without the define)
ef79bbde
P
27#define HALFBRIGHTMODE3
28
29// color decode defines
30
31#define XCOL1(x) (x & 0x1f)
32#define XCOL2(x) (x & 0x3e0)
33#define XCOL3(x) (x & 0x7c00)
34
35#define XCOL1D(x) (x & 0x1f)
36#define XCOL2D(x) ((x>>5) & 0x1f)
37#define XCOL3D(x) ((x>>10) & 0x1f)
38
39#define X32TCOL1(x) ((x & 0x001f001f)<<7)
40#define X32TCOL2(x) ((x & 0x03e003e0)<<2)
41#define X32TCOL3(x) ((x & 0x7c007c00)>>3)
42
43#define X32COL1(x) (x & 0x001f001f)
44#define X32COL2(x) ((x>>5) & 0x001f001f)
45#define X32COL3(x) ((x>>10) & 0x001f001f)
46
47#define X32ACOL1(x) (x & 0x001e001e)
48#define X32ACOL2(x) ((x>>5) & 0x001e001e)
49#define X32ACOL3(x) ((x>>10) & 0x001e001e)
50
51#define X32BCOL1(x) (x & 0x001c001c)
52#define X32BCOL2(x) ((x>>5) & 0x001c001c)
53#define X32BCOL3(x) ((x>>10) & 0x001c001c)
54
55#define X32PSXCOL(r,g,b) ((g<<10)|(b<<5)|r)
56
57#define XPSXCOL(r,g,b) ((g&0x7c00)|(b&0x3e0)|(r&0x1f))
58
ef79bbde 59// soft globals
ef79bbde
P
60short g_m1=255,g_m2=255,g_m3=255;
61short DrawSemiTrans=FALSE;
62short Ymin;
63short Ymax;
ef79bbde 64short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3; // global psx vertex coords
a96a5eb2 65int32_t GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP,GlobalTextIL;
ef79bbde
P
66int32_t GlobalTextREST,GlobalTextABR,GlobalTextPAGE;
67
68////////////////////////////////////////////////////////////////////////
69// POLYGON OFFSET FUNCS
70////////////////////////////////////////////////////////////////////////
71
a96a5eb2 72static void offsetPSX2(void)
ef79bbde
P
73{
74 lx0 += PSXDisplay.DrawOffset.x;
75 ly0 += PSXDisplay.DrawOffset.y;
76 lx1 += PSXDisplay.DrawOffset.x;
77 ly1 += PSXDisplay.DrawOffset.y;
78}
79
a96a5eb2 80static void offsetPSX3(void)
ef79bbde
P
81{
82 lx0 += PSXDisplay.DrawOffset.x;
83 ly0 += PSXDisplay.DrawOffset.y;
84 lx1 += PSXDisplay.DrawOffset.x;
85 ly1 += PSXDisplay.DrawOffset.y;
86 lx2 += PSXDisplay.DrawOffset.x;
87 ly2 += PSXDisplay.DrawOffset.y;
88}
89
a96a5eb2 90static void offsetPSX4(void)
ef79bbde
P
91{
92 lx0 += PSXDisplay.DrawOffset.x;
93 ly0 += PSXDisplay.DrawOffset.y;
94 lx1 += PSXDisplay.DrawOffset.x;
95 ly1 += PSXDisplay.DrawOffset.y;
96 lx2 += PSXDisplay.DrawOffset.x;
97 ly2 += PSXDisplay.DrawOffset.y;
98 lx3 += PSXDisplay.DrawOffset.x;
99 ly3 += PSXDisplay.DrawOffset.y;
100}
101
102/////////////////////////////////////////////////////////////////
103/////////////////////////////////////////////////////////////////
104/////////////////////////////////////////////////////////////////
105// PER PIXEL FUNCS
106////////////////////////////////////////////////////////////////////////
107/////////////////////////////////////////////////////////////////
108/////////////////////////////////////////////////////////////////
109
110
111unsigned char dithertable[16] =
112{
113 7, 0, 6, 1,
114 2, 5, 3, 4,
115 1, 6, 0, 7,
116 4, 3, 5, 2
117};
118
a96a5eb2 119static inline void Dither16(unsigned short * pdest,uint32_t r,uint32_t g,uint32_t b,unsigned short sM)
ef79bbde
P
120{
121 unsigned char coeff;
122 unsigned char rlow, glow, blow;
123 int x,y;
124
125 x=pdest-psxVuw;
126 y=x>>10;
127 x-=(y<<10);
128
129 coeff = dithertable[(y&3)*4+(x&3)];
130
131 rlow = r&7; glow = g&7; blow = b&7;
132
133 r>>=3; g>>=3; b>>=3;
134
135 if ((r < 0x1F) && rlow > coeff) r++;
136 if ((g < 0x1F) && glow > coeff) g++;
137 if ((b < 0x1F) && blow > coeff) b++;
138
139 PUTLE16(pdest, ((unsigned short)b<<10) |
140 ((unsigned short)g<<5) |
141 (unsigned short)r | sM);
142}
143
144/////////////////////////////////////////////////////////////////
145/////////////////////////////////////////////////////////////////
146/////////////////////////////////////////////////////////////////
147
a96a5eb2 148static inline void GetShadeTransCol_Dither(unsigned short * pdest, int32_t m1, int32_t m2, int32_t m3)
ef79bbde
P
149{
150 int32_t r,g,b;
151
152 if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
153
154 if(DrawSemiTrans)
155 {
156 r=((XCOL1D(GETLE16(pdest)))<<3);
157 b=((XCOL2D(GETLE16(pdest)))<<3);
158 g=((XCOL3D(GETLE16(pdest)))<<3);
159
160 if(GlobalTextABR==0)
161 {
162 r=(r>>1)+(m1>>1);
163 b=(b>>1)+(m2>>1);
164 g=(g>>1)+(m3>>1);
165 }
166 else
167 if(GlobalTextABR==1)
168 {
169 r+=m1;
170 b+=m2;
171 g+=m3;
172 }
173 else
174 if(GlobalTextABR==2)
175 {
176 r-=m1;
177 b-=m2;
178 g-=m3;
179 if(r&0x80000000) r=0;
180 if(b&0x80000000) b=0;
181 if(g&0x80000000) g=0;
182 }
183 else
184 {
185#ifdef HALFBRIGHTMODE3
186 r+=(m1>>2);
187 b+=(m2>>2);
188 g+=(m3>>2);
189#else
190 r+=(m1>>1);
191 b+=(m2>>1);
192 g+=(m3>>1);
193#endif
194 }
195 }
196 else
197 {
198 r=m1;
199 b=m2;
200 g=m3;
201 }
202
203 if(r&0x7FFFFF00) r=0xff;
204 if(b&0x7FFFFF00) b=0xff;
205 if(g&0x7FFFFF00) g=0xff;
206
207 Dither16(pdest,r,b,g,sSetMask);
208}
209
210////////////////////////////////////////////////////////////////////////
211
a96a5eb2 212static inline void GetShadeTransCol(unsigned short * pdest,unsigned short color)
ef79bbde
P
213{
214 if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
215
216 if(DrawSemiTrans)
217 {
218 int32_t r,g,b;
219
220 if(GlobalTextABR==0)
221 {
222 PUTLE16(pdest, (((GETLE16(pdest)&0x7bde)>>1)+(((color)&0x7bde)>>1))|sSetMask);//0x8000;
223 return;
ef79bbde
P
224 }
225 else
226 if(GlobalTextABR==1)
227 {
228 r=(XCOL1(GETLE16(pdest)))+((XCOL1(color)));
229 b=(XCOL2(GETLE16(pdest)))+((XCOL2(color)));
230 g=(XCOL3(GETLE16(pdest)))+((XCOL3(color)));
231 }
232 else
233 if(GlobalTextABR==2)
234 {
235 r=(XCOL1(GETLE16(pdest)))-((XCOL1(color)));
236 b=(XCOL2(GETLE16(pdest)))-((XCOL2(color)));
237 g=(XCOL3(GETLE16(pdest)))-((XCOL3(color)));
238 if(r&0x80000000) r=0;
239 if(b&0x80000000) b=0;
240 if(g&0x80000000) g=0;
241 }
242 else
243 {
244#ifdef HALFBRIGHTMODE3
245 r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>2);
246 b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>2);
247 g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>2);
248#else
249 r=(XCOL1(GETLE16(pdest)))+((XCOL1(color))>>1);
250 b=(XCOL2(GETLE16(pdest)))+((XCOL2(color))>>1);
251 g=(XCOL3(GETLE16(pdest)))+((XCOL3(color))>>1);
252#endif
253 }
254
255 if(r&0x7FFFFFE0) r=0x1f;
256 if(b&0x7FFFFC00) b=0x3e0;
257 if(g&0x7FFF8000) g=0x7c00;
258
259 PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask);//0x8000;
260 }
261 else PUTLE16(pdest, color|sSetMask);
262}
263
264////////////////////////////////////////////////////////////////////////
265
a96a5eb2 266static inline void GetShadeTransCol32(uint32_t * pdest,uint32_t color)
ef79bbde
P
267{
268 if(DrawSemiTrans)
269 {
270 int32_t r,g,b;
271
272 if(GlobalTextABR==0)
273 {
274 if(!bCheckMask)
275 {
276 PUTLE32(pdest, (((GETLE32(pdest)&0x7bde7bde)>>1)+(((color)&0x7bde7bde)>>1))|lSetMask);//0x80008000;
277 return;
278 }
279 r=(X32ACOL1(GETLE32(pdest))>>1)+((X32ACOL1(color))>>1);
280 b=(X32ACOL2(GETLE32(pdest))>>1)+((X32ACOL2(color))>>1);
281 g=(X32ACOL3(GETLE32(pdest))>>1)+((X32ACOL3(color))>>1);
282 }
283 else
284 if(GlobalTextABR==1)
285 {
286 r=(X32COL1(GETLE32(pdest)))+((X32COL1(color)));
287 b=(X32COL2(GETLE32(pdest)))+((X32COL2(color)));
288 g=(X32COL3(GETLE32(pdest)))+((X32COL3(color)));
289 }
290 else
291 if(GlobalTextABR==2)
292 {
293 int32_t sr,sb,sg,src,sbc,sgc,c;
294 src=XCOL1(color);sbc=XCOL2(color);sgc=XCOL3(color);
295 c=GETLE32(pdest)>>16;
296 sr=(XCOL1(c))-src; if(sr&0x8000) sr=0;
297 sb=(XCOL2(c))-sbc; if(sb&0x8000) sb=0;
298 sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
299 r=((int32_t)sr)<<16;b=((int32_t)sb)<<11;g=((int32_t)sg)<<6;
300 c=LOWORD(GETLE32(pdest));
301 sr=(XCOL1(c))-src; if(sr&0x8000) sr=0;
302 sb=(XCOL2(c))-sbc; if(sb&0x8000) sb=0;
303 sg=(XCOL3(c))-sgc; if(sg&0x8000) sg=0;
304 r|=sr;b|=sb>>5;g|=sg>>10;
305 }
306 else
307 {
308#ifdef HALFBRIGHTMODE3
309 r=(X32COL1(GETLE32(pdest)))+((X32BCOL1(color))>>2);
310 b=(X32COL2(GETLE32(pdest)))+((X32BCOL2(color))>>2);
311 g=(X32COL3(GETLE32(pdest)))+((X32BCOL3(color))>>2);
312#else
313 r=(X32COL1(GETLE32(pdest)))+((X32ACOL1(color))>>1);
314 b=(X32COL2(GETLE32(pdest)))+((X32ACOL2(color))>>1);
315 g=(X32COL3(GETLE32(pdest)))+((X32ACOL3(color))>>1);
316#endif
317 }
318
319 if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
320 if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
321 if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
322 if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
323 if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
324 if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
325
326 if(bCheckMask)
327 {
328 uint32_t ma=GETLE32(pdest);
329 PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
330 if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(*pdest&0xFFFF));
331 if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF) |(*pdest&0xFFFF0000));
332 return;
333 }
334 PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask);//0x80008000;
335 }
336 else
337 {
338 if(bCheckMask)
339 {
340 uint32_t ma=GETLE32(pdest);
341 PUTLE32(pdest, color|lSetMask);//0x80008000;
342 if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
343 if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
344 return;
345 }
346
347 PUTLE32(pdest, color|lSetMask);//0x80008000;
348 }
349}
350
351////////////////////////////////////////////////////////////////////////
352
a96a5eb2 353static inline void GetTextureTransColG(unsigned short * pdest,unsigned short color)
ef79bbde
P
354{
355 int32_t r,g,b;unsigned short l;
356
357 if(color==0) return;
358
359 if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
360
361 l=sSetMask|(color&0x8000);
362
363 if(DrawSemiTrans && (color&0x8000))
364 {
365 if(GlobalTextABR==0)
366 {
367 unsigned short d;
368 d =(GETLE16(pdest)&0x7bde)>>1;
369 color =((color) &0x7bde)>>1;
370 r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
371 b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
372 g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
ef79bbde
P
373 }
374 else
375 if(GlobalTextABR==1)
376 {
377 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
378 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
379 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
380 }
381 else
382 if(GlobalTextABR==2)
383 {
384 r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
385 b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
386 g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
387 if(r&0x80000000) r=0;
388 if(b&0x80000000) b=0;
389 if(g&0x80000000) g=0;
390 }
391 else
392 {
393#ifdef HALFBRIGHTMODE3
394 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
395 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
396 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
397#else
398 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
399 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
400 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
401#endif
402 }
403 }
404 else
405 {
406 r=((XCOL1(color))* g_m1)>>7;
407 b=((XCOL2(color))* g_m2)>>7;
408 g=((XCOL3(color))* g_m3)>>7;
409 }
410
411 if(r&0x7FFFFFE0) r=0x1f;
412 if(b&0x7FFFFC00) b=0x3e0;
413 if(g&0x7FFF8000) g=0x7c00;
414
415 PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
416}
417
418////////////////////////////////////////////////////////////////////////
419
a96a5eb2 420static inline void GetTextureTransColG_S(unsigned short * pdest,unsigned short color)
ef79bbde
P
421{
422 int32_t r,g,b;unsigned short l;
423
424 if(color==0) return;
425
426 l=sSetMask|(color&0x8000);
427
428 r=((XCOL1(color))* g_m1)>>7;
429 b=((XCOL2(color))* g_m2)>>7;
430 g=((XCOL3(color))* g_m3)>>7;
431
432 if(r&0x7FFFFFE0) r=0x1f;
433 if(b&0x7FFFFC00) b=0x3e0;
434 if(g&0x7FFF8000) g=0x7c00;
435
436 PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
437}
438
439////////////////////////////////////////////////////////////////////////
440
a96a5eb2 441static inline void GetTextureTransColG_SPR(unsigned short * pdest,unsigned short color)
ef79bbde
P
442{
443 int32_t r,g,b;unsigned short l;
444
445 if(color==0) return;
446
447 if(bCheckMask && (GETLE16(pdest) & 0x8000)) return;
448
449 l=sSetMask|(color&0x8000);
450
451 if(DrawSemiTrans && (color&0x8000))
452 {
453 if(GlobalTextABR==0)
454 {
455 unsigned short d;
456 d =(GETLE16(pdest)&0x7bde)>>1;
457 color =((color) &0x7bde)>>1;
458 r=(XCOL1(d))+((((XCOL1(color)))* g_m1)>>7);
459 b=(XCOL2(d))+((((XCOL2(color)))* g_m2)>>7);
460 g=(XCOL3(d))+((((XCOL3(color)))* g_m3)>>7);
ef79bbde
P
461 }
462 else
463 if(GlobalTextABR==1)
464 {
465 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* g_m1)>>7);
466 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* g_m2)>>7);
467 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* g_m3)>>7);
468 }
469 else
470 if(GlobalTextABR==2)
471 {
472 r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* g_m1)>>7);
473 b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* g_m2)>>7);
474 g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* g_m3)>>7);
475 if(r&0x80000000) r=0;
476 if(b&0x80000000) b=0;
477 if(g&0x80000000) g=0;
478 }
479 else
480 {
481#ifdef HALFBRIGHTMODE3
482 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* g_m1)>>7);
483 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* g_m2)>>7);
484 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* g_m3)>>7);
485#else
486 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* g_m1)>>7);
487 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* g_m2)>>7);
488 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* g_m3)>>7);
489#endif
490 }
491 }
492 else
493 {
494 r=((XCOL1(color))* g_m1)>>7;
495 b=((XCOL2(color))* g_m2)>>7;
496 g=((XCOL3(color))* g_m3)>>7;
497 }
498
499 if(r&0x7FFFFFE0) r=0x1f;
500 if(b&0x7FFFFC00) b=0x3e0;
501 if(g&0x7FFF8000) g=0x7c00;
502
503 PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
504}
505
506////////////////////////////////////////////////////////////////////////
507
a96a5eb2 508static inline void GetTextureTransColG32(uint32_t * pdest,uint32_t color)
ef79bbde
P
509{
510 int32_t r,g,b,l;
511
512 if(color==0) return;
513
514 l=lSetMask|(color&0x80008000);
515
516 if(DrawSemiTrans && (color&0x80008000))
517 {
518 if(GlobalTextABR==0)
519 {
520 r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
521 b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
522 g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
523 }
524 else
525 if(GlobalTextABR==1)
526 {
527 r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
528 b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
529 g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
530 }
531 else
532 if(GlobalTextABR==2)
533 {
534 int32_t t;
535 r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
536 t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
537 r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
538 r|=t;
539
540 b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
541 t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
542 b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
543 b|=t;
544
545 g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
546 t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
547 g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
548 g|=t;
549 }
550 else
551 {
552#ifdef HALFBRIGHTMODE3
553 r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
554 b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
555 g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
556#else
557 r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
558 b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
559 g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
560#endif
561 }
562
563 if(!(color&0x8000))
564 {
565 r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
566 b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
567 g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
568 }
569 if(!(color&0x80000000))
570 {
571 r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
572 b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
573 g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
574 }
575
576 }
577 else
578 {
579 r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
580 b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
581 g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
582 }
583
584 if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
585 if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
586 if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
587 if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
588 if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
589 if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
590
591 if(bCheckMask)
592 {
593 uint32_t ma=GETLE32(pdest);
594
595 PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
596
597 if((color&0xffff)==0 ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
598 if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
599 if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
600 if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
601
602 return;
603 }
604 if((color&0xffff)==0 ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|l)&0xffff0000));return;}
605 if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|l)&0xffff));return;}
606
607 PUTLE32(pdest, (X32PSXCOL(r,g,b))|l);
608}
609
610////////////////////////////////////////////////////////////////////////
611
a96a5eb2 612static inline void GetTextureTransColG32_S(uint32_t * pdest,uint32_t color)
ef79bbde
P
613{
614 int32_t r,g,b;
615
616 if(color==0) return;
617
618 r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
619 b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
620 g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
621
622 if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
623 if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
624 if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
625 if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
626 if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
627 if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
628
629 if((color&0xffff)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
630 if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
631
632 PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
633}
634
635////////////////////////////////////////////////////////////////////////
636
a96a5eb2 637static inline void GetTextureTransColG32_SPR(uint32_t * pdest,uint32_t color)
ef79bbde
P
638{
639 int32_t r,g,b;
640
641 if(color==0) return;
642
643 if(DrawSemiTrans && (color&0x80008000))
644 {
645 if(GlobalTextABR==0)
646 {
647 r=((((X32TCOL1(GETLE32(pdest)))+((X32COL1(color)) * g_m1))&0xFF00FF00)>>8);
648 b=((((X32TCOL2(GETLE32(pdest)))+((X32COL2(color)) * g_m2))&0xFF00FF00)>>8);
649 g=((((X32TCOL3(GETLE32(pdest)))+((X32COL3(color)) * g_m3))&0xFF00FF00)>>8);
650 }
651 else
652 if(GlobalTextABR==1)
653 {
654 r=(X32COL1(GETLE32(pdest)))+(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
655 b=(X32COL2(GETLE32(pdest)))+(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
656 g=(X32COL3(GETLE32(pdest)))+(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
657 }
658 else
659 if(GlobalTextABR==2)
660 {
661 int32_t t;
662 r=(((((X32COL1(color)))* g_m1)&0xFF80FF80)>>7);
663 t=(GETLE32(pdest)&0x001f0000)-(r&0x003f0000); if(t&0x80000000) t=0;
664 r=(GETLE32(pdest)&0x0000001f)-(r&0x0000003f); if(r&0x80000000) r=0;
665 r|=t;
666
667 b=(((((X32COL2(color)))* g_m2)&0xFF80FF80)>>7);
668 t=((GETLE32(pdest)>>5)&0x001f0000)-(b&0x003f0000); if(t&0x80000000) t=0;
669 b=((GETLE32(pdest)>>5)&0x0000001f)-(b&0x0000003f); if(b&0x80000000) b=0;
670 b|=t;
671
672 g=(((((X32COL3(color)))* g_m3)&0xFF80FF80)>>7);
673 t=((GETLE32(pdest)>>10)&0x001f0000)-(g&0x003f0000); if(t&0x80000000) t=0;
674 g=((GETLE32(pdest)>>10)&0x0000001f)-(g&0x0000003f); if(g&0x80000000) g=0;
675 g|=t;
676 }
677 else
678 {
679#ifdef HALFBRIGHTMODE3
680 r=(X32COL1(GETLE32(pdest)))+(((((X32BCOL1(color))>>2)* g_m1)&0xFF80FF80)>>7);
681 b=(X32COL2(GETLE32(pdest)))+(((((X32BCOL2(color))>>2)* g_m2)&0xFF80FF80)>>7);
682 g=(X32COL3(GETLE32(pdest)))+(((((X32BCOL3(color))>>2)* g_m3)&0xFF80FF80)>>7);
683#else
684 r=(X32COL1(GETLE32(pdest)))+(((((X32ACOL1(color))>>1)* g_m1)&0xFF80FF80)>>7);
685 b=(X32COL2(GETLE32(pdest)))+(((((X32ACOL2(color))>>1)* g_m2)&0xFF80FF80)>>7);
686 g=(X32COL3(GETLE32(pdest)))+(((((X32ACOL3(color))>>1)* g_m3)&0xFF80FF80)>>7);
687#endif
688 }
689
690 if(!(color&0x8000))
691 {
692 r=(r&0xffff0000)|((((X32COL1(color))* g_m1)&0x0000FF80)>>7);
693 b=(b&0xffff0000)|((((X32COL2(color))* g_m2)&0x0000FF80)>>7);
694 g=(g&0xffff0000)|((((X32COL3(color))* g_m3)&0x0000FF80)>>7);
695 }
696 if(!(color&0x80000000))
697 {
698 r=(r&0xffff)|((((X32COL1(color))* g_m1)&0xFF800000)>>7);
699 b=(b&0xffff)|((((X32COL2(color))* g_m2)&0xFF800000)>>7);
700 g=(g&0xffff)|((((X32COL3(color))* g_m3)&0xFF800000)>>7);
701 }
702
703 }
704 else
705 {
706 r=(((X32COL1(color))* g_m1)&0xFF80FF80)>>7;
707 b=(((X32COL2(color))* g_m2)&0xFF80FF80)>>7;
708 g=(((X32COL3(color))* g_m3)&0xFF80FF80)>>7;
709 }
710
711 if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
712 if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
713 if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
714 if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
715 if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
716 if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
717
718 if(bCheckMask)
719 {
720 uint32_t ma=GETLE32(pdest);
721
722 PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
723
724 if((color&0xffff)==0 ) PUTLE32(pdest, (ma&0xffff)|(GETLE32(pdest)&0xffff0000));
725 if((color&0xffff0000)==0) PUTLE32(pdest, (ma&0xffff0000)|(GETLE32(pdest)&0xffff));
726 if(ma&0x80000000) PUTLE32(pdest, (ma&0xFFFF0000)|(GETLE32(pdest)&0xFFFF));
727 if(ma&0x00008000) PUTLE32(pdest, (ma&0xFFFF) |(GETLE32(pdest)&0xFFFF0000));
728
729 return;
730 }
731 if((color&0xffff)==0 ) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
732 if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
733
734 PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
735}
736
737////////////////////////////////////////////////////////////////////////
738
a96a5eb2 739static inline void GetTextureTransColGX_Dither(unsigned short * pdest,unsigned short color,int32_t m1,int32_t m2,int32_t m3)
ef79bbde
P
740{
741 int32_t r,g,b;
742
743 if(color==0) return;
744
745 if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
746
747 m1=(((XCOL1D(color)))*m1)>>4;
748 m2=(((XCOL2D(color)))*m2)>>4;
749 m3=(((XCOL3D(color)))*m3)>>4;
750
751 if(DrawSemiTrans && (color&0x8000))
752 {
753 r=((XCOL1D(GETLE16(pdest)))<<3);
754 b=((XCOL2D(GETLE16(pdest)))<<3);
755 g=((XCOL3D(GETLE16(pdest)))<<3);
756
757 if(GlobalTextABR==0)
758 {
759 r=(r>>1)+(m1>>1);
760 b=(b>>1)+(m2>>1);
761 g=(g>>1)+(m3>>1);
762 }
763 else
764 if(GlobalTextABR==1)
765 {
766 r+=m1;
767 b+=m2;
768 g+=m3;
769 }
770 else
771 if(GlobalTextABR==2)
772 {
773 r-=m1;
774 b-=m2;
775 g-=m3;
776 if(r&0x80000000) r=0;
777 if(b&0x80000000) b=0;
778 if(g&0x80000000) g=0;
779 }
780 else
781 {
782#ifdef HALFBRIGHTMODE3
783 r+=(m1>>2);
784 b+=(m2>>2);
785 g+=(m3>>2);
786#else
787 r+=(m1>>1);
788 b+=(m2>>1);
789 g+=(m3>>1);
790#endif
791 }
792 }
793 else
794 {
795 r=m1;
796 b=m2;
797 g=m3;
798 }
799
800 if(r&0x7FFFFF00) r=0xff;
801 if(b&0x7FFFFF00) b=0xff;
802 if(g&0x7FFFFF00) g=0xff;
803
804 Dither16(pdest,r,b,g,sSetMask|(color&0x8000));
805
806}
807
808////////////////////////////////////////////////////////////////////////
809
a96a5eb2 810static inline void GetTextureTransColGX(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
ef79bbde
P
811{
812 int32_t r,g,b;unsigned short l;
813
814 if(color==0) return;
815
816 if(bCheckMask && (*pdest & HOST2LE16(0x8000))) return;
817
818 l=sSetMask|(color&0x8000);
819
820 if(DrawSemiTrans && (color&0x8000))
821 {
822 if(GlobalTextABR==0)
823 {
824 unsigned short d;
825 d =(GETLE16(pdest)&0x7bde)>>1;
826 color =((color) &0x7bde)>>1;
827 r=(XCOL1(d))+((((XCOL1(color)))* m1)>>7);
828 b=(XCOL2(d))+((((XCOL2(color)))* m2)>>7);
829 g=(XCOL3(d))+((((XCOL3(color)))* m3)>>7);
ef79bbde
P
830 }
831 else
832 if(GlobalTextABR==1)
833 {
834 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color)))* m1)>>7);
835 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color)))* m2)>>7);
836 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color)))* m3)>>7);
837 }
838 else
839 if(GlobalTextABR==2)
840 {
841 r=(XCOL1(GETLE16(pdest)))-((((XCOL1(color)))* m1)>>7);
842 b=(XCOL2(GETLE16(pdest)))-((((XCOL2(color)))* m2)>>7);
843 g=(XCOL3(GETLE16(pdest)))-((((XCOL3(color)))* m3)>>7);
844 if(r&0x80000000) r=0;
845 if(b&0x80000000) b=0;
846 if(g&0x80000000) g=0;
847 }
848 else
849 {
850#ifdef HALFBRIGHTMODE3
851 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>2)* m1)>>7);
852 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>2)* m2)>>7);
853 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>2)* m3)>>7);
854#else
855 r=(XCOL1(GETLE16(pdest)))+((((XCOL1(color))>>1)* m1)>>7);
856 b=(XCOL2(GETLE16(pdest)))+((((XCOL2(color))>>1)* m2)>>7);
857 g=(XCOL3(GETLE16(pdest)))+((((XCOL3(color))>>1)* m3)>>7);
858#endif
859 }
860 }
861 else
862 {
863 r=((XCOL1(color))* m1)>>7;
864 b=((XCOL2(color))* m2)>>7;
865 g=((XCOL3(color))* m3)>>7;
866 }
867
868 if(r&0x7FFFFFE0) r=0x1f;
869 if(b&0x7FFFFC00) b=0x3e0;
870 if(g&0x7FFF8000) g=0x7c00;
871
872 PUTLE16(pdest, (XPSXCOL(r,g,b))|l);
873}
874
875////////////////////////////////////////////////////////////////////////
876
a96a5eb2 877static inline void GetTextureTransColGX_S(unsigned short * pdest,unsigned short color,short m1,short m2,short m3)
ef79bbde
P
878{
879 int32_t r,g,b;
880
881 if(color==0) return;
882
883 r=((XCOL1(color))* m1)>>7;
884 b=((XCOL2(color))* m2)>>7;
885 g=((XCOL3(color))* m3)>>7;
886
887 if(r&0x7FFFFFE0) r=0x1f;
888 if(b&0x7FFFFC00) b=0x3e0;
889 if(g&0x7FFF8000) g=0x7c00;
890
891 PUTLE16(pdest, (XPSXCOL(r,g,b))|sSetMask|(color&0x8000));
892}
893
894////////////////////////////////////////////////////////////////////////
895
a96a5eb2 896static inline void GetTextureTransColGX32_S(uint32_t * pdest,uint32_t color,short m1,short m2,short m3)
ef79bbde
P
897{
898 int32_t r,g,b;
899
900 if(color==0) return;
901
902 r=(((X32COL1(color))* m1)&0xFF80FF80)>>7;
903 b=(((X32COL2(color))* m2)&0xFF80FF80)>>7;
904 g=(((X32COL3(color))* m3)&0xFF80FF80)>>7;
905
906 if(r&0x7FE00000) r=0x1f0000|(r&0xFFFF);
907 if(r&0x7FE0) r=0x1f |(r&0xFFFF0000);
908 if(b&0x7FE00000) b=0x1f0000|(b&0xFFFF);
909 if(b&0x7FE0) b=0x1f |(b&0xFFFF0000);
910 if(g&0x7FE00000) g=0x1f0000|(g&0xFFFF);
911 if(g&0x7FE0) g=0x1f |(g&0xFFFF0000);
912
913 if((color&0xffff)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff0000));return;}
914 if((color&0xffff0000)==0) {PUTLE32(pdest, (GETLE32(pdest)&0xffff0000)|(((X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000))&0xffff));return;}
915
916 PUTLE32(pdest, (X32PSXCOL(r,g,b))|lSetMask|(color&0x80008000));
917}
918
919////////////////////////////////////////////////////////////////////////
920// FILL FUNCS
921////////////////////////////////////////////////////////////////////////
922
a96a5eb2 923static void FillSoftwareAreaTrans(short x0,short y0,short x1, // FILL AREA TRANS
ef79bbde
P
924 short y1,unsigned short col)
925{
926 short j,i,dx,dy;
927
928 if(y0>y1) return;
929 if(x0>x1) return;
930
931 if(x1<drawX) return;
932 if(y1<drawY) return;
933 if(x0>drawW) return;
934 if(y0>drawH) return;
935
936 x1=min(x1,drawW+1);
937 y1=min(y1,drawH+1);
938 x0=max(x0,drawX);
939 y0=max(y0,drawY);
940
a96a5eb2 941 if(y0>=512) return;
ef79bbde
P
942 if(x0>1023) return;
943
a96a5eb2 944 if(y1>512) y1=512;
ef79bbde
P
945 if(x1>1024) x1=1024;
946
947 dx=x1-x0;dy=y1-y0;
948
949 if(dx==1 && dy==1 && x0==1020 && y0==511) // special fix for pinball game... emu protection???
950 {
ef79bbde
P
951 static int iCheat=0;
952 col+=iCheat;
953 if(iCheat==1) iCheat=0; else iCheat=1;
954 }
955
956
957 if(dx&1) // slow fill
958 {
959 unsigned short *DSTPtr;
960 unsigned short LineOffset;
961 DSTPtr = psxVuw + (1024*y0) + x0;
962 LineOffset = 1024 - dx;
963 for(i=0;i<dy;i++)
964 {
965 for(j=0;j<dx;j++)
966 GetShadeTransCol(DSTPtr++,col);
967 DSTPtr += LineOffset;
968 }
969 }
970 else // fast fill
971 {
972 uint32_t *DSTPtr;
973 unsigned short LineOffset;
974 uint32_t lcol=lSetMask|(((uint32_t)(col))<<16)|col;
975 dx>>=1;
976 DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
977 LineOffset = 512 - dx;
978
979 if(!bCheckMask && !DrawSemiTrans)
980 {
981 for(i=0;i<dy;i++)
982 {
983 for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
984 DSTPtr += LineOffset;
985 }
986 }
987 else
988 {
989 for(i=0;i<dy;i++)
990 {
991 for(j=0;j<dx;j++)
992 GetShadeTransCol32(DSTPtr++,lcol);
993 DSTPtr += LineOffset;
994 }
995 }
996 }
997}
998
999////////////////////////////////////////////////////////////////////////
1000
a96a5eb2 1001static void FillSoftwareArea(short x0,short y0,short x1, // FILL AREA (BLK FILL)
ef79bbde
P
1002 short y1,unsigned short col) // no draw area check here!
1003{
1004 short j,i,dx,dy;
1005
da1a56d5 1006 // ?? ff9 pal hooligan crack sets nonsense x0
1007 if(x0<0) x0=0;
1008 if(y0<0) y0=0;
1009
ef79bbde
P
1010 if(y0>y1) return;
1011 if(x0>x1) return;
1012
a96a5eb2 1013 if(y0>=512) return;
ef79bbde
P
1014 if(x0>1023) return;
1015
a96a5eb2 1016 if(y1>512) y1=512;
ef79bbde
P
1017 if(x1>1024) x1=1024;
1018
1019 dx=x1-x0;dy=y1-y0;
1020 if(dx&1)
1021 {
1022 unsigned short *DSTPtr;
1023 unsigned short LineOffset;
1024
1025 DSTPtr = psxVuw + (1024*y0) + x0;
1026 LineOffset = 1024 - dx;
1027
1028 for(i=0;i<dy;i++)
1029 {
1030 for(j=0;j<dx;j++) { PUTLE16(DSTPtr, col); DSTPtr++; }
1031 DSTPtr += LineOffset;
1032 }
1033 }
1034 else
1035 {
1036 uint32_t *DSTPtr;
1037 unsigned short LineOffset;
1038 uint32_t lcol=(((int32_t)col)<<16)|col;
1039 dx>>=1;
1040 DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
1041 LineOffset = 512 - dx;
1042
1043 for(i=0;i<dy;i++)
1044 {
1045 for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
1046 DSTPtr += LineOffset;
1047 }
1048 }
1049}
1050
1051////////////////////////////////////////////////////////////////////////
1052////////////////////////////////////////////////////////////////////////
1053////////////////////////////////////////////////////////////////////////
1054// EDGE INTERPOLATION
1055////////////////////////////////////////////////////////////////////////
1056////////////////////////////////////////////////////////////////////////
1057////////////////////////////////////////////////////////////////////////
1058
1059typedef struct SOFTVTAG
1060{
1061 int x,y;
1062 int u,v;
1063 int32_t R,G,B;
1064} soft_vertex;
1065
1066static soft_vertex vtx[4];
1067static soft_vertex * left_array[4], * right_array[4];
1068static int left_section, right_section;
1069static int left_section_height, right_section_height;
1070static int left_x, delta_left_x, right_x, delta_right_x;
1071static int left_u, delta_left_u, left_v, delta_left_v;
1072static int right_u, delta_right_u, right_v, delta_right_v;
1073static int left_R, delta_left_R, right_R, delta_right_R;
1074static int left_G, delta_left_G, right_G, delta_right_G;
1075static int left_B, delta_left_B, right_B, delta_right_B;
1076
a96a5eb2 1077// USE_NASM
1078static inline int shl10idiv(int x, int y)
ef79bbde
P
1079{
1080 __int64 bi=x;
1081 bi<<=10;
1082 return bi/y;
1083}
1084
ef79bbde
P
1085////////////////////////////////////////////////////////////////////////
1086////////////////////////////////////////////////////////////////////////
1087////////////////////////////////////////////////////////////////////////
1088
a96a5eb2 1089static inline int RightSection_F(void)
ef79bbde
P
1090{
1091 soft_vertex * v1 = right_array[ right_section ];
1092 soft_vertex * v2 = right_array[ right_section-1 ];
1093
1094 int height = v2->y - v1->y;
1095 if(height == 0) return 0;
1096 delta_right_x = (v2->x - v1->x) / height;
1097 right_x = v1->x;
1098
1099 right_section_height = height;
1100 return height;
1101}
1102
1103////////////////////////////////////////////////////////////////////////
1104
a96a5eb2 1105static inline int LeftSection_F(void)
ef79bbde
P
1106{
1107 soft_vertex * v1 = left_array[ left_section ];
1108 soft_vertex * v2 = left_array[ left_section-1 ];
1109
1110 int height = v2->y - v1->y;
1111 if(height == 0) return 0;
1112 delta_left_x = (v2->x - v1->x) / height;
1113 left_x = v1->x;
1114
1115 left_section_height = height;
1116 return height;
1117}
1118
1119////////////////////////////////////////////////////////////////////////
1120
a96a5eb2 1121static inline BOOL NextRow_F(void)
ef79bbde
P
1122{
1123 if(--left_section_height<=0)
1124 {
1125 if(--left_section <= 0) {return TRUE;}
1126 if(LeftSection_F() <= 0) {return TRUE;}
1127 }
1128 else
1129 {
1130 left_x += delta_left_x;
1131 }
1132
1133 if(--right_section_height<=0)
1134 {
1135 if(--right_section<=0) {return TRUE;}
1136 if(RightSection_F() <=0) {return TRUE;}
1137 }
1138 else
1139 {
1140 right_x += delta_right_x;
1141 }
1142 return FALSE;
1143}
1144
1145////////////////////////////////////////////////////////////////////////
1146
a96a5eb2 1147static inline BOOL SetupSections_F(short x1, short y1, short x2, short y2, short x3, short y3)
ef79bbde
P
1148{
1149 soft_vertex * v1, * v2, * v3;
1150 int height,longest;
1151
1152 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1153 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1154 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1155
1156 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1157 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1158 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1159
1160 height = v3->y - v1->y;
1161 if(height == 0) {return FALSE;}
1162 longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1163 if(longest == 0) {return FALSE;}
1164
1165 if(longest < 0)
1166 {
1167 right_array[0] = v3;
1168 right_array[1] = v2;
1169 right_array[2] = v1;
1170 right_section = 2;
1171 left_array[0] = v3;
1172 left_array[1] = v1;
1173 left_section = 1;
1174
1175 if(LeftSection_F() <= 0) return FALSE;
1176 if(RightSection_F() <= 0)
1177 {
1178 right_section--;
1179 if(RightSection_F() <= 0) return FALSE;
1180 }
1181 }
1182 else
1183 {
1184 left_array[0] = v3;
1185 left_array[1] = v2;
1186 left_array[2] = v1;
1187 left_section = 2;
1188 right_array[0] = v3;
1189 right_array[1] = v1;
1190 right_section = 1;
1191
1192 if(RightSection_F() <= 0) return FALSE;
1193 if(LeftSection_F() <= 0)
1194 {
1195 left_section--;
1196 if(LeftSection_F() <= 0) return FALSE;
1197 }
1198 }
1199
1200 Ymin=v1->y;
1201 Ymax=min(v3->y-1,drawH);
1202
1203 return TRUE;
1204}
1205
1206////////////////////////////////////////////////////////////////////////
1207////////////////////////////////////////////////////////////////////////
1208
a96a5eb2 1209static inline int RightSection_G(void)
ef79bbde
P
1210{
1211 soft_vertex * v1 = right_array[ right_section ];
1212 soft_vertex * v2 = right_array[ right_section-1 ];
1213
1214 int height = v2->y - v1->y;
1215 if(height == 0) return 0;
1216 delta_right_x = (v2->x - v1->x) / height;
1217 right_x = v1->x;
1218
1219 right_section_height = height;
1220 return height;
1221}
1222
1223////////////////////////////////////////////////////////////////////////
1224
a96a5eb2 1225static inline int LeftSection_G(void)
ef79bbde
P
1226{
1227 soft_vertex * v1 = left_array[ left_section ];
1228 soft_vertex * v2 = left_array[ left_section-1 ];
1229
1230 int height = v2->y - v1->y;
1231 if(height == 0) return 0;
1232 delta_left_x = (v2->x - v1->x) / height;
1233 left_x = v1->x;
1234
1235 delta_left_R = ((v2->R - v1->R)) / height;
1236 left_R = v1->R;
1237 delta_left_G = ((v2->G - v1->G)) / height;
1238 left_G = v1->G;
1239 delta_left_B = ((v2->B - v1->B)) / height;
1240 left_B = v1->B;
1241
1242 left_section_height = height;
1243 return height;
1244}
1245
1246////////////////////////////////////////////////////////////////////////
1247
a96a5eb2 1248static inline BOOL NextRow_G(void)
ef79bbde
P
1249{
1250 if(--left_section_height<=0)
1251 {
1252 if(--left_section <= 0) {return TRUE;}
1253 if(LeftSection_G() <= 0) {return TRUE;}
1254 }
1255 else
1256 {
1257 left_x += delta_left_x;
1258 left_R += delta_left_R;
1259 left_G += delta_left_G;
1260 left_B += delta_left_B;
1261 }
1262
1263 if(--right_section_height<=0)
1264 {
1265 if(--right_section<=0) {return TRUE;}
1266 if(RightSection_G() <=0) {return TRUE;}
1267 }
1268 else
1269 {
1270 right_x += delta_right_x;
1271 }
1272 return FALSE;
1273}
1274
1275////////////////////////////////////////////////////////////////////////
1276
a96a5eb2 1277static inline BOOL SetupSections_G(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb1, int32_t rgb2, int32_t rgb3)
ef79bbde
P
1278{
1279 soft_vertex * v1, * v2, * v3;
1280 int height,longest,temp;
1281
1282 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1283 v1->R=(rgb1) & 0x00ff0000;
1284 v1->G=(rgb1<<8) & 0x00ff0000;
1285 v1->B=(rgb1<<16) & 0x00ff0000;
1286 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1287 v2->R=(rgb2) & 0x00ff0000;
1288 v2->G=(rgb2<<8) & 0x00ff0000;
1289 v2->B=(rgb2<<16) & 0x00ff0000;
1290 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1291 v3->R=(rgb3) & 0x00ff0000;
1292 v3->G=(rgb3<<8) & 0x00ff0000;
1293 v3->B=(rgb3<<16) & 0x00ff0000;
1294
1295 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1296 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1297 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1298
1299 height = v3->y - v1->y;
1300 if(height == 0) {return FALSE;}
1301 temp=(((v2->y - v1->y) << 16) / height);
1302 longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1303 if(longest == 0) {return FALSE;}
1304
1305 if(longest < 0)
1306 {
1307 right_array[0] = v3;
1308 right_array[1] = v2;
1309 right_array[2] = v1;
1310 right_section = 2;
1311 left_array[0] = v3;
1312 left_array[1] = v1;
1313 left_section = 1;
1314
1315 if(LeftSection_G() <= 0) return FALSE;
1316 if(RightSection_G() <= 0)
1317 {
1318 right_section--;
1319 if(RightSection_G() <= 0) return FALSE;
1320 }
1321 if(longest > -0x1000) longest = -0x1000;
1322 }
1323 else
1324 {
1325 left_array[0] = v3;
1326 left_array[1] = v2;
1327 left_array[2] = v1;
1328 left_section = 2;
1329 right_array[0] = v3;
1330 right_array[1] = v1;
1331 right_section = 1;
1332
1333 if(RightSection_G() <= 0) return FALSE;
1334 if(LeftSection_G() <= 0)
1335 {
1336 left_section--;
1337 if(LeftSection_G() <= 0) return FALSE;
1338 }
1339 if(longest < 0x1000) longest = 0x1000;
1340 }
1341
1342 Ymin=v1->y;
1343 Ymax=min(v3->y-1,drawH);
1344
1345 delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1346 delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1347 delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1348
1349 return TRUE;
1350}
1351
1352////////////////////////////////////////////////////////////////////////
1353////////////////////////////////////////////////////////////////////////
1354
a96a5eb2 1355static inline int RightSection_FT(void)
ef79bbde
P
1356{
1357 soft_vertex * v1 = right_array[ right_section ];
1358 soft_vertex * v2 = right_array[ right_section-1 ];
1359
1360 int height = v2->y - v1->y;
1361 if(height == 0) return 0;
1362 delta_right_x = (v2->x - v1->x) / height;
1363 right_x = v1->x;
1364
1365 right_section_height = height;
1366 return height;
1367}
1368
1369////////////////////////////////////////////////////////////////////////
1370
a96a5eb2 1371static inline int LeftSection_FT(void)
ef79bbde
P
1372{
1373 soft_vertex * v1 = left_array[ left_section ];
1374 soft_vertex * v2 = left_array[ left_section-1 ];
1375
1376 int height = v2->y - v1->y;
1377 if(height == 0) return 0;
1378 delta_left_x = (v2->x - v1->x) / height;
1379 left_x = v1->x;
1380
1381 delta_left_u = ((v2->u - v1->u)) / height;
1382 left_u = v1->u;
1383 delta_left_v = ((v2->v - v1->v)) / height;
1384 left_v = v1->v;
1385
1386 left_section_height = height;
1387 return height;
1388}
1389
1390////////////////////////////////////////////////////////////////////////
1391
a96a5eb2 1392static inline BOOL NextRow_FT(void)
ef79bbde
P
1393{
1394 if(--left_section_height<=0)
1395 {
1396 if(--left_section <= 0) {return TRUE;}
1397 if(LeftSection_FT() <= 0) {return TRUE;}
1398 }
1399 else
1400 {
1401 left_x += delta_left_x;
1402 left_u += delta_left_u;
1403 left_v += delta_left_v;
1404 }
1405
1406 if(--right_section_height<=0)
1407 {
1408 if(--right_section<=0) {return TRUE;}
1409 if(RightSection_FT() <=0) {return TRUE;}
1410 }
1411 else
1412 {
1413 right_x += delta_right_x;
1414 }
1415 return FALSE;
1416}
1417
1418////////////////////////////////////////////////////////////////////////
1419
a96a5eb2 1420static inline BOOL SetupSections_FT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3)
ef79bbde
P
1421{
1422 soft_vertex * v1, * v2, * v3;
1423 int height,longest,temp;
1424
1425 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1426 v1->u=tx1<<16;v1->v=ty1<<16;
1427 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1428 v2->u=tx2<<16;v2->v=ty2<<16;
1429 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1430 v3->u=tx3<<16;v3->v=ty3<<16;
1431
1432 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1433 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1434 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1435
1436 height = v3->y - v1->y;
1437 if(height == 0) {return FALSE;}
1438
1439 temp=(((v2->y - v1->y) << 16) / height);
1440 longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1441
1442 if(longest == 0) {return FALSE;}
1443
1444 if(longest < 0)
1445 {
1446 right_array[0] = v3;
1447 right_array[1] = v2;
1448 right_array[2] = v1;
1449 right_section = 2;
1450 left_array[0] = v3;
1451 left_array[1] = v1;
1452 left_section = 1;
1453
1454 if(LeftSection_FT() <= 0) return FALSE;
1455 if(RightSection_FT() <= 0)
1456 {
1457 right_section--;
1458 if(RightSection_FT() <= 0) return FALSE;
1459 }
1460 if(longest > -0x1000) longest = -0x1000;
1461 }
1462 else
1463 {
1464 left_array[0] = v3;
1465 left_array[1] = v2;
1466 left_array[2] = v1;
1467 left_section = 2;
1468 right_array[0] = v3;
1469 right_array[1] = v1;
1470 right_section = 1;
1471
1472 if(RightSection_FT() <= 0) return FALSE;
1473 if(LeftSection_FT() <= 0)
1474 {
1475 left_section--;
1476 if(LeftSection_FT() <= 0) return FALSE;
1477 }
1478 if(longest < 0x1000) longest = 0x1000;
1479 }
1480
1481 Ymin=v1->y;
1482 Ymax=min(v3->y-1,drawH);
1483
1484 delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1485 delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1486
ef79bbde
P
1487 return TRUE;
1488}
1489
1490////////////////////////////////////////////////////////////////////////
1491////////////////////////////////////////////////////////////////////////
1492
a96a5eb2 1493static inline int RightSection_GT(void)
ef79bbde
P
1494{
1495 soft_vertex * v1 = right_array[ right_section ];
1496 soft_vertex * v2 = right_array[ right_section-1 ];
1497
1498 int height = v2->y - v1->y;
1499 if(height == 0) return 0;
1500 delta_right_x = (v2->x - v1->x) / height;
1501 right_x = v1->x;
1502
1503 right_section_height = height;
1504 return height;
1505}
1506
1507////////////////////////////////////////////////////////////////////////
1508
a96a5eb2 1509static inline int LeftSection_GT(void)
ef79bbde
P
1510{
1511 soft_vertex * v1 = left_array[ left_section ];
1512 soft_vertex * v2 = left_array[ left_section-1 ];
1513
1514 int height = v2->y - v1->y;
1515 if(height == 0) return 0;
1516 delta_left_x = (v2->x - v1->x) / height;
1517 left_x = v1->x;
1518
1519 delta_left_u = ((v2->u - v1->u)) / height;
1520 left_u = v1->u;
1521 delta_left_v = ((v2->v - v1->v)) / height;
1522 left_v = v1->v;
1523
1524 delta_left_R = ((v2->R - v1->R)) / height;
1525 left_R = v1->R;
1526 delta_left_G = ((v2->G - v1->G)) / height;
1527 left_G = v1->G;
1528 delta_left_B = ((v2->B - v1->B)) / height;
1529 left_B = v1->B;
1530
1531 left_section_height = height;
1532 return height;
1533}
1534
1535////////////////////////////////////////////////////////////////////////
1536
a96a5eb2 1537static inline BOOL NextRow_GT(void)
ef79bbde
P
1538{
1539 if(--left_section_height<=0)
1540 {
1541 if(--left_section <= 0) {return TRUE;}
1542 if(LeftSection_GT() <= 0) {return TRUE;}
1543 }
1544 else
1545 {
1546 left_x += delta_left_x;
1547 left_u += delta_left_u;
1548 left_v += delta_left_v;
1549 left_R += delta_left_R;
1550 left_G += delta_left_G;
1551 left_B += delta_left_B;
1552 }
1553
1554 if(--right_section_height<=0)
1555 {
1556 if(--right_section<=0) {return TRUE;}
1557 if(RightSection_GT() <=0) {return TRUE;}
1558 }
1559 else
1560 {
1561 right_x += delta_right_x;
1562 }
1563 return FALSE;
1564}
1565
1566////////////////////////////////////////////////////////////////////////
1567
a96a5eb2 1568static inline BOOL SetupSections_GT(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, int32_t rgb1, int32_t rgb2, int32_t rgb3)
ef79bbde
P
1569{
1570 soft_vertex * v1, * v2, * v3;
1571 int height,longest,temp;
1572
1573 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1574 v1->u=tx1<<16;v1->v=ty1<<16;
1575 v1->R=(rgb1) & 0x00ff0000;
1576 v1->G=(rgb1<<8) & 0x00ff0000;
1577 v1->B=(rgb1<<16) & 0x00ff0000;
1578
1579 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1580 v2->u=tx2<<16;v2->v=ty2<<16;
1581 v2->R=(rgb2) & 0x00ff0000;
1582 v2->G=(rgb2<<8) & 0x00ff0000;
1583 v2->B=(rgb2<<16) & 0x00ff0000;
1584
1585 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1586 v3->u=tx3<<16;v3->v=ty3<<16;
1587 v3->R=(rgb3) & 0x00ff0000;
1588 v3->G=(rgb3<<8) & 0x00ff0000;
1589 v3->B=(rgb3<<16) & 0x00ff0000;
1590
1591 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1592 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1593 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1594
1595 height = v3->y - v1->y;
1596 if(height == 0) {return FALSE;}
1597
1598 temp=(((v2->y - v1->y) << 16) / height);
1599 longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1600
1601 if(longest == 0) {return FALSE;}
1602
1603 if(longest < 0)
1604 {
1605 right_array[0] = v3;
1606 right_array[1] = v2;
1607 right_array[2] = v1;
1608 right_section = 2;
1609 left_array[0] = v3;
1610 left_array[1] = v1;
1611 left_section = 1;
1612
1613 if(LeftSection_GT() <= 0) return FALSE;
1614 if(RightSection_GT() <= 0)
1615 {
1616 right_section--;
1617 if(RightSection_GT() <= 0) return FALSE;
1618 }
1619
1620 if(longest > -0x1000) longest = -0x1000;
1621 }
1622 else
1623 {
1624 left_array[0] = v3;
1625 left_array[1] = v2;
1626 left_array[2] = v1;
1627 left_section = 2;
1628 right_array[0] = v3;
1629 right_array[1] = v1;
1630 right_section = 1;
1631
1632 if(RightSection_GT() <= 0) return FALSE;
1633 if(LeftSection_GT() <= 0)
1634 {
1635 left_section--;
1636 if(LeftSection_GT() <= 0) return FALSE;
1637 }
1638 if(longest < 0x1000) longest = 0x1000;
1639 }
1640
1641 Ymin=v1->y;
1642 Ymax=min(v3->y-1,drawH);
1643
1644 delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1645 delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1646 delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1647
1648 delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1649 delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1650
ef79bbde
P
1651 return TRUE;
1652}
1653
1654////////////////////////////////////////////////////////////////////////
1655////////////////////////////////////////////////////////////////////////
1656
a96a5eb2 1657static inline int RightSection_F4(void)
ef79bbde
P
1658{
1659 soft_vertex * v1 = right_array[ right_section ];
1660 soft_vertex * v2 = right_array[ right_section-1 ];
1661
1662 int height = v2->y - v1->y;
1663 right_section_height = height;
1664 right_x = v1->x;
1665 if(height == 0)
1666 {
1667 return 0;
1668 }
1669 delta_right_x = (v2->x - v1->x) / height;
1670
1671 return height;
1672}
1673
1674////////////////////////////////////////////////////////////////////////
1675
a96a5eb2 1676static inline int LeftSection_F4(void)
ef79bbde
P
1677{
1678 soft_vertex * v1 = left_array[ left_section ];
1679 soft_vertex * v2 = left_array[ left_section-1 ];
1680
1681 int height = v2->y - v1->y;
1682 left_section_height = height;
1683 left_x = v1->x;
1684 if(height == 0)
1685 {
1686 return 0;
1687 }
1688 delta_left_x = (v2->x - v1->x) / height;
1689
1690 return height;
1691}
1692
1693////////////////////////////////////////////////////////////////////////
1694
a96a5eb2 1695static inline BOOL NextRow_F4(void)
ef79bbde
P
1696{
1697 if(--left_section_height<=0)
1698 {
1699 if(--left_section > 0)
1700 while(LeftSection_F4()<=0)
1701 {
1702 if(--left_section <= 0) break;
1703 }
1704 }
1705 else
1706 {
1707 left_x += delta_left_x;
1708 }
1709
1710 if(--right_section_height<=0)
1711 {
1712 if(--right_section > 0)
1713 while(RightSection_F4()<=0)
1714 {
1715 if(--right_section<=0) break;
1716 }
1717 }
1718 else
1719 {
1720 right_x += delta_right_x;
1721 }
1722 return FALSE;
1723}
1724
1725////////////////////////////////////////////////////////////////////////
1726
a96a5eb2 1727static inline BOOL SetupSections_F4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4)
ef79bbde
P
1728{
1729 soft_vertex * v1, * v2, * v3, * v4;
1730 int height,width,longest1,longest2;
1731
1732 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1733 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1734 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1735 v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1736
1737 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1738 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1739 if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1740 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1741 if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1742 if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1743
1744 height = v4->y - v1->y; if(height == 0) height =1;
1745 width = (v4->x - v1->x)>>16;
1746 longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1747 longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1748
1749 if(longest1 < 0) // 2 is right
1750 {
1751 if(longest2 < 0) // 3 is right
1752 {
1753 left_array[0] = v4;
1754 left_array[1] = v1;
1755 left_section = 1;
1756
1757 height = v3->y - v1->y; if(height == 0) height=1;
1758 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1759 if(longest1 >= 0)
1760 {
1761 right_array[0] = v4; // 1
1762 right_array[1] = v3; // 3
1763 right_array[2] = v1; // 4
1764 right_section = 2;
1765 }
1766 else
1767 {
1768 height = v4->y - v2->y; if(height == 0) height=1;
1769 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1770 if(longest1 >= 0)
1771 {
1772 right_array[0] = v4; // 1
1773 right_array[1] = v2; // 2
1774 right_array[2] = v1; // 4
1775 right_section = 2;
1776 }
1777 else
1778 {
1779 right_array[0] = v4; // 1
1780 right_array[1] = v3; // 2
1781 right_array[2] = v2; // 3
1782 right_array[3] = v1; // 4
1783 right_section = 3;
1784 }
1785 }
1786 }
1787 else
1788 {
1789 left_array[0] = v4;
1790 left_array[1] = v3; // 1
1791 left_array[2] = v1; // 2
1792 left_section = 2; // 3
1793 right_array[0] = v4; // 4
1794 right_array[1] = v2;
1795 right_array[2] = v1;
1796 right_section = 2;
1797 }
1798 }
1799 else
1800 {
1801 if(longest2 < 0)
1802 {
1803 left_array[0] = v4; // 1
1804 left_array[1] = v2; // 2
1805 left_array[2] = v1; // 3
1806 left_section = 2; // 4
1807 right_array[0] = v4;
1808 right_array[1] = v3;
1809 right_array[2] = v1;
1810 right_section = 2;
1811 }
1812 else
1813 {
1814 right_array[0] = v4;
1815 right_array[1] = v1;
1816 right_section = 1;
1817
1818 height = v3->y - v1->y; if(height == 0) height=1;
1819 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1820 if(longest1<0)
1821 {
1822 left_array[0] = v4; // 1
1823 left_array[1] = v3; // 3
1824 left_array[2] = v1; // 4
1825 left_section = 2;
1826 }
1827 else
1828 {
1829 height = v4->y - v2->y; if(height == 0) height=1;
1830 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1831 if(longest1<0)
1832 {
1833 left_array[0] = v4; // 1
1834 left_array[1] = v2; // 2
1835 left_array[2] = v1; // 4
1836 left_section = 2;
1837 }
1838 else
1839 {
1840 left_array[0] = v4; // 1
1841 left_array[1] = v3; // 2
1842 left_array[2] = v2; // 3
1843 left_array[3] = v1; // 4
1844 left_section = 3;
1845 }
1846 }
1847 }
1848 }
1849
1850 while(LeftSection_F4()<=0)
1851 {
1852 if(--left_section <= 0) break;
1853 }
1854
1855 while(RightSection_F4()<=0)
1856 {
1857 if(--right_section <= 0) break;
1858 }
1859
1860 Ymin=v1->y;
1861 Ymax=min(v4->y-1,drawH);
1862
1863 return TRUE;
1864}
1865
1866////////////////////////////////////////////////////////////////////////
1867////////////////////////////////////////////////////////////////////////
1868
a96a5eb2 1869static inline int RightSection_FT4(void)
ef79bbde
P
1870{
1871 soft_vertex * v1 = right_array[ right_section ];
1872 soft_vertex * v2 = right_array[ right_section-1 ];
1873
1874 int height = v2->y - v1->y;
1875 right_section_height = height;
1876 right_x = v1->x;
1877 right_u = v1->u;
1878 right_v = v1->v;
1879 if(height == 0)
1880 {
1881 return 0;
1882 }
1883 delta_right_x = (v2->x - v1->x) / height;
1884 delta_right_u = (v2->u - v1->u) / height;
1885 delta_right_v = (v2->v - v1->v) / height;
1886
1887 return height;
1888}
1889
1890////////////////////////////////////////////////////////////////////////
1891
a96a5eb2 1892static inline int LeftSection_FT4(void)
ef79bbde
P
1893{
1894 soft_vertex * v1 = left_array[ left_section ];
1895 soft_vertex * v2 = left_array[ left_section-1 ];
1896
1897 int height = v2->y - v1->y;
1898 left_section_height = height;
1899 left_x = v1->x;
1900 left_u = v1->u;
1901 left_v = v1->v;
1902 if(height == 0)
1903 {
1904 return 0;
1905 }
1906 delta_left_x = (v2->x - v1->x) / height;
1907 delta_left_u = (v2->u - v1->u) / height;
1908 delta_left_v = (v2->v - v1->v) / height;
1909
1910 return height;
1911}
1912
1913////////////////////////////////////////////////////////////////////////
1914
a96a5eb2 1915static inline BOOL NextRow_FT4(void)
ef79bbde
P
1916{
1917 if(--left_section_height<=0)
1918 {
1919 if(--left_section > 0)
1920 while(LeftSection_FT4()<=0)
1921 {
1922 if(--left_section <= 0) break;
1923 }
1924 }
1925 else
1926 {
1927 left_x += delta_left_x;
1928 left_u += delta_left_u;
1929 left_v += delta_left_v;
1930 }
1931
1932 if(--right_section_height<=0)
1933 {
1934 if(--right_section > 0)
1935 while(RightSection_FT4()<=0)
1936 {
1937 if(--right_section<=0) break;
1938 }
1939 }
1940 else
1941 {
1942 right_x += delta_right_x;
1943 right_u += delta_right_u;
1944 right_v += delta_right_v;
1945 }
1946 return FALSE;
1947}
1948
1949////////////////////////////////////////////////////////////////////////
1950
a96a5eb2 1951static inline BOOL SetupSections_FT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4)
ef79bbde
P
1952{
1953 soft_vertex * v1, * v2, * v3, * v4;
1954 int height,width,longest1,longest2;
1955
1956 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1957 v1->u=tx1<<16;v1->v=ty1<<16;
1958
1959 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1960 v2->u=tx2<<16;v2->v=ty2<<16;
1961
1962 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1963 v3->u=tx3<<16;v3->v=ty3<<16;
1964
1965 v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1966 v4->u=tx4<<16;v4->v=ty4<<16;
1967
1968 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1969 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1970 if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1971 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1972 if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1973 if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1974
1975 height = v4->y - v1->y; if(height == 0) height =1;
1976 width = (v4->x - v1->x)>>16;
1977 longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1978 longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1979
1980 if(longest1 < 0) // 2 is right
1981 {
1982 if(longest2 < 0) // 3 is right
1983 {
1984 left_array[0] = v4;
1985 left_array[1] = v1;
1986 left_section = 1;
1987
1988 height = v3->y - v1->y; if(height == 0) height=1;
1989 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1990 if(longest1 >= 0)
1991 {
1992 right_array[0] = v4; // 1
1993 right_array[1] = v3; // 3
1994 right_array[2] = v1; // 4
1995 right_section = 2;
1996 }
1997 else
1998 {
1999 height = v4->y - v2->y; if(height == 0) height=1;
2000 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2001 if(longest1 >= 0)
2002 {
2003 right_array[0] = v4; // 1
2004 right_array[1] = v2; // 2
2005 right_array[2] = v1; // 4
2006 right_section = 2;
2007 }
2008 else
2009 {
2010 right_array[0] = v4; // 1
2011 right_array[1] = v3; // 2
2012 right_array[2] = v2; // 3
2013 right_array[3] = v1; // 4
2014 right_section = 3;
2015 }
2016 }
2017 }
2018 else
2019 {
2020 left_array[0] = v4;
2021 left_array[1] = v3; // 1
2022 left_array[2] = v1; // 2
2023 left_section = 2; // 3
2024 right_array[0] = v4; // 4
2025 right_array[1] = v2;
2026 right_array[2] = v1;
2027 right_section = 2;
2028 }
2029 }
2030 else
2031 {
2032 if(longest2 < 0)
2033 {
2034 left_array[0] = v4; // 1
2035 left_array[1] = v2; // 2
2036 left_array[2] = v1; // 3
2037 left_section = 2; // 4
2038 right_array[0] = v4;
2039 right_array[1] = v3;
2040 right_array[2] = v1;
2041 right_section = 2;
2042 }
2043 else
2044 {
2045 right_array[0] = v4;
2046 right_array[1] = v1;
2047 right_section = 1;
2048
2049 height = v3->y - v1->y; if(height == 0) height=1;
2050 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2051 if(longest1<0)
2052 {
2053 left_array[0] = v4; // 1
2054 left_array[1] = v3; // 3
2055 left_array[2] = v1; // 4
2056 left_section = 2;
2057 }
2058 else
2059 {
2060 height = v4->y - v2->y; if(height == 0) height=1;
2061 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2062 if(longest1<0)
2063 {
2064 left_array[0] = v4; // 1
2065 left_array[1] = v2; // 2
2066 left_array[2] = v1; // 4
2067 left_section = 2;
2068 }
2069 else
2070 {
2071 left_array[0] = v4; // 1
2072 left_array[1] = v3; // 2
2073 left_array[2] = v2; // 3
2074 left_array[3] = v1; // 4
2075 left_section = 3;
2076 }
2077 }
2078 }
2079 }
2080
2081 while(LeftSection_FT4()<=0)
2082 {
2083 if(--left_section <= 0) break;
2084 }
2085
2086 while(RightSection_FT4()<=0)
2087 {
2088 if(--right_section <= 0) break;
2089 }
2090
2091 Ymin=v1->y;
2092 Ymax=min(v4->y-1,drawH);
2093
2094 return TRUE;
2095}
2096
2097////////////////////////////////////////////////////////////////////////
2098////////////////////////////////////////////////////////////////////////
2099
a96a5eb2 2100static inline int RightSection_GT4(void)
ef79bbde
P
2101{
2102 soft_vertex * v1 = right_array[ right_section ];
2103 soft_vertex * v2 = right_array[ right_section-1 ];
2104
2105 int height = v2->y - v1->y;
2106 right_section_height = height;
2107 right_x = v1->x;
2108 right_u = v1->u;
2109 right_v = v1->v;
2110 right_R = v1->R;
2111 right_G = v1->G;
2112 right_B = v1->B;
2113
2114 if(height == 0)
2115 {
2116 return 0;
2117 }
2118 delta_right_x = (v2->x - v1->x) / height;
2119 delta_right_u = (v2->u - v1->u) / height;
2120 delta_right_v = (v2->v - v1->v) / height;
2121 delta_right_R = (v2->R - v1->R) / height;
2122 delta_right_G = (v2->G - v1->G) / height;
2123 delta_right_B = (v2->B - v1->B) / height;
2124
2125 return height;
2126}
2127
2128////////////////////////////////////////////////////////////////////////
2129
a96a5eb2 2130static inline int LeftSection_GT4(void)
ef79bbde
P
2131{
2132 soft_vertex * v1 = left_array[ left_section ];
2133 soft_vertex * v2 = left_array[ left_section-1 ];
2134
2135 int height = v2->y - v1->y;
2136 left_section_height = height;
2137 left_x = v1->x;
2138 left_u = v1->u;
2139 left_v = v1->v;
2140 left_R = v1->R;
2141 left_G = v1->G;
2142 left_B = v1->B;
2143
2144 if(height == 0)
2145 {
2146 return 0;
2147 }
2148 delta_left_x = (v2->x - v1->x) / height;
2149 delta_left_u = (v2->u - v1->u) / height;
2150 delta_left_v = (v2->v - v1->v) / height;
2151 delta_left_R = (v2->R - v1->R) / height;
2152 delta_left_G = (v2->G - v1->G) / height;
2153 delta_left_B = (v2->B - v1->B) / height;
2154
2155 return height;
2156}
2157
2158////////////////////////////////////////////////////////////////////////
2159
a96a5eb2 2160static inline BOOL NextRow_GT4(void)
ef79bbde
P
2161{
2162 if(--left_section_height<=0)
2163 {
2164 if(--left_section > 0)
2165 while(LeftSection_GT4()<=0)
2166 {
2167 if(--left_section <= 0) break;
2168 }
2169 }
2170 else
2171 {
2172 left_x += delta_left_x;
2173 left_u += delta_left_u;
2174 left_v += delta_left_v;
2175 left_R += delta_left_R;
2176 left_G += delta_left_G;
2177 left_B += delta_left_B;
2178 }
2179
2180 if(--right_section_height<=0)
2181 {
2182 if(--right_section > 0)
2183 while(RightSection_GT4()<=0)
2184 {
2185 if(--right_section<=0) break;
2186 }
2187 }
2188 else
2189 {
2190 right_x += delta_right_x;
2191 right_u += delta_right_u;
2192 right_v += delta_right_v;
2193 right_R += delta_right_R;
2194 right_G += delta_right_G;
2195 right_B += delta_right_B;
2196 }
2197 return FALSE;
2198}
2199
2200////////////////////////////////////////////////////////////////////////
2201
a96a5eb2 2202static inline BOOL SetupSections_GT4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,int32_t rgb1,int32_t rgb2,int32_t rgb3,int32_t rgb4)
ef79bbde
P
2203{
2204 soft_vertex * v1, * v2, * v3, * v4;
2205 int height,width,longest1,longest2;
2206
2207 v1 = vtx; v1->x=x1<<16;v1->y=y1;
2208 v1->u=tx1<<16;v1->v=ty1<<16;
2209 v1->R=(rgb1) & 0x00ff0000;
2210 v1->G=(rgb1<<8) & 0x00ff0000;
2211 v1->B=(rgb1<<16) & 0x00ff0000;
2212
2213 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
2214 v2->u=tx2<<16;v2->v=ty2<<16;
2215 v2->R=(rgb2) & 0x00ff0000;
2216 v2->G=(rgb2<<8) & 0x00ff0000;
2217 v2->B=(rgb2<<16) & 0x00ff0000;
2218
2219 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
2220 v3->u=tx3<<16;v3->v=ty3<<16;
2221 v3->R=(rgb3) & 0x00ff0000;
2222 v3->G=(rgb3<<8) & 0x00ff0000;
2223 v3->B=(rgb3<<16) & 0x00ff0000;
2224
2225 v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
2226 v4->u=tx4<<16;v4->v=ty4<<16;
2227 v4->R=(rgb4) & 0x00ff0000;
2228 v4->G=(rgb4<<8) & 0x00ff0000;
2229 v4->B=(rgb4<<16) & 0x00ff0000;
2230
2231 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
2232 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
2233 if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
2234 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
2235 if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
2236 if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
2237
2238 height = v4->y - v1->y; if(height == 0) height =1;
2239 width = (v4->x - v1->x)>>16;
2240 longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
2241 longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
2242
2243 if(longest1 < 0) // 2 is right
2244 {
2245 if(longest2 < 0) // 3 is right
2246 {
2247 left_array[0] = v4;
2248 left_array[1] = v1;
2249 left_section = 1;
2250
2251 height = v3->y - v1->y; if(height == 0) height=1;
2252 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2253 if(longest1 >= 0)
2254 {
2255 right_array[0] = v4; // 1
2256 right_array[1] = v3; // 3
2257 right_array[2] = v1; // 4
2258 right_section = 2;
2259 }
2260 else
2261 {
2262 height = v4->y - v2->y; if(height == 0) height=1;
2263 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2264 if(longest1 >= 0)
2265 {
2266 right_array[0] = v4; // 1
2267 right_array[1] = v2; // 2
2268 right_array[2] = v1; // 4
2269 right_section = 2;
2270 }
2271 else
2272 {
2273 right_array[0] = v4; // 1
2274 right_array[1] = v3; // 2
2275 right_array[2] = v2; // 3
2276 right_array[3] = v1; // 4
2277 right_section = 3;
2278 }
2279 }
2280 }
2281 else
2282 {
2283 left_array[0] = v4;
2284 left_array[1] = v3; // 1
2285 left_array[2] = v1; // 2
2286 left_section = 2; // 3
2287 right_array[0] = v4; // 4
2288 right_array[1] = v2;
2289 right_array[2] = v1;
2290 right_section = 2;
2291 }
2292 }
2293 else
2294 {
2295 if(longest2 < 0)
2296 {
2297 left_array[0] = v4; // 1
2298 left_array[1] = v2; // 2
2299 left_array[2] = v1; // 3
2300 left_section = 2; // 4
2301 right_array[0] = v4;
2302 right_array[1] = v3;
2303 right_array[2] = v1;
2304 right_section = 2;
2305 }
2306 else
2307 {
2308 right_array[0] = v4;
2309 right_array[1] = v1;
2310 right_section = 1;
2311
2312 height = v3->y - v1->y; if(height == 0) height=1;
2313 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2314 if(longest1<0)
2315 {
2316 left_array[0] = v4; // 1
2317 left_array[1] = v3; // 3
2318 left_array[2] = v1; // 4
2319 left_section = 2;
2320 }
2321 else
2322 {
2323 height = v4->y - v2->y; if(height == 0) height=1;
2324 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2325 if(longest1<0)
2326 {
2327 left_array[0] = v4; // 1
2328 left_array[1] = v2; // 2
2329 left_array[2] = v1; // 4
2330 left_section = 2;
2331 }
2332 else
2333 {
2334 left_array[0] = v4; // 1
2335 left_array[1] = v3; // 2
2336 left_array[2] = v2; // 3
2337 left_array[3] = v1; // 4
2338 left_section = 3;
2339 }
2340 }
2341 }
2342 }
2343
2344 while(LeftSection_GT4()<=0)
2345 {
2346 if(--left_section <= 0) break;
2347 }
2348
2349 while(RightSection_GT4()<=0)
2350 {
2351 if(--right_section <= 0) break;
2352 }
2353
2354 Ymin=v1->y;
2355 Ymax=min(v4->y-1,drawH);
2356
2357 return TRUE;
2358}
2359
2360////////////////////////////////////////////////////////////////////////
2361////////////////////////////////////////////////////////////////////////
2362////////////////////////////////////////////////////////////////////////
2363// POLY FUNCS
2364////////////////////////////////////////////////////////////////////////
2365////////////////////////////////////////////////////////////////////////
2366////////////////////////////////////////////////////////////////////////
2367
2368////////////////////////////////////////////////////////////////////////
2369// POLY 3/4 FLAT SHADED
2370////////////////////////////////////////////////////////////////////////
2371
a96a5eb2 2372static inline void drawPoly3Fi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb)
ef79bbde
P
2373{
2374 int i,j,xmin,xmax,ymin,ymax;
2375 unsigned short color;uint32_t lcolor;
2376
2377 if(x1>drawW && x2>drawW && x3>drawW) return;
2378 if(y1>drawH && y2>drawH && y3>drawH) return;
2379 if(x1<drawX && x2<drawX && x3<drawX) return;
2380 if(y1<drawY && y2<drawY && y3<drawY) return;
2381 if(drawY>=drawH) return;
2382 if(drawX>=drawW) return;
2383
2384 if(!SetupSections_F(x1,y1,x2,y2,x3,y3)) return;
2385
2386 ymax=Ymax;
2387
2388 color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2389 lcolor=lSetMask|(((uint32_t)(color))<<16)|color;
2390
2391 for(ymin=Ymin;ymin<drawY;ymin++)
2392 if(NextRow_F()) return;
2393
2394#ifdef FASTSOLID
2395
2396 if(!bCheckMask && !DrawSemiTrans)
2397 {
2398 color |=sSetMask;
2399 for (i=ymin;i<=ymax;i++)
2400 {
2401 xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
2402 xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2403
2404 for(j=xmin;j<xmax;j+=2)
2405 {
2406 PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2407 }
2408 if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2409
2410 if(NextRow_F()) return;
2411 }
2412 return;
2413 }
2414
2415#endif
2416
2417 for (i=ymin;i<=ymax;i++)
2418 {
2419 xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
2420 xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2421
2422 for(j=xmin;j<xmax;j+=2)
2423 {
2424 GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2425 }
2426 if(j==xmax)
2427 GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2428
2429 if(NextRow_F()) return;
2430 }
2431}
2432
2433////////////////////////////////////////////////////////////////////////
2434
a96a5eb2 2435static void drawPoly3F(int32_t rgb)
ef79bbde
P
2436{
2437 drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2438}
2439
2440#ifdef POLYQUAD3FS
2441
a96a5eb2 2442static void drawPoly4F_TRI(int32_t rgb)
ef79bbde
P
2443{
2444 drawPoly3Fi(lx1,ly1,lx3,ly3,lx2,ly2,rgb);
2445 drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2446}
2447
2448#endif
2449
2450// more exact:
2451
a96a5eb2 2452static void drawPoly4F(int32_t rgb)
ef79bbde
P
2453{
2454 int i,j,xmin,xmax,ymin,ymax;
2455 unsigned short color;uint32_t lcolor;
2456
2457 if(lx0>drawW && lx1>drawW && lx2>drawW && lx3>drawW) return;
2458 if(ly0>drawH && ly1>drawH && ly2>drawH && ly3>drawH) return;
2459 if(lx0<drawX && lx1<drawX && lx2<drawX && lx3<drawX) return;
2460 if(ly0<drawY && ly1<drawY && ly2<drawY && ly3<drawY) return;
2461 if(drawY>=drawH) return;
2462 if(drawX>=drawW) return;
2463
2464 if(!SetupSections_F4(lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3)) return;
2465
2466 ymax=Ymax;
2467
2468 for(ymin=Ymin;ymin<drawY;ymin++)
2469 if(NextRow_F4()) return;
2470
2471 color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2472 lcolor= lSetMask|(((uint32_t)(color))<<16)|color;
2473
2474#ifdef FASTSOLID
2475
2476 if(!bCheckMask && !DrawSemiTrans)
2477 {
2478 color |=sSetMask;
2479 for (i=ymin;i<=ymax;i++)
2480 {
2481 xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
2482 xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2483
2484 for(j=xmin;j<xmax;j+=2)
2485 {
2486 PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2487 }
2488 if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2489
2490 if(NextRow_F4()) return;
2491 }
2492 return;
2493 }
2494
2495#endif
2496
2497 for (i=ymin;i<=ymax;i++)
2498 {
2499 xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
2500 xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2501
2502 for(j=xmin;j<xmax;j+=2)
2503 {
2504 GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2505 }
2506 if(j==xmax) GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2507
2508 if(NextRow_F4()) return;
2509 }
2510}
2511
2512////////////////////////////////////////////////////////////////////////
2513// POLY 3/4 F-SHADED TEX PAL 4
2514////////////////////////////////////////////////////////////////////////
2515
a96a5eb2 2516static void drawPoly3TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
ef79bbde
P
2517{
2518 int i,j,xmin,xmax,ymin,ymax;
2519 int32_t difX, difY,difX2, difY2;
2520 int32_t posX,posY,YAdjust,XAdjust;
2521 int32_t clutP;
2522 short tC1,tC2;
2523
2524 if(x1>drawW && x2>drawW && x3>drawW) return;
2525 if(y1>drawH && y2>drawH && y3>drawH) return;
2526 if(x1<drawX && x2<drawX && x3<drawX) return;
2527 if(y1<drawY && y2<drawY && y3<drawY) return;
2528 if(drawY>=drawH) return;
2529 if(drawX>=drawW) return;
2530
2531 if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2532
2533 ymax=Ymax;
2534
2535 for(ymin=Ymin;ymin<drawY;ymin++)
2536 if(NextRow_FT()) return;
2537
2538 clutP=(clY<<10)+clX;
2539
2540 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2541
2542 difX=delta_right_u;difX2=difX<<1;
2543 difY=delta_right_v;difY2=difY<<1;
2544
2545#ifdef FASTSOLID
2546
2547 if(!bCheckMask && !DrawSemiTrans)
2548 {
2549 for (i=ymin;i<=ymax;i++)
2550 {
2551 xmin=(left_x >> 16);
2552 xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
2553 if(drawW<xmax) xmax=drawW;
2554
2555 if(xmax>=xmin)
2556 {
2557 posX=left_u;
2558 posY=left_v;
2559
2560 if(xmin<drawX)
2561 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2562
2563 for(j=xmin;j<xmax;j+=2)
2564 {
2565 XAdjust=(posX>>16);
2566 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2567 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2568 XAdjust=((posX+difX)>>16);
2569 tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2570 (XAdjust>>1)];
2571 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2572
2573 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2574 GETLE16(&psxVuw[clutP+tC1])|
2575 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2576
2577 posX+=difX2;
2578 posY+=difY2;
2579 }
2580 if(j==xmax)
2581 {
2582 XAdjust=(posX>>16);
2583 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2584 (XAdjust>>1)];
2585 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2586 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2587 }
2588 }
2589 if(NextRow_FT())
2590 {
2591 return;
2592 }
2593 }
2594 return;
2595 }
2596
2597#endif
2598
2599 for (i=ymin;i<=ymax;i++)
2600 {
2601 xmin=(left_x >> 16);
2602 xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2603 if(drawW<xmax) xmax=drawW;
2604
2605 if(xmax>=xmin)
2606 {
2607 posX=left_u;
2608 posY=left_v;
2609
2610 if(xmin<drawX)
2611 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2612
2613 for(j=xmin;j<xmax;j+=2)
2614 {
2615 XAdjust=(posX>>16);
2616 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2617 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2618 XAdjust=((posX+difX)>>16);
2619 tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2620 (XAdjust>>1)];
2621 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2622
2623 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2624 GETLE16(&psxVuw[clutP+tC1])|
2625 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2626
2627 posX+=difX2;
2628 posY+=difY2;
2629 }
2630 if(j==xmax)
2631 {
2632 XAdjust=(posX>>16);
2633 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2634 (XAdjust>>1)];
2635 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2636 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2637 }
2638 }
2639 if(NextRow_FT())
2640 {
2641 return;
2642 }
2643 }
2644}
2645
2646////////////////////////////////////////////////////////////////////////
2647
a96a5eb2 2648static void drawPoly3TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
ef79bbde
P
2649{
2650 int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
2651 int32_t difX, difY,difX2, difY2;
2652 int32_t posX,posY,YAdjust,XAdjust;
2653 int32_t clutP;
2654 short tC1,tC2;
2655
2656 if(x1>drawW && x2>drawW && x3>drawW) return;
2657 if(y1>drawH && y2>drawH && y3>drawH) return;
2658 if(x1<drawX && x2<drawX && x3<drawX) return;
2659 if(y1<drawY && y2<drawY && y3<drawY) return;
2660 if(drawY>=drawH) return;
2661 if(drawX>=drawW) return;
2662
2663 if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2664
2665 ymax=Ymax;
2666
2667 for(ymin=Ymin;ymin<drawY;ymin++)
2668 if(NextRow_FT()) return;
2669
2670 clutP=(clY<<10)+clX;
2671
2672 YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
2673
2674 difX=delta_right_u;difX2=difX<<1;
2675 difY=delta_right_v;difY2=difY<<1;
2676
2677#ifdef FASTSOLID
2678
2679 if(!bCheckMask && !DrawSemiTrans)
2680 {
2681 for (i=ymin;i<=ymax;i++)
2682 {
2683 xmin=(left_x >> 16);
2684 xmax=(right_x >> 16)-1;
2685 if(drawW<xmax) xmax=drawW;
2686
2687 if(xmax>=xmin)
2688 {
2689 posX=left_u;
2690 posY=left_v;
2691
2692 if(xmin<drawX)
2693 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2694
2695 for(j=xmin;j<xmax;j+=2)
2696 {
2697 XAdjust=(posX>>16);
2698
2699 TXV=posY>>16;
2700 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2701 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2702
2703 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2704
2705 XAdjust=((posX+difX)>>16);
2706
2707 TXV=(posY+difY)>>16;
2708 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2709 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2710
2711 tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2712
2713 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2714 GETLE16(&psxVuw[clutP+tC1])|
2715 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2716
2717 posX+=difX2;
2718 posY+=difY2;
2719 }
2720 if(j==xmax)
2721 {
2722 XAdjust=(posX>>16);
2723
2724 TXV=posY>>16;
2725 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2726 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2727
2728 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2729
2730 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2731 }
2732 }
2733 if(NextRow_FT())
2734 {
2735 return;
2736 }
2737 }
2738 return;
2739 }
2740
2741#endif
2742
2743 for (i=ymin;i<=ymax;i++)
2744 {
2745 xmin=(left_x >> 16);
2746 xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2747 if(drawW<xmax) xmax=drawW;
2748
2749 if(xmax>=xmin)
2750 {
2751 posX=left_u;
2752 posY=left_v;
2753
2754 if(xmin<drawX)
2755 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2756
2757 for(j=xmin;j<xmax;j+=2)
2758 {
2759 XAdjust=(posX>>16);
2760
2761 TXV=posY>>16;
2762 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2763 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2764
2765 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2766
2767 XAdjust=((posX+difX)>>16);
2768
2769 TXV=(posY+difY)>>16;
2770 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2771 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2772
2773 tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2774
2775 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2776 GETLE16(&psxVuw[clutP+tC1])|
2777 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2778
2779 posX+=difX2;
2780 posY+=difY2;
2781 }
2782 if(j==xmax)
2783 {
2784 XAdjust=(posX>>16);
2785
2786 TXV=posY>>16;
2787 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2788 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2789
2790 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2791
2792 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2793 }
2794 }
2795 if(NextRow_FT())
2796 {
2797 return;
2798 }
2799 }
2800}
2801
2802////////////////////////////////////////////////////////////////////////
2803
a96a5eb2 2804static void drawPoly3TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3,short clX, short clY)
ef79bbde
P
2805{
2806 int i,j,xmin,xmax,ymin,ymax;
2807 int32_t difX, difY,difX2, difY2;
2808 int32_t posX,posY,YAdjust,XAdjust;
2809 int32_t clutP;
2810 short tC1,tC2;
2811
2812 if(x1>drawW && x2>drawW && x3>drawW) return;
2813 if(y1>drawH && y2>drawH && y3>drawH) return;
2814 if(x1<drawX && x2<drawX && x3<drawX) return;
2815 if(y1<drawY && y2<drawY && y3<drawY) return;
2816 if(drawY>=drawH) return;
2817 if(drawX>=drawW) return;
2818
2819 if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2820
2821 ymax=Ymax;
2822
2823 for(ymin=Ymin;ymin<drawY;ymin++)
2824 if(NextRow_FT()) return;
2825
2826 clutP=(clY<<10)+clX;
2827
2828 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2829 YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
2830
2831 difX=delta_right_u;difX2=difX<<1;
2832 difY=delta_right_v;difY2=difY<<1;
2833
2834#ifdef FASTSOLID
2835
2836 if(!bCheckMask && !DrawSemiTrans)
2837 {
2838 for (i=ymin;i<=ymax;i++)
2839 {
2840 xmin=(left_x >> 16);
2841 xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
2842 if(xmax>xmin) xmax--;
2843
2844 if(drawW<xmax) xmax=drawW;
2845
2846 if(xmax>=xmin)
2847 {
2848 posX=left_u;
2849 posY=left_v;
2850
2851 if(xmin<drawX)
2852 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2853
2854 for(j=xmin;j<xmax;j+=2)
2855 {
2856 XAdjust=(posX>>16)%TWin.Position.x1;
2857 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2858 YAdjust+(XAdjust>>1)];
2859 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2860 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
2861 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
2862 YAdjust+(XAdjust>>1)];
2863 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2864
2865 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2866 GETLE16(&psxVuw[clutP+tC1])|
2867 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2868
2869 posX+=difX2;
2870 posY+=difY2;
2871 }
2872 if(j==xmax)
2873 {
2874 XAdjust=(posX>>16)%TWin.Position.x1;
2875 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2876 YAdjust+(XAdjust>>1)];
2877 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2878 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2879 }
2880 }
2881 if(NextRow_FT())
2882 {
2883 return;
2884 }
2885 }
2886 return;
2887 }
2888
2889#endif
2890
2891 for (i=ymin;i<=ymax;i++)
2892 {
2893 xmin=(left_x >> 16);
2894 xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2895 if(drawW<xmax) xmax=drawW;
2896
2897 if(xmax>=xmin)
2898 {
2899 posX=left_u;
2900 posY=left_v;
2901
2902 if(xmin<drawX)
2903 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2904
2905 for(j=xmin;j<xmax;j+=2)
2906 {
2907 XAdjust=(posX>>16)%TWin.Position.x1;
2908 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2909 YAdjust+(XAdjust>>1)];
2910 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2911 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
2912 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
2913 YAdjust+(XAdjust>>1)];
2914 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2915
2916 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2917 GETLE16(&psxVuw[clutP+tC1])|
2918 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2919
2920 posX+=difX2;
2921 posY+=difY2;
2922 }
2923 if(j==xmax)
2924 {
2925 XAdjust=(posX>>16)%TWin.Position.x1;
2926 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2927 YAdjust+(XAdjust>>1)];
2928 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2929 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2930 }
2931 }
2932 if(NextRow_FT())
2933 {
2934 return;
2935 }
2936 }
2937}
2938
2939////////////////////////////////////////////////////////////////////////
2940
2941#ifdef POLYQUAD3
2942
a96a5eb2 2943static void drawPoly4TEx4_TRI(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
ef79bbde
P
2944{
2945 drawPoly3TEx4(x2,y2,x3,y3,x4,y4,
2946 tx2,ty2,tx3,ty3,tx4,ty4,
2947 clX,clY);
2948 drawPoly3TEx4(x1,y1,x2,y2,x4,y4,
2949 tx1,ty1,tx2,ty2,tx4,ty4,
2950 clX,clY);
2951}
2952
2953#endif
2954
2955// more exact:
2956
a96a5eb2 2957static void drawPoly4TEx4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
ef79bbde
P
2958{
2959 int32_t num;
2960 int32_t i,j,xmin,xmax,ymin,ymax;
2961 int32_t difX, difY, difX2, difY2;
2962 int32_t posX,posY,YAdjust,clutP,XAdjust;
2963 short tC1,tC2;
2964
2965 if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
2966 if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
2967 if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
2968 if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
2969 if(drawY>=drawH) return;
2970 if(drawX>=drawW) return;
2971
2972 if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
2973
2974 ymax=Ymax;
2975
2976 for(ymin=Ymin;ymin<drawY;ymin++)
2977 if(NextRow_FT4()) return;
2978
2979 clutP=(clY<<10)+clX;
2980
2981 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2982
2983#ifdef FASTSOLID
2984
2985 if(!bCheckMask && !DrawSemiTrans)
2986 {
2987 for (i=ymin;i<=ymax;i++)
2988 {
2989 xmin=(left_x >> 16);
2990 xmax=(right_x >> 16);
2991
2992 if(xmax>=xmin)
2993 {
2994 posX=left_u;
2995 posY=left_v;
2996
2997 num=(xmax-xmin);
2998 if(num==0) num=1;
2999 difX=(right_u-posX)/num;
3000 difY=(right_v-posY)/num;
3001 difX2=difX<<1;
3002 difY2=difY<<1;
3003
3004 if(xmin<drawX)
3005 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3006 xmax--;if(drawW<xmax) xmax=drawW;
3007
3008 for(j=xmin;j<xmax;j+=2)
3009 {
3010 XAdjust=(posX>>16);
3011 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3012 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3013 XAdjust=((posX+difX)>>16);
3014 tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3015 (XAdjust>>1)];
3016 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3017
3018 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3019 GETLE16(&psxVuw[clutP+tC1])|
3020 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3021 posX+=difX2;
3022 posY+=difY2;
3023 }
3024 if(j==xmax)
3025 {
3026 XAdjust=(posX>>16);
3027 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3028 (XAdjust>>1)];
3029 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3030 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3031 }
3032
3033 }
3034 if(NextRow_FT4()) return;
3035 }
3036 return;
3037 }
3038
3039#endif
3040
3041 for (i=ymin;i<=ymax;i++)
3042 {
3043 xmin=(left_x >> 16);
3044 xmax=(right_x >> 16);
3045
3046 if(xmax>=xmin)
3047 {
3048 posX=left_u;
3049 posY=left_v;
3050
3051 num=(xmax-xmin);
3052 if(num==0) num=1;
3053 difX=(right_u-posX)/num;
3054 difY=(right_v-posY)/num;
3055 difX2=difX<<1;
3056 difY2=difY<<1;
3057
3058 if(xmin<drawX)
3059 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3060 xmax--;if(drawW<xmax) xmax=drawW;
3061
3062 for(j=xmin;j<xmax;j+=2)
3063 {
3064 XAdjust=(posX>>16);
3065 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3066 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3067 XAdjust=((posX+difX)>>16);
3068 tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3069 (XAdjust>>1)];
3070 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3071
3072 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3073 GETLE16(&psxVuw[clutP+tC1])|
3074 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3075 posX+=difX2;
3076 posY+=difY2;
3077 }
3078 if(j==xmax)
3079 {
3080 XAdjust=(posX>>16);
3081 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3082 (XAdjust>>1)];
3083 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3084 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3085 }
3086 }
3087 if(NextRow_FT4()) return;
3088 }
3089}
3090
3091////////////////////////////////////////////////////////////////////////
3092
a96a5eb2 3093static void drawPoly4TEx4_IL(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
ef79bbde
P
3094{
3095 int32_t num;
3096 int32_t i,j=0,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
3097 int32_t difX, difY, difX2, difY2;
3098 int32_t posX=0,posY=0,YAdjust,clutP,XAdjust;
3099 short tC1,tC2;
3100
3101 if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3102 if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3103 if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3104 if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3105 if(drawY>=drawH) return;
3106 if(drawX>=drawW) return;
3107
3108 if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3109
3110 ymax=Ymax;
3111
3112 for(ymin=Ymin;ymin<drawY;ymin++)
3113 if(NextRow_FT4()) return;
3114
3115 clutP=(clY<<10)+clX;
3116
3117 YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX;
3118
3119#ifdef FASTSOLID
3120
3121 if(!bCheckMask && !DrawSemiTrans)
3122 {
3123 for (i=ymin;i<=ymax;i++)
3124 {
3125 xmin=(left_x >> 16);
3126 xmax=(right_x >> 16);
3127
3128 if(xmax>=xmin)
3129 {
3130 posX=left_u;
3131 posY=left_v;
3132
3133 num=(xmax-xmin);
3134 if(num==0) num=1;
3135 difX=(right_u-posX)/num;
3136 difY=(right_v-posY)/num;
3137 difX2=difX<<1;
3138 difY2=difY<<1;
3139
3140 if(xmin<drawX)
3141 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3142 xmax--;if(drawW<xmax) xmax=drawW;
3143
3144 for(j=xmin;j<xmax;j+=2)
3145 {
3146 XAdjust=(posX>>16);
3147
3148 TXV=posY>>16;
3149 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3150 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3151
3152 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3153
3154 XAdjust=((posX+difX)>>16);
3155
3156 TXV=(posY+difY)>>16;
3157 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3158 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3159
3160 tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3161
3162 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3163 GETLE16(&psxVuw[clutP+tC1])|
3164 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3165 posX+=difX2;
3166 posY+=difY2;
3167 }
3168 posX+=difX2;
3169 posY+=difY2;
3170 }
3171
3172 if(j==xmax)
3173 {
3174 XAdjust=(posX>>16);
3175 TXV=posY>>16;
3176 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3177 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3178
3179 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3180
3181 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3182 }
3183
3184 }
3185 if(NextRow_FT4()) return;
3186 }
3187#endif
3188
3189 for (i=ymin;i<=ymax;i++)
3190 {
3191 xmin=(left_x >> 16);
3192 xmax=(right_x >> 16);
3193
3194 if(xmax>=xmin)
3195 {
3196 posX=left_u;
3197 posY=left_v;
3198
3199 num=(xmax-xmin);
3200 if(num==0) num=1;
3201 difX=(right_u-posX)/num;
3202 difY=(right_v-posY)/num;
3203 difX2=difX<<1;
3204 difY2=difY<<1;
3205
3206 if(xmin<drawX)
3207 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3208 xmax--;if(drawW<xmax) xmax=drawW;
3209
3210 for(j=xmin;j<xmax;j+=2)
3211 {
3212 XAdjust=(posX>>16);
3213
3214 TXV=posY>>16;
3215 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3216 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3217
3218 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3219
3220 XAdjust=((posX+difX)>>16);
3221
3222 TXV=(posY+difY)>>16;
3223 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3224 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3225
3226 tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3227
3228 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3229 GETLE16(&psxVuw[clutP+tC1])|
3230 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3231 posX+=difX2;
3232 posY+=difY2;
3233 }
3234 if(j==xmax)
3235 {
3236 XAdjust=(posX>>16);
3237 TXV=posY>>16;
3238 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3239 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3240
3241 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3242
3243 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3244 }
3245 }
3246 if(NextRow_FT4()) return;
3247 }
3248}
3249
3250////////////////////////////////////////////////////////////////////////
3251
a96a5eb2 3252static void drawPoly4TEx4_TW(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
ef79bbde
P
3253{
3254 int32_t num;
3255 int32_t i,j,xmin,xmax,ymin,ymax;
3256 int32_t difX, difY, difX2, difY2;
3257 int32_t posX,posY,YAdjust,clutP,XAdjust;
3258 short tC1,tC2;
3259
3260 if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3261 if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3262 if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3263 if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3264 if(drawY>=drawH) return;
3265 if(drawX>=drawW) return;
3266
3267 if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3268
3269 ymax=Ymax;
3270
3271 for(ymin=Ymin;ymin<drawY;ymin++)
3272 if(NextRow_FT4()) return;
3273
3274 clutP=(clY<<10)+clX;
3275
3276 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3277 YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3278
3279#ifdef FASTSOLID
3280
3281 if(!bCheckMask && !DrawSemiTrans)
3282 {
3283 for (i=ymin;i<=ymax;i++)
3284 {
3285 xmin=(left_x >> 16);
3286 xmax=(right_x >> 16);
3287
3288 if(xmax>=xmin)
3289 {
3290 posX=left_u;
3291 posY=left_v;
3292
3293 num=(xmax-xmin);
3294 if(num==0) num=1;
3295 difX=(right_u-posX)/num;
3296 difY=(right_v-posY)/num;
3297 difX2=difX<<1;
3298 difY2=difY<<1;
3299
3300 if(xmin<drawX)
3301 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3302 xmax--;if(drawW<xmax) xmax=drawW;
3303
3304 for(j=xmin;j<xmax;j+=2)
3305 {
3306 XAdjust=(posX>>16)%TWin.Position.x1;
3307 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3308 YAdjust+(XAdjust>>1)];
3309 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3310 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3311 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3312 YAdjust+(XAdjust>>1)];
3313 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3314
3315 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3316 GETLE16(&psxVuw[clutP+tC1])|
3317 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3318 posX+=difX2;
3319 posY+=difY2;
3320 }
3321 if(j==xmax)
3322 {
3323 XAdjust=(posX>>16)%TWin.Position.x1;
3324 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3325 YAdjust+(XAdjust>>1)];
3326 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3327 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3328 }
3329 }
3330 if(NextRow_FT4()) return;
3331 }
3332 return;
3333 }
3334
3335#endif
3336
3337 for (i=ymin;i<=ymax;i++)
3338 {
3339 xmin=(left_x >> 16);
3340 xmax=(right_x >> 16);
3341
3342 if(xmax>=xmin)
3343 {
3344 posX=left_u;
3345 posY=left_v;
3346
3347 num=(xmax-xmin);
3348 if(num==0) num=1;
3349 difX=(right_u-posX)/num;
3350 difY=(right_v-posY)/num;
3351 difX2=difX<<1;
3352 difY2=difY<<1;
3353
3354 if(xmin<drawX)
3355 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3356 xmax--;if(drawW<xmax) xmax=drawW;
3357
3358 for(j=xmin;j<xmax;j+=2)
3359 {
3360 XAdjust=(posX>>16)%TWin.Position.x1;
3361 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3362 YAdjust+(XAdjust>>1)];
3363 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3364 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3365 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3366 YAdjust+(XAdjust>>1)];
3367 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3368
3369 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3370 GETLE16(&psxVuw[clutP+tC1])|
3371 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3372 posX+=difX2;
3373 posY+=difY2;
3374 }
3375 if(j==xmax)
3376 {
3377 XAdjust=(posX>>16)%TWin.Position.x1;
3378 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3379 YAdjust+(XAdjust>>1)];
3380 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3381 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3382 }
3383 }
3384 if(NextRow_FT4()) return;
3385 }
3386}
3387
3388////////////////////////////////////////////////////////////////////////
3389
a96a5eb2 3390static void drawPoly4TEx4_TW_S(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4, short tx1, short ty1, short tx2, short ty2, short tx3, short ty3, short tx4, short ty4,short clX, short clY)
ef79bbde
P
3391{
3392 int32_t num;
3393 int32_t i,j,xmin,xmax,ymin,ymax;
3394 int32_t difX, difY, difX2, difY2;
3395 int32_t posX,posY,YAdjust,clutP,XAdjust;
3396 short tC1,tC2;
3397
3398 if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3399 if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3400 if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3401 if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3402 if(drawY>=drawH) return;
3403 if(drawX>=drawW) return;
3404
3405 if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3406
3407 ymax=Ymax;
3408
3409 for(ymin=Ymin;ymin<drawY;ymin++)
3410 if(NextRow_FT4()) return;
3411
3412 clutP=(clY<<10)+clX;
3413
3414 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3415 YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3416
3417#ifdef FASTSOLID
3418
3419 if(!bCheckMask && !DrawSemiTrans)
3420 {
3421 for (i=ymin;i<=ymax;i++)
3422 {
3423 xmin=(left_x >> 16);
3424 xmax=(right_x >> 16);
3425
3426 if(xmax>=xmin)
3427 {
3428 posX=left_u;
3429 posY=left_v;
3430
3431 num=(xmax-xmin);
3432 if(num==0) num=1;
3433 difX=(right_u-posX)/num;
3434 difY=(right_v-posY)/num;
3435 difX2=difX<<1;
3436 difY2=difY<<1;
3437
3438 if(xmin<drawX)
3439 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3440 xmax--;if(drawW<xmax) xmax=drawW;
3441
3442 for(j=xmin;j<xmax;j+=2)
3443 {
3444 XAdjust=(posX>>16)%TWin.Position.x1;
3445 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3446 YAdjust+(XAdjust>>1)];
3447 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3448 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3449 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3450 YAdjust+(XAdjust>>1)];
3451 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3452
3453 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3454 GETLE16(&psxVuw[clutP+tC1])|
3455 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3456 posX+=difX2;
3457 posY+=difY2;
3458 }
3459 if(j==xmax)
3460 {
3461 XAdjust=(posX>>16)%TWin.Position.x1;
3462 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3463 YAdjust+(XAdjust>>1)];
3464 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3465 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3466 }
3467 }
3468 if(NextRow_FT4()) return;
3469 }
3470 return;
3471 }
3472
3473#endif
3474
3475 for (i=ymin;i<=ymax;i++)
3476 {
3477 xmin=(left_x >> 16);
3478 xmax=(right_x >> 16);
3479
3480 if(xmax>=xmin)
3481 {
3482 posX=left_u;
3483 posY=left_v;
3484
3485 num=(xmax-xmin);
3486 if(num==0) num=1;
3487 difX=(right_u-posX)/num;
3488 difY=(right_v-posY)/num;
3489 difX2=difX<<1;
3490 difY2=difY<<1;
3491
3492 if(xmin<drawX)
3493 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3494 xmax--;if(drawW<xmax) xmax=drawW;
3495
3496 for(j=xmin;j<xmax;j+=2)
3497 {
3498 XAdjust=(posX>>16)%TWin.Position.x1;
3499 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3500 YAdjust+(XAdjust>>1)];
3501 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3502 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3503 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3504 YAdjust+(XAdjust>>1)];
3505 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3506
3507 GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
3508 GETLE16(&psxVuw[clutP+tC1])|
3509 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3510 posX+=difX2;
3511 posY+=difY2;
3512 }
3513 if(j==xmax)
3514 {
3515 XAdjust=(posX>>16)%TWin.Position.x1;
3516 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3517 YAdjust+(XAdjust>>1)];
3518 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3519 GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3520 }
3521 }
3522 if(NextRow_FT4()) return;
3523 }