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