File: common\plot3d.c
1 /*
2 This file includes miscellaneous plot functions and logic
3 for 3D, used by lorenz.c and line3d.c
4 By Tim Wegner and Marc Reinig.
5 */
6
7 /* see Fractint.c for a description of the "include" hierarchy */
8 #include "port.h"
9 #include "prototyp.h"
10 #include "fractype.h"
11
12 /* Use these palette indices for red/blue - same on ega/vga */
13 #define PAL_BLUE 1
14 #define PAL_RED 2
15 #define PAL_MAGENTA 3
16
17 int whichimage;
18 int xxadjust1;
19 int yyadjust1;
20 int eyeseparation = 0;
21 int glassestype = 0;
22 int xshift1;
23 int yshift1;
24 int xtrans = 0;
25 int ytrans = 0;
26 int red_local_left;
27 int red_local_right;
28 int blue_local_left;
29 int blue_local_right;
30 int red_crop_left = 4;
31 int red_crop_right = 0;
32 int blue_crop_left = 0;
33 int blue_crop_right = 4;
34 int red_bright = 80;
35 int blue_bright = 100;
36
37 BYTE T_RED;
38
39 /* Bresenham's algorithm for drawing line */
40 void cdecl draw_line (int X1, int Y1, int X2, int Y2, int color)
41
42 { /* uses Bresenham algorithm to draw a line */
43 int dX, dY; /* vector components */
44 int row, col,
45 final, /* final row or column number */
46 G, /* used to test for new row or column */
47 inc1, /* G increment when row or column doesn't change */
48 inc2; /* G increment when row or column changes */
49 char pos_slope;
50
51 dX = X2 - X1; /* find vector components */
52 dY = Y2 - Y1;
53 pos_slope = (char)(dX > 0); /* is slope positive? */
54 if (dY < 0)
55 pos_slope = (char)!pos_slope;
56 if (abs (dX) > abs (dY)) /* shallow line case */
57 {
58 if (dX > 0) /* determine start point and last column */
59 {
60 col = X1;
61 row = Y1;
62 final = X2;
63 }
64 else
65 {
66 col = X2;
67 row = Y2;
68 final = X1;
69 }
70 inc1 = 2 * abs (dY); /* determine increments and initial G */
71 G = inc1 - abs (dX);
72 inc2 = 2 * (abs (dY) - abs (dX));
73 if (pos_slope)
74 while (col <= final) /* step through columns checking for new row */
75 {
76 (*plot) (col, row, color);
77 col++;
78 if (G >= 0) /* it's time to change rows */
79 {
80 row++; /* positive slope so increment through the rows */
81 G += inc2;
82 }
83 else /* stay at the same row */
84 G += inc1;
85 }
86 else
87 while (col <= final) /* step through columns checking for new row */
88 {
89 (*plot) (col, row, color);
90 col++;
91 if (G > 0) /* it's time to change rows */
92 {
93 row--; /* negative slope so decrement through the rows */
94 G += inc2;
95 }
96 else /* stay at the same row */
97 G += inc1;
98 }
99 } /* if |dX| > |dY| */
100 else /* steep line case */
101 {
102 if (dY > 0) /* determine start point and last row */
103 {
104 col = X1;
105 row = Y1;
106 final = Y2;
107 }
108 else
109 {
110 col = X2;
111 row = Y2;
112 final = Y1;
113 }
114 inc1 = 2 * abs (dX); /* determine increments and initial G */
115 G = inc1 - abs (dY);
116 inc2 = 2 * (abs (dX) - abs (dY));
117 if (pos_slope)
118 while (row <= final) /* step through rows checking for new column */
119 {
120 (*plot) (col, row, color);
121 row++;
122 if (G >= 0) /* it's time to change columns */
123 {
124 col++; /* positive slope so increment through the columns */
125 G += inc2;
126 }
127 else /* stay at the same column */
128 G += inc1;
129 }
130 else
131 while (row <= final) /* step through rows checking for new column */
132 {
133 (*plot) (col, row, color);
134 row++;
135 if (G > 0) /* it's time to change columns */
136 {
137 col--; /* negative slope so decrement through the columns */
138 G += inc2;
139 }
140 else /* stay at the same column */
141 G += inc1;
142 }
143 }
144 } /* draw_line */
145
146 #if 0
147 /* use this for continuous colors later */
148 void _fastcall plot3dsuperimpose16b(int x,int y,int color)
149 {
150 int tmp;
151 if (color != 0) /* Keeps index 0 still 0 */
152 {
153 color = colors - color; /* Reverses color order */
154 color = color / 4;
155 if(color == 0)
156 color = 1;
157 }
158 color = 3;
159 tmp = getcolor(x,y);
160
161 /* map to 4 colors */
162 if(whichimage == 1) /* RED */
163 {
164 if(red_local_left < x && x < red_local_right)
165 {
166 putcolor(x,y,color|tmp);
167 if (Targa_Out)
168 targa_color(x, y, color|tmp);
169 }
170 }
171 else if(whichimage == 2) /* BLUE */
172 if(blue_local_left < x && x < blue_local_right)
173 {
174 color = color <<2;
175 putcolor(x,y,color|tmp);
176 if (Targa_Out)
177 targa_color(x, y, color|tmp);
178 }
179 }
180 181 #endif
182
183 void _fastcall plot3dsuperimpose16(int x,int y,int color)
184 {
185 int tmp;
186
187 tmp = getcolor(x,y);
188
189 if(whichimage == 1) /* RED */
190 {
191 color = PAL_RED;
192 if(tmp > 0 && tmp != color)
193 color = PAL_MAGENTA;
194 if(red_local_left < x && x < red_local_right)
195 {
196 putcolor(x,y,color);
197 if (Targa_Out)
198 targa_color(x, y, color);
199 }
200 }
201 else if(whichimage == 2) /* BLUE */
202 if(blue_local_left < x && x < blue_local_right)
203 {
204 color = PAL_BLUE;
205 if(tmp > 0 && tmp != color)
206 color = PAL_MAGENTA;
207 putcolor(x,y,color);
208 if (Targa_Out)
209 targa_color(x, y, color);
210 }
211 }
212
213
214 void _fastcall plot3dsuperimpose256(int x,int y,int color)
215 {
216 int tmp;
217 BYTE t_c;
218
219 t_c = (BYTE)(255-color);
220
221 if (color != 0) /* Keeps index 0 still 0 */
222 {
223 color = colors - color; /* Reverses color order */
224 if (max_colors == 236)
225 color = 1 + color / 21; /* Maps colors 1-255 to 13 even ranges */
226 else
227 color = 1 + color / 18; /* Maps colors 1-255 to 15 even ranges */
228 }
229
230 tmp = getcolor(x,y);
231 /* map to 16 colors */
232 if(whichimage == 1) /* RED */
233 {
234 if(red_local_left < x && x < red_local_right)
235 {
236 /* Overwrite prev Red don't mess w/blue */
237 putcolor(x,y,color|(tmp&240));
238 if (Targa_Out) {
239 if (!ILLUMINE)
240 targa_color(x, y, color|(tmp&240));
241 else
242 targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0);
243 }
244 }
245 }
246 else if(whichimage == 2) /* BLUE */
247 if(blue_local_left < x && x < blue_local_right)
248 {
249 /* Overwrite previous blue, don't mess with existing red */
250 color = color <<4;
251 putcolor(x,y,color|(tmp&15));
252 if (Targa_Out) {
253 if (!ILLUMINE)
254 targa_color(x, y, color|(tmp&15));
255 else
256 {
257 targa_readdisk (x+sxoffs, y+syoffs, &T_RED, (BYTE *)&tmp, (BYTE *)&tmp);
258 targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c);
259 }
260 }
261 }
262 }
263
264 void _fastcall plotIFS3dsuperimpose256(int x,int y,int color)
265 {
266 int tmp;
267 BYTE t_c;
268
269 t_c = (BYTE)(255-color);
270
271 if (color != 0) /* Keeps index 0 still 0 */
272 {
273 /* my mind is fried - lower indices = darker colors is EASIER! */
274 color = colors - color; /* Reverses color order */
275 if (max_colors == 236)
276 color = 1 + color / 21; /* Maps colors 1-255 to 13 even ranges */
277 else
278 color = 1 + color / 18; /* Looks weird but maps colors 1-255 to 15
279 relatively even ranges */
280 }
281
282 tmp = getcolor(x,y);
283 /* map to 16 colors */
284 if(whichimage == 1) /* RED */
285 {
286 if(red_local_left < x && x < red_local_right)
287 {
288 putcolor(x,y,color|tmp);
289 if (Targa_Out) {
290 if (!ILLUMINE)
291 targa_color(x, y, color|tmp);
292 else
293 targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0);
294 }
295 }
296 }
297 else if(whichimage == 2) /* BLUE */
298 if(blue_local_left < x && x < blue_local_right)
299 {
300 color = color <<4;
301 putcolor(x,y,color|tmp);
302 if (Targa_Out) {
303 if (!ILLUMINE)
304 targa_color(x, y, color|tmp);
305 else
306 {
307 targa_readdisk (x+sxoffs, y+syoffs, &T_RED, (BYTE *)&tmp, (BYTE *)&tmp);
308 targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c);
309 }
310 }
311 }
312 }
313
314 void _fastcall plot3dalternate(int x,int y,int color)
315 {
316 BYTE t_c;
317
318 t_c = (BYTE)(255-color);
319 /* lorez high color red/blue 3D plot function */
320 /* if which image = 1, compresses color to lower 128 colors */
321
322 /* my mind is STILL fried - lower indices = darker colors is EASIER! */
323 color = colors - color;
324 if((whichimage == 1) && !((x+y)&1)) /* - lower half palette */
325 {
326 if(red_local_left < x && x < red_local_right)
327 {
328 putcolor(x,y,color>>1);
329 if (Targa_Out) {
330 if (!ILLUMINE)
331 targa_color(x, y, color>>1);
332 else
333 targa_writedisk (x+sxoffs, y+syoffs, t_c, 0, 0);
334 }
335 }
336 }
337 else if((whichimage == 2) && ((x+y)&1) ) /* - upper half palette */
338 {
339 if(blue_local_left < x && x < blue_local_right)
340 {
341 putcolor(x,y,(color>>1)+(colors>>1));
342 if (Targa_Out) {
343 if (!ILLUMINE)
344 targa_color(x, y, (color>>1)+(colors>>1));
345 else
346 targa_writedisk (x+sxoffs, y+syoffs, T_RED, 0, t_c);
347 }
348 }
349 }
350 }
351
352 void _fastcall plot3dcrosseyedA(int x,int y,int color)
353 {
354 x /= 2;
355 y /= 2;
356 if(whichimage == 2)
357 x += xdots/2;
358 if(rowcount >= ydots/2)
359 /* hidden surface kludge */
360 if(getcolor(x,y) != 0)
361 return;
362 putcolor(x,y,color);
363 }
364
365 void _fastcall plot3dcrosseyedB(int x,int y,int color)
366 {
367 x /= 2;
368 y /= 2;
369 if(whichimage == 2)
370 x += xdots/2;
371 putcolor(x,y,color);
372 }
373
374 void _fastcall plot3dcrosseyedC(int x,int y,int color)
375 {
376 if(rowcount >= ydots/2)
377 /* hidden surface kludge */
378 if(getcolor(x,y) != 0)
379 return;
380 putcolor(x,y,color);
381 }
382
383 void plot_setup()
384 {
385 double d_red_bright = 0;
386 double d_blue_bright = 0;
387 int i;
388
389 /* set funny glasses plot function */
390 switch(glassestype)
391 {
392 case 1:
393 standardplot = plot3dalternate;
394 break;
395
396 case 2:
397 if(colors == 256)
398 if (fractype != IFS3D)
399 standardplot = plot3dsuperimpose256;
400 else
401 standardplot = plotIFS3dsuperimpose256;
402 else
403 standardplot = plot3dsuperimpose16;
404 break;
405
406 case 4: /* crosseyed mode */
407 if(sxdots < 2*xdots)
408 {
409 if(XROT == 0 && YROT == 0)
410 standardplot = plot3dcrosseyedA; /* use hidden surface kludge */
411 else
412 standardplot = plot3dcrosseyedB;
413 }
414 else if(XROT == 0 && YROT == 0)
415 standardplot = plot3dcrosseyedC; /* use hidden surface kludge */
416 else
417 standardplot = putcolor;
418 break;
419
420 default:
421 standardplot = putcolor;
422 break;
423 }
424
425 xshift1 = xshift = (int)((XSHIFT * (double)xdots)/100);
426 yshift1 = yshift = (int)((YSHIFT * (double)ydots)/100);
427
428 if(glassestype)
429 {
430 red_local_left = (int)((red_crop_left * (double)xdots)/100.0);
431 red_local_right = (int)(((100 - red_crop_right) * (double)xdots)/100.0);
432 blue_local_left = (int)((blue_crop_left * (double)xdots)/100.0);
433 blue_local_right = (int)(((100 - blue_crop_right) * (double)xdots)/100.0);
434 d_red_bright = (double)red_bright/100.0;
435 d_blue_bright = (double)blue_bright/100.0;
436
437 switch(whichimage)
438 {
439 case 1:
440 xshift += (int)((eyeseparation* (double)xdots)/200);
441 xxadjust = (int)(((xtrans+xadjust)* (double)xdots)/100);
442 xshift1 -= (int)((eyeseparation* (double)xdots)/200);
443 xxadjust1 = (int)(((xtrans-xadjust)* (double)xdots)/100);
444 if(glassestype == 4 && sxdots >= 2*xdots)
445 sxoffs = sxdots / 2 - xdots;
446 break;
447
448 case 2:
449 xshift -= (int)((eyeseparation* (double)xdots)/200);
450 xxadjust = (int)(((xtrans-xadjust)* (double)xdots)/100);
451 if(glassestype == 4 && sxdots >= 2*xdots)
452 sxoffs = sxdots / 2;
453 break;
454 }
455 }
456 else
457 xxadjust = (int)((xtrans* (double)xdots)/100);
458 yyadjust = (int)(-(ytrans* (double)ydots)/100);
459
460 if (mapset)
461 {
462 ValidateLuts(MAP_name); /* read the palette file */
463 if(glassestype==1 || glassestype==2)
464 {
465 if(glassestype == 2 && colors < 256)
466 {
467 dacbox[PAL_RED ][0] = 63;
468 dacbox[PAL_RED ][1] = 0;
469 dacbox[PAL_RED ][2] = 0;
470
471 dacbox[PAL_BLUE ][0] = 0;
472 dacbox[PAL_BLUE ][1] = 0;
473 dacbox[PAL_BLUE ][2] = 63;
474
475 dacbox[PAL_MAGENTA][0] = 63;
476 dacbox[PAL_MAGENTA][1] = 0;
477 dacbox[PAL_MAGENTA][2] = 63;
478 }
479 for (i=0;i<256;i++)
480 {
481 dacbox[i][0] = (BYTE)(dacbox[i][0] * d_red_bright);
482 dacbox[i][2] = (BYTE)(dacbox[i][2] * d_blue_bright);
483 }
484 }
485 spindac(0,1); /* load it, but don't spin */
486 }
487 }
488
489