r7061: initial property settings
[ctsim.git] / libctgraphics / bresenham.cpp
index e9936fe0231d8cb44861c927b3cd5de5d002ad0a..43c8f349d2c68c42e1350fc9c73ebd8a085b2910 100644 (file)
-/* ; FILE IDENTIFICATION
-;
-;              Name:  CRT_LINE.ASM
-;           Purpose:  Draw lines on screen using Bresenham's integer algorithm
-;        Programmer:  Kevin Rosenberg
-;      Date Started:  1 Jun 84
-;  Last Modification: 15 Jul 85, Version 1.0
-;      
-; CORRESPONDENCE
-;      Kevin Rosenberg
-;      2515 E. 16th St.
-;      Newport Beach, CA 92663
-;      (714) 642-0119 (voice)
-;      (714) 842-6348 (E-Mail on Consultant's Exchange RBBS)
-;      Compuserve 73775,1232
-;
-; LANGAUGE
-;      IBM macro v1.000000000
-;
-; LANGAUGE INTERFACE
-;      Public routines callable from Lattice C v2.0+
-;          Works with S & L memory models.  Can easily add support for the
-;          other models by changing the STK structure below.
-;
-; NEEDED FILES
-;      egadrive.inc    Definitions, macros, & procedures for driving EGA
-;      hidden.inc      Defines OPTIONAL public procedure, crt_hdn_line().
-;      dos.mac         Lattice's file containing memory model macros
-;                      See inclusion statement for more documentation
-;
-; GRAPHIC MODES SUPPORTED
-;      - Standard CGA modes -- BIOS codes 4, 5, & 6 -- are support through
-;        the ROM BIOS pixel setting routine.  Things could be speeded up
-;        by a factor of 7-15 by writing to the video buffer directly.
-;      - You may remove support for the CGA completely by changing the
-;        EQU of STD_GRF to 0, a slight speed increase in EGA operations
-;        is the gain.
-;      - All EGA graphic modes are supported with optimized direct pixel
-;        accessing.  Note: mode 13 (320x200) is bugged, see LOG date 6-20-85
-;
-; LANGUAGE INTERFACE
-;      Lattice C v2.0+
-;
-; HISTORY LOG
-;    7-15-85
-;      Released in PD as version 1.0
-;    6-27-85
-;      Put EGA routines in INCLUDE file EGADRIVE.INC
-;      Put Hidden line routines in OPTIONAL INCLUDE file HIDDEN.INC
-;    6-20-85
-;      Tested with video modes 13 (320x200) & 14 (640x200).  Mode 14 worked
-;      ok, mode 13 was missing every other vertical line:  I'm probably
-;      not setting one of the myriad of registers correctly.  Since I'll
-;      never use mode 13, I won't investigate it further.
-;    6-05-85
-;      Added & updated documentation
-;    2-28-85
-;      Added hidden line routines
-;         PUBLIC crt_hdn_line plus internal routines
-;         (see function summary for more info)
-;    1-20-85
-;      Added global variable STD_GRF
-;         Will support standard graphic modes if it is set to non-zero value;
-;         however, the slow ROM BIOS is used as well as a slight overhead
-;         for the EG code.  IT IS MUCH FASTER TO USE THE EGA ENHANCED
-;         (350 line) GRAPHIC MODES.
-;    1-09-85
-;      Convert to support IBM's Enhanced graphics adapter.
-;      Remove all optimized code for color graphics adapter (CGA)
-;    7-16-84
-;      Changed calls to ROM that set pixels to speedy routines which use
-;      incremental address calculation and direct writing the to graphics
-;      buffer.
-;    1-12-84
-;      File creation:
-;           Converted C function, bresline.c, to assembly langauge.
-;           Retained C source of Bresenham's integer rastering algorithm
-;           as comments.
-;
-; FUNCTION SUMMARY 
-;
-;      crt_line_page (page)
-;              Set graphics page to plot lines on [default = 0]
-;
-;      crt_line_style (style)
-;              Set line style [Default = solid line]
-;
-;      crt_line (x1, y1, x2, y1, color)
-;              Plots a line on the screen using Bresenham's integer algorithm
-;
-;      crt_hdn_line (x1, y1, x2, y1, color, col_min, col_max)
-;              OPTIONAL routine to plots lines using hidden areas
-;              INCLUDE file HIDDEN.INC if you wish to use this routine
-;
-;      crt_init_hdn (col_min, col_max)
-;              Initializes vectors for use with crt_hdn_line()
-;
-;
-;      int x1, y1 - starting point
-;      int x2, y2 - end point
-;      int color  - color to draw line, as defined by IBM bios setting
-;      int linestyle - 16 bit wide dot setting pattern
-;      int col_min[640]  Minimum values for each X column (initialize to 349)
-;      int col_max[640]  Maximum values for each X column (initialize to 0)
-;                        (Do not display any points between the min & max,
-;                         and update these values for each new min & max)
-;                        If a vector == NULL, then do not clip against that
-;                        boundary.
-;
-; REFERENCES FOR BRESENHAM'S ALGORITHM
-;      Newman & Sproll, "Principals of Interactive Computer Graphics",
-;         page 25.
-;      Foley & van Dam, "Fundementals of Interactive Computer Graphics",
-;         page 433
-*/
-
-;------        Bresenham variables
-
-       deltx           dw      ?
-       delty           dw      ?
-       absdx           dw      ?
-       absdy           dw      ?
-       min_inc         dw      ?       ; (-1, 1) indicates direction of minor axis
-       dinc1           dw      ?       ; d increment if (d >= 0)
-       dinc2           dw      ?       ; d increment if (d < 0)
-
-
-
-
-;------------------------------------------------------------------------------
-; PROCEDURE
-;      crt_line [PUBLIC]       Plot a line on the screen using Bresenham's alg
-;
-; SYNOPSIS
-;      crt_line (x1, y1, x2, y2, color)
-
-void bresenham (int x1, int y1, int x2, int y2)
-{
-       delta_x = x2 - x1;
-        dx_abs = (delta_x >= 0 ? delta_x : -delta_x);
-
-       delta_y = y2 - y1;
-        dy_abs = (delta_y >= 0 ? delta_y : -delta_y);
-
-if (dx_abs > dy_abs) 
-    bresx();
-else
-   bresy();
-}
-
-lastx= x2;
-lasty = y2;
-
-
-;------------------------------------------------------------------------------
-; MACRO NAME
-;      BRES
-;
-; FUNCTION
-;      Do inner most loop to draw pictures
-;
-; SYNOPSIS
-;      BRES P1,P2
-;      P1      Major axis & direction 
-;      P2      Minor axis 
-;
-; EXAMPLES
-;      BRES INC_COL,ROW
-;
-; INPUT
-;      (DI)            Address of local routine to call when setting pixel
-;      (BX)            Decision variable
-;      (CX)            Number of points to plot on major axis (loop counter)
-;      [bp].min_inc    Direction of minor axis increments
-;      [bp].dinc1      Bresenham decision increments (see references)
-;      [bp].dinc2
-;      MACROS          ADDR_INC_ROW, _DEC_ROW, _INC_COL, _DEC_COL
-;
-; REGISTERS USED BY PIXEL SETTING ROUTINES
-;      (SI)            Offset in EGA buffer
-;      (AH)            Bitmask
-;
-; REGISTERS AVAILABLE FOR USE
-;      (AL)
-;      (DX)
-;
-; CALLS
-;      LS_PSET, this routine uses the addr in (DI) to set a point if
-;               the linestyle allows.
-;------------------------------------------------------------------------------
-
-BRES   MACRO   P1,P2
-       LOCAL   b0,b1
-       cmp     [bp].min_inc,0  ;if (min_inc >= 0)
-       jl      b0
-       _BRES   P1,INC_&P2      ;       inc_minor_axis
-       jmp     b1              ;else
-b0:    _BRES   P1,DEC_&P2      ;       dec_minor_axis
-b1:
-       ENDM
-
-
-_BRES  MACRO   P1,P2
-       LOCAL   bres0,bres1,bres2
-bres0:                         ; do {
-       LS_PSET                 ;       ls_pset() /* set pix using linestyle */
-
-       ADDR_&P1                        ;       P1 (change major axis)
-
-       cmp     bx,0            ;
-       jge     bres1           ;       if (d < 0)
-       add     bx,[bp].dinc2   ;           d += dinc2;
-       jmp     bres2           ;       else {
-bres1:                         ;
-       add     bx,[bp].dinc1   ;           d += dinc1
-       ADDR_&P2                        ;           P2 (change minor axis)
-                               ;       }
-bres2:
-       loop    bres0           ; } while (--count > 0)
-       ENDM
-
-bresx()
+/*****************************************************************************
+**  This is part of the CTSim program
+**  Copyright (c) 1983-2001 Kevin Rosenberg
+**
+**  $Id$
+**
+**  This program is free software; you can redistribute it and/or modify
+**  it under the terms of the GNU General Public License (version 2) as
+**  published by the Free Software Foundation.
+**
+**  This program is distributed in the hope that it will be useful,
+**  but WITHOUT ANY WARRANTY; without even the implied warranty of
+**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+**  GNU General Public License for more details.
+**
+**  You should have received a copy of the GNU General Public License
+**  along with this program; if not, write to the Free Software
+**  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+******************************************************************************/
+
+// REFERENCES FOR BRESENHAM'S ALGORITHM
+// Newman & Sproll, "Principals of Interactive Computer Graphics",  page 25.
+// Foley & van Dam, "Fundementals of Interactive Computer Graphics", page 433
+
+
+
+void 
+bresenham (int x1, int y1, int x2, int y2)
 {
-    /*    draws a line then abs(dx) >= abs(dy) */
-
-    int npix = dx_abs + 1;
-
-    /* determine direction of minor axis */
-
-    int  min_inc = 1;
-    if (delta_y < 0)
-       min_inc = -1;
-
-    /* Put decision variable in d */
-
-    int d = dy_abs * 2 - dx_abs;
+  int delta_x = x2 - x1;
+  int dx_abs = (delta_x >= 0 ? delta_x : -delta_x);
+  
+  int delta_y = y2 - y1;
+  int dy_abs = (delta_y >= 0 ? delta_y : -delta_y);
+  
+  // draws a line when abs(dx) >= abs(dy) 
+  if (dx_abs > dy_abs) {
+    int count = dx_abs + 1;
+    int major_inc = (x1 <= x2 ? 1 : -1);
+    int min_inc = (delta_y >= 0 ? 1 : -1);     // determine direction of minor axis 
+    
+    int d = dy_abs * 2 - dx_abs;      // Put decision variable in d
     int dinc1 = (dy_abs - dx_abs) * 2;
     int dinc2 = 2 * dy_abs;
-
-    if (x1 <= x2)
-       bres(INC_COL, ROW);
-    else 
-       breas (DEC_COL, ROW)l
-
-           }
-
-
-void bresy()
-{
-    /*;    bresy [LOCAL]       For plotting lines with abs(dy) > abs(sx)
-
- NOTES
-    Logic identical to bresx's, substitution x for y and
-    vice versa.  I separate the into two routines rather
-    than having the main loop spending time determining
-    which are the major & minor axis. 
-    */
-
-
+    
+    bresx (x1, y1, major_inc, d, d1, d2);
+  } else {    //For plotting lines with abs(dy) > abs(sx)
     int count = dy_abs + 1;
-
-    /* check direction of minor axis */
-
-    min_inc = 1;
-    if (delta_x < 0)
-       min_inc = -1;
-
-
+    
+    int major_inc = (y1 <= y2 ? 1 : -1);
+    int min_inc = (delta_x >= 0 ? 1 : -1);      // check direction of minor axis
+        
     int d = dx_abs * 2 - dy_abs;
     dinc1 = (dx_abs - dy_abs) * 2;
     dinc2 = 2 * dx_abs;
-
-    if (y1 <= y2)
-       bres(INC_ROW,COL);
-    else
-       bres(DEL_ROW,COL);
+    
+    bresy (x1, y1, major_inc, min_inc, count, d, d1, d2);
+  }
 }
 
+
+static void 
+bresx (int x, int y, int majorinc, int minorinc, int count, int d, int d1, int d2)
+{
+  do {
+    setpixel();
+    x += majorinc;
+    
+    if (d < 0)
+      d += dinc2;
+    else {
+      d += dinc1;
+      y += min_inc;
+    }
+  } while (--count > 0);
+}
+  
+  
+static void 
+bresy (int x, int y, int majorinc, int minorinc, int count, int d, int d1, int d2)
+{
+  do {
+    setpixel();
+    y += majorinc;
+    
+    if (d < 0)
+      d += dinc2;
+    else {
+      d += dinc1;
+      x += min_inc;
+    }
+  } while (--count > 0);
+}
+  
+