using kprintf to output debug, which may be redirected to serial, is not a good idea...
[AROS-Contrib.git] / gfx / libs / wazp3d / Wazp3D-src / soft3d.c
blobd1e436b8bad1c9cc4a2f71f2d547866639148b7a
1 /* Wazp3D Beta 52 : Alain THELLIER - Paris - FRANCE - (November 2006 to 2012) */
2 /* Adaptation to AROS from Matthias Rustler */
3 /* Code clean-up and library enhancements from Gunther Nikl */
4 /* LICENSE: GNU General Public License (GNU GPL) for this file */
6 /* This file contain the SOFT3D rasterizer that truly draw the pixels */
8 #include "Wazp3D.h"
9 #include "soft3d_protos.h"
10 #include "soft3d_opengl.h"
12 /* use a local pointer on Wazp3D : having a copy here allow to separate the sof3d binary & wazp3d binary*/
13 #ifdef SOFT3DLIB
15 struct WAZP3D_parameters *Wazp3D; /* local pointer to the struct in Warp3d.library */
16 #include "soft3d_mem_print.h" /* memory and print/debug functions : usually in Warp3d.c */
18 #endif
20 #if !defined(AMIGA) /* so we are compiling the DLL */
21 #include "soft3d_pc_glue.h"
22 #else
23 #define SLOWCPU 1 /* OS3 68k */
24 #endif
26 #ifdef __amigaos4__
27 #undef SLOWCPU /* OS4 ppc */
28 #endif
30 /*==================================================================================*/
31 /* structures definitions only used in SOFT3D */
32 union pixel3D {
33 struct pixel3DL{
34 ZBUFF z;
35 float w;
36 LONG u;
37 LONG v;
38 LONG R;
39 LONG G;
40 LONG B;
41 LONG A;
42 LONG x;
43 LONG y;
44 LONG F;
45 LONG large;
46 UBYTE *Image8Y;
47 UWORD bpp;
48 ZBUFF *ZbufferY;
49 ZBUFF dz;
50 float dw;
51 LONG du;
52 LONG dv;
53 LONG ddu;
54 LONG ddv;
55 LONG dR;
56 LONG dG;
57 LONG dB;
58 LONG dA;
59 LONG dx;
60 LONG dF;
61 } L;
63 #ifdef MOTOROLAORDER
64 struct pixel3DW{
65 ZBUFF z;
66 float w;
67 UBYTE u1,u,u3,u4;
68 UBYTE v1,v,v3,v4;
69 UBYTE R1,R,R3,R4;
70 UBYTE G1,G,G3,G4;
71 UBYTE B1,B,B3,B4;
72 UBYTE A1,A,A3,A4;
73 WORD x,xlow;
74 WORD y,ylow;
75 WORD F,Flow;
76 WORD large,largelow;
77 UBYTE *Image8Y;
78 UWORD bpp;
79 ZBUFF *ZbufferY;
80 ZBUFF dz;
81 float dw;
82 LONG du;
83 LONG dv;
84 LONG ddu;
85 LONG ddv;
86 LONG dR;
87 LONG dG;
88 LONG dB;
89 LONG dA;
90 LONG dx;
91 LONG dF;
92 } W;
93 #else
94 struct pixel3DW{
95 ZBUFF z;
96 float w;
97 UBYTE u4,u3,u,u1;
98 UBYTE v4,v3,v,v1;
99 UBYTE R4,R3,R,R1;
100 UBYTE G4,G3,G,G1;
101 UBYTE B4,B3,B,B1;
102 UBYTE A4,A3,A,A1;
103 WORD xlow,x;
104 WORD ylow,y;
105 WORD Flow,F;
106 WORD largelow,large;
107 UBYTE *Image8Y;
108 UWORD bpp;
109 ZBUFF *ZbufferY;
110 ZBUFF dz;
111 float dw;
112 LONG du;
113 LONG dv;
114 LONG ddu;
115 LONG ddv;
116 LONG dR;
117 LONG dG;
118 LONG dB;
119 LONG dA;
120 LONG dx;
121 LONG dF;
122 } W;
123 #endif
125 /*=============================================================*/
126 #ifdef MOTOROLAORDER
127 union oper3D {
128 struct oper3DW{
129 ULONG Index;
130 } L;
131 struct oper3DB{
132 UBYTE empty1,empty2,a,b;
133 } B;
135 #else
136 union oper3D {
137 struct oper3DW{
138 ULONG Index;
139 } L;
140 struct oper3DB{
141 UBYTE b,a,empty3,empty4;
142 } B;
144 #endif
145 /*=============================================================*/
146 struct fragbuffer3D{
147 UBYTE *Image8;
148 UBYTE *Tex8;
149 UBYTE ColorRGBA[4];
150 UBYTE BufferRGBA[4];
151 UBYTE FogRGBA[4];
152 UBYTE TmpRGBA[4];
154 /*=============================================================*/
155 struct AvailableFunctions{
156 HOOKEDFUNCTION Fill[8]; /* functions available */
157 HOOKEDFUNCTION Edge[16];
158 HOOKEDFUNCTION TexEnv[6*2+1];
159 HOOKEDFUNCTION Ztest[16];
160 HOOKEDFUNCTION BlendFast[256];
162 struct AvailableFunctions Functions;
163 /*=============================================================*/
164 struct SOFT3D_context{
165 #ifdef SLOWCPU
166 UBYTE Mul8[256*256]; /* table for multiplying two UBYTE */
167 UBYTE Add8[256*256]; /* table for adding two UBYTE with overflow */
168 UBYTE Fil8[256*256]; /* table for filtering two UBYTE */
169 #endif
170 ULONG B0toRGBA32[256]; /* tables for converting 8/15/16 bits to RGBA */
171 ULONG B1toRGBA32[256];
172 UBYTE RtoB0[256];
173 UBYTE GtoB0[256];
174 UBYTE BtoB0[256];
175 UBYTE RtoB1[256];
176 UBYTE GtoB1[256];
177 UBYTE BtoB1[256];
178 WORD large,high,bits;
179 ULONG bmformat;
180 struct vertex3D ClipMin; /* 3D clipper */
181 struct vertex3D ClipMax;
182 UBYTE *Image8;
183 ULONG *ImageBuffer32;
184 ZBUFF *Zbuffer;
185 UBYTE NoopRGBA[4];
186 UBYTE FlatRGBA[4];
187 struct SOFT3D_mipmap *MM;
188 WORD Pnb;
189 union pixel3D *Pix;
190 WORD PointLarges[MAXSCREEN];
191 union pixel3D edge1[MAXSCREEN];
192 union pixel3D edge2[MAXSCREEN];
193 union pixel3D edgeM[MAXSCREEN];
194 UWORD Image8X[MAXSCREEN];
195 UBYTE Ztest[MAXSCREEN];
196 HOOKEDFUNCTION FunctionPoly; /* functions currently used in pipeline */
197 HOOKEDFUNCTION FunctionEdge;
198 HOOKEDFUNCTION FunctionFill;
199 HOOKEDFUNCTION FunctionZtest;
200 HOOKEDFUNCTION FunctionIn;
201 HOOKEDFUNCTION FunctionBlend;
202 HOOKEDFUNCTION FunctionBlendFast;
203 HOOKEDFUNCTION FunctionTexEnv;
204 HOOKEDFUNCTION FunctionFog;
205 HOOKEDFUNCTION FunctionFilter;
206 HOOKEDFUNCTION FunctionSepia;
207 HOOKEDFUNCTION FunctionOut;
208 HOOKEDFUNCTION FunctionBitmapOut;
209 HOOKEDFUNCTION FunctionBitmapIn;
210 HOOKEDFUNCTION FunctionWriteImageBuffer;
211 struct fragbuffer3D FragBuffer[FRAGBUFFERSIZE];
212 struct fragbuffer3D *FragBufferDone; /* last pixel written in FragBuffer */
213 struct fragbuffer3D *FragBufferMaxi; /* dont fill FragBuffer beyond this limit ==> flush it*/
214 ULONG FragSize2; /* nb pixels = FragSize*2 */
215 ULONG FogRGBAs[FOGSIZE];
216 WORD PolyPnb;
217 union pixel3D PolyPix[MAXPOLY];
218 union pixel3D *P1; /* do FunctionEdge/FunctionPoly from P1 to P2 */
219 union pixel3D *P2;
220 ULONG PolyHigh,PolyLarge;
221 struct point3D PolyP[MAXPOLY];
222 struct point3D T1[MAXPOLY];
223 struct point3D T2[MAXPOLY];
224 void *firstST;
225 WORD Pxmin,Pxmax,Pymin,Pymax; /* really updated region */
226 float Pzmin,Pzmax;
227 WORD xUpdate,largeUpdate,yUpdate,highUpdate; /* really updated region previous frame*/
228 UWORD Tnb;
229 UBYTE SrcFunc,DstFunc;
230 UBYTE UseFunctionBitmapIn;
231 UBYTE ColorChange; /* V41: Soft3D can smartly desactivate the gouraud if all points got the same color */
232 UBYTE ColorTransp; /* V43: Soft3D detect if points got alpha value */
233 UBYTE ColorWhite; /* V47: Soft3D detect if points are all white ==> no coloring */
234 LONG dmin;
235 UWORD yoffset;
236 UBYTE UseHard;
237 struct state3D state;
238 struct HARD3D_context HC;
239 #ifdef AMIGA /* of course the PC DLL cant manipulate an Amiga's bitmap */
240 void *bm;
241 void *bmHandle; /* to directly write to bitmap */
242 struct RastPort rastport;
243 void *colorsbm;
244 #endif
246 /*=================================================================*/
247 struct SOFT3D_mipmap{
248 UBYTE *Tex8V[256]; /* adresse of the texture at this line */
249 ULONG Tex8Vlow[256];
250 UWORD Tex8U[256];
251 UWORD Tex8Ulow[256];
253 /*=================================================================*/
254 #define NBMIPMAPS 12
255 struct SOFT3D_texture{
256 struct SOFT3D_mipmap MMs[NBMIPMAPS];
257 UBYTE *pt; /* original data from 3Dprog as RGB or RGBA */
258 UBYTE *ptmm; /* mipmaps as RGB or RGBA */
259 UWORD large,high,format,bits;
260 UBYTE TexFlags;
261 UBYTE name[40];
262 UWORD Tnum;
263 void *nextST;
264 void *bm;
265 struct HARD3D_texture HT;
267 /*=================================================================*/
268 #ifdef WAZP3DDEBUG
269 UBYTE font8x8[14*16*8] = {
270 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
271 0,8,24,24,8,0,16,8,8,16,24,0,0,0,0,8,
272 0,8,24,60,28,36,40,8,16,8,24,8,0,0,0,8,
273 0,8,0,24,24,8,20,0,16,8,0,28,0,24,0,24,
274 0,0,0,60,12,16,40,0,16,8,0,8,0,0,0,16,
275 0,8,0,24,28,36,20,0,16,8,0,0,8,0,8,16,
276 0,0,0,0,8,0,0,0,8,16,0,0,8,0,0,0,
277 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
278 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
279 28,8,28,24,4,28,28,28,28,28,0,0,0,0,0,16,
280 20,24,4,4,12,16,16,4,20,20,0,0,0,0,0,8,
281 20,8,28,12,20,28,28,8,28,28,8,8,8,0,16,16,
282 20,8,16,4,28,4,20,8,20,4,0,0,16,24,8,0,
283 28,8,28,24,4,28,28,8,28,28,8,8,8,0,16,16,
284 0,0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,
285 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
286 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
287 24,24,56,24,56,28,28,28,36,8,4,36,16,34,36,24,
288 36,24,36,36,36,16,16,32,36,8,4,40,16,54,52,36,
289 90,36,56,32,36,24,24,44,60,8,4,48,16,42,44,36,
290 94,60,36,36,36,16,16,36,36,8,20,40,16,34,36,36,
291 32,36,56,24,56,28,16,28,36,8,24,36,28,34,36,24,
292 24,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
293 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
294 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
295 56,24,56,28,28,36,20,34,20,20,28,24,16,24,8,0,
296 36,36,36,32,8,36,20,42,20,20,4,16,16,8,20,0,
297 56,36,56,24,8,36,20,42,8,8,8,16,24,8,0,0,
298 32,40,36,4,8,36,8,20,20,8,16,16,8,8,0,0,
299 32,20,36,56,8,24,8,20,20,8,28,16,8,8,0,0,
300 0,0,0,0,0,0,0,0,0,0,0,24,0,24,0,60,
301 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
302 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
303 16,0,16,0,4,0,24,0,16,8,8,16,8,0,0,0,
304 8,0,16,0,4,8,16,0,16,0,0,16,8,0,0,0,
305 0,12,28,28,28,28,24,28,28,8,8,20,8,54,24,28,
306 0,20,20,16,20,16,16,20,20,8,8,24,8,42,20,20,
307 0,12,28,28,28,28,16,28,20,8,8,20,8,42,20,28,
308 0,0,0,0,0,0,0,4,0,0,8,0,0,0,0,0,
309 0,0,0,0,0,0,0,28,0,0,0,0,0,0,0,0,
310 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
311 0,0,0,0,0,0,0,0,0,0,0,8,8,16,12,0,
312 0,0,0,0,16,0,0,0,0,0,0,8,8,16,24,0,
313 24,12,24,24,24,20,20,36,20,20,28,16,8,8,0,0,
314 20,20,16,16,16,20,20,36,8,20,8,16,8,8,0,0,
315 24,12,16,48,8,12,8,60,20,8,28,8,8,16,0,0,
316 16,4,0,0,0,0,0,0,0,16,0,8,0,16,0,0,
317 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
318 0,0,0,0,0,0,0,0,0,0,8,0,0,0,0,0,
319 8,0,0,12,0,0,8,8,8,20,28,0,62,0,8,0,
320 8,0,0,8,0,0,28,28,20,40,32,0,40,0,8,0,
321 8,0,0,28,0,0,8,8,0,26,24,8,44,0,8,0,
322 8,0,0,8,0,0,8,8,0,20,4,16,40,0,8,0,
323 8,0,8,8,40,84,8,28,0,42,56,8,62,0,8,0,
324 0,0,8,16,40,0,8,8,0,0,0,0,0,0,0,0,
325 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
326 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
327 0,8,8,24,24,0,0,0,12,122,40,0,0,0,8,20,
328 0,0,0,0,0,0,0,0,24,46,0,0,0,0,8,20,
329 0,0,0,0,0,24,0,0,0,42,24,16,28,0,8,8,
330 0,0,0,0,0,24,28,62,0,0,16,8,42,0,8,8,
331 0,0,0,0,0,0,0,0,0,0,48,16,28,0,8,8,
332 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
333 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
334 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
335 0,0,0,4,20,20,8,12,24,24,8,0,0,0,24,60,
336 0,8,4,8,8,28,8,24,0,44,8,0,0,0,52,0,
337 0,0,12,28,20,8,8,20,0,52,0,8,0,0,44,0,
338 0,8,16,8,0,28,8,12,0,24,0,16,28,8,24,0,
339 0,8,12,12,0,8,8,12,0,0,0,8,4,0,0,0,
340 0,8,8,0,0,0,8,24,0,0,0,0,0,0,0,0,
341 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
342 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
343 0,0,8,0,8,0,0,0,0,0,0,0,0,0,0,0,
344 8,0,8,8,16,0,24,0,0,8,8,0,36,36,36,8,
345 0,24,0,8,0,40,24,8,0,8,8,16,40,40,40,0,
346 0,24,0,0,0,40,8,0,0,0,0,8,20,20,20,8,
347 0,24,0,0,0,52,8,0,8,0,0,16,36,36,36,16,
348 0,0,0,0,0,32,8,0,24,0,0,0,0,0,0,8,
349 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
350 8,8,8,8,8,8,14,24,28,28,28,28,8,16,40,0,
351 20,20,20,20,20,20,24,36,16,16,16,16,0,0,0,16,
352 20,20,20,20,20,20,46,32,28,28,28,28,8,16,16,16,
353 28,28,28,28,28,28,56,36,16,16,16,16,8,16,16,16,
354 20,20,20,20,20,20,46,24,28,28,28,28,8,16,16,16,
355 0,0,0,0,0,0,0,8,0,0,0,0,0,0,0,0,
356 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
357 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
358 0,24,16,8,24,24,36,0,0,16,8,24,24,8,0,0,
359 24,36,24,24,24,24,24,0,28,36,36,36,36,20,16,8,
360 20,52,36,36,36,36,36,20,44,36,36,36,36,20,28,20,
361 52,44,36,36,36,36,36,8,52,36,36,36,36,8,20,28,
362 20,36,36,36,36,36,36,20,52,36,36,36,36,8,28,20,
363 24,36,24,24,24,24,24,0,56,24,24,24,24,8,16,24,
364 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
365 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
366 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
367 8,4,12,12,20,8,0,0,16,8,8,20,16,8,16,0,
368 4,8,0,0,0,0,0,0,8,16,20,0,8,16,40,40,
369 12,12,12,12,12,12,28,12,24,24,24,24,0,0,0,0,
370 20,20,20,20,20,20,42,16,20,20,20,20,8,16,16,16,
371 12,12,12,12,12,12,30,12,12,12,12,12,8,16,16,16,
372 0,0,0,0,0,0,0,4,0,0,0,0,0,0,0,0,
373 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
374 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
375 0,24,16,4,8,12,20,0,0,16,4,8,20,4,16,20,
376 16,0,8,8,20,0,0,0,0,8,8,20,0,8,16,0,
377 8,24,28,28,28,28,28,8,28,20,20,20,20,20,24,20,
378 24,20,20,20,20,20,20,28,28,20,20,20,20,8,20,8,
379 24,20,28,28,28,28,28,8,28,12,12,12,12,8,24,8,
380 0,0,0,0,0,0,0,0,0,0,0,0,0,16,16,16,
381 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
383 #endif
384 /*=================================================================*/
385 void PrintST(struct SOFT3D_texture *ST)
387 #ifdef WAZP3DDEBUG
388 if(ST==NULL) return;
389 if (!Wazp3D->DebugST.ON) return;
390 Libprintf("SOFT3D_texture(%ld) %s pt %ld NextST(%ld) TexFlags %ld \n",(IPTR)ST,ST->name,(IPTR)ST->pt,(IPTR)ST->nextST,(ULONG)ST->TexFlags);
391 #else
392 return;
393 #endif
395 /*=================================================================*/
396 void PrintPix(union pixel3D *Pix)
398 #ifdef WAZP3DDEBUG
399 if (!Wazp3D->DebugPoint.ON) return;
400 if (!Wazp3D->DebugSOFT3D.ON) return;
401 Libprintf(" Pix XY %ld %ld \tUV %ld %ld ",(LONG)Pix->W.x,(LONG)Pix->W.y,(LONG)Pix->W.u,(LONG)Pix->W.v);
402 Libprintf("RGBA %ld %ld %ld %ld large %ld",(LONG)Pix->W.R,(LONG)Pix->W.G,(LONG)Pix->W.B,(LONG)Pix->W.A,(LONG)Pix->W.large);
403 Libprintf(" ZWF "); pf((float)Pix->L.z); pf(Pix->L.w); pf(Pix->W.F);Libprintf("\n");
404 #else
405 return;
406 #endif
408 /*=================================================================*/
409 void PrintP2(struct point3D *P)
411 #ifdef WAZP3DDEBUG
412 Libprintf("ClipXYZW; %ld; %ld; %ld; %ld; UV; %ld; %ld\n",(ULONG)P->x,(ULONG)P->y,(ULONG)(1000.0*P->z),(ULONG)(1000.0*P->w),(ULONG)(P->u),(ULONG)(P->v));
413 #else
414 return;
415 #endif
417 /*=================================================================*/
418 /* SOFT3D internal private functions */
419 void AntiAliasImage(void *image,UWORD large,UWORD high);
420 void ClipPoly(struct SOFT3D_context *SC);
421 void ClipLine(struct SOFT3D_context *SC);
422 void CreateMipmaps(struct SOFT3D_texture *ST);
423 void DrawLinePix(struct SOFT3D_context *SC);
424 void DrawPointPix(struct SOFT3D_context *SC);
425 void DrawSimplePix(struct SOFT3D_context *SC,register union pixel3D *P);
426 void DrawPolyP(struct SOFT3D_context *SC);
427 void DrawPolyPix(struct SOFT3D_context *SC);
428 void DrawTriP(struct SOFT3D_context *SC,register struct point3D *A,register struct point3D *B,register struct point3D *C);
429 void Fill_BigTexPersp2_Gouraud_Fog(struct SOFT3D_context *SC);
430 void Fill_BigTexPersp2(struct SOFT3D_context *SC);
431 void Fill_Flat(struct SOFT3D_context *SC);
432 void Fill_Fog(struct SOFT3D_context *SC);
433 void Fill_Gouraud(struct SOFT3D_context *SC);
434 void Fill_Gouraud_Fog(struct SOFT3D_context *SC);
435 void Fill_Tex(struct SOFT3D_context *SC);
436 void Fill_Tex_Fog(struct SOFT3D_context *SC);
437 void Fill_Tex_Gouraud(struct SOFT3D_context *SC);
438 void Fill_Tex_Gouraud_Fog(struct SOFT3D_context *SC);
439 BOOL LockBM(struct SOFT3D_context *SC);
440 void PixelsARGB(struct SOFT3D_context *SC);
441 void PixelsAdd24(struct SOFT3D_context *SC);
442 void PixelsAdd32(struct SOFT3D_context *SC);
443 void PixelsSub24(struct SOFT3D_context *SC);
444 void PixelsSub32(struct SOFT3D_context *SC);
445 void PixelsBlend24(struct SOFT3D_context *SC);
446 void PixelsBlend32(struct SOFT3D_context *SC);
447 void PixelsDecal24(struct SOFT3D_context *SC);
448 void PixelsDecal32(struct SOFT3D_context *SC);
449 void PixelsInOutBGRA(struct SOFT3D_context *SC);
450 void PixelsModulate24(struct SOFT3D_context *SC);
451 void PixelsModulate32(struct SOFT3D_context *SC);
452 void PixelsOne_One24(struct SOFT3D_context *SC);
453 void PixelsReplace24(struct SOFT3D_context *SC);
454 void PixelsReplace32(struct SOFT3D_context *SC);
455 void PixelsOne_Zero32(struct SOFT3D_context *SC);
456 void PixelsSrcAlpha_OneMinusSrcAlpha32(struct SOFT3D_context *SC);
457 void PixelsSrcAlpha_One32(struct SOFT3D_context *SC);
458 void PixelsOne_One24(struct SOFT3D_context *SC);
459 void PixelsZero_SrcAlpha32(struct SOFT3D_context *SC);
460 void PixelsZero_SrcColor24(struct SOFT3D_context *SC);
461 void PixelsDstColor_Zero24(struct SOFT3D_context *SC);
462 void PixelsZero_OneMinusSrcColor24(struct SOFT3D_context *SC);
463 void PixelsSrcAlpha_OneMinusSrcColor32(struct SOFT3D_context *SC);
464 void PixelsOne_OneMinusSrcAlpha32(struct SOFT3D_context *SC);
465 void PixelsSrcAlpha_OneMinusSrcAlpha32fast(struct SOFT3D_context *SC);
466 void PixelsSrcAlpha_OneMinusSrcAlpha32perfect(struct SOFT3D_context *SC);
467 void PixelsChroma32fast(struct SOFT3D_context *SC);
468 void PrintPix(union pixel3D *Pix);
469 void PrintST(struct SOFT3D_texture *ST);
470 void ReduceBitmap(UBYTE *pt,UBYTE *pt2,UWORD large,UWORD high, WORD bits,WORD ratio);
471 void UnLockBM(struct SOFT3D_context *SC);
472 void UVtoRGBA(struct SOFT3D_texture *ST,float u,float v,UBYTE *RGBA);
473 void Ztest_zalways(struct SOFT3D_context *SC);
474 void Ztest_zalways_update(struct SOFT3D_context *SC);
475 void Ztest_zequal(struct SOFT3D_context *SC);
476 void Ztest_zequal_update(struct SOFT3D_context *SC);
477 void Ztest_zgequal(struct SOFT3D_context *SC);
478 void Ztest_zgequal_update(struct SOFT3D_context *SC);
479 void Ztest_zgreater(struct SOFT3D_context *SC);
480 void Ztest_zgreater_update(struct SOFT3D_context *SC);
481 void Ztest_zlequal(struct SOFT3D_context *SC);
482 void Ztest_zlequal_update(struct SOFT3D_context *SC);
483 void Ztest_zless(struct SOFT3D_context *SC);
484 void Ztest_zless_update(struct SOFT3D_context *SC);
485 void Ztest_znequal(struct SOFT3D_context *SC);
486 void Ztest_znequal_update(struct SOFT3D_context *SC);
487 void Ztest_znever_update(struct SOFT3D_context *SC);
488 void Ztest_znotequal(struct SOFT3D_context *SC);
489 void Ztest_znotequal_update(struct SOFT3D_context *SC);
490 void PixelsOut8(struct SOFT3D_context *SC);
491 void PixelsIn8(struct SOFT3D_context *SC);
492 void PixelsOut16(struct SOFT3D_context *SC);
493 void PixelsIn16(struct SOFT3D_context *SC);
494 void PixelsBlendFunctionAll(struct SOFT3D_context *SC);
495 void Poly_Persp0_Tex(struct SOFT3D_context *SC);
496 void Poly_Persp0_Gouraud(struct SOFT3D_context *SC);
497 void Poly_Persp0_Flat(struct SOFT3D_context *SC);
498 void Poly_Persp0_Tex_Gouraud_Fog(struct SOFT3D_context *SC);
499 void Poly_Persp1_Tex(struct SOFT3D_context *SC);
500 void Poly_Persp1_Gouraud(struct SOFT3D_context *SC);
501 void Poly_Persp1_Flat(struct SOFT3D_context *SC);
502 void Poly_Persp1_Tex_Gouraud_Fog(struct SOFT3D_context *SC);
503 void Poly_Persp2x2_Tex_Gouraud_Fog(struct SOFT3D_context *SC);
504 void Edge_Persp_Tex_Gouraud_Fog(struct SOFT3D_context *SC);
505 void Edge_Tex_Gouraud_Fog(struct SOFT3D_context *SC);
506 void Edge_Gouraud(struct SOFT3D_context *SC);
507 void Edge_Flat(struct SOFT3D_context *SC);
508 void Edge_Persp_Tex(struct SOFT3D_context *SC);
509 void Edge_Tex(struct SOFT3D_context *SC);
510 void ChangeSoftPoint(APTR sc);
511 void SOFT3D_SetDrawFunctions(APTR sc);
512 /*==========================================================================*/
513 #ifdef __amigaos4__
515 #define OS4COMPOSITING 1
516 #include "soft3d_compositing.c" /* use OS4 compositing engine as hardware renderer */
518 #endif
519 /*==========================================================================*/
520 void WriteImageBuffer(struct SOFT3D_context *SC)
522 #ifdef AMIGA
523 WritePixelArray(SC->ImageBuffer32,SC->xUpdate,SC->yUpdate,SC->large*(32/8),&SC->rastport,SC->xUpdate,SC->yUpdate+SC->yoffset,SC->largeUpdate,SC->highUpdate,RECTFMT_RGBA);
524 #endif
526 /*==========================================================================*/
527 void SetImage(APTR sc,UWORD x,UWORD y,UWORD large,UWORD high,UWORD bits,UBYTE *Image8)
529 struct SOFT3D_context *SC=sc;
530 UWORD bpp;
531 ULONG offset;
533 SFUNCTION(SetImage)
534 SVAR(Image8)
535 SVAR(x)
536 SVAR(y)
537 SVAR(large)
538 SVAR(high)
539 SVAR(bits)
540 if(SC==NULL) return;
541 if(Image8==NULL) return;
544 offset =y*large*bits/8 + x*bits/8; /* Dont use x y offset in SOFT3D : use real pointer to Image */
545 SC->Image8 =Image8=Image8+offset;
546 SC->large =large;
547 SC->high =high;
548 SC->bits =bits;
549 bpp =bits/8;
550 SVAR(offset)
551 SVAR(SC->Image8)
553 SC->FragBufferMaxi=SC->FragBuffer + (FRAGBUFFERSIZE - SC->large - 4);
555 SC->Pxmin=0;
556 SC->Pymin=0;
557 SC->Pxmax=large-1;
558 SC->Pymax=high -1;
560 YLOOP(high)
562 SC->edge1[y].L.Image8Y=Image8; SC->edge1[y].L.y=0; SC->edge1[y].W.y=y;SC->edge1[y].L.bpp=bpp;
563 SC->edge2[y].L.Image8Y=Image8; SC->edge2[y].L.y=0; SC->edge2[y].W.y=y;SC->edge2[y].L.bpp=bpp;
564 SC->edgeM[y].L.Image8Y=Image8; SC->edgeM[y].L.y=0; SC->edgeM[y].W.y=y;SC->edgeM[y].L.bpp=bpp;
565 Image8+=bpp*large;
567 XLOOP(MAXSCREEN)
569 SC->Image8X[x]=x*bpp;
573 /*=============================================================*/
574 void SOFT3D_AllocImageBuffer(APTR sc,UWORD large,UWORD high)
576 struct SOFT3D_context *SC=sc;
577 ULONG size;
579 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
580 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
582 SFUNCTION(SOFT3D_AllocImageBuffer)
583 #ifdef AMIGA
584 SVAR(large)
585 SVAR(high)
586 if(SC->ImageBuffer32!=NULL)
587 { SREM(changing ImageBuffer...); }
589 FREEPTR(SC->ImageBuffer32);
591 size=large*high*32/8;
592 if(size!=0)
593 SC->ImageBuffer32=MYmalloc(size,"SOFT3D_ImageBuffer32");
594 SetImage(SC,0,0,large,high,32,(UBYTE *)SC->ImageBuffer32);
595 #else
596 Libprintf("WAZP3D/SOFT3D: cant use Soft to bitmap!!!\n");
597 #endif
599 /*=============================================================*/
600 void SOFT3D_Debug(APTR txt)
601 /* to do a printf from WinUAE */
603 if(Wazp3D->UseDLL)
604 Libprintf(txt);
606 /*=============================================================*/
607 BOOL SOFT3D_Init(void *exec)
609 SFUNCTION(SOFT3D_Init)
610 #ifdef AMIGA
611 #ifdef SOFT3DLIB
612 firstME=NULL; /* Tracked memory-allocation */
613 if(OpenAmigaLibraries(exec)==FALSE) return(FALSE);
614 OpenSoft3DDLL();
615 #endif
616 #endif
617 return(TRUE);
619 /*=============================================================*/
620 void SOFT3D_Close()
622 SFUNCTION(SOFT3D_Close)
623 #ifdef AMIGA
624 #ifdef SOFT3DLIB
625 CloseSoft3DDLL();
626 CloseAmigaLibraries();
627 #endif
628 #endif
629 return;
631 /*=============================================================*/
632 APTR SOFT3D_AllocZbuffer(APTR sc,UWORD large,UWORD high)
634 struct SOFT3D_context *SC=sc;
635 ZBUFF *Zbuffer=NULL;
636 ULONG y;
638 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
639 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
640 SFUNCTION(SOFT3D_AllocZbuffer)
641 SVAR(large)
642 SVAR(high)
643 if(!SC->UseHard)
645 if(SC->Zbuffer!=NULL) /* only happen in software mode */
646 { SREM(will change an existing Zbuffer...); }
648 FREEPTR(SC->Zbuffer);
650 if(high!=0)
651 if(large!=0)
652 SC->Zbuffer=Zbuffer=MYmalloc(large*high*sizeof(ZBUFF),"Zbuffer");
654 if(Zbuffer!=NULL)
655 YLOOP(high)
656 { SC->edge1[y].L.ZbufferY = SC->edge2[y].L.ZbufferY =SC->edgeM[y].L.ZbufferY =Zbuffer;Zbuffer+=large;}
658 #ifdef USEOPENGL
659 if(SC->UseHard)
661 HARD3D_AllocZbuffer(&SC->HC,large,high);
662 SC->Zbuffer=NULL; /* hard cant give the zbuffer adress */
664 #endif
665 return(SC->Zbuffer);
667 /*=============================================================*/
668 void *SOFT3D_Start(APTR PrefsWazp3D)
670 struct SOFT3D_context *SC;
671 UBYTE ZMode,FillMode;
672 ULONG n;
674 #ifdef SLOWCPU
675 UWORD x,y;
676 union oper3D Oper;
677 #endif
679 #ifdef SOFT3DLIB
680 Wazp3D=PrefsWazp3D;
681 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
682 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
683 #ifdef AMIGA
684 Wazp3D->UseDLL=FALSE; /* will inform Wazp3D that soft3d is Amiga native */
685 #else
686 Wazp3D->UseDLL=TRUE; /* then we are runnig soft3d compiled as a PC DLL */
687 #endif
688 #endif
690 SVAR(sizeof(union pixel3D))
691 SVAR(sizeof(union oper3D ))
692 SVAR(sizeof(struct fragbuffer3D))
693 SVAR(sizeof(struct HARD3D_context))
694 SVAR(sizeof(struct SOFT3D_context))
695 SVAR(sizeof(struct SOFT3D_mipmap))
696 SVAR(sizeof(struct SOFT3D_texture))
697 SVAR(sizeof(struct state3D))
700 SFUNCTION(SOFT3D_Start)
701 SVAR(PrefsWazp3D)
703 SC=MYmalloc(sizeof(struct SOFT3D_context),"SOFT3D_context");
704 if(SC==NULL) return(NULL);
705 SC->large=SC->high=0; /* undefined now */
708 #ifdef AMIGA
709 InitRastPort(&SC->rastport);
710 #endif
712 /* ZCompareMode is from 1 to 8 */
713 ZMode=ZMODE(0,W3D_Z_NEVER); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_znever_update; /* same as Ztest_znever */
714 ZMode=ZMODE(0,W3D_Z_LESS); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zless;
715 ZMode=ZMODE(0,W3D_Z_GEQUAL); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zgequal;
716 ZMode=ZMODE(0,W3D_Z_LEQUAL); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zlequal;
717 ZMode=ZMODE(0,W3D_Z_GREATER); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zgreater;
718 ZMode=ZMODE(0,W3D_Z_NOTEQUAL);Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_znotequal;
719 ZMode=ZMODE(0,W3D_Z_EQUAL); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zequal;
720 ZMode=ZMODE(0,W3D_Z_ALWAYS); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zalways;
722 ZMode=ZMODE(1,W3D_Z_NEVER); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_znever_update;
723 ZMode=ZMODE(1,W3D_Z_LESS); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zless_update;
724 ZMode=ZMODE(1,W3D_Z_GEQUAL); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zgequal_update;
725 ZMode=ZMODE(1,W3D_Z_LEQUAL); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zlequal_update;
726 ZMode=ZMODE(1,W3D_Z_GREATER); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zgreater_update;
727 ZMode=ZMODE(1,W3D_Z_NOTEQUAL);Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_znotequal_update;
728 ZMode=ZMODE(1,W3D_Z_EQUAL); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zequal_update;
729 ZMode=ZMODE(1,W3D_Z_ALWAYS); Functions.Ztest[ZMode]=(HOOKEDFUNCTION)Ztest_zalways_update;
731 FillMode=(FALSE*4 + TRUE*2 + TRUE*1 ); Functions.Fill[FillMode]=(HOOKEDFUNCTION)Fill_Gouraud_Fog;
732 FillMode=(FALSE*4 + TRUE*2 + FALSE*1 ); Functions.Fill[FillMode]=(HOOKEDFUNCTION)Fill_Gouraud;
733 FillMode=(FALSE*4 + FALSE*2 + TRUE*1 ); Functions.Fill[FillMode]=(HOOKEDFUNCTION)Fill_Fog;
734 FillMode=(FALSE*4 + FALSE*2 + FALSE*1 ); Functions.Fill[FillMode]=(HOOKEDFUNCTION)Fill_Flat;
736 FillMode=(TRUE*4 + TRUE*2 + TRUE*1 ); Functions.Fill[FillMode]=(HOOKEDFUNCTION)Fill_Tex_Gouraud_Fog;
737 FillMode=(TRUE*4 + TRUE*2 + FALSE*1 ); Functions.Fill[FillMode]=(HOOKEDFUNCTION)Fill_Tex_Gouraud;
738 FillMode=(TRUE*4 + FALSE*2 + TRUE*1 ); Functions.Fill[FillMode]=(HOOKEDFUNCTION)Fill_Tex_Fog;
739 FillMode=(TRUE*4 + FALSE*2 + FALSE*1 ); Functions.Fill[FillMode]=(HOOKEDFUNCTION)Fill_Tex;
741 Functions.Edge[0]=(HOOKEDFUNCTION)Edge_Flat; /* Flat */
742 Functions.Edge[1]=(HOOKEDFUNCTION)Edge_Tex_Gouraud_Fog; /* Fog */
743 Functions.Edge[2]=(HOOKEDFUNCTION)Edge_Gouraud; /* Gouraud */
744 Functions.Edge[3]=(HOOKEDFUNCTION)Edge_Tex_Gouraud_Fog; /* Gouraud_Fog */
745 Functions.Edge[4]=(HOOKEDFUNCTION)Edge_Tex; /* Tex */
746 Functions.Edge[5]=(HOOKEDFUNCTION)Edge_Tex_Gouraud_Fog; /* Tex_Fog */
747 Functions.Edge[6]=(HOOKEDFUNCTION)Edge_Tex_Gouraud_Fog; /* Tex_Gouraud */
748 Functions.Edge[7]=(HOOKEDFUNCTION)Edge_Tex_Gouraud_Fog; /* Tex_Gouraud_Fog */
750 Functions.Edge[ 8]=(HOOKEDFUNCTION)Edge_Flat; /* Persp_Flat */
751 Functions.Edge[ 9]=(HOOKEDFUNCTION)Edge_Tex_Gouraud_Fog; /* Persp_Fog */
752 Functions.Edge[10]=(HOOKEDFUNCTION)Edge_Gouraud; /* Persp_Gouraud */
753 Functions.Edge[11]=(HOOKEDFUNCTION)Edge_Tex_Gouraud_Fog; /* Persp_Gouraud_Fog */
754 Functions.Edge[12]=(HOOKEDFUNCTION)Edge_Persp_Tex; /* Persp_Tex */
755 Functions.Edge[13]=(HOOKEDFUNCTION)Edge_Persp_Tex_Gouraud_Fog; /* Persp_Tex_Fog */
756 Functions.Edge[14]=(HOOKEDFUNCTION)Edge_Persp_Tex_Gouraud_Fog; /* Persp_Tex_Gouraud */
757 Functions.Edge[15]=(HOOKEDFUNCTION)Edge_Persp_Tex_Gouraud_Fog; /* Persp_Tex_Gouraud_Fog*/
759 Functions.TexEnv[0 *2+0]=(HOOKEDFUNCTION)NULL;
760 Functions.TexEnv[W3D_REPLACE *2+0]=(HOOKEDFUNCTION)PixelsReplace24;
761 Functions.TexEnv[W3D_REPLACE *2+1]=(HOOKEDFUNCTION)PixelsReplace32;
762 Functions.TexEnv[W3D_MODULATE *2+0]=(HOOKEDFUNCTION)PixelsModulate24;
763 Functions.TexEnv[W3D_MODULATE *2+1]=(HOOKEDFUNCTION)PixelsModulate32;
764 Functions.TexEnv[W3D_DECAL *2+0]=(HOOKEDFUNCTION)PixelsDecal24;
765 Functions.TexEnv[W3D_DECAL *2+1]=(HOOKEDFUNCTION)PixelsDecal32;
766 Functions.TexEnv[W3D_BLEND *2+0]=(HOOKEDFUNCTION)PixelsBlend24;
767 Functions.TexEnv[W3D_BLEND *2+1]=(HOOKEDFUNCTION)PixelsBlend32;
768 #ifdef WARP3DV5
769 Functions.TexEnv[W3D_ADD *2+0]=(HOOKEDFUNCTION)PixelsAdd24;
770 Functions.TexEnv[W3D_ADD *2+1]=(HOOKEDFUNCTION)PixelsAdd32;
771 Functions.TexEnv[W3D_SUB *2+0]=(HOOKEDFUNCTION)PixelsSub24;
772 Functions.TexEnv[W3D_SUB *2+1]=(HOOKEDFUNCTION)PixelsSub32;
773 #endif
775 SC->FunctionWriteImageBuffer=(HOOKEDFUNCTION)WriteImageBuffer;
777 /* default set to "no fast blend function " */
778 NLOOP(256)
779 Functions.BlendFast[n]=(HOOKEDFUNCTION)NULL;
781 Functions.BlendFast[W3D_ONE*16 + W3D_ZERO]= (HOOKEDFUNCTION)PixelsOne_Zero32; /* classic Replace */
782 Functions.BlendFast[W3D_SRC_ALPHA*16 + W3D_ONE_MINUS_SRC_ALPHA]= (HOOKEDFUNCTION)PixelsSrcAlpha_OneMinusSrcAlpha32; /* classic Alpha transparency */
783 Functions.BlendFast[W3D_SRC_ALPHA*16 + W3D_ONE]= (HOOKEDFUNCTION)PixelsSrcAlpha_One32; /* Glxcess' transparency */
784 Functions.BlendFast[W3D_ONE*16 + W3D_ONE]= (HOOKEDFUNCTION)PixelsOne_One24; /* Quake's glow effect */
785 Functions.BlendFast[W3D_ZERO*16 + W3D_SRC_ALPHA]= (HOOKEDFUNCTION)PixelsZero_SrcAlpha32; /* Quake's lightmap effect */
786 Functions.BlendFast[W3D_ZERO*16 + W3D_SRC_COLOR]= (HOOKEDFUNCTION)PixelsZero_SrcColor24; /* Modulate effect */
787 Functions.BlendFast[W3D_DST_COLOR*16 + W3D_ZERO]= (HOOKEDFUNCTION)PixelsDstColor_Zero24; /* modulate effect = same as M */
788 Functions.BlendFast[W3D_ZERO*16 + W3D_ONE_MINUS_SRC_COLOR]= (HOOKEDFUNCTION)PixelsZero_OneMinusSrcColor24; /* Coloring for demo Glxcess */
789 Functions.BlendFast[W3D_SRC_ALPHA*16 + W3D_ONE_MINUS_SRC_COLOR]= (HOOKEDFUNCTION)PixelsSrcAlpha_OneMinusSrcColor32; /* coloring for demo Glxcess */
790 Functions.BlendFast[W3D_ONE*16 + W3D_ONE_MINUS_SRC_ALPHA]= (HOOKEDFUNCTION)PixelsOne_OneMinusSrcAlpha32; /* GlTron transparency */
792 /* v51: fast simple chromatest : color not black */
793 Functions.BlendFast[BLENDCHROMA]= (HOOKEDFUNCTION)PixelsChroma32fast;
795 Functions.BlendFast[BLENDFASTALPHA]= (HOOKEDFUNCTION)PixelsSrcAlpha_OneMinusSrcAlpha32fast;
798 #ifdef SLOWCPU
799 /* compute the precalculated tables */
800 Oper.L.Index=0;
801 XLOOP(256)
802 YLOOP(256)
804 Oper.B.a=x;
805 Oper.B.b=y;
806 SC->Mul8[Oper.L.Index]=((x*y)/255);
807 if((x+y)<256)
808 SC->Add8[Oper.L.Index]=x+y;
809 else
810 SC->Add8[Oper.L.Index]=255;
811 SC->Fil8[Oper.L.Index]=(x+y)/2;
813 #endif
816 /* fragments buffer sizes */
817 SC->FragBufferDone=SC->FragBuffer;
818 SC->FragBufferMaxi=SC->FragBuffer + (FRAGBUFFERSIZE-MAXSCREEN-4);
820 SC->UseHard=FALSE;
821 #if defined(OS4COMPOSITING)
822 SC->UseHard=(Wazp3D->Renderer.ON==2); /* 2= Compositing so will disable soft renderering */
823 if(SC->UseHard) COMP3D_Start(SC);
824 #endif
826 #ifdef USEOPENGL
827 struct HARD3D_context *HC=&SC->HC;
828 SC->UseHard=(Wazp3D->Renderer.ON>=2); /* as 2 mean "use hard" */
829 if(SC->UseHard)
831 HC->UseAntiAlias = (Wazp3D->UseAntiImage.ON );
832 HC->UseOverlay = (Wazp3D->Renderer.ON==3 );
833 HC->DebugHard = (Wazp3D->DebugSC.ON==TRUE );
834 HC->awin = Wazp3D->window;
835 HARD3D_Start(&SC->HC);
837 #endif
838 SC->Tnb=0; /* texture number */
840 #if !defined(AMIGA) /* so we are compiling the DLL */
841 Wazp3D->UseRatioAlpha.ON=FALSE;
842 Wazp3D->UseAlphaMinMax.ON=FALSE;
843 Wazp3D->TexMode.ON=1; /* we assume that PC cpu is fast enough to enable nice features */
844 Wazp3D->PerspMode.ON=2;
845 #endif
847 SREM(SOFT3D_Start:OK)
848 return(SC);
850 /*=================================================================*/
851 void SOFT3D_SetClipping(APTR sc,UWORD xmin,UWORD xmax,UWORD ymin,UWORD ymax)
853 struct SOFT3D_context *SC=sc;
855 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
856 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
857 SFUNCTION(SOFT3D_SetClipping)
858 SVAR(xmin)
859 SVAR(xmax)
860 SVAR(ymin)
861 SVAR(ymax)
862 SC->ClipMin.x=xmin;
863 SC->ClipMax.x=xmax;
864 SC->ClipMin.y=ymin;
865 SC->ClipMax.y=ymax;
866 SC->ClipMin.z=0.0;
867 SC->ClipMax.z=1.0;
868 #ifdef USEOPENGL
869 if(SC->UseHard) HARD3D_SetClipping(&SC->HC,xmin,xmax,ymin,ymax);
870 #endif
872 /*=============================================================*/
873 void SOFT3D_ClearImageBuffer(APTR sc,UWORD x,UWORD y,UWORD large,UWORD high,APTR rgba)
875 struct SOFT3D_context *SC=sc;
876 UBYTE *RGBA=rgba;
877 ULONG *ptRGBA32=(ULONG *)RGBA;
878 register ULONG RGBA32=ptRGBA32[0];
879 register ULONG *I32;
880 register LONG size;
881 register LONG n;
883 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
884 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
885 SFUNCTION(SOFT3D_ClearImageBuffer)
886 if(SC->ImageBuffer32==NULL) return;
887 SVAR(SC->Image8)
888 SVAR(x)
889 SVAR(y)
890 SVAR(large)
891 SVAR(high)
892 SVAR(SC->large)
894 #ifdef USEOPENGL
895 ; /* do nothing as the hardware cant use an existing ImageBuffer32 */
896 #endif
897 SREM(ImageBuffer32 present)
898 I32=&SC->ImageBuffer32[y*SC->large];
899 SVAR(I32)
900 size=SC->large*high/8;
901 if(RGBA32==0)
902 NLOOP(size)
904 I32[0]=0;I32[1]=0;I32[2]=0;I32[3]=0;
905 I32[4]=0;I32[5]=0;I32[6]=0;I32[7]=0;
906 I32+=8;
908 else
909 NLOOP(size)
911 I32[0]=RGBA32;I32[1]=RGBA32;I32[2]=RGBA32;I32[3]=RGBA32;
912 I32[4]=RGBA32;I32[5]=RGBA32;I32[6]=RGBA32;I32[7]=RGBA32;
913 I32+=8;
917 /*=============================================================*/
918 void SOFT3D_ClearZBuffer(APTR sc,float fz)
920 struct SOFT3D_context *SC=sc;
921 register ZBUFF *Zbuffer;
922 register ULONG size=SC->high*SC->large/8;
923 register ULONG n;
924 register ZBUFF z;
925 register float zresize=ZRESIZE;
927 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
928 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
930 SFUNCTION(SOFT3D_ClearZBuffer)
932 if(SC->Zbuffer!=NULL) /* only happen in software mode */
934 Zbuffer=SC->Zbuffer;
935 SVARF(fz)
936 z=fz*zresize;
937 if (z < MINZ) z=MINZ;
938 if (MAXZ < z) z=MAXZ;
939 SVARF(z)
940 NLOOP(size)
942 Zbuffer[0]=z; Zbuffer[1]=z; Zbuffer[2]=z; Zbuffer[3]=z;
943 Zbuffer[4]=z; Zbuffer[5]=z; Zbuffer[6]=z; Zbuffer[7]=z;
944 Zbuffer+=8;
948 #ifdef USEOPENGL
949 if(SC->UseHard) HARD3D_ClearZBuffer(&SC->HC,fz);
950 #endif
952 /*==========================================================================*/
953 void SOFT3D_ReadZSpan(APTR sc, UWORD x, UWORD y,ULONG n, APTR z)
955 struct SOFT3D_context *SC=sc;
956 register ZBUFF *Zbuffer;
957 W3D_Double *dz=z;
958 register float fz;
959 register float zresize=ZRESIZE;
960 register ULONG i;
962 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
963 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
964 SFUNCTION(SOFT3D_ReadZSpan)
965 if(SC->Zbuffer!=NULL) /* only happen in software mode */
967 Zbuffer=SC->edge1[y].L.ZbufferY + x;
968 ILOOP(n)
970 fz=(float)Zbuffer[i];
971 fz=fz/zresize;
972 dz[i]=(W3D_Double)fz;
975 #ifdef USEOPENGL
976 if(SC->UseHard) HARD3D_ReadZSpan(&SC->HC,x,y,n,z);
977 #endif
979 /*==========================================================================*/
980 void SOFT3D_WriteZSpan(APTR sc, UWORD x, UWORD y,ULONG n,APTR z,APTR mask)
982 struct SOFT3D_context *SC=sc;
983 register ZBUFF *Zbuffer;
984 register W3D_Double *dz=z;
985 register float fz;
986 register float zresize=ZRESIZE;
987 register UBYTE *m=mask;
988 register ULONG i;
990 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
991 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
992 SFUNCTION(SOFT3D_WriteZSpan)
993 if(SC->Zbuffer!=NULL) /* only happen in software mode */
995 Zbuffer=SC->edge1[y].L.ZbufferY + x;
996 ILOOP(n)
997 if(m[i]!=0)
999 fz=dz[i];
1000 if (fz < MINZ) fz=MINZ;
1001 if (MAXZ < fz) fz=MAXZ;
1002 Zbuffer[i]=fz*zresize;
1005 #ifdef USEOPENGL
1006 if(SC->UseHard) HARD3D_WriteZSpan(&SC->HC,x,y,n,z,mask);
1007 #endif
1009 /*=============================================================*/
1010 void SOFT3D_End(APTR sc)
1012 struct SOFT3D_context *SC=sc;
1014 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
1015 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
1016 SFUNCTION(SOFT3D_End)
1017 if(SC==NULL) return;
1018 if(SC->ImageBuffer32!=NULL)
1020 SREM(Free ImageBuffer32)
1021 FREEPTR(SC->ImageBuffer32);
1023 #ifdef USEOPENGL
1024 if(SC->UseHard) HARD3D_End(&SC->HC);
1025 #endif
1026 #if defined(OS4COMPOSITING)
1027 if(SC->UseHard) COMP3D_End(SC);
1028 #endif
1029 FREEPTR(SC);
1031 /*=============================================================*/
1032 #ifdef SLOWCPU
1034 #define ADD8(a1,b1,dst) Add.B.b=b1; Add.B.a=a1; dst=Add8[Add.L.Index];
1035 #define MUL8(a1,b1,dst) Mul.B.b=b1; Mul.B.a=a1; dst=Mul8[Mul.L.Index];
1036 #define NEXTADDMUL8(b1,a1,b2,a2,dst) Mul.B.b=b1; Mul2.B.b=b2; dst=Mul8[Mul.L.Index]+Mul8[Mul2.L.Index];
1037 #define FULLADDMUL8(b1,a1,b2,a2,dst) Mul.B.a=a1; Mul2.B.a=a2; NEXTADDMUL8(b1,a1,b2,a2,dst)
1038 #define FOG8X3(fog,dst) Mul.B.a=fog[3]; Mul.B.b=dst[0]; dst[0]=fog[0]+Mul8[Mul.L.Index]; Mul.B.b=dst[1];dst[1]=fog[1]+Mul8[Mul.L.Index]; Mul.B.b=dst[2]; dst[2]=fog[2]+Mul8[Mul.L.Index];
1039 #define FIL8(a1,b1,dst) Fil.B.a=a1; Fil.B.b=b1; dst=Fil8[Fil.L.Index];
1041 #else /* On x86 dont use the precalculated tables = just compute */
1043 #define ADD8(a1,b1,dst) if( ((UWORD)(b1)+(UWORD)(a1)) < 255) dst=((UWORD)(b1)+(UWORD)(a1)); else dst=255;
1044 #define MUL8(a1,b1,dst) dst=( ((UWORD)(b1)*(UWORD)(a1)) /255);
1045 #define NEXTADDMUL8(b1,a1,b2,a2,dst) dst=( ((UWORD)(b1)*(UWORD)(a1)) /255) + ( ((UWORD)(b2)*(UWORD)(a2)) /255);
1046 #define FULLADDMUL8(b1,a1,b2,a2,dst) dst=( ((UWORD)(b1)*(UWORD)(a1)) /255) + ( ((UWORD)(b2)*(UWORD)(a2)) /255);
1047 #define FOG8X3(fog,dst) dst[0]=fog[0]+( ((UWORD)(fog[3])*(UWORD)(dst[0])) /255); dst[1]=fog[1]+( ((UWORD)(fog[3])*(UWORD)(dst[1])) /255); dst[2]=fog[2]+( ((UWORD)(fog[3])*(UWORD)(dst[2])) /255);
1048 #define FIL8(a1,b1,dst) dst=((UWORD)(b1)+(UWORD)(a1))/2;
1050 #endif
1051 /*=============================================================*/
1052 /* since v34:new pixels-functions to do multi-pass blending */
1053 /* see OpenGL doc Ct=texture Cf=color Cc=env*/
1055 GL_TEXTURE_ENV_MODE:
1056 GL_REPLACE C = Ct A = At
1057 GL_MODULATE C = Ct * Cf A = At * Af
1058 GL_BLEND C = Cf*(1-Ct) + Cc*Ct A = Af * At
1059 GL_DECAL C = Cf*(1-At) + Ct*At A = Af
1060 f = fragment, t = texture, c = GL_TEXTURE_ENV_COLOR
1061 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE,param);
1062 glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR,param);
1064 /*=============================================================*/
1065 #define CT1R Frag[0].Tex8[0]
1066 #define CT1G Frag[0].Tex8[1]
1067 #define CT1B Frag[0].Tex8[2]
1068 #define AT1 Frag[0].Tex8[3]
1069 #define CF1R Frag[0].ColorRGBA[0]
1070 #define CF1G Frag[0].ColorRGBA[1]
1071 #define CF1B Frag[0].ColorRGBA[2]
1072 #define AF1 Frag[0].ColorRGBA[3]
1074 #define CT2R Frag[1].Tex8[0]
1075 #define CT2G Frag[1].Tex8[1]
1076 #define CT2B Frag[1].Tex8[2]
1077 #define AT2 Frag[1].Tex8[3]
1078 #define CF2R Frag[1].ColorRGBA[0]
1079 #define CF2G Frag[1].ColorRGBA[1]
1080 #define CF2B Frag[1].ColorRGBA[2]
1081 #define AF2 Frag[1].ColorRGBA[3]
1083 #define CCR EnvRGBA[0]
1084 #define CCG EnvRGBA[1]
1085 #define CCB EnvRGBA[2]
1087 #define AT Ct[3]
1088 #define AF Cf[3]
1089 #define ONE 255
1090 /*=============================================================*/
1091 void PixelsTex32ToImage(struct SOFT3D_context *SC)
1093 register struct fragbuffer3D *Frag=SC->FragBuffer;
1094 register ULONG size=SC->FragSize2;
1096 SREM(PixelsTex32ToImage)
1097 while(0<size--)
1099 COPYRGBA(Frag[0].Image8,Frag[0].Tex8);
1100 COPYRGBA(Frag[1].Image8,Frag[1].Tex8);
1101 Frag+=2;
1104 /*=============================================================*/
1105 void PixelsTex24ToImage(struct SOFT3D_context *SC)
1107 register struct fragbuffer3D *Frag=SC->FragBuffer;
1108 register ULONG size=SC->FragSize2;
1109 register union rgba3D Color;
1110 register ULONG *dst32;
1112 SREM(PixelsTex24ToImage)
1113 Color.B.RGBA[3]=ONE;
1114 while(0<size--)
1116 Color.B.RGBA[0]=Frag[0].Tex8[0];
1117 Color.B.RGBA[1]=Frag[0].Tex8[1];
1118 Color.B.RGBA[2]=Frag[0].Tex8[2];
1119 dst32=(ULONG *)Frag[0].Image8;
1120 *dst32=Color.L.RGBA32;
1122 Color.B.RGBA[0]=Frag[1].Tex8[0];
1123 Color.B.RGBA[1]=Frag[1].Tex8[1];
1124 Color.B.RGBA[2]=Frag[1].Tex8[2];
1125 dst32=(ULONG *)Frag[1].Image8;
1126 *dst32=Color.L.RGBA32;
1127 Frag+=2;
1130 /*=============================================================*/
1131 void PixelsColorToImage(struct SOFT3D_context *SC)
1133 register struct fragbuffer3D *Frag=SC->FragBuffer;
1134 register ULONG size=SC->FragSize2;
1136 SREM(PixelsColorToImage)
1137 while(0<size--)
1139 COPYRGBA(Frag[0].Image8,Frag[0].ColorRGBA);
1140 COPYRGBA(Frag[1].Image8,Frag[1].ColorRGBA);
1141 Frag+=2;
1144 /*=============================================================*/
1145 void PixelsTex32ToBuffer(struct SOFT3D_context *SC)
1147 register struct fragbuffer3D *Frag=SC->FragBuffer;
1148 register ULONG size=SC->FragSize2;
1150 SREM(PixelsTex32ToBuffer)
1151 while(0<size--)
1153 COPYRGBA(Frag[0].BufferRGBA,Frag[0].Tex8);
1154 COPYRGBA(Frag[1].BufferRGBA,Frag[1].Tex8);
1155 Frag+=2;
1158 /*=============================================================*/
1159 void PixelsTex24ToBuffer(struct SOFT3D_context *SC)
1161 register struct fragbuffer3D *Frag=SC->FragBuffer;
1162 register ULONG size=SC->FragSize2;
1163 register union rgba3D Color;
1164 register ULONG *dst32;
1166 SREM(PixelsTex24ToBuffer)
1167 Color.B.RGBA[3]=ONE;
1168 while(0<size--)
1170 Color.B.RGBA[0]=Frag[0].Tex8[0];
1171 Color.B.RGBA[1]=Frag[0].Tex8[1];
1172 Color.B.RGBA[2]=Frag[0].Tex8[2];
1173 dst32=(ULONG *)Frag[0].BufferRGBA;
1174 *dst32=Color.L.RGBA32;
1176 Color.B.RGBA[0]=Frag[1].Tex8[0];
1177 Color.B.RGBA[1]=Frag[1].Tex8[1];
1178 Color.B.RGBA[2]=Frag[1].Tex8[2];
1179 dst32=(ULONG *)Frag[1].BufferRGBA;
1180 *dst32=Color.L.RGBA32;
1181 Frag+=2;
1184 /*=============================================================*/
1185 void PixelsColorToBuffer(struct SOFT3D_context *SC)
1187 register struct fragbuffer3D *Frag=SC->FragBuffer;
1188 register ULONG size=SC->FragSize2;
1190 SREM(PixelsColorToBuffer)
1191 while(0<size--)
1193 COPYRGBA(Frag[0].BufferRGBA,Frag[0].ColorRGBA);
1194 COPYRGBA(Frag[1].BufferRGBA,Frag[1].ColorRGBA);
1195 Frag+=2;
1198 /*=============================================================*/
1199 void PixelsReplace24(struct SOFT3D_context *SC)
1201 /* replace color=tex (always) */
1202 register struct fragbuffer3D *Frag=SC->FragBuffer;
1203 register ULONG size=SC->FragSize2;
1204 register union rgba3D Color;
1205 register ULONG *dst32;
1207 SREM(PixelsReplace24)
1208 Color.B.RGBA[3]=ONE;
1209 while(0<size--)
1211 Color.B.RGBA[0]=Frag[0].Tex8[0];
1212 Color.B.RGBA[1]=Frag[0].Tex8[1];
1213 Color.B.RGBA[2]=Frag[0].Tex8[2];
1214 dst32=(ULONG *)Frag[0].ColorRGBA;
1215 *dst32=Color.L.RGBA32;
1217 Color.B.RGBA[0]=Frag[1].Tex8[0];
1218 Color.B.RGBA[1]=Frag[1].Tex8[1];
1219 Color.B.RGBA[2]=Frag[1].Tex8[2];
1220 dst32=(ULONG *)Frag[1].ColorRGBA;
1221 *dst32=Color.L.RGBA32;
1222 Frag+=2;
1225 /*=============================================================*/
1226 void PixelsReplace32(struct SOFT3D_context *SC)
1228 /* replace color=tex (always) */
1229 register struct fragbuffer3D *Frag=SC->FragBuffer;
1230 register ULONG size=SC->FragSize2;
1232 SREM(PixelsReplace32)
1233 while(0<size--)
1235 COPYRGBA(Frag[0].ColorRGBA,Frag[0].Tex8);
1236 COPYRGBA(Frag[1].ColorRGBA,Frag[1].Tex8);
1237 Frag+=2;
1240 /*=============================================================*/
1241 void PixelsModulate24(struct SOFT3D_context *SC)
1243 /* v40: modulate src & dst (always) */
1244 register struct fragbuffer3D *Frag=SC->FragBuffer;
1245 register ULONG size=SC->FragSize2;
1246 #ifdef SLOWCPU
1247 register UBYTE *Mul8=SC->Mul8;
1248 register union oper3D Mul;
1250 Mul.L.Index=0;
1251 #endif
1252 SREM(PixelsModulate24)
1253 while(0<size--)
1255 MUL8(CT1R,CF1R,CF1R)
1256 MUL8(CT1G,CF1G,CF1G)
1257 MUL8(CT1B,CF1B,CF1B)
1259 MUL8(CT2R,CF2R,CF2R)
1260 MUL8(CT2G,CF2G,CF2G)
1261 MUL8(CT2B,CF2B,CF2B)
1262 Frag+=2;
1265 /*=============================================================*/
1266 void PixelsModulate32(struct SOFT3D_context *SC)
1268 /* v40: modulate src & dst (always) */
1269 register struct fragbuffer3D *Frag=SC->FragBuffer;
1270 register ULONG size=SC->FragSize2;
1271 #ifdef SLOWCPU
1272 register UBYTE *Mul8=SC->Mul8;
1273 register union oper3D Mul;
1275 Mul.L.Index=0;
1276 #endif
1278 SREM(PixelsModulate32)
1279 while(0<size--)
1281 MUL8(CT1R,CF1R,CF1R)
1282 MUL8(CT1G,CF1G,CF1G)
1283 MUL8(CT1B,CF1B,CF1B)
1284 MUL8(AT1,AF1,AF1)
1286 MUL8(CT2R,CF2R,CF2R)
1287 MUL8(CT2G,CF2G,CF2G)
1288 MUL8(CT2B,CF2B,CF2B)
1289 MUL8(AT2,AF2,AF2)
1290 Frag+=2;
1293 /*=============================================================*/
1294 void PixelsDecal24(struct SOFT3D_context *SC)
1296 /* v40: decal src & dst (always) */
1297 register struct fragbuffer3D *Frag=SC->FragBuffer;
1298 register ULONG size=SC->FragSize2;
1300 SREM(Pixels24DEC)
1301 while(0<size--)
1303 CF1R=CT1R;
1304 CF1G=CT1G;
1305 CF1B=CT1B;
1306 AF1 =ONE;
1308 CF2R=CT2R;
1309 CF2G=CT2G;
1310 CF2B=CT2B;
1311 AF2 =ONE;
1312 Frag+=2;
1315 /*=============================================================*/
1316 void PixelsDecal32(struct SOFT3D_context *SC)
1318 /* v40: decal src & dst (always) */
1319 register struct fragbuffer3D *Frag=SC->FragBuffer;
1320 register ULONG size=SC->FragSize2;
1321 #ifdef SLOWCPU
1322 register UBYTE *Mul8=SC->Mul8;
1323 register union oper3D Mul;
1324 register union oper3D Mul2;
1326 Mul.L.Index=Mul2.L.Index=0;
1327 #endif
1329 SREM(PixelsDecal32)
1330 while(0<size--)
1332 FULLADDMUL8(CT1R,AT1,CF1R,ONE-AT1,CF1R)
1333 FULLADDMUL8(CT1G,AT1,CF1G,ONE-AT1,CF1G)
1334 FULLADDMUL8(CT1B,AT1,CF1B,ONE-AT1,CF1B)
1335 /* AF1=AF1; */ /* alpha from color */
1337 FULLADDMUL8(CT2R,AT2,CF2R,ONE-AT2,CF2R)
1338 FULLADDMUL8(CT2G,AT2,CF2G,ONE-AT2,CF2G)
1339 FULLADDMUL8(CT2B,AT2,CF2B,ONE-AT2,CF2B)
1340 /* AF2=AF2; */ /* alpha from color */
1341 Frag+=2;
1344 /*=============================================================*/
1345 void PixelsBlend24(struct SOFT3D_context *SC)
1347 /* v40: blend src & dst & env (always) */
1348 register struct fragbuffer3D *Frag=SC->FragBuffer;
1349 register ULONG size=SC->FragSize2;
1350 register UBYTE *EnvRGBA=SC->state.EnvRGBA;
1351 #ifdef SLOWCPU
1352 register UBYTE *Mul8=SC->Mul8;
1353 register union oper3D Mul;
1354 register union oper3D Mul2;
1356 Mul.L.Index=Mul2.L.Index=0;
1357 #endif
1359 SREM(PixelsBlend24)
1360 while(0<size--)
1362 FULLADDMUL8(CF1R,ONE-CT1R,CCR,CT1R,CF1R)
1363 FULLADDMUL8(CF1G,ONE-CT1G,CCG,CT1G,CF1G)
1364 FULLADDMUL8(CF1B,ONE-CT1B,CCB,CT1B,CF1B)
1366 FULLADDMUL8(CF2R,ONE-CT2R,CCR,CT2R,CF2R)
1367 FULLADDMUL8(CF2G,ONE-CT2G,CCG,CT2G,CF2G)
1368 FULLADDMUL8(CF2B,ONE-CT2B,CCB,CT2B,CF2B)
1369 Frag+=2;
1372 /*=============================================================*/
1373 void PixelsBlend32(struct SOFT3D_context *SC)
1375 /* v40: blend src & dst & env (always) */
1376 register struct fragbuffer3D *Frag=SC->FragBuffer;
1377 register ULONG size=SC->FragSize2;
1378 register UBYTE *EnvRGBA=SC->state.EnvRGBA;
1379 #ifdef SLOWCPU
1380 register UBYTE *Mul8=SC->Mul8;
1381 register union oper3D Mul;
1382 register union oper3D Mul2;
1384 Mul.L.Index=Mul2.L.Index=0;
1385 #endif
1387 SREM(PixelsBlend32)
1388 while(0<size--)
1390 FULLADDMUL8(CF1R,ONE-CT1R,CCR,CT1R,CF1R)
1391 FULLADDMUL8(CF1G,ONE-CT1G,CCG,CT1G,CF1G)
1392 FULLADDMUL8(CF1B,ONE-CT1B,CCB,CT1B,CF1B)
1393 MUL8(AF1,AT1,AF1)
1395 FULLADDMUL8(CF2R,ONE-CT2R,CCR,CT2R,CF2R)
1396 FULLADDMUL8(CF2G,ONE-CT2G,CCG,CT2G,CF2G)
1397 FULLADDMUL8(CF2B,ONE-CT2B,CCB,CT2B,CF2B)
1398 MUL8(AF2,AT2,AF2)
1399 Frag+=2;
1402 /*=============================================================*/
1403 void PixelsAdd24(struct SOFT3D_context *SC)
1405 /* v50: add src & dst (always) */
1406 register struct fragbuffer3D *Frag=SC->FragBuffer;
1407 register ULONG size=SC->FragSize2;
1408 #ifdef SLOWCPU
1409 register UBYTE *Add8=SC->Add8;
1410 register union oper3D Add;
1412 Add.L.Index=0;
1413 #endif
1414 SREM(PixelsAdd24)
1415 while(0<size--)
1417 ADD8(CT1R,CF1R,CF1R) /* do color=color+tex */
1418 ADD8(CT1G,CF1G,CF1G)
1419 ADD8(CT1B,CF1B,CF1B)
1421 ADD8(CT2R,CF2R,CF2R)
1422 ADD8(CT2G,CF2G,CF2G)
1423 ADD8(CT2B,CF2B,CF2B)
1424 Frag+=2;
1427 /*=============================================================*/
1428 void PixelsAdd32(struct SOFT3D_context *SC)
1430 /* v50: add src & dst (always) */
1431 register struct fragbuffer3D *Frag=SC->FragBuffer;
1432 register ULONG size=SC->FragSize2;
1433 #ifdef SLOWCPU
1434 register UBYTE *Add8=SC->Add8;
1435 register union oper3D Add;
1437 Add.L.Index=0;
1438 #endif
1440 SREM(PixelsAdd32)
1441 while(0<size--)
1443 ADD8(CT1R,CF1R,CF1R) /* do color=color+tex */
1444 ADD8(CT1G,CF1G,CF1G)
1445 ADD8(CT1B,CF1B,CF1B)
1446 ADD8(AT1,AF1,AF1)
1448 ADD8(CT2R,CF2R,CF2R)
1449 ADD8(CT2G,CF2G,CF2G)
1450 ADD8(CT2B,CF2B,CF2B)
1451 ADD8(AT2,AF2,AF2)
1452 Frag+=2;
1455 /*=============================================================*/
1456 void PixelsSub24(struct SOFT3D_context *SC)
1458 /* v50: sub src & dst (always) */
1459 register struct fragbuffer3D *Frag=SC->FragBuffer;
1460 register ULONG size=SC->FragSize2;
1462 SREM(PixelsSub24)
1463 while(0<size--)
1465 if(CF1R>CT1R) CF1R=CF1R-CT1R; else CF1R=0;
1466 if(CF1G>CT1G) CF1G=CF1G-CT1G; else CF1G=0;
1467 if(CF1B>CT1B) CF1B=CF1B-CT1B; else CF1B=0;
1469 if(CF2R>CT2R) CF2R=CF2R-CT2R; else CF2R=0;
1470 if(CF2G>CT2G) CF2G=CF2G-CT2G; else CF2G=0;
1471 if(CF2B>CT2B) CF2B=CF2B-CT2B; else CF2B=0;
1472 Frag+=2;
1475 /*=============================================================*/
1476 void PixelsSub32(struct SOFT3D_context *SC)
1478 /* v50: sub src & dst (always) */
1479 register struct fragbuffer3D *Frag=SC->FragBuffer;
1480 register ULONG size=SC->FragSize2;
1482 SREM(PixelsSub32)
1483 while(0<size--)
1485 if(CF1R>CT1R) CF1R=CF1R-CT1R; else CF1R=0;
1486 if(CF1G>CT1G) CF1G=CF1G-CT1G; else CF1G=0;
1487 if(CF1B>CT1B) CF1B=CF1B-CT1B; else CF1B=0;
1488 if(AF1>AT1) AF1=AF1-AT1; else AF1=0;
1490 if(CF2R>CT2R) CF2R=CF2R-CT2R; else CF2R=0;
1491 if(CF2G>CT2G) CF2G=CF2G-CT2G; else CF2G=0;
1492 if(CF2B>CT2B) CF2B=CF2B-CT2B; else CF2B=0;
1493 if(AF2>AT2) AF2=AF2-AT2; else AF2=0;
1494 Frag+=2;
1497 /*=============================================================*/
1498 void PixelsFogToImage(struct SOFT3D_context *SC)
1500 /* blend source & dest (always) with a fog color already weigthed to fog A */
1501 /* FogRGBA[3] is set to background transparency against fog level */
1502 register struct fragbuffer3D *Frag=SC->FragBuffer;
1503 register ULONG size=SC->FragSize2;
1505 UBYTE A;
1507 #ifdef SLOWCPU
1508 register UBYTE *Mul8=SC->Mul8;
1509 register union oper3D Mul;
1511 register union oper3D Mul2;
1512 Mul2.L.Index=0;
1514 Mul.L.Index=0;
1515 #endif
1517 SREM(PixelsFogToBuffer)
1518 while(0<size--)
1520 /* TODO: find why this dont works
1521 FOG8X3(Frag[0].FogRGBA,Frag[0].Image8);
1522 FOG8X3(Frag[1].FogRGBA,Frag[1].Image8);
1524 A=Frag[0].FogRGBA[3];
1525 FULLADDMUL8(SC->state.FogRGBA[0],ONE-A,Frag[0].Image8[0],A,Frag[0].Image8[0])
1526 FULLADDMUL8(SC->state.FogRGBA[1],ONE-A,Frag[0].Image8[1],A,Frag[0].Image8[1])
1527 FULLADDMUL8(SC->state.FogRGBA[2],ONE-A,Frag[0].Image8[2],A,Frag[0].Image8[2])
1528 Frag[0].Image8[3]=255;
1530 A=Frag[1].FogRGBA[3];
1531 FULLADDMUL8(SC->state.FogRGBA[0],ONE-A,Frag[1].Image8[0],A,Frag[1].Image8[0])
1532 FULLADDMUL8(SC->state.FogRGBA[1],ONE-A,Frag[1].Image8[1],A,Frag[1].Image8[1])
1533 FULLADDMUL8(SC->state.FogRGBA[2],ONE-A,Frag[1].Image8[2],A,Frag[1].Image8[2])
1534 Frag[1].Image8[3]=255;
1536 Frag+=2;
1539 /*=============================================================*/
1540 void PixelsFogToBuffer(struct SOFT3D_context *SC)
1542 /* blend source & dest (always) with a fog color already weigthed to fog A */
1543 /* FogRGBA[3] is set to background transparency against fog level */
1544 register struct fragbuffer3D *Frag=SC->FragBuffer;
1545 register ULONG size=SC->FragSize2;
1547 UBYTE A;
1549 #ifdef SLOWCPU
1550 register UBYTE *Mul8=SC->Mul8;
1551 register union oper3D Mul;
1553 register union oper3D Mul2;
1554 Mul2.L.Index=0;
1556 Mul.L.Index=0;
1557 #endif
1559 SREM(PixelsFogToBuffer)
1560 while(0<size--)
1562 /* TODO: find why this dont works
1563 FOG8X3(Frag[0].FogRGBA,Frag[0].BufferRGBA);
1564 FOG8X3(Frag[1].FogRGBA,Frag[1].BufferRGBA);
1566 A=Frag[0].FogRGBA[3];
1567 FULLADDMUL8(SC->state.FogRGBA[0],ONE-A,Frag[0].BufferRGBA[0],A,Frag[0].BufferRGBA[0])
1568 FULLADDMUL8(SC->state.FogRGBA[1],ONE-A,Frag[0].BufferRGBA[1],A,Frag[0].BufferRGBA[1])
1569 FULLADDMUL8(SC->state.FogRGBA[2],ONE-A,Frag[0].BufferRGBA[2],A,Frag[0].BufferRGBA[2])
1570 Frag[0].BufferRGBA[3]=255;
1572 A=Frag[1].FogRGBA[3];
1573 FULLADDMUL8(SC->state.FogRGBA[0],ONE-A,Frag[1].BufferRGBA[0],A,Frag[1].BufferRGBA[0])
1574 FULLADDMUL8(SC->state.FogRGBA[1],ONE-A,Frag[1].BufferRGBA[1],A,Frag[1].BufferRGBA[1])
1575 FULLADDMUL8(SC->state.FogRGBA[2],ONE-A,Frag[1].BufferRGBA[2],A,Frag[1].BufferRGBA[2])
1576 Frag[1].BufferRGBA[3]=255;
1578 Frag+=2;
1581 /*=============================================================*/
1582 void PixelsSepiaToImage(struct SOFT3D_context *SC)
1584 /* colorize in red the pixels */
1585 register struct fragbuffer3D *Frag=SC->FragBuffer;
1586 register ULONG size=SC->FragSize2;
1587 register UWORD r;
1589 SREM(PixelsSepiaToImage)
1590 while(0<size--)
1592 r=Frag[0].Image8[0]+Frag[0].Image8[1]+Frag[0].Image8[2];
1593 Frag[0].Image8[0]=255;
1594 if(r<=255*2)
1595 Frag[0].Image8[0]=r/2;
1596 Frag[0].Image8[1]=r/4;
1597 Frag[0].Image8[2]=r/6;
1599 r=Frag[1].Image8[0]+Frag[1].Image8[1]+Frag[1].Image8[2];
1600 Frag[1].Image8[0]=255;
1601 if(r<=255*2)
1602 Frag[1].Image8[0]=r/2;
1603 Frag[1].Image8[1]=r/4;
1604 Frag[1].Image8[2]=r/6;
1605 Frag+=2;
1608 /*=============================================================*/
1609 void PixelsSepiaToBuffer(struct SOFT3D_context *SC)
1611 /* colorize in red the pixels */
1612 register struct fragbuffer3D *Frag=SC->FragBuffer;
1613 register ULONG size=SC->FragSize2;
1614 register UWORD r;
1616 SREM(PixelsSepiaToBuffer)
1617 while(0<size--)
1619 r=Frag[0].BufferRGBA[0]+Frag[0].BufferRGBA[1]+Frag[0].BufferRGBA[2];
1620 Frag[0].BufferRGBA[0]=255;
1621 if(r<=255*2)
1622 Frag[0].BufferRGBA[0]=r/2;
1623 Frag[0].BufferRGBA[1]=r/4;
1624 Frag[0].BufferRGBA[2]=r/6;
1626 r=Frag[1].BufferRGBA[0]+Frag[1].BufferRGBA[1]+Frag[1].BufferRGBA[2];
1627 Frag[1].BufferRGBA[0]=255;
1628 if(r<=255*2)
1629 Frag[1].BufferRGBA[0]=r/2;
1630 Frag[1].BufferRGBA[1]=r/4;
1631 Frag[1].BufferRGBA[2]=r/6;
1632 Frag+=2;
1635 /*=============================================================*/
1636 void PixelsFilterToImage(struct SOFT3D_context *SC)
1638 /* colorize in red the pixels */
1639 register struct fragbuffer3D *Frag=SC->FragBuffer;
1640 register LONG size=SC->FragSize2-4;
1641 #ifdef SLOWCPU
1642 register UBYTE *Fil8=SC->Fil8;
1643 register union oper3D Fil;
1645 Fil.L.Index=0;
1646 #endif
1648 SREM(PixelsFilterToImage)
1649 while(0<size--)
1652 if( (Frag[1].Image8-Frag[0].Image8) <= 4) /* if pixels are contiguous ? TODO: remove this slow test */
1654 FIL8(Frag[0].Image8[0],Frag[1].Image8[0],Frag[0].Image8[0]);
1655 FIL8(Frag[0].Image8[1],Frag[1].Image8[1],Frag[0].Image8[1]);
1656 FIL8(Frag[0].Image8[2],Frag[1].Image8[2],Frag[0].Image8[2]);
1659 if( (Frag[2].Image8-Frag[1].Image8) <= 4)
1661 FIL8(Frag[1].Image8[0],Frag[2].Image8[0],Frag[1].Image8[0]);
1662 FIL8(Frag[1].Image8[1],Frag[2].Image8[1],Frag[1].Image8[1]);
1663 FIL8(Frag[1].Image8[2],Frag[2].Image8[2],Frag[1].Image8[2]);
1666 Frag+=2;
1669 /*=============================================================*/
1670 void PixelsFilterToBuffer(struct SOFT3D_context *SC)
1672 /* colorize in red the pixels */
1673 register struct fragbuffer3D *Frag=SC->FragBuffer;
1674 register LONG size=SC->FragSize2-4;
1675 #ifdef SLOWCPU
1676 register UBYTE *Fil8=SC->Fil8;
1677 register union oper3D Fil;
1679 Fil.L.Index=0;
1680 #endif
1682 SREM(PixelsFilterToBuffer)
1683 while(0<size--)
1685 if( (Frag[1].Image8-Frag[0].Image8) <= 4)
1687 FIL8(Frag[0].BufferRGBA[0],Frag[1].BufferRGBA[0],Frag[0].BufferRGBA[0]);
1688 FIL8(Frag[0].BufferRGBA[1],Frag[1].BufferRGBA[1],Frag[0].BufferRGBA[1]);
1689 FIL8(Frag[0].BufferRGBA[2],Frag[1].BufferRGBA[2],Frag[0].BufferRGBA[2]);
1692 if( (Frag[2].Image8-Frag[1].Image8) <= 4)
1694 FIL8(Frag[1].BufferRGBA[0],Frag[2].BufferRGBA[0],Frag[1].BufferRGBA[0]);
1695 FIL8(Frag[1].BufferRGBA[1],Frag[2].BufferRGBA[1],Frag[1].BufferRGBA[1]);
1696 FIL8(Frag[1].BufferRGBA[2],Frag[2].BufferRGBA[2],Frag[1].BufferRGBA[2]);
1699 Frag+=2;
1702 /*=============================================================*/
1703 /* define all that to make formulas more easy to read */
1704 #define SRC1 Frag[0].ColorRGBA
1705 #define SRC1R Frag[0].ColorRGBA[0]
1706 #define SRC1G Frag[0].ColorRGBA[1]
1707 #define SRC1B Frag[0].ColorRGBA[2]
1708 #define SRC1A Frag[0].ColorRGBA[3]
1710 #define DST1 Frag[0].BufferRGBA
1711 #define DST1R Frag[0].BufferRGBA[0]
1712 #define DST1G Frag[0].BufferRGBA[1]
1713 #define DST1B Frag[0].BufferRGBA[2]
1714 #define DST1A Frag[0].BufferRGBA[3]
1716 #define TMP1 Frag[0].TmpRGBA
1717 #define TMP1R Frag[0].TmpRGBA[0]
1718 #define TMP1G Frag[0].TmpRGBA[1]
1719 #define TMP1B Frag[0].TmpRGBA[2]
1720 #define TMP1A Frag[0].TmpRGBA[3]
1722 #define SRC2 Frag[1].ColorRGBA
1723 #define SRC2R Frag[1].ColorRGBA[0]
1724 #define SRC2G Frag[1].ColorRGBA[1]
1725 #define SRC2B Frag[1].ColorRGBA[2]
1726 #define SRC2A Frag[1].ColorRGBA[3]
1728 #define DST2 Frag[1].BufferRGBA
1729 #define DST2R Frag[1].BufferRGBA[0]
1730 #define DST2G Frag[1].BufferRGBA[1]
1731 #define DST2B Frag[1].BufferRGBA[2]
1732 #define DST2A Frag[1].BufferRGBA[3]
1734 #define TMP2 Frag[1].TmpRGBA
1735 #define TMP2R Frag[1].TmpRGBA[0]
1736 #define TMP2G Frag[1].TmpRGBA[1]
1737 #define TMP2B Frag[1].TmpRGBA[2]
1738 #define TMP2A Frag[1].TmpRGBA[3]
1740 #define CONSTR SC->state.CurrentRGBA[0]
1741 #define CONSTG SC->state.CurrentRGBA[1]
1742 #define CONSTB SC->state.CurrentRGBA[2]
1743 #define CONSTA SC->state.CurrentRGBA[3]
1745 #define SRCFUNC1(rf,gf,bf,af) MUL8(SRC1R,rf,TMP1R) MUL8(SRC1G,gf,TMP1G) MUL8(SRC1B,bf,TMP1B) MUL8(SRC1A,af,TMP1A)
1746 #define SRCFUNC2(rf,gf,bf,af) MUL8(SRC2R,rf,TMP2R) MUL8(SRC2G,gf,TMP2G) MUL8(SRC2B,bf,TMP2B) MUL8(SRC2A,af,TMP2A)
1747 #define DSTFUNC1(rf,gf,bf,af) MUL8(DST1R,rf,dst) ADD8(TMP1R,dst,DST1R) MUL8(DST1G,gf,dst) ADD8(TMP1G,dst,DST1G) MUL8(DST1B,bf,dst) ADD8(TMP1B,dst,DST1B) MUL8(DST1A,af,dst) ADD8(TMP1A,dst,DST1A)
1748 #define DSTFUNC2(rf,gf,bf,af) MUL8(DST2R,rf,dst) ADD8(TMP2R,dst,DST2R) MUL8(DST2G,gf,dst) ADD8(TMP2G,dst,DST2G) MUL8(DST2B,bf,dst) ADD8(TMP2B,dst,DST2B) MUL8(DST2A,af,dst) ADD8(TMP2A,dst,DST2A)
1749 /*=============================================================*/
1751 srcfunc - The mode for the source pixel:
1752 1 W3D_ZERO
1753 2 W3D_ONE
1755 4 W3D_DST_COLOR
1756 6 W3D_ONE_MINUS_DST_COLOR
1757 9 W3D_DST_ALPHA
1758 10 W3D_ONE_MINUS_DST_ALPHA
1760 7 W3D_SRC_ALPHA
1761 8 W3D_ONE_MINUS_SRC_ALPHA
1763 12 W3D_CONSTANT_COLOR
1764 13 W3D_ONE_MINUS_CONSTANT_COLOR
1765 14 W3D_CONSTANT_ALPHA
1766 15 W3D_ONE_MINUS_CONSTANT_ALPHA
1768 11 W3D_SRC_ALPHA_SATURATE
1770 dstfunc - Mode for the destination:
1771 1 W3D_ZERO
1772 2 W3D_ONE
1774 3 W3D_SRC_COLOR
1775 5 W3D_ONE_MINUS_SRC_COLOR
1776 7 W3D_SRC_ALPHA
1777 8 W3D_ONE_MINUS_SRC_ALPHA
1779 9 W3D_DST_ALPHA
1780 10 W3D_ONE_MINUS_DST_ALPHA
1782 12 W3D_CONSTANT_COLOR
1783 13 W3D_ONE_MINUS_CONSTANT_COLOR
1784 14 W3D_CONSTANT_ALPHA
1785 15 W3D_ONE_MINUS_CONSTANT_ALPHA
1788 /*=============================================================*/
1789 void PixelsSrcAlpha_OneMinusSrcAlpha32perfect(struct SOFT3D_context *SC)
1791 /* blend source & dest (allways)*/
1792 register struct fragbuffer3D *Frag=SC->FragBuffer;
1793 register ULONG size=SC->FragSize2;
1794 #ifdef SLOWCPU
1795 register UBYTE *Mul8=SC->Mul8;
1796 register union oper3D Mul;
1797 register union oper3D Mul2;
1799 Mul.L.Index=Mul2.L.Index=0;
1800 #endif
1802 SREM(PixelsSrcAlpha_OneMinusSrcAlpha32perfect)
1803 while(0<size--)
1805 FULLADDMUL8(SRC1R,SRC1A,DST1R,ONE-SRC1A,DST1R)
1806 NEXTADDMUL8(SRC1G,SRC1A,DST1G,ONE-SRC1A,DST1G)
1807 NEXTADDMUL8(SRC1B,SRC1A,DST1B,ONE-SRC1A,DST1B)
1809 FULLADDMUL8(SRC2R,SRC2A,DST2R,ONE-SRC2A,DST2R)
1810 NEXTADDMUL8(SRC2G,SRC2A,DST2G,ONE-SRC2A,DST2G)
1811 NEXTADDMUL8(SRC2B,SRC2A,DST2B,ONE-SRC2A,DST2B)
1812 Frag+=2;
1815 /*=============================================================*/
1816 void PixelsSrcAlpha_OneMinusSrcAlpha32(struct SOFT3D_context *SC)
1818 /* blend source & dest (if source not solid nor transparent)*/
1819 register struct fragbuffer3D *Frag=SC->FragBuffer;
1820 register ULONG size=SC->FragSize2;
1821 #ifdef SLOWCPU
1822 register UBYTE *Mul8=SC->Mul8;
1823 register union oper3D Mul;
1824 register union oper3D Mul2;
1826 Mul.L.Index=Mul2.L.Index=0;
1827 #endif
1828 if(!Wazp3D->UseAlphaMinMax.ON)
1829 { PixelsSrcAlpha_OneMinusSrcAlpha32perfect(SC); return; }
1831 SREM(PixelsSrcAlpha_OneMinusSrcAlpha32)
1832 while(0<size--)
1834 if (SRC1A > MINALPHA) /* if source visible ? */
1836 if(SRC1A < MAXALPHA) /* if source not solid ? */
1838 FULLADDMUL8(SRC1R,SRC1A,DST1R,ONE-SRC1A,DST1R)
1839 NEXTADDMUL8(SRC1G,SRC1A,DST1G,ONE-SRC1A,DST1G)
1840 NEXTADDMUL8(SRC1B,SRC1A,DST1B,ONE-SRC1A,DST1B)
1842 else
1844 COPYRGBA(Frag[0].BufferRGBA,Frag[0].ColorRGBA);
1849 if (SRC2A > MINALPHA) /* if source visible ? */
1851 if(SRC2A < MAXALPHA) /* if source not solid ? */
1853 FULLADDMUL8(SRC2R,SRC2A,DST2R,ONE-SRC2A,DST2R)
1854 NEXTADDMUL8(SRC2G,SRC2A,DST2G,ONE-SRC2A,DST2G)
1855 NEXTADDMUL8(SRC2B,SRC2A,DST2B,ONE-SRC2A,DST2B)
1857 else
1859 COPYRGBA(Frag[1].BufferRGBA,Frag[1].ColorRGBA);
1863 Frag+=2;
1866 /*=============================================================*/
1867 void PixelsChroma32fast(struct SOFT3D_context *SC)
1869 /* copy source to dest (if not black)*/
1870 register struct fragbuffer3D *Frag=SC->FragBuffer;
1871 register ULONG size=SC->FragSize2;
1872 register ULONG black=((0<<24) + (0<<16) + (0<<8) + 255);
1873 register ULONG *rgba32;
1875 SREM(PixelsChroma32fast)
1876 while(0<size--)
1878 rgba32=(ULONG *)Frag[0].ColorRGBA;
1879 if (rgba32[0] != black) /* if source visible ? */
1880 COPYRGBA(Frag[0].BufferRGBA,Frag[0].ColorRGBA);
1882 rgba32=(ULONG *)Frag[1].ColorRGBA;
1883 if (rgba32[0] != black) /* if source visible ? */
1884 COPYRGBA(Frag[1].BufferRGBA,Frag[1].ColorRGBA);
1885 Frag+=2;
1888 /*=============================================================*/
1889 void PixelsSrcAlpha_OneMinusSrcAlpha32fast(struct SOFT3D_context *SC)
1891 /* copy source to dest (if source not transparent)*/
1892 register struct fragbuffer3D *Frag=SC->FragBuffer;
1893 register ULONG size=SC->FragSize2;
1895 SREM(PixelsSrcAlpha_OneMinusSrcAlpha32fast)
1896 while(0<size--)
1898 if (SRC1A > MINALPHA) /* if source visible ? */
1899 COPYRGBA(Frag[0].BufferRGBA,Frag[0].ColorRGBA);
1901 if (SRC2A > MINALPHA) /* if source visible ? */
1902 COPYRGBA(Frag[1].BufferRGBA,Frag[1].ColorRGBA);
1903 Frag+=2;
1906 /*=============================================================*/
1907 void PixelsOne_Zero32(struct SOFT3D_context *SC)
1909 /* copy source to dest = replace */
1910 register struct fragbuffer3D *Frag=SC->FragBuffer;
1911 register ULONG size=SC->FragSize2;
1913 SREM(PixelsOne_Zero)
1914 while(0<size--)
1916 COPYRGBA(Frag[0].BufferRGBA,Frag[0].ColorRGBA);
1917 COPYRGBA(Frag[1].BufferRGBA,Frag[1].ColorRGBA);
1918 Frag+=2;
1921 /*=============================================================*/
1922 void PixelsSrcAlpha_One32(struct SOFT3D_context *SC)
1924 /* v45: for glxcess :-) */
1925 register struct fragbuffer3D *Frag=SC->FragBuffer;
1926 register ULONG size=SC->FragSize2;
1927 register UBYTE tmp;
1928 #ifdef SLOWCPU
1929 register UBYTE *Mul8=SC->Mul8;
1930 register UBYTE *Add8=SC->Add8;
1931 register union oper3D Add;
1932 register union oper3D Mul;
1934 Mul.L.Index=Add.L.Index=0;
1935 #endif
1937 SREM(PixelsSrcAlpha_One32)
1938 while(0<size--)
1940 if (SRC1A > MINALPHA) /* if source visible ? */
1942 if(SRC1A < MAXALPHA) /* if source not solid ? */
1944 MUL8(SRC1R,SRC1A,tmp) ADD8(tmp,DST1R,DST1R)
1945 MUL8(SRC1G,SRC1A,tmp) ADD8(tmp,DST1G,DST1G)
1946 MUL8(SRC1B,SRC1A,tmp) ADD8(tmp,DST1B,DST1B)
1948 else
1950 ADD8(SRC1R,DST1R,DST1R)
1951 ADD8(SRC1G,DST1G,DST1G)
1952 ADD8(SRC1B,DST1B,DST1B)
1957 if (SRC2A > MINALPHA) /* if source visible ? */
1959 if(SRC2A < MAXALPHA) /* if source not solid ? */
1961 MUL8(SRC2R,SRC2A,tmp) ADD8(tmp,DST2R,DST2R)
1962 MUL8(SRC2G,SRC2A,tmp) ADD8(tmp,DST2G,DST2G)
1963 MUL8(SRC2B,SRC2A,tmp) ADD8(tmp,DST2B,DST2B)
1965 else
1967 ADD8(SRC2R,DST2R,DST2R)
1968 ADD8(SRC2G,DST2G,DST2G)
1969 ADD8(SRC2B,DST2B,DST2B)
1973 Frag+=2;
1977 /*=============================================================*/
1978 void PixelsOne_OneMinusSrcAlpha32(struct SOFT3D_context *SC)
1980 /* v45: for glxcess :-) */
1981 /* v50: this function fixed */
1982 register struct fragbuffer3D *Frag=SC->FragBuffer;
1983 register ULONG size=SC->FragSize2;
1984 register UBYTE tmp;
1985 register UBYTE A;
1986 #ifdef SLOWCPU
1987 register UBYTE *Mul8=SC->Mul8;
1988 register UBYTE *Add8=SC->Add8;
1989 register union oper3D Add;
1990 register union oper3D Mul;
1992 Mul.L.Index=Add.L.Index=0;
1993 #endif
1995 SREM(PixelsOne_OneMinusSrcAlpha32)
1996 while(0<size--)
1998 A=ONE-SRC1A;
1999 if (A < MAXALPHA) /* just keep dest unchanged */
2001 if(A > MINALPHA) /* if dest not cleaned */
2003 MUL8(DST1R,A,tmp); ADD8(tmp,SRC1R,DST1R);
2004 MUL8(DST1G,A,tmp); ADD8(tmp,SRC1G,DST1G);
2005 MUL8(DST1B,A,tmp); ADD8(tmp,SRC1B,DST1B);
2007 else
2009 COPYRGBA(Frag[0].BufferRGBA,Frag[0].ColorRGBA);
2013 DST1A=ONE;
2015 A=ONE-SRC2A;
2016 if (A < MAXALPHA) /* just keep dest unchanged */
2018 if(A > MINALPHA) /* if dest not cleaned */
2020 MUL8(DST2R,A,tmp); ADD8(tmp,SRC2R,DST2R);
2021 MUL8(DST2G,A,tmp); ADD8(tmp,SRC2G,DST2G);
2022 MUL8(DST2B,A,tmp); ADD8(tmp,SRC2B,DST2B);
2024 else
2026 COPYRGBA(Frag[1].BufferRGBA,Frag[0].ColorRGBA);
2030 DST2A=ONE;
2032 Frag+=2;
2036 /*=============================================================*/
2037 void PixelsOne_One24(struct SOFT3D_context *SC)
2039 /* v41: add saturate src & dst (allways) */
2040 register struct fragbuffer3D *Frag=SC->FragBuffer;
2041 register ULONG size=SC->FragSize2;
2042 register union rgba3D Tmp1;
2043 register union rgba3D Tmp2;
2044 #ifdef SLOWCPU
2045 register UBYTE *Add8=SC->Add8;
2046 register union oper3D Add;
2048 Add.L.Index=0;
2049 #endif
2050 SREM(PixelsOne_One24)
2051 while(0<size--)
2053 ULONG *_dst1 = (ULONG *)DST1;
2054 ULONG *_dst2 = (ULONG *)DST2;
2055 Tmp1.L.RGBA32=*_dst1;
2056 Tmp2.L.RGBA32=*_dst2;
2058 ADD8(SRC1R,Tmp1.B.RGBA[0],Tmp1.B.RGBA[0])
2059 ADD8(SRC1G,Tmp1.B.RGBA[1],Tmp1.B.RGBA[1])
2060 ADD8(SRC1B,Tmp1.B.RGBA[2],Tmp1.B.RGBA[2])
2062 ADD8(SRC2R,Tmp2.B.RGBA[0],Tmp2.B.RGBA[0])
2063 ADD8(SRC2G,Tmp2.B.RGBA[1],Tmp2.B.RGBA[1])
2064 ADD8(SRC2B,Tmp2.B.RGBA[2],Tmp2.B.RGBA[2])
2066 *_dst1=Tmp1.L.RGBA32;
2067 *_dst2=Tmp2.L.RGBA32;
2068 Frag+=2;
2071 /*=============================================================*/
2072 void PixelsZero_SrcAlpha32(struct SOFT3D_context *SC)
2074 /* v41: alpha-modulate dst (allways) */
2075 register struct fragbuffer3D *Frag=SC->FragBuffer;
2076 register ULONG size=SC->FragSize2;
2077 #ifdef SLOWCPU
2078 register UBYTE *Mul8=SC->Mul8;
2079 register union oper3D Mul;
2081 Mul.L.Index=0;
2082 #endif
2084 SREM(PixelsZero_SrcAlpha32)
2085 while(0<size--)
2087 MUL8(SRC1A,DST1R,DST1R)
2088 MUL8(SRC1A,DST1G,DST1G)
2089 MUL8(SRC1A,DST1B,DST1B)
2091 MUL8(SRC2A,DST2R,DST2R)
2092 MUL8(SRC2A,DST2G,DST2G)
2093 MUL8(SRC2A,DST2B,DST2B)
2094 Frag+=2;
2097 /*=============================================================*/
2098 void PixelsZero_SrcColor24(struct SOFT3D_context *SC)
2100 /* v45: color-modulate dst (allways) */
2101 register struct fragbuffer3D *Frag=SC->FragBuffer;
2102 register ULONG size=SC->FragSize2;
2103 #ifdef SLOWCPU
2104 register UBYTE *Mul8=SC->Mul8;
2105 register union oper3D Mul;
2107 Mul.L.Index=0;
2108 #endif
2110 SREM(PixelsZero_SrcColor24)
2111 while(0<size--)
2113 MUL8(SRC1R,DST1R,DST1R)
2114 MUL8(SRC1G,DST1G,DST1G)
2115 MUL8(SRC1B,DST1B,DST1B)
2117 MUL8(SRC2R,DST2R,DST2R)
2118 MUL8(SRC2G,DST2G,DST2G)
2119 MUL8(SRC2B,DST2B,DST2B)
2120 Frag+=2;
2123 /*=============================================================*/
2124 void PixelsZero_OneMinusSrcColor24(struct SOFT3D_context *SC)
2126 /* v45: for glxcess :-) */
2127 register struct fragbuffer3D *Frag=SC->FragBuffer;
2128 register ULONG size=SC->FragSize2;
2129 #ifdef SLOWCPU
2130 register UBYTE *Mul8=SC->Mul8;
2131 register union oper3D Mul;
2133 Mul.L.Index=0;
2134 #endif
2136 SREM(PixelsZero_OneMinusSrcColor24)
2137 while(0<size--)
2139 MUL8(ONE-SRC1R,DST1R,DST1R)
2140 MUL8(ONE-SRC1G,DST1G,DST1G)
2141 MUL8(ONE-SRC1B,DST1B,DST1B)
2143 MUL8(ONE-SRC2R,DST2R,DST2R)
2144 MUL8(ONE-SRC2G,DST2G,DST2G)
2145 MUL8(ONE-SRC2B,DST2B,DST2B)
2146 Frag+=2;
2149 /*=============================================================*/
2150 void PixelsSrcAlpha_OneMinusSrcColor32(struct SOFT3D_context *SC)
2152 /* v45: for glxcess :-) */
2153 register struct fragbuffer3D *Frag=SC->FragBuffer;
2154 register ULONG size=SC->FragSize2;
2155 #ifdef SLOWCPU
2156 register UBYTE *Mul8=SC->Mul8;
2157 register union oper3D Mul;
2158 register union oper3D Mul2;
2160 Mul.L.Index=Mul2.L.Index=0;
2161 #endif
2163 SREM(PixelsSrcAlpha_OneMinusSrcColor32)
2164 while(0<size--)
2166 FULLADDMUL8(SRC1R,SRC1A,DST1R,ONE-SRC1R,DST1R)
2167 FULLADDMUL8(SRC1G,SRC1A,DST1G,ONE-SRC1G,DST1G)
2168 FULLADDMUL8(SRC1B,SRC1A,DST1B,ONE-SRC1B,DST1B)
2170 FULLADDMUL8(SRC2R,SRC2A,DST2R,ONE-SRC2R,DST2R)
2171 FULLADDMUL8(SRC2G,SRC2A,DST2G,ONE-SRC2G,DST2G)
2172 FULLADDMUL8(SRC2B,SRC2A,DST2B,ONE-SRC2B,DST2B)
2173 Frag+=2;
2176 /*=============================================================*/
2177 void PixelsDstColor_Zero24(struct SOFT3D_context *SC)
2179 SREM(PixelsDstColor_Zero24)
2180 PixelsZero_SrcColor24(SC);
2182 /*=============================================================*/
2183 void PixelsBlendFunctionAll(struct SOFT3D_context *SC)
2185 register struct fragbuffer3D *Frag=SC->FragBuffer;
2186 register ULONG size;
2187 register UBYTE dst;
2188 UBYTE ZeroRGBA[]={0,0,0,0};
2189 #define MIN(a, b) (((a) < (b)) ? (a) : (b))
2190 UBYTE i;
2192 #ifdef SLOWCPU
2193 register UBYTE *Mul8=SC->Mul8;
2194 register UBYTE *Add8=SC->Add8;
2195 register union oper3D Add;
2196 register union oper3D Mul;
2198 Mul.L.Index=Add.L.Index=0;
2199 #endif
2201 SREM(PixelsBlendFunctionAll)
2202 if(SC->FunctionBlendFast==NULL)
2203 if(Wazp3D->DebugBlendFunction.ON)
2205 PrintST(SC->state.ST);
2206 Libprintf("use slow BlendFunction(Src:%ld,Dst%ld)\n",(ULONG)SC->SrcFunc,(ULONG)SC->DstFunc);
2210 /* store Image to Buffer ? */
2211 if(SC->ImageBuffer32!=NULL)
2213 size=SC->FragSize2;
2214 Frag=SC->FragBuffer;
2215 while(0<size--)
2217 COPYRGBA(Frag[0].BufferRGBA,Frag[0].Image8);
2218 COPYRGBA(Frag[1].BufferRGBA,Frag[1].Image8);
2219 Frag+=2;
2223 if(SC->FunctionBlendFast!=NULL)
2225 SC->FunctionBlendFast(SC);
2226 goto BlendDone;
2229 size=SC->FragSize2;
2230 Frag=SC->FragBuffer;
2232 /* Step1: do Src Function to TmpRGBA */
2233 switch(SC->SrcFunc)
2236 case W3D_ZERO:
2237 while(0<size--)
2239 COPYRGBA(Frag[0].TmpRGBA,ZeroRGBA);
2240 COPYRGBA(Frag[1].TmpRGBA,ZeroRGBA);
2241 Frag+=2;
2243 break;
2245 case W3D_ONE:
2246 while(0<size--)
2248 COPYRGBA(Frag[0].TmpRGBA,SRC1); /* ONE x SRC1 = SRC1 */
2249 COPYRGBA(Frag[1].TmpRGBA,SRC2);
2250 Frag+=2;
2252 break;
2254 case W3D_DST_COLOR:
2255 while(0<size--)
2257 SRCFUNC1(DST1R,DST1G,DST1B,DST1A)
2258 SRCFUNC2(DST2R,DST2G,DST2B,DST2A)
2259 Frag+=2;
2261 break;
2263 case W3D_ONE_MINUS_DST_COLOR:
2264 while(0<size--)
2266 SRCFUNC1(ONE-DST1R,ONE-DST1G,ONE-DST1B,ONE-DST1A)
2267 SRCFUNC2(ONE-DST2R,ONE-DST2G,ONE-DST2B,ONE-DST2A)
2268 Frag+=2;
2270 break;
2272 case W3D_SRC_ALPHA:
2273 while(0<size--)
2275 SRCFUNC1(SRC1A,SRC1A,SRC1A,SRC1A)
2276 SRCFUNC2(SRC2A,SRC2A,SRC2A,SRC2A)
2277 Frag+=2;
2279 break;
2281 case W3D_ONE_MINUS_SRC_ALPHA:
2282 while(0<size--)
2284 SRCFUNC1(ONE-SRC1A,ONE-SRC1A,ONE-SRC1A,ONE-SRC1A)
2285 SRCFUNC2(ONE-SRC2A,ONE-SRC2A,ONE-SRC2A,ONE-SRC2A)
2286 Frag+=2;
2288 break;
2290 case W3D_DST_ALPHA:
2291 while(0<size--)
2293 SRCFUNC1(DST1A,DST1A,DST1A,DST1A)
2294 SRCFUNC2(DST2A,DST2A,DST2A,DST2A)
2295 Frag+=2;
2297 break;
2299 case W3D_ONE_MINUS_DST_ALPHA:
2300 while(0<size--)
2302 SRCFUNC1(ONE-DST1A,ONE-DST1A,ONE-DST1A,ONE-DST1A)
2303 SRCFUNC2(ONE-DST2A,ONE-DST2A,ONE-DST2A,ONE-DST2A)
2304 Frag+=2;
2306 break;
2308 case W3D_CONSTANT_COLOR:
2309 while(0<size--)
2311 SRCFUNC1(CONSTR,CONSTG,CONSTB,CONSTA)
2312 SRCFUNC2(CONSTR,CONSTG,CONSTB,CONSTA)
2313 Frag+=2;
2315 break;
2317 case W3D_ONE_MINUS_CONSTANT_COLOR:
2318 while(0<size--)
2320 SRCFUNC1(ONE-CONSTR,ONE-CONSTG,ONE-CONSTB,ONE-CONSTA)
2321 SRCFUNC2(ONE-CONSTR,ONE-CONSTG,ONE-CONSTB,ONE-CONSTA)
2322 Frag+=2;
2324 break;
2326 case W3D_CONSTANT_ALPHA:
2327 while(0<size--)
2329 SRCFUNC1(CONSTA,CONSTA,CONSTA,CONSTA)
2330 SRCFUNC2(CONSTA,CONSTA,CONSTA,CONSTA)
2331 Frag+=2;
2333 break;
2335 case W3D_ONE_MINUS_CONSTANT_ALPHA:
2336 while(0<size--)
2338 SRCFUNC1(ONE-CONSTA,ONE-CONSTA,ONE-CONSTA,ONE-CONSTA)
2339 SRCFUNC2(ONE-CONSTA,ONE-CONSTA,ONE-CONSTA,ONE-CONSTA)
2340 Frag+=2;
2342 break;
2344 case W3D_SRC_ALPHA_SATURATE:
2345 while(0<size--)
2347 i = MIN (SRC1A,ONE - DST1A) ; /* v47: OpenGL compliant */
2348 SRCFUNC1(i,i,i,i)
2349 i = MIN (SRC2A,ONE - DST2A) ;
2350 SRCFUNC2(i,i,i,i)
2351 Frag+=2;
2353 break;
2356 /* Step2: do Dst Function from TmpRGBA */
2357 size=SC->FragSize2;
2358 Frag=SC->FragBuffer;
2360 switch(SC->DstFunc)
2362 case W3D_ZERO:
2363 while(0<size--)
2365 COPYRGBA(Frag[0].BufferRGBA,Frag[0].TmpRGBA);
2366 COPYRGBA(Frag[1].BufferRGBA,Frag[1].TmpRGBA);
2367 Frag+=2;
2369 break;
2371 case W3D_ONE:
2372 while(0<size--)
2374 ADD8(TMP1R,DST1R,DST1R) ADD8(TMP1G,DST1G,DST1G) ADD8(TMP1B,DST1B,DST1B) ADD8(TMP1A,DST1A,DST1A)
2375 ADD8(TMP2R,DST2R,DST2R) ADD8(TMP2G,DST2G,DST2G) ADD8(TMP2B,DST2B,DST2B) ADD8(TMP2A,DST2A,DST2A)
2376 Frag+=2;
2378 break;
2380 case W3D_SRC_COLOR:
2381 while(0<size--)
2383 DSTFUNC1(SRC1R,SRC1G,SRC1B,SRC1A)
2384 DSTFUNC2(SRC2R,SRC2G,SRC2B,SRC2A)
2385 Frag+=2;
2387 break;
2389 case W3D_ONE_MINUS_SRC_COLOR:
2390 while(0<size--)
2392 DSTFUNC1(ONE-SRC1R,ONE-SRC1G,ONE-SRC1B,ONE-SRC1A)
2393 DSTFUNC2(ONE-SRC2R,ONE-SRC2G,ONE-SRC2B,ONE-SRC2A)
2394 Frag+=2;
2396 break;
2398 case W3D_DST_ALPHA:
2399 while(0<size--)
2401 DSTFUNC1(DST1A,DST1A,DST1A,DST1A)
2402 DSTFUNC2(DST2A,DST2A,DST2A,DST2A)
2403 Frag+=2;
2405 break;
2407 case W3D_ONE_MINUS_DST_ALPHA:
2408 while(0<size--)
2410 DSTFUNC1(ONE-DST1A,ONE-DST1A,ONE-DST1A,ONE-DST1A)
2411 DSTFUNC2(ONE-DST2A,ONE-DST2A,ONE-DST2A,ONE-DST2A)
2412 Frag+=2;
2414 break;
2416 case W3D_SRC_ALPHA:
2417 while(0<size--)
2419 DSTFUNC1(SRC1A,SRC1A,SRC1A,SRC1A)
2420 DSTFUNC2(SRC2A,SRC2A,SRC2A,SRC2A)
2421 Frag+=2;
2423 break;
2425 case W3D_ONE_MINUS_SRC_ALPHA:
2426 while(0<size--)
2428 DSTFUNC1(ONE-SRC1A,ONE-SRC1A,ONE-SRC1A,ONE-SRC1A)
2429 DSTFUNC2(ONE-SRC2A,ONE-SRC2A,ONE-SRC2A,ONE-SRC2A)
2430 Frag+=2;
2432 break;
2434 case W3D_CONSTANT_COLOR:
2435 while(0<size--)
2437 DSTFUNC1(CONSTR,CONSTG,CONSTB,CONSTA)
2438 DSTFUNC2(CONSTR,CONSTG,CONSTB,CONSTA)
2439 Frag+=2;
2441 break;
2443 case W3D_ONE_MINUS_CONSTANT_COLOR:
2444 while(0<size--)
2446 DSTFUNC1(ONE-CONSTR,ONE-CONSTG,ONE-CONSTB,ONE-CONSTA)
2447 DSTFUNC2(ONE-CONSTR,ONE-CONSTG,ONE-CONSTB,ONE-CONSTA)
2448 Frag+=2;
2450 break;
2452 case W3D_CONSTANT_ALPHA:
2453 while(0<size--)
2455 DSTFUNC1(CONSTA,CONSTA,CONSTA,CONSTA)
2456 DSTFUNC2(CONSTA,CONSTA,CONSTA,CONSTA)
2457 Frag+=2;
2459 break;
2461 case W3D_ONE_MINUS_CONSTANT_ALPHA:
2462 while(0<size--)
2464 DSTFUNC1(ONE-CONSTA,ONE-CONSTA,ONE-CONSTA,ONE-CONSTA)
2465 DSTFUNC2(ONE-CONSTA,ONE-CONSTA,ONE-CONSTA,ONE-CONSTA)
2466 Frag+=2;
2468 break;
2472 BlendDone:
2473 /* store the buffer to image8 ? */
2474 if(SC->ImageBuffer32!=NULL)
2476 size=SC->FragSize2;
2477 Frag=SC->FragBuffer;
2478 while(0<size--)
2480 COPYRGBA(Frag[0].Image8,Frag[0].BufferRGBA );
2481 COPYRGBA(Frag[1].Image8,Frag[1].BufferRGBA );
2482 Frag+=2;
2487 /*=============================================================*/
2488 /* v52: Optimized 32 bits PixelsIn/Out */
2489 /*=============================================================*/
2491 static inline void SetCOLOR32(APTR dst, ULONG color)
2493 ULONG *_dst = (ULONG *)dst;
2494 *_dst = color;
2497 static inline ULONG COLOR32(APTR src)
2499 ULONG *_src = (ULONG *)src;
2500 return *_src;
2503 /*=============================================================*/
2504 void PixelsInBGRA(struct SOFT3D_context *SC)
2506 /* Convert BGRA -> buffer */
2507 register struct fragbuffer3D *Frag=SC->FragBuffer;
2508 register ULONG size=SC->FragSize2;
2509 register union rgba3D Color0;
2510 register union rgba3D Color1;
2511 register UBYTE temp;
2513 while(0<size--)
2515 Color0.L.RGBA32=COLOR32(Frag[0].Image8);
2516 Color1.L.RGBA32=COLOR32(Frag[1].Image8);
2518 SWAP(Color0.B.RGBA[0],Color0.B.RGBA[2]);
2519 SWAP(Color1.B.RGBA[0],Color1.B.RGBA[2]);
2521 SetCOLOR32(Frag[0].BufferRGBA, Color0.L.RGBA32);
2522 SetCOLOR32(Frag[1].BufferRGBA, Color1.L.RGBA32);
2523 Frag+=2;
2526 /*=============================================================*/
2527 void PixelsInARGB(struct SOFT3D_context *SC)
2529 /* Convert ARGB -> buffer */
2530 register struct fragbuffer3D *Frag=SC->FragBuffer;
2531 register ULONG size=SC->FragSize2;
2532 register union rgba3D Color0;
2533 register union rgba3D Color1;
2535 while(0<size--)
2537 Color0.L.RGBA32=COLOR32(Frag[0].Image8);
2538 Color1.L.RGBA32=COLOR32(Frag[1].Image8);
2540 Color0.L.RGBA32=(Color0.B.RGBA[0]+(Color0.L.RGBA32<<8));
2541 Color1.L.RGBA32=(Color1.B.RGBA[0]+(Color1.L.RGBA32<<8));
2543 SetCOLOR32(Frag[0].BufferRGBA, Color0.L.RGBA32);
2544 SetCOLOR32(Frag[1].BufferRGBA, Color1.L.RGBA32);
2545 Frag+=2;
2548 /*=============================================================*/
2549 void PixelsInABGR(struct SOFT3D_context *SC)
2551 /* Convert ABGR -> buffer */
2552 register struct fragbuffer3D *Frag=SC->FragBuffer;
2553 register ULONG size=SC->FragSize2;
2554 register union rgba3D Color0;
2555 register union rgba3D Color1;
2556 register UBYTE temp;
2558 while(0<size--)
2560 Color0.L.RGBA32=COLOR32(Frag[0].Image8);
2561 Color1.L.RGBA32=COLOR32(Frag[1].Image8);
2563 SWAP(Color0.B.RGBA[0],Color0.B.RGBA[3]);
2564 SWAP(Color0.B.RGBA[1],Color0.B.RGBA[2]);
2566 SWAP(Color1.B.RGBA[0],Color1.B.RGBA[3]);
2567 SWAP(Color1.B.RGBA[1],Color1.B.RGBA[2]);
2569 SetCOLOR32(Frag[0].BufferRGBA, Color0.L.RGBA32);
2570 SetCOLOR32(Frag[1].BufferRGBA, Color1.L.RGBA32);
2571 Frag+=2;
2574 /*=============================================================*/
2575 /*=============================================================*/
2576 void PixelsOutBGRA_Flat(struct SOFT3D_context *SC)
2578 /* Convert BGRA <- buffer */
2579 register struct fragbuffer3D *Frag=SC->FragBuffer;
2580 register ULONG size4=SC->FragSize2/2;
2581 register union rgba3D Color0;
2582 register UBYTE temp;
2584 Color0.L.RGBA32=COLOR32(Frag[0].BufferRGBA);
2585 SWAP(Color0.B.RGBA[0],Color0.B.RGBA[2]);
2587 while(0<size4--)
2589 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2590 SetCOLOR32(Frag[1].Image8, Color0.L.RGBA32);
2591 SetCOLOR32(Frag[2].Image8, Color0.L.RGBA32);
2592 SetCOLOR32(Frag[3].Image8, Color0.L.RGBA32);
2593 Frag+=4;
2596 /*=============================================================*/
2597 void PixelsOutARGB_Flat(struct SOFT3D_context *SC)
2599 /* Convert ARGB <- buffer */
2600 register struct fragbuffer3D *Frag=SC->FragBuffer;
2601 register ULONG size4=SC->FragSize2/2;
2602 register union rgba3D Color0;
2604 Color0.L.RGBA32=COLOR32(Frag[0].BufferRGBA);
2605 Color0.L.RGBA32=((Color0.B.RGBA[3]<<24)+(Color0.L.RGBA32>>8));
2607 while(0<size4--)
2609 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2610 SetCOLOR32(Frag[1].Image8, Color0.L.RGBA32);
2611 SetCOLOR32(Frag[2].Image8, Color0.L.RGBA32);
2612 SetCOLOR32(Frag[3].Image8, Color0.L.RGBA32);
2613 Frag+=4;
2616 /*=============================================================*/
2617 void PixelsOutABGR_Flat(struct SOFT3D_context *SC)
2619 /* Convert ABGR <- buffer */
2620 register struct fragbuffer3D *Frag=SC->FragBuffer;
2621 register ULONG size4=SC->FragSize2/2;
2622 register union rgba3D Color0;
2623 register UBYTE temp;
2625 Color0.L.RGBA32=COLOR32(Frag[0].BufferRGBA);
2626 SWAP(Color0.B.RGBA[0],Color0.B.RGBA[3]);
2627 SWAP(Color0.B.RGBA[1],Color0.B.RGBA[2]);
2629 while(0<size4--)
2631 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2632 SetCOLOR32(Frag[1].Image8, Color0.L.RGBA32);
2633 SetCOLOR32(Frag[2].Image8, Color0.L.RGBA32);
2634 SetCOLOR32(Frag[3].Image8, Color0.L.RGBA32);
2635 Frag+=4;
2638 /*=============================================================*/
2639 void PixelsOutBGRA(struct SOFT3D_context *SC)
2641 /* Convert BGRA <- buffer */
2642 register struct fragbuffer3D *Frag=SC->FragBuffer;
2643 register ULONG size=SC->FragSize2;
2644 register union rgba3D Color0;
2645 register union rgba3D Color1;
2646 register UBYTE temp;
2648 while(0<size--)
2650 Color0.L.RGBA32=COLOR32(Frag[0].BufferRGBA);
2651 Color1.L.RGBA32=COLOR32(Frag[1].BufferRGBA);
2653 SWAP(Color0.B.RGBA[0],Color0.B.RGBA[2]);
2654 SWAP(Color1.B.RGBA[0],Color1.B.RGBA[2]);
2656 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2657 SetCOLOR32(Frag[1].Image8, Color1.L.RGBA32);
2658 Frag+=2;
2661 /*=============================================================*/
2662 void PixelsOutARGB(struct SOFT3D_context *SC)
2664 /* Convert ARGB <- buffer */
2665 register struct fragbuffer3D *Frag=SC->FragBuffer;
2666 register ULONG size=SC->FragSize2;
2667 register union rgba3D Color0;
2668 register union rgba3D Color1;
2670 while(0<size--)
2672 Color0.L.RGBA32=COLOR32(Frag[0].BufferRGBA);
2673 Color1.L.RGBA32=COLOR32(Frag[1].BufferRGBA);
2675 Color0.L.RGBA32=((Color0.B.RGBA[3]<<24)+(Color0.L.RGBA32>>8));
2676 Color1.L.RGBA32=((Color1.B.RGBA[3]<<24)+(Color1.L.RGBA32>>8));
2678 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2679 SetCOLOR32(Frag[1].Image8, Color1.L.RGBA32);
2680 Frag+=2;
2683 /*=============================================================*/
2684 void PixelsOutABGR(struct SOFT3D_context *SC)
2686 /* Convert ABGR <- buffer */
2687 register struct fragbuffer3D *Frag=SC->FragBuffer;
2688 register ULONG size=SC->FragSize2;
2689 register union rgba3D Color0;
2690 register union rgba3D Color1;
2691 register UBYTE temp;
2693 while(0<size--)
2695 Color0.L.RGBA32=COLOR32(Frag[0].BufferRGBA);
2696 Color1.L.RGBA32=COLOR32(Frag[1].BufferRGBA);
2698 SWAP(Color0.B.RGBA[0],Color0.B.RGBA[3]);
2699 SWAP(Color0.B.RGBA[1],Color0.B.RGBA[2]);
2701 SWAP(Color1.B.RGBA[0],Color1.B.RGBA[3]);
2702 SWAP(Color1.B.RGBA[1],Color1.B.RGBA[2]);
2704 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2705 SetCOLOR32(Frag[1].Image8, Color1.L.RGBA32);
2706 Frag+=2;
2709 /*=============================================================*/
2710 void PixelsInRGBA(struct SOFT3D_context *SC)
2712 /* Convert RGBA -> buffer */
2713 register struct fragbuffer3D *Frag=SC->FragBuffer;
2714 register ULONG size4=SC->FragSize2/2;
2716 while(0<size4--)
2718 COPYRGBA(Frag[0].BufferRGBA,Frag[0].Image8);
2719 COPYRGBA(Frag[1].BufferRGBA,Frag[1].Image8);
2720 COPYRGBA(Frag[2].BufferRGBA,Frag[0].Image8);
2721 COPYRGBA(Frag[3].BufferRGBA,Frag[1].Image8);
2722 Frag+=4;
2726 /*=============================================================*/
2727 void PixelsOutRGBA_Flat(struct SOFT3D_context *SC)
2729 /* Convert buffer -> RGBA */
2730 register struct fragbuffer3D *Frag=SC->FragBuffer;
2731 register ULONG size4=SC->FragSize2/2;
2732 register union rgba3D Color0;
2734 Color0.L.RGBA32=COLOR32(Frag[0].BufferRGBA);
2735 while(0<size4--)
2737 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2738 SetCOLOR32(Frag[1].Image8, Color0.L.RGBA32);
2739 SetCOLOR32(Frag[2].Image8, Color0.L.RGBA32);
2740 SetCOLOR32(Frag[3].Image8, Color0.L.RGBA32);
2741 Frag+=4;
2745 /*=============================================================*/
2746 void PixelsOutRGBA(struct SOFT3D_context *SC)
2748 /* Convert buffer -> RGBA */
2749 register struct fragbuffer3D *Frag=SC->FragBuffer;
2750 register ULONG size=SC->FragSize2;
2752 while(0<size--)
2754 COPYRGBA(Frag[0].Image8,Frag[0].BufferRGBA);
2755 COPYRGBA(Frag[1].Image8,Frag[1].BufferRGBA);
2756 Frag+=2;
2760 /*=============================================================*/
2761 void PixelsOutBGRAfromtex24(struct SOFT3D_context *SC)
2763 /* patch suggestion from "Cosmos" : */
2764 /* For a simple prog like CoW3D dont use pipe-line but write tex directly to the BGRA bitmap */
2765 register struct fragbuffer3D *Frag=SC->FragBuffer;
2766 register ULONG size=SC->FragSize2;
2767 register union rgba3D Color0;
2768 register union rgba3D Color1;
2771 Color0.B.RGBA[3]=Color1.B.RGBA[3]=ONE;
2772 while(0<size--)
2774 Color0.B.RGBA[2]=Frag[0].Tex8[0];
2775 Color0.B.RGBA[1]=Frag[0].Tex8[1];
2776 Color0.B.RGBA[0]=Frag[0].Tex8[2];
2778 Color1.B.RGBA[2]=Frag[1].Tex8[0];
2779 Color1.B.RGBA[1]=Frag[1].Tex8[1];
2780 Color1.B.RGBA[0]=Frag[1].Tex8[2];
2782 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2783 SetCOLOR32(Frag[1].Image8, Color1.L.RGBA32);
2784 Frag+=2;
2787 /*=============================================================*/
2788 void PixelsOutARGBfromtex24(struct SOFT3D_context *SC)
2790 /* patch suggestion from "Cosmos" : */
2791 /* For a simple prog like CoW3D dont use pipe-line but write tex directly to the ARGB bitmap */
2792 register struct fragbuffer3D *Frag=SC->FragBuffer;
2793 register ULONG size=SC->FragSize2;
2794 register union rgba3D Color0;
2795 register union rgba3D Color1;
2798 Color0.B.RGBA[0]=Color1.B.RGBA[0]=ONE;
2799 while(0<size--)
2801 Color0.B.RGBA[1]=Frag[0].Tex8[0];
2802 Color0.B.RGBA[2]=Frag[0].Tex8[1];
2803 Color0.B.RGBA[3]=Frag[0].Tex8[2];
2805 Color1.B.RGBA[1]=Frag[1].Tex8[0];
2806 Color1.B.RGBA[2]=Frag[1].Tex8[1];
2807 Color1.B.RGBA[3]=Frag[1].Tex8[2];
2809 SetCOLOR32(Frag[0].Image8, Color0.L.RGBA32);
2810 SetCOLOR32(Frag[1].Image8, Color1.L.RGBA32);
2811 Frag+=2;
2814 /*=============================================================*/
2815 /* End of 32 bits functions */
2816 /*=============================================================*/
2817 void PixelsInRGB(struct SOFT3D_context *SC)
2819 /* Convert RGB -> buffer */
2820 register struct fragbuffer3D *Frag=SC->FragBuffer;
2821 register ULONG size=SC->FragSize2;
2823 while(0<size--)
2825 Frag[0].BufferRGBA[0]=Frag[0].Image8[0];
2826 Frag[0].BufferRGBA[1]=Frag[0].Image8[1];
2827 Frag[0].BufferRGBA[2]=Frag[0].Image8[2];
2828 Frag[0].BufferRGBA[3]=ONE;
2830 Frag[1].BufferRGBA[0]=Frag[1].Image8[0];
2831 Frag[1].BufferRGBA[1]=Frag[1].Image8[1];
2832 Frag[1].BufferRGBA[2]=Frag[1].Image8[2];
2833 Frag[1].BufferRGBA[3]=ONE;
2834 Frag+=2;
2838 /*=============================================================*/
2839 void PixelsOutRGB(struct SOFT3D_context *SC)
2841 /* Convert buffer -> RGB */
2842 register struct fragbuffer3D *Frag=SC->FragBuffer;
2843 register ULONG size=SC->FragSize2;
2845 while(0<size--)
2847 Frag[0].Image8[0]=Frag[0].BufferRGBA[0];
2848 Frag[0].Image8[1]=Frag[0].BufferRGBA[1];
2849 Frag[0].Image8[2]=Frag[0].BufferRGBA[2];
2851 Frag[1].Image8[0]=Frag[1].BufferRGBA[0];
2852 Frag[1].Image8[1]=Frag[1].BufferRGBA[1];
2853 Frag[1].Image8[2]=Frag[1].BufferRGBA[2];
2854 Frag+=2;
2858 /*=============================================================*/
2859 void PixelsInBGR(struct SOFT3D_context *SC)
2861 /* Convert BGR -> buffer */
2862 register struct fragbuffer3D *Frag=SC->FragBuffer;
2863 register ULONG size=SC->FragSize2;
2865 while(0<size--)
2867 Frag[0].BufferRGBA[0]=Frag[0].Image8[2];
2868 Frag[0].BufferRGBA[1]=Frag[0].Image8[1];
2869 Frag[0].BufferRGBA[2]=Frag[0].Image8[0];
2870 Frag[0].BufferRGBA[3]=ONE;
2872 Frag[1].BufferRGBA[0]=Frag[1].Image8[2];
2873 Frag[1].BufferRGBA[1]=Frag[1].Image8[1];
2874 Frag[1].BufferRGBA[2]=Frag[1].Image8[0];
2875 Frag[1].BufferRGBA[3]=ONE;
2876 Frag+=2;
2880 /*=============================================================*/
2881 void PixelsOutBGR(struct SOFT3D_context *SC)
2883 /* Convert buffer -> BGR */
2884 register struct fragbuffer3D *Frag=SC->FragBuffer;
2885 register ULONG size=SC->FragSize2;
2887 while(0<size--)
2889 Frag[0].Image8[0]=Frag[0].BufferRGBA[2];
2890 Frag[0].Image8[1]=Frag[0].BufferRGBA[1];
2891 Frag[0].Image8[2]=Frag[0].BufferRGBA[0];
2893 Frag[1].Image8[0]=Frag[1].BufferRGBA[2];
2894 Frag[1].Image8[1]=Frag[1].BufferRGBA[1];
2895 Frag[1].Image8[2]=Frag[1].BufferRGBA[0];
2896 Frag+=2;
2900 /*=============================================================*/
2901 void SelectMipMap(struct SOFT3D_context *SC)
2903 struct SOFT3D_texture *ST=SC->state.ST;
2904 LONG dmin;
2905 UBYTE mm;
2907 if(ST==NULL) return;
2908 SC->MM=&ST->MMs[0];
2910 if(!Wazp3D->DoMipMaps.ON) return;
2912 SREM(SelectMipMap)
2913 dmin=SC->dmin>>(16-3); /* rescale dmin to [0 to 2048] */
2915 mm=0; /* default: use biggest mipmap = more precision*/
2916 if(dmin>=2048) mm=11; /* Example we skip 3000 texels for each pixel ==> use a 1x1 texels mipmap[11] not the 2048x2048 original */
2917 if(dmin>=1024) mm=10;
2918 if(dmin>=512) mm=9;
2919 if(dmin>=256) mm=8;
2920 if(dmin>=128) mm=7;
2921 if(dmin>=64) mm=6;
2922 if(dmin>=32) mm=5;
2923 if(dmin>=16) mm=4;
2924 if(dmin>=8) mm=3;
2925 if(dmin>=4) mm=2;
2926 if(dmin>=2) mm=1;
2927 if(dmin>=1) mm=0; /* we skip 1 texel for each pixel ==> need the more precise(biggest) mipmap */
2929 SVAR(dmin)
2930 SVAR(mm)
2931 SC->MM=&ST->MMs[mm];
2933 /*=============================================================*/
2934 void Fill_BigTexPersp2_Gouraud_Fog(struct SOFT3D_context *SC)
2936 register UBYTE *Image8;
2937 register UBYTE *Ztest;
2938 register union pixel3D *Pix=SC->Pix;
2939 register struct SOFT3D_mipmap *MM=SC->MM;
2940 register struct fragbuffer3D *Frag=SC->FragBufferDone;
2941 register WORD high =SC->PolyHigh;
2942 register WORD large;
2944 SREM(Fill_BigTexPersp2_Gouraud_Fog)
2946 while(0<high--)
2948 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
2949 large = Pix->W.large;
2951 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
2952 while(0<large--)
2954 if(*Ztest++)
2956 Frag->Image8=Image8;
2957 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
2958 Frag->Tex8+=MM->Tex8Ulow[Pix->W.u3]+MM->Tex8Vlow[Pix->W.v3];
2959 Frag->ColorRGBA[0]=Pix->W.R;
2960 Frag->ColorRGBA[1]=Pix->W.G;
2961 Frag->ColorRGBA[2]=Pix->W.B;
2962 Frag->ColorRGBA[3]=Pix->W.A;
2963 COPYRGBA(Frag->FogRGBA,(&SC->FogRGBAs[Pix->W.F]));
2964 Frag++;
2966 Image8=Image8+Pix->L.bpp;
2967 Pix->L.u +=Pix->L.du;
2968 Pix->L.v +=Pix->L.dv;
2969 Pix->L.du+=Pix->L.ddu;
2970 Pix->L.dv+=Pix->L.ddv;
2971 Pix->L.R +=Pix->L.dR;
2972 Pix->L.G +=Pix->L.dG;
2973 Pix->L.B +=Pix->L.dB;
2974 Pix->L.A +=Pix->L.dA;
2975 Pix->L.F +=Pix->L.dF;
2978 if(Frag > SC->FragBufferMaxi)
2979 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
2980 Pix++;
2982 SC->FragBufferDone=Frag;
2984 /*=============================================================*/
2985 void Fill_BigTexPersp2(struct SOFT3D_context *SC)
2987 register UBYTE *Image8;
2988 register UBYTE *Ztest;
2989 register union pixel3D *Pix=SC->Pix;
2990 register struct SOFT3D_mipmap *MM=SC->MM;
2991 register struct fragbuffer3D *Frag=SC->FragBufferDone;
2992 register WORD high =SC->PolyHigh;
2993 register WORD large;
2995 SREM(Fill_BigTexPersp2)
2997 while(0<high--)
2999 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3000 large = Pix->W.large;
3002 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3003 while(0<large--)
3005 if(*Ztest++)
3007 Frag->Image8=Image8;
3008 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3009 Frag->Tex8+=MM->Tex8Ulow[Pix->W.u3]+MM->Tex8Vlow[Pix->W.v3];
3010 COPYRGBA(Frag->ColorRGBA,SC->FlatRGBA);
3011 Frag++;
3013 Image8=Image8+Pix->L.bpp;
3014 Pix->L.u +=Pix->L.du;
3015 Pix->L.v +=Pix->L.dv;
3016 Pix->L.du+=Pix->L.ddu;
3017 Pix->L.dv+=Pix->L.ddv;
3021 if(Frag > SC->FragBufferMaxi)
3022 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3023 Pix++;
3025 SC->FragBufferDone=Frag;
3027 /*=============================================================*/
3028 void Fill_TexPersp2_Gouraud_Fog(struct SOFT3D_context *SC)
3030 register UBYTE *Image8;
3031 register UBYTE *Ztest;
3032 register union pixel3D *Pix=SC->Pix;
3033 register struct SOFT3D_mipmap *MM=SC->MM;
3034 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3035 register WORD high =SC->PolyHigh;
3036 register WORD large;
3038 SREM(Fill_TexPersp2_Gouraud_Fog)
3040 while(0<high--)
3042 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3043 large = Pix->W.large;
3045 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3046 while(0<large--)
3048 if(*Ztest++)
3050 Frag->Image8=Image8;
3051 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3052 Frag->ColorRGBA[0]=Pix->W.R;
3053 Frag->ColorRGBA[1]=Pix->W.G;
3054 Frag->ColorRGBA[2]=Pix->W.B;
3055 Frag->ColorRGBA[3]=Pix->W.A;
3056 COPYRGBA(Frag->FogRGBA,(&SC->FogRGBAs[Pix->W.F]));
3057 Frag++;
3059 Image8=Image8+Pix->L.bpp;
3060 Pix->L.u +=Pix->L.du;
3061 Pix->L.v +=Pix->L.dv;
3062 Pix->L.du+=Pix->L.ddu;
3063 Pix->L.dv+=Pix->L.ddv;
3064 Pix->L.R +=Pix->L.dR;
3065 Pix->L.G +=Pix->L.dG;
3066 Pix->L.B +=Pix->L.dB;
3067 Pix->L.A +=Pix->L.dA;
3068 Pix->L.F +=Pix->L.dF;
3071 if(Frag > SC->FragBufferMaxi)
3072 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3073 Pix++;
3075 SC->FragBufferDone=Frag;
3077 /*=============================================================*/
3078 void Fill_Tex_Gouraud_Fog(struct SOFT3D_context *SC)
3080 register UBYTE *Image8;
3081 register UBYTE *Ztest;
3082 register union pixel3D *Pix=SC->Pix;
3083 register struct SOFT3D_mipmap *MM=SC->MM;
3084 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3085 register WORD high =SC->PolyHigh;
3086 register WORD large;
3088 if(SC->state.PerspMode==2)
3089 {Fill_TexPersp2_Gouraud_Fog(SC); return;}
3090 SREM(Fill_Tex_Gouraud_Fog)
3092 while(0<high--)
3094 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3095 large = Pix->W.large;
3097 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3098 while(0<large--)
3100 if(*Ztest++)
3102 Frag->Image8=Image8;
3103 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3104 Frag->ColorRGBA[0]=Pix->W.R;
3105 Frag->ColorRGBA[1]=Pix->W.G;
3106 Frag->ColorRGBA[2]=Pix->W.B;
3107 Frag->ColorRGBA[3]=Pix->W.A;
3108 COPYRGBA(Frag->FogRGBA,(&SC->FogRGBAs[Pix->W.F]));
3109 Frag++;
3111 Image8=Image8+Pix->L.bpp;
3112 Pix->L.u +=Pix->L.du;
3113 Pix->L.v +=Pix->L.dv;
3114 Pix->L.R +=Pix->L.dR;
3115 Pix->L.G +=Pix->L.dG;
3116 Pix->L.B +=Pix->L.dB;
3117 Pix->L.A +=Pix->L.dA;
3118 Pix->L.F +=Pix->L.dF;
3121 if(Frag > SC->FragBufferMaxi)
3122 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3123 Pix++;
3125 SC->FragBufferDone=Frag;
3127 /*=============================================================*/
3128 void Fill_Gouraud_Fog(struct SOFT3D_context *SC)
3130 register UBYTE *Image8;
3131 register UBYTE *Ztest;
3132 register union pixel3D *Pix=SC->Pix;
3133 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3134 register WORD high =SC->PolyHigh;
3135 register WORD large;
3137 SREM(Fill_Gouraud_Fog)
3139 while(0<high--)
3141 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3142 large = Pix->W.large;
3144 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3145 while(0<large--)
3147 if(*Ztest++)
3149 Frag->Image8=Image8;
3150 Frag->ColorRGBA[0]=Pix->W.R;
3151 Frag->ColorRGBA[1]=Pix->W.G;
3152 Frag->ColorRGBA[2]=Pix->W.B;
3153 Frag->ColorRGBA[3]=Pix->W.A;
3154 COPYRGBA(Frag->FogRGBA,(&SC->FogRGBAs[Pix->W.F]));
3155 Frag++;
3157 Image8=Image8+Pix->L.bpp;
3158 Pix->L.R +=Pix->L.dR;
3159 Pix->L.G +=Pix->L.dG;
3160 Pix->L.B +=Pix->L.dB;
3161 Pix->L.A +=Pix->L.dA;
3162 Pix->L.F +=Pix->L.dF;
3165 if(Frag > SC->FragBufferMaxi)
3166 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3167 Pix++;
3169 SC->FragBufferDone=Frag;
3171 /*=============================================================*/
3172 void Fill_Gouraud(struct SOFT3D_context *SC)
3174 register UBYTE *Image8;
3175 register UBYTE *Ztest;
3176 register union pixel3D *Pix=SC->Pix;
3177 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3178 register WORD high =SC->PolyHigh;
3179 register WORD large;
3181 SREM(Fill_Gouraud)
3183 while(0<high--)
3185 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3186 large = Pix->W.large;
3188 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3189 while(0<large--)
3191 if(*Ztest++)
3193 Frag->Image8=Image8;
3194 Frag->ColorRGBA[0]=Pix->W.R;
3195 Frag->ColorRGBA[1]=Pix->W.G;
3196 Frag->ColorRGBA[2]=Pix->W.B;
3197 Frag->ColorRGBA[3]=Pix->W.A;
3198 Frag++;
3200 Image8=Image8+Pix->L.bpp;
3201 Pix->L.R +=Pix->L.dR;
3202 Pix->L.G +=Pix->L.dG;
3203 Pix->L.B +=Pix->L.dB;
3204 Pix->L.A +=Pix->L.dA;
3207 if(Frag > SC->FragBufferMaxi)
3208 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3209 Pix++;
3211 SC->FragBufferDone=Frag;
3213 /*=============================================================*/
3214 void Fill_Fog(struct SOFT3D_context *SC)
3216 register UBYTE *Image8;
3217 register UBYTE *Ztest;
3218 register union pixel3D *Pix=SC->Pix;
3219 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3220 register WORD high =SC->PolyHigh;
3221 register WORD large;
3223 SREM(Fill_Fog)
3225 while(0<high--)
3227 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3228 large = Pix->W.large;
3230 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3231 while(0<large--)
3233 if(*Ztest++)
3235 Frag->Image8=Image8;
3236 COPYRGBA(Frag->ColorRGBA,SC->FlatRGBA);
3237 COPYRGBA(Frag->FogRGBA,(&SC->FogRGBAs[Pix->W.F]));
3238 Frag++;
3240 Image8=Image8+Pix->L.bpp;
3241 Pix->L.F +=Pix->L.dF;
3244 if(Frag > SC->FragBufferMaxi)
3245 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3246 Pix++;
3248 SC->FragBufferDone=Frag;
3250 /*=============================================================*/
3251 void Fill_TexPersp2_Gouraud(struct SOFT3D_context *SC)
3253 register UBYTE *Image8;
3254 register UBYTE *Ztest;
3255 register union pixel3D *Pix=SC->Pix;
3256 register struct SOFT3D_mipmap *MM=SC->MM;
3257 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3258 register WORD high =SC->PolyHigh;
3259 register WORD large;
3261 SREM(Fill_TexPersp2_Gouraud)
3263 while(0<high--)
3265 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3266 large = Pix->W.large;
3268 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3269 while(0<large--)
3271 if(*Ztest++)
3273 Frag->Image8=Image8;
3274 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3275 Frag->ColorRGBA[0]=Pix->W.R;
3276 Frag->ColorRGBA[1]=Pix->W.G;
3277 Frag->ColorRGBA[2]=Pix->W.B;
3278 Frag->ColorRGBA[3]=Pix->W.A;
3279 Frag++;
3281 Image8=Image8+Pix->L.bpp;
3282 Pix->L.u +=Pix->L.du;
3283 Pix->L.v +=Pix->L.dv;
3284 Pix->L.du+=Pix->L.ddu;
3285 Pix->L.dv+=Pix->L.ddv;
3286 Pix->L.R +=Pix->L.dR;
3287 Pix->L.G +=Pix->L.dG;
3288 Pix->L.B +=Pix->L.dB;
3289 Pix->L.A +=Pix->L.dA;
3292 if(Frag > SC->FragBufferMaxi)
3293 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3294 Pix++;
3296 SC->FragBufferDone=Frag;
3298 /*=============================================================*/
3299 void Fill_Tex_Gouraud(struct SOFT3D_context *SC)
3301 register UBYTE *Image8;
3302 register UBYTE *Ztest;
3303 register union pixel3D *Pix=SC->Pix;
3304 register struct SOFT3D_mipmap *MM=SC->MM;
3305 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3306 register WORD high =SC->PolyHigh;
3307 register WORD large;
3309 if(SC->state.PerspMode==2)
3310 {Fill_TexPersp2_Gouraud(SC); return;}
3311 SREM(Fill_Tex_Gouraud)
3313 while(0<high--)
3315 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3316 large = Pix->W.large;
3318 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3319 while(0<large--)
3321 if(*Ztest++)
3323 Frag->Image8=Image8;
3324 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3325 Frag->ColorRGBA[0]=Pix->W.R;
3326 Frag->ColorRGBA[1]=Pix->W.G;
3327 Frag->ColorRGBA[2]=Pix->W.B;
3328 Frag->ColorRGBA[3]=Pix->W.A;
3329 Frag++;
3331 Image8=Image8+Pix->L.bpp;
3332 Pix->L.u +=Pix->L.du;
3333 Pix->L.v +=Pix->L.dv;
3334 Pix->L.R +=Pix->L.dR;
3335 Pix->L.G +=Pix->L.dG;
3336 Pix->L.B +=Pix->L.dB;
3337 Pix->L.A +=Pix->L.dA;
3340 if(Frag > SC->FragBufferMaxi)
3341 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3342 Pix++;
3344 SC->FragBufferDone=Frag;
3346 /*=============================================================*/
3347 void Fill_TexPersp2_Fog(struct SOFT3D_context *SC)
3349 register UBYTE *Image8;
3350 register UBYTE *Ztest;
3351 register union pixel3D *Pix=SC->Pix;
3352 register struct SOFT3D_mipmap *MM=SC->MM;
3353 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3354 register WORD high =SC->PolyHigh;
3355 register WORD large;
3356 UBYTE *FogRGBA;
3358 SREM(Fill_TexPersp2_Fog)
3360 while(0<high--)
3362 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3363 large = Pix->W.large;
3365 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3366 while(0<large--)
3368 if(*Ztest++)
3370 Frag->Image8=Image8;
3371 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3372 COPYRGBA(Frag->ColorRGBA,SC->FlatRGBA);
3373 COPYRGBA(Frag->FogRGBA,(&SC->FogRGBAs[Pix->W.F]));
3374 Frag++;
3376 Image8=Image8+Pix->L.bpp;
3377 Pix->L.u +=Pix->L.du;
3378 Pix->L.v +=Pix->L.dv;
3379 Pix->L.du+=Pix->L.ddu;
3380 Pix->L.dv+=Pix->L.ddv;
3381 Pix->L.F +=Pix->L.dF;
3384 if(Frag > SC->FragBufferMaxi)
3385 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3386 Pix++;
3388 SC->FragBufferDone=Frag;
3390 /*=============================================================*/
3391 void Fill_Tex_Fog(struct SOFT3D_context *SC)
3393 register UBYTE *Image8;
3394 register UBYTE *Ztest;
3395 register union pixel3D *Pix=SC->Pix;
3396 register struct SOFT3D_mipmap *MM=SC->MM;
3397 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3398 register WORD high =SC->PolyHigh;
3399 register WORD large;
3401 if(SC->state.PerspMode==2)
3402 {Fill_TexPersp2_Fog(SC); return;}
3403 SREM(Fill_Tex_Fog)
3405 while(0<high--)
3407 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3408 large = Pix->W.large;
3410 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3411 while(0<large--)
3413 if(*Ztest++)
3415 Frag->Image8=Image8;
3416 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3417 COPYRGBA(Frag->ColorRGBA,SC->FlatRGBA);
3418 COPYRGBA(Frag->FogRGBA,(&SC->FogRGBAs[Pix->W.F]));
3419 Frag++;
3421 Image8=Image8+Pix->L.bpp;
3422 Pix->L.u +=Pix->L.du;
3423 Pix->L.v +=Pix->L.dv;
3424 Pix->L.F +=Pix->L.dF;
3427 if(Frag > SC->FragBufferMaxi)
3428 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3429 Pix++;
3431 SC->FragBufferDone=Frag;
3433 /*=============================================================*/
3434 void Fill_TexPersp2(struct SOFT3D_context *SC)
3436 register UBYTE *Image8;
3437 register UBYTE *Ztest;
3438 register union pixel3D *Pix=SC->Pix;
3439 register struct SOFT3D_mipmap *MM=SC->MM;
3440 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3441 register WORD high =SC->PolyHigh;
3442 register WORD large;
3444 SREM(Fill_TexPersp2)
3445 while(0<high--)
3447 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3448 large = Pix->W.large;
3450 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3451 while(0<large--)
3453 if(*Ztest++)
3455 Frag->Image8=Image8;
3456 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3457 COPYRGBA(Frag->ColorRGBA,SC->FlatRGBA);
3458 Frag++;
3460 Image8=Image8+Pix->L.bpp;
3461 Pix->L.u +=Pix->L.du;
3462 Pix->L.v +=Pix->L.dv;
3463 Pix->L.du+=Pix->L.ddu;
3464 Pix->L.dv+=Pix->L.ddv;
3467 if(Frag > SC->FragBufferMaxi)
3468 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3469 Pix++;
3471 SC->FragBufferDone=Frag;
3473 /*=============================================================*/
3474 void Fill_TexMul(struct SOFT3D_context *SC)
3476 register UBYTE *Image8;
3477 register UBYTE *Ztest;
3478 register union pixel3D *Pix=SC->Pix;
3479 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3480 register WORD high =SC->PolyHigh;
3481 register WORD large;
3482 struct SOFT3D_texture *ST=SC->state.ST;
3483 register UBYTE *tex8=ST->pt;
3484 register UWORD texU=ST->bits/8;
3485 register UWORD texV=ST->large*ST->bits/8;
3487 SREM(Fill_TexMul)
3489 while(0<high--)
3491 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3492 large = Pix->W.large;
3494 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3495 while(0<large--)
3497 if(*Ztest++)
3499 Frag->Image8=Image8;
3500 Frag->Tex8 =tex8;
3501 Frag->Tex8 +=Pix->W.u * texU;
3502 Frag->Tex8 +=Pix->W.v * texV;
3503 COPYRGBA(Frag->ColorRGBA,SC->FlatRGBA);
3504 Frag++;
3506 Image8=Image8+Pix->L.bpp;
3507 Pix->L.u +=Pix->L.du;
3508 Pix->L.v +=Pix->L.dv;
3511 if(Frag > SC->FragBufferMaxi)
3512 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3513 Pix++;
3515 SC->FragBufferDone=Frag;
3517 /*=============================================================*/
3518 void Fill_Tex(struct SOFT3D_context *SC)
3520 register UBYTE *Image8;
3521 register UBYTE *Ztest;
3522 register union pixel3D *Pix=SC->Pix;
3523 register struct SOFT3D_mipmap *MM=SC->MM;
3524 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3525 register WORD high =SC->PolyHigh;
3526 register WORD large;
3528 if(SC->state.PerspMode==2)
3529 {Fill_TexPersp2(SC); return;}
3531 if(Wazp3D->DebugDriver.ON) /* Just a way to test that function speed */
3532 {Fill_TexMul(SC); return;}
3534 SREM(Fill_Tex)
3535 while(0<high--)
3537 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3538 large = Pix->W.large;
3540 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3541 while(0<large--)
3543 if(*Ztest++)
3545 Frag->Image8=Image8;
3546 Frag->Tex8 =MM->Tex8U [Pix->W.u ]+MM->Tex8V [Pix->W.v ];
3547 COPYRGBA(Frag->ColorRGBA,SC->FlatRGBA);
3548 Frag++;
3550 Image8=Image8+Pix->L.bpp;
3551 Pix->L.u +=Pix->L.du;
3552 Pix->L.v +=Pix->L.dv;
3555 if(Frag > SC->FragBufferMaxi)
3556 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3557 Pix++;
3559 SC->FragBufferDone=Frag;
3561 /*=============================================================*/
3562 void Fill_Flat(struct SOFT3D_context *SC)
3564 register UBYTE *Image8;
3565 register UBYTE *Ztest;
3566 register union pixel3D *Pix=SC->Pix;
3567 register struct fragbuffer3D *Frag=SC->FragBufferDone;
3568 register WORD high =SC->PolyHigh;
3569 register WORD large;
3571 SREM(Fill_Flat)
3573 while(0<high--)
3575 Image8 = Pix->L.Image8Y + SC->Image8X[Pix->W.x];
3576 large = Pix->W.large;
3578 SC->Pix=Pix; SC->FunctionZtest(SC); Ztest=SC->Ztest;
3579 while(0<large--)
3581 if(*Ztest++)
3583 Frag->Image8=Image8;
3584 COPYRGBA(Frag->ColorRGBA,SC->FlatRGBA);
3585 Frag++;
3587 Image8=Image8+Pix->L.bpp;
3590 if(Frag > SC->FragBufferMaxi)
3591 {SC->FragBufferDone=Frag; SOFT3D_Flush(SC); Frag=SC->FragBuffer;}
3592 Pix++;
3594 SC->FragBufferDone=Frag;
3596 /*=============================================================*/
3597 void Ztest_znever_update(struct SOFT3D_context *SC)
3599 register UBYTE *Ztest=SC->Ztest;
3600 register union pixel3D *Pix=SC->Pix;
3601 register WORD large=Pix->W.large;
3603 while(0<large--)
3604 { *Ztest=(FALSE); Ztest++; }
3606 /*=============================================================*/
3607 void Ztest_zless_update(struct SOFT3D_context *SC)
3609 register UBYTE *Ztest=SC->Ztest;
3610 register union pixel3D *Pix=SC->Pix;
3611 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3612 register ZBUFF dz=Pix->L.dz;
3613 register WORD large=Pix->W.large;
3615 while(0<large--)
3616 { *Ztest=(ZVALUE < *Zbuffer ); if(*Ztest) *Zbuffer=ZVALUE; Ztest++; Zbuffer++; Pix->L.z+=dz;}
3618 /*=============================================================*/
3619 void Ztest_zgequal_update(struct SOFT3D_context *SC)
3621 register UBYTE *Ztest=SC->Ztest;
3622 register union pixel3D *Pix=SC->Pix;
3623 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3624 register ZBUFF dz=Pix->L.dz;
3625 register WORD large=Pix->W.large;
3627 while(0<large--)
3628 { *Ztest=(ZVALUE >= *Zbuffer ); if(*Ztest) *Zbuffer=ZVALUE; Ztest++; Zbuffer++; Pix->L.z+=dz;}
3630 /*=============================================================*/
3631 void Ztest_zlequal_update(struct SOFT3D_context *SC)
3633 register UBYTE *Ztest=SC->Ztest;
3634 register union pixel3D *Pix=SC->Pix;
3635 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3636 register ZBUFF dz=Pix->L.dz;
3637 register WORD large=Pix->W.large;
3639 while(0<large--)
3640 { *Ztest=(ZVALUE <= *Zbuffer ); if(*Ztest) *Zbuffer=ZVALUE; Ztest++; Zbuffer++; Pix->L.z+=dz;}
3642 /*=============================================================*/
3643 void Ztest_zgreater_update(struct SOFT3D_context *SC)
3645 register UBYTE *Ztest=SC->Ztest;
3646 register union pixel3D *Pix=SC->Pix;
3647 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3648 register ZBUFF dz=Pix->L.dz;
3649 register WORD large=Pix->W.large;
3651 while(0<large--)
3652 { *Ztest=(ZVALUE > *Zbuffer ); if(*Ztest) *Zbuffer=ZVALUE; Ztest++; Zbuffer++; Pix->L.z+=dz;}
3654 /*=============================================================*/
3655 void Ztest_znotequal_update(struct SOFT3D_context *SC)
3657 register UBYTE *Ztest=SC->Ztest;
3658 register union pixel3D *Pix=SC->Pix;
3659 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3660 register ZBUFF dz=Pix->L.dz;
3661 register WORD large=Pix->W.large;
3663 while(0<large--)
3664 { *Ztest=(ZVALUE != *Zbuffer ); if(*Ztest) *Zbuffer=ZVALUE; Ztest++; Zbuffer++; Pix->L.z+=dz;}
3666 /*=============================================================*/
3667 void Ztest_zequal_update(struct SOFT3D_context *SC)
3669 register UBYTE *Ztest=SC->Ztest;
3670 register union pixel3D *Pix=SC->Pix;
3671 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3672 register ZBUFF dz=Pix->L.dz;
3673 register WORD large=Pix->W.large;
3675 while(0<large--)
3676 { *Ztest=(ZVALUE == *Zbuffer ); if(*Ztest) *Zbuffer=ZVALUE; Ztest++; Zbuffer++; Pix->L.z+=dz;}
3678 /*=============================================================*/
3679 void Ztest_zalways_update(struct SOFT3D_context *SC)
3681 register UBYTE *Ztest=SC->Ztest;
3682 register union pixel3D *Pix=SC->Pix;
3683 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3684 register ZBUFF dz=Pix->L.dz;
3685 register WORD large=Pix->W.large;
3687 while(0<large--)
3688 { *Ztest=(TRUE); *Zbuffer=ZVALUE; Ztest++; Zbuffer++; Pix->L.z+=dz;}
3690 /*=============================================================*/
3691 /* void Ztest_znever(struct SOFT3D_context *SC) same as Ztest_znever_update */
3692 /*=============================================================*/
3693 void Ztest_zless(struct SOFT3D_context *SC)
3695 register UBYTE *Ztest=SC->Ztest;
3696 register union pixel3D *Pix=SC->Pix;
3697 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3698 register ZBUFF dz=Pix->L.dz;
3699 register WORD large=Pix->W.large;
3701 while(0<large--)
3702 { *Ztest=(ZVALUE < *Zbuffer ); Ztest++; Zbuffer++; Pix->L.z+=dz; }
3704 /*=============================================================*/
3705 void Ztest_zgequal(struct SOFT3D_context *SC)
3707 register UBYTE *Ztest=SC->Ztest;
3708 register union pixel3D *Pix=SC->Pix;
3709 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3710 register ZBUFF dz=Pix->L.dz;
3711 register WORD large=Pix->W.large;
3713 while(0<large--)
3714 { *Ztest=(ZVALUE >= *Zbuffer ); Ztest++; Zbuffer++; Pix->L.z+=dz; }
3716 /*=============================================================*/
3717 void Ztest_zlequal(struct SOFT3D_context *SC)
3719 register UBYTE *Ztest=SC->Ztest;
3720 register union pixel3D *Pix=SC->Pix;
3721 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3722 register ZBUFF dz=Pix->L.dz;
3723 register WORD large=Pix->W.large;
3725 while(0<large--)
3726 { *Ztest=(ZVALUE <= *Zbuffer ); Ztest++; Zbuffer++; Pix->L.z+=dz; }
3728 /*=============================================================*/
3729 void Ztest_zgreater(struct SOFT3D_context *SC)
3731 register UBYTE *Ztest=SC->Ztest;
3732 register union pixel3D *Pix=SC->Pix;
3733 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3734 register ZBUFF dz=Pix->L.dz;
3735 register WORD large=Pix->W.large;
3737 while(0<large--)
3738 { *Ztest=(ZVALUE > *Zbuffer ); Ztest++; Zbuffer++; Pix->L.z+=dz; }
3740 /*=============================================================*/
3741 void Ztest_znotequal(struct SOFT3D_context *SC)
3743 register UBYTE *Ztest=SC->Ztest;
3744 register union pixel3D *Pix=SC->Pix;
3745 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3746 register ZBUFF dz=Pix->L.dz;
3747 register WORD large=Pix->W.large;
3749 while(0<large--)
3750 { *Ztest=(ZVALUE != *Zbuffer ); Ztest++; Zbuffer++; Pix->L.z+=dz; }
3752 /*=============================================================*/
3753 void Ztest_zequal(struct SOFT3D_context *SC)
3755 register UBYTE *Ztest=SC->Ztest;
3756 register union pixel3D *Pix=SC->Pix;
3757 register ZBUFF *Zbuffer= &(Pix->L.ZbufferY[Pix->W.x]);
3758 register ZBUFF dz=Pix->L.dz;
3759 register WORD large=Pix->W.large;
3761 while(0<large--)
3762 { *Ztest=(ZVALUE == *Zbuffer ); Ztest++; Zbuffer++; Pix->L.z+=dz; }
3764 /*=============================================================*/
3765 void Ztest_zalways(struct SOFT3D_context *SC)
3767 register UBYTE *Ztest=SC->Ztest;
3768 register union pixel3D *Pix=SC->Pix;
3769 register WORD large=Pix->W.large;
3771 while(0<large--)
3772 { *Ztest=(TRUE); Ztest++; }
3774 /*=============================================================*/
3775 void EdgeMinDeltas(struct SOFT3D_context *SC,union pixel3D *P1,union pixel3D *P2)
3777 /* for selecting mipmap find the minimum uv linear delta */
3778 register WORD size;
3779 register LONG u,v,du,dv;
3781 if(SC->state.ST==NULL) /* = Color only so dont bother with mipmapped-texturing*/
3782 return;
3784 SREM(EdgeMinDeltas)
3785 PrintPix(P1);
3786 PrintPix(P2);
3788 size=P2->W.y - P1->W.y;
3789 SVAR(size)
3790 if(size==0)
3791 size=P2->W.x - P1->W.x;
3792 SVAR(size)
3793 if(size==0)
3794 return;
3796 u=(P2->L.u - P1->L.u);
3797 v=(P2->L.v - P1->L.v);
3799 SVAR(u>>16)
3800 SVAR(v>>16)
3801 du=u/size;
3802 dv=v/size;
3804 if(du<0) du=-du; /* absolute value */
3805 if(dv<0) dv=-dv;
3807 if(du!=0)
3808 if(du<SC->dmin) /* find minimal delta = texture step */
3809 SC->dmin=du;
3811 if(dv!=0)
3812 if(dv<SC->dmin) /* find minimal delta = texture step */
3813 SC->dmin=dv;
3815 SVAR(du>>16)
3816 SVAR(dv>>16)
3817 SVAR(SC->dmin>>16)
3819 /*=============================================================*/
3820 void Edge_Persp_Tex_Gouraud_Fog(struct SOFT3D_context *SC)
3822 register union pixel3D *P1=SC->P1;
3823 register union pixel3D *P2=SC->P2;
3824 register WORD high,n;
3825 double u,v,u2,v2,du,dv,w;
3826 union pixel3D DeltaY;
3828 SFUNCTION(Edge_Persp_Tex_Gouraud_Fog)
3829 high=P2->W.y - P1->W.y;
3830 if(high<2) return;
3832 DeltaY.L.dx=(P2->L.x - P1->L.x)/high;
3833 DeltaY.L.dz=(P2->L.z - P1->L.z)/high;
3834 DeltaY.L.dw=(P2->L.w - P1->L.w)/high;
3835 DeltaY.L.dR=(P2->L.R - P1->L.R)/high;
3836 DeltaY.L.dG=(P2->L.G - P1->L.G)/high;
3837 DeltaY.L.dB=(P2->L.B - P1->L.B)/high;
3838 DeltaY.L.dA=(P2->L.A - P1->L.A)/high;
3839 DeltaY.L.dF=(P2->L.F - P1->L.F)/high;
3841 u =(double)P1->L.u * P1->L.w;
3842 u2=(double)P2->L.u * P2->L.w;
3843 v =(double)P1->L.v * P1->L.w;
3844 v2=(double)P2->L.v * P2->L.w;
3846 du=(u2 - u)/high;
3847 dv=(v2 - v)/high;
3849 high--; /* ne pas recalculer les points extremites */
3850 NLOOP(high)
3852 P1[1].L.x=P1->L.x+DeltaY.L.dx;
3853 P1[1].L.z=P1->L.z+DeltaY.L.dz;
3854 P1[1].L.w=P1->L.w+DeltaY.L.dw;
3855 P1[1].L.R=P1->L.R+DeltaY.L.dR;
3856 P1[1].L.G=P1->L.G+DeltaY.L.dG;
3857 P1[1].L.B=P1->L.B+DeltaY.L.dB;
3858 P1[1].L.A=P1->L.A+DeltaY.L.dA;
3859 P1[1].L.F=P1->L.F+DeltaY.L.dF;
3860 w=P1[1].L.w;
3861 u=u+du;
3862 v=v+dv;
3863 P1[1].L.u=u/w;
3864 P1[1].L.v=v/w;
3865 P1++;
3868 /*=============================================================*/
3869 void Edge_Tex_Gouraud_Fog(struct SOFT3D_context *SC)
3871 register union pixel3D *P1=SC->P1;
3872 register union pixel3D *P2=SC->P2;
3873 register WORD high,n;
3874 union pixel3D DeltaY;
3876 if(Wazp3D->DoMipMaps.ON)
3877 EdgeMinDeltas(SC,P1,P2);
3879 high=P2->W.y - P1->W.y;
3880 if(high<2) return;
3882 SFUNCTION(Edge_Tex_Gouraud_Fog)
3883 DeltaY.L.dx=(P2->L.x - P1->L.x)/high;
3884 DeltaY.L.dz=(P2->L.z - P1->L.z)/high;
3885 DeltaY.L.du=(P2->L.u - P1->L.u)/high;
3886 DeltaY.L.dv=(P2->L.v - P1->L.v)/high;
3887 DeltaY.L.dR=(P2->L.R - P1->L.R)/high;
3888 DeltaY.L.dG=(P2->L.G - P1->L.G)/high;
3889 DeltaY.L.dB=(P2->L.B - P1->L.B)/high;
3890 DeltaY.L.dA=(P2->L.A - P1->L.A)/high;
3891 DeltaY.L.dF=(P2->L.F - P1->L.F)/high;
3893 high--; /* ne pas recalculer les points extremites */
3894 NLOOP(high)
3896 P1[1].L.x=P1->L.x+DeltaY.L.dx;
3897 P1[1].L.z=P1->L.z+DeltaY.L.dz;
3898 P1[1].L.u=P1->L.u+DeltaY.L.du;
3899 P1[1].L.v=P1->L.v+DeltaY.L.dv;
3900 P1[1].L.R=P1->L.R+DeltaY.L.dR;
3901 P1[1].L.G=P1->L.G+DeltaY.L.dG;
3902 P1[1].L.B=P1->L.B+DeltaY.L.dB;
3903 P1[1].L.A=P1->L.A+DeltaY.L.dA;
3904 P1[1].L.F=P1->L.F+DeltaY.L.dF;
3905 P1++;
3908 /*=============================================================*/
3909 void Edge_Gouraud(struct SOFT3D_context *SC)
3911 register union pixel3D *P1=SC->P1;
3912 register union pixel3D *P2=SC->P2;
3913 register WORD high,n;
3914 union pixel3D DeltaY;
3916 high=P2->W.y - P1->W.y;
3917 if(high<2) return;
3919 SFUNCTION(Edge_Gouraud)
3920 DeltaY.L.dx=(P2->L.x - P1->L.x)/high;
3921 DeltaY.L.dz=(P2->L.z - P1->L.z)/high;
3922 DeltaY.L.dR=(P2->L.R - P1->L.R)/high;
3923 DeltaY.L.dG=(P2->L.G - P1->L.G)/high;
3924 DeltaY.L.dB=(P2->L.B - P1->L.B)/high;
3925 DeltaY.L.dA=(P2->L.A - P1->L.A)/high;
3927 high--; /* ne pas recalculer les points extremites */
3928 NLOOP(high)
3930 P1[1].L.x=P1->L.x+DeltaY.L.dx;
3931 P1[1].L.z=P1->L.z+DeltaY.L.dz;
3932 P1[1].L.R=P1->L.R+DeltaY.L.dR;
3933 P1[1].L.G=P1->L.G+DeltaY.L.dG;
3934 P1[1].L.B=P1->L.B+DeltaY.L.dB;
3935 P1[1].L.A=P1->L.A+DeltaY.L.dA;
3936 P1++;
3939 /*=============================================================*/
3940 void Edge_Flat(struct SOFT3D_context *SC)
3942 register union pixel3D *P1=SC->P1;
3943 register union pixel3D *P2=SC->P2;
3944 register WORD high,n;
3945 union pixel3D DeltaY;
3947 high=P2->W.y - P1->W.y;
3948 if(high<2) return;
3950 SFUNCTION(Edge_Flat)
3951 DeltaY.L.dx=(P2->L.x - P1->L.x)/high;
3952 DeltaY.L.dz=(P2->L.z - P1->L.z)/high;
3954 high--; /* ne pas recalculer les points extremites */
3955 NLOOP(high)
3957 P1[1].L.x=P1->L.x+DeltaY.L.dx;
3958 P1[1].L.z=P1->L.z+DeltaY.L.dz;
3959 P1++;
3962 /*=============================================================*/
3963 void Edge_Persp_Tex(struct SOFT3D_context *SC)
3965 register union pixel3D *P1=SC->P1;
3966 register union pixel3D *P2=SC->P2;
3967 register WORD high,n;
3968 double u,v,u2,v2,du,dv,w;
3969 union pixel3D DeltaY;
3971 SFUNCTION(Edge_Persp_Tex)
3972 high=P2->W.y - P1->W.y;
3973 if(high<2) return;
3975 DeltaY.L.dx=(P2->L.x - P1->L.x)/high;
3976 DeltaY.L.dz=(P2->L.z - P1->L.z)/high;
3977 DeltaY.L.dw=(P2->L.w - P1->L.w)/high;
3979 u =(double)P1->L.u * P1->L.w;
3980 u2=(double)P2->L.u * P2->L.w;
3981 v =(double)P1->L.v * P1->L.w;
3982 v2=(double)P2->L.v * P2->L.w;
3984 du=(u2 - u)/high;
3985 dv=(v2 - v)/high;
3987 high--; /* ne pas recalculer les points extremites */
3988 NLOOP(high)
3990 P1[1].L.x=P1->L.x+DeltaY.L.dx;
3991 P1[1].L.z=P1->L.z+DeltaY.L.dz;
3992 P1[1].L.w=P1->L.w+DeltaY.L.dw;
3993 w=P1[1].L.w;
3994 u=u+du;
3995 v=v+dv;
3996 P1[1].L.u=u/w;
3997 P1[1].L.v=v/w;
3998 P1++;
4001 /*=============================================================*/
4002 void Edge_Tex(struct SOFT3D_context *SC)
4004 register union pixel3D *P1=SC->P1;
4005 register union pixel3D *P2=SC->P2;
4006 register WORD high,n;
4007 union pixel3D DeltaY;
4009 if(Wazp3D->DoMipMaps.ON)
4010 EdgeMinDeltas(SC,P1,P2);
4012 high=P2->W.y - P1->W.y;
4013 if(high<2) return;
4015 SFUNCTION(Edge_Tex)
4016 DeltaY.L.dx=(P2->L.x - P1->L.x)/high;
4017 DeltaY.L.dz=(P2->L.z - P1->L.z)/high;
4018 DeltaY.L.du=(P2->L.u - P1->L.u)/high;
4019 DeltaY.L.dv=(P2->L.v - P1->L.v)/high;
4021 high--; /* ne pas recalculer les points extremites */
4022 NLOOP(high)
4024 P1[1].L.x=P1->L.x+DeltaY.L.dx;
4025 P1[1].L.z=P1->L.z+DeltaY.L.dz;
4026 P1[1].L.u=P1->L.u+DeltaY.L.du;
4027 P1[1].L.v=P1->L.v+DeltaY.L.dv;
4028 P1++;
4032 /*=============================================================*/
4033 void SOFT3D_SetDrawState(APTR sc,APTR sta)
4035 struct state3D *state=sta;
4036 struct SOFT3D_context *SC=sc;
4037 struct SOFT3D_texture *ST=state->ST;
4040 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
4041 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
4042 SFUNCTION(SOFT3D_SetDrawState)
4043 if(Wazp3D->DebugSOFT3D.ON)
4045 Libprintf(" state:Changed%ld UseTex%ld ST%ld ZMode%ld TexEnvMode%ld BlendMode%ld UseGouraud%ld UseFog%ld\n",(ULONG)state->Changed,(ULONG)state->UseTex,(IPTR)state->ST,(ULONG)state->ZMode,(ULONG)state->TexEnvMode,(ULONG)state->BlendMode,(ULONG)state->UseGouraud,(ULONG)state->UseFog);
4046 PrintST(state->ST);
4047 Libprintf(" CurrentRGBA: %ld %ld %ld %ld\n",(ULONG)state->CurrentRGBA[0],(ULONG)state->CurrentRGBA[1],(ULONG)state->CurrentRGBA[2],(ULONG)state->CurrentRGBA[3]);
4050 if(!state->Changed)
4052 SREM( state unchanged) /* not changed ==> do nothing */
4053 return;
4056 if(Wazp3D->UseStateTracker.ON)
4057 if(!Wazp3D->PrefsIsOpened) /* if the user dont change states */
4058 if(SC->state.ST ==state->ST)
4059 if(SC->state.ZMode ==state->ZMode)
4060 if(SC->state.BlendMode ==state->BlendMode)
4061 if(SC->state.TexEnvMode ==state->TexEnvMode)
4062 if(SC->state.PerspMode ==state->PerspMode)
4063 if(SC->state.CullingMode==state->CullingMode)
4064 if(SC->state.FogMode ==state->FogMode)
4065 if(SC->state.UseGouraud ==state->UseGouraud)
4066 if(SC->state.UseTex ==state->UseTex)
4067 if(SC->state.UseFog ==state->UseFog)
4068 if(SAMERGBA(SC->state.FogRGBA ,state->FogRGBA))
4069 if(SAMERGBA(SC->state.CurrentRGBA ,state->CurrentRGBA))
4070 if(SAMERGBA(SC->state.EnvRGBA ,state->EnvRGBA))
4071 if(SC->state.PointSize ==state->PointSize)
4072 if(SC->state.LineSize ==state->LineSize)
4073 if(SC->state.FogZmin ==state->FogZmin)
4074 if(SC->state.FogZmax ==state->FogZmax)
4075 if(SC->state.FogDensity ==state->FogDensity)
4077 SREM( all same states) /* if nothing truly changed ==> do nothing */
4078 SC->state.Changed=state->Changed=FALSE;
4079 return;
4083 SC->state.ZMode =state->ZMode;
4084 SC->state.BlendMode =state->BlendMode;
4085 SC->state.TexEnvMode =state->TexEnvMode;
4086 SC->state.PerspMode =state->PerspMode;
4087 SC->state.CullingMode =state->CullingMode;
4088 SC->state.FogMode =state->FogMode;
4089 SC->state.UseGouraud =state->UseGouraud;
4090 SC->state.UseTex =state->UseTex;
4091 SC->state.UseFog =state->UseFog;
4092 COPYRGBA(SC->state.FogRGBA ,state->FogRGBA);
4093 COPYRGBA(SC->state.CurrentRGBA ,state->CurrentRGBA);
4094 COPYRGBA(SC->state.EnvRGBA ,state->EnvRGBA);
4095 COPYRGBA(SC->state.BackRGBA ,state->BackRGBA);
4096 SC->state.PointSize =state->PointSize;
4097 SC->state.LineSize =state->LineSize;
4098 SC->state.FogZmin =state->FogZmin;
4099 SC->state.FogZmax =state->FogZmax;
4100 SC->state.FogDensity =state->FogDensity;
4101 SC->state.ST =state->ST;
4102 /*hard stuffs */
4103 SC->state.gltex =0;
4104 if(ST!=NULL)
4105 SC->state.gltex =ST->HT.gltex; /*direct access to gltex value */
4106 SC->HC.state=&SC->state; /*direct access to state */
4109 /* flush remaining pixels before any changes */
4110 SOFT3D_Flush(SC);
4112 /* Now change hardware/software drawing functions */
4113 #ifdef USEOPENGL
4114 if(SC->UseHard) HARD3D_SetDrawFunctions(&SC->HC);
4115 #endif
4116 if(!SC->UseHard) SOFT3D_SetDrawFunctions(sc);
4118 SC->state.Changed=state->Changed=FALSE; /* change treated */
4120 /*=============================================================*/
4121 void SOFT3D_SetDrawFunctions(APTR sc)
4123 struct SOFT3D_context *SC=sc;
4124 struct SOFT3D_texture *ST=SC->state.ST;
4125 UBYTE FillMode,EdgeMode,TexEnvMode,BlendMode,UseFog,UseGouraud,UseBigTex,UseTex24,UseBuffer;
4127 SFUNCTION(SOFT3D_SetDrawFunctions)
4129 /* We may change those state values for a faster soft-rendering */
4130 ST =SC->state.ST;
4131 TexEnvMode =SC->state.TexEnvMode;
4132 if(!SC->state.UseTex)
4133 TexEnvMode =0;
4134 BlendMode =SC->state.BlendMode;
4135 UseFog =SC->state.UseFog;
4136 UseGouraud =SC->state.UseGouraud;
4138 if(Wazp3D->DebugSOFT3D.ON)
4139 Libprintf(" FlatRGBA: %ld %ld %ld %ld\n",(ULONG)SC->FlatRGBA[0],(ULONG)SC->FlatRGBA[1],(ULONG)SC->FlatRGBA[2],(ULONG)SC->FlatRGBA[3]);
4141 if(UseGouraud==FALSE) /* if truly want flat color*/
4143 SREM(True Flat)
4144 if(Wazp3D->TexMode.ON!=3) /* in this case flatcolor is already polygon's averagecolor */
4145 COPYRGBA(SC->FlatRGBA,SC->state.CurrentRGBA); /* if true no-gouraud mode then flat-color come from current-color */
4148 if(!SC->ColorChange) /* then dont truly need gouraud shading */
4150 SREM(Gouraud to Flat)
4151 UseGouraud=FALSE; /* then flat color come from point-color NOT from current-color */
4154 UseTex24=FALSE; /* default 32 bits color */
4155 UseBigTex=FALSE;
4156 if(SC->state.UseTex)
4158 if(256<ST->large) UseBigTex=TRUE;
4159 if(256<ST->high ) UseBigTex=TRUE;
4160 UseTex24=(ST->bits==24); /* but the tex can be only 24 bits */
4163 if( (BlendMode==BLENDFASTALPHA) ou (BlendMode==BLENDNOALPHA) )
4164 if(TexEnvMode>W3D_REPLACE) /* if got a coloring function */
4165 if(SC->ColorTransp) /* that colorize in alpha (=make texture transparent)*/
4167 SREM(ColorTransp so really use BLENDALPHA)
4168 BlendMode=BLENDALPHA; /* then use the tex as a true alpha one */
4172 if(Wazp3D->QuakeMatrixPatch.ON) /* patch: for glmatrix transparency */
4173 if(BlendMode==W3D_ONE_MINUS_SRC_ALPHA*16 + W3D_SRC_ALPHA)
4174 BlendMode=W3D_SRC_ALPHA*16 + W3D_ONE_MINUS_SRC_ALPHA;
4178 /* if color is white dont do a stupid flat-color modulate on a texture = do nothing */
4179 if(TexEnvMode>W3D_REPLACE) /* with a coloring function */
4180 if(!SC->ColorChange)
4181 if(SC->ColorWhite)
4183 SREM(Color is white so no Coloring)
4184 TexEnvMode=W3D_REPLACE;
4187 if(Wazp3D->DebugTexColor.ON)
4188 if(SC->state.UseTex)
4189 if(ST!=NULL) /* display the parameters as the texture color */
4191 SC->FlatRGBA[0]=ST->Tnum; SC->FlatRGBA[1]=TexEnvMode; SC->FlatRGBA[2]=BlendMode;
4192 TexEnvMode=0; BlendMode=BLENDREPLACE; UseFog=FALSE; UseGouraud=SC->ColorChange=FALSE;
4196 FillMode=SC->state.UseTex*4 + UseGouraud*2 + UseFog*1;
4197 SC->FunctionFill =Functions.Fill[FillMode];
4199 if(UseBigTex)
4201 SC->FunctionFill=(HOOKEDFUNCTION)Fill_BigTexPersp2_Gouraud_Fog;
4202 if(!UseFog)
4203 if(!UseGouraud)
4204 SC->FunctionFill=(HOOKEDFUNCTION)Fill_BigTexPersp2;
4208 EdgeMode=(SC->state.PerspMode!=0)*8+FillMode;
4209 SC->FunctionEdge=Functions.Edge[EdgeMode];
4211 if(SC->state.PerspMode==2)
4212 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp2x2_Tex_Gouraud_Fog;
4214 if(SC->state.PerspMode==1)
4216 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp1_Tex_Gouraud_Fog;
4217 if(!SC->state.UseTex)
4218 if(!UseFog)
4220 if(UseGouraud)
4221 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp1_Gouraud;
4222 else
4223 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp1_Flat;
4225 if(SC->state.UseTex)
4226 if(!UseFog)
4227 if(!UseGouraud)
4228 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp1_Tex;
4231 if(SC->state.PerspMode==0)
4233 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp0_Tex_Gouraud_Fog;
4234 if(!SC->state.UseTex)
4235 if(!UseFog)
4237 if(UseGouraud)
4238 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp0_Gouraud;
4239 else
4240 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp0_Flat;
4242 if(SC->state.UseTex)
4243 if(!UseFog)
4244 if(!UseGouraud)
4245 SC->FunctionPoly=(HOOKEDFUNCTION)Poly_Persp0_Tex;
4248 SC->FunctionZtest =Functions.Ztest [SC->state.ZMode];
4249 SINFO((void *)SC->FunctionZtest,(void *)Ztest_znever_update)
4250 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zless)
4251 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zgequal)
4252 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zlequal)
4253 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zgreater)
4254 SINFO((void *)SC->FunctionZtest,(void *)Ztest_znotequal)
4255 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zequal)
4256 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zalways)
4258 SINFO((void *)SC->FunctionZtest,(void *)Ztest_znever_update)
4259 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zless_update)
4260 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zgequal_update)
4261 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zlequal_update)
4262 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zgreater_update)
4263 SINFO((void *)SC->FunctionZtest,(void *)Ztest_znotequal_update)
4264 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zequal_update)
4265 SINFO((void *)SC->FunctionZtest,(void *)Ztest_zalways_update)
4267 SC->FunctionIn =(HOOKEDFUNCTION)SC->FunctionBitmapIn;
4268 SC->FunctionTexEnv =NULL;
4269 SC->FunctionBlend =NULL;
4270 SC->FunctionBlendFast =NULL;
4271 SC->FunctionFog =NULL;
4272 SC->FunctionFilter =NULL;
4273 SC->FunctionSepia =NULL;
4274 SC->FunctionOut =(HOOKEDFUNCTION)SC->FunctionBitmapOut;
4276 /* FunctionTexEnv */
4277 SC->FunctionTexEnv =Functions.TexEnv[TexEnvMode*2+!UseTex24];
4279 /* FunctionBlend */
4280 SC->SrcFunc=BlendMode/16; SC->DstFunc=BlendMode-SC->SrcFunc*16;
4282 if(UseTex24)
4283 if(SC->FunctionTexEnv==NULL) /* if no function to convert a 24bits tex to 32bits color with alpha*/
4285 SREM( tex dont have alpha)
4286 if(SC->SrcFunc==W3D_SRC_ALPHA) SC->SrcFunc=W3D_ONE;
4287 if(SC->SrcFunc==W3D_ONE_MINUS_SRC_ALPHA) SC->SrcFunc=W3D_ZERO;
4288 if(SC->SrcFunc==W3D_SRC_ALPHA_SATURATE) SC->SrcFunc=W3D_ONE;
4289 if(SC->DstFunc==W3D_SRC_ALPHA) SC->DstFunc=W3D_ONE;
4290 if(SC->DstFunc==W3D_ONE_MINUS_SRC_ALPHA ) SC->DstFunc=W3D_ZERO;
4291 BlendMode=(SC->SrcFunc*16 + SC->DstFunc);
4294 if(SC->bits==24) /* if screen dont have alpha*/
4296 SREM( screen dont have alpha)
4297 if(SC->SrcFunc==W3D_DST_ALPHA) SC->SrcFunc=W3D_ONE;
4298 if(SC->SrcFunc==W3D_ONE_MINUS_DST_ALPHA) SC->SrcFunc=W3D_ZERO;
4299 if(SC->DstFunc==W3D_DST_ALPHA) SC->DstFunc=W3D_ONE;
4300 if(SC->DstFunc==W3D_ONE_MINUS_DST_ALPHA) SC->DstFunc=W3D_ZERO;
4301 BlendMode=(SC->SrcFunc*16 + SC->DstFunc);
4304 if(SC->state.CurrentRGBA[3]==255) /* if current-color dont have alpha*/
4306 SREM( CurrentRGBA dont have alpha)
4307 if(SC->SrcFunc==W3D_CONSTANT_ALPHA) SC->SrcFunc=W3D_ONE;
4308 if(SC->SrcFunc==W3D_ONE_MINUS_CONSTANT_ALPHA) SC->SrcFunc=W3D_ZERO;
4309 if(SC->DstFunc==W3D_CONSTANT_ALPHA) SC->DstFunc=W3D_ONE;
4310 if(SC->DstFunc==W3D_ONE_MINUS_CONSTANT_ALPHA) SC->DstFunc=W3D_ZERO;
4311 BlendMode=(SC->SrcFunc*16 + SC->DstFunc);
4314 SC->FunctionBlend =(HOOKEDFUNCTION)PixelsBlendFunctionAll; /* default is an universal (slow) blend function */
4315 SC->FunctionBlendFast =(HOOKEDFUNCTION)Functions.BlendFast[BlendMode];
4318 UseBuffer=(SC->FunctionOut!=NULL);
4319 if(BlendMode==BLENDREPLACE)
4321 SC->FunctionBlend =(HOOKEDFUNCTION)PixelsColorToImage;
4322 if(UseBuffer)
4323 SC->FunctionBlend=(HOOKEDFUNCTION)PixelsColorToBuffer;
4325 if(TexEnvMode==W3D_REPLACE) /* if no texenv function to convert a 24bits tex to 32bits color*/
4327 SC->FunctionTexEnv= NULL; /* FunctionTexEnv==FunctionBlend==REPLACE */
4328 if(UseTex24)
4330 SC->FunctionBlend=(HOOKEDFUNCTION)PixelsTex24ToImage;
4331 if(UseBuffer)
4332 SC->FunctionBlend=(HOOKEDFUNCTION)PixelsTex24ToBuffer;
4334 else
4336 SC->FunctionBlend=(HOOKEDFUNCTION)PixelsTex32ToImage;
4337 if(UseBuffer)
4338 SC->FunctionBlend=(HOOKEDFUNCTION)PixelsTex32ToBuffer;
4340 SC->FunctionIn=NULL; /* not need to read Image's pixels = : they are all replaced */
4344 if(Wazp3D->DebugSOFT3D.ON)
4345 Libprintf("Functions set with TexEnvMode%ld BlendMode%ld\n",(ULONG)TexEnvMode,(ULONG)BlendMode);
4347 /* FunctionFog */
4348 if(UseFog)
4350 SC->FunctionFog=(HOOKEDFUNCTION)PixelsFogToImage;
4351 if(UseBuffer)
4352 SC->FunctionFog=(HOOKEDFUNCTION)PixelsFogToBuffer;
4356 /* FunctionFilter */
4357 if(Wazp3D->UseFiltering.ON)
4359 SC->FunctionFilter=(HOOKEDFUNCTION)PixelsFilterToImage;
4360 if(UseBuffer)
4361 SC->FunctionFilter=(HOOKEDFUNCTION)PixelsFilterToBuffer;
4364 /* FunctionSepia */
4365 if(Wazp3D->DebugSepiaImage.ON)
4367 SC->FunctionSepia=(HOOKEDFUNCTION)PixelsSepiaToImage;
4368 if(UseBuffer)
4369 SC->FunctionSepia=(HOOKEDFUNCTION)PixelsSepiaToBuffer;
4374 /* patch suggestion from "Cosmos" */
4375 if(SC->FunctionIn ==NULL)
4376 if(SC->FunctionTexEnv ==NULL)
4377 if(SC->FunctionBlend ==(HOOKEDFUNCTION)PixelsTex24ToBuffer)
4378 if(SC->FunctionFog ==NULL)
4379 if(SC->FunctionFilter ==NULL)
4380 if(SC->FunctionSepia ==NULL)
4382 if(SC->FunctionOut ==(HOOKEDFUNCTION)PixelsOutBGRA)
4384 SC->FunctionBlend =NULL;
4385 SC->FunctionOut =(HOOKEDFUNCTION)PixelsOutBGRAfromtex24;
4387 if(SC->FunctionOut ==(HOOKEDFUNCTION)PixelsOutARGB)
4389 SC->FunctionBlend =NULL;
4390 SC->FunctionOut =(HOOKEDFUNCTION)PixelsOutARGBfromtex24;
4395 if(FillMode==0) /* flat color like Blender gui */
4396 if(SC->FunctionBlend==NULL) /* not transparent */
4398 if(SC->FunctionOut==(HOOKEDFUNCTION)PixelsOutRGBA)
4399 SC->FunctionOut =(HOOKEDFUNCTION)PixelsOutRGBA_Flat;
4400 if(SC->FunctionOut==(HOOKEDFUNCTION)PixelsOutBGRA)
4401 SC->FunctionOut =(HOOKEDFUNCTION)PixelsOutBGRA_Flat;
4402 if(SC->FunctionOut==(HOOKEDFUNCTION)PixelsOutARGB)
4403 SC->FunctionOut =(HOOKEDFUNCTION)PixelsOutARGB_Flat;
4404 if(SC->FunctionOut==(HOOKEDFUNCTION)PixelsOutABGR)
4405 SC->FunctionOut =(HOOKEDFUNCTION)PixelsOutABGR_Flat;
4408 ChangeSoftPoint(SC);
4410 /*=============================================================*/
4411 void SOFT3D_Flush(APTR sc)
4413 struct SOFT3D_context *SC=sc;
4415 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
4416 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
4417 SFUNCTION(SOFT3D_Flush)
4418 #ifdef USEOPENGL
4419 if(SC->UseHard)
4421 HARD3D_Flush(&SC->HC);
4422 return;
4424 #endif
4426 /* Will draw what is in the Fragments Buffer */
4427 SC->FragSize2=(SC->FragBufferDone - SC->FragBuffer + 3)/2;
4428 if(SC->FragSize2==0) {SREM( ==> No fragments to draw);goto DrawFragBufferEnd;}
4429 SVAR(SC->FragSize2)
4430 if(SC->Image8==NULL) return;
4432 /* v52: add three (noop) fragments to FragBuffer so can do size2=(size + 1)/2 and so can process 2 (or even 4) Frags inside a loop */
4433 SC->FragBufferDone[0].Tex8 =SC->NoopRGBA; /* read the noop pixel as texture */
4434 SC->FragBufferDone[1].Tex8 =SC->NoopRGBA;
4435 SC->FragBufferDone[2].Tex8 =SC->NoopRGBA;
4436 SC->FragBufferDone[0].Image8 =SC->NoopRGBA; /* write it in noop pixel = do nothing with Image */
4437 SC->FragBufferDone[1].Image8 =SC->NoopRGBA;
4438 SC->FragBufferDone[2].Image8 =SC->NoopRGBA;
4440 if(SC->FunctionIn!=NULL)
4442 SREM(Pass1: FunctionIn)
4443 /* cant print inside lockbitmap so print the functionIn/Out name here */
4444 SINFO((void *)SC->FunctionIn,(void *)NULL)
4445 SINFO((void *)SC->FunctionIn,(void *)PixelsInBGRA)
4446 SINFO((void *)SC->FunctionIn,(void *)PixelsInRGBA)
4447 SINFO((void *)SC->FunctionIn,(void *)PixelsInARGB)
4448 SINFO((void *)SC->FunctionIn,(void *)PixelsInABGR)
4449 SINFO((void *)SC->FunctionIn,(void *)PixelsInRGB)
4450 SINFO((void *)SC->FunctionIn,(void *)PixelsInBGR)
4451 SINFO((void *)SC->FunctionIn,(void *)PixelsIn16)
4452 SINFO((void *)SC->FunctionIn,(void *)PixelsIn8)
4453 if(!LockBM(SC))
4454 goto DrawFragBufferEnd; /* if cant read pixels then cancel this drawing */
4456 SC->FunctionIn(SC); /* convert readed pixels to RGBA format. */
4457 UnLockBM(SC);
4460 if(SC->FunctionTexEnv!=NULL)
4462 SREM(Pass2: FunctionTexEnv (coloring/light) )
4463 SC->FunctionTexEnv(SC);
4466 if(SC->FunctionBlend!=NULL)
4468 SREM(Pass3: FunctionBlend (transparency) )
4469 SC->FunctionBlend(SC);
4472 if(SC->FunctionFog!=NULL)
4474 SREM(Pass4: FunctionFog)
4475 SC->FunctionFog(SC);
4478 if(SC->FunctionFilter!=NULL)
4480 SREM(Pass 5: FunctionFilter )
4481 SC->FunctionFilter(SC);
4484 if(SC->FunctionSepia!=NULL)
4486 SREM(Pass 6: FunctionSepia: debug effect )
4487 SC->FunctionSepia(SC);
4490 if(SC->FunctionOut!=NULL)
4492 SREM(Pass 7:FunctionOut)
4493 /* cant print inside lockbitmap so print the functionIn/Out name here */
4494 SINFO((void *)SC->FunctionOut,(void *)NULL)
4495 SINFO((void *)SC->FunctionOut,(void *)PixelsOutBGRA)
4496 SINFO((void *)SC->FunctionOut,(void *)PixelsOutRGBA)
4497 SINFO((void *)SC->FunctionOut,(void *)PixelsOutARGB)
4498 SINFO((void *)SC->FunctionOut,(void *)PixelsOutABGR)
4499 SINFO((void *)SC->FunctionOut,(void *)PixelsOutBGRA_Flat)
4500 SINFO((void *)SC->FunctionOut,(void *)PixelsOutRGBA_Flat)
4501 SINFO((void *)SC->FunctionOut,(void *)PixelsOutARGB_Flat)
4502 SINFO((void *)SC->FunctionOut,(void *)PixelsOutABGR_Flat)
4503 SINFO((void *)SC->FunctionOut,(void *)PixelsOutRGB)
4504 SINFO((void *)SC->FunctionOut,(void *)PixelsOutBGR)
4505 SINFO((void *)SC->FunctionOut,(void *)PixelsOut16)
4506 SINFO((void *)SC->FunctionOut,(void *)PixelsOut8)
4507 SINFO((void *)SC->FunctionOut,(void *)PixelsOutBGRAfromtex24)
4508 SINFO((void *)SC->FunctionOut,(void *)PixelsOutARGBfromtex24)
4509 if(LockBM(SC))
4511 SC->FunctionOut(SC);
4512 UnLockBM(SC);
4516 SREM(Flush done...)
4517 DrawFragBufferEnd:
4518 SC->FragBufferDone =SC->FragBuffer;
4521 /*=============================================================*/
4522 void DrawSimplePix(struct SOFT3D_context *SC,register union pixel3D *P)
4524 struct SOFT3D_texture *ST=SC->state.ST;
4526 SFUNCTION(DrawPointSimplePIX)
4527 if ( (P->W.x < 0) ou (P->W.y < 0) ou (SC->large <= P->W.x) ou (SC->high <= P->W.y))
4528 return;
4530 SC->Pix =&(SC->edge1[P->W.y]);
4531 COPYPIX(SC->Pix,P);
4532 SC->Pix->W.large=1;
4533 SC->PolyHigh=1;
4535 if(ST!=NULL)
4536 SC->MM=&ST->MMs[0]; /* default to biggest mipmap <=> never call FunctionFill with SC->MM=NULL*/
4538 SC->FunctionFill(SC);
4540 /*=============================================================*/
4541 void DrawPointPix(struct SOFT3D_context *SC)
4543 register union pixel3D *P=SC->PolyPix;
4544 register WORD *PointLarge=SC->PointLarges;
4545 register WORD xmin,xmax,ymin,ymax,y;
4546 register WORD R;
4547 struct SOFT3D_texture *ST=SC->state.ST;
4548 struct state3D flatstate;
4551 SFUNCTION(DrawPointPIX)
4552 SVAR(SC->state.PointSize)
4553 SC->ColorChange=FALSE;
4555 /* point as tex nofog nogouraud just color */
4556 flatstate.ZMode =SC->state.ZMode;
4557 flatstate.PointSize=SC->state.PointSize;
4558 flatstate.LineSize =SC->state.LineSize;
4559 flatstate.BlendMode=SC->state.BlendMode;
4561 flatstate.TexEnvMode=0;
4562 flatstate.PerspMode=0;
4563 flatstate.CullingMode=W3D_NOW;
4564 flatstate.UseGouraud=FALSE;
4565 flatstate.UseTex=FALSE;
4566 flatstate.UseFog=FALSE;
4567 flatstate.ST=NULL;
4568 flatstate.Changed=TRUE;
4570 SOFT3D_SetDrawState(SC,&flatstate);
4572 COPYRGBA(SC->FlatRGBA,SC->PolyP->RGBA);
4574 if(SC->state.PointSize==1.0)
4575 {DrawSimplePix(SC,P);return;}
4577 R=SC->state.PointSize/2+1;
4578 xmin=0+R;
4579 ymin=0+R;
4580 xmax=SC->large-R;
4581 ymax=SC->high -R;
4582 if ( (P->W.x<xmin) ou (P->W.y<ymin) ou (xmax<=P->W.x) ou (ymax<=P->W.y))
4583 return;
4585 P->W.y =P->W.y - SC->state.PointSize/2.0;
4586 SC->Pix =&(SC->edge1[P->W.y]);
4587 SC->PolyHigh=SC->state.PointSize;
4589 YLOOP(SC->PolyHigh)
4591 COPYPIX(&SC->Pix[y],P);
4592 SC->Pix[y].W.large =PointLarge[y];
4593 SC->Pix[y].W.x =SC->Pix[y].W.x - PointLarge[y]/2;
4596 if(ST!=NULL)
4597 SC->MM=&ST->MMs[0]; /* default to biggest mipmap <=> never call FunctionFill with SC->MM=NULL*/
4598 SC->FunctionFill(SC);
4600 /*=============================================================*/
4601 void DoDeltasUV(union pixel3D *P1,union pixel3D *P2)
4603 /* V44: Compute a quadratic approximation of texture to emulate perspective */
4604 double a,b,z0,z2,n,dt,rz4dt;
4605 double u0,u2,du,ddu;
4606 double v0,v2,dv,ddv;
4608 n=P1->W.large;
4609 if(P1->L.w==P2->L.w)
4611 P1->L.du=(P2->L.u - P1->L.u)/n;
4612 P1->L.dv=(P2->L.v - P1->L.v)/n;
4613 P1->L.ddu=P1->L.ddv=0;
4614 return;
4617 z0=1.0/P1->L.w;
4618 z2=1.0/P2->L.w;
4620 u0=P1->L.u;
4621 u2=P2->L.u;
4622 v0=P1->L.v;
4623 v2=P2->L.v;
4625 dt = u2-u0;
4626 rz4dt = (4.0*dt*z0) / (z0 + z2) ;
4627 a = ( -rz4dt +dt +dt ) / (n*n) ;
4628 b = ( +rz4dt -dt ) / (n) ;
4629 du = a + b ;
4630 ddu = a + a ;
4632 dt = v2-v0;
4633 rz4dt = (4.0*dt*z0) / (z0 + z2) ;
4634 a = ( -rz4dt +dt +dt ) / (n*n) ;
4635 b = ( +rz4dt -dt ) / (n) ;
4636 dv = a + b ;
4637 ddv = a + a ;
4639 /* store ddu ddv du dv as LONG */
4640 P1->L.du = du ;
4641 P1->L.dv = dv ;
4642 P1->L.ddu = ddu ;
4643 P1->L.ddv = ddv ;
4646 /*=============================================================*/
4647 void Poly_Persp0_Tex(struct SOFT3D_context *SC)
4649 register union pixel3D *P1=SC->P1;
4650 register union pixel3D *P2=SC->P2;
4651 register LONG high=SC->PolyHigh;
4652 register LONG n;
4653 register WORD large,maxlarge,maxn;
4654 union pixel3D DeltaX;
4656 SFUNCTION(Poly_Persp0_Tex)
4657 maxn=maxlarge=0;
4658 NLOOP(high) /* trouver le large max du polygone = meilleur delta */
4660 large=P2->W.x - P1->W.x; P1->W.large=large;
4662 if(maxlarge < large)
4663 {maxn=n; maxlarge=large;}
4665 P1++;P2++;
4668 /* compute best delta */
4669 P1=&SC->P1[maxn];
4670 P2=&SC->P2[maxn];
4672 if(maxlarge!=0)
4674 DeltaX.L.dz=(P2->L.z - P1->L.z)/maxlarge;
4675 DeltaX.L.du=(P2->L.u - P1->L.u)/maxlarge;
4676 DeltaX.L.dv=(P2->L.v - P1->L.v)/maxlarge;
4680 SVAR(maxlarge)
4681 PrintPix(P1);
4682 PrintPix(P2);
4683 PrintPix(&DeltaX);
4686 /* and copy same delta for all segments */
4687 P1=SC->P1;
4688 NLOOP(high)
4690 P1->L.dz =DeltaX.L.dz;
4691 P1->L.du =DeltaX.L.du;
4692 P1->L.dv =DeltaX.L.dv;
4693 P1->L.ddu =0;
4694 P1->L.ddv =0;
4695 P1++;
4698 SC->Pix=SC->P1;
4699 SelectMipMap(SC);
4700 SC->FunctionFill(SC);
4702 /*=============================================================*/
4703 void Poly_Persp0_Gouraud(struct SOFT3D_context *SC)
4705 register union pixel3D *P1=SC->P1;
4706 register union pixel3D *P2=SC->P2;
4707 register LONG high=SC->PolyHigh;
4708 register LONG n;
4709 register WORD large,maxlarge,maxn;
4710 union pixel3D DeltaX = {};
4712 SFUNCTION(Poly_Persp0_Gouraud)
4713 maxn=maxlarge=0;
4714 NLOOP(high) /* trouver le large max du polygone = meilleur delta */
4716 large=P2->W.x - P1->W.x; P1->W.large=large;
4718 if(maxlarge < large)
4719 {maxn=n; maxlarge=large;}
4720 P1++;P2++;
4723 /* compute best delta */
4724 P1=&SC->P1[maxn];
4725 P2=&SC->P2[maxn];
4726 if(maxlarge!=0)
4728 DeltaX.L.dz=(P2->L.z - P1->L.z)/maxlarge;
4729 DeltaX.L.dR=(P2->L.R - P1->L.R)/maxlarge;
4730 DeltaX.L.dG=(P2->L.G - P1->L.G)/maxlarge;
4731 DeltaX.L.dB=(P2->L.B - P1->L.B)/maxlarge;
4732 DeltaX.L.dA=(P2->L.A - P1->L.A)/maxlarge;
4735 /* and copy same delta for all segments */
4736 P1=SC->P1;
4737 NLOOP(high)
4739 P1->L.dz =DeltaX.L.dz;
4740 P1->L.dR =DeltaX.L.dR;
4741 P1->L.dG =DeltaX.L.dG;
4742 P1->L.dB =DeltaX.L.dB;
4743 P1->L.dA =DeltaX.L.dA;
4744 P1++;
4747 SC->Pix=SC->P1;
4748 SC->FunctionFill(SC);
4750 /*=============================================================*/
4751 void Poly_Persp0_Flat(struct SOFT3D_context *SC)
4753 register union pixel3D *P1=SC->P1;
4754 register union pixel3D *P2=SC->P2;
4755 register LONG high=SC->PolyHigh;
4756 register LONG n;
4757 register WORD large;
4759 SFUNCTION(Poly_Persp0_Flat)
4760 /* compute a delta per segment */
4761 NLOOP(high)
4763 large=P2->W.x - P1->W.x; P1->W.large=large;
4765 if(large!=0)
4767 P1->L.dz=(P2->L.z - P1->L.z)/large;
4769 P1++,P2++;
4772 SC->Pix=SC->P1;
4773 SC->FunctionFill(SC);
4775 /*=============================================================*/
4776 void Poly_Persp0_Tex_Gouraud_Fog(struct SOFT3D_context *SC)
4778 register union pixel3D *P1=SC->P1;
4779 register union pixel3D *P2=SC->P2;
4780 register LONG high=SC->PolyHigh;
4781 register LONG n;
4782 register WORD large,maxlarge,maxn;
4783 union pixel3D DeltaX = {};
4785 SFUNCTION(Poly_Persp0_Tex_Gouraud_Fog)
4786 maxn=maxlarge=0;
4787 NLOOP(high) /* trouver le large max du polygone = meilleur delta */
4789 large=P2->W.x - P1->W.x; P1->W.large=large;
4791 if(maxlarge < large)
4792 {maxn=n; maxlarge=large;}
4793 P1++;P2++;
4796 /* compute best delta */
4797 P1=&SC->P1[maxn];
4798 P2=&SC->P2[maxn];
4799 if(maxlarge!=0)
4801 DeltaX.L.dz=(P2->L.z - P1->L.z)/maxlarge;
4802 DeltaX.L.du=(P2->L.u - P1->L.u)/maxlarge;
4803 DeltaX.L.dv=(P2->L.v - P1->L.v)/maxlarge;
4804 DeltaX.L.dR=(P2->L.R - P1->L.R)/maxlarge;
4805 DeltaX.L.dG=(P2->L.G - P1->L.G)/maxlarge;
4806 DeltaX.L.dB=(P2->L.B - P1->L.B)/maxlarge;
4807 DeltaX.L.dA=(P2->L.A - P1->L.A)/maxlarge;
4808 DeltaX.L.dF=(P2->L.F - P1->L.F)/maxlarge;
4811 /* and copy same delta for all segments */
4812 P1=SC->P1;
4813 NLOOP(high)
4815 P1->L.dz =DeltaX.L.dz;
4816 P1->L.du =DeltaX.L.du;
4817 P1->L.dv =DeltaX.L.dv;
4818 P1->L.dR =DeltaX.L.dR;
4819 P1->L.dG =DeltaX.L.dG;
4820 P1->L.dB =DeltaX.L.dB;
4821 P1->L.dA =DeltaX.L.dA;
4822 P1->L.dF =DeltaX.L.dF;
4823 P1->L.ddu =0;
4824 P1->L.ddv =0;
4825 P1++;
4828 SC->Pix=SC->P1;
4829 SelectMipMap(SC);
4830 SC->FunctionFill(SC);
4832 /*=============================================================*/
4833 void Poly_Persp1_Tex(struct SOFT3D_context *SC)
4835 register union pixel3D *P1=SC->P1;
4836 register union pixel3D *P2=SC->P2;
4837 register LONG high=SC->PolyHigh;
4838 register LONG n;
4839 register WORD large;
4841 SFUNCTION(Poly_Persp1_Tex)
4842 /* compute a delta per segment */
4843 NLOOP(high)
4845 large=P2->W.x - P1->W.x; P1->W.large=large;
4848 if(large!=0)
4850 P1->L.dz=(P2->L.z - P1->L.z)/large;
4851 P1->L.du=(P2->L.u - P1->L.u)/large;
4852 P1->L.dv=(P2->L.v - P1->L.v)/large;
4853 P1->L.ddu=0;
4854 P1->L.ddv=0;
4856 P1++,P2++;
4859 SC->Pix=SC->P1;
4860 SelectMipMap(SC);
4861 SC->FunctionFill(SC);
4863 /*=============================================================*/
4864 void Poly_Persp1_Gouraud(struct SOFT3D_context *SC)
4866 register union pixel3D *P1=SC->P1;
4867 register union pixel3D *P2=SC->P2;
4868 register LONG high=SC->PolyHigh;
4869 register LONG n;
4870 register WORD large;
4872 SFUNCTION(Poly_Persp1_Gouraud)
4873 /* compute a delta per segment */
4874 NLOOP(high)
4876 large=P2->W.x - P1->W.x; P1->W.large=large;
4878 if(large!=0)
4880 P1->L.dz=(P2->L.z - P1->L.z)/large;
4881 P1->L.dR=(P2->L.R - P1->L.R)/large;
4882 P1->L.dG=(P2->L.G - P1->L.G)/large;
4883 P1->L.dB=(P2->L.B - P1->L.B)/large;
4884 P1->L.dA=(P2->L.A - P1->L.A)/large;
4886 P1++,P2++;
4889 SC->Pix=SC->P1;
4890 SC->FunctionFill(SC);
4892 /*=============================================================*/
4893 void Poly_Persp1_Flat(struct SOFT3D_context *SC)
4895 register union pixel3D *P1=SC->P1;
4896 register union pixel3D *P2=SC->P2;
4897 register LONG high=SC->PolyHigh;
4898 register LONG n;
4899 register WORD large;
4901 SFUNCTION(Poly_Persp1_Flat)
4902 /* compute a delta per segment */
4903 NLOOP(high)
4905 large=P2->W.x - P1->W.x; P1->W.large=large;
4907 if(large!=0)
4909 P1->L.dz=(P2->L.z - P1->L.z)/large;
4911 P1++,P2++;
4914 SC->Pix=SC->P1;
4915 SC->FunctionFill(SC);
4917 /*=============================================================*/
4918 void Poly_Persp1_Tex_Gouraud_Fog(struct SOFT3D_context *SC)
4920 register union pixel3D *P1=SC->P1;
4921 register union pixel3D *P2=SC->P2;
4922 register LONG high=SC->PolyHigh;
4923 register LONG n;
4924 register WORD large;
4926 SFUNCTION(Poly_Persp1_Tex_Gouraud_Fog)
4927 /* compute a delta per segment */
4928 NLOOP(high)
4930 large=P2->W.x - P1->W.x; P1->W.large=large;
4932 if(large!=0)
4934 P1->L.dz=(P2->L.z - P1->L.z)/large;
4935 P1->L.du=(P2->L.u - P1->L.u)/large;
4936 P1->L.dv=(P2->L.v - P1->L.v)/large;
4937 P1->L.dR=(P2->L.R - P1->L.R)/large;
4938 P1->L.dG=(P2->L.G - P1->L.G)/large;
4939 P1->L.dB=(P2->L.B - P1->L.B)/large;
4940 P1->L.dA=(P2->L.A - P1->L.A)/large;
4941 P1->L.dF=(P2->L.F - P1->L.F)/large;
4942 P1->L.ddu=0;
4943 P1->L.ddv=0;
4945 P1++,P2++;
4948 SC->Pix=SC->P1;
4949 SelectMipMap(SC);
4950 SC->FunctionFill(SC);
4952 /*=============================================================*/
4953 void Poly_Persp2_Tex_Gouraud_Fog(struct SOFT3D_context *SC,union pixel3D *P1,union pixel3D *P2)
4955 register LONG high=SC->PolyHigh;
4956 register LONG n;
4957 register WORD large;
4959 SFUNCTION(Poly_Persp2_Tex_Gouraud_Fog)
4960 SC->Pix=P1;
4961 /* compute a delta per segment */
4962 NLOOP(high)
4964 large=P2->W.x - P1->W.x; P1->W.large=large;
4966 if(large!=0)
4968 P1->L.dz=(P2->L.z - P1->L.z)/large;
4969 P1->L.dR=(P2->L.R - P1->L.R)/large;
4970 P1->L.dG=(P2->L.G - P1->L.G)/large;
4971 P1->L.dB=(P2->L.B - P1->L.B)/large;
4972 P1->L.dA=(P2->L.A - P1->L.A)/large;
4973 P1->L.dF=(P2->L.F - P1->L.F)/large;
4974 DoDeltasUV(P1,P2);
4976 P1++,P2++;
4978 SelectMipMap(SC);
4979 SC->FunctionFill(SC);
4981 /*=============================================================*/
4982 void Poly_Persp2x2_Tex_Gouraud_Fog(struct SOFT3D_context *SC)
4984 /* V44: convert polygon to 2 polygons for better perspective emulation */
4985 register union pixel3D *P1=SC->P1;
4986 register union pixel3D *P2=SC->P2;
4987 register union pixel3D *PM=&SC->edgeM[P1->W.y];
4988 register LONG high=SC->PolyHigh;
4989 register LONG n;
4990 float u,v;
4992 SFUNCTION(Poly_Persp2x2_Tex_Gouraud_Fog)
4993 if(SC->PolyLarge<10)
4994 {Poly_Persp1_Tex_Gouraud_Fog(SC); return;}
4995 if(SC->PolyLarge<40)
4996 {Poly_Persp2_Tex_Gouraud_Fog(SC,SC->P1,SC->P2);return;}
4998 /* compute center point PM */
4999 NLOOP(high)
5001 PM->L.x=(P1->L.x + P2->L.x)/2;
5002 PM->L.z=(P1->L.z + P2->L.z)/2.0;
5003 PM->L.w=(P1->L.w + P2->L.w)/2.0;
5004 PM->L.R=(P1->L.R + P2->L.R)/2;
5005 PM->L.G=(P1->L.G + P2->L.G)/2;
5006 PM->L.B=(P1->L.B + P2->L.B)/2;
5007 PM->L.A=(P1->L.A + P2->L.A)/2;
5008 PM->L.F=(P1->L.F + P2->L.F)/2;
5010 if(PM->L.w==0.0) PM->L.w=0.00001;
5011 u= ( (P1->L.u*P1->L.w) + (P2->L.u*P2->L.w) ) /2.0 ;
5012 PM->L.u=(u/ PM->L.w);
5014 v= ( (P1->L.v*P1->L.w) + (P2->L.v*P2->L.w) ) /2.0 ;
5015 PM->L.v=(v/ PM->L.w);
5017 PM->W.large=P1->W.large/2;
5018 P1->W.large=P1->W.large - PM->W.large;
5020 P1++,P2++;PM++;
5023 P1=SC->P1;
5024 P2=SC->P2;
5025 PM=&SC->edgeM[P1->W.y];
5026 Poly_Persp2_Tex_Gouraud_Fog(SC,P1,PM);
5027 Poly_Persp2_Tex_Gouraud_Fog(SC,PM,P2);
5029 /*=============================================================*/
5030 void DrawSegmentPix(struct SOFT3D_context *SC,union pixel3D *P1,union pixel3D *P2)
5032 /* draw a simple horizontal line */
5033 register union pixel3D *temp;
5035 SFUNCTION(DrawSegmentPIX)
5036 /* Trouver point P1 et point P2 des deux points de cette ligne */
5037 if (P1->W.x > P2->W.x)
5038 SWAP(P1,P2);
5040 SC->P1=&(SC->edge1[P1->W.y]);
5041 COPYPIX(SC->P1,P1);
5042 SC->P2=&(SC->edge2[P2->W.y]);
5043 COPYPIX(SC->P2,P2);
5045 SC->PolyHigh=1;
5046 SC->FunctionPoly(SC);
5048 /*=============================================================*/
5049 void DrawLinePix(struct SOFT3D_context *SC)
5051 union pixel3D *P1=&SC->PolyPix[0];
5052 union pixel3D *P2=&SC->PolyPix[1];
5053 union pixel3D *temp;
5054 ULONG n,ordered;
5056 SFUNCTION(DrawLinePIX)
5057 /* Trouver point min et point max des deux points P1&P2 de cette ligne */
5058 if (P1->W.y > P2->W.y)
5059 {P2=&SC->PolyPix[0];P1=&SC->PolyPix[1];}
5061 ordered=P1->W.x < P2->W.x;
5062 if(ordered)
5063 n= P2->W.x - P1->W.x; /* normal case : fill from left to right */
5064 else
5065 n= P1->W.x - P2->W.x; /* other case ... */
5066 SC->PolyHigh = P2->W.y - P1->W.y;
5067 n = n + SC->PolyHigh;
5069 if(n==0)
5070 {DrawSimplePix(SC,P1);return;}
5072 if(SC->PolyHigh==0)
5073 {DrawSegmentPix(SC,P1,P2);return;}
5075 /* Store the 2 points in an edge (edge1) */
5076 SC->P1=&SC->edge1[P1->W.y]; /* draw edge from top(P1) to bottom (P2)*/
5077 SC->P2=&SC->edge1[P2->W.y];
5078 COPYPIX(SC->P1,P1);
5079 COPYPIX(SC->P2,P2);
5080 SC->FunctionEdge(SC);
5082 P1= SC->P1 ;
5083 P2= SC->P2 =&SC->edge2[P1->W.y]; /* get the two edges (P1 & P2) both from top*/
5085 if(ordered)
5087 NLOOP(SC->PolyHigh)
5089 COPYPIX(P2,&P1[1]);
5090 P2->W.x++; /* so avoid to have a segment with large=0 */
5091 P1++;
5092 P2++;
5094 COPYPIX(P2,P1); /* copy last point of line identically */
5096 else /* not ordered */
5098 NLOOP(SC->PolyHigh)
5100 COPYPIX(P2,&P1[1]);
5101 P1->W.x++; /* so avoid to have a segment with large=0 */
5102 P1++;
5103 P2++;
5105 COPYPIX(P2,P1); /* copy last point of line identically */
5106 SWAP(SC->P1,SC->P2); /* swap P1 & P2 */
5109 SC->PolyHigh++;
5110 SC->dmin=1024<<16;
5111 SC->FunctionPoly(SC);
5113 /*=============================================================*/
5114 void DrawPolyPix(struct SOFT3D_context *SC)
5116 register union pixel3D *P1=NULL;
5117 register union pixel3D *P2=NULL;
5118 register WORD Pnb=SC->PolyPnb;
5119 register WORD n;
5120 union pixel3D *Pxmin;
5121 union pixel3D *Pxmax;
5122 union pixel3D *Pymin;
5123 union pixel3D *Pymax;
5125 SFUNCTION(DrawPolyPix)
5126 SVAR(SC->PolyPnb)
5127 Pymin=Pymax=Pxmin=Pxmax=SC->PolyPix;
5128 SC->dmin=1024<<16;
5130 /* Polygon loop : draw all edges */
5131 NLOOP(Pnb)
5133 PrintPix(&SC->PolyPix[n]);
5134 P1 =&(SC->PolyPix[n]);
5135 P2 =&(SC->PolyPix[n+1]);
5136 if (n+1==Pnb)
5137 P2 =&(SC->PolyPix[0]);
5139 /* polygon size */
5140 if (P1->W.x < Pxmin->W.x) Pxmin=P1;
5141 if (P2->W.x < Pxmin->W.x) Pxmin=P2;
5142 if (Pxmax->W.x < P1->W.x ) Pxmax=P1;
5143 if (Pxmax->W.x < P2->W.x ) Pxmax=P2;
5145 /* do edge */
5146 if(P1->W.y != P2->W.y ) /* skip horizontal edges */
5148 /* if P1 up and P2 down */
5149 if (P1->W.y < P2->W.y)
5151 if (P1->W.y < Pymin->W.y) Pymin=P1;
5152 if (Pymax->W.y < P2->W.y ) Pymax=P2;
5153 SC->P1=&(SC->edge1[P1->W.y]);
5154 SC->P2=&(SC->edge1[P2->W.y]);
5155 COPYPIX(SC->P1,P1); /* store the two points in this edge */
5156 COPYPIX(SC->P2,P2);
5158 else
5160 /* if P2 up and P1 down */
5161 if (P2->W.y < Pymin->W.y) Pymin=P2;
5162 if (Pymax->W.y < P1->W.y ) Pymax=P1;
5163 SC->P1=&(SC->edge2[P2->W.y]);
5164 SC->P2=&(SC->edge2[P1->W.y]);
5165 COPYPIX(SC->P1,P2); /* store the two points in the other edge */
5166 COPYPIX(SC->P2,P1);
5168 /* draw this edge */
5169 SC->FunctionEdge(SC);
5172 /* all edges drawn */
5174 /* compute Poly sizes */
5175 SC->PolyLarge= Pxmax->W.x - Pxmin->W.x ;
5176 SC->PolyHigh = Pymax->W.y - Pymin->W.y ;
5178 /* if poly is only an horizontal line */
5179 if(SC->PolyHigh==0)
5181 DrawSegmentPix(SC,Pxmin,Pxmax);
5182 return;
5185 /* eliminate poly if PolyLarge = 0 */
5186 if(SC->PolyLarge==0)
5187 return;
5189 /* patch: for TheVague if last line of screen then dont crop it */
5190 if(Pymax->W.y==(SC->high-1))
5191 SC->PolyHigh++;
5193 /* Sort edges */
5194 n=(Pymin->W.y + Pymax->W.y)/2; /* central line */
5196 if (SC->edge1[n].L.x < SC->edge2[n].L.x)
5198 SC->P1=&(SC->edge1[Pymin->W.y]);
5199 SC->P2=&(SC->edge2[Pymin->W.y]);
5201 else
5203 SC->P1=&(SC->edge2[Pymin->W.y]);
5204 SC->P2=&(SC->edge1[Pymin->W.y]);
5207 SC->FunctionPoly(SC);
5209 SFUNCTION(-----------)
5211 /*==================================================================================*/
5212 void ChangeSoftFog(APTR sc,UBYTE FogMode,float FogZmin,float FogZmax,float FogDensity,APTR fogrgba)
5214 struct SOFT3D_context *SC=sc;
5215 register float d,z,f;
5216 register UWORD n;
5217 UBYTE A;
5218 UBYTE *FogRGBA=fogrgba;
5219 UBYTE *RGBA;
5221 #ifdef SLOWCPU
5222 register UBYTE *Mul8=SC->Mul8;
5223 register union oper3D Mul;
5224 Mul.L.Index=0;
5225 #endif
5227 #define CLAMP(X,MIN,MAX) ((X)<(MIN)?(MIN):((X)>(MAX)?(MAX):(X)))
5229 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
5230 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5231 SFUNCTION(ChangeSoftFog)
5232 if(Wazp3D->DebugSOFT3D.ON)
5234 SVAR(FogMode)
5235 SVARF(FogZmin)
5236 SVARF(FogZmax)
5237 SVARF(FogDensity)
5240 if(3<FogMode)
5241 return;
5243 if(FogZmin < MINZ ) FogZmin =MINZ;
5244 if(MAXZ <= FogZmax) FogZmax =MAXZ;
5246 SC->state.FogMode =FogMode;
5247 SC->state.FogZmin =FogZmin;
5248 SC->state.FogZmax =FogZmax;
5249 SC->state.FogDensity =FogDensity;
5250 COPYRGBA(SC->state.FogRGBA,FogRGBA);
5252 if(FogMode!=0)
5253 NLOOP(FOGSIZE)
5255 z=(((float)n)/((float)FOGSIZE));
5256 switch (FogMode)
5258 case 1:
5259 d = 1.0F / (FogZmax - FogZmin);
5260 f= (FogZmax - z) * d;
5261 break;
5262 case 2:
5263 d = -FogDensity;
5264 f= FEXP( d * z);
5265 break;
5266 case 3:
5267 d = -(FogDensity*FogDensity);
5268 f= FEXP( d * z*z );
5269 break;
5270 default:
5271 f=0.0;
5272 break;
5275 f=CLAMP(f,0.0F,1.0F);
5276 f=1.0-f; /* alpha for fog */
5277 A=(255.0*f);
5278 RGBA=(UBYTE *) &SC->FogRGBAs[n];
5279 MUL8(A,FogRGBA[0],RGBA[0])
5280 MUL8(A,FogRGBA[1],RGBA[1])
5281 MUL8(A,FogRGBA[2],RGBA[2])
5282 RGBA[3]=ONE-A; /* alpha for background */
5284 if(Wazp3D->DebugSOFT3D.ON) /* dont display all the fog values */
5285 if(n % 100 == 0)
5287 SVARF(f*100.0)
5288 SVAR(A)
5295 /*================================================================*/
5296 void DrawPolyP(struct SOFT3D_context *SC)
5298 union pixel3D *Pix=SC->PolyPix;
5299 struct point3D *P=SC->PolyP;
5300 struct point3D PolyMin;
5301 struct point3D PolyMax;
5302 WORD Pnb,n;
5303 BOOL FaceCCW;
5304 UBYTE ColorChange,ColorTransp,ColorWhite,FlatChange;
5306 #ifdef WAZP3DDEBUG
5307 if(Wazp3D->DebugSOFT3D.ON) Libprintf("DrawPolyP Pnb %ld \n",(ULONG)SC->PolyPnb);
5308 #endif
5311 if(SC->PolyPnb > MAXPOLY ) {SREM(Poly has too much Points!); return;}
5313 P=SC->PolyP;
5314 Pnb=SC->PolyPnb;
5316 PolyMin.x=PolyMax.x=P->x;
5317 PolyMin.y=PolyMax.y=P->y;
5318 PolyMin.z=PolyMax.z=P->z;
5319 PolyMin.u=PolyMax.u=P->u;
5320 PolyMin.v=PolyMax.v=P->v;
5322 NLOOP(Pnb)
5324 P->y=P->y+0.49; /* round to nearer pixel */
5325 P->x=P->x+0.49;
5327 if (P->x < PolyMin.x) PolyMin.x=P->x;
5328 if (PolyMax.x < P->x) PolyMax.x=P->x;
5329 if (P->y < PolyMin.y) PolyMin.y=P->y;
5330 if (PolyMax.y < P->y) PolyMax.y=P->y;
5331 if (P->z < PolyMin.z) PolyMin.z=P->z;
5332 if (PolyMax.z < P->z) PolyMax.z=P->z;
5334 if (P->u < PolyMin.u) PolyMin.u=P->u;
5335 if (PolyMax.u < P->u) PolyMax.u=P->u;
5336 if (P->v < PolyMin.v) PolyMin.v=P->v;
5337 if (PolyMax.v < P->v) PolyMax.v=P->v;
5340 P++;
5344 if(Wazp3D->QuakeMatrixPatch.ON)
5346 REM(adjusting u v )
5347 if(Wazp3D->DebugSOFT3D.ON) { SVARF(PolyMin.u) SVARF(PolyMin.v) }
5348 PolyMin.u=FFLOOR(PolyMin.u);
5349 PolyMin.v=FFLOOR(PolyMin.v);
5350 if(Wazp3D->DebugSOFT3D.ON) { SVARF(PolyMin.u) SVARF(PolyMin.v) }
5352 P=SC->PolyP;
5353 Pnb=SC->PolyPnb;
5354 NLOOP(Pnb)
5356 P->u=P->u - PolyMin.u;
5357 P->v=P->v - PolyMin.v;
5358 PrintP(P);
5359 P++;
5363 if(SC->PolyPnb == 2)
5364 ClipLine(SC);
5366 if(SC->PolyPnb > 2)
5367 ClipPoly(SC);
5369 if(SC->PolyPnb==0)
5370 {SREM( clipped away); return;}
5372 Pnb=SC->PolyPnb;
5373 P=SC->PolyP;
5375 if(Pnb>=3)
5377 FaceCCW= ((P[1].x - P[0].x)*(P[2].y - P[0].y)-(P[2].x - P[0].x)*(P[1].y - P[0].y) < 0.0); /* formula from TinyGL */
5379 if(SC->state.CullingMode==W3D_CCW)
5380 if(!FaceCCW)
5381 {SREM( hided face); return;}
5383 if(SC->state.CullingMode==W3D_CW)
5384 if(FaceCCW)
5385 {SREM( hided face); return;}
5388 FlatChange=FALSE;
5389 if(NOTSAMERGBA(SC->FlatRGBA,SC->PolyP->RGBA))
5390 {SREM(FlatRGBA changed); FlatChange=TRUE;}
5392 COPYRGBA(SC->FlatRGBA,SC->PolyP->RGBA); /* default: flat-color come from current points */
5393 if(Wazp3D->TexMode.ON==3) /* in this case use face center as flat color */
5394 if(Pnb>=3)
5395 UVtoRGBA(SC->state.ST,(P[0].u+P[1].u+P[2].u)/3.0,(P[0].v+P[1].v+P[2].v)/3.0,SC->FlatRGBA);
5397 ColorChange=FALSE;
5398 ColorTransp=FALSE;
5399 ColorWhite=FALSE;
5401 NLOOP(Pnb)
5405 if(Wazp3D->TexMode.ON==2)
5406 UVtoRGBA(SC->state.ST,P->u,P->v,P->RGBA);
5408 Pix->L.x = 0; /* erase low parts */
5409 Pix->L.y = 0;
5410 Pix->W.x = P->x;
5411 Pix->W.y = P->y;
5413 ZCONVERSION
5414 Pix->L.w = P->w;
5416 Pix->L.F = 0;
5417 Pix->W.F = P->z * (float)FOGSIZE ;
5419 if(P->z<MINZ) Pix->W.F=0;
5420 if(MAXZ<P->z) Pix->W.F=FOGSIZE-1;
5423 Pix->L.u = P->u * (256.0*65536.0); /* range UV to [0..256] + shift per 16 */
5424 Pix->L.v = P->v * (256.0*65536.0);
5426 Pix->W.R = P->RGBA[0];
5427 Pix->W.G = P->RGBA[1];
5428 Pix->W.B = P->RGBA[2];
5429 Pix->W.A = P->RGBA[3];
5431 if(NOTSAMERGBA(SC->PolyP->RGBA,P->RGBA)) /* if color truly change ==> do gouraud */
5432 {SREM(ColorChange);ColorChange=TRUE;}
5434 if(SC->PolyP->RGBA[3]!=P->RGBA[3]) /* if alpha change ==> do alpha */
5435 {SREM(ColorTransp:A changed);ColorTransp=TRUE;}
5437 if(Pix->W.x < SC->Pxmin) SC->Pxmin=Pix->W.x;
5438 if(SC->Pxmax < Pix->W.x) SC->Pxmax=Pix->W.x;
5439 if(Pix->W.y < SC->Pymin) SC->Pymin=Pix->W.y;
5440 if(SC->Pymax < Pix->W.y) SC->Pymax=Pix->W.y;
5441 if(ZVALUE < SC->Pzmin) SC->Pzmin=ZVALUE;
5442 if(SC->Pzmax < ZVALUE) SC->Pzmax=ZVALUE;
5444 Pix++;
5445 P++;
5448 if(SC->PolyP->RGBA[3]!=255) /* if not solid ==> do alpha */
5449 {SREM(ColorTransp:A not solid);ColorTransp=TRUE;}
5451 if(SC->FlatRGBA[0]==255)
5452 if(SC->FlatRGBA[1]==255)
5453 if(SC->FlatRGBA[2]==255)
5454 if(SC->FlatRGBA[3]==255)
5455 {SREM(ColorWhite);ColorWhite=TRUE;}
5458 /* This face is inside a linear Fog ? */
5459 if(SC->state.UseFog)
5460 if(SC->state.FogMode==1)
5462 if(PolyMax.z < SC->state.FogZmin) /* after start of fogging area ? */
5464 SREM(states changed:Fog)
5465 SC->state.UseFog =FALSE;
5466 SC->state.Changed =TRUE;
5468 #ifdef WAZP3DDEBUG
5469 if(Wazp3D->DebugSOFT3D.ON)
5471 Libprintf("LinearFog:UseFog%ld. FogZmin FogZmax PolyZmin PolyZmax:",(ULONG)SC->state.UseFog);
5472 pf(SC->state.FogZmin);pf(SC->state.FogZmax);pf(PolyMin.z);pf(PolyMax.z);
5473 Libprintf("\n");
5475 #endif
5478 if(SC->state.TexEnvMode!=W3D_REPLACE)
5479 if( (FlatChange) ou (SC->ColorChange!=ColorChange) ou (SC->ColorTransp!=ColorTransp) ou (SC->ColorWhite!=ColorWhite) )
5481 SREM(states changed:Color)
5482 SC->ColorChange =ColorChange;
5483 SC->ColorTransp =ColorTransp;
5484 SC->ColorWhite =ColorWhite;
5485 SC->state.Changed =TRUE;
5488 if(SC->state.Changed)
5490 SOFT3D_SetDrawFunctions(SC); /* draw functions still can change now if ColorChange ColorTransp UseFog just changed */
5491 SC->state.Changed=FALSE;
5494 switch(Pnb)
5496 case 1: DrawPointPix(SC); break;
5497 case 2: DrawLinePix(SC); break;
5498 default: DrawPolyPix(SC); break;
5502 /*=============================================================*/
5503 void DrawTriP(struct SOFT3D_context *SC,register struct point3D *A,register struct point3D *B,register struct point3D *C)
5505 COPYP(&(SC->PolyP[0]),A);
5506 COPYP(&(SC->PolyP[1]),B);
5507 COPYP(&(SC->PolyP[2]),C);
5508 SC->PolyPnb=3;
5509 DrawPolyP(SC);
5511 /*=============================================================*/
5512 void UVtoRGBA(struct SOFT3D_texture *ST,float u,float v,UBYTE *RGBA)
5514 register UBYTE *Tex8;
5515 UBYTE u8,v8;
5517 SREM(UVtoRGBA)
5518 if(ST==NULL) return;
5519 PrintST(ST);
5521 u8=u;
5522 v8=v;
5523 Tex8=ST->MMs[0].Tex8U[u8]+ST->MMs[0].Tex8V[v8];
5525 RGBA[0]=Tex8[0];
5526 RGBA[1]=Tex8[1];
5527 RGBA[2]=Tex8[2];
5528 RGBA[3]=255;
5529 if (ST->bits==32)
5530 RGBA[3]=Tex8[3];
5531 if(Wazp3D->DebugSOFT3D.ON) PrintRGBA((UBYTE *)RGBA);
5533 /*=============================================================*/
5534 #ifdef WAZP3DDEBUG
5535 /*=============================================================*/
5536 void TexturePlot(struct SOFT3D_texture *ST,UWORD x,UWORD y,UBYTE *ColorRGBA)
5538 UBYTE *RGB;
5539 ULONG offset;
5541 if(x<ST->large)
5542 if(y<ST->high )
5544 offset=(ST->large*y + x) * ST->bits / 8;
5545 RGB=&(ST->pt[offset]);
5546 RGB[0]=ColorRGBA[0];
5547 RGB[1]=ColorRGBA[1];
5548 RGB[2]=ColorRGBA[2];
5549 if(ST->bits==32)
5550 RGB[3]=ColorRGBA[3];
5553 /*=============================================================*/
5554 void TextureBorder(struct SOFT3D_texture *ST)
5556 UBYTE GreenRGBA[4]={0,255,0,255};
5557 UBYTE RedRGBA[4]={255,0,0,255};
5558 UWORD x,y;
5560 XLOOP(ST->large)
5562 TexturePlot(ST,x,0,RedRGBA);
5563 TexturePlot(ST,x,ST->high-1,RedRGBA);
5565 YLOOP(ST->high )
5567 TexturePlot(ST,0,y,GreenRGBA);
5568 TexturePlot(ST,ST->large-1,y,GreenRGBA);
5572 /*=============================================================*/
5573 void TexturePrint(struct SOFT3D_texture *ST,WORD x,WORD y,UBYTE *texte)
5575 UBYTE *F;
5576 UBYTE RGBA[4];
5577 UWORD m,n,c;
5578 UBYTE Bit[] = {128,64,32,16,8,4,2,1};
5579 #define FONTSIZE 8
5580 #define FONTLARGE (128/8)
5582 RGBA[3]=255;
5583 while(*texte!=0)
5585 c=*texte++;
5586 if(32<c) c=c-32; else c=0;
5587 F=&(font8x8[(c AND 15) + (c/16)*FONTLARGE*FONTSIZE]);
5588 MLOOP(FONTSIZE)
5590 NLOOP(FONTSIZE)
5592 RGBA[0]=RGBA[1]=RGBA[2]=0;
5593 if (F[0] AND Bit[n])
5594 RGBA[0]=RGBA[1]=RGBA[2]=255;
5595 TexturePlot(ST,x+n,y+m,RGBA);
5597 F+=FONTLARGE;
5599 x+=FONTSIZE;
5603 #endif
5604 /*================================================================*/
5605 void SOFT3D_DrawPrimitive(APTR sc,APTR p,ULONG Pnb,ULONG primitive)
5607 struct SOFT3D_context *SC=sc;
5608 struct point3D *P=p;
5609 WORD n,nb;
5610 WORD MaxPolyHack;
5611 BOOL DebugState;
5612 struct SOFT3D_texture *ST=SC->state.ST;
5614 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
5615 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5616 /* If it's debug-texture then activate debugger to debug the full polygon */
5617 DebugState=LibDebug;
5618 if(ST!=NULL)
5619 if(Wazp3D->DebugTexNumber.ON)
5620 if(ST->Tnum==DEBUGTNUM)
5622 LibDebug=TRUE;
5623 Libprintf("DrawPrimitive using DebugTexture %s===============\n",ST->name);
5624 NLOOP(Pnb)
5625 PrintP(&P[n]);
5628 #ifdef WAZP3DDEBUG
5629 if(Wazp3D->DebugSOFT3D.ON)
5631 Libprintf("SOFT3D_DrawPrimitive Pnb %ld (%ld)\n",(ULONG)Pnb,(ULONG)primitive);
5632 SVAR(ST)
5633 if(ST!=NULL) Libprintf(" %s\n",ST->name);
5635 #endif
5638 if(Wazp3D->DebugContext.ON) /* backdoor: for debugging = display all the scene as lines */
5639 primitive=W3D_PRIMITIVE_LINELOOP;
5641 if(!SC->UseHard)
5642 if(SC->Image8==NULL)
5643 { REM(Image is lost or freed: cant draw !!); return;} /* happen if SOFT3D_AllocImageBuffer() fail */
5645 SINFO(primitive,W3D_PRIMITIVE_TRIANGLES)
5646 SINFO(primitive,W3D_PRIMITIVE_TRIFAN)
5647 SINFO(primitive,W3D_PRIMITIVE_TRISTRIP)
5648 SINFO(primitive,W3D_PRIMITIVE_POINTS)
5649 SINFO(primitive,W3D_PRIMITIVE_LINES)
5650 SINFO(primitive,W3D_PRIMITIVE_LINELOOP)
5651 SINFO(primitive,W3D_PRIMITIVE_LINESTRIP)
5652 SINFO(primitive,W3D_PRIMITIVE_POLYGON)
5654 #ifdef USEOPENGL
5655 if(SC->UseHard) /* so dont use "soft" for drawing the primitive*/
5657 HARD3D_DrawPrimitive(&SC->HC,p,Pnb,primitive);
5658 LibDebug =DebugState;
5659 return;
5661 #endif
5662 #if defined(OS4COMPOSITING)
5663 if(SC->UseHard)
5665 COMP3D_DrawPrimitive(SC,p,Pnb,primitive);
5666 LibDebug =DebugState;
5667 return;
5669 #endif
5672 if(primitive==W3D_PRIMITIVE_TRIANGLES)
5674 nb=Pnb/3;
5675 NLOOP(nb)
5676 DrawTriP(SC,&P[3*n+0],&P[3*n+1],&P[3*n+2]);
5679 MaxPolyHack=0;
5680 if(Wazp3D->PolyMode.ON==1)
5681 MaxPolyHack=MAXPOLYHACK;
5683 if(Wazp3D->PolyMode.ON==2)
5684 MaxPolyHack=MAXPOLYHACK2;
5686 if(Pnb<=MaxPolyHack) /* a simple quad after a clipping in x y z can have now more than 4 points */
5688 if(primitive==W3D_PRIMITIVE_TRIFAN)
5689 primitive=W3D_PRIMITIVE_POLYGON;
5691 if(Wazp3D->PolyMode.ON!=2)
5692 if(primitive==W3D_PRIMITIVE_TRISTRIP)
5694 if(Pnb==3)
5696 COPYP(&(SC->PolyP[0]),&P[0]);
5697 COPYP(&(SC->PolyP[1]),&P[2]);
5698 COPYP(&(SC->PolyP[2]),&P[1]);
5701 if(Pnb==4)
5703 COPYP(&(SC->PolyP[0]),&P[0]);
5704 COPYP(&(SC->PolyP[1]),&P[2]);
5705 COPYP(&(SC->PolyP[2]),&P[3]);
5706 COPYP(&(SC->PolyP[3]),&P[1]);
5709 if(Pnb==5)
5711 COPYP(&(SC->PolyP[0]),&P[0]);
5712 COPYP(&(SC->PolyP[1]),&P[2]);
5713 COPYP(&(SC->PolyP[2]),&P[4]);
5714 COPYP(&(SC->PolyP[3]),&P[3]);
5715 COPYP(&(SC->PolyP[4]),&P[1]);
5718 if(Pnb==6)
5720 COPYP(&(SC->PolyP[0]),&P[0]);
5721 COPYP(&(SC->PolyP[1]),&P[2]);
5722 COPYP(&(SC->PolyP[2]),&P[4]);
5723 COPYP(&(SC->PolyP[3]),&P[5]);
5724 COPYP(&(SC->PolyP[4]),&P[3]);
5725 COPYP(&(SC->PolyP[5]),&P[1]);
5728 if(Pnb==7)
5730 COPYP(&(SC->PolyP[0]),&P[0]);
5731 COPYP(&(SC->PolyP[1]),&P[2]);
5732 COPYP(&(SC->PolyP[2]),&P[4]);
5733 COPYP(&(SC->PolyP[3]),&P[5]);
5734 COPYP(&(SC->PolyP[4]),&P[6]);
5735 COPYP(&(SC->PolyP[5]),&P[3]);
5736 COPYP(&(SC->PolyP[6]),&P[1]);
5739 SC->PolyPnb=Pnb;
5740 DrawPolyP(SC);
5741 goto DrawDone;
5745 if(primitive==W3D_PRIMITIVE_TRIFAN)
5747 for (n=2;n<Pnb;n++)
5748 DrawTriP(SC,&P[0],&P[n-1],&P[n]);
5749 goto DrawDone;
5752 if(primitive==W3D_PRIMITIVE_TRISTRIP)
5754 for (n=2;n<Pnb;n++)
5755 if (n&1) /* reverse vertex order */
5756 DrawTriP(SC,&P[n-1],&P[n-2],&P[n-0]);
5757 else
5758 DrawTriP(SC,&P[n-2],&P[n-1],&P[n-0]);
5759 goto DrawDone;
5762 if(primitive==W3D_PRIMITIVE_POINTS)
5764 NLOOP(Pnb)
5766 COPYP(&(SC->PolyP[0]),&P[n]);
5767 SC->PolyPnb=1;
5768 DrawPolyP(SC);
5770 goto DrawDone;
5774 if(primitive==W3D_PRIMITIVE_LINES)
5776 nb=Pnb/2;
5777 NLOOP(nb)
5779 COPYP(&(SC->PolyP[0]),&P[2*n]);
5780 COPYP(&(SC->PolyP[1]),&P[2*n+1]);
5781 SC->PolyPnb=2;
5782 DrawPolyP(SC);
5784 goto DrawDone;
5787 if(primitive==W3D_PRIMITIVE_LINELOOP)
5789 nb=Pnb-1;
5790 NLOOP(nb)
5792 COPYP(&(SC->PolyP[0]),&P[n]);
5793 COPYP(&(SC->PolyP[1]),&P[n+1]);
5794 SC->PolyPnb=2;
5795 DrawPolyP(SC);
5798 COPYP(&(SC->PolyP[0]),&P[nb]);
5799 COPYP(&(SC->PolyP[1]),&P[0 ]);
5800 SC->PolyPnb=2;
5801 DrawPolyP(SC);
5802 goto DrawDone;
5805 if(primitive==W3D_PRIMITIVE_LINESTRIP)
5807 nb=Pnb-1;
5808 NLOOP(nb)
5810 COPYP(&(SC->PolyP[0]),&P[n]);
5811 COPYP(&(SC->PolyP[1]),&P[n+1]);
5812 SC->PolyPnb=2;
5813 DrawPolyP(SC);
5815 goto DrawDone;
5818 if(primitive==W3D_PRIMITIVE_POLYGON )
5820 NLOOP(Pnb)
5822 COPYP(&(SC->PolyP[n]),&P[n]);
5824 SC->PolyPnb=Pnb;
5826 DrawPolyP(SC);
5829 DrawDone:
5830 LibDebug =DebugState;
5832 /*=============================================================*/
5833 void ChangeSoftPoint(APTR sc)
5835 struct SOFT3D_context *SC=sc;
5836 register WORD *PointLarge;
5837 register WORD x,y,D;
5839 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
5840 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5842 SFUNCTION(ChangeSoftPoint)
5843 PointLarge=SC->PointLarges;
5844 D=SC->state.PointSize;
5845 SVAR(SC->state.PointSize)
5846 YLOOP(D)
5847 XLOOP(D)
5848 if( ( (2*y-D)*(2*y-D) + 2*2*x*x) < D*D ) PointLarge[y]=x*2;
5850 /*==================================================================*/
5851 void *SOFT3D_CreateTexture(APTR sc,APTR pt,UWORD large,UWORD high,UWORD format,UBYTE TexFlags)
5853 struct SOFT3D_context *SC=sc;
5854 struct SOFT3D_texture *ST;
5855 UBYTE *Tex8V;
5856 UBYTE *ptmm;
5857 float TexelsPerU,TexelsPerV,nf;
5858 UWORD BytesPerTexel,BytesPerLine,n,m,bits;
5859 UBYTE BitmapName[40];
5860 ULONG Tsize,MMsize;
5861 UBYTE UseMip=TexFlags AND 1;
5863 #ifndef W3D_R8G8B8
5864 #define W3D_R8G8B8 4
5865 #define W3D_R8G8B8A8 11
5866 #endif
5868 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
5869 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5870 SFUNCTION(SOFT3D_CreateTexture)
5871 ST=MYmalloc(sizeof(struct SOFT3D_texture),"SOFT3D_texture");
5872 if(ST==NULL) return(NULL);
5874 if(format==W3D_R8G8B8) bits=24;
5875 if(format==W3D_R8G8B8A8) bits=32;
5877 ST->pt =pt;
5878 ST->large =large;
5879 ST->high =high;
5880 ST->bits =bits;
5881 ST->format =format;
5882 ST->TexFlags=TexFlags;
5883 /* add to linkage */
5884 ST->nextST =SC->firstST;
5885 SC->firstST=ST;
5886 ST->ptmm=NULL;
5888 /* Create texture index */
5889 BytesPerTexel=bits/8;
5890 BytesPerLine =ST->large*BytesPerTexel;
5892 TexelsPerU=((float)ST->large)/256.0;
5893 TexelsPerV=((float)ST->high )/256.0;
5894 Tex8V=ST->pt;
5896 Tsize=ST->large*ST->high*ST->bits/8;
5898 if(UseMip)
5899 CreateMipmaps(ST);
5901 ptmm=ST->ptmm;
5902 MMsize=MAXTEXTURE*MAXTEXTURE*ST->bits/8;
5903 MLOOP(NBMIPMAPS)
5905 NLOOP(256)
5907 nf=(float)n;
5908 ST->MMs[m].Tex8U[n]= (ULONG)( BytesPerTexel * (UWORD)(TexelsPerU*nf));
5909 ST->MMs[m].Tex8V[n]=Tex8V +(ULONG)( BytesPerLine * (UWORD)(TexelsPerV*nf));
5910 ST->MMs[m].Tex8Ulow[n]= (ULONG)( BytesPerTexel * (UWORD)(TexelsPerU*nf/256.0));
5911 ST->MMs[m].Tex8Vlow[n]= (ULONG)( BytesPerLine * (UWORD)(TexelsPerV*nf/256.0));
5912 if(TexelsPerU<=1.0)
5913 ST->MMs[m].Tex8Ulow[n]=0;
5914 if(TexelsPerV<=1.0)
5915 ST->MMs[m].Tex8Vlow[n]=0;
5918 if(UseMip)
5920 if(Tsize > MMsize) /* for smaller texture-models use mipmaps */
5922 Tex8V=ptmm;
5923 TexelsPerU=TexelsPerU/2.0;
5924 TexelsPerV=TexelsPerV/4.0;
5925 ptmm=ptmm+MMsize;
5927 MMsize=MMsize/4;
5932 SC->Tnb++; ST->Tnum=SC->Tnb;
5933 Libsprintf((char*)ST->name,(char*)"Texture%ld_%ldX%ldX%ld.RAW",(ULONG)ST->Tnum,(ULONG)ST->large,(ULONG)ST->high,(ULONG)ST->bits);
5934 Libsprintf((char*)BitmapName,(char*)"Tex%ld %ld",(ULONG)ST->Tnum,(ULONG)ST->bits);
5936 #ifdef WAZP3DDEBUG
5937 if(Wazp3D->DebugTexNumber.ON)
5939 TextureBorder(ST);
5940 TexturePrint(ST,0,ST->high/2,BitmapName);
5942 #endif
5944 #ifdef USEOPENGL
5945 if(ST!=NULL)
5946 if(SC->UseHard) HARD3D_CreateTexture(&SC->HC,&ST->HT,ST->pt,ST->large,ST->high,ST->format,ST->TexFlags);
5947 #endif
5949 #if defined(OS4COMPOSITING)
5950 if(SC->UseHard) COMP3D_CreateTexture(SC,ST,ST->pt,ST->large,ST->high,ST->format,ST->TexFlags);
5951 #endif
5953 #ifdef WAZP3DDEBUG
5954 if(Wazp3D->DebugSOFT3D.ON)
5955 Libprintf("Tex<%s> ST%ld HT%ld gltex%ld\n",ST->name,(IPTR)ST,(IPTR)&ST->HT,(ULONG)ST->HT.gltex);
5957 if(Wazp3D->DebugST.ON)
5958 if(Wazp3D->DebugSOFT3D.ON)
5959 LibAlert("Tex done...");
5960 #endif
5962 return( (void *) ST);
5964 /*==================================================================*/
5965 void SOFT3D_UpdateTexture(APTR sc,APTR st,APTR pt)
5967 struct SOFT3D_context *SC=sc;
5968 struct SOFT3D_texture *ST=st;
5969 UBYTE UseMip=ST->TexFlags AND 1;
5970 LONG Tsize;
5972 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
5973 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
5974 SFUNCTION(SOFT3D_UpdateTexture)
5975 if(st==NULL)
5976 {SREM(NULL ST!!); return;}
5977 Tsize=ST->large*ST->high*ST->bits/8;
5978 Libmemcpy(ST->pt,pt,Tsize);
5979 if(UseMip)
5980 CreateMipmaps(ST);
5982 #ifdef USEOPENGL
5983 if(SC->UseHard) HARD3D_UpdateTexture(&SC->HC,&ST->HT,pt,ST->large,ST->high,ST->bits);
5984 #endif
5985 #if defined(OS4COMPOSITING)
5986 if(SC->UseHard) COMP3D_UpdateTexture(SC,ST,pt,ST->large,ST->high,ST->bits);
5987 #endif
5989 /*==================================================================*/
5990 void SOFT3D_FreeTexture(APTR sc,APTR st)
5992 struct SOFT3D_context *SC=sc;
5993 struct SOFT3D_texture *ST=st;
5994 struct SOFT3D_texture fakeST;
5995 struct SOFT3D_texture *thisST=&fakeST;
5996 WORD Ntexture=0;
5998 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
5999 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
6000 SFUNCTION(SOFT3D_FreeTexture)
6001 if(st==NULL)
6002 {SREM(NULL ST!!); return;}
6004 PrintST(ST);
6005 thisST->nextST=SC->firstST;
6006 while(thisST!=NULL)
6008 VAL(Ntexture)
6009 if(thisST->nextST==ST)
6011 SREM(is ST found)
6012 if(thisST->nextST==SC->firstST)
6013 SC->firstST=ST->nextST;
6014 else
6015 thisST->nextST=ST->nextST;
6016 FREEPTR(ST->ptmm);
6017 break;
6019 thisST=thisST->nextST;
6020 Ntexture++;
6023 #ifdef USEOPENGL
6024 if(SC->UseHard) HARD3D_FreeTexture(&SC->HC,&ST->HT);
6025 #endif
6026 #if defined(OS4COMPOSITING)
6027 if(SC->UseHard) COMP3D_FreeTexture(SC,ST);
6028 #endif
6029 if(SC->state.ST==ST)
6030 SC->FragBufferDone =SC->FragBuffer; /* cant draw fragments from a deleted texture */
6032 /*=================================================================*/
6033 void ClipPoint(struct SOFT3D_context *SC,struct point3D *PN,struct point3D *P,float t)
6035 register float c0,c1;
6036 register float u0w,v0w,u1w,v1w;
6038 P->x= PN[0].x + t * (PN[1].x - PN[0].x) ;
6039 P->y= PN[0].y + t * (PN[1].y - PN[0].y) ;
6040 P->z= PN[0].z + t * (PN[1].z - PN[0].z) ;
6041 P->w= PN[0].w + t * (PN[1].w - PN[0].w) ;
6042 c0=PN[0].RGBA[0]; c1=PN[1].RGBA[0]; P->RGBA[0]=c0 + t * (c1 - c0);
6043 c0=PN[0].RGBA[1]; c1=PN[1].RGBA[1]; P->RGBA[1]=c0 + t * (c1 - c0);
6044 c0=PN[0].RGBA[2]; c1=PN[1].RGBA[2]; P->RGBA[2]=c0 + t * (c1 - c0);
6045 c0=PN[0].RGBA[3]; c1=PN[1].RGBA[3]; P->RGBA[3]=c0 + t * (c1 - c0);
6047 /* if want perspective then compute the new U V with a true-perspective */
6048 if(SC->state.PerspMode!=0)
6049 if(P->w!=0.0)
6051 u0w=PN[0].u*PN[0].w;
6052 v0w=PN[0].v*PN[0].w;
6053 u1w=PN[1].u*PN[1].w;
6054 v1w=PN[1].v*PN[1].w;
6055 P->u= (u0w + t * (u1w - u0w) )/P->w;
6056 P->v= (v0w + t * (v1w - v0w) )/P->w;
6057 return;
6060 /* else compute UV linearly as other coordinates */
6061 P->u= PN[0].u + t * (PN[1].u - PN[0].u) ;
6062 P->v= PN[0].v + t * (PN[1].v - PN[0].v) ;
6064 /*=================================================================*/
6065 #define CopyPoint(A) {COPYP(P,A); P++; NewPnb++; }
6066 #define SwapBuffers useT1=!useT1; if(useT1) {PN=T1; P=T2;} else {PN=T2; P=T1;}
6067 #define CLIPPOINT(val,limit) {ClipPoint(SC,PN,P,(limit - PN[0].val) / (PN[1].val - PN[0].val)); P->val=limit; }
6068 #define NEWCLIPPOINT(val,limit) {ClipPoint(SC,PN,P,(limit - PN[0].val) / (PN[1].val - PN[0].val)); P->val=limit; P++; NewPnb++; }
6069 /*=================================================================*/
6070 void ClipLine(struct SOFT3D_context *SC)
6072 struct point3D *PN=SC->PolyP;
6073 struct point3D *P; /* point to clip */
6074 register ULONG IsInside0;
6075 register ULONG IsInside1;
6077 IsInside0=(SC->ClipMin.x <= PN[0].x);
6078 IsInside1=(SC->ClipMin.x <= PN[1].x);
6079 if(!IsInside0) if(!IsInside1)
6080 { SC->PolyPnb=0; return; }
6081 if(IsInside0!=IsInside1)
6082 { if(IsInside0) P=&PN[1]; else P=&PN[0]; CLIPPOINT(x,SC->ClipMin.x); }
6084 IsInside0=(PN[0].x <= SC->ClipMax.x);
6085 IsInside1=(PN[1].x <= SC->ClipMax.x);
6086 if(!IsInside0) if(!IsInside1)
6087 { SC->PolyPnb=0; return; }
6088 if(IsInside0!=IsInside1)
6089 { if(IsInside0) P=&PN[1]; else P=&PN[0]; CLIPPOINT(x,SC->ClipMax.x); }
6091 IsInside0=(SC->ClipMin.y <= PN[0].y);
6092 IsInside1=(SC->ClipMin.y <= PN[1].y);
6093 if(!IsInside0) if(!IsInside1)
6094 { SC->PolyPnb=0; return; }
6095 if(IsInside0!=IsInside1)
6096 { if(IsInside0) P=&PN[1]; else P=&PN[0]; CLIPPOINT(y,SC->ClipMin.y); }
6098 IsInside0=(PN[0].y <= SC->ClipMax.y);
6099 IsInside1=(PN[1].y <= SC->ClipMax.y);
6100 if(!IsInside0) if(!IsInside1)
6101 { SC->PolyPnb=0; return; }
6102 if(IsInside0!=IsInside1)
6103 { if(IsInside0) P=&PN[1]; else P=&PN[0]; CLIPPOINT(y,SC->ClipMax.y); }
6105 return;
6107 /*=================================================================*/
6108 void ClipPoly(struct SOFT3D_context *SC)
6110 struct point3D *P;
6111 struct point3D *PN;
6112 struct point3D *T1=(struct point3D *)&SC->T1;
6113 struct point3D *T2=(struct point3D *)&SC->T2;
6114 BOOL useT1=TRUE;
6115 UBYTE IsInside[MAXPOLY];
6116 UBYTE InsidePnb;
6117 LONG Pnb=SC->PolyPnb;
6118 LONG n,NewPnb;
6119 BOOL FaceClipped;
6121 if(Wazp3D->DebugClipper.ON) REM(ClipPoly)
6122 if(Pnb>MAXPOLY) return;
6123 FaceClipped=FALSE;
6124 NewPnb=0;
6126 useT1=TRUE;
6127 PN=T1; P=T2;
6128 Libmemcpy(PN,SC->PolyP,Pnb*PSIZE);
6130 NewPnb=InsidePnb=0;
6131 NLOOP(Pnb)
6133 IsInside[n]=FALSE;
6134 if(PN[n].x <= SC->ClipMax.x)
6135 { IsInside[n]=TRUE; InsidePnb++; }
6138 if(InsidePnb==0) {if(Wazp3D->DebugClipper.ON) REM(Outside Max.x) goto HideFace;}
6140 if(InsidePnb!=Pnb)
6142 if(Wazp3D->DebugClipper.ON) REM(Clip Max.x)
6143 FaceClipped=TRUE; IsInside[Pnb]=IsInside[0]; COPYP(&(PN[Pnb]),PN);
6144 NLOOP(Pnb)
6146 if(IsInside[n]==TRUE)
6147 CopyPoint(PN);
6148 if(IsInside[n]!=IsInside[n+1])
6149 NEWCLIPPOINT(x,SC->ClipMax.x);
6151 PN++;
6153 Pnb=NewPnb;
6154 SwapBuffers
6156 /*=================================*/
6157 NewPnb=InsidePnb=0;
6158 NLOOP(Pnb)
6161 IsInside[n]=FALSE;
6162 if(SC->ClipMin.x <= PN[n].x)
6163 { IsInside[n]=TRUE; InsidePnb++; }
6166 if(InsidePnb==0) {if(Wazp3D->DebugClipper.ON) REM(Outside Min.x) goto HideFace;}
6168 if(InsidePnb!=Pnb)
6170 if(Wazp3D->DebugClipper.ON) REM(Clip Min.x)
6171 FaceClipped=TRUE; IsInside[Pnb]=IsInside[0]; COPYP(&(PN[Pnb]),PN);
6172 NLOOP(Pnb)
6174 if(IsInside[n]==TRUE)
6175 CopyPoint(PN);
6176 if(IsInside[n]!=IsInside[n+1])
6177 NEWCLIPPOINT(x,SC->ClipMin.x);
6178 PN++;
6180 Pnb=NewPnb;
6181 SwapBuffers
6183 /*=================================*/
6184 NewPnb=InsidePnb=0;
6185 NLOOP(Pnb)
6188 IsInside[n]=FALSE;
6189 if(PN[n].y <= SC->ClipMax.y)
6190 { IsInside[n]=TRUE; InsidePnb++; }
6193 if(InsidePnb==0) {if(Wazp3D->DebugClipper.ON) REM(Outside Max.y) goto HideFace;}
6195 if(InsidePnb!=Pnb)
6197 if(Wazp3D->DebugClipper.ON) REM(Clip Max.y)
6198 FaceClipped=TRUE; IsInside[Pnb]=IsInside[0]; COPYP(&(PN[Pnb]),PN);
6199 NLOOP(Pnb)
6201 if(IsInside[n]==TRUE)
6202 CopyPoint(PN);
6203 if(IsInside[n]!=IsInside[n+1])
6204 NEWCLIPPOINT(y,SC->ClipMax.y);
6205 PN++;
6207 Pnb=NewPnb;
6208 SwapBuffers
6210 /*=================================*/
6211 NewPnb=InsidePnb=0;
6212 NLOOP(Pnb)
6215 IsInside[n]=FALSE;
6216 if(SC->ClipMin.y <= PN[n].y)
6217 { IsInside[n]=TRUE; InsidePnb++; }
6220 if(InsidePnb==0) {if(Wazp3D->DebugClipper.ON) REM(Outside Min.y) goto HideFace;}
6222 if(InsidePnb!=Pnb)
6224 if(Wazp3D->DebugClipper.ON) REM(Clip Min.y)
6225 FaceClipped=TRUE; IsInside[Pnb]=IsInside[0]; COPYP(&(PN[Pnb]),PN);
6226 NLOOP(Pnb)
6228 if(IsInside[n]==TRUE)
6229 CopyPoint(PN);
6230 if(IsInside[n]!=IsInside[n+1])
6231 NEWCLIPPOINT(y,SC->ClipMin.y);
6232 PN++;
6234 Pnb=NewPnb;
6235 SwapBuffers
6237 /*=================================*/
6239 if(FaceClipped==FALSE) return;
6241 /* if clipped get the new PolyPnb & PolyP */
6243 if(useT1) PN=T1; else PN=T2;
6245 if(Wazp3D->DebugClipper.ON)
6247 SVARF(SC->ClipMin.x);
6248 SVARF(SC->ClipMax.x);
6249 SVARF(SC->ClipMin.y);
6250 SVARF(SC->ClipMax.y);
6251 SVARF(SC->ClipMin.z);
6252 SVARF(SC->ClipMax.z);
6254 if(SC->state.ST!=NULL)
6255 PrintST(SC->state.ST);
6257 Wazp3D->DebugPoint.ON=TRUE;
6258 REM(CLIPPER: original points)
6259 NLOOP(SC->PolyPnb)
6260 PrintP(&SC->PolyP[n]);
6261 REM(-------: clipped points)
6262 NLOOP(Pnb)
6263 PrintP2(&PN[n]);
6264 REM(=======================)
6265 Wazp3D->DebugPoint.ON=FALSE;
6267 SC->PolyPnb=Pnb;
6268 Libmemcpy(SC->PolyP,PN,SC->PolyPnb*PSIZE);
6269 return;
6270 HideFace:
6271 SC->PolyPnb=0;
6272 return;
6274 /*=================================================================*/
6275 void ReduceBitmap(UBYTE *pt,UBYTE *pt2,UWORD large,UWORD high, WORD bits,WORD ratio)
6277 UBYTE *RGB2;
6278 UBYTE *RGB1;
6279 LONG P,L; /* bytesperpixel, bytesperline */
6280 LONG x,y,m,n;
6281 LONG r,g,b,a;
6282 LONG ratio2;
6283 LONG offset;
6285 #ifdef WAZP3DDEBUG
6286 if(Wazp3D->DebugSOFT3D.ON) Libprintf("ReduceBitmap/%ld %ldX%ld %ldbits >from %ld to %ld\n",(ULONG)ratio,(ULONG)large,(ULONG)high,(ULONG)bits,(IPTR)pt,(IPTR)pt2);
6287 #endif
6288 if(pt ==NULL) return;
6289 if(pt2==NULL) return;
6290 L=large * bits /8;
6291 P=bits /8;
6292 large=large/ratio;
6293 high =high /ratio;
6294 ratio2=ratio*ratio;
6296 RGB1=pt;
6297 RGB2=pt2;
6299 YLOOP(high)
6301 XLOOP(large)
6303 r=g=b=a=0;
6304 MLOOP(ratio)
6305 NLOOP(ratio)
6307 offset=L*m+P*n+L*ratio*y+P*ratio*x;
6308 RGB1=&(pt[offset]);
6309 r=r+(LONG)RGB1[0];
6310 g=g+(LONG)RGB1[1];
6311 b=b+(LONG)RGB1[2];
6312 if(bits==32)
6313 a=a+(LONG)RGB1[3];
6315 r=r/ratio2;
6316 g=g/ratio2;
6317 b=b/ratio2;
6318 a=a/ratio2;
6319 RGB2[0]=r;
6320 RGB2[1]=g;
6321 RGB2[2]=b;
6323 if(Wazp3D->DebugFunction.ON)
6324 RGB2[1]=255/ratio;
6326 if(bits==32)
6327 RGB2[3]=a;
6328 RGB2=&(RGB2[P]);
6333 /*==================================================================================*/
6334 void CreateMipmaps(struct SOFT3D_texture *ST)
6336 UBYTE *ptmm;
6337 UWORD large,high,level,reduction;
6338 ULONG size;
6341 large=ST->large;
6342 high =ST->high;
6343 size =ST->large * ST->high * ST->bits / 8;
6344 ST->ptmm=MYmalloc(size/3,"mipmaps"); /* size is mathematically false but allways fit */
6345 if(ST->ptmm==NULL) return;
6346 ptmm=ST->ptmm;
6348 level=0;
6349 reduction=2;
6350 next_mipmap:
6351 #ifdef WAZP3DDEBUG
6352 if(Wazp3D->DebugSOFT3D.ON) Libprintf("MipMap %ldX%ld = %ld (%ld)\n",(ULONG)large,(ULONG)high,(ULONG)size,(IPTR)ptmm);
6353 #endif
6354 ReduceBitmap(ST->pt,ptmm,ST->large,ST->high,ST->bits,reduction);
6355 level++;
6356 large=large/2;
6357 high =high /2;
6358 size =size /4;
6359 reduction=reduction*2;
6360 ptmm=ptmm+size;
6361 if (high>0) goto next_mipmap;
6363 /*==========================================================================*/
6364 void AntiAliasImage(void *image,UWORD large,UWORD high)
6366 UBYTE AliasedLines[4*MAXSCREEN*2];
6367 register UWORD r,g,b,x,y;
6368 register UBYTE *L0=(UBYTE *)image;
6369 register UBYTE *L1;
6370 register UBYTE *L2;
6371 register UBYTE *line0;
6372 register UBYTE *line1;
6373 UBYTE *temp;
6374 #define B32 4
6376 if (large>MAXSCREEN) return;
6377 line0=(UBYTE *) &AliasedLines[B32*MAXSCREEN*0];
6378 line1=(UBYTE *) &AliasedLines[B32*MAXSCREEN*1];
6379 L1=L0+large*B32;
6380 L2=L1+large*B32;
6381 large=large-2;
6382 high =high -2;
6384 XLOOP(large)
6386 line0[0+B32]=L0[0+B32];
6387 line0[1+B32]=L0[1+B32];
6388 line0[2+B32]=L0[2+B32];
6389 line0+=B32;
6390 L0+=B32;
6392 line1=(UBYTE *)&AliasedLines[B32*MAXSCREEN*1];
6393 L0=(UBYTE *)image;
6395 YLOOP(high)
6397 line0=(UBYTE *) &AliasedLines[B32*MAXSCREEN*0];
6398 line1=(UBYTE *) &AliasedLines[B32*MAXSCREEN*1];
6399 if(y&1)
6400 SWAP(line0,line1)
6401 XLOOP(large)
6403 r=L1[0+B32]; r=r+r; r=r+r; r=r+r;
6404 g=L1[1+B32]; g=g+g; g=g+g; g=g+g;
6405 b=L1[2+B32]; b=b+b; b=b+b; b=b+b;
6406 r=r+L0[0+0]+L0[0+B32]+L0[0+B32*2]+L1[0+0]+L1[0+B32*2]+L2[0+0]+L2[0+B32]+L2[0+B32*2];
6407 g=g+L0[1+0]+L0[1+B32]+L0[1+B32*2]+L1[1+0]+L1[1+B32*2]+L2[1+0]+L2[1+B32]+L2[1+B32*2];
6408 b=b+L0[2+0]+L0[2+B32]+L0[2+B32*2]+L1[2+0]+L1[2+B32*2]+L2[2+0]+L2[2+B32]+L2[2+B32*2];
6410 line1[0+B32]=r>>4;
6411 line1[1+B32]=g>>4;
6412 line1[2+B32]=b>>4;
6414 L0[0+B32]=line0[0+B32];
6415 L0[1+B32]=line0[1+B32];
6416 L0[2+B32]=line0[2+B32];
6418 line0+=B32;
6419 line1+=B32;
6420 L0+=B32;
6421 L1+=B32;
6422 L2+=B32;
6425 L0+=B32*2;
6426 L1+=B32*2;
6427 L2+=B32*2;
6430 /*==========================================================================*/
6431 UBYTE SOFT3D_DoUpdate(APTR sc)
6433 struct SOFT3D_context *SC=sc;
6435 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
6436 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
6437 SFUNCTION(SOFT3D_DoUpdate)
6439 #ifdef USEOPENGL
6440 if(SC->UseHard)
6442 if(Wazp3D->StepUpdate.ON)
6443 LibAlert("Update will occurs now !!");
6444 HARD3D_DoUpdate(&SC->HC);
6445 if(Wazp3D->UseClearImage.ON)
6446 if(SC->UseHard) HARD3D_ClearImageBuffer(&SC->HC,0,0,SC->large,SC->high,SC->state.BackRGBA);
6447 return(TRUE);
6449 #endif
6453 /* check is something new has been drawn ==> update */
6454 if(SC->Pxmax==0) return(FALSE);
6455 if(SC->Pymax==0) return(FALSE);
6457 if(!SC->UseHard)
6459 if(SC->Image8==NULL) return(FALSE);
6460 SOFT3D_Flush(SC);
6463 if(Wazp3D->StepUpdate.ON)
6464 LibAlert("Update will occurs now !!");
6466 if(SC->ImageBuffer32!=NULL)
6468 SREM(Got an ImageBuffer32)
6469 SREM(MinUpdate)
6470 if(Wazp3D->UseMinUpdate.ON)
6472 SC->xUpdate =SC->Pxmin; /* should also be used to clear the previous drawing */
6473 SC->yUpdate =SC->Pymin;
6474 SC->largeUpdate =SC->Pxmax-SC->Pxmin+1;
6475 SC->highUpdate =SC->Pymax-SC->Pymin+1;
6477 else
6480 SC->xUpdate =0;
6481 SC->yUpdate =0;
6482 SC->largeUpdate =SC->large;
6483 SC->highUpdate =SC->high;
6486 #ifdef WAZP3DDEBUG
6487 if(Wazp3D->DebugSOFT3D.ON)
6488 Libprintf("Updated Region from %ld %ld (%ld X %ld pixels) \n",(ULONG)SC->xUpdate,(ULONG)SC->yUpdate,(ULONG)SC->largeUpdate,(ULONG)SC->highUpdate);
6489 #endif
6490 SVARF(SC->Pzmin)
6491 SVARF(SC->Pzmax)
6493 SREM(UseAntiImage)
6494 if(Wazp3D->UseAntiImage.ON)
6495 AntiAliasImage(SC->ImageBuffer32,SC->large,SC->high);
6497 SREM(WriteImageBuffer)
6498 if(0<SC->largeUpdate)
6499 if(SC->largeUpdate<=SC->large)
6500 if(0< SC->highUpdate)
6501 if(SC->highUpdate <=SC->high)
6503 SVAR(SC->xUpdate)
6504 SVAR(SC->yUpdate)
6505 SVAR(SC->largeUpdate)
6506 SVAR(SC->highUpdate)
6507 SC->FunctionWriteImageBuffer(SC); /* Do in fact WritePixelArray(ImageBuffer32) to rastport */
6508 if(Wazp3D->UseClearImage.ON)
6509 SOFT3D_ClearImageBuffer(SC,0,0,SC->large,SC->high,SC->state.BackRGBA);
6513 SC->Pxmin=SC->large-1;
6514 SC->Pymin=SC->high -1;
6515 SC->Pzmin= 1000.0;
6516 SC->Pxmax=0;
6517 SC->Pymax=0;
6518 SC->Pzmax=-1000.0;
6520 return(TRUE);
6522 /*==========================================================================*/
6523 void SetDefaults(struct SOFT3D_context *SC)
6525 /* Set SOFT3D default values : notex nofog nozbuffer just white color */
6526 struct state3D defaultstate;
6527 UBYTE WhiteRGBA[4]={255,255,255,255};
6528 UBYTE BlackRGBA[4]={0,0,0,255};
6530 SREM(SetDefaults)
6531 defaultstate.ZMode=ZMODE(0,W3D_Z_ALWAYS);
6532 defaultstate.BlendMode=BLENDREPLACE;
6533 defaultstate.UseGouraud=FALSE;
6534 defaultstate.TexEnvMode=0;
6535 defaultstate.PerspMode=0;
6536 defaultstate.CullingMode=W3D_NOW;
6538 COPYRGBA(defaultstate.FogRGBA,WhiteRGBA); /* default white fog */
6539 COPYRGBA(defaultstate.CurrentRGBA,WhiteRGBA); /* default white color */
6540 COPYRGBA(defaultstate.EnvRGBA,WhiteRGBA); /* default white env-color */
6541 COPYRGBA(defaultstate.BackRGBA,BlackRGBA); /* default black background */
6543 defaultstate.PointSize=1;
6544 defaultstate.LineSize =1;
6546 defaultstate.UseFog=FALSE;
6547 defaultstate.FogMode=0;
6548 defaultstate.FogZmin=MINZ;
6549 defaultstate.FogZmax=MAXZ;
6550 defaultstate.FogDensity=0.0;
6552 defaultstate.UseTex=FALSE;
6553 defaultstate.ST=NULL;
6554 defaultstate.Changed=TRUE;
6556 SOFT3D_SetDrawState(SC,&defaultstate);
6558 /*==========================================================================*/
6559 void SOFT3D_SetBitmap(APTR sc,void *bm,APTR bmdata,ULONG bmformat,UWORD x,UWORD y,UWORD large,UWORD high)
6561 #if !defined(PIXFMT_ABGR32)
6562 #define PIXFMT_ABGR32 100
6563 #define PIXFMT_0RGB32 101
6564 #define PIXFMT_BGR032 102
6565 #define PIXFMT_RGB032 103
6566 #define PIXFMT_0BGR32 104
6567 #endif
6569 struct SOFT3D_context *SC=sc;
6570 UBYTE *RGBA;
6571 ULONG Rbits,Gbits,Bbits;
6572 ULONG Rpos,Gpos,Bpos;
6573 ULONG Rlostbits,Glostbits,Blostbits;
6574 UWORD W,B0,B1;
6575 ULONG n;
6576 BOOL PcOrder,ChangeOrder;
6577 ULONG temp;
6578 WORD bits;
6579 BOOL started;
6582 if(!Wazp3D->PrefsIsOpened) /* if the user dont changing debug states */
6583 LibDebug=Wazp3D->DebugWazp3D.ON; /* synchronize soft3d's LibDebug with global debug value "DebugWazp3D" setted with Wazp3-Prefs */
6584 if(SC==NULL) return;
6585 SFUNCTION(SOFT3D_SetBitmap)
6586 SVAR(bm)
6587 SVAR(bmdata)
6588 SVAR(bmformat)
6590 started=(SC->Image8!=NULL);
6591 #ifdef AMIGA
6592 SC->bm=bm;
6593 SC->rastport.BitMap=bm;
6594 #endif
6595 SC->yoffset=y; /* only stored for WritePixelArray() */
6597 if(SC->ImageBuffer32!=NULL)
6599 SREM(SetImage to ImageBuffer32)
6600 SC->bmformat=PIXFMT_RGBA32;
6601 SC->FunctionBitmapIn =NULL; /* no need to read/write a bitmap in this case */
6602 SC->FunctionBitmapOut=NULL;
6603 SetImage(SC,0,0,large,high,32,(UBYTE *)SC->ImageBuffer32);
6604 return;
6607 if(SC->bits!=0)
6608 if(SC->bmformat==bmformat)
6609 {bits=SC->bits; goto setimageonly;}
6611 SC->bmformat=bmformat;
6613 /* Define the Pixels In/Out functions for this bitmap format */
6614 SREM(Bitmap format changed)
6615 Rbits=Gbits=Bbits=Rpos=Gpos=Bpos=bits=0;
6616 PcOrder=FALSE;
6618 switch (bmformat)
6620 case PIXFMT_BGRA32:
6621 case PIXFMT_BGR032:
6622 SC->FunctionBitmapIn =(HOOKEDFUNCTION)PixelsInBGRA;
6623 SC->FunctionBitmapOut=(HOOKEDFUNCTION)PixelsOutBGRA;
6624 Rbits=8; Gbits=8; Bbits=8;
6625 Rpos=8; Gpos= 16; Bpos= 24;
6626 bits=32;
6627 PcOrder=FALSE;
6628 break;
6629 case PIXFMT_RGBA32:
6630 case PIXFMT_RGB032:
6631 SC->FunctionBitmapIn =(HOOKEDFUNCTION)PixelsInRGBA;
6632 SC->FunctionBitmapOut=(HOOKEDFUNCTION)PixelsOutRGBA;
6633 Rbits=8; Gbits=8; Bbits=8;
6634 Rpos=24; Gpos= 16; Bpos= 8;
6635 bits=32;
6636 PcOrder=FALSE;
6637 break;
6638 case PIXFMT_ARGB32:
6639 case PIXFMT_0RGB32:
6640 SC->FunctionBitmapIn =(HOOKEDFUNCTION)PixelsInARGB;
6641 SC->FunctionBitmapOut=(HOOKEDFUNCTION)PixelsOutARGB;
6642 Rbits=8; Gbits=8; Bbits=8;
6643 Rpos=16; Gpos= 8; Bpos= 0;
6644 bits=32;
6645 PcOrder=FALSE;
6646 break;
6647 case PIXFMT_ABGR32:
6648 case PIXFMT_0BGR32:
6649 SC->FunctionBitmapIn =(HOOKEDFUNCTION)PixelsInABGR;
6650 SC->FunctionBitmapOut=(HOOKEDFUNCTION)PixelsOutABGR;
6651 Rbits=8; Gbits=8; Bbits=8;
6652 Rpos=0; Gpos= 8; Bpos=16;
6653 bits=32;
6654 PcOrder=FALSE;
6655 break;
6657 case PIXFMT_RGB24:
6658 SC->FunctionBitmapIn =(HOOKEDFUNCTION)PixelsInRGB;
6659 SC->FunctionBitmapOut=(HOOKEDFUNCTION)PixelsOutRGB;
6660 Rbits=8; Gbits=8; Bbits=8;
6661 Rpos=16; Gpos= 8; Bpos= 0;
6662 bits=24;
6663 PcOrder=FALSE;
6664 break;
6665 case PIXFMT_BGR24:
6666 SC->FunctionBitmapIn =(HOOKEDFUNCTION)PixelsInBGR;
6667 SC->FunctionBitmapOut=(HOOKEDFUNCTION)PixelsOutBGR;
6668 Rbits=8; Gbits=8; Bbits=8;
6669 Rpos=0; Gpos= 8; Bpos= 16;
6670 bits=24;
6671 PcOrder=FALSE;
6672 break;
6674 case PIXFMT_RGB15:
6675 Rbits=5; Gbits=5; Bbits=5;
6676 Rpos=10; Gpos= 5; Bpos= 0;
6677 bits=16;
6678 PcOrder=FALSE;
6679 break;
6680 case PIXFMT_RGB16:
6681 Rbits=5; Gbits=6; Bbits=5;
6682 Rpos=11; Gpos= 5; Bpos= 0;
6683 bits=16;
6684 PcOrder=FALSE;
6685 break;
6686 case PIXFMT_BGR15:
6687 Rbits=5; Gbits=5; Bbits=5;
6688 Bpos=10; Gpos= 5; Rpos= 0;
6689 bits=16;
6690 PcOrder=FALSE;
6691 break;
6692 case PIXFMT_BGR16:
6693 Rbits=5; Gbits=6; Bbits=5;
6694 Bpos=11; Gpos= 5; Rpos= 0;
6695 bits=16;
6696 PcOrder=FALSE;
6697 break;
6699 case PIXFMT_RGB15PC:
6700 Rbits=5; Gbits=5; Bbits=5;
6701 Rpos=10; Gpos= 5; Bpos= 0;
6702 bits=16;
6703 PcOrder=TRUE;
6704 break;
6705 case PIXFMT_RGB16PC:
6706 Rbits=5; Gbits=6; Bbits=5;
6707 Rpos=11; Gpos= 5; Bpos= 0;
6708 bits=16;
6709 PcOrder=TRUE;
6710 break;
6711 case PIXFMT_BGR15PC:
6712 Rbits=5; Gbits=5; Bbits=5;
6713 Bpos=10; Gpos= 5; Rpos= 0;
6714 bits=16;
6715 PcOrder=TRUE;
6716 break;
6717 case PIXFMT_BGR16PC:
6718 Rbits=5; Gbits=6; Bbits=5;
6719 Bpos=11; Gpos= 5; Rpos= 0;
6720 bits=16;
6721 PcOrder=TRUE;
6722 break;
6724 case PIXFMT_LUT8:
6725 Rbits=3; Gbits=3; Bbits=2;
6726 Rpos=5; Gpos= 2; Bpos= 0;
6727 bits=8;
6728 PcOrder=FALSE;
6729 SC->FunctionBitmapIn =(HOOKEDFUNCTION)PixelsIn8;
6730 SC->FunctionBitmapOut=(HOOKEDFUNCTION)PixelsOut8;
6731 break;
6733 default:
6734 Libprintf("WAZP3D/SOFT3D: Unknown bitmap format %ld (%ld X %ld)\n",bmformat,large,high);
6735 return;
6738 SVAR(bmformat)
6739 SVAR(bits)
6742 if(bits<=16)
6744 SVAR(Rbits)
6745 SVAR(Gbits)
6746 SVAR(Bbits)
6747 SVAR(Rpos)
6748 SVAR(Gpos)
6749 SVAR(Bpos)
6750 if(bits==16)
6752 SC->FunctionBitmapIn =(HOOKEDFUNCTION)PixelsIn16;
6753 SC->FunctionBitmapOut=(HOOKEDFUNCTION)PixelsOut16;
6756 ChangeOrder= PcOrder; /* if cpu is motorola need to change pc's pixel-formats */
6757 SVAR(ChangeOrder)
6760 /* do the precalculated tables to convert 8/15/16 bits <-> 32bits */
6761 Rlostbits=8-Rbits;
6762 Glostbits=8-Gbits;
6763 Blostbits=8-Bbits;
6765 NLOOP(256)
6767 W=((n>>Rlostbits)<<Rpos);
6768 SC->RtoB0[n]=W>>8;
6769 SC->RtoB1[n]=W;
6770 W=((n>>Glostbits)<<Gpos);
6771 SC->GtoB0[n]=W>>8;
6772 SC->GtoB1[n]=W;
6773 W=((n>>Blostbits)<<Bpos);
6774 SC->BtoB0[n]=W>>8;
6775 SC->BtoB1[n]=W;
6777 B0=n<<8; B1=n;
6779 RGBA=(UBYTE *) &(SC->B0toRGBA32[n]) ;
6780 RGBA[0]=((B0>>Rpos)<<Rlostbits);
6781 RGBA[1]=((B0>>Gpos)<<Glostbits);
6782 RGBA[2]=((B0>>Bpos)<<Blostbits);
6783 RGBA[3]=255;
6785 RGBA=(UBYTE *) &(SC->B1toRGBA32[n]) ;
6786 RGBA[0]=((B1>>Rpos)<<Rlostbits);
6787 RGBA[1]=((B1>>Gpos)<<Glostbits);
6788 RGBA[2]=((B1>>Bpos)<<Blostbits);
6789 RGBA[3]=255;
6791 if(ChangeOrder)
6793 SWAP(SC->RtoB0[n],SC->RtoB1[n])
6794 SWAP(SC->GtoB0[n],SC->GtoB1[n])
6795 SWAP(SC->BtoB0[n],SC->BtoB1[n])
6796 SWAP(SC->B0toRGBA32[n],SC->B1toRGBA32[n])
6802 setimageonly:
6803 SREM(SetImage to bitmap data)
6804 SetImage(SC,x,y,large,high,bits,bmdata);
6806 #ifdef USEOPENGL
6807 SVAR(SC->Image8)
6808 if(SC->UseHard) HARD3D_SetBitmap(&SC->HC,bm,SC->Image8,bmformat,0,0,large,high);
6809 #endif
6810 if(!started)
6811 SetDefaults(SC);
6813 /*=============================================================*/
6814 void PixelsIn16(struct SOFT3D_context *SC)
6816 /* Convert 16bits -> buffer */
6817 register struct fragbuffer3D *Frag=SC->FragBuffer;
6818 register ULONG size=SC->FragSize2;
6819 register ULONG *B0toRGBA32=(ULONG *)SC->B0toRGBA32;
6820 register ULONG *B1toRGBA32=(ULONG *)SC->B1toRGBA32;
6821 register ULONG *RGBA32;
6823 while(0<size--)
6825 RGBA32=(ULONG *)Frag[0].BufferRGBA;
6826 RGBA32[0]=B0toRGBA32[Frag[0].Image8[0]]+B1toRGBA32[Frag[0].Image8[1]];
6828 RGBA32=(ULONG *)Frag[1].BufferRGBA;
6829 RGBA32[0]=B0toRGBA32[Frag[1].Image8[0]]+B1toRGBA32[Frag[1].Image8[1]];
6830 Frag+=2;
6834 /*=============================================================*/
6835 void PixelsOut16(struct SOFT3D_context *SC)
6837 /* Convert buffer -> 16bits */
6838 register struct fragbuffer3D *Frag=SC->FragBuffer;
6839 register ULONG size=SC->FragSize2;
6840 register UBYTE *RGB;
6841 register UBYTE *RtoB0=SC->RtoB0;
6842 register UBYTE *GtoB0=SC->GtoB0;
6843 register UBYTE *BtoB0=SC->BtoB0;
6844 register UBYTE *RtoB1=SC->RtoB1;
6845 register UBYTE *GtoB1=SC->GtoB1;
6846 register UBYTE *BtoB1=SC->BtoB1;
6848 while(0<size--)
6850 RGB=Frag[0].BufferRGBA;
6851 Frag[0].Image8[0]=RtoB0[RGB[0]]+GtoB0[RGB[1]]+BtoB0[RGB[2]];
6852 Frag[0].Image8[1]=RtoB1[RGB[0]]+GtoB1[RGB[1]]+BtoB1[RGB[2]];
6853 RGB=Frag[1].BufferRGBA;
6854 Frag[1].Image8[0]=RtoB0[RGB[0]]+GtoB0[RGB[1]]+BtoB0[RGB[2]];
6855 Frag[1].Image8[1]=RtoB1[RGB[0]]+GtoB1[RGB[1]]+BtoB1[RGB[2]];
6856 Frag+=2;
6860 /*=============================================================*/
6861 void PixelsIn8(struct SOFT3D_context *SC)
6863 /* Convert 8bits -> buffer */
6864 register struct fragbuffer3D *Frag=SC->FragBuffer;
6865 register ULONG size=SC->FragSize2;
6866 register ULONG *B0toRGBA32=(ULONG *)SC->B0toRGBA32;
6867 register ULONG *RGBA32;
6869 while(0<size--)
6871 RGBA32=(ULONG *)Frag[0].BufferRGBA;
6872 RGBA32[0]=B0toRGBA32[Frag[0].Image8[0]];
6874 RGBA32=(ULONG *)Frag[1].BufferRGBA;
6875 RGBA32[0]=B0toRGBA32[Frag[1].Image8[0]];
6876 Frag+=2;
6880 /*=============================================================*/
6881 void PixelsOut8(struct SOFT3D_context *SC)
6883 /* Convert buffer -> 8bits */
6884 register struct fragbuffer3D *Frag=SC->FragBuffer;
6885 register ULONG size=SC->FragSize2;
6886 register UBYTE *RtoB=SC->RtoB0;
6887 register UBYTE *GtoB=SC->GtoB0;
6888 register UBYTE *BtoB=SC->BtoB0;
6889 register UBYTE *RGB;
6891 while(0<size--)
6893 RGB=Frag[0].BufferRGBA;
6894 Frag[0].Image8[0]=RtoB[RGB[0]]+GtoB[RGB[1]]+BtoB[RGB[2]];
6895 RGB=Frag[1].BufferRGBA;
6896 Frag[1].Image8[0]=RtoB[RGB[0]]+GtoB[RGB[1]]+BtoB[RGB[2]];
6897 Frag+=2;
6901 /*==========================================================================*/
6902 BOOL LockBM(struct SOFT3D_context *SC)
6904 #ifdef AMIGA
6905 UBYTE *Image8; /* = bitmap memory */
6907 if(SC->ImageBuffer32!=NULL) /* So we dont write to a bitmap but to an RGBA buffer called "ImageBuffer32" */
6908 return(TRUE);
6910 SC->bmHandle=LockBitMapTags((APTR)SC->bm,LBMI_BASEADDRESS,(IPTR)&Image8, TAG_DONE);
6911 return(SC->bmHandle!=NULL);
6912 #else
6913 return(TRUE);
6914 #endif
6916 /*==========================================================================*/
6917 void UnLockBM(struct SOFT3D_context *SC)
6919 #ifdef AMIGA
6920 if(SC->ImageBuffer32!=NULL) /* So we dont write to a bitmap but to an RGBA buffer called "ImageBuffer32" */
6921 return;
6923 if(SC->bmHandle!=NULL)
6924 UnLockBitMap(SC->bmHandle);
6925 #endif
6927 /*=================================================================*/