Jspice3
mfbpoly.c
Go to the documentation of this file.
1 /*************************************************************************
2  MFB graphics and miscellaneous library
3  Copyright (c) Stephen R. Whiteley 1992
4  Author: Stephen R. Whiteley
5  *************************************************************************/
6 
7 #include "mfb.h"
8 #include "mfbP.h"
9 #include <dos.h>
10 
11 #define ror(x,n) ((x >> n) | (x << (8-n)))
12 
13 #define pswap(tab,i,j) {int temp; temp = *((tab)+(i));\
14  *((tab)+(i)) = *((tab)+(j));\
15  *((tab)+(j)) = temp; }
16 
18 
19 #ifdef __STDC__
20 static void sort(int*,int,int);
21 static void mode_1_zoids(int*,int*,int,int,int);
22 static void mode_2_zoids(int*,int*,int,int,int);
23 #else
24 static void sort();
25 static void mode_1_zoids();
26 static void mode_2_zoids();
27 #endif
28 
29 
30 void
32 MFBPOLYGON *poly;
33 {
34  int i, twonvert, *line, stored = 0;
35  int *xup, *ll, ny;
36  int *xlp, *xip;
37  int yl, yu;
38  int sto1, sto2;
39  int *ylist = (int *) mfb_polybuffer;
40  int *xulist = ylist + MFBMAXPOLYGONVERTICES;
41  int *xllist = xulist + MFBMAXPOLYGONVERTICES;
42  int *xilist = xllist + MFBMAXPOLYGONVERTICES;
43 
44  twonvert = poly->nvertices << 1;
45 
46  line = (int *) poly->xy;
47 
48  if ((line[0] != line[twonvert-2]) || (line[1] != line[twonvert-1])) {
49 
50  sto1 = line[twonvert]; /* who knows what lives here! */
51  sto2 = line[twonvert+1]; /* might generate gp fault */
52  line[twonvert] = line[0]; /* on extremely rare occasions */
53  line[twonvert+1] = line[1];
54  twonvert += 2;
55  stored = 1;
56  }
57 
58  xip = line + twonvert;
59  ll = ylist;
60  while (line < xip) {
61  *ll++ = *(line+1);
62  line += 2;
63  }
64  ny = ll-ylist-1;
65  sort(ylist,0,ny);
66 
67  xip = xilist;
68  ll = ylist;
69  while (ny--) {
70  yl = *ll;
71  yu = *(++ll);
72  while (yu == yl) {
73  if (!ny) goto done;
74  ny--;
75  yu = *(++ll);
76  }
77  memcpy(xllist,xilist,(int)((char *) xip - (char *) xilist));
78  xlp = xllist + (int) (xip - xilist);
79  xup = xulist;
80  xip = xilist;
81 
82  for (i = twonvert - 4; i >= 0; i -= 2) {
83  line = (int *) poly->xy + i;
84  if (((line[1] > yu) && (line[3] < yu)) ||
85  ((line[3] > yu) && (line[1] < yu))) {
86 
87  *xup++ = *xip++ = line[0] +
88  ((long)(yu-line[1])*(line[2]-line[0])) /
89  (line[3]-line[1]);
90  }
91  if (line[1] == yu) {
92 
93  if (line[3] < yu)
94  *xup++ = line[0];
95 
96  if (i) {
97  if (*(line-1) < yu)
98  *xup++ = line[0];
99  }
100  else
101  if (line[twonvert-3] < yu)
102  *xup++ = line[0];
103  }
104  if (line[1] == yl) {
105 
106  if (line[3] > yl)
107  *xlp++ = line[0];
108 
109  if (i) {
110  if (*(line-1) > yl)
111  *xlp++ = line[0];
112  }
113  else
114  if (line[twonvert-3] > yl)
115  *xlp++ = line[0];
116  }
117  }
118 
119  sort(xulist,0,(int)(xup-xulist-1));
120  sort(xllist,0,(int)(xlp-xllist-1));
121 
122  if (pc.mfbMODE & 2)
123  mode_2_zoids(xllist,xulist,(int)(xlp-xllist),yl,yu);
124  else
125  mode_1_zoids(xllist,xulist,(int)(xlp-xllist),yl,yu);
126  }
127 done:
128  if (stored) {
129  line = (int *) poly->xy;
130  line[twonvert-2] = sto1;
131  line[twonvert-1] = sto2;
132  }
133 }
134 
135 
136 static void
137 sort(tab,left,right)
138 
139 int left,right, *tab;
140 {
141  int i, last;
142 
143  if (right <= left) return;
144  i = (left + right) >> 1;
145  pswap(tab,left,i);
146  last = left;
147  for (i = left + 1; i <= right; i++)
148  if (tab[i] < tab[left]) {
149  last++;
150  pswap(tab,last,i);
151  }
152  pswap(tab,left,last);
153  sort(tab,left,last-1);
154  sort(tab,last+1,right);
155 }
156 
157 
158 static void
159 mode_1_zoids(xll,xul,num,yl,yu)
160 
161 int *xll, *xul, num, yl, yu;
162 {
163  int x1, x2, x3, x4;
164  int dx, dy, dy2, dx1, dx2, errterm1, errterm2;
165  int i, s1, s2, lnum, lcnt, next, *st = NULL;
166  vidmptr rgen, rgen0, rgen1;
167  unsigned char left, right, cbuf;
168  union { unsigned short color2; unsigned char c[2]; } c;
169 
170  if (pc.curfillpatt)
171  st = pc.stipples[pc.curfillpatt];
172 
173  c.c[0] = pc.curcolor;
174  c.c[1] = c.c[0];
175  lnum = (pc.ysize-1-yu);
176 
177  dy2 = yu - yl;
178 
179  next = pc.bytpline;
180  rgen1 = pc.base + (long) lnum*next;
181 
182  outpw(0x3ce,0x0b05); /* read mode 1, write mode 3 */
183  outpw(0x3ce,c.color2 & 0xff00); /* set/reset */
184  outpw(0x3ce,0x7); /* zero color dont care */
185  outpw(0x3ce,pc.alumode); /* set alu mode */
186 
187  for (i = 0; i < num; i += 2) {
188 
189  rgen0 = rgen1;
190 
191  x1 = xll[i];
192  x4 = xll[i+1];
193  x2 = xul[i];
194  x3 = xul[i+1];
195 
196  dy = dy2 + 1;
197 
198  dx1 = x1 - x2;
199  dx2 = x3 - x4;
200  s1 = 1;
201  s2 = -1;
202  if (x2 >= x1) { dx1 = -dx1; s1 = -1; }
203  if (x4 >= x3) { dx2 = -dx2; s2 = 1; }
204  errterm1 = errterm2 = 0;
205  x3++;
206  x4++;
207 
208  if (!st)
209  while (dy--) {
210  left = (0xff >> (x2 & 7));
211  right = ~(0xff >> (x3 & 7));
212  dx = (x3 >> 3) - (x2 >> 3) - 1;
213  if (dx < 0) { left &= right; dx = 0; right = 0; }
214  rgen = rgen0 + (x2 >> 3);
215  mfb_trash = *rgen;
216  *rgen = left;
217  rgen++;
218  while (dx--) {
219  mfb_trash = *rgen;
220  *rgen = 0xff;
221  rgen++;
222  }
223  mfb_trash = *rgen;
224  *rgen = right;
225  rgen0 += next;
226  errterm1 += dx1;
227  errterm2 += dx2;
228  while (errterm1 > 0 && x1 != x2) {
229  errterm1 -= dy2;
230  x2 += s1;
231  }
232  while (errterm2 > 0 && x3 != x4) {
233  errterm2 -= dy2;
234  x3 += s2;
235  }
236  }
237  else {
238  lcnt = lnum;
239  while (dy--) {
240  left = (0xff >> (x2 & 7));
241  right = ~(0xff >> (x3 & 7));
242  dx = (x3 >> 3) - (x2 >> 3) - 1;
243  if (dx < 0) { left &= right; dx = 0; right = 0; }
244  rgen = rgen0 + (x2 >> 3);
245  cbuf = st[lcnt++ & 7];
246  mfb_trash = *rgen;
247  *rgen = cbuf & left;
248  rgen++;
249  while (dx--) {
250  mfb_trash = *rgen;
251  *rgen = cbuf;
252  rgen++;
253  }
254  mfb_trash = *rgen;
255  *rgen = cbuf & right;
256  rgen0 += next;
257 
258  errterm1 += dx1;
259  errterm2 += dx2;
260  while (errterm1 > 0 && x1 != x2) {
261  errterm1 -= dy2;
262  x2 += s1;
263  }
264  while (errterm2 > 0 && x3 != x4) {
265  errterm2 -= dy2;
266  x3 += s2;
267  }
268  }
269  }
270  }
271  outpw(0x3ce,0x5);
272  outpw(0x3ce,0xff07);
273 }
274 
275 
276 #ifndef __GNUC__
277 
278 static void
279 mode_2_zoids(xll,xul,num,yl,yu)
280 
281 int *xll, *xul, num, yl, yu;
282 {
283  int x1, x2, x3, x4;
284  int dy, dy2, dx1, dx2, errterm1, errterm2;
285  unsigned short dx;
286  int i, s1, s2, lnum, lcnt, next, *st = NULL;
287  unsigned char left, right, cbuf;
288  union { unsigned short o[2]; long l; } p1, p2, p3, p4;
289  union { unsigned short color2; unsigned char c[2]; } c;
290  vidmptr rgen;
291 
292  if (pc.curfillpatt)
293  st = pc.stipples[pc.curfillpatt];
294 
295  c.c[0] = pc.curcolor;
296  c.c[1] = c.c[0];
297  lnum = (pc.ysize-1-yu);
298 
299  outpw(0x3ce,0xff08); /* set bit mask */
300  outpw(0x3ce,pc.alumode); /* set alu mode */
301 
302  dy2 = yu - yl;
303 
304  next = pc.xsize;
305  p4.l = (long) lnum*next;
306  cbuf = inp(0x3cd);
307  cbuf |= (cbuf << 4);
308  for (i = 0; i < num; i += 2) {
309 
310  p3.l = p4.l;
311 
312  x1 = xll[i];
313  x4 = xll[i+1];
314  x2 = xul[i];
315  x3 = xul[i+1];
316 
317  dy = dy2 + 1;
318 
319  dx1 = x1 - x2;
320  dx2 = x3 - x4;
321  s1 = 1;
322  s2 = -1;
323  if (x2 >= x1) { dx1 = -dx1; s1 = -1; }
324  if (x4 >= x3) { dx2 = -dx2; s2 = 1; }
325  errterm1 = errterm2 = 0;
326  x3++;
327  x4++;
328 
329  if (!st) {
330 
331  while (dy--) {
332  dx = x3 - x2;
333  p1.l = p3.l + x2;
334  p2.l = p3.l + x3;
335  if (p1.o[1] != p2.o[1])
336  dx = ~(p1.o[0]) + 1;
337  if ((cbuf & 0xf) != p1.o[1]) {
338  cbuf = p1.o[1];
339  cbuf |= (cbuf << 4);
340  outp(0x3cd,cbuf);
341  }
342  rgen = pc.base + p1.o[0];
343  if (pc.alumode == 3) {
344  if ((unsigned)rgen & 1) {
345  *rgen = c.c[0];
346  rgen++;
347  dx--;
348  }
349  if (dx & 1)
350  *(rgen + dx - 1) = c.c[0];
351  dx >>= 1;
352  while (dx--) {
353  *(short far *)rgen = c.color2;
354  rgen += 2;
355  }
356  }
357  else {
358  while (dx--) {
359  mfb_trash = *rgen;
360  *rgen = c.c[0];
361  rgen++;
362  }
363  }
364 
365  if (p1.o[1] != p2.o[1]) {
366  outp(0x3cd,cbuf + 0x11);
367  dx = p2.o[0];
368  rgen = pc.base;
369  if (pc.alumode == 0x3) {
370  if (dx & 1)
371  *(rgen + dx - 1) = c.c[0];
372  dx >>= 1;
373  while (dx--) {
374  *(short far *)rgen = c.color2;
375  rgen += 2;
376  }
377  }
378  else {
379  while (dx--) {
380  mfb_trash = *rgen;
381  *rgen = c.c[0];
382  rgen++;
383  }
384  }
385 
386  }
387  p3.l += next;
388 
389  errterm1 += dx1;
390  errterm2 += dx2;
391  while (errterm1 > 0 && x1 != x2) {
392  errterm1 -= dy2;
393  x2 += s1;
394  }
395  while (errterm2 > 0 && x3 != x4) {
396  errterm2 -= dy2;
397  x3 += s2;
398  }
399  }
400  }
401  else {
402  lcnt = lnum;
403  while (dy--) {
404  right = st[lcnt++ & 7];
405  left = 0x80 >> (x2 & 7);
406  dx = x3 - x2;
407  p1.l = p3.l + x2;
408 
409  if ((cbuf & 0xf) != p1.o[1]) {
410  cbuf = p1.o[1];
411  cbuf |= (cbuf << 4);
412  outp(0x3cd,cbuf);
413  }
414  rgen = pc.base + p1.o[0];
415 
416  while (dx--) {
417  if (left & right) {
418  if (pc.alumode != 3)
419  mfb_trash = *rgen;
420  *rgen = c.c[0];
421  }
422  left = ror(left,1);
423  rgen++;
424  }
425  if (p1.o[1] != p2.o[1]) {
426  outp(0x3cd,cbuf + 0x11);
427  dx = p2.o[0];
428  rgen = pc.base;
429  while (dx--) {
430  if (left & right) {
431  if (pc.alumode != 3)
432  mfb_trash = *rgen;
433  *rgen = c.c[0];
434  }
435  left = ror(left,1);
436  rgen++;
437  }
438  }
439 
440  p3.l += next;
441  errterm1 += dx1;
442  errterm2 += dx2;
443  while (errterm1 > 0 && x1 != x2) {
444  errterm1 -= dy2;
445  x2 += s1;
446  }
447  while (errterm2 > 0 && x3 != x4) {
448  errterm2 -= dy2;
449  x3 += s2;
450  }
451  }
452  }
453  }
454 }
455 
456 
457 #else /* __GNUC__ */
458 
459 
460 static void
461 mode_2_zoids(xll,xul,num,yl,yu)
462 
463 int *xll, *xul, num, yl, yu;
464 {
465  int x1, x2, x3, x4;
466  int dx, dy, dy2, dx1, dx2, errterm1, errterm2;
467  int i, s1, s2, lnum, lcnt, next, *st = NULL;
468  unsigned char left, right;
469  int p0, p1;
470  union { unsigned short color2; unsigned char c[2]; } c;
471  vidmptr rgen;
472 
473  if (pc.curfillpatt)
474  st = pc.stipples[pc.curfillpatt];
475 
476  c.c[0] = pc.curcolor;
477  c.c[1] = c.c[0];
478  lnum = (pc.ysize-1-yu);
479 
480  outpw(0x3ce,0xff08); /* set bit mask */
481  outpw(0x3ce,pc.alumode); /* set alu mode */
482 
483  dy2 = yu - yl;
484  next = pc.xsize;
485  p0 = (long) lnum*next;
486 
487  for (i = 0; i < num; i += 2) {
488 
489  p1 = p0;
490 
491  x1 = xll[i];
492  x4 = xll[i+1];
493  x2 = xul[i];
494  x3 = xul[i+1];
495 
496  dy = dy2 + 1;
497 
498  dx1 = x1 - x2;
499  dx2 = x3 - x4;
500  s1 = 1;
501  s2 = -1;
502  if (x2 >= x1) { dx1 = -dx1; s1 = -1; }
503  if (x4 >= x3) { dx2 = -dx2; s2 = 1; }
504  errterm1 = errterm2 = 0;
505  x3++;
506  x4++;
507 
508  if (!st) {
509 
510  while (dy--) {
511  dx = x3 - x2;
512  rgen = pc.base + p1 + x2;
513  if (pc.alumode == 3) {
514  if ((unsigned)rgen & 1) {
515  *rgen = c.c[0];
516  rgen++;
517  dx--;
518  }
519  if (dx & 1)
520  *(rgen + dx - 1) = c.c[0];
521  dx >>= 1;
522  while (dx--) {
523  *(short*)rgen = c.color2;
524  rgen += 2;
525  }
526  }
527  else {
528  while (dx--) {
529  mfb_trash = *rgen;
530  *rgen = c.c[0];
531  rgen++;
532  }
533  }
534  p1 += next;
535  errterm1 += dx1;
536  errterm2 += dx2;
537  while (errterm1 > 0 && x1 != x2) {
538  errterm1 -= dy2;
539  x2 += s1;
540  }
541  while (errterm2 > 0 && x3 != x4) {
542  errterm2 -= dy2;
543  x3 += s2;
544  }
545  }
546  }
547  else {
548  lcnt = lnum;
549  while (dy--) {
550  right = st[lcnt++ & 7];
551  left = 0x80 >> (x2 & 7);
552  dx = x3 - x2;
553  rgen = pc.base + p1 + x2;
554 
555  while (dx--) {
556  if (left & right) {
557  if (pc.alumode != 3)
558  mfb_trash = *rgen;
559  *rgen = c.c[0];
560  }
561  left = ror(left,1);
562  rgen++;
563  }
564  p1 += next;
565  errterm1 += dx1;
566  errterm2 += dx2;
567  while (errterm1 > 0 && x1 != x2) {
568  errterm1 -= dy2;
569  x2 += s1;
570  }
571  while (errterm2 > 0 && x3 != x4) {
572  errterm2 -= dy2;
573  x3 += s2;
574  }
575  }
576  }
577  }
578 }
579 
580 #endif /* __GNUC__ */
static void mode_2_zoids()
#define MFBMAXPOLYGONVERTICES
Definition: mfb.h:32
if(TDesc==NULL)
Definition: cd.c:1326
int mfbMODE
Definition: mfbp.h:41
char mfb_trash
Definition: mfbopen.c:15
Definition: subckt.c:51
Definition: cddefs.h:312
#define MFBPOLYGONBUFSIZE
Definition: mfb.h:31
static void sort()
long mfb_polybuffer[2 *MFBPOLYGONBUFSIZE]
Definition: mfbpoly.c:17
int stipples[10][8]
Definition: mfbp.h:70
char * vidmptr
Definition: mfbp.h:17
int ysize
Definition: mfbp.h:54
Definition: fteinp.h:14
vidmptr base
Definition: mfbp.h:38
#define NULL
Definition: spdefs.h:121
int alumode
Definition: mfbp.h:56
Definition: mfb.h:104
static double c
Definition: vectors.c:16
#define pswap(tab, i, j)
Definition: mfbpoly.c:13
static void mode_1_zoids()
Definition: cddefs.h:142
int xsize
Definition: mfbp.h:53
while(TDesc->tSucc!=NULL)
Definition: cd.c:1335
Definition: cddefs.h:177
int bytpline
Definition: mfbp.h:39
#define ror(x, n)
Definition: mfbpoly.c:11
int curcolor
Definition: mfbp.h:46
struct mfbpc pc
Definition: mfbopen.c:14
int curfillpatt
Definition: mfbp.h:48
void MFBPolygon(MFBPOLYGON *poly)
Definition: mfbpoly.c:31