# dont perform the libgen and libsocket test in configure for AROS.
[AROS-Contrib.git] / fish / surf / mapstuff.c
blobe564d716ef43e4f22dda3eb6d16c761c185ec134
1 #include <proto/mathffp.h>
2 #include <proto/mathtrans.h>
3 #include <aros/oldprograms.h>
4 #include "mytypes.h"
5 #include "poly.h"
6 #include "bezpt.h"
7 #include "revolve.h"
8 #include "readilbm.h"
9 #include "mapstuff.h"
10 #include "menuexp.h"
12 #define FarRight 1e6
13 #define FarLeft -1e6
14 #define FarTop 0x7fff
15 #define FarBottom -0x7fff
18 #ifndef MANX
19 #include <libraries/mathffp.h>
20 #define ceil SPCeil
21 #define floor SPFloor
22 #define fabs SPAbs
23 #endif
25 extern struct Library * MathBase;
26 extern struct Library * MathTransBase;
28 void PaintPoint(short, short, float);
30 typedef struct { float left, right; } Hedge;
32 static float *BezMapping = null,
33 *RevMapping = null;
34 static float revmin, revdiff,
35 bezmin, bezdiff;
39 * given the ptlist of a polygon, find its vertical range
41 static void FindVRange(scrnlist, top, bottom)
42 register ScrnPair *scrnlist;
43 short *top, *bottom;
45 short i;
46 short localtop, localbot;
48 localtop = FarBottom;
49 localbot = FarTop;
51 for( i = 4; i--; scrnlist++ ) {
52 if( localtop < scrnlist->y ) localtop = scrnlist->y;
53 if( localbot > scrnlist->y ) localbot = scrnlist->y;
55 *top = localtop;
56 *bottom = localbot;
59 * allocate table to store a quick and dirty representation of the
60 * quadrilateral segments
62 static Hedge *InitVRange( depth, tabptr, olddepth )
63 short depth, *olddepth;
64 Hedge *tabptr;
66 Hedge *edgel, *tab;
67 if( *olddepth < depth || !tabptr ) {
68 if( tabptr ) free( tabptr);
69 tab = (Hedge *) malloc(sizeof(Hedge)*depth);
70 *olddepth = depth;
72 else {
73 tab = tabptr;
75 if( !tab ) return( null);
77 for( edgel = tab; depth--; edgel++) {
78 edgel->left = FarRight;
79 edgel->right = FarLeft;
81 return( tab );
86 * add line to quadrilateral descriptions
88 static void AddVLine( tab, x1, y1, x2, y2 )
89 Hedge *tab;
90 short x1, y1, x2, y2;
92 short dy;
93 float curx, slope;
95 * want y1 to have smaller value, ie, y1 below y2
97 if( y1 > y2 ) {
98 short temp;
99 temp = y1; y1 = y2; y2 = temp;
100 temp = x1; x1 = x2; x2 = temp;
102 dy = y2 - y1;
103 tab += y1;
105 if( !dy ) {
106 if ( x1 < x2 ) {
107 short tempx;
108 tempx = x1; x1 = x2; x2 = tempx;
110 if( x2 < tab->left ) tab->left = x2;
111 if( x1 > tab->right ) tab->right = x1;
112 return;
114 slope = (float)(x2 - x1)/dy;
116 curx = x1;
117 #define ZipIt(xxx) { if( xxx < tab->left) tab->left = xxx; \
118 if( xxx > tab->right ) tab->right = xxx; }
119 ZipIt(curx);
120 while( dy--) {
121 curx += slope;
122 tab++;
123 ZipIt(curx);
128 static void AdjMapXY( inx, iny, outpair)
129 float inx, iny;
130 ScrnPair *outpair;
132 float outx, outy;
133 MapXYRatio( inx, iny, &outx, &outy);
135 outpair->y = MapImageH * (bezmin + bezdiff * outy);
136 outpair->x = MapImageV * (revmin + revdiff * outx);
139 if( RevAxis == RevX ) {
140 outpair->y = MapImageH * (bezmin + bezdiff * outy);
141 outpair->x = MapImageV * (revmin + revdiff * outx);
142 } else {
143 outpair->x = MapImageH * (bezmin + bezdiff * outy);
144 outpair->y = MapImageV * (revmin + revdiff * outx);
149 static void ScanCnvQuad( tab, pt)
150 Hedge *tab;
151 ScrnPair pt[];
153 register int i;
154 ScrnPair *listb, *liste;
156 liste = pt;
157 listb = liste + 3;
158 for ( i = 4; i--;) {
159 AddVLine( tab, listb->x, listb->y, liste->x, liste->y);
160 listb = liste++;
164 static float AverageShade(pts)
165 ScrnPair pts[];
167 register Hedge *tab;
168 static Hedge *tabfree = null;
169 static short olddepth = 0;
170 short top, bot;
171 long shade = 0,
172 pixcnt = 0;
174 FindVRange( pts, &top, &bot);
175 tabfree = tab = InitVRange( top - bot + 1, tabfree, &olddepth);
176 if(!tabfree) return(0.0);
178 ScanCnvQuad( tab-bot, pts );
179 #if DEBUG
180 if( DebugOn ) {
181 printf("AverageShade top is %d, bot = %d\n", top, bot );
183 #endif /* DEBUG */
185 while( bot <= top ) {
186 register int hori;
187 int right, left;
188 #if DEBUG
189 if( DebugOn ) {
190 printf("....row %d \t%d -> %d\n", bot, left, right );
192 #endif /* DEBUG */
194 left = (int) ceil(tab->left - SingleTinyVal);
195 right = (int)floor(tab->right+ SingleTinyVal);
197 for( hori= left; hori <= right; hori++ ) {
198 shade += GetImgPix( bot, hori);
199 pixcnt++;
203 if( RevAxis == RevX ) {
204 for( hori= left; hori <= right; hori++ ) {
205 shade += GetImgPix( bot, hori);
206 pixcnt++;
209 else {
210 for( hori= left; hori <= right; hori++ ) {
211 shade += GetImgPix( hori, bot);
212 pixcnt++;
216 tab++;
217 bot++;
219 return( (float)shade / (pixcnt *(15 *16)) );
223 * mess with the number so truncation doesn't
224 * do nasty things to a float containing an int
226 static int NearestInt( afloat )
227 float afloat;
229 afloat += ( afloat > 0 )? 1e-2 : -1e-2;
230 return( (int)afloat );
234 static void ShadeQuad(tab, top, bot, intensity)
235 register Hedge *tab;
236 short top, bot;
237 float intensity;
239 short vert;
240 float rowminl, rowminr,
241 rowmaxl, rowmaxr;
242 Hedge *oldtab = NULL, *nexttab;
244 for ( vert = bot;
245 nexttab = tab+1, vert <= top;
246 vert++, oldtab = tab, tab++ ) {
247 float hori;
248 float colmin, colmax;
249 float leftmost, rightmost;
250 int ihori, ileftmost, irightmost;
251 ScrnPair MpPnts[4];
253 #define lefttop MpPnts[0]
254 #define leftbot MpPnts[3]
255 #define righttop MpPnts[1]
256 #define rightbot MpPnts[2]
259 rowminl = (float)vert;
260 rowmaxr = rowmaxl = rowminr = rowminl;
262 if( vert > bot && oldtab->left < tab->left ) {
263 rowminl -= 0.5;
265 if( vert > bot && oldtab->right > tab->right ) {
266 rowminr -= 0.5;
268 if( vert < top && nexttab->left < tab->left ) {
269 rowmaxl += 0.5;
271 if( vert < top && nexttab->right > tab->right ) {
272 rowmaxr += 0.5;
275 irightmost = NearestInt( tab->right );
276 rightmost = irightmost;
277 ileftmost = NearestInt( tab->left );
278 leftmost = ileftmost;
279 if( irightmost < ileftmost ) {
280 irightmost = ileftmost;
282 for( ihori = leftmost, hori = leftmost;
283 ihori <= irightmost;
284 ihori += 1, hori += 1.0 ) {
287 if( AbortDraw ) { return; }
289 colmin = hori - 0.5;
290 colmax = hori + 0.5;
292 colmin =(colmin > leftmost)?colmin: tab->left;
293 colmax =(colmax < rightmost)?colmax: tab->right;
295 AdjMapXY( colmin, rowmaxl, &lefttop, MP_XMIN| MP_YMAX);
296 AdjMapXY( colmax, rowmaxr, &righttop, MP_XMAX| MP_YMAX);
297 AdjMapXY( colmin, rowminl, &leftbot, MP_XMIN| MP_YMIN);
298 AdjMapXY( colmax, rowminr, &rightbot, MP_XMAX| MP_YMIN);
300 PaintPoint(ihori, vert, AverageShade(MpPnts) *intensity);
303 #undef lefttop
304 #undef righttop
305 #undef rightbot
306 #undef leftbot
310 void DrawRhomMap(mpr)
311 MapRhomboid *mpr;
313 short top, bottom;
314 static Hedge *tab = null;
315 static short olddepth = 0;
317 CalcMapConsts( mpr->rhom.pt );
318 FindVRange( mpr->rhom.pt, &top, &bottom );
319 tab = InitVRange( top - bottom + 1, tab, &olddepth );
320 if(!tab) return;
321 ScanCnvQuad( tab -bottom, mpr->rhom.pt );
323 bezmin = BezMapping[mpr->bezindex];/* make it global */
324 bezdiff = BezMapping[mpr->bezindex+1] - bezmin;
325 revmin = RevMapping[mpr->revindex];
326 revdiff = RevMapping[mpr->revindex+1] - revmin;
327 #if DEBUG
328 if( DebugOn ) {
329 DBMAP(mpr->rhom.pt, mpr->bezindex, mpr->revindex);
331 #endif /* DEBUG */
332 ShadeQuad(tab, top, bottom, mpr->rhom.intensity);
335 #ifdef DEBUG
336 DBMAP(ptlist, bindex, rindex)
337 ScrnPair ptlist[];
338 short bindex, rindex;
340 int i;
342 printf("...................................\n");
343 for( i = 0; i < 4; i++ ) {
344 printf("%10d", ptlist[i].x);
346 printf("\n");
347 for( i = 0; i < 4; i++ ) {
348 printf("%10d", ptlist[i].y);
350 printf("\n");
351 printf(" bezmin %f bezdiff %f index = %d \n", bezmin, bezdiff, bindex );
352 printf(" revmin %f revdiff %f index = %d \n", revmin, revdiff, rindex );
354 #endif /* DEBUG */
358 * return true if image mappings could not be performed
359 * false if successful
361 bool InitMapping() {
362 float *vfmptr;
363 float totallen = 0,
364 scaling;
365 short numvslices;
367 if( BezMapping ) free( BezMapping );
368 if( RevMapping ) free( RevMapping );
371 * compute width of each bezier segment
373 numvslices = BezMesh*GetNumSegs() +1;
374 vfmptr = BezMapping = (float *) malloc(sizeof(float) * numvslices);
375 if( !BezMapping ) return(true);
377 *vfmptr++ = totallen = 0.0;
378 ResetActSeg();
379 do {
380 float t, ffromx, ftox, ffromy, ftoy;
381 int i;
382 InitCalcBez();
383 for( i = 1, ffromx = StartPtX(ActSeg), ffromy = StartPtY(ActSeg);
384 i <= BezMesh; i++, ffromx = ftox, ffromy = ftoy ) {
385 float diffx, diffy;
387 t = (float)i/BezMesh;
389 CalcBezPt( t, &ftox, &ftoy );
390 diffx = ftox - ffromx;
391 diffy = ftoy - ffromy;
392 totallen += sqrt( diffx * diffx + diffy * diffy );
393 *vfmptr++ = totallen;
395 NextSeg();
396 } while( ActSeg);
398 * convert scale floating point values to integer pixel positions
400 scaling = 1.0 / totallen;
401 for( vfmptr = BezMapping; numvslices; numvslices--, vfmptr++ ) {
402 *vfmptr *= scaling;
405 * compute height of each revolution segment
407 RevMapping = (float *) malloc( sizeof(float) * (RevMesh + 1));
408 if( !RevMapping ) return( true );
410 short i;
411 for( i = 0; i <= RevMesh; i++ ) {
412 RevMapping[i] = ((float) i)/RevMesh;
416 return(false);