Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download

open-axiom repository from github

24005 views
1
/*
2
Copyright (C) 1991-2002, The Numerical Algorithms Group Ltd.
3
All rights reserved.
4
Copyright (C) 2007-2010, Gabriel Dos Reis.
5
All rights reserved.
6
7
Redistribution and use in source and binary forms, with or without
8
modification, are permitted provided that the following conditions are
9
met:
10
11
- Redistributions of source code must retain the above copyright
12
notice, this list of conditions and the following disclaimer.
13
14
- Redistributions in binary form must reproduce the above copyright
15
notice, this list of conditions and the following disclaimer in
16
the documentation and/or other materials provided with the
17
distribution.
18
19
- Neither the name of The Numerical Algorithms Group Ltd. nor the
20
names of its contributors may be used to endorse or promote products
21
derived from this software without specific prior written permission.
22
23
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
24
IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
25
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
26
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
27
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
28
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
29
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
*/
35
36
#define _MAIN3D_C
37
#include "openaxiom-c-macros.h"
38
#include <string.h>
39
#include <stdio.h>
40
#include <stdlib.h>
41
#include <unistd.h>
42
#include <signal.h>
43
#include <math.h>
44
45
#include "header.h"
46
#include "cpanel.h"
47
#include "process.h"
48
#include "bsdsignal.h"
49
50
#include "util.H1"
51
#include "Gfun.H1"
52
#include "XSpadFill.h"
53
#include "XShade.h"
54
#include "all_3d.H1"
55
56
#include "spadBitmap.bitmap"
57
#include "spadMask.mask"
58
59
viewPoints *viewport;
60
GCptr GChead=NULL; /* ptr to head of ps GC linked list */
61
char *PSfilename; /* output file name used in user directory */
62
int psInit=no; /* need to call globaInitPs() each run */
63
char *envAXIOM; /* used for ps file paths */
64
int maxGreyShade=0;
65
GC globalGC1, globalGC2, anotherGC, globGC, trashGC,
66
controlMessageGC, lightingGC, volumeGC, quitGC, processGC,
67
saveGC, graphGC, componentGC, opaqueGC, renderGC;
68
unsigned long foregroundColor, backgroundColor;
69
int Socket=1, ack=1;
70
Colormap colorMap;
71
viewTriple *splitPoints;
72
Display *dsply;
73
int scrn;
74
Window rtWindow;
75
HashTable *table;
76
int mono, totalColors, totalSolid, totalDithered, totalHues,
77
totalSolidShades, totalDitheredAndSolids,totalShades;
78
XFontStruct *globalFont, *buttonFont, *headerFont, *titleFont, *graphFont,
79
*lightingFont, *volumeFont, *quitFont, *saveFont,*serverFont;
80
XGCValues gcVals;
81
unsigned long * spadColors;
82
float transform[4][4], transform1[4][4],
83
R[4][4], R1[4][4], S[4][4], T[4][4], I[4][4];
84
float A[4][4], B[4][4], D[4], E[4][4], F[4], array[4][4];
85
86
int followMouse=no,
87
viewportKeyNum=0;
88
/**********************/
89
/** global variables **/
90
/**********************/
91
92
char scaleReport[5];
93
char deltaXReport[5], deltaYReport[5];
94
XSizeHints viewSizeHints;
95
96
GC processGC;
97
viewPoints *viewport;
98
controlPanelStruct *control;
99
const char* s;
100
int someInt;
101
102
/* check /usr/include/X11 for current implementation of
103
pixels (e.g. BlackPixel()) */
104
105
/** totalShades is initially set to totalShadesConst.
106
If X cannot allocate 8 shades for each hue, total-
107
Shades is decremented. there is currently only a check for
108
this value to be positive. --> something to add: change over
109
to monochrome if totalShades=0. just modify the spadcolors.c
110
file. spadcolors.c has been modified so that it returns the
111
value for totalShades. since the return value had previously
112
been unused, a modification in this way ensures continued
113
support of other routines calling this function (e.g.
114
hypertex stuff). **/
115
116
117
int drawMore;
118
119
int spadMode=no, /* yes if receiving OpenAxiom command and
120
calling drawViewport */
121
spadDraw=no; /* yes if drawing viewport for
122
an OpenAxiom command */
123
int spadSignalReceived=0; /* yes if current state is a result of
124
a signal from OpenAxiom */
125
int inNextEvent=no; /* true just before a call to
126
XNextEvent */
127
jmp_buf jumpFlag;
128
129
char errorStr[80];
130
131
view3DStruct viewData;
132
133
Window quitWindow, saveWindow;
134
135
/** variables below assume only one viewport per process **/
136
137
Window lightingWindow, lightingAxes;
138
float lightPointer[3], tempLightPointer[3];
139
140
int axesXY[3][4];
141
float axesZ[3][2];
142
143
float lightIntensity=1.0, tempLightIntensity;
144
float backLightIntensity = 1.0;
145
146
/** used for writing viewport info out to a file **/
147
char filename[256];
148
149
150
/** used for draw viewport routines */
151
float sinTheta, sinPhi, cosTheta, cosPhi, viewScale,
152
viewScaleX, viewScaleY, viewScaleZ, reScale;
153
int xCenter, yCenter;
154
155
XWindowAttributes vwInfo;
156
XWindowAttributes graphWindowAttrib;
157
158
XPoint *quadMesh;
159
XImage *imageX;
160
int *xPts; /* pointer to projected points (x followed by y) */
161
float transform[4][4], transform1[4][4],
162
R[4][4], R1[4][4], S[4][4], T[4][4], I[4][4];
163
float A[4][4], B[4][4], D[4], E[4][4], F[4], array[4][4];
164
165
166
int scanline, polyCount;
167
polyList *scanList[ARRAY_HEIGHT];
168
float xleft = (float)0 ,xright = (float)ARRAY_WIDTH;
169
170
colorBuffer cBuffer[ARRAY_WIDTH];
171
float zBuffer[ARRAY_WIDTH];
172
173
float zC, dzdx, lum, point_norm[3];
174
float intersectColor[2], dcolor;
175
triple dpt, dnorm;
176
177
/** eyePoint **/
178
float eyePoint[3];
179
180
/** tube stuff **/
181
XPoint polygonMesh[20];
182
183
/* bypass the hidden surface algorithm if no rotations, etc */
184
int saveFlag=no;
185
int firstTime=yes, noTrans = yes, startup = yes;
186
int redrawView = no; /* set to yes when returning from
187
subpanels */
188
int redoColor = no, pixelSetFlag = no, redoDither = no;
189
int redoSmooth = no, multiColorFlag = no;
190
191
/* In order to set recalc to true (see draw.h) */
192
int finishedList=no, zoomed=yes, translated = yes,
193
changedIntensity, movingLight = no, writeImage = no,
194
rotated=yes, switchedPerspective, changedEyeDistance,
195
gotToggle = no;
196
poly *quickList;
197
198
/** if not connected to OpenAxiom **/
199
int viewAloned;
200
201
/** for drawing the box **/
202
viewTriple corners[8], clipCorners[8];
203
boxSideStruct box[6], clipBox[6];
204
205
/** for freeing up points created frrom split polygons **/
206
int resMax=0; /* number of points in the split point resevoir */
207
208
/** view volume stuff **/
209
Window volumeWindow;
210
int frustrumVertex;
211
int doingPanel=CONTROLpanel; /* rewrite titles in proper panel */
212
int doingVolume;
213
214
int screenX; /* global floating point indicating mouse position
215
on frustrum screen */
216
float xClipMinN, xClipMaxN, /* normalized values for
217
clip volume */
218
yClipMinN, yClipMaxN,
219
zClipMinN, zClipMaxN,
220
clipValue; /* mouse input */
221
float pzMin, pzMax; /* for a given (theta,phi): calculated in
222
drawViewport(), used in drawFrustrum() */
223
224
/** B/W shades **/
225
/** events from the viewport manager **/
226
char propertyName[14];
227
char propertyBuffer[256];
228
229
/* global ps variables */
230
231
/** Resource database **/
232
XrmDatabase rDB;
233
234
/** variables used for smooth shading **/
235
int smoothError = no;
236
Pixmap viewmap;
237
float Cspec = 0.30;
238
float Cdiff = 0.4;
239
float Camb = 0.3;
240
float coeff = 35.0;
241
float saturation = 0.8;
242
int smoothHue;
243
int smoothConst = 50;
244
245
246
247
248
void
249
main(void)
250
{
251
252
XGCValues controlGCVals;
253
int i, code;
254
255
char property[256];
256
char *prop = &property[0];
257
char *str_type[20];
258
XrmValue value;
259
260
Atom wm_delete_window;
261
XColor foreColor, backColor;
262
XSizeHints titleSizeHints;
263
Window viewTitleWindow, viewGraphWindow;
264
XSetWindowAttributes viewAttrib;
265
Pixmap spadbits,spadmask;
266
267
/**** Global inits ****/
268
splitPoints = NIL(viewTriple);
269
270
/**** Set up display ****/
271
if ((dsply = XOpenDisplay(oa_getenv("DISPLAY"))) == NULL)
272
{fprintf(stderr,"Could not open display.\n");exit (-1);}
273
scrn = DefaultScreen(dsply);
274
rtWindow = RootWindow(dsply,scrn);
275
276
/**** link Xwindows to viewports - X10 feature ****/
277
table = XCreateAssocTable(nbuckets);
278
279
/**** Create OpenAxiom color map ****/
280
totalShades = 0;
281
totalColors = XInitSpadFill(dsply,scrn,&colorMap,
282
&totalHues,&totalSolidShades,
283
&totalDitheredAndSolids,&totalShades);
284
if (totalColors < 0) {
285
fprintf(stderr,"ERROR: Could not allocate all the necessary colors.\n");
286
exitWithAck(RootWindow(dsply,scrn),Window,-1);
287
}
288
289
290
291
PSGlobalInit();
292
/* must initiate before using any G/PS functions */
293
/* need character name: used as postscript GC variable */
294
/* need to create ps GCs for all GCs used by drawing in viewWindow */
295
296
/* globalGC1 */
297
controlGCVals.foreground = monoColor(axesColor);
298
controlGCVals.background = backgroundColor;
299
globalGC1 = XCreateGC(dsply,rtWindow,GCForeground |
300
GCBackground ,&controlGCVals);
301
carefullySetFont(globalGC1,globalFont);
302
PSCreateContext(globalGC1, "globalGC1", psNormalWidth, psButtCap,
303
psMiterJoin, psWhite, psBlack);
304
305
/* controlMessageGC */
306
controlGCVals.foreground = controlMessageColor;
307
controlGCVals.background = backgroundColor;
308
controlMessageGC = XCreateGC(dsply,rtWindow,GCForeground |
309
GCBackground ,&controlGCVals);
310
carefullySetFont(controlMessageGC,globalFont);
311
312
/* globalGC2 */
313
controlGCVals.foreground = monoColor(labelColor);
314
globalGC2 = XCreateGC(dsply,rtWindow,GCForeground,&controlGCVals);
315
carefullySetFont(globalGC2,buttonFont);
316
PSCreateContext(globalGC2, "globalGC2", psNormalWidth, psButtCap,
317
psMiterJoin, psWhite, psBlack);
318
319
/* trashGC */
320
controlGCVals.function = GXcopy;
321
trashGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
322
carefullySetFont(trashGC,buttonFont);
323
PSCreateContext(trashGC, "trashGC", psNormalWidth, psButtCap,
324
psMiterJoin, psWhite, psBlack);
325
326
/* componentGC */
327
componentGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
328
carefullySetFont(componentGC,buttonFont);
329
PSCreateContext(componentGC, "componentGC", psNormalWidth, psButtCap,
330
psMiterJoin, psWhite, psBlack);
331
332
/* opaqueGC */
333
opaqueGC = XCreateGC(dsply,rtWindow,0 ,&controlGCVals);
334
carefullySetFont(opaqueGC,buttonFont);
335
PSCreateContext(opaqueGC, "opaqueGC", psNormalWidth, psButtCap,
336
psMiterJoin, psWhite, psBlack);
337
338
/* renderGC */
339
renderGC = XCreateGC(dsply,rtWindow,0,&controlGCVals);
340
carefullySetFont(renderGC,buttonFont);
341
PSCreateContext(renderGC, "renderGC", psNormalWidth, psButtCap,
342
psMiterJoin, psWhite, psBlack);
343
344
/* globGC */
345
globGC = XCreateGC(dsply,rtWindow,0,&controlGCVals);
346
carefullySetFont(globGC,headerFont);
347
PSCreateContext(globGC, "globGC", psNormalWidth, psButtCap,
348
psMiterJoin, psWhite, psBlack);
349
350
/* anotherGC */
351
controlGCVals.line_width = colorWidth;
352
anotherGC = XCreateGC(dsply,rtWindow,GCBackground | GCLineWidth |
353
GCFunction ,&controlGCVals);
354
carefullySetFont(anotherGC,titleFont);
355
PSCreateContext(anotherGC, "anotherGC", psNormalWidth, psButtCap,
356
psMiterJoin, psWhite, psBlack);
357
358
/* also create one for rendering (grayscale only for now) */
359
/* assign arbitrary number to renderGC as 9991 - see header.h */
360
PSCreateContext(GC9991, "renderGC", psNormalWidth, psButtCap,
361
psRoundJoin, psWhite, psBlack );
362
363
364
/* processGC */
365
gcVals.background = backgroundColor;
366
processGC = XCreateGC(dsply,rtWindow,GCBackground |
367
GCFillStyle,&gcVals);
368
carefullySetFont(processGC,buttonFont);
369
370
/* lightingGC */
371
controlGCVals.foreground = monoColor(axesColor);
372
controlGCVals.background = backgroundColor;
373
lightingGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
374
,&controlGCVals);
375
carefullySetFont(lightingGC,lightingFont);
376
377
378
/* volumeGC */
379
volumeGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
380
,&controlGCVals);
381
carefullySetFont(volumeGC,volumeFont);
382
383
/* quitGC */
384
quitGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
385
,&controlGCVals);
386
carefullySetFont(quitGC,buttonFont);
387
388
/* saveGC */
389
saveGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
390
,&controlGCVals);
391
carefullySetFont(saveGC,buttonFont);
392
393
394
/* graphGC */
395
graphGC = XCreateGC(dsply,rtWindow,GCForeground | GCBackground
396
,&controlGCVals);
397
carefullySetFont(graphGC,buttonFont);
398
if (!(viewport = (viewPoints *)saymem("viewport3D.c",
399
1,sizeof(viewPoints)))) {
400
fprintf(stderr,"Ran out of memory trying to create a viewport.\n");
401
exitWithAck(RootWindow(dsply,scrn),Window,-1);
402
}
403
/* Definition of the 4x4 identity matrix. */
404
I[0][0] = 1.0; I[0][1] = 0.0; I[0][2] = 0.0; I[0][3] = 0.0;
405
I[1][0] = 0.0; I[1][1] = 1.0; I[1][2] = 0.0; I[1][3] = 0.0;
406
I[2][0] = 0.0; I[2][1] = 0.0; I[2][2] = 1.0; I[2][3] = 0.0;
407
I[3][0] = 0.0; I[3][1] = 0.0; I[3][2] = 0.0; I[3][3] = 1.0;
408
409
viewport->viewportKey = viewportKeyNum++;
410
viewport->nextViewport = 0;
411
viewport->prevViewport = 0;
412
viewport->deltaX = viewport->deltaX0 = viewData.deltaX;
413
viewport->deltaY = viewport->deltaY0 = viewData.deltaY;
414
viewport->deltaZ = viewport->deltaZ0 = viewData.deltaZ;
415
viewport->scale = viewport->scale0 = viewData.scale;
416
viewport->scaleX = viewData.scaleX;
417
viewport->scaleY = viewData.scaleY;
418
viewport->scaleZ = viewData.scaleZ;
419
viewport->transX = (viewData.xmax + viewData.xmin)/2.0;
420
viewport->transY = (viewData.ymax + viewData.ymin)/2.0;
421
viewport->transZ = (viewData.zmax + viewData.zmin)/2.0;
422
423
viewport->theta = viewport->axestheta = viewport->theta0 = viewData.theta;
424
viewport->phi = viewport->axesphi = viewport->phi0 = viewData.phi;
425
viewport->thetaObj = 0.0;
426
viewport->phiObj = 0.0;
427
428
viewData.title = "untitled";
429
strcpy(viewport->title,viewData.title);
430
431
viewport->axesOn = yes;
432
viewport->regionOn = no;
433
viewport->monoOn = no;
434
viewport->zoomXOn = yes;
435
viewport->zoomYOn = yes;
436
viewport->zoomZOn = yes;
437
438
viewport->originrOn = yes;
439
viewport->objectrOn = no;
440
viewport->originFlag = no;
441
442
viewport->xyOn = no;
443
viewport->xzOn = no;
444
viewport->yzOn = no;
445
446
viewport->closing = no;
447
viewport->allowDraw = yes; /*if no, just draw axes the first time */
448
viewport->needNorm = yes;
449
450
viewport->lightVector[0] = -0.5;
451
viewport->lightVector[1] = 0.5;
452
viewport->lightVector[2] = 0.5;
453
viewport->translucency = viewData.translucency;
454
455
viewport->hueOffset = viewData.hueOff;
456
viewport->numberOfHues = viewData.numOfHues;
457
viewport->hueTop = viewData.hueOff + viewData.numOfHues;
458
if (viewport->hueTop > totalHues-1) viewport->hueTop = totalHues-1;
459
viewport->diagonals = viewData.diagonals;
460
461
/* make theta in [0..2pi) and phi in (-pi..pi] */
462
while (viewport->theta >= two_pi) {
463
viewport->theta -= two_pi;
464
}
465
while (viewport->theta < 0.0) {
466
viewport->theta += two_pi;
467
}
468
while (viewport->phi > pi) {
469
viewport->phi -= two_pi;
470
}
471
while (viewport->phi <= -pi) {
472
viewport->phi += two_pi;
473
}
474
475
while (viewport->axestheta >= two_pi) {
476
viewport->axestheta -= two_pi;
477
}
478
while (viewport->axestheta < 0.0) {
479
viewport->axestheta += two_pi;
480
}
481
while (viewport->axesphi > pi) {
482
viewport->axesphi -= two_pi;
483
}
484
while (viewport->axesphi <= -pi) {
485
viewport->axesphi += two_pi;
486
}
487
488
/* Initialize the rotation matrix about the origin. */
489
sinTheta = sin(-viewport->theta);
490
cosTheta = cos(-viewport->theta);
491
sinPhi = sin(viewport->phi);
492
cosPhi = cos(viewport->phi);
493
ROTATE(R); /* angles theta and phi are global */
494
495
/* Initialize the rotation matrix about the object's center of volume. */
496
sinTheta = sin(-viewport->thetaObj);
497
cosTheta = cos(-viewport->thetaObj);
498
sinPhi = sin(viewport->phiObj);
499
cosPhi = cos(viewport->phiObj);
500
ROTATE1(R1); /* angles theta and phi are global */
501
502
503
/* Initialize the non-uniform scaling matrix. */
504
SCALE(viewport->scaleX,viewport->scaleY,viewport->scaleZ,S);
505
/* Initialize the translation matrix. */
506
TRANSLATE(-viewport->deltaX,-viewport->deltaY,0.0,T);
507
/**** make the windows for the viewport ****/
508
spadbits = XCreateBitmapFromData(dsply,rtWindow,
509
spadBitmap_bits,
510
spadBitmap_width,spadBitmap_height);
511
spadmask = XCreateBitmapFromData(dsply,rtWindow,
512
spadMask_bits,
513
spadMask_width,spadMask_height);
514
viewAttrib.background_pixel = backgroundColor;
515
viewAttrib.border_pixel = foregroundColor;
516
517
viewAttrib.override_redirect = overrideManager;
518
519
viewAttrib.colormap = colorMap;
520
foreColor.pixel = foregroundColor;
521
backColor.pixel = backgroundColor;
522
/*
523
foreColor.pixel = viewCursorForeground;
524
backColor.pixel = viewCursorBackground;
525
*/
526
XQueryColor(dsply,colorMap,&foreColor);
527
XQueryColor(dsply,colorMap,&backColor);
528
viewAttrib.cursor = XCreatePixmapCursor(dsply,spadbits,spadmask,
529
&foreColor,&backColor,spadBitmap_x_hot,spadBitmap_y_hot);
530
viewAttrib.event_mask = titleMASK;
531
if (viewData.vW) {
532
titleSizeHints.flags = PPosition | PSize;
533
titleSizeHints.x = viewData.vX;
534
titleSizeHints.y = viewData.vY;
535
titleSizeHints.width = viewData.vW;
536
titleSizeHints.height = viewData.vH;
537
} else { /* ain't gonna allow this for now... */
538
titleSizeHints.flags = PSize;
539
titleSizeHints.width = viewWidth;
540
titleSizeHints.height = viewHeight;
541
}
542
543
viewTitleWindow = XCreateWindow(dsply,rtWindow,viewData.vX,viewData.vY,
544
viewData.vW,viewData.vH,viewBorderWidth+3,
545
CopyFromParent,InputOutput,CopyFromParent,
546
viewportTitleCreateMASK,&viewAttrib);
547
548
wm_delete_window = XInternAtom(dsply, "WM_DELETE_WINDOW", False);
549
(void) XSetWMProtocols(dsply, viewTitleWindow, &wm_delete_window, 1);
550
551
XSetNormalHints(dsply,viewTitleWindow,&titleSizeHints);
552
if (strlen(viewport->title) < 30)
553
XSetStandardProperties(dsply,viewTitleWindow,"OpenAxiom 3D",viewport->title,
554
None,NULL,0,&titleSizeHints);
555
else
556
XSetStandardProperties(dsply,viewTitleWindow,"OpenAxiom 3D","3D OpenAxiom Graph",
557
None,NULL,0,&titleSizeHints);
558
viewport->titleWindow = viewTitleWindow;
559
560
viewAttrib.event_mask = viewportMASK;
561
viewSizeHints.flags = PPosition | PSize;
562
viewSizeHints.x = -(viewBorderWidth+3);
563
viewSizeHints.y = titleHeight;
564
viewSizeHints.width = titleSizeHints.width;
565
viewSizeHints.height = titleSizeHints.height-(titleHeight+appendixHeight);
566
viewGraphWindow = XCreateWindow(dsply,viewTitleWindow,
567
viewSizeHints.x,viewSizeHints.y,
568
viewSizeHints.width,viewSizeHints.height,
569
viewBorderWidth+3,
570
CopyFromParent,InputOutput,CopyFromParent,
571
viewportCreateMASK,&viewAttrib);
572
XSetNormalHints(dsply,viewGraphWindow,&viewSizeHints);
573
XSetStandardProperties(dsply,viewGraphWindow,"","",None,NULL,0,
574
&viewSizeHints);
575
viewport->viewWindow = viewGraphWindow;
576
graphWindowAttrib.width = viewSizeHints.width;
577
graphWindowAttrib.height = viewSizeHints.height;
578
579
if (viewport->hueOffset != viewport->hueTop) {
580
multiColorFlag = yes;
581
redoColor = no;
582
} else {
583
if (viewport->hueTop < 11)
584
smoothHue = viewport->hueTop*6;
585
else {
586
if (viewport->hueTop > 10 && viewport->hueTop < 16)
587
smoothHue = viewport->hueTop*20 - 140;
588
else smoothHue = viewport->hueTop*12 - 12;
589
}
590
redoColor = yes;
591
}
592
593
594
} /* main() */
595
596
597
598
599