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 #ifdef __STDC__
14 static void mode_1_line(int,int);
15 static void mode_2_line(int,int);
16 #else
17 static void mode_1_line();
18 static void mode_2_line();
19 #endif
20
21
22 void
MFBLine(x0,y0,x1,y1)23 MFBLine(x0,y0,x1,y1)
24
25 int x0, y0, x1, y1;
26 {
27 pc.curx = x0;
28 pc.cury = y0;
29 if (pc.mfbMODE & 2)
30 mode_2_line(x1,y1);
31 else
32 mode_1_line(x1,y1);
33 }
34
35
36 void
MFBDrawLineTo(x,y)37 MFBDrawLineTo(x,y)
38
39 int x, y;
40 {
41 if (pc.mfbMODE & 2)
42 mode_2_line(x,y);
43 else
44 mode_1_line(x,y);
45 }
46
47
48 void
MFBMoveTo(x,y)49 MFBMoveTo(x,y)
50
51 int x, y;
52 {
53 pc.curx = x;
54 pc.cury = y;
55 }
56
57
58 int
MFBSetLineStyle(style)59 MFBSetLineStyle(style)
60
61 int style;
62 {
63 if ((style < 0) || (style >= NSTYLES))
64 return (MFBBADLST);
65 pc.curstyle = style;
66 return (MFBOK);
67 }
68
69
70 int
MFBDefineLineStyle(num,mask)71 MFBDefineLineStyle(num, mask)
72
73 int num, mask;
74 {
75 if ((num < 0) || (num >= NSTYLES))
76 return (MFBBADLST);
77 if (num == 0) return (MFBOK);
78 pc.linestyles[num] = (unsigned char) mask;
79 pc.curstyle = num;
80 return (MFBOK);
81 }
82
83
84 static void
mode_1_line(x,y)85 mode_1_line(x,y)
86 int x, y;
87 {
88 int xl, yl, dx, dy, dy2, errterm = 0, next, lcnt;
89 vidmptr rgen;
90 unsigned char cbuf, left, right;
91 union { unsigned short color2; unsigned char c[2]; } c;
92
93 xl = pc.curx;
94 yl = pc.cury;
95 pc.curx = x;
96 pc.cury = y;
97
98 c.c[0] = pc.curcolor;
99 c.c[1] = c.c[0];
100
101 outpw(0x3ce,0x0b05); /* read mode 1, write mode 3 */
102 outpw(0x3ce,c.color2 & 0xff00); /* set/reset */
103 outpw(0x3ce,0x7); /* zero color dont care */
104 outpw(0x3ce,pc.alumode); /* set alu mode */
105
106 if (y == yl) {
107 if (x < xl) MFBSwapInt(x,xl);
108 x++;
109 left = (0xff >> (xl & 7));
110 right = ~(0xff >> (x & 7));
111 dx = (x >> 3) - (xl >>= 3) - 1;
112 if (dx < 0) { left &= right; dx = 0; right = 0; }
113 rgen = pc.base + xl + (long) (pc.ysize-1-y)*pc.bytpline;
114
115 cbuf = 0xff;
116 if (pc.curstyle) {
117 cbuf = pc.linestyles[pc.curstyle];
118 left &= cbuf;
119 right &= cbuf;
120 }
121 mfb_trash = *rgen;
122 *rgen = left;
123 rgen++;
124 while (dx--) {
125 mfb_trash = *rgen;
126 *rgen = cbuf;
127 rgen++;
128 }
129 mfb_trash = *rgen;
130 *rgen = right;
131
132 goto done;
133 }
134
135 if (x == xl) {
136
137 if (y < yl) MFBSwapInt(y,yl);
138 yl--;
139 dy = y - yl;
140
141 cbuf = 0x80 >> (xl & 7);
142
143 next = pc.bytpline;
144
145 if (!pc.curstyle) {
146 rgen = pc.base + (x >> 3) + (long) (pc.ysize-1-y)*next;
147 while (dy--) {
148 mfb_trash = *rgen;
149 *rgen = cbuf;
150 rgen += next;
151 }
152 }
153 else {
154 lcnt = pc.ysize-1-y;
155 rgen = pc.base + (x >> 3) + (long) lcnt*next;
156 left = 0x80 >> ((lcnt+xl) & 7);
157 right = pc.linestyles[pc.curstyle];
158
159 while (dy--) {
160 if (left & right) {
161 mfb_trash = *rgen;
162 *rgen = cbuf;
163 }
164 left = ror(left,1);
165 rgen += next;
166 }
167 }
168 goto done;
169 }
170
171 if (x < xl) {
172 MFBSwapInt(xl,x);
173 MFBSwapInt(yl,y);
174 }
175 dx = x - xl;
176
177 next = pc.bytpline;
178 dy = yl - y;
179
180 if (!pc.curstyle) {
181 rgen = pc.base + (xl >> 3) + (long) (pc.ysize-1-yl)*next;
182 if (yl < y) {
183 next = -next;
184 dy = -dy;
185 }
186
187 cbuf = 0x80 >> (xl & 7);
188
189 dy2 = dy;
190 dy++;
191 while (dy--) {
192 errterm += dx;
193 if (errterm <= 0) {
194 mfb_trash = *rgen;
195 *rgen = cbuf;
196 rgen += next;
197 continue;
198 }
199 while (errterm > 0 && xl <= x) {
200 mfb_trash = *rgen;
201 *rgen = cbuf;
202 cbuf = ror(cbuf,1);
203 if (cbuf & 0x80) rgen++;
204 xl++;
205 errterm -= dy2;
206 }
207 rgen += next;
208 }
209 }
210 else {
211 lcnt = pc.ysize-1-yl;
212 rgen = pc.base + (xl >> 3) + (long) lcnt*next;
213 left = 0x80 >> ((lcnt+xl) & 7);
214 right = pc.linestyles[pc.curstyle];
215
216 if (yl < y) {
217 next = -next;
218 dy = -dy;
219 }
220
221 cbuf = 0x80 >> (xl & 7);
222
223 dy2 = dy;
224 dy++;
225 while (dy--) {
226 errterm += dx;
227 if (errterm <= 0) {
228 if (left & right) {
229 mfb_trash = *rgen;
230 *rgen = cbuf;
231 }
232 rgen += next;
233 left = ror(left,1);
234 continue;
235 }
236 while (errterm > 0 && xl <= x) {
237 if (left & right) {
238 mfb_trash = *rgen;
239 *rgen = cbuf;
240 }
241 left = ror(left,1);
242 cbuf = ror(cbuf,1);
243 if (cbuf & 0x80) rgen++;
244 xl++;
245 errterm -= dy2;
246 }
247 rgen += next;
248 left = ror(left,1);
249 }
250 }
251 done:
252 outpw(0x3ce,0xff07);
253 outpw(0x3ce,0x5);
254 }
255
256
257 #ifndef __GNUC__
258
259
260 static void
mode_2_line(x,y)261 mode_2_line(x,y)
262 int x, y;
263 {
264 int xl, yl, dy, dy2, errterm = 0, next, lcnt;
265 unsigned short dx;
266 unsigned char cbuf, left, right;
267 union { unsigned short o[2]; long l; } p1, p2;
268 union { unsigned short color2; unsigned char c[2]; } c;
269 vidmptr rgen;
270
271 xl = pc.curx;
272 yl = pc.cury;
273 pc.curx = x;
274 pc.cury = y;
275
276 c.c[0] = pc.curcolor;
277 c.c[1] = c.c[0];
278
279 outpw(0x3ce,0xff08); /* set bit mask */
280 outpw(0x3ce,pc.alumode); /* set alu mode */
281
282 if (y == yl) {
283 if (x < xl) MFBSwapInt(x,xl);
284 x++;
285 dx = x - xl;
286 p1.l = xl + (long) (pc.ysize-1-y)*pc.xsize;
287 p2.l = p1.l + dx;
288 if (p1.o[1] != p2.o[1])
289 dx = ~(p1.o[0]) + 1;
290 cbuf = p1.o[1];
291 cbuf |= (cbuf << 4);
292 outp(0x3cd,cbuf);
293 rgen = pc.base + p1.o[0];
294
295 if (!pc.curstyle) {
296
297 if (pc.alumode == 0x3) {
298 if ((unsigned)rgen & 1) {
299 *rgen = c.c[0];
300 rgen++;
301 dx--;
302 }
303 if (dx & 1)
304 *(rgen + dx - 1) = c.c[0];
305 dx >>= 1;
306 while (dx--) {
307 *(short far *)rgen = c.color2;
308 rgen += 2;
309 }
310 }
311 else {
312 while (dx--) {
313 mfb_trash = *rgen;
314 *rgen = c.c[0];
315 rgen++;
316 }
317 }
318
319 if (p1.o[1] != p2.o[1]) {
320 outp(0x3cd,cbuf + 0x11);
321 dx = p2.o[0];
322 rgen = pc.base;
323 if (pc.alumode == 0x3) {
324 if (dx & 1)
325 *(rgen + dx - 1) = c.c[0];
326 dx >>= 1;
327 while (dx--) {
328 *(short far *)rgen = c.color2;
329 rgen += 2;
330 }
331 }
332 else {
333 while (dx--) {
334 mfb_trash = *rgen;
335 *rgen = c.c[0];
336 rgen++;
337 }
338 }
339 }
340 }
341 else {
342
343 lcnt = pc.ysize-1-y;
344 p1.l = xl + (long) lcnt*pc.xsize;
345 left = 0x80 >> ((lcnt+xl) & 7);
346 right = pc.linestyles[pc.curstyle];
347
348 while (dx--) {
349 if (left & right) {
350 if (pc.alumode != 3)
351 mfb_trash = *rgen;
352 *rgen = c.c[0];
353 }
354 left = ror(left,1);
355 rgen++;
356 }
357
358 if (p1.o[1] != p2.o[1]) {
359 outp(0x3cd,cbuf + 0x11);
360 dx = p2.o[0];
361 rgen = pc.base;
362 while (dx--) {
363 if (left & right) {
364 if (pc.alumode != 3)
365 mfb_trash = *rgen;
366 *rgen = c.c[0];
367 }
368 left = ror(left,1);
369 rgen++;
370 }
371 }
372 }
373 return;
374 }
375
376
377 if (x == xl) {
378 if (y < yl) MFBSwapInt(y,yl);
379 yl--;
380 dy = y - yl;
381 next = pc.xsize;
382 lcnt = pc.ysize-1-y;
383 p1.l = xl + (long) lcnt*next;
384 cbuf = p1.o[1];
385 cbuf |= (cbuf << 4);
386 outp(0x3cd,cbuf);
387
388 if (!pc.curstyle) {
389 while (dy--) {
390 rgen = pc.base + p1.o[0];
391 if (pc.alumode != 3)
392 mfb_trash = *rgen;
393 *rgen = c.c[0];
394 p1.l += next;
395 if ((cbuf & 0xf) != p1.o[1]) {
396 cbuf += 0x11;
397 outp(0x3cd,cbuf);
398 }
399 }
400 }
401 else {
402 left = 0x80 >> ((lcnt+xl) & 7);
403 right = pc.linestyles[pc.curstyle];
404
405 while (dy--) {
406 rgen = pc.base + p1.o[0];
407 if (left & right) {
408 if (pc.alumode != 3)
409 mfb_trash = *rgen;
410 *rgen = c.c[0];
411 }
412 left = ror(left,1);
413 p1.l += next;
414 if ((cbuf & 0xf) != p1.o[1]) {
415 cbuf += 0x11;
416 outp(0x3cd,cbuf);
417 }
418 }
419 }
420 return;
421 }
422
423 cbuf = inp(0x3cd);
424 cbuf |= (cbuf << 4);
425
426 if (x < xl) {
427 MFBSwapInt(xl,x);
428 MFBSwapInt(yl,y);
429 }
430 dx = x - xl;
431
432 next = pc.xsize;
433 dy = yl - y;
434
435 if (!pc.curstyle) {
436 p1.l = xl + (long) (pc.ysize-1-yl)*next;
437
438 if (yl < y) {
439 next = -next;
440 dy = -dy;
441 }
442
443 dy2 = dy;
444 dy++;
445 while (dy--) {
446 errterm += dx;
447 if (errterm <= 0) {
448 if ((cbuf & 0xf) != p1.o[1]) {
449 cbuf = p1.o[1];
450 cbuf |= (cbuf << 4);
451 outp(0x3cd,cbuf);
452 }
453 if (pc.alumode != 3)
454 mfb_trash = *(pc.base + p1.o[0]);
455 *(pc.base + p1.o[0]) = c.c[0];
456 p1.l += next;
457 continue;
458 }
459 while (errterm > 0 && xl <= x) {
460 if ((cbuf & 0xf) != p1.o[1]) {
461 cbuf = p1.o[1];
462 cbuf |= (cbuf << 4);
463 outp(0x3cd,cbuf);
464 }
465 if (pc.alumode != 3)
466 mfb_trash = *(pc.base + p1.o[0]);
467 *(pc.base + p1.o[0]) = c.c[0];
468 p1.l++;
469 xl++;
470 errterm -= dy2;
471 }
472 p1.l += next;
473
474 }
475 }
476 else {
477 lcnt = pc.ysize-1-yl;
478 p1.l = xl + (long) lcnt*next;
479 left = 0x80 >> ((lcnt+xl) & 7);
480 right = pc.linestyles[pc.curstyle];
481
482 if (yl < y) {
483 next = -next;
484 dy = -dy;
485 }
486
487 dy2 = dy;
488 dy++;
489 while (dy--) {
490
491 errterm += dx;
492 if (errterm <= 0) {
493 if (left & right) {
494 if ((cbuf & 0xf) != p1.o[1]) {
495 cbuf = p1.o[1];
496 cbuf |= (cbuf << 4);
497 outp(0x3cd,cbuf);
498 }
499 if (pc.alumode != 3)
500 mfb_trash = *(pc.base + p1.o[0]);
501 *(pc.base + p1.o[0]) = c.color2;
502 }
503 p1.l += next;
504 left = ror(left,1);
505 continue;
506 }
507 while (errterm > 0 && xl <= x) {
508 if (left & right) {
509 if ((cbuf & 0xf) != p1.o[1]) {
510 cbuf = p1.o[1];
511 cbuf |= (cbuf << 4);
512 outp(0x3cd,cbuf);
513 }
514 if (pc.alumode != 3)
515 mfb_trash = *(pc.base + p1.o[0]);
516 *(pc.base + p1.o[0]) = c.color2;
517 }
518 left = ror(left,1);
519 p1.l++;
520 xl++;
521 errterm -= dy2;
522 }
523 p1.l += next;
524 left = ror(left,1);
525
526 }
527 }
528 }
529
530
531 #else /* __GNUC__ */
532
533
534 static void
mode_2_line(x,y)535 mode_2_line(x,y)
536 int x, y;
537 {
538 int xl, yl, dx, dy, dy2, errterm = 0, next, lcnt;
539 unsigned left, right;
540 union { unsigned short color2; unsigned char c[2]; } c;
541 vidmptr rgen;
542
543 xl = pc.curx;
544 yl = pc.cury;
545 pc.curx = x;
546 pc.cury = y;
547
548 c.c[0] = pc.curcolor;
549 c.c[1] = c.c[0];
550
551 outpw(0x3ce,0xff08); /* set bit mask */
552 outpw(0x3ce,pc.alumode); /* set alu mode */
553
554 if (y == yl) {
555 if (x < xl) MFBSwapInt(x,xl);
556 x++;
557 dx = x - xl;
558 lcnt = pc.ysize-1-y;
559 rgen = pc.base + xl + (long) lcnt*pc.xsize;
560
561 if (!pc.curstyle) {
562
563 if (pc.alumode == 0x3) {
564 if ((unsigned)rgen & 1) {
565 *rgen = c.c[0];
566 rgen++;
567 dx--;
568 }
569 if (dx & 1)
570 *(rgen + dx - 1) = c.c[0];
571 dx >>= 1;
572 while (dx--) {
573 *(short*)rgen = c.color2;
574 rgen += 2;
575 }
576 }
577 else {
578 while (dx--) {
579 mfb_trash = *rgen;
580 *rgen = c.c[0];
581 rgen++;
582 }
583 }
584 }
585 else {
586
587 left = 0x80 >> ((lcnt+xl) & 7);
588 right = pc.linestyles[pc.curstyle];
589
590 while (dx--) {
591 if (left & right) {
592 if (pc.alumode != 3)
593 mfb_trash = *rgen;
594 *rgen = c.c[0];
595 }
596 left = ror(left,1);
597 rgen++;
598 }
599 }
600 return;
601 }
602
603
604 if (x == xl) {
605 if (y < yl) MFBSwapInt(y,yl);
606 yl--;
607 dy = y - yl;
608 next = pc.xsize;
609 lcnt = pc.ysize-1-y;
610 rgen = pc.base + xl + (long) lcnt*next;
611
612 if (!pc.curstyle) {
613 while (dy--) {
614 if (pc.alumode != 3)
615 mfb_trash = *rgen;
616 *rgen = c.c[0];
617 rgen += next;
618 }
619 }
620 else {
621 left = 0x80 >> ((lcnt+xl) & 7);
622 right = pc.linestyles[pc.curstyle];
623
624 while (dy--) {
625 if (left & right) {
626 if (pc.alumode != 3)
627 mfb_trash = *rgen;
628 *rgen = c.c[0];
629 }
630 left = ror(left,1);
631 rgen += next;
632 }
633 }
634 return;
635 }
636
637 if (x < xl) {
638 MFBSwapInt(xl,x);
639 MFBSwapInt(yl,y);
640 }
641 dx = x - xl;
642
643 next = pc.xsize;
644 dy = yl - y;
645 lcnt = pc.ysize-1-yl;
646 rgen = pc.base + xl + (long) lcnt*next;
647
648 if (!pc.curstyle) {
649
650 if (yl < y) {
651 next = -next;
652 dy = -dy;
653 }
654
655 dy2 = dy;
656 dy++;
657 while (dy--) {
658 errterm += dx;
659 if (errterm <= 0) {
660 if (pc.alumode != 3)
661 mfb_trash = *rgen;
662 *rgen = c.c[0];
663 rgen += next;
664 continue;
665 }
666 while (errterm > 0 && xl <= x) {
667 if (pc.alumode != 3)
668 mfb_trash = *rgen;
669 *rgen = c.c[0];
670 rgen++;
671 xl++;
672 errterm -= dy2;
673 }
674 rgen += next;
675
676 }
677 }
678 else {
679 left = 0x80 >> ((lcnt+xl) & 7);
680 right = pc.linestyles[pc.curstyle];
681
682 if (yl < y) {
683 next = -next;
684 dy = -dy;
685 }
686
687 dy2 = dy;
688 dy++;
689 while (dy--) {
690
691 errterm += dx;
692 if (errterm <= 0) {
693 if (left & right) {
694 if (pc.alumode != 3)
695 mfb_trash = *rgen;
696 *rgen = c.color2;
697 }
698 rgen += next;
699 left = ror(left,1);
700 continue;
701 }
702 while (errterm > 0 && xl <= x) {
703 if (left & right) {
704 if (pc.alumode != 3)
705 mfb_trash = *rgen;
706 *rgen = c.color2;
707 }
708 left = ror(left,1);
709 rgen++;
710 xl++;
711 errterm -= dy2;
712 }
713 rgen += next;
714 left = ror(left,1);
715
716 }
717 }
718 }
719
720 #endif /* __GNUC__ */
721