home *** CD-ROM | disk | FTP | other *** search
/ Virtual Reality Homebrewer's Handbook / vr.iso / vr386 / horizon.c < prev    next >
C/C++ Source or Header  |  1996-03-19  |  7KB  |  262 lines

  1. /* Horizon and window/screen clearing    */
  2. /* Written by Dave STampe, December 1993 */
  3. /* All algortims and code in this module by Dave Stampe */
  4.  
  5. /*
  6.  This code is part of the REND386 project, created by Dave Stampe and
  7.  Bernie Roehl.
  8.  
  9.  Copyright 1992, 1993, 1994 by Dave Stampe and Bernie Roehl.
  10.  
  11.  May be freely used to write software for release into the public domain;
  12.  all commercial endeavours MUST contact BOTH Bernie Roehl and Dave Stampe
  13.  for permission to incorporate any part of this software into their
  14.  products!  Usually there is no charge for under 50-100 items for
  15.  low-cost or shareware, and terms are reasonable.  Any royalties are used
  16.  for development, so equipment is often acceptable payment.
  17.  
  18.  ATTRIBUTION:  If you use any part of this source code or the libraries
  19.  in your projects, you must give attribution to REND386, Dave Stampe,
  20.  and Bernie Roehl in your documentation, source code, and at startup
  21.  of your program.  Let's keep the freeware ball rolling!  No more
  22.  code ripoffs please.
  23.  
  24.  CONTACTS: dstampe@psych.toronto.edu, broehl@sunee.uwaterloo.ca
  25.  See the COPYRITE.H file for more information.
  26. */
  27.  
  28. /* Contact: dstampe@sunee.waterloo.edu */
  29.  
  30. #include <stdio.h>
  31. #include <dos.h>
  32. #include <stdlib.h>    /* labs */
  33.  
  34. #include "3dstruct.h"
  35. #include "rendpriv.h"
  36. #include "renderer.h"
  37. #include "intmath.h"
  38.  
  39. #include "f3dkitd.h"    // for block clears
  40.  
  41. static void band_horizon(VIEW *v, int page, long step, int nstep, int *colorlist)
  42. {
  43.  int l = v->left;
  44.  int r = v->right;
  45.  int t = v->top;
  46.  int b = v->bottom;
  47.  int i, j, k;
  48.  int vert = 0;
  49.  int mfup, mfdn;
  50.  int upright;
  51.  int cd = 1;           /* step direction in thru color list */
  52.  
  53.  int vx[10],vy[10];
  54.  
  55.  long offset;
  56.  
  57.  int olx, orx, oly, ory;
  58.  int nlx, nrx, nly, nry;
  59.  
  60.  if(nstep==0)        /* just clear screen totally */
  61.   {
  62.    clr_block(l, t, r, b-1, page, colorlist[0]);
  63.    return;
  64.   }
  65.  
  66.  if(nstep>20) nstep = 20;
  67.  offset = -(step * nstep)/2;     /* uppermost position */
  68.  
  69.  mfup = (above_horizon(l,t,v,offset) ) +   /* corners with top of horizon */
  70.     (above_horizon(r,t,v,offset)<<1) +
  71.     (above_horizon(l,b,v,offset)<<2) +
  72.     (above_horizon(r,b,v,offset)<<3) ;
  73.  
  74.  mfdn = (above_horizon(l,t,v,-offset) ) +   /* corners with bot of horizon */
  75.     (above_horizon(r,t,v,-offset)<<1) +
  76.     (above_horizon(l,b,v,-offset)<<2) +
  77.     (above_horizon(r,b,v,-offset)<<3) ;
  78.  
  79.  if(mfup==15)                               /* sky only case */
  80.    {
  81.     clr_block(l, t, r, b-1, page, colorlist[0]);
  82.     return;
  83.    }
  84.  if(mfdn==0)                                /* ground only case */
  85.    {
  86.     clr_block(l, t, r, b-1, page, colorlist[nstep]);
  87.     return;
  88.    }
  89.  
  90.  if(labs(v->eye_xform[0][1]) > labs(v->eye_xform[1][1]) ) /* check slope */
  91.   {
  92.    vert++;        /* horizon is more vertical than horizontal */
  93.    upright = (v->eye_xform[0][1]>=0);       /* sky on left */
  94.   }
  95.  else upright = (v->eye_xform[1][1]>=0);  /* sky on top */
  96.  
  97.  if(!upright)         /* will work backwards through colors */
  98.   {                   /* and through horizon offsets */
  99.    cd = -1;
  100.    colorlist += nstep;
  101.    step = -step;
  102.    offset = step-offset;
  103.   }
  104.  
  105.  if(!vert)
  106.   {
  107.    olx = l;               /* forcing top... */
  108.    orx = r;
  109.    oly = ory = -32000;
  110.   }
  111.  else
  112.   {
  113.    oly = t;               /* forcing left... */
  114.    ory = b;
  115.    olx = orx = 32000;
  116.   }
  117.  
  118.  for(i=0;i<nstep;i++)
  119.   {
  120.    int nlx, nrx, nly, nry;
  121.                  /* compute new division */
  122.    if(!vert)
  123.     {
  124.      nlx = l;
  125.      nrx = r;
  126.      nly = y_horizon(l, v, offset);
  127.      nry = y_horizon(r, v, offset);
  128.     }
  129.    else
  130.     {
  131.      nly = t;
  132.      nry = b;
  133.      nlx = x_horizon(t, v, offset);
  134.      nrx = x_horizon(b, v, offset);
  135.     }
  136.  
  137.    vx[0] = orx;    // clip and render 4-vertex poly (most common)
  138.    vy[0] = ory;
  139.    vx[1] = olx;
  140.    vy[1] = oly;
  141.    vx[2] = nlx;
  142.    vy[2] = nly;
  143.    vx[3] = nrx;
  144.    vy[3] = nry;
  145.    render_ext_poly(4, vx, vy, *colorlist);
  146.    colorlist += cd;
  147.    olx = nlx;
  148.    oly = nly;
  149.    orx = nrx;
  150.    ory = nry;
  151.    offset += step;
  152.   }
  153.  
  154.  
  155.  vx[0] = orx;             /* finish off last slice */
  156.  vy[0] = ory;
  157.  vx[1] = olx;
  158.  vy[1] = oly;
  159.  if(!vert)
  160.   {
  161.    i = 32000;  /* force bottom */
  162.    vx[2] = l;
  163.    vy[2] = i;
  164.    vx[3] = r;
  165.    vy[3] = i;
  166.   }
  167.  else
  168.   {
  169.    i = -32000;  /* force right */
  170.    vx[2] = i;
  171.    vy[2] = t;
  172.    vx[3] = i;
  173.    vy[3] = b;
  174.   }
  175.  render_ext_poly(4, vx, vy, *colorlist);
  176.  
  177. }
  178.  
  179.  
  180. /*********** SKY/GROUNDCOLOR INTERFACE *********/
  181.  
  182. static int h2colors[2] = { 0xAe, 0x8D }; // 2-color horizon default
  183.  
  184. static int  horizon_ncolors = 2;          // cached clear arguments
  185. static int *horizon_colors = h2colors;
  186. static int  horizon_stepsize = 48;
  187.  
  188.  
  189. void set_skycolor(int color)
  190. {
  191.  h2colors[0] = color;
  192.  horizon_colors = h2colors;
  193.  horizon_ncolors = 2;
  194.  if(h2colors[0]==h2colors[1]) horizon_ncolors = 1;
  195. }
  196.  
  197. void set_groundcolor(int color)
  198. {
  199.  h2colors[1] = color;
  200.  horizon_colors = h2colors;
  201.  horizon_ncolors = 2;
  202.  if(h2colors[0]==h2colors[1]) horizon_ncolors = 1;
  203. }
  204.  
  205.  
  206. /*********** EXTERNAL HORIZON TYPE SETUP *********/
  207.  
  208. // args: ncolor = 0 for no clear, others 0
  209. //       ncolor = 1 for solid clear to skycolor, or skycolor=groundcolor
  210. //       ncolor = 2 for normal horizon, or skycolor<>groundcolor
  211. //       ncolor > 2 for banded horizon with array of colors from palette
  212. //     leave bandsize 0 (unchanged), or use 128 for best size
  213.  
  214. void set_horizon(int ncolors, int colors[16], int bandsize)
  215. {
  216.  horizon_ncolors = ncolors;
  217.  if(ncolors==0) return;          // horizon off: ignore rest
  218.  
  219.  if(ncolors<3 && colors==NULL) horizon_colors = h2colors;
  220.  if(colors!=NULL) horizon_colors = colors;
  221.  if(bandsize) horizon_stepsize = bandsize;
  222. }
  223.  
  224.  
  225.  
  226. /************* DRAW HORIZON/CLEAR WINDOW ************/
  227.  
  228. void horizon(VIEW *v, int page)    // clear window or draw horizon
  229. {
  230.   set_drawpage(page);
  231.   setup_hdwe(0);
  232.  
  233.   switch(horizon_ncolors)
  234.     {
  235.       case 0:             // no clear: whole page done before?
  236.     break;
  237.  
  238.       case 1:          // solid clear window
  239.     clr_block(v->left, v->top, v->right, v->bottom-1, page, horizon_colors[0]);
  240.     break;
  241.  
  242.       case 2:
  243.     band_horizon(v, page, 0, 1, horizon_colors);
  244.     break;
  245.  
  246.       default:
  247.     band_horizon(v, page, horizon_stepsize, horizon_ncolors-1, horizon_colors);
  248.     break;
  249.     }
  250.   reset_hdwe();
  251.   return;
  252. }
  253.  
  254. // some test values
  255.  
  256. //unsigned hcolors[20] = { 0xaf, 0xae, 0xad, 0xac, 0x79, 0x7a, 0x7b, 0x7c };
  257. //
  258. //test_h()
  259. //{
  260. // set_horizon(8, hcolors, 48);
  261. //}
  262.