home *** CD-ROM | disk | FTP | other *** search
/ Stars of Shareware: Raytrace & Morphing / SOS-RAYTRACE.ISO / programm / source / devel5 / colormap.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-04-27  |  7.7 KB  |  264 lines

  1. /* Routine to setup and compute colors */
  2. /* for 256-color mode                */
  3.  
  4. /* Written by Dave Stampe Mar 21 1992 */
  5. /* Modified by Bernie Roehl, April 2, 1992 */
  6. /* Substantially upgraded by Dave Stampe, August '92 */
  7.  
  8. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  9.    May be freely used to write software for release into the public domain;
  10.    all commercial endeavours MUST contact Bernie Roehl and Dave Stampe
  11.    for permission to incorporate any part of this software into their
  12.    products!
  13.  
  14.      ATTRIBUTION:  If you use any part of this source code or the libraries
  15.      in your projects, you must give attribution to REND386, Dave Stampe,
  16.      and Bernie Roehl in your documentation, source code, and at startup
  17.      of your program.  Let's keep the freeware ball rolling!
  18.  */
  19.  
  20. #pragma inline
  21.  
  22. #include <stdio.h>
  23. #include <stdlib.h>  /* strtoul() */
  24. #include <dos.h>
  25. #include <ctype.h>   /* isdigit(), isalnum() */
  26. #include <string.h>  /* strnicmp() */
  27. #include "3dstruct.h"    /* for POLY struct */
  28. #include "rend386.h"
  29.  
  30. extern void load_DAC_colors(void *ptr, int high, int bwflag);
  31.  
  32. /* colors to use on screen */
  33.  
  34. int screen_clear_color = -1;
  35. int sky_color = -1;
  36. int ground_color = -1;
  37. int wireframe_color = -1;
  38. int highlight_color = -1;
  39. int highest_color = -1;
  40.  
  41. extern int do_horizon;
  42.  
  43. void preset_default_colors()
  44. {
  45.  if (screen_clear_color==-1 && sky_color!=-1) screen_clear_color=sky_color;
  46.  if (screen_clear_color!=-1 && sky_color==-1) sky_color=screen_clear_color;
  47.  if (highest_color > 254)
  48.   {
  49.    if (screen_clear_color == -1) screen_clear_color = 3;
  50.    if (sky_color == -1) sky_color = 3;
  51.    if (ground_color == -1) ground_color = 0x88;
  52.    if (wireframe_color == -1) wireframe_color = 13;
  53.    if (highlight_color == -1) highlight_color = 15;
  54.   }
  55.  else /* if (highest_color > 14) */
  56.   {
  57.    if (screen_clear_color == -1) screen_clear_color = 10;
  58.    if (sky_color == -1) sky_color = 10;
  59.    if (ground_color == -1) ground_color = 5;
  60.    if (wireframe_color == -1) wireframe_color = 12;
  61.    if (highlight_color == -1) highlight_color = 15;
  62.   }
  63.  do_horizon = (sky_color==ground_color) ? 0 : 1 ;
  64. }
  65.  
  66. void set_colors(int bw)
  67. {
  68.  load_DAC_colors(NULL, highest_color+1, bw);
  69. }
  70.  
  71.  
  72. /* USER POLYGON LIGHTING ROUTINE: DETERMINES POLY COLOR # */
  73.  
  74. /* The 16-bit color the user specifies for a polygon is broken down as
  75.    follows:
  76.          H R SS CCCC BBBBBBBB
  77.  
  78.    H is the highlight flag (the polygon should be highlighted in
  79.    some way, usually by outlining it in the highlight_color given above).
  80.  
  81.    R is a reserved bit, which should be set to zero
  82.  
  83.    SS is a two-bit field specifying one of four surface types:
  84.  
  85.       00 is a constant-color surface; the 4-bit field CCCC is ignored, and the
  86.      8-bit field BBBBBBBB is used as an absolute color number
  87.  
  88.       01 is a cosine-lit surface; the 4-bit field CCCC specifies one of 16
  89.          basic colors, and the 8-bit brightness field BBBBBBBB is multiplied
  90.          by the cosine of the angle between the light source and the polygon's
  91.          surface normal to provide a 4-bit shading value.
  92.  
  93.       10 is a pseudo-metallic surface; the CCCC field gives the starting hue,
  94.      and the BBBBBBBB value is ignored.  The color will cycle through
  95.      the different shades to give a 'metallic' effect.
  96.  
  97.       11 is a pseudo-transparent surface made up of alternating rows of
  98.      spaced dots; other than that, it behaves like a pseudo-metallic
  99.      surface.
  100.  
  101.    This routine maps the above into an 8-bit color number in the low byte
  102.    of its return value, and passes through the top four bits.
  103.  
  104.  */
  105.  
  106. int ambient_light = 76;
  107.  
  108. int light1_i = 51;
  109. long light1_x, light1_y, light1_z;
  110. int light1_s = 0;
  111.  
  112. int light2_i = 0;
  113. long light2_x, light2_y, light2_z;
  114. int light2_s = 0;
  115.  
  116. SEGMENT *light_seg  = NULL;
  117. SEGMENT *light_seg2  = NULL;
  118.  
  119. int user_poly_color(POLY *p, int pcolor, long maxz)
  120. {
  121.  int hilite = pcolor & 0xF000; /* highlight flag  (MSB) */
  122.  int bright = pcolor & 0xFF; /* mask out albedo (7 bits) */
  123.  int hue = (pcolor & 0x0F00) >> 4; /* 16 * basis color */
  124.  signed int color, color1, color2;
  125.  
  126.  switch(highest_color)
  127.   {
  128.    case 15:
  129.     {
  130.      if (hue == 0) return ((bright & 15) | hilite); /* abs. color */
  131.  
  132.      if ((pcolor & 0x3000) == 0 || p->npoints<3) /* fixed (unlit) color */
  133.       {
  134.        if (bright > 15) bright = 15;
  135.        return (hilite | bright);
  136.       }
  137.  
  138.      if (pcolor & 0x2000) /* develop offset for metal/glass cycle */
  139.       {
  140.        color = poly_cosine(p, light1_x, light1_y, light1_z, light1_s);
  141.        color = (bright >> 6) - (color >> 5) + ((hue+320) >> 6);
  142.        if (color < 0) color = 0;
  143.        if (color > 15) color = 15;
  144.        return (hilite | color);
  145.       }
  146.                 /* compute brightness index */
  147.      color1 = color2 = 0;
  148.      if(light1_i) color1 = poly_cosine(p, light1_x, light1_y, light1_z, light1_s);
  149.      if(light2_i) color2 = poly_cosine(p, light2_x, light2_y, light2_z, light2_s);
  150.      if (color1 < 0) color1 = 0;
  151.      if (color2 < 0) color2 = 0;
  152.  
  153. /*     color = (( ((color*(128-ambient_light)) >> 7) + ambient_light)
  154.         * (bright>>1) );
  155.      color = ((color>>5)*((hue+768)>>4))>>11;  */
  156.  
  157.      asm {
  158.     .386
  159.     mov    ax,color1
  160.     mul    byte ptr light1_i
  161.     mov    bx,ax
  162.     mov    ax,color2
  163.     mul    byte ptr light2_i
  164.     add    ax,bx
  165.     shr    ax,7
  166.     add    ax,ambient_light
  167.     mul    byte ptr bright
  168.     shr    ax,6
  169.     mov    bx,hue
  170.     add    bx,768
  171.     shr    bx,4
  172.     mul     bx
  173.     shr    ax,11
  174.     mov    color,ax
  175.      }
  176.  
  177.      if (color <= 0) return( hilite );
  178.      if (color > 15) return (15 | hilite);
  179.      return (color | hilite);
  180.     }
  181.  
  182.    case 255:
  183.     {
  184.      if ((pcolor & 0x3000) == 0 || p->npoints<3) /* fixed (unlit) color */
  185.      return hue ? (hilite | hue | ((bright >> 4) & 0x0F)) : (bright | hilite);
  186.  
  187.      if (pcolor & 0x2000)     /* develop offset for metal/glass cycle */
  188.       {
  189.      color = poly_cosine(p, light1_x, light1_y, light1_z, light1_s);
  190.  
  191. /*       color = (-(color >> 1)) + bright >> 3;
  192.        color = (color & 16) ? (color & 15) | 0x100 : color & 15;  */
  193.  
  194.        asm {
  195.     mov    ax,color
  196.     shl    ax,1
  197.     sub    ax,bright
  198.     neg    ax
  199.     sar    ax,4
  200.     mov    ah,al
  201.     shr    ah,4
  202.     and    ax,010Fh
  203.     mov    color,ax
  204.        }
  205.  
  206.        return (hilite | hue | color);
  207.       }                /* compute brightness index */
  208.      color1 = color2 = 0;
  209.      if(light1_i) color1 = poly_cosine(p, light1_x, light1_y, light1_z, light1_s);
  210.      if(light2_i) color2 = poly_cosine(p, light2_x, light2_y, light2_z, light2_s);
  211.      if (color1 < 0) color1 = 0;
  212.      if (color2 < 0) color2 = 0;
  213.  
  214.      asm {
  215.     mov    ax,color1
  216.     mul    byte ptr light1_i
  217.     mov    bx,ax
  218.     mov    ax,color2
  219.     mul    byte ptr light2_i
  220.     add    ax,bx
  221.     shr    ax,7
  222.     add    ax,ambient_light
  223.     mul    byte ptr bright
  224.     shr    ax,11
  225.     mov    color,ax
  226.      }
  227.  
  228. /*     color = (( ((color*light_1+color*light_2) >> 7) + ambient_light)
  229.         * (bright >> 1) ) >>10;
  230.      color = (( ((color*(128-ambient_light)) >> 7) + ambient_light)
  231.         * (bright >> 1) ) >>10;           */
  232.  
  233.      if (color < 1) /* absolute zero: black */
  234.       return (hilite & 0x2000) ? (hilite | hue) : hilite;
  235.      if (color > 15) return (15 | hue | hilite);
  236.      return (color | hue | hilite);
  237.     }
  238.  
  239.    default:
  240.     return pcolor;
  241.   }
  242. }
  243.  
  244. unsigned convert_color(char *s, char **ptr)
  245.     {
  246.     int hue, value;
  247.     if (isdigit(*s)) return (unsigned) strtoul(s, ptr, 0);
  248.     if (ptr) for (*ptr = s; isalnum(**ptr) || **ptr == '_'; ++*ptr);
  249.     if (!strnicmp(s, "shaded", 6)) {
  250.         sscanf(s, "shaded_%d_%d", &hue, &value);
  251.         return 0x1000 | ((hue & 0x0F) << 8) | (value & 0xFF);
  252.         }
  253.     else if (!strnicmp(s, "metal", 5)) {
  254.         sscanf(s, "metal_%d_%d", &hue, &value);
  255.         return 0x2000 | ((hue & 0x0F) << 8) | ((value & 0x1F) << 3);
  256.         }
  257.     else if (!strnicmp(s, "glass", 5)) {
  258.         sscanf(s, "glass_%d_%d", &hue, &value);
  259.         return 0x3000 | ((hue & 0x0F) << 8) | ((value & 0x1F) << 3);
  260.         }
  261.     return 0;
  262.     }
  263.  
  264.