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