dfxvideo: fix word access macros
[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
1006 if(y0>y1) return;
1007 if(x0>x1) return;
1008
a96a5eb2 1009 if(y0>=512) return;
ef79bbde
P
1010 if(x0>1023) return;
1011
a96a5eb2 1012 if(y1>512) y1=512;
ef79bbde
P
1013 if(x1>1024) x1=1024;
1014
1015 dx=x1-x0;dy=y1-y0;
1016 if(dx&1)
1017 {
1018 unsigned short *DSTPtr;
1019 unsigned short LineOffset;
1020
1021 DSTPtr = psxVuw + (1024*y0) + x0;
1022 LineOffset = 1024 - dx;
1023
1024 for(i=0;i<dy;i++)
1025 {
1026 for(j=0;j<dx;j++) { PUTLE16(DSTPtr, col); DSTPtr++; }
1027 DSTPtr += LineOffset;
1028 }
1029 }
1030 else
1031 {
1032 uint32_t *DSTPtr;
1033 unsigned short LineOffset;
1034 uint32_t lcol=(((int32_t)col)<<16)|col;
1035 dx>>=1;
1036 DSTPtr = (uint32_t *)(psxVuw + (1024*y0) + x0);
1037 LineOffset = 512 - dx;
1038
1039 for(i=0;i<dy;i++)
1040 {
1041 for(j=0;j<dx;j++) { PUTLE32(DSTPtr, lcol); DSTPtr++; }
1042 DSTPtr += LineOffset;
1043 }
1044 }
1045}
1046
1047////////////////////////////////////////////////////////////////////////
1048////////////////////////////////////////////////////////////////////////
1049////////////////////////////////////////////////////////////////////////
1050// EDGE INTERPOLATION
1051////////////////////////////////////////////////////////////////////////
1052////////////////////////////////////////////////////////////////////////
1053////////////////////////////////////////////////////////////////////////
1054
1055typedef struct SOFTVTAG
1056{
1057 int x,y;
1058 int u,v;
1059 int32_t R,G,B;
1060} soft_vertex;
1061
1062static soft_vertex vtx[4];
1063static soft_vertex * left_array[4], * right_array[4];
1064static int left_section, right_section;
1065static int left_section_height, right_section_height;
1066static int left_x, delta_left_x, right_x, delta_right_x;
1067static int left_u, delta_left_u, left_v, delta_left_v;
1068static int right_u, delta_right_u, right_v, delta_right_v;
1069static int left_R, delta_left_R, right_R, delta_right_R;
1070static int left_G, delta_left_G, right_G, delta_right_G;
1071static int left_B, delta_left_B, right_B, delta_right_B;
1072
a96a5eb2 1073// USE_NASM
1074static inline int shl10idiv(int x, int y)
ef79bbde
P
1075{
1076 __int64 bi=x;
1077 bi<<=10;
1078 return bi/y;
1079}
1080
ef79bbde
P
1081////////////////////////////////////////////////////////////////////////
1082////////////////////////////////////////////////////////////////////////
1083////////////////////////////////////////////////////////////////////////
1084
a96a5eb2 1085static inline int RightSection_F(void)
ef79bbde
P
1086{
1087 soft_vertex * v1 = right_array[ right_section ];
1088 soft_vertex * v2 = right_array[ right_section-1 ];
1089
1090 int height = v2->y - v1->y;
1091 if(height == 0) return 0;
1092 delta_right_x = (v2->x - v1->x) / height;
1093 right_x = v1->x;
1094
1095 right_section_height = height;
1096 return height;
1097}
1098
1099////////////////////////////////////////////////////////////////////////
1100
a96a5eb2 1101static inline int LeftSection_F(void)
ef79bbde
P
1102{
1103 soft_vertex * v1 = left_array[ left_section ];
1104 soft_vertex * v2 = left_array[ left_section-1 ];
1105
1106 int height = v2->y - v1->y;
1107 if(height == 0) return 0;
1108 delta_left_x = (v2->x - v1->x) / height;
1109 left_x = v1->x;
1110
1111 left_section_height = height;
1112 return height;
1113}
1114
1115////////////////////////////////////////////////////////////////////////
1116
a96a5eb2 1117static inline BOOL NextRow_F(void)
ef79bbde
P
1118{
1119 if(--left_section_height<=0)
1120 {
1121 if(--left_section <= 0) {return TRUE;}
1122 if(LeftSection_F() <= 0) {return TRUE;}
1123 }
1124 else
1125 {
1126 left_x += delta_left_x;
1127 }
1128
1129 if(--right_section_height<=0)
1130 {
1131 if(--right_section<=0) {return TRUE;}
1132 if(RightSection_F() <=0) {return TRUE;}
1133 }
1134 else
1135 {
1136 right_x += delta_right_x;
1137 }
1138 return FALSE;
1139}
1140
1141////////////////////////////////////////////////////////////////////////
1142
a96a5eb2 1143static inline BOOL SetupSections_F(short x1, short y1, short x2, short y2, short x3, short y3)
ef79bbde
P
1144{
1145 soft_vertex * v1, * v2, * v3;
1146 int height,longest;
1147
1148 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1149 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1150 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1151
1152 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1153 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1154 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1155
1156 height = v3->y - v1->y;
1157 if(height == 0) {return FALSE;}
1158 longest = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1159 if(longest == 0) {return FALSE;}
1160
1161 if(longest < 0)
1162 {
1163 right_array[0] = v3;
1164 right_array[1] = v2;
1165 right_array[2] = v1;
1166 right_section = 2;
1167 left_array[0] = v3;
1168 left_array[1] = v1;
1169 left_section = 1;
1170
1171 if(LeftSection_F() <= 0) return FALSE;
1172 if(RightSection_F() <= 0)
1173 {
1174 right_section--;
1175 if(RightSection_F() <= 0) return FALSE;
1176 }
1177 }
1178 else
1179 {
1180 left_array[0] = v3;
1181 left_array[1] = v2;
1182 left_array[2] = v1;
1183 left_section = 2;
1184 right_array[0] = v3;
1185 right_array[1] = v1;
1186 right_section = 1;
1187
1188 if(RightSection_F() <= 0) return FALSE;
1189 if(LeftSection_F() <= 0)
1190 {
1191 left_section--;
1192 if(LeftSection_F() <= 0) return FALSE;
1193 }
1194 }
1195
1196 Ymin=v1->y;
1197 Ymax=min(v3->y-1,drawH);
1198
1199 return TRUE;
1200}
1201
1202////////////////////////////////////////////////////////////////////////
1203////////////////////////////////////////////////////////////////////////
1204
a96a5eb2 1205static inline int RightSection_G(void)
ef79bbde
P
1206{
1207 soft_vertex * v1 = right_array[ right_section ];
1208 soft_vertex * v2 = right_array[ right_section-1 ];
1209
1210 int height = v2->y - v1->y;
1211 if(height == 0) return 0;
1212 delta_right_x = (v2->x - v1->x) / height;
1213 right_x = v1->x;
1214
1215 right_section_height = height;
1216 return height;
1217}
1218
1219////////////////////////////////////////////////////////////////////////
1220
a96a5eb2 1221static inline int LeftSection_G(void)
ef79bbde
P
1222{
1223 soft_vertex * v1 = left_array[ left_section ];
1224 soft_vertex * v2 = left_array[ left_section-1 ];
1225
1226 int height = v2->y - v1->y;
1227 if(height == 0) return 0;
1228 delta_left_x = (v2->x - v1->x) / height;
1229 left_x = v1->x;
1230
1231 delta_left_R = ((v2->R - v1->R)) / height;
1232 left_R = v1->R;
1233 delta_left_G = ((v2->G - v1->G)) / height;
1234 left_G = v1->G;
1235 delta_left_B = ((v2->B - v1->B)) / height;
1236 left_B = v1->B;
1237
1238 left_section_height = height;
1239 return height;
1240}
1241
1242////////////////////////////////////////////////////////////////////////
1243
a96a5eb2 1244static inline BOOL NextRow_G(void)
ef79bbde
P
1245{
1246 if(--left_section_height<=0)
1247 {
1248 if(--left_section <= 0) {return TRUE;}
1249 if(LeftSection_G() <= 0) {return TRUE;}
1250 }
1251 else
1252 {
1253 left_x += delta_left_x;
1254 left_R += delta_left_R;
1255 left_G += delta_left_G;
1256 left_B += delta_left_B;
1257 }
1258
1259 if(--right_section_height<=0)
1260 {
1261 if(--right_section<=0) {return TRUE;}
1262 if(RightSection_G() <=0) {return TRUE;}
1263 }
1264 else
1265 {
1266 right_x += delta_right_x;
1267 }
1268 return FALSE;
1269}
1270
1271////////////////////////////////////////////////////////////////////////
1272
a96a5eb2 1273static 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
1274{
1275 soft_vertex * v1, * v2, * v3;
1276 int height,longest,temp;
1277
1278 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1279 v1->R=(rgb1) & 0x00ff0000;
1280 v1->G=(rgb1<<8) & 0x00ff0000;
1281 v1->B=(rgb1<<16) & 0x00ff0000;
1282 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1283 v2->R=(rgb2) & 0x00ff0000;
1284 v2->G=(rgb2<<8) & 0x00ff0000;
1285 v2->B=(rgb2<<16) & 0x00ff0000;
1286 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1287 v3->R=(rgb3) & 0x00ff0000;
1288 v3->G=(rgb3<<8) & 0x00ff0000;
1289 v3->B=(rgb3<<16) & 0x00ff0000;
1290
1291 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1292 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1293 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1294
1295 height = v3->y - v1->y;
1296 if(height == 0) {return FALSE;}
1297 temp=(((v2->y - v1->y) << 16) / height);
1298 longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1299 if(longest == 0) {return FALSE;}
1300
1301 if(longest < 0)
1302 {
1303 right_array[0] = v3;
1304 right_array[1] = v2;
1305 right_array[2] = v1;
1306 right_section = 2;
1307 left_array[0] = v3;
1308 left_array[1] = v1;
1309 left_section = 1;
1310
1311 if(LeftSection_G() <= 0) return FALSE;
1312 if(RightSection_G() <= 0)
1313 {
1314 right_section--;
1315 if(RightSection_G() <= 0) return FALSE;
1316 }
1317 if(longest > -0x1000) longest = -0x1000;
1318 }
1319 else
1320 {
1321 left_array[0] = v3;
1322 left_array[1] = v2;
1323 left_array[2] = v1;
1324 left_section = 2;
1325 right_array[0] = v3;
1326 right_array[1] = v1;
1327 right_section = 1;
1328
1329 if(RightSection_G() <= 0) return FALSE;
1330 if(LeftSection_G() <= 0)
1331 {
1332 left_section--;
1333 if(LeftSection_G() <= 0) return FALSE;
1334 }
1335 if(longest < 0x1000) longest = 0x1000;
1336 }
1337
1338 Ymin=v1->y;
1339 Ymax=min(v3->y-1,drawH);
1340
1341 delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1342 delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1343 delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1344
1345 return TRUE;
1346}
1347
1348////////////////////////////////////////////////////////////////////////
1349////////////////////////////////////////////////////////////////////////
1350
a96a5eb2 1351static inline int RightSection_FT(void)
ef79bbde
P
1352{
1353 soft_vertex * v1 = right_array[ right_section ];
1354 soft_vertex * v2 = right_array[ right_section-1 ];
1355
1356 int height = v2->y - v1->y;
1357 if(height == 0) return 0;
1358 delta_right_x = (v2->x - v1->x) / height;
1359 right_x = v1->x;
1360
1361 right_section_height = height;
1362 return height;
1363}
1364
1365////////////////////////////////////////////////////////////////////////
1366
a96a5eb2 1367static inline int LeftSection_FT(void)
ef79bbde
P
1368{
1369 soft_vertex * v1 = left_array[ left_section ];
1370 soft_vertex * v2 = left_array[ left_section-1 ];
1371
1372 int height = v2->y - v1->y;
1373 if(height == 0) return 0;
1374 delta_left_x = (v2->x - v1->x) / height;
1375 left_x = v1->x;
1376
1377 delta_left_u = ((v2->u - v1->u)) / height;
1378 left_u = v1->u;
1379 delta_left_v = ((v2->v - v1->v)) / height;
1380 left_v = v1->v;
1381
1382 left_section_height = height;
1383 return height;
1384}
1385
1386////////////////////////////////////////////////////////////////////////
1387
a96a5eb2 1388static inline BOOL NextRow_FT(void)
ef79bbde
P
1389{
1390 if(--left_section_height<=0)
1391 {
1392 if(--left_section <= 0) {return TRUE;}
1393 if(LeftSection_FT() <= 0) {return TRUE;}
1394 }
1395 else
1396 {
1397 left_x += delta_left_x;
1398 left_u += delta_left_u;
1399 left_v += delta_left_v;
1400 }
1401
1402 if(--right_section_height<=0)
1403 {
1404 if(--right_section<=0) {return TRUE;}
1405 if(RightSection_FT() <=0) {return TRUE;}
1406 }
1407 else
1408 {
1409 right_x += delta_right_x;
1410 }
1411 return FALSE;
1412}
1413
1414////////////////////////////////////////////////////////////////////////
1415
a96a5eb2 1416static 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
1417{
1418 soft_vertex * v1, * v2, * v3;
1419 int height,longest,temp;
1420
1421 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1422 v1->u=tx1<<16;v1->v=ty1<<16;
1423 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1424 v2->u=tx2<<16;v2->v=ty2<<16;
1425 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1426 v3->u=tx3<<16;v3->v=ty3<<16;
1427
1428 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1429 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1430 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1431
1432 height = v3->y - v1->y;
1433 if(height == 0) {return FALSE;}
1434
1435 temp=(((v2->y - v1->y) << 16) / height);
1436 longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1437
1438 if(longest == 0) {return FALSE;}
1439
1440 if(longest < 0)
1441 {
1442 right_array[0] = v3;
1443 right_array[1] = v2;
1444 right_array[2] = v1;
1445 right_section = 2;
1446 left_array[0] = v3;
1447 left_array[1] = v1;
1448 left_section = 1;
1449
1450 if(LeftSection_FT() <= 0) return FALSE;
1451 if(RightSection_FT() <= 0)
1452 {
1453 right_section--;
1454 if(RightSection_FT() <= 0) return FALSE;
1455 }
1456 if(longest > -0x1000) longest = -0x1000;
1457 }
1458 else
1459 {
1460 left_array[0] = v3;
1461 left_array[1] = v2;
1462 left_array[2] = v1;
1463 left_section = 2;
1464 right_array[0] = v3;
1465 right_array[1] = v1;
1466 right_section = 1;
1467
1468 if(RightSection_FT() <= 0) return FALSE;
1469 if(LeftSection_FT() <= 0)
1470 {
1471 left_section--;
1472 if(LeftSection_FT() <= 0) return FALSE;
1473 }
1474 if(longest < 0x1000) longest = 0x1000;
1475 }
1476
1477 Ymin=v1->y;
1478 Ymax=min(v3->y-1,drawH);
1479
1480 delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1481 delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1482
ef79bbde
P
1483 return TRUE;
1484}
1485
1486////////////////////////////////////////////////////////////////////////
1487////////////////////////////////////////////////////////////////////////
1488
a96a5eb2 1489static inline int RightSection_GT(void)
ef79bbde
P
1490{
1491 soft_vertex * v1 = right_array[ right_section ];
1492 soft_vertex * v2 = right_array[ right_section-1 ];
1493
1494 int height = v2->y - v1->y;
1495 if(height == 0) return 0;
1496 delta_right_x = (v2->x - v1->x) / height;
1497 right_x = v1->x;
1498
1499 right_section_height = height;
1500 return height;
1501}
1502
1503////////////////////////////////////////////////////////////////////////
1504
a96a5eb2 1505static inline int LeftSection_GT(void)
ef79bbde
P
1506{
1507 soft_vertex * v1 = left_array[ left_section ];
1508 soft_vertex * v2 = left_array[ left_section-1 ];
1509
1510 int height = v2->y - v1->y;
1511 if(height == 0) return 0;
1512 delta_left_x = (v2->x - v1->x) / height;
1513 left_x = v1->x;
1514
1515 delta_left_u = ((v2->u - v1->u)) / height;
1516 left_u = v1->u;
1517 delta_left_v = ((v2->v - v1->v)) / height;
1518 left_v = v1->v;
1519
1520 delta_left_R = ((v2->R - v1->R)) / height;
1521 left_R = v1->R;
1522 delta_left_G = ((v2->G - v1->G)) / height;
1523 left_G = v1->G;
1524 delta_left_B = ((v2->B - v1->B)) / height;
1525 left_B = v1->B;
1526
1527 left_section_height = height;
1528 return height;
1529}
1530
1531////////////////////////////////////////////////////////////////////////
1532
a96a5eb2 1533static inline BOOL NextRow_GT(void)
ef79bbde
P
1534{
1535 if(--left_section_height<=0)
1536 {
1537 if(--left_section <= 0) {return TRUE;}
1538 if(LeftSection_GT() <= 0) {return TRUE;}
1539 }
1540 else
1541 {
1542 left_x += delta_left_x;
1543 left_u += delta_left_u;
1544 left_v += delta_left_v;
1545 left_R += delta_left_R;
1546 left_G += delta_left_G;
1547 left_B += delta_left_B;
1548 }
1549
1550 if(--right_section_height<=0)
1551 {
1552 if(--right_section<=0) {return TRUE;}
1553 if(RightSection_GT() <=0) {return TRUE;}
1554 }
1555 else
1556 {
1557 right_x += delta_right_x;
1558 }
1559 return FALSE;
1560}
1561
1562////////////////////////////////////////////////////////////////////////
1563
a96a5eb2 1564static 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
1565{
1566 soft_vertex * v1, * v2, * v3;
1567 int height,longest,temp;
1568
1569 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1570 v1->u=tx1<<16;v1->v=ty1<<16;
1571 v1->R=(rgb1) & 0x00ff0000;
1572 v1->G=(rgb1<<8) & 0x00ff0000;
1573 v1->B=(rgb1<<16) & 0x00ff0000;
1574
1575 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1576 v2->u=tx2<<16;v2->v=ty2<<16;
1577 v2->R=(rgb2) & 0x00ff0000;
1578 v2->G=(rgb2<<8) & 0x00ff0000;
1579 v2->B=(rgb2<<16) & 0x00ff0000;
1580
1581 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1582 v3->u=tx3<<16;v3->v=ty3<<16;
1583 v3->R=(rgb3) & 0x00ff0000;
1584 v3->G=(rgb3<<8) & 0x00ff0000;
1585 v3->B=(rgb3<<16) & 0x00ff0000;
1586
1587 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1588 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1589 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1590
1591 height = v3->y - v1->y;
1592 if(height == 0) {return FALSE;}
1593
1594 temp=(((v2->y - v1->y) << 16) / height);
1595 longest = temp * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1596
1597 if(longest == 0) {return FALSE;}
1598
1599 if(longest < 0)
1600 {
1601 right_array[0] = v3;
1602 right_array[1] = v2;
1603 right_array[2] = v1;
1604 right_section = 2;
1605 left_array[0] = v3;
1606 left_array[1] = v1;
1607 left_section = 1;
1608
1609 if(LeftSection_GT() <= 0) return FALSE;
1610 if(RightSection_GT() <= 0)
1611 {
1612 right_section--;
1613 if(RightSection_GT() <= 0) return FALSE;
1614 }
1615
1616 if(longest > -0x1000) longest = -0x1000;
1617 }
1618 else
1619 {
1620 left_array[0] = v3;
1621 left_array[1] = v2;
1622 left_array[2] = v1;
1623 left_section = 2;
1624 right_array[0] = v3;
1625 right_array[1] = v1;
1626 right_section = 1;
1627
1628 if(RightSection_GT() <= 0) return FALSE;
1629 if(LeftSection_GT() <= 0)
1630 {
1631 left_section--;
1632 if(LeftSection_GT() <= 0) return FALSE;
1633 }
1634 if(longest < 0x1000) longest = 0x1000;
1635 }
1636
1637 Ymin=v1->y;
1638 Ymax=min(v3->y-1,drawH);
1639
1640 delta_right_R=shl10idiv(temp*((v3->R - v1->R)>>10)+((v1->R - v2->R)<<6),longest);
1641 delta_right_G=shl10idiv(temp*((v3->G - v1->G)>>10)+((v1->G - v2->G)<<6),longest);
1642 delta_right_B=shl10idiv(temp*((v3->B - v1->B)>>10)+((v1->B - v2->B)<<6),longest);
1643
1644 delta_right_u=shl10idiv(temp*((v3->u - v1->u)>>10)+((v1->u - v2->u)<<6),longest);
1645 delta_right_v=shl10idiv(temp*((v3->v - v1->v)>>10)+((v1->v - v2->v)<<6),longest);
1646
ef79bbde
P
1647 return TRUE;
1648}
1649
1650////////////////////////////////////////////////////////////////////////
1651////////////////////////////////////////////////////////////////////////
1652
a96a5eb2 1653static inline int RightSection_F4(void)
ef79bbde
P
1654{
1655 soft_vertex * v1 = right_array[ right_section ];
1656 soft_vertex * v2 = right_array[ right_section-1 ];
1657
1658 int height = v2->y - v1->y;
1659 right_section_height = height;
1660 right_x = v1->x;
1661 if(height == 0)
1662 {
1663 return 0;
1664 }
1665 delta_right_x = (v2->x - v1->x) / height;
1666
1667 return height;
1668}
1669
1670////////////////////////////////////////////////////////////////////////
1671
a96a5eb2 1672static inline int LeftSection_F4(void)
ef79bbde
P
1673{
1674 soft_vertex * v1 = left_array[ left_section ];
1675 soft_vertex * v2 = left_array[ left_section-1 ];
1676
1677 int height = v2->y - v1->y;
1678 left_section_height = height;
1679 left_x = v1->x;
1680 if(height == 0)
1681 {
1682 return 0;
1683 }
1684 delta_left_x = (v2->x - v1->x) / height;
1685
1686 return height;
1687}
1688
1689////////////////////////////////////////////////////////////////////////
1690
a96a5eb2 1691static inline BOOL NextRow_F4(void)
ef79bbde
P
1692{
1693 if(--left_section_height<=0)
1694 {
1695 if(--left_section > 0)
1696 while(LeftSection_F4()<=0)
1697 {
1698 if(--left_section <= 0) break;
1699 }
1700 }
1701 else
1702 {
1703 left_x += delta_left_x;
1704 }
1705
1706 if(--right_section_height<=0)
1707 {
1708 if(--right_section > 0)
1709 while(RightSection_F4()<=0)
1710 {
1711 if(--right_section<=0) break;
1712 }
1713 }
1714 else
1715 {
1716 right_x += delta_right_x;
1717 }
1718 return FALSE;
1719}
1720
1721////////////////////////////////////////////////////////////////////////
1722
a96a5eb2 1723static inline BOOL SetupSections_F4(short x1, short y1, short x2, short y2, short x3, short y3, short x4, short y4)
ef79bbde
P
1724{
1725 soft_vertex * v1, * v2, * v3, * v4;
1726 int height,width,longest1,longest2;
1727
1728 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1729 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1730 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1731 v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1732
1733 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1734 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1735 if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1736 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1737 if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1738 if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1739
1740 height = v4->y - v1->y; if(height == 0) height =1;
1741 width = (v4->x - v1->x)>>16;
1742 longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1743 longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1744
1745 if(longest1 < 0) // 2 is right
1746 {
1747 if(longest2 < 0) // 3 is right
1748 {
1749 left_array[0] = v4;
1750 left_array[1] = v1;
1751 left_section = 1;
1752
1753 height = v3->y - v1->y; if(height == 0) height=1;
1754 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1755 if(longest1 >= 0)
1756 {
1757 right_array[0] = v4; // 1
1758 right_array[1] = v3; // 3
1759 right_array[2] = v1; // 4
1760 right_section = 2;
1761 }
1762 else
1763 {
1764 height = v4->y - v2->y; if(height == 0) height=1;
1765 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1766 if(longest1 >= 0)
1767 {
1768 right_array[0] = v4; // 1
1769 right_array[1] = v2; // 2
1770 right_array[2] = v1; // 4
1771 right_section = 2;
1772 }
1773 else
1774 {
1775 right_array[0] = v4; // 1
1776 right_array[1] = v3; // 2
1777 right_array[2] = v2; // 3
1778 right_array[3] = v1; // 4
1779 right_section = 3;
1780 }
1781 }
1782 }
1783 else
1784 {
1785 left_array[0] = v4;
1786 left_array[1] = v3; // 1
1787 left_array[2] = v1; // 2
1788 left_section = 2; // 3
1789 right_array[0] = v4; // 4
1790 right_array[1] = v2;
1791 right_array[2] = v1;
1792 right_section = 2;
1793 }
1794 }
1795 else
1796 {
1797 if(longest2 < 0)
1798 {
1799 left_array[0] = v4; // 1
1800 left_array[1] = v2; // 2
1801 left_array[2] = v1; // 3
1802 left_section = 2; // 4
1803 right_array[0] = v4;
1804 right_array[1] = v3;
1805 right_array[2] = v1;
1806 right_section = 2;
1807 }
1808 else
1809 {
1810 right_array[0] = v4;
1811 right_array[1] = v1;
1812 right_section = 1;
1813
1814 height = v3->y - v1->y; if(height == 0) height=1;
1815 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1816 if(longest1<0)
1817 {
1818 left_array[0] = v4; // 1
1819 left_array[1] = v3; // 3
1820 left_array[2] = v1; // 4
1821 left_section = 2;
1822 }
1823 else
1824 {
1825 height = v4->y - v2->y; if(height == 0) height=1;
1826 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1827 if(longest1<0)
1828 {
1829 left_array[0] = v4; // 1
1830 left_array[1] = v2; // 2
1831 left_array[2] = v1; // 4
1832 left_section = 2;
1833 }
1834 else
1835 {
1836 left_array[0] = v4; // 1
1837 left_array[1] = v3; // 2
1838 left_array[2] = v2; // 3
1839 left_array[3] = v1; // 4
1840 left_section = 3;
1841 }
1842 }
1843 }
1844 }
1845
1846 while(LeftSection_F4()<=0)
1847 {
1848 if(--left_section <= 0) break;
1849 }
1850
1851 while(RightSection_F4()<=0)
1852 {
1853 if(--right_section <= 0) break;
1854 }
1855
1856 Ymin=v1->y;
1857 Ymax=min(v4->y-1,drawH);
1858
1859 return TRUE;
1860}
1861
1862////////////////////////////////////////////////////////////////////////
1863////////////////////////////////////////////////////////////////////////
1864
a96a5eb2 1865static inline int RightSection_FT4(void)
ef79bbde
P
1866{
1867 soft_vertex * v1 = right_array[ right_section ];
1868 soft_vertex * v2 = right_array[ right_section-1 ];
1869
1870 int height = v2->y - v1->y;
1871 right_section_height = height;
1872 right_x = v1->x;
1873 right_u = v1->u;
1874 right_v = v1->v;
1875 if(height == 0)
1876 {
1877 return 0;
1878 }
1879 delta_right_x = (v2->x - v1->x) / height;
1880 delta_right_u = (v2->u - v1->u) / height;
1881 delta_right_v = (v2->v - v1->v) / height;
1882
1883 return height;
1884}
1885
1886////////////////////////////////////////////////////////////////////////
1887
a96a5eb2 1888static inline int LeftSection_FT4(void)
ef79bbde
P
1889{
1890 soft_vertex * v1 = left_array[ left_section ];
1891 soft_vertex * v2 = left_array[ left_section-1 ];
1892
1893 int height = v2->y - v1->y;
1894 left_section_height = height;
1895 left_x = v1->x;
1896 left_u = v1->u;
1897 left_v = v1->v;
1898 if(height == 0)
1899 {
1900 return 0;
1901 }
1902 delta_left_x = (v2->x - v1->x) / height;
1903 delta_left_u = (v2->u - v1->u) / height;
1904 delta_left_v = (v2->v - v1->v) / height;
1905
1906 return height;
1907}
1908
1909////////////////////////////////////////////////////////////////////////
1910
a96a5eb2 1911static inline BOOL NextRow_FT4(void)
ef79bbde
P
1912{
1913 if(--left_section_height<=0)
1914 {
1915 if(--left_section > 0)
1916 while(LeftSection_FT4()<=0)
1917 {
1918 if(--left_section <= 0) break;
1919 }
1920 }
1921 else
1922 {
1923 left_x += delta_left_x;
1924 left_u += delta_left_u;
1925 left_v += delta_left_v;
1926 }
1927
1928 if(--right_section_height<=0)
1929 {
1930 if(--right_section > 0)
1931 while(RightSection_FT4()<=0)
1932 {
1933 if(--right_section<=0) break;
1934 }
1935 }
1936 else
1937 {
1938 right_x += delta_right_x;
1939 right_u += delta_right_u;
1940 right_v += delta_right_v;
1941 }
1942 return FALSE;
1943}
1944
1945////////////////////////////////////////////////////////////////////////
1946
a96a5eb2 1947static 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
1948{
1949 soft_vertex * v1, * v2, * v3, * v4;
1950 int height,width,longest1,longest2;
1951
1952 v1 = vtx; v1->x=x1<<16;v1->y=y1;
1953 v1->u=tx1<<16;v1->v=ty1<<16;
1954
1955 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
1956 v2->u=tx2<<16;v2->v=ty2<<16;
1957
1958 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
1959 v3->u=tx3<<16;v3->v=ty3<<16;
1960
1961 v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
1962 v4->u=tx4<<16;v4->v=ty4<<16;
1963
1964 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
1965 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
1966 if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
1967 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
1968 if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
1969 if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
1970
1971 height = v4->y - v1->y; if(height == 0) height =1;
1972 width = (v4->x - v1->x)>>16;
1973 longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
1974 longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
1975
1976 if(longest1 < 0) // 2 is right
1977 {
1978 if(longest2 < 0) // 3 is right
1979 {
1980 left_array[0] = v4;
1981 left_array[1] = v1;
1982 left_section = 1;
1983
1984 height = v3->y - v1->y; if(height == 0) height=1;
1985 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
1986 if(longest1 >= 0)
1987 {
1988 right_array[0] = v4; // 1
1989 right_array[1] = v3; // 3
1990 right_array[2] = v1; // 4
1991 right_section = 2;
1992 }
1993 else
1994 {
1995 height = v4->y - v2->y; if(height == 0) height=1;
1996 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
1997 if(longest1 >= 0)
1998 {
1999 right_array[0] = v4; // 1
2000 right_array[1] = v2; // 2
2001 right_array[2] = v1; // 4
2002 right_section = 2;
2003 }
2004 else
2005 {
2006 right_array[0] = v4; // 1
2007 right_array[1] = v3; // 2
2008 right_array[2] = v2; // 3
2009 right_array[3] = v1; // 4
2010 right_section = 3;
2011 }
2012 }
2013 }
2014 else
2015 {
2016 left_array[0] = v4;
2017 left_array[1] = v3; // 1
2018 left_array[2] = v1; // 2
2019 left_section = 2; // 3
2020 right_array[0] = v4; // 4
2021 right_array[1] = v2;
2022 right_array[2] = v1;
2023 right_section = 2;
2024 }
2025 }
2026 else
2027 {
2028 if(longest2 < 0)
2029 {
2030 left_array[0] = v4; // 1
2031 left_array[1] = v2; // 2
2032 left_array[2] = v1; // 3
2033 left_section = 2; // 4
2034 right_array[0] = v4;
2035 right_array[1] = v3;
2036 right_array[2] = v1;
2037 right_section = 2;
2038 }
2039 else
2040 {
2041 right_array[0] = v4;
2042 right_array[1] = v1;
2043 right_section = 1;
2044
2045 height = v3->y - v1->y; if(height == 0) height=1;
2046 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2047 if(longest1<0)
2048 {
2049 left_array[0] = v4; // 1
2050 left_array[1] = v3; // 3
2051 left_array[2] = v1; // 4
2052 left_section = 2;
2053 }
2054 else
2055 {
2056 height = v4->y - v2->y; if(height == 0) height=1;
2057 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2058 if(longest1<0)
2059 {
2060 left_array[0] = v4; // 1
2061 left_array[1] = v2; // 2
2062 left_array[2] = v1; // 4
2063 left_section = 2;
2064 }
2065 else
2066 {
2067 left_array[0] = v4; // 1
2068 left_array[1] = v3; // 2
2069 left_array[2] = v2; // 3
2070 left_array[3] = v1; // 4
2071 left_section = 3;
2072 }
2073 }
2074 }
2075 }
2076
2077 while(LeftSection_FT4()<=0)
2078 {
2079 if(--left_section <= 0) break;
2080 }
2081
2082 while(RightSection_FT4()<=0)
2083 {
2084 if(--right_section <= 0) break;
2085 }
2086
2087 Ymin=v1->y;
2088 Ymax=min(v4->y-1,drawH);
2089
2090 return TRUE;
2091}
2092
2093////////////////////////////////////////////////////////////////////////
2094////////////////////////////////////////////////////////////////////////
2095
a96a5eb2 2096static inline int RightSection_GT4(void)
ef79bbde
P
2097{
2098 soft_vertex * v1 = right_array[ right_section ];
2099 soft_vertex * v2 = right_array[ right_section-1 ];
2100
2101 int height = v2->y - v1->y;
2102 right_section_height = height;
2103 right_x = v1->x;
2104 right_u = v1->u;
2105 right_v = v1->v;
2106 right_R = v1->R;
2107 right_G = v1->G;
2108 right_B = v1->B;
2109
2110 if(height == 0)
2111 {
2112 return 0;
2113 }
2114 delta_right_x = (v2->x - v1->x) / height;
2115 delta_right_u = (v2->u - v1->u) / height;
2116 delta_right_v = (v2->v - v1->v) / height;
2117 delta_right_R = (v2->R - v1->R) / height;
2118 delta_right_G = (v2->G - v1->G) / height;
2119 delta_right_B = (v2->B - v1->B) / height;
2120
2121 return height;
2122}
2123
2124////////////////////////////////////////////////////////////////////////
2125
a96a5eb2 2126static inline int LeftSection_GT4(void)
ef79bbde
P
2127{
2128 soft_vertex * v1 = left_array[ left_section ];
2129 soft_vertex * v2 = left_array[ left_section-1 ];
2130
2131 int height = v2->y - v1->y;
2132 left_section_height = height;
2133 left_x = v1->x;
2134 left_u = v1->u;
2135 left_v = v1->v;
2136 left_R = v1->R;
2137 left_G = v1->G;
2138 left_B = v1->B;
2139
2140 if(height == 0)
2141 {
2142 return 0;
2143 }
2144 delta_left_x = (v2->x - v1->x) / height;
2145 delta_left_u = (v2->u - v1->u) / height;
2146 delta_left_v = (v2->v - v1->v) / height;
2147 delta_left_R = (v2->R - v1->R) / height;
2148 delta_left_G = (v2->G - v1->G) / height;
2149 delta_left_B = (v2->B - v1->B) / height;
2150
2151 return height;
2152}
2153
2154////////////////////////////////////////////////////////////////////////
2155
a96a5eb2 2156static inline BOOL NextRow_GT4(void)
ef79bbde
P
2157{
2158 if(--left_section_height<=0)
2159 {
2160 if(--left_section > 0)
2161 while(LeftSection_GT4()<=0)
2162 {
2163 if(--left_section <= 0) break;
2164 }
2165 }
2166 else
2167 {
2168 left_x += delta_left_x;
2169 left_u += delta_left_u;
2170 left_v += delta_left_v;
2171 left_R += delta_left_R;
2172 left_G += delta_left_G;
2173 left_B += delta_left_B;
2174 }
2175
2176 if(--right_section_height<=0)
2177 {
2178 if(--right_section > 0)
2179 while(RightSection_GT4()<=0)
2180 {
2181 if(--right_section<=0) break;
2182 }
2183 }
2184 else
2185 {
2186 right_x += delta_right_x;
2187 right_u += delta_right_u;
2188 right_v += delta_right_v;
2189 right_R += delta_right_R;
2190 right_G += delta_right_G;
2191 right_B += delta_right_B;
2192 }
2193 return FALSE;
2194}
2195
2196////////////////////////////////////////////////////////////////////////
2197
a96a5eb2 2198static 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
2199{
2200 soft_vertex * v1, * v2, * v3, * v4;
2201 int height,width,longest1,longest2;
2202
2203 v1 = vtx; v1->x=x1<<16;v1->y=y1;
2204 v1->u=tx1<<16;v1->v=ty1<<16;
2205 v1->R=(rgb1) & 0x00ff0000;
2206 v1->G=(rgb1<<8) & 0x00ff0000;
2207 v1->B=(rgb1<<16) & 0x00ff0000;
2208
2209 v2 = vtx+1; v2->x=x2<<16;v2->y=y2;
2210 v2->u=tx2<<16;v2->v=ty2<<16;
2211 v2->R=(rgb2) & 0x00ff0000;
2212 v2->G=(rgb2<<8) & 0x00ff0000;
2213 v2->B=(rgb2<<16) & 0x00ff0000;
2214
2215 v3 = vtx+2; v3->x=x3<<16;v3->y=y3;
2216 v3->u=tx3<<16;v3->v=ty3<<16;
2217 v3->R=(rgb3) & 0x00ff0000;
2218 v3->G=(rgb3<<8) & 0x00ff0000;
2219 v3->B=(rgb3<<16) & 0x00ff0000;
2220
2221 v4 = vtx+3; v4->x=x4<<16;v4->y=y4;
2222 v4->u=tx4<<16;v4->v=ty4<<16;
2223 v4->R=(rgb4) & 0x00ff0000;
2224 v4->G=(rgb4<<8) & 0x00ff0000;
2225 v4->B=(rgb4<<16) & 0x00ff0000;
2226
2227 if(v1->y > v2->y) { soft_vertex * v = v1; v1 = v2; v2 = v; }
2228 if(v1->y > v3->y) { soft_vertex * v = v1; v1 = v3; v3 = v; }
2229 if(v1->y > v4->y) { soft_vertex * v = v1; v1 = v4; v4 = v; }
2230 if(v2->y > v3->y) { soft_vertex * v = v2; v2 = v3; v3 = v; }
2231 if(v2->y > v4->y) { soft_vertex * v = v2; v2 = v4; v4 = v; }
2232 if(v3->y > v4->y) { soft_vertex * v = v3; v3 = v4; v4 = v; }
2233
2234 height = v4->y - v1->y; if(height == 0) height =1;
2235 width = (v4->x - v1->x)>>16;
2236 longest1 = (((v2->y - v1->y) << 16) / height) * width + (v1->x - v2->x);
2237 longest2 = (((v3->y - v1->y) << 16) / height) * width + (v1->x - v3->x);
2238
2239 if(longest1 < 0) // 2 is right
2240 {
2241 if(longest2 < 0) // 3 is right
2242 {
2243 left_array[0] = v4;
2244 left_array[1] = v1;
2245 left_section = 1;
2246
2247 height = v3->y - v1->y; if(height == 0) height=1;
2248 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2249 if(longest1 >= 0)
2250 {
2251 right_array[0] = v4; // 1
2252 right_array[1] = v3; // 3
2253 right_array[2] = v1; // 4
2254 right_section = 2;
2255 }
2256 else
2257 {
2258 height = v4->y - v2->y; if(height == 0) height=1;
2259 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2260 if(longest1 >= 0)
2261 {
2262 right_array[0] = v4; // 1
2263 right_array[1] = v2; // 2
2264 right_array[2] = v1; // 4
2265 right_section = 2;
2266 }
2267 else
2268 {
2269 right_array[0] = v4; // 1
2270 right_array[1] = v3; // 2
2271 right_array[2] = v2; // 3
2272 right_array[3] = v1; // 4
2273 right_section = 3;
2274 }
2275 }
2276 }
2277 else
2278 {
2279 left_array[0] = v4;
2280 left_array[1] = v3; // 1
2281 left_array[2] = v1; // 2
2282 left_section = 2; // 3
2283 right_array[0] = v4; // 4
2284 right_array[1] = v2;
2285 right_array[2] = v1;
2286 right_section = 2;
2287 }
2288 }
2289 else
2290 {
2291 if(longest2 < 0)
2292 {
2293 left_array[0] = v4; // 1
2294 left_array[1] = v2; // 2
2295 left_array[2] = v1; // 3
2296 left_section = 2; // 4
2297 right_array[0] = v4;
2298 right_array[1] = v3;
2299 right_array[2] = v1;
2300 right_section = 2;
2301 }
2302 else
2303 {
2304 right_array[0] = v4;
2305 right_array[1] = v1;
2306 right_section = 1;
2307
2308 height = v3->y - v1->y; if(height == 0) height=1;
2309 longest1 = (((v2->y - v1->y) << 16) / height) * ((v3->x - v1->x)>>16) + (v1->x - v2->x);
2310 if(longest1<0)
2311 {
2312 left_array[0] = v4; // 1
2313 left_array[1] = v3; // 3
2314 left_array[2] = v1; // 4
2315 left_section = 2;
2316 }
2317 else
2318 {
2319 height = v4->y - v2->y; if(height == 0) height=1;
2320 longest1 = (((v3->y - v2->y) << 16) / height) * ((v4->x - v2->x)>>16) + (v2->x - v3->x);
2321 if(longest1<0)
2322 {
2323 left_array[0] = v4; // 1
2324 left_array[1] = v2; // 2
2325 left_array[2] = v1; // 4
2326 left_section = 2;
2327 }
2328 else
2329 {
2330 left_array[0] = v4; // 1
2331 left_array[1] = v3; // 2
2332 left_array[2] = v2; // 3
2333 left_array[3] = v1; // 4
2334 left_section = 3;
2335 }
2336 }
2337 }
2338 }
2339
2340 while(LeftSection_GT4()<=0)
2341 {
2342 if(--left_section <= 0) break;
2343 }
2344
2345 while(RightSection_GT4()<=0)
2346 {
2347 if(--right_section <= 0) break;
2348 }
2349
2350 Ymin=v1->y;
2351 Ymax=min(v4->y-1,drawH);
2352
2353 return TRUE;
2354}
2355
2356////////////////////////////////////////////////////////////////////////
2357////////////////////////////////////////////////////////////////////////
2358////////////////////////////////////////////////////////////////////////
2359// POLY FUNCS
2360////////////////////////////////////////////////////////////////////////
2361////////////////////////////////////////////////////////////////////////
2362////////////////////////////////////////////////////////////////////////
2363
2364////////////////////////////////////////////////////////////////////////
2365// POLY 3/4 FLAT SHADED
2366////////////////////////////////////////////////////////////////////////
2367
a96a5eb2 2368static inline void drawPoly3Fi(short x1,short y1,short x2,short y2,short x3,short y3,int32_t rgb)
ef79bbde
P
2369{
2370 int i,j,xmin,xmax,ymin,ymax;
2371 unsigned short color;uint32_t lcolor;
2372
2373 if(x1>drawW && x2>drawW && x3>drawW) return;
2374 if(y1>drawH && y2>drawH && y3>drawH) return;
2375 if(x1<drawX && x2<drawX && x3<drawX) return;
2376 if(y1<drawY && y2<drawY && y3<drawY) return;
2377 if(drawY>=drawH) return;
2378 if(drawX>=drawW) return;
2379
2380 if(!SetupSections_F(x1,y1,x2,y2,x3,y3)) return;
2381
2382 ymax=Ymax;
2383
2384 color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2385 lcolor=lSetMask|(((uint32_t)(color))<<16)|color;
2386
2387 for(ymin=Ymin;ymin<drawY;ymin++)
2388 if(NextRow_F()) return;
2389
2390#ifdef FASTSOLID
2391
2392 if(!bCheckMask && !DrawSemiTrans)
2393 {
2394 color |=sSetMask;
2395 for (i=ymin;i<=ymax;i++)
2396 {
2397 xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
2398 xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2399
2400 for(j=xmin;j<xmax;j+=2)
2401 {
2402 PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2403 }
2404 if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2405
2406 if(NextRow_F()) return;
2407 }
2408 return;
2409 }
2410
2411#endif
2412
2413 for (i=ymin;i<=ymax;i++)
2414 {
2415 xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
2416 xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2417
2418 for(j=xmin;j<xmax;j+=2)
2419 {
2420 GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2421 }
2422 if(j==xmax)
2423 GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2424
2425 if(NextRow_F()) return;
2426 }
2427}
2428
2429////////////////////////////////////////////////////////////////////////
2430
a96a5eb2 2431static void drawPoly3F(int32_t rgb)
ef79bbde
P
2432{
2433 drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2434}
2435
2436#ifdef POLYQUAD3FS
2437
a96a5eb2 2438static void drawPoly4F_TRI(int32_t rgb)
ef79bbde
P
2439{
2440 drawPoly3Fi(lx1,ly1,lx3,ly3,lx2,ly2,rgb);
2441 drawPoly3Fi(lx0,ly0,lx1,ly1,lx2,ly2,rgb);
2442}
2443
2444#endif
2445
2446// more exact:
2447
a96a5eb2 2448static void drawPoly4F(int32_t rgb)
ef79bbde
P
2449{
2450 int i,j,xmin,xmax,ymin,ymax;
2451 unsigned short color;uint32_t lcolor;
2452
2453 if(lx0>drawW && lx1>drawW && lx2>drawW && lx3>drawW) return;
2454 if(ly0>drawH && ly1>drawH && ly2>drawH && ly3>drawH) return;
2455 if(lx0<drawX && lx1<drawX && lx2<drawX && lx3<drawX) return;
2456 if(ly0<drawY && ly1<drawY && ly2<drawY && ly3<drawY) return;
2457 if(drawY>=drawH) return;
2458 if(drawX>=drawW) return;
2459
2460 if(!SetupSections_F4(lx0,ly0,lx1,ly1,lx2,ly2,lx3,ly3)) return;
2461
2462 ymax=Ymax;
2463
2464 for(ymin=Ymin;ymin<drawY;ymin++)
2465 if(NextRow_F4()) return;
2466
2467 color = ((rgb & 0x00f80000)>>9) | ((rgb & 0x0000f800)>>6) | ((rgb & 0x000000f8)>>3);
2468 lcolor= lSetMask|(((uint32_t)(color))<<16)|color;
2469
2470#ifdef FASTSOLID
2471
2472 if(!bCheckMask && !DrawSemiTrans)
2473 {
2474 color |=sSetMask;
2475 for (i=ymin;i<=ymax;i++)
2476 {
2477 xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
2478 xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2479
2480 for(j=xmin;j<xmax;j+=2)
2481 {
2482 PUTLE32(((uint32_t *)&psxVuw[(i<<10)+j]), lcolor);
2483 }
2484 if(j==xmax) PUTLE16(&psxVuw[(i<<10)+j], color);
2485
2486 if(NextRow_F4()) return;
2487 }
2488 return;
2489 }
2490
2491#endif
2492
2493 for (i=ymin;i<=ymax;i++)
2494 {
2495 xmin=left_x >> 16; if(drawX>xmin) xmin=drawX;
2496 xmax=(right_x >> 16)-1; if(drawW<xmax) xmax=drawW;
2497
2498 for(j=xmin;j<xmax;j+=2)
2499 {
2500 GetShadeTransCol32((uint32_t *)&psxVuw[(i<<10)+j],lcolor);
2501 }
2502 if(j==xmax) GetShadeTransCol(&psxVuw[(i<<10)+j],color);
2503
2504 if(NextRow_F4()) return;
2505 }
2506}
2507
2508////////////////////////////////////////////////////////////////////////
2509// POLY 3/4 F-SHADED TEX PAL 4
2510////////////////////////////////////////////////////////////////////////
2511
a96a5eb2 2512static 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
2513{
2514 int i,j,xmin,xmax,ymin,ymax;
2515 int32_t difX, difY,difX2, difY2;
2516 int32_t posX,posY,YAdjust,XAdjust;
2517 int32_t clutP;
2518 short tC1,tC2;
2519
2520 if(x1>drawW && x2>drawW && x3>drawW) return;
2521 if(y1>drawH && y2>drawH && y3>drawH) return;
2522 if(x1<drawX && x2<drawX && x3<drawX) return;
2523 if(y1<drawY && y2<drawY && y3<drawY) return;
2524 if(drawY>=drawH) return;
2525 if(drawX>=drawW) return;
2526
2527 if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2528
2529 ymax=Ymax;
2530
2531 for(ymin=Ymin;ymin<drawY;ymin++)
2532 if(NextRow_FT()) return;
2533
2534 clutP=(clY<<10)+clX;
2535
2536 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2537
2538 difX=delta_right_u;difX2=difX<<1;
2539 difY=delta_right_v;difY2=difY<<1;
2540
2541#ifdef FASTSOLID
2542
2543 if(!bCheckMask && !DrawSemiTrans)
2544 {
2545 for (i=ymin;i<=ymax;i++)
2546 {
2547 xmin=(left_x >> 16);
2548 xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!
2549 if(drawW<xmax) xmax=drawW;
2550
2551 if(xmax>=xmin)
2552 {
2553 posX=left_u;
2554 posY=left_v;
2555
2556 if(xmin<drawX)
2557 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2558
2559 for(j=xmin;j<xmax;j+=2)
2560 {
2561 XAdjust=(posX>>16);
2562 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2563 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2564 XAdjust=((posX+difX)>>16);
2565 tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2566 (XAdjust>>1)];
2567 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2568
2569 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2570 GETLE16(&psxVuw[clutP+tC1])|
2571 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2572
2573 posX+=difX2;
2574 posY+=difY2;
2575 }
2576 if(j==xmax)
2577 {
2578 XAdjust=(posX>>16);
2579 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2580 (XAdjust>>1)];
2581 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2582 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2583 }
2584 }
2585 if(NextRow_FT())
2586 {
2587 return;
2588 }
2589 }
2590 return;
2591 }
2592
2593#endif
2594
2595 for (i=ymin;i<=ymax;i++)
2596 {
2597 xmin=(left_x >> 16);
2598 xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2599 if(drawW<xmax) xmax=drawW;
2600
2601 if(xmax>=xmin)
2602 {
2603 posX=left_u;
2604 posY=left_v;
2605
2606 if(xmin<drawX)
2607 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2608
2609 for(j=xmin;j<xmax;j+=2)
2610 {
2611 XAdjust=(posX>>16);
2612 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
2613 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2614 XAdjust=((posX+difX)>>16);
2615 tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
2616 (XAdjust>>1)];
2617 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2618
2619 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2620 GETLE16(&psxVuw[clutP+tC1])|
2621 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2622
2623 posX+=difX2;
2624 posY+=difY2;
2625 }
2626 if(j==xmax)
2627 {
2628 XAdjust=(posX>>16);
2629 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
2630 (XAdjust>>1)];
2631 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2632 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2633 }
2634 }
2635 if(NextRow_FT())
2636 {
2637 return;
2638 }
2639 }
2640}
2641
2642////////////////////////////////////////////////////////////////////////
2643
a96a5eb2 2644static 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
2645{
2646 int i,j,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
2647 int32_t difX, difY,difX2, difY2;
2648 int32_t posX,posY,YAdjust,XAdjust;
2649 int32_t clutP;
2650 short tC1,tC2;
2651
2652 if(x1>drawW && x2>drawW && x3>drawW) return;
2653 if(y1>drawH && y2>drawH && y3>drawH) return;
2654 if(x1<drawX && x2<drawX && x3<drawX) return;
2655 if(y1<drawY && y2<drawY && y3<drawY) return;
2656 if(drawY>=drawH) return;
2657 if(drawX>=drawW) return;
2658
2659 if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2660
2661 ymax=Ymax;
2662
2663 for(ymin=Ymin;ymin<drawY;ymin++)
2664 if(NextRow_FT()) return;
2665
2666 clutP=(clY<<10)+clX;
2667
2668 YAdjust=(GlobalTextAddrY<<10)+GlobalTextAddrX;
2669
2670 difX=delta_right_u;difX2=difX<<1;
2671 difY=delta_right_v;difY2=difY<<1;
2672
2673#ifdef FASTSOLID
2674
2675 if(!bCheckMask && !DrawSemiTrans)
2676 {
2677 for (i=ymin;i<=ymax;i++)
2678 {
2679 xmin=(left_x >> 16);
2680 xmax=(right_x >> 16)-1;
2681 if(drawW<xmax) xmax=drawW;
2682
2683 if(xmax>=xmin)
2684 {
2685 posX=left_u;
2686 posY=left_v;
2687
2688 if(xmin<drawX)
2689 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2690
2691 for(j=xmin;j<xmax;j+=2)
2692 {
2693 XAdjust=(posX>>16);
2694
2695 TXV=posY>>16;
2696 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2697 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2698
2699 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2700
2701 XAdjust=((posX+difX)>>16);
2702
2703 TXV=(posY+difY)>>16;
2704 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2705 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2706
2707 tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2708
2709 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2710 GETLE16(&psxVuw[clutP+tC1])|
2711 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2712
2713 posX+=difX2;
2714 posY+=difY2;
2715 }
2716 if(j==xmax)
2717 {
2718 XAdjust=(posX>>16);
2719
2720 TXV=posY>>16;
2721 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2722 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2723
2724 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2725
2726 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2727 }
2728 }
2729 if(NextRow_FT())
2730 {
2731 return;
2732 }
2733 }
2734 return;
2735 }
2736
2737#endif
2738
2739 for (i=ymin;i<=ymax;i++)
2740 {
2741 xmin=(left_x >> 16);
2742 xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2743 if(drawW<xmax) xmax=drawW;
2744
2745 if(xmax>=xmin)
2746 {
2747 posX=left_u;
2748 posY=left_v;
2749
2750 if(xmin<drawX)
2751 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2752
2753 for(j=xmin;j<xmax;j+=2)
2754 {
2755 XAdjust=(posX>>16);
2756
2757 TXV=posY>>16;
2758 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2759 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2760
2761 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2762
2763 XAdjust=((posX+difX)>>16);
2764
2765 TXV=(posY+difY)>>16;
2766 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2767 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2768
2769 tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2770
2771 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2772 GETLE16(&psxVuw[clutP+tC1])|
2773 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2774
2775 posX+=difX2;
2776 posY+=difY2;
2777 }
2778 if(j==xmax)
2779 {
2780 XAdjust=(posX>>16);
2781
2782 TXV=posY>>16;
2783 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
2784 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
2785
2786 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
2787
2788 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2789 }
2790 }
2791 if(NextRow_FT())
2792 {
2793 return;
2794 }
2795 }
2796}
2797
2798////////////////////////////////////////////////////////////////////////
2799
a96a5eb2 2800static 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
2801{
2802 int i,j,xmin,xmax,ymin,ymax;
2803 int32_t difX, difY,difX2, difY2;
2804 int32_t posX,posY,YAdjust,XAdjust;
2805 int32_t clutP;
2806 short tC1,tC2;
2807
2808 if(x1>drawW && x2>drawW && x3>drawW) return;
2809 if(y1>drawH && y2>drawH && y3>drawH) return;
2810 if(x1<drawX && x2<drawX && x3<drawX) return;
2811 if(y1<drawY && y2<drawY && y3<drawY) return;
2812 if(drawY>=drawH) return;
2813 if(drawX>=drawW) return;
2814
2815 if(!SetupSections_FT(x1,y1,x2,y2,x3,y3,tx1,ty1,tx2,ty2,tx3,ty3)) return;
2816
2817 ymax=Ymax;
2818
2819 for(ymin=Ymin;ymin<drawY;ymin++)
2820 if(NextRow_FT()) return;
2821
2822 clutP=(clY<<10)+clX;
2823
2824 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2825 YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
2826
2827 difX=delta_right_u;difX2=difX<<1;
2828 difY=delta_right_v;difY2=difY<<1;
2829
2830#ifdef FASTSOLID
2831
2832 if(!bCheckMask && !DrawSemiTrans)
2833 {
2834 for (i=ymin;i<=ymax;i++)
2835 {
2836 xmin=(left_x >> 16);
2837 xmax=(right_x >> 16);//-1; //!!!!!!!!!!!!!!!!
2838 if(xmax>xmin) xmax--;
2839
2840 if(drawW<xmax) xmax=drawW;
2841
2842 if(xmax>=xmin)
2843 {
2844 posX=left_u;
2845 posY=left_v;
2846
2847 if(xmin<drawX)
2848 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2849
2850 for(j=xmin;j<xmax;j+=2)
2851 {
2852 XAdjust=(posX>>16)%TWin.Position.x1;
2853 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2854 YAdjust+(XAdjust>>1)];
2855 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2856 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
2857 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
2858 YAdjust+(XAdjust>>1)];
2859 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2860
2861 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
2862 GETLE16(&psxVuw[clutP+tC1])|
2863 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2864
2865 posX+=difX2;
2866 posY+=difY2;
2867 }
2868 if(j==xmax)
2869 {
2870 XAdjust=(posX>>16)%TWin.Position.x1;
2871 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2872 YAdjust+(XAdjust>>1)];
2873 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2874 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2875 }
2876 }
2877 if(NextRow_FT())
2878 {
2879 return;
2880 }
2881 }
2882 return;
2883 }
2884
2885#endif
2886
2887 for (i=ymin;i<=ymax;i++)
2888 {
2889 xmin=(left_x >> 16);
2890 xmax=(right_x >> 16)-1; //!!!!!!!!!!!!!!!!!!
2891 if(drawW<xmax) xmax=drawW;
2892
2893 if(xmax>=xmin)
2894 {
2895 posX=left_u;
2896 posY=left_v;
2897
2898 if(xmin<drawX)
2899 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
2900
2901 for(j=xmin;j<xmax;j+=2)
2902 {
2903 XAdjust=(posX>>16)%TWin.Position.x1;
2904 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2905 YAdjust+(XAdjust>>1)];
2906 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2907 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
2908 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
2909 YAdjust+(XAdjust>>1)];
2910 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
2911
2912 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
2913 GETLE16(&psxVuw[clutP+tC1])|
2914 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
2915
2916 posX+=difX2;
2917 posY+=difY2;
2918 }
2919 if(j==xmax)
2920 {
2921 XAdjust=(posX>>16)%TWin.Position.x1;
2922 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
2923 YAdjust+(XAdjust>>1)];
2924 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
2925 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
2926 }
2927 }
2928 if(NextRow_FT())
2929 {
2930 return;
2931 }
2932 }
2933}
2934
2935////////////////////////////////////////////////////////////////////////
2936
2937#ifdef POLYQUAD3
2938
a96a5eb2 2939static 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
2940{
2941 drawPoly3TEx4(x2,y2,x3,y3,x4,y4,
2942 tx2,ty2,tx3,ty3,tx4,ty4,
2943 clX,clY);
2944 drawPoly3TEx4(x1,y1,x2,y2,x4,y4,
2945 tx1,ty1,tx2,ty2,tx4,ty4,
2946 clX,clY);
2947}
2948
2949#endif
2950
2951// more exact:
2952
a96a5eb2 2953static 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
2954{
2955 int32_t num;
2956 int32_t i,j,xmin,xmax,ymin,ymax;
2957 int32_t difX, difY, difX2, difY2;
2958 int32_t posX,posY,YAdjust,clutP,XAdjust;
2959 short tC1,tC2;
2960
2961 if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
2962 if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
2963 if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
2964 if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
2965 if(drawY>=drawH) return;
2966 if(drawX>=drawW) return;
2967
2968 if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
2969
2970 ymax=Ymax;
2971
2972 for(ymin=Ymin;ymin<drawY;ymin++)
2973 if(NextRow_FT4()) return;
2974
2975 clutP=(clY<<10)+clX;
2976
2977 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
2978
2979#ifdef FASTSOLID
2980
2981 if(!bCheckMask && !DrawSemiTrans)
2982 {
2983 for (i=ymin;i<=ymax;i++)
2984 {
2985 xmin=(left_x >> 16);
2986 xmax=(right_x >> 16);
2987
2988 if(xmax>=xmin)
2989 {
2990 posX=left_u;
2991 posY=left_v;
2992
2993 num=(xmax-xmin);
2994 if(num==0) num=1;
2995 difX=(right_u-posX)/num;
2996 difY=(right_v-posY)/num;
2997 difX2=difX<<1;
2998 difY2=difY<<1;
2999
3000 if(xmin<drawX)
3001 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3002 xmax--;if(drawW<xmax) xmax=drawW;
3003
3004 for(j=xmin;j<xmax;j+=2)
3005 {
3006 XAdjust=(posX>>16);
3007 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3008 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3009 XAdjust=((posX+difX)>>16);
3010 tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3011 (XAdjust>>1)];
3012 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3013
3014 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3015 GETLE16(&psxVuw[clutP+tC1])|
3016 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3017 posX+=difX2;
3018 posY+=difY2;
3019 }
3020 if(j==xmax)
3021 {
3022 XAdjust=(posX>>16);
3023 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3024 (XAdjust>>1)];
3025 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3026 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3027 }
3028
3029 }
3030 if(NextRow_FT4()) return;
3031 }
3032 return;
3033 }
3034
3035#endif
3036
3037 for (i=ymin;i<=ymax;i++)
3038 {
3039 xmin=(left_x >> 16);
3040 xmax=(right_x >> 16);
3041
3042 if(xmax>=xmin)
3043 {
3044 posX=left_u;
3045 posY=left_v;
3046
3047 num=(xmax-xmin);
3048 if(num==0) num=1;
3049 difX=(right_u-posX)/num;
3050 difY=(right_v-posY)/num;
3051 difX2=difX<<1;
3052 difY2=difY<<1;
3053
3054 if(xmin<drawX)
3055 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3056 xmax--;if(drawW<xmax) xmax=drawW;
3057
3058 for(j=xmin;j<xmax;j+=2)
3059 {
3060 XAdjust=(posX>>16);
3061 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+(XAdjust>>1)];
3062 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3063 XAdjust=((posX+difX)>>16);
3064 tC2 = psxVub[(((posY+difY)>>5)&(int32_t)0xFFFFF800)+YAdjust+
3065 (XAdjust>>1)];
3066 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3067
3068 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3069 GETLE16(&psxVuw[clutP+tC1])|
3070 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3071 posX+=difX2;
3072 posY+=difY2;
3073 }
3074 if(j==xmax)
3075 {
3076 XAdjust=(posX>>16);
3077 tC1 = psxVub[((posY>>5)&(int32_t)0xFFFFF800)+YAdjust+
3078 (XAdjust>>1)];
3079 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3080 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3081 }
3082 }
3083 if(NextRow_FT4()) return;
3084 }
3085}
3086
3087////////////////////////////////////////////////////////////////////////
3088
a96a5eb2 3089static 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
3090{
3091 int32_t num;
3092 int32_t i,j=0,xmin,xmax,ymin,ymax,n_xi,n_yi,TXV;
3093 int32_t difX, difY, difX2, difY2;
3094 int32_t posX=0,posY=0,YAdjust,clutP,XAdjust;
3095 short tC1,tC2;
3096
3097 if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3098 if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3099 if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3100 if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3101 if(drawY>=drawH) return;
3102 if(drawX>=drawW) return;
3103
3104 if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3105
3106 ymax=Ymax;
3107
3108 for(ymin=Ymin;ymin<drawY;ymin++)
3109 if(NextRow_FT4()) return;
3110
3111 clutP=(clY<<10)+clX;
3112
3113 YAdjust=((GlobalTextAddrY)<<10)+GlobalTextAddrX;
3114
3115#ifdef FASTSOLID
3116
3117 if(!bCheckMask && !DrawSemiTrans)
3118 {
3119 for (i=ymin;i<=ymax;i++)
3120 {
3121 xmin=(left_x >> 16);
3122 xmax=(right_x >> 16);
3123
3124 if(xmax>=xmin)
3125 {
3126 posX=left_u;
3127 posY=left_v;
3128
3129 num=(xmax-xmin);
3130 if(num==0) num=1;
3131 difX=(right_u-posX)/num;
3132 difY=(right_v-posY)/num;
3133 difX2=difX<<1;
3134 difY2=difY<<1;
3135
3136 if(xmin<drawX)
3137 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3138 xmax--;if(drawW<xmax) xmax=drawW;
3139
3140 for(j=xmin;j<xmax;j+=2)
3141 {
3142 XAdjust=(posX>>16);
3143
3144 TXV=posY>>16;
3145 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3146 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3147
3148 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3149
3150 XAdjust=((posX+difX)>>16);
3151
3152 TXV=(posY+difY)>>16;
3153 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3154 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3155
3156 tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3157
3158 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3159 GETLE16(&psxVuw[clutP+tC1])|
3160 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3161 posX+=difX2;
3162 posY+=difY2;
3163 }
3164 posX+=difX2;
3165 posY+=difY2;
3166 }
3167
3168 if(j==xmax)
3169 {
3170 XAdjust=(posX>>16);
3171 TXV=posY>>16;
3172 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3173 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3174
3175 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3176
3177 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3178 }
3179
3180 }
3181 if(NextRow_FT4()) return;
3182 }
3183#endif
3184
3185 for (i=ymin;i<=ymax;i++)
3186 {
3187 xmin=(left_x >> 16);
3188 xmax=(right_x >> 16);
3189
3190 if(xmax>=xmin)
3191 {
3192 posX=left_u;
3193 posY=left_v;
3194
3195 num=(xmax-xmin);
3196 if(num==0) num=1;
3197 difX=(right_u-posX)/num;
3198 difY=(right_v-posY)/num;
3199 difX2=difX<<1;
3200 difY2=difY<<1;
3201
3202 if(xmin<drawX)
3203 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3204 xmax--;if(drawW<xmax) xmax=drawW;
3205
3206 for(j=xmin;j<xmax;j+=2)
3207 {
3208 XAdjust=(posX>>16);
3209
3210 TXV=posY>>16;
3211 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3212 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3213
3214 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3215
3216 XAdjust=((posX+difX)>>16);
3217
3218 TXV=(posY+difY)>>16;
3219 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3220 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3221
3222 tC2= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3223
3224 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3225 GETLE16(&psxVuw[clutP+tC1])|
3226 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3227 posX+=difX2;
3228 posY+=difY2;
3229 }
3230 if(j==xmax)
3231 {
3232 XAdjust=(posX>>16);
3233 TXV=posY>>16;
3234 n_xi = ( ( XAdjust >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
3235 n_yi = ( TXV & ~0xf ) + ( ( XAdjust >> 4 ) & 0xf );
3236
3237 tC1= (GETLE16(&psxVuw[(n_yi<<10)+YAdjust+n_xi]) >> ((XAdjust & 0x03)<<2)) & 0x0f ;
3238
3239 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3240 }
3241 }
3242 if(NextRow_FT4()) return;
3243 }
3244}
3245
3246////////////////////////////////////////////////////////////////////////
3247
a96a5eb2 3248static 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
3249{
3250 int32_t num;
3251 int32_t i,j,xmin,xmax,ymin,ymax;
3252 int32_t difX, difY, difX2, difY2;
3253 int32_t posX,posY,YAdjust,clutP,XAdjust;
3254 short tC1,tC2;
3255
3256 if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3257 if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3258 if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3259 if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3260 if(drawY>=drawH) return;
3261 if(drawX>=drawW) return;
3262
3263 if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3264
3265 ymax=Ymax;
3266
3267 for(ymin=Ymin;ymin<drawY;ymin++)
3268 if(NextRow_FT4()) return;
3269
3270 clutP=(clY<<10)+clX;
3271
3272 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3273 YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3274
3275#ifdef FASTSOLID
3276
3277 if(!bCheckMask && !DrawSemiTrans)
3278 {
3279 for (i=ymin;i<=ymax;i++)
3280 {
3281 xmin=(left_x >> 16);
3282 xmax=(right_x >> 16);
3283
3284 if(xmax>=xmin)
3285 {
3286 posX=left_u;
3287 posY=left_v;
3288
3289 num=(xmax-xmin);
3290 if(num==0) num=1;
3291 difX=(right_u-posX)/num;
3292 difY=(right_v-posY)/num;
3293 difX2=difX<<1;
3294 difY2=difY<<1;
3295
3296 if(xmin<drawX)
3297 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3298 xmax--;if(drawW<xmax) xmax=drawW;
3299
3300 for(j=xmin;j<xmax;j+=2)
3301 {
3302 XAdjust=(posX>>16)%TWin.Position.x1;
3303 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3304 YAdjust+(XAdjust>>1)];
3305 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3306 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3307 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3308 YAdjust+(XAdjust>>1)];
3309 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3310
3311 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3312 GETLE16(&psxVuw[clutP+tC1])|
3313 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3314 posX+=difX2;
3315 posY+=difY2;
3316 }
3317 if(j==xmax)
3318 {
3319 XAdjust=(posX>>16)%TWin.Position.x1;
3320 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3321 YAdjust+(XAdjust>>1)];
3322 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3323 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3324 }
3325 }
3326 if(NextRow_FT4()) return;
3327 }
3328 return;
3329 }
3330
3331#endif
3332
3333 for (i=ymin;i<=ymax;i++)
3334 {
3335 xmin=(left_x >> 16);
3336 xmax=(right_x >> 16);
3337
3338 if(xmax>=xmin)
3339 {
3340 posX=left_u;
3341 posY=left_v;
3342
3343 num=(xmax-xmin);
3344 if(num==0) num=1;
3345 difX=(right_u-posX)/num;
3346 difY=(right_v-posY)/num;
3347 difX2=difX<<1;
3348 difY2=difY<<1;
3349
3350 if(xmin<drawX)
3351 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3352 xmax--;if(drawW<xmax) xmax=drawW;
3353
3354 for(j=xmin;j<xmax;j+=2)
3355 {
3356 XAdjust=(posX>>16)%TWin.Position.x1;
3357 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3358 YAdjust+(XAdjust>>1)];
3359 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3360 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3361 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3362 YAdjust+(XAdjust>>1)];
3363 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3364
3365 GetTextureTransColG32((uint32_t *)&psxVuw[(i<<10)+j],
3366 GETLE16(&psxVuw[clutP+tC1])|
3367 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3368 posX+=difX2;
3369 posY+=difY2;
3370 }
3371 if(j==xmax)
3372 {
3373 XAdjust=(posX>>16)%TWin.Position.x1;
3374 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3375 YAdjust+(XAdjust>>1)];
3376 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3377 GetTextureTransColG(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3378 }
3379 }
3380 if(NextRow_FT4()) return;
3381 }
3382}
3383
3384////////////////////////////////////////////////////////////////////////
3385
a96a5eb2 3386static 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
3387{
3388 int32_t num;
3389 int32_t i,j,xmin,xmax,ymin,ymax;
3390 int32_t difX, difY, difX2, difY2;
3391 int32_t posX,posY,YAdjust,clutP,XAdjust;
3392 short tC1,tC2;
3393
3394 if(x1>drawW && x2>drawW && x3>drawW && x4>drawW) return;
3395 if(y1>drawH && y2>drawH && y3>drawH && y4>drawH) return;
3396 if(x1<drawX && x2<drawX && x3<drawX && x4<drawX) return;
3397 if(y1<drawY && y2<drawY && y3<drawY && y4<drawY) return;
3398 if(drawY>=drawH) return;
3399 if(drawX>=drawW) return;
3400
3401 if(!SetupSections_FT4(x1,y1,x2,y2,x3,y3,x4,y4,tx1,ty1,tx2,ty2,tx3,ty3,tx4,ty4)) return;
3402
3403 ymax=Ymax;
3404
3405 for(ymin=Ymin;ymin<drawY;ymin++)
3406 if(NextRow_FT4()) return;
3407
3408 clutP=(clY<<10)+clX;
3409
3410 YAdjust=((GlobalTextAddrY)<<11)+(GlobalTextAddrX<<1);
3411 YAdjust+=(TWin.Position.y0<<11)+(TWin.Position.x0>>1);
3412
3413#ifdef FASTSOLID
3414
3415 if(!bCheckMask && !DrawSemiTrans)
3416 {
3417 for (i=ymin;i<=ymax;i++)
3418 {
3419 xmin=(left_x >> 16);
3420 xmax=(right_x >> 16);
3421
3422 if(xmax>=xmin)
3423 {
3424 posX=left_u;
3425 posY=left_v;
3426
3427 num=(xmax-xmin);
3428 if(num==0) num=1;
3429 difX=(right_u-posX)/num;
3430 difY=(right_v-posY)/num;
3431 difX2=difX<<1;
3432 difY2=difY<<1;
3433
3434 if(xmin<drawX)
3435 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3436 xmax--;if(drawW<xmax) xmax=drawW;
3437
3438 for(j=xmin;j<xmax;j+=2)
3439 {
3440 XAdjust=(posX>>16)%TWin.Position.x1;
3441 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3442 YAdjust+(XAdjust>>1)];
3443 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3444 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3445 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3446 YAdjust+(XAdjust>>1)];
3447 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3448
3449 GetTextureTransColG32_S((uint32_t *)&psxVuw[(i<<10)+j],
3450 GETLE16(&psxVuw[clutP+tC1])|
3451 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3452 posX+=difX2;
3453 posY+=difY2;
3454 }
3455 if(j==xmax)
3456 {
3457 XAdjust=(posX>>16)%TWin.Position.x1;
3458 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3459 YAdjust+(XAdjust>>1)];
3460 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3461 GetTextureTransColG_S(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3462 }
3463 }
3464 if(NextRow_FT4()) return;
3465 }
3466 return;
3467 }
3468
3469#endif
3470
3471 for (i=ymin;i<=ymax;i++)
3472 {
3473 xmin=(left_x >> 16);
3474 xmax=(right_x >> 16);
3475
3476 if(xmax>=xmin)
3477 {
3478 posX=left_u;
3479 posY=left_v;
3480
3481 num=(xmax-xmin);
3482 if(num==0) num=1;
3483 difX=(right_u-posX)/num;
3484 difY=(right_v-posY)/num;
3485 difX2=difX<<1;
3486 difY2=difY<<1;
3487
3488 if(xmin<drawX)
3489 {j=drawX-xmin;xmin=drawX;posX+=j*difX;posY+=j*difY;}
3490 xmax--;if(drawW<xmax) xmax=drawW;
3491
3492 for(j=xmin;j<xmax;j+=2)
3493 {
3494 XAdjust=(posX>>16)%TWin.Position.x1;
3495 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3496 YAdjust+(XAdjust>>1)];
3497 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3498 XAdjust=((posX+difX)>>16)%TWin.Position.x1;
3499 tC2 = psxVub[((((posY+difY)>>16)%TWin.Position.y1)<<11)+
3500 YAdjust+(XAdjust>>1)];
3501 tC2=(tC2>>((XAdjust&1)<<2))&0xf;
3502
3503 GetTextureTransColG32_SPR((uint32_t *)&psxVuw[(i<<10)+j],
3504 GETLE16(&psxVuw[clutP+tC1])|
3505 ((int32_t)GETLE16(&psxVuw[clutP+tC2]))<<16);
3506 posX+=difX2;
3507 posY+=difY2;
3508 }
3509 if(j==xmax)
3510 {
3511 XAdjust=(posX>>16)%TWin.Position.x1;
3512 tC1 = psxVub[(((posY>>16)%TWin.Position.y1)<<11)+
3513 YAdjust+(XAdjust>>1)];
3514 tC1=(tC1>>((XAdjust&1)<<2))&0xf;
3515 GetTextureTransColG_SPR(&psxVuw[(i<<10)+j],GETLE16(&psxVuw[clutP+tC1]));
3516 }
3517 }
3518 if(NextRow_FT4()) return;
3519 }
3520}
3521////////////////////////////////////////////////////////////////////////
3522// POLY 3 F-SHADED TEX PAL 8
3523////////////////////////////////////////////////////////////////////////