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

  1. /* Written by Bernie Roehl, January 1992 */
  2. /* Redone by Dave Stampe for integer, fast polys, colors etc */
  3. /* Modified by Bernie Roehl to support surface types */
  4.  
  5. /* Copyright 1992 by Dave Stampe and Bernie Roehl.
  6.    May be freely used to write software for release into the public domain;
  7.    all commercial endeavours MUST contact Bernie Roehl and Dave Stamrpe
  8.    for permission to incorporate any part of this software into their
  9.    products!
  10.  
  11.      ATTRIBUTION:  If you use any part of this source code or the libraries
  12.      in your projects, you must give attribution to REND386, Dave Stampe,
  13.      and Bernie Roehl in your documentation, source code, and at startup
  14.      of your program.  Let's keep the freeware ball rolling!
  15.  */
  16.  
  17. /* Contact: broehl@sunee.waterloo.edu or dstampe@sunee.waterloo.edu */
  18.  
  19. #include <stdio.h>
  20. #include <dos.h>
  21. #include <stdlib.h>    /* labs */
  22. #include "f3dkitd.h"
  23. #include "rend386.h"
  24. #include "f3dkitd.h"
  25. #include "intmath.h"
  26. #include "splits.h"
  27.  
  28. #define MAIN_VGA  1  /* for multi-VGA only */
  29. #define LEFT_VGA  2
  30. #define RIGHT_VGA 4
  31. #define ALL_VGA   7
  32.  
  33. #define MONOSCOPIC 0 /* stereo types */
  34. #define SWITCHED   1
  35. #define SPLITLR    3
  36. #define SEPARATE   5
  37.  
  38. struct Screeninfo *screeninfo;
  39.  
  40. extern int set_colors(); /* defined in color file */
  41. extern int reset_colors();
  42. extern int screen_clear_color;
  43. extern int sky_color;
  44. extern int ground_color;
  45. extern int wireframe_color;
  46. extern int highlight_color;
  47. extern int highest_color;
  48.  
  49. extern int use_wide;
  50. extern int use_ht;
  51. extern int use_BW;
  52. extern int vdmode;
  53.  
  54. long display_tilt =8*65536L; /* correction for display toe-in */
  55.  
  56. enter_graphics() /* enter and setup graphics screen */
  57. {
  58.     int i;
  59.  
  60.     set_gmode(vdmode);
  61.     set_vpage(0);
  62.     set_drawpage(0);
  63.     clr_page(0,0);
  64.     set_colors(use_BW);
  65.  
  66.     return(0);
  67. }
  68.  
  69.  
  70. exit_graphics() /* exit and restore text screen */
  71. {
  72.     exit_gmode();
  73.     return 0;
  74. }
  75.  
  76. void clear_display(int pge)
  77. {
  78. if(pge<screeninfo->pages) clr_page(pge,screen_clear_color);
  79. }
  80.  
  81. void ptpoly(int count, int *pcoords, int color)
  82. {
  83.     int surface_type = (color>>12)&3;
  84.  
  85.     color &= 0xFFF;
  86.  
  87.     switch (surface_type) {
  88.     case 0:
  89.     case 1:
  90.         fastpoly(count, pcoords, color);
  91.         break;
  92.     case 2:
  93.         m_fastpoly(count, pcoords, color, 0xFF, 0x00);
  94.         break;
  95.     case 3:
  96.         m_fastpoly(count, pcoords, color, 0xAA, 0xFF);
  97.         break;
  98.     }
  99. }
  100.  
  101.  
  102. extern int above_horizon(long x, long y, VIEW *v, long offset);
  103. extern long y_horizon(long x, VIEW *v, long offset);
  104. extern long x_horizon(long y, VIEW *v, long offset);
  105. extern int clr_block(int left, int top, int right, int bottom, int page, int color);
  106.  
  107.  
  108. #define HORSTEP 128L
  109. #define HORDIVS 7
  110. unsigned hcolors[20] = { 0xae, 0xad, 0xac, 0xab, 0x8a, 0x8b, 0x8c, 0x8d };
  111.  
  112. void init_ext_poly();
  113. void add_ext_vertex(long x, long y);
  114. void render_ext_poly(unsigned color);
  115.  
  116.  
  117. static nhorizon(VIEW *v, int page, long step, int nstep, int *colorlist)
  118. {
  119.  int l = v->left;
  120.  int r = v->right;
  121.  int t = v->top;
  122.  int b = v->bottom;
  123.  int i, j, k;
  124.  int vert = 0;
  125.  int mfup, mfdn;
  126.  int upright;
  127.  int cd = 1;           /* step direction in thru color list */
  128.  
  129.  long offset;
  130.  
  131.  int olx, orx, oly, ory;
  132.  int nlx, nrx, nly, nry;
  133.  
  134.  if(nstep==0)        /* just clear screen totally */
  135.   {
  136.    clr_block(l, t, r, b, page, colorlist[0]);
  137.    return;
  138.   }
  139.  
  140.  if(nstep>20) nstep = 20;
  141.  offset = -(step * nstep)/2;     /* uppermost position */
  142.  
  143.  mfup = (above_horizon(l,t,v,offset) ) +   /* corners with top of horizon */
  144.     (above_horizon(r,t,v,offset)<<1) +
  145.     (above_horizon(l,b,v,offset)<<2) +
  146.     (above_horizon(r,b,v,offset)<<3) ;
  147.  
  148.  mfdn = (above_horizon(l,t,v,-offset) ) +   /* corners with bot of horizon */
  149.     (above_horizon(r,t,v,-offset)<<1) +
  150.     (above_horizon(l,b,v,-offset)<<2) +
  151.     (above_horizon(r,b,v,-offset)<<3) ;
  152.  
  153.  if(mfup==15)                               /* sky only case */
  154.    {
  155.     clr_block(l, t, r, b, page, colorlist[0]);
  156.     return;
  157.    }
  158.  if(mfdn==0)                                /* ground only case */
  159.    {
  160.     clr_block(l, t, r, b, page, colorlist[nstep]);
  161.     return;
  162.    }
  163.  
  164.  if(labs(v->eye_xform[0][1]) > labs(v->eye_xform[1][1]) ) /* check slope */
  165.   {
  166.    vert++;        /* horizon is more vertical than horizontal */
  167.    upright = (v->eye_xform[0][1]>=0);       /* sky on left */
  168.   }
  169.  else upright = (v->eye_xform[1][1]>=0);  /* sky on top */
  170.  
  171.  if(!upright)         /* will work backwards through colors */
  172.   {                   /* and through horizon offsets */
  173.    cd = -1;
  174.    colorlist += nstep;
  175.    step = -step;
  176.    offset = step-offset;
  177.   }
  178.  
  179.  if(!vert)
  180.   {
  181.    olx = l;               /* forcing top... */
  182.    orx = r;
  183.    oly = ory = -32000;
  184.   }
  185.  else
  186.   {
  187.    oly = t;               /* forcing left... */
  188.    ory = b;
  189.    olx = orx = 32000;
  190.   }
  191.  
  192.  for(i=0;i<nstep;i++)
  193.   {
  194.    int nlx, nrx, nly, nry;
  195.                                  /* compute new division */
  196.    if(!vert)
  197.     {
  198.      nlx = l;
  199.      nrx = r;
  200.      nly = y_horizon(l, v, offset);
  201.      nry = y_horizon(r, v, offset);
  202.     }
  203.    else
  204.     {
  205.      nly = t;
  206.      nry = b;
  207.      nlx = x_horizon(t, v, offset);
  208.      nrx = x_horizon(b, v, offset);
  209.     }
  210.  
  211.    init_ext_poly();              /* clip, draw polys */
  212.    add_ext_vertex(orx, ory);
  213.    add_ext_vertex(olx, oly);
  214.    add_ext_vertex(nlx, nly);
  215.    add_ext_vertex(nrx, nry);
  216.    render_ext_poly(*colorlist);
  217.    colorlist += cd;
  218.    olx = nlx;
  219.    oly = nly;
  220.    orx = nrx;
  221.    ory = nry;
  222.    offset += step;
  223.   }
  224.  
  225.  init_ext_poly();                 /* finish off last slice */
  226.  add_ext_vertex(orx, ory);
  227.  add_ext_vertex(olx, oly);
  228.  if(!vert)
  229.   {
  230.    i = 32000;  /* force bottom */
  231.    add_ext_vertex(l, i);
  232.    add_ext_vertex(r, i);
  233.   }
  234.  else
  235.   {
  236.    i = -32000;  /* force right */
  237.    add_ext_vertex(i, t);
  238.    add_ext_vertex(i, b);
  239.   }
  240.  render_ext_poly(*colorlist);
  241.  
  242. }
  243.  
  244. #define OLD_HORIZON 1
  245.  
  246. static void horizon(VIEW *v, int page)
  247. {
  248.  set_drawpage(page);
  249.  setup_hdwe(0);
  250.  
  251. #ifdef OLD_HORIZON
  252.  hcolors[0] = sky_color;
  253.  hcolors[1] = ground_color;
  254.  nhorizon(v, page, 0, 1, hcolors);
  255. #else
  256.  nhorizon(v, page, HORSTEP, HORDIVS, hcolors);
  257. #endif
  258.  
  259.  reset_hdwe();
  260.  return;
  261. }
  262.  
  263.  
  264. extern volatile int has_switched; /* 3 when Sega has shown both eyes */
  265. extern int v_page;
  266. extern int fancy_background, reflection_pool, have_logo, show_logo;
  267. extern int do_screen_clear, do_horizon;
  268. extern int reframe, use_frame;
  269. extern int stereo_type;
  270. extern int swap_eyes;
  271. extern int left_page, right_page;
  272. extern STEREO default_stereo;
  273. extern SPLIT *split_tree;
  274. extern int show_location, show_compass, show_framerate;
  275. extern int splitlx1, splitly1, splitlx2, splitly2;
  276.  
  277.  
  278. extern int screen_clear_color;
  279.  
  280. long last_render_time = 8; /* time in 1/180 sec to redraw */
  281.  
  282. static int ccyc[30] = { 
  283.     0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,
  284.     14,13,12,11,10,9,8,7,6,5,4,3,2,1 };
  285.  
  286. void background(int page, int top, int bot, int color)
  287. {
  288.     int inc = (top + (color & 15)) % 30;
  289.     color &= 0xF0;
  290.  
  291.     for (; top <= bot; top += 2)
  292.     {
  293.         clr_block(0, top, 319, top+1, page, color+ccyc[inc]);
  294.         if ((++inc) == 30) inc = 0;
  295.     }
  296. }
  297.  
  298. void reflection(int page, int top, int bot, int step)
  299. {
  300.     int src = top-step;
  301.  
  302.     for( ; top <= bot; top++)
  303.     {
  304.         copy_block(page, 0, src, page, 0, top, 320, 1);
  305.         src -= step;
  306.     }
  307. }
  308.  
  309. static void coord_ref(int xc, int yc, int size, VIEW *v, int xcolor, int ycolor, int zcolor, int bcolor)
  310. {
  311.     long x, y, z;
  312.     MATRIX m;
  313.  
  314.     if (show_compass == 0) return;
  315.  
  316.     view_to_matrix(v,m);
  317.     m[3][0] = m[3][1] = m[3][2] = 0;
  318.     matrix_transpose(m,m);
  319.  
  320.     setup_hdwe(0);
  321.     x = size; 
  322.     y = 0; 
  323.     z = 0;
  324.     matrix_point(m, &x, &y, &z);
  325.     if (v->orientation & XFLIP)
  326.     {
  327.         vgaline(xc,yc,xc-x,yc-y,bcolor);
  328.         printxyr(xc-x-5,yc-y,bcolor,"x",1);
  329.         setup_hdwe(0);
  330.         vgaline(xc-1,yc+1,xc-1-x,yc+1-y,xcolor);
  331.         printxyr(xc-x-5-1,yc-y+1,xcolor,"x",1);
  332.     }
  333.     else
  334.         {
  335.         vgaline(xc,yc,x+xc,yc-y,bcolor);
  336.         printxyr(x+xc+5,yc-y,bcolor,"x",0);
  337.         setup_hdwe(0);
  338.         vgaline(xc+1,yc+1,x+xc+1,yc-y+1,xcolor);
  339.         printxyr(x+xc+5+1,yc-y+1,xcolor,"x",0);
  340.     }
  341.  
  342.     setup_hdwe(0);
  343.     y = size; 
  344.     x = 0; 
  345.     z = 0;
  346.     matrix_point(m, &x, &y, &z);
  347.     if (v->orientation & XFLIP)
  348.     {
  349.         vgaline(xc,yc,xc-x,yc-y,bcolor);
  350.         printxyr(xc-x-5,yc-y,bcolor,"y",1);
  351.         setup_hdwe(0);
  352.         vgaline(xc-1,yc+1,xc-1-x,yc+1-y,ycolor);
  353.         printxyr(xc-x-5-1,yc-y+1,ycolor,"y",1);
  354.     }
  355.     else
  356.         {
  357.         vgaline(xc,yc,x+xc,yc-y,bcolor);
  358.         printxyr(x+xc+5,yc-y,bcolor,"y",0);
  359.         setup_hdwe(0);
  360.         vgaline(xc+1,yc+1,x+xc+1,yc-y+1,ycolor);
  361.         printxyr(x+xc+5+1,yc-y+1,ycolor,"y",0);
  362.     }
  363.  
  364.     setup_hdwe(0);
  365.     z = size; 
  366.     y = 0; 
  367.     x = 0;
  368.     matrix_point(m, &x, &y, &z);
  369.     if (v->orientation & XFLIP)
  370.     {
  371.         vgaline(xc,yc,xc-x,yc-y,bcolor);
  372.         printxyr(xc-x-5,yc-y,bcolor,"z",1);
  373.         setup_hdwe(0);
  374.         vgaline(xc-1,yc+1,xc-1-x,yc+1-y,zcolor);
  375.         printxyr(xc-x-5-1,yc-y+1,zcolor,"z",1);
  376.     }
  377.     else
  378.         {
  379.         vgaline(xc,yc,x+xc,yc-y,bcolor);
  380.         printxyr(x+xc+5,yc-y,bcolor,"z",0);
  381.         setup_hdwe(0);
  382.         vgaline(xc+1,yc+1,x+xc+1,yc-y+1,zcolor);
  383.         printxyr(x+xc+5+1,yc-y+1,zcolor,"z",0);
  384.     }
  385.     reset_hdwe();
  386. }
  387.  
  388.  
  389. static VIEW left_view, right_view;
  390.  
  391. extern int frame_x, frame_y, frame_w, frame_h;
  392.  
  393. void reset_screens()
  394. {
  395.     int i;
  396.     cursor_hide();
  397.     for (i = 0; i < 4; ++i) {
  398.         if (use_frame)
  399.             copy_block(3, 0, 0, i, frame_x, frame_y, frame_w, frame_h);
  400.         else
  401.             clear_display(i);
  402.     }
  403.     cursor_show(v_page);
  404. }
  405.  
  406. void screen_refresh(VIEW *current_view) /* now does stereo drawing */
  407. {
  408.     long old_time = current_time();
  409.     int mxpge = 2;
  410.     if (screeninfo->pages < 3) mxpge = 1;
  411.  
  412.     if (stereo_type == MONOSCOPIC)
  413.     {
  414.         if (reframe && use_frame) {
  415.             copy_block((v_page == 3) ? 0 : (v_page + 1), 0, 0,
  416.                 v_page, 0, 0, 320, 200);
  417.             reframe = 0;
  418.         }
  419.         if (++v_page > mxpge) v_page = 0; /* use 3 pages to avoid flicker */
  420.         set_drawpage(v_page);
  421.  
  422.         render_set_view(current_view);
  423.  
  424.         if (fancy_background)
  425.         {
  426.             if (have_logo && show_logo)
  427.                 background(v_page, 30, reflection_pool ? 160 : 199, 0xBF);
  428.             else background(v_page, 0, reflection_pool ? 160 : 199, 0xB0);
  429.         }
  430.         else if (use_frame && do_screen_clear && !do_horizon)
  431.             clr_block(current_view->left,current_view->top,
  432.                 current_view->right,current_view->bottom,
  433.                 v_page,screen_clear_color);
  434.         else if (do_horizon) {
  435.             horizon(current_view,v_page);
  436.         }
  437.         else if (do_screen_clear)
  438.             clear_display(v_page);
  439.         if (have_logo && show_logo)
  440.             copy_block(3, 0, 0, v_page, 0, 0, 320, 30);
  441.         render_split(split_tree, current_view);
  442.         if (reflection_pool) reflection(v_page, 160, 199, 3);
  443.         status_on_screen();
  444.         coord_ref(250,65,35,current_view,15,13,10,0);
  445.         set_vpage(v_page);
  446.         cursor_hide();
  447.     }
  448.  else if (stereo_type==SPLITLR)
  449.     {
  450.     if (++v_page > mxpge) v_page = 0;
  451.     make_stereo_view(current_view,&left_view,LEFT_EYE);
  452.  
  453.     set_drawpage(v_page);
  454.     render_set_view(&left_view);
  455.     if (do_horizon) horizon(&left_view,v_page);
  456.     else clear_display(v_page);
  457.  
  458.     setup_hdwe(0);
  459.     render_split(split_tree, &left_view);
  460.     reset_hdwe();
  461.     make_stereo_view(current_view,&right_view,RIGHT_EYE);
  462.     render_set_view(&right_view);
  463.     if (do_horizon) horizon(&right_view,v_page);
  464.     setup_hdwe(0);
  465.     render_split(split_tree, &right_view);
  466.     reset_hdwe();
  467.     set_vpage(v_page);
  468.     cursor_hide();
  469.     if(splitlx1 >= 0)
  470.       {
  471.        setup_hdwe(0);
  472.        vgaline(splitlx1, splitly1, splitlx2, splitly2, highest_color);
  473.        reset_hdwe();
  474.       }
  475.     if (mxpge < 2) vsync();
  476.     }
  477.  else
  478.     {
  479.     v_page = v_page ^ 2;
  480.  
  481.     if (stereo_type == SWITCHED)
  482.         {
  483.         make_stereo_view(current_view,&left_view,0);
  484.         while ((has_switched&1) == 0) if (kbhit()) break;
  485.         set_drawpage(v_page);
  486.         render_set_view(&left_view);
  487.         if (do_horizon) horizon(&left_view,v_page);
  488.         else if (do_screen_clear)
  489.         clear_display(v_page);
  490.         render_split(split_tree, &left_view);
  491.         setup_hdwe(0);
  492.         printxyr(20,10,0,"L",0);
  493.         status_on_screen();
  494.         reset_hdwe();
  495.         coord_ref(250,65,35,current_view,15,13,10,0);
  496.         make_stereo_view(current_view,&right_view,1);
  497.         while ((has_switched&2) == 0) if (kbhit()) break;
  498.         set_drawpage(v_page+1);
  499.         render_set_view(&right_view);
  500.         if (do_horizon) horizon(&right_view,v_page+1);
  501.         else if (do_screen_clear)
  502.             clear_display(v_page+1); /* right page */
  503.         render_split(split_tree, &right_view);
  504.         setup_hdwe(0);
  505.         printxyr(300,10,0,"R",0);
  506.         status_on_screen();
  507.         reset_hdwe();
  508.         coord_ref(250,65,35,current_view,15,13,10,0);
  509.         disable();
  510.         if (swap_eyes)
  511.             {
  512.             left_page = v_page+1; /* display them now */
  513.             right_page = v_page;
  514.             }
  515.         else
  516.             {
  517.             left_page = v_page;
  518.             right_page = v_page+1;
  519.             }
  520.         has_switched = 0;
  521.         enable();
  522.         cursor_hide();
  523.         }
  524.     else if (stereo_type == SEPARATE) /* wide- angle display with seperate VGA cards */
  525.         {
  526.         set_drawpage(v_page);
  527.         VGA_select(swap_eyes ? RIGHT_VGA : LEFT_VGA|MAIN_VGA);
  528.         make_stereo_view(current_view, &left_view,0);
  529.         render_set_view(&left_view);
  530.         if (do_horizon) horizon(&left_view,v_page);
  531.         else if (do_screen_clear)
  532.                 clear_display(v_page);
  533.         render_split(split_tree, &left_view);
  534.         setup_hdwe(0);
  535.         printxyr(20,10,0,"L",0);
  536.         reset_hdwe();
  537.  
  538.         VGA_select(swap_eyes ? LEFT_VGA|MAIN_VGA : RIGHT_VGA);
  539.         make_stereo_view(current_view, &right_view, 1);
  540.         render_set_view(&right_view);
  541.         if (do_horizon) horizon(&right_view,v_page);
  542.         else if (do_screen_clear)
  543.                 clear_display(v_page);
  544.         render_split(split_tree, &right_view);
  545.         setup_hdwe(0);
  546.         printxyr(20,10,0,"R",1);
  547.         coord_ref(60,175,25,&right_view,15,14,13,0);
  548.         reset_hdwe();
  549.  
  550.         VGA_select(LEFT_VGA|MAIN_VGA);
  551.         set_vpage(v_page);
  552.         VGA_select(LEFT_VGA);
  553.         VGA_select(RIGHT_VGA);
  554.         set_vpage(v_page);
  555.         VGA_select(MAIN_VGA);
  556.         cursor_hide();
  557.         }
  558.     }
  559.  
  560.     last_render_time = current_time() - old_time;
  561.     if (last_render_time == 0) last_render_time++;
  562.     if (show_framerate)
  563.     {
  564.         char c[69];
  565.         sprintf(c,"Frames/sec: %d",get_ticks_per_second()/last_render_time);
  566.         printxyr(5,170,15,c,0);
  567.     }
  568.     set_drawpage(v_page);
  569.     cursor_show(v_page);
  570.  
  571. }
  572.  
  573.  
  574.  
  575. /********************************************************/
  576. /* USER ROUTINES CALLED BY THE RENDERING LIBRARY        */
  577. /* KEEP THIS AS FAST AS POSSIBLE: SOME MAY BE           */
  578. /* CALLED UP TO 1000 TIMES PER SCREEN!                  */
  579. /********************************************************/
  580.  
  581. extern int wireframe;
  582.  
  583. /* USER ROUTINE TO SETUP FOR POLY DRAWING - CALLED ONCE PER FRAME */
  584. void user_setup_blitter()
  585. {
  586.     setup_hdwe(0);
  587. }
  588.  
  589. /* USER ROUTINE TO RECOVER AFTER POLY DRAWING: ONCE PER FRAME */
  590. void user_reset_blitter()
  591. {
  592.     reset_hdwe();
  593. }
  594.  
  595.  
  596. /* USER ROUTINE TO DRAW TEXT BOXES */
  597. void user_box(int x1, int y1, int x2, int y2, int color)
  598. {
  599.     int av[8];
  600.  
  601.     setup_hdwe(0);
  602.  
  603.     if (x1 < screeninfo->xmin) x1 = screeninfo->xmin; 
  604.     if (x2 < screeninfo->xmin) x2 = screeninfo->xmin;
  605.     if (y1 < screeninfo->ymin) y1 = screeninfo->ymin; 
  606.     if (y2 < screeninfo->ymin) y2 = screeninfo->ymin;
  607.     if (x1 > screeninfo->xmax) x1 = screeninfo->xmax; 
  608.     if (x2 > screeninfo->xmax) x2 = screeninfo->xmax;
  609.     if (y1 > screeninfo->ymax) y1 = screeninfo->ymax; 
  610.     if (y2 > screeninfo->ymax) y2 = screeninfo->ymax;
  611.  
  612.     av[0] = x1; 
  613.     av[1] = y1;
  614.     av[2] = x1; 
  615.     av[3] = y2;
  616.     av[4] = x2; 
  617.     av[5] = y2;
  618.     av[6] = x2;
  619.     av[7] = y1;
  620.  
  621.     fastpoly(4, &av[0], color);
  622.     reset_hdwe();
  623. }
  624.  
  625. /* USER ROUTINE TO DRAW TEXT */
  626. void user_text(int x, int y, int color, char *string)
  627. {
  628.     printxyr(x, y, color, string,0);
  629. }
  630.  
  631.  
  632. static int x1, y1;
  633. static void vlineto(int x, int y, int color)
  634. {
  635.     vgaline(x,y,x1,y1,color);
  636.     x1 = x;
  637.     y1 = y;
  638. }
  639.  
  640. /* CALLED FROM RENDREP TO DRAW POLYS */
  641.  
  642. void user_render_poly(int number, int *pcoords, unsigned color, long maxz)
  643. {
  644.     int i;
  645.  
  646.     if (number == 1)
  647.     {
  648.         vgapoint(pcoords[0], pcoords[1], color);
  649.         return;
  650.     }
  651.     if (number == 2)
  652.     {
  653.         vgaline(pcoords[0],pcoords[1],pcoords[2],pcoords[3],color);
  654.         return;
  655.     }
  656.     if (!wireframe)
  657.     {
  658.         ptpoly(number, pcoords, color);
  659.  
  660.         if (color & 0x8000) /* highlighted? */
  661.         {
  662.             x1 = pcoords[0];
  663.             y1 = pcoords[1];
  664.             for (i = 1; i < number; ++i) vlineto(pcoords[i+i], pcoords[i+i+1], highlight_color);
  665.             vlineto(pcoords[0], pcoords[1], highlight_color);
  666.         }
  667.     }
  668.     else
  669.         {
  670.         x1 = pcoords[0];
  671.         y1 = pcoords[1];
  672.         for (i = 1; i < number; ++i) vlineto(pcoords[i+i], pcoords[i+i+1], wireframe_color);
  673.         vlineto(pcoords[0], pcoords[1], wireframe_color);
  674.     }
  675. }
  676.  
  677. void vgabox(int left, int top, int right, int bottom, int color)
  678. {
  679.     setup_hdwe(0);
  680.     vgaline(left, top, right, top, color);
  681.     vgaline(right, top, right, bottom, color);
  682.     vgaline(right, bottom, left, bottom, color);
  683.     vgaline(left, bottom, left, top, color);
  684.     reset_hdwe();
  685. }
  686.