1 | /*
|
---|
2 | ===========================================================================
|
---|
3 | LSEG.C -- Generalized line drawing function (Integer DDA algorithm)
|
---|
4 | Version 6 -- 1987-08-04 -- D.N. Lynx Crowe
|
---|
5 | Copyright 1985, 1986, 1987 -- D.N. Lynx Crowe
|
---|
6 | ===========================================================================
|
---|
7 | */
|
---|
8 |
|
---|
9 | #include "ram.h"
|
---|
10 |
|
---|
11 | void (*point)(int16_t x, int16_t y, int16_t pen);
|
---|
12 |
|
---|
13 | #define ABS(x) ((x) < 0 ? (-(x)) : (x))
|
---|
14 | #define SIGN(x) ((x) < 0 ? (-1) : ((x) ? 1 : 0))
|
---|
15 |
|
---|
16 | #define LE <=
|
---|
17 |
|
---|
18 | /*
|
---|
19 | =============================================================================
|
---|
20 | lseg(x1, y1, x2, y2, t) -- draw a line from ('x1', 'y1') to ('x2', 'y2')
|
---|
21 | in drawing mode 't'.
|
---|
22 |
|
---|
23 | All coordinates are short integers in whatever plotting units the
|
---|
24 | 'point' function expects. No clipping or scaling is done, as this is
|
---|
25 | the lowest level 'line' primitive in the drawing code, and coordinates
|
---|
26 | are expected to have already been checked and found to be on screen.
|
---|
27 |
|
---|
28 | The 'point' variable must be initialized to point at the
|
---|
29 | pixel plotting function before this function is called. The pixel
|
---|
30 | plotting function is passed 3 arguments: the x coordinate, the y
|
---|
31 | coordinate, and the plotting mode. It is declared here as type 'short',
|
---|
32 | but any value it returns will be ignored.
|
---|
33 |
|
---|
34 | The register variable assignments were chosen based on the Alcyon C
|
---|
35 | compiler for the Atari 1040ST and reflect the capabilities of that
|
---|
36 | compiler. Other compilers may require different optimizations based
|
---|
37 | on their use of register variables.
|
---|
38 | =============================================================================
|
---|
39 | */
|
---|
40 |
|
---|
41 | void lseg(int16_t x1, int16_t y1, int16_t x2, int16_t y2, int16_t t)
|
---|
42 | {
|
---|
43 | register int16_t dx, dy, ptx, pty, p;
|
---|
44 | int16_t i, px, py;
|
---|
45 |
|
---|
46 | p = x2 - (ptx = x1);
|
---|
47 | dx = SIGN(p);
|
---|
48 | py = ABS(p);
|
---|
49 |
|
---|
50 | p = y2 - (pty = y1);
|
---|
51 | dy = SIGN(p);
|
---|
52 | px = ABS(p);
|
---|
53 |
|
---|
54 | (*point)(ptx, pty, t);
|
---|
55 |
|
---|
56 | if (py > px) {
|
---|
57 |
|
---|
58 | p = py >> 1;
|
---|
59 |
|
---|
60 | for (i = 1; i < py; i++) {
|
---|
61 |
|
---|
62 | ptx += dx;
|
---|
63 |
|
---|
64 | if ( (p -= px) < 0) {
|
---|
65 |
|
---|
66 | pty += dy;
|
---|
67 | p += py;
|
---|
68 | }
|
---|
69 |
|
---|
70 | (*point)(ptx, pty, t);
|
---|
71 | }
|
---|
72 |
|
---|
73 | } else {
|
---|
74 |
|
---|
75 | p = px >> 1;
|
---|
76 |
|
---|
77 | for (i = 1; i LE px; i++) {
|
---|
78 |
|
---|
79 | pty += dy;
|
---|
80 |
|
---|
81 | if ( (p -= py) < 0) {
|
---|
82 |
|
---|
83 | ptx += dx;
|
---|
84 | p += px;
|
---|
85 | }
|
---|
86 |
|
---|
87 | (*point)(ptx, pty, t);
|
---|
88 | }
|
---|
89 | }
|
---|
90 | }
|
---|