]> 4ch.mooo.com Git - 16.git/blob - 16/w_modex/XPRIM.CPP
66e2f72aed65c36dbee5342745b7c671f33099b3
[16.git] / 16 / w_modex / XPRIM.CPP
1 #include <conio.h>\r
2 #include <dos.h>\r
3 #include <mem.h>\r
4 #include <stdio.h>\r
5 \r
6 #include "modex.hpp"\r
7 #include "xprim.hpp"\r
8 \r
9 #define SEQU_ADDR       0x3C4\r
10 #define GRACON_ADDR     0x3CE\r
11 #define CRTC_ADDR       0x3D4\r
12 #define STATUS_ADDR     0x3DA\r
13 \r
14 BYTE Xfont[2048];\r
15 \r
16 \r
17 void\r
18 wait_for_retrace(void)\r
19 {\r
20     while (!(inp(STATUS_ADDR) & 0x08));\r
21 }\r
22 \r
23 \r
24 void\r
25 setDrawPage(unsigned int page)\r
26 {\r
27     activeStart = page_offset[page];\r
28 }\r
29 \r
30 \r
31 void\r
32 setVisiblePage(unsigned int page)\r
33 {\r
34     // setVisibleStart() tells the VGA from which byte to fetch the first\r
35     // pixel when starting refresh at the top of the screen.\r
36     visibleStart = page_offset[page];\r
37 \r
38     // set high byte\r
39     outpw(CRTC_ADDR, page_mask_high[page]);\r
40 \r
41     // set low byte\r
42     outpw(CRTC_ADDR, page_mask_low[page]);\r
43 }\r
44 \r
45 \r
46 void\r
47 clearX(BYTE color)\r
48 {\r
49     outpw(SEQU_ADDR, 0x0F02);\r
50     memset((unsigned char *)(0xA000 << 4) + activeStart, color, 0x00010000);\r
51 }\r
52 \r
53 \r
54 void\r
55 putpixelX(COORD x, COORD y, BYTE color)\r
56 {\r
57     BYTE temp;\r
58 \r
59     if (write_plane != (temp = (x & 3))) {\r
60         write_plane = temp;\r
61         outpw(SEQU_ADDR, plane_mask[temp]);\r
62     }\r
63 \r
64     *(RowsX[y] + (x >> 2) + activeStart) = color;\r
65 }\r
66 \r
67 \r
68 BYTE\r
69 getpixelX(COORD x, COORD y)\r
70 {\r
71     BYTE temp;\r
72 \r
73     if (read_plane != (temp = (x & 3))) {\r
74         read_plane = temp;\r
75         outpw(GRACON_ADDR, read_mask[temp]);\r
76     }\r
77 \r
78     return (*(RowsX[y] + (x >> 2) + activeStart));\r
79 }\r
80 \r
81 \r
82 void\r
83 internal_vert_lineX(COORD x, COORD top_y, int len, BYTE color)\r
84 {\r
85     BYTE *ptr;\r
86     BYTE temp;\r
87 \r
88     if (write_plane != (temp = (x & 3))) {\r
89         write_plane = temp;\r
90         outpw(SEQU_ADDR, plane_mask[temp]);\r
91     }\r
92 \r
93     ptr = RowsX[top_y] + (x >> 2) + activeStart;\r
94 \r
95     while (len--) {\r
96         *ptr = color;\r
97         ptr += widthBytes;\r
98     }\r
99 }\r
100 \r
101 \r
102 void\r
103 internal_horiz_lineX(COORD left_x, COORD y, int len, BYTE color)\r
104 {\r
105     BYTE *ptr;\r
106     BYTE temp;\r
107 \r
108     ptr = RowsX[y] + (left_x >> 2) + activeStart;\r
109 \r
110     // Set current plane to invalid value\r
111     write_plane = -1;\r
112 \r
113     if (temp = (left_x & 3)) {\r
114         outp(SEQU_ADDR, 0x02);\r
115         outp(0x3C5, line_head[temp]);\r
116         *ptr++ = color;\r
117         len -= (4 - temp);\r
118     }\r
119 \r
120     if (temp = (len >> 2)) {\r
121         outpw(SEQU_ADDR, 0x0F02);\r
122 \r
123         len &= 3;\r
124 \r
125         memset(ptr, color, temp);\r
126         ptr += temp;\r
127     }\r
128 \r
129     if (len) {\r
130         outp(SEQU_ADDR, 0x02);\r
131         outp(0x3C5, line_tail[len]);\r
132         *ptr = color;\r
133     }\r
134 }\r
135 \r
136 \r
137 void\r
138 boxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
139 {\r
140     int xsize, ysize;\r
141 \r
142     xsize = (x2 - x1) + 1;\r
143     internal_horiz_lineX(x1, y1, xsize, color);\r
144     internal_horiz_lineX(x1, y2, xsize, color);\r
145 \r
146     y1++;\r
147     ysize = (y2 - y1);\r
148 \r
149     internal_vert_lineX(x1, y1, ysize, color);\r
150     internal_vert_lineX(x2, y1, ysize, color);\r
151 }\r
152 \r
153 \r
154 void\r
155 filledboxX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
156 {\r
157     BYTE *base_ptr;\r
158     BYTE *ptr;\r
159     BYTE temp;\r
160     short int i, xsize, ysize;\r
161 \r
162     // Set current plane to invalid value\r
163     write_plane = -1;\r
164 \r
165     xsize = (x2 - x1) + 1;\r
166     ysize = (y2 - y1) + 1;\r
167 \r
168     if (ysize == 1) {\r
169         internal_horiz_lineX(x1, y1, xsize, color);\r
170         return;\r
171     }\r
172 \r
173     base_ptr = RowsX[y1] + (x1 >> 2) + activeStart;\r
174 \r
175     if (temp = (x1 & 3)) {\r
176         outp(SEQU_ADDR, 0x02);\r
177         outp(0x3C5, line_head[temp]);\r
178         ptr = base_ptr;\r
179         i=ysize;\r
180         while (i--) {\r
181             *ptr = color;\r
182             ptr += widthBytes;\r
183         }\r
184         xsize -= (4 - temp);\r
185         base_ptr++;\r
186     }\r
187 \r
188     if (temp = (xsize >> 2)) {\r
189         outpw(SEQU_ADDR, 0x0F02);\r
190 \r
191         xsize &= 3;\r
192         ptr = base_ptr;\r
193         i=ysize;\r
194         while (i--) {\r
195             memset(ptr, color, temp);\r
196             ptr += widthBytes;\r
197         }\r
198         base_ptr += temp;\r
199     }\r
200 \r
201     if (xsize) {\r
202         outp(SEQU_ADDR, 0x02);\r
203         outp(0x3C5, line_tail[xsize]);\r
204         while (ysize--) {\r
205             *base_ptr = color;\r
206             base_ptr += widthBytes;\r
207         }\r
208     }\r
209 }\r
210 \r
211 \r
212 void\r
213 circleX(COORD x, COORD y, DIST r, BYTE color)\r
214 {\r
215     int ix, iy, d, deltaE, deltaSE;\r
216 \r
217     ix = 0;\r
218     iy = r;\r
219     d = 1 - r;\r
220     deltaE = 3;\r
221     deltaSE = (-2 * r) + 5;\r
222 \r
223     putpixelX(x + ix, y + iy, color);\r
224     putpixelX(x + ix, y - iy, color);\r
225     putpixelX(x + iy, y + ix, color);\r
226     putpixelX(x + iy, y - ix, color);\r
227     putpixelX(x - ix, y + iy, color);\r
228     putpixelX(x - ix, y - iy, color);\r
229     putpixelX(x - iy, y + ix, color);\r
230     putpixelX(x - iy, y - ix, color);\r
231 \r
232     while (iy > ix++) {\r
233         if (d < 0) {\r
234             d += deltaE;\r
235             deltaE += 2;\r
236             deltaSE += 2;\r
237         } else {\r
238             d += deltaSE;\r
239             deltaE += 2;\r
240             deltaSE += 4;\r
241             iy--;\r
242         }\r
243 \r
244         putpixelX(x + ix, y + iy, color);\r
245         putpixelX(x + ix, y - iy, color);\r
246         putpixelX(x + iy, y + ix, color);\r
247         putpixelX(x + iy, y - ix, color);\r
248         putpixelX(x - ix, y + iy, color);\r
249         putpixelX(x - ix, y - iy, color);\r
250         putpixelX(x - iy, y + ix, color);\r
251         putpixelX(x - iy, y - ix, color);\r
252     }\r
253 }\r
254 \r
255 \r
256 void\r
257 filledcircleX(COORD x, COORD y, DIST r, BYTE color)\r
258 {\r
259     int ix, iy, d, deltaE, deltaSE;\r
260 \r
261     ix = 0;\r
262     iy = r;\r
263     d = 1 - r;\r
264     deltaE = 3;\r
265     deltaSE = (-2 * r) + 5;\r
266 \r
267     internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color);\r
268     internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color);\r
269     internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color);\r
270     internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color);\r
271 \r
272     while (iy > ix++) {\r
273         if (d < 0) {\r
274             d += deltaE;\r
275             deltaE += 2;\r
276             deltaSE += 2;\r
277         } else {\r
278             d += deltaSE;\r
279             deltaE += 2;\r
280             deltaSE += 4;\r
281             iy--;\r
282         }\r
283 \r
284         internal_horiz_lineX(x - ix, y + iy, (ix << 1) + 1, color);\r
285         internal_horiz_lineX(x - ix, y - iy, (ix << 1) + 1, color);\r
286         internal_horiz_lineX(x - iy, y + ix, (iy << 1) + 1, color);\r
287         internal_horiz_lineX(x - iy, y - ix, (iy << 1) + 1, color);\r
288     }\r
289 }\r
290 \r
291 \r
292 void\r
293 internal_xmajor(BYTE *vga_ptr, short int len, short int yskip,\r
294     unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
295 {\r
296     if (len) {\r
297         len--;\r
298         while (len--) {\r
299             *vga_ptr++ = color;\r
300             ErrorAcc += ErrorAdj;\r
301 \r
302             if (ErrorAcc & ~0xFFFFL) {\r
303                 ErrorAcc &= 0xFFFFL;\r
304                 vga_ptr += yskip;\r
305             }\r
306         }\r
307         *vga_ptr = color;\r
308     }\r
309 }\r
310 \r
311 \r
312 void\r
313 internal_middle(BYTE *vga_ptr, short int len, short int yskip,\r
314     unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
315 {\r
316     if (len) {\r
317         len--;\r
318         while (len--) {\r
319             *vga_ptr++ = color;\r
320             ErrorAcc += ErrorAdj;\r
321             vga_ptr += (yskip * (ErrorAcc >> 16));\r
322             ErrorAcc &= 0xFFFFL;\r
323         }\r
324         *vga_ptr = color;\r
325     }\r
326 }\r
327 \r
328 \r
329 void\r
330 internal_ymajor(BYTE *vga_ptr, short int len, short int yskip,\r
331     unsigned long ErrorAcc, unsigned long ErrorAdj, BYTE color)\r
332 {\r
333     unsigned long TinyAdj;\r
334     short int i;\r
335 \r
336     if (len) {\r
337         TinyAdj = (ErrorAdj >> 2);\r
338         ErrorAdj -= TinyAdj;\r
339 \r
340         len--;\r
341         while (len--) {\r
342             ErrorAcc += TinyAdj;\r
343             i = (ErrorAcc >> 16);\r
344             ErrorAcc &= 0xFFFFL;\r
345 \r
346             while (i--) {\r
347                 *vga_ptr = color;\r
348                 vga_ptr += yskip;\r
349             }\r
350 \r
351             ErrorAcc += ErrorAdj;\r
352             vga_ptr += (yskip * (ErrorAcc >> 16)) + 1;\r
353             ErrorAcc &= 0xFFFFL;\r
354         }\r
355         ErrorAcc += TinyAdj;\r
356         i = (ErrorAcc >> 16);\r
357         while (i--) {\r
358             *vga_ptr = color;\r
359             vga_ptr += yskip;\r
360         }\r
361     }\r
362 }\r
363 \r
364 \r
365 void\r
366 lineX(COORD x1, COORD y1, COORD x2, COORD y2, BYTE color)\r
367 {\r
368     unsigned long ErrorAcc, ErrorAdj, TinyAdj;\r
369     short int i, DeltaX, DeltaY, yskip;\r
370     short int len[4];\r
371     BYTE *vga_ptr;\r
372     COORD temp;\r
373 \r
374     // Mode X 4-way folded Bresenham line function - by David Boeren\r
375 \r
376     // Set invalid plane, because we're screwing with the plane mask\r
377     write_plane = -1;\r
378 \r
379     // Make sure the line runs left to right\r
380     if (x1 > x2) {\r
381         temp = x1; x1 = x2; x2 = temp;\r
382         temp = y1; y1 = y2; y2 = temp;\r
383     }\r
384 \r
385     DeltaX = (x2 - x1);\r
386     DeltaY = (y2 - y1);\r
387 \r
388     if (DeltaY >= 0) {\r
389         yskip = widthBytes;\r
390     } else {\r
391         DeltaY = -DeltaY;  // Make DeltaY positive\r
392         yskip = -widthBytes;\r
393     }\r
394 \r
395     if (DeltaX == 0) {\r
396         // Vertical Line (and one pixel lines)\r
397         if (yskip > 0) {\r
398             internal_vert_lineX(x1, y1, (DeltaY + 1), color);\r
399         } else {\r
400             internal_vert_lineX(x1, y2, (DeltaY + 1), color);\r
401         }\r
402         return;\r
403     }\r
404 \r
405     if (DeltaY == 0) {\r
406         // Horizontal Line\r
407         internal_horiz_lineX(x1, y1, (DeltaX + 1), color);\r
408         return;\r
409     }\r
410 \r
411     vga_ptr = RowsX[y1] + (x1 >> 2) + activeStart;\r
412     ErrorAcc = 0x8000;\r
413 \r
414     // Length of sub-line in each plane\r
415     temp = (x1 & 3);\r
416     i = DeltaX + temp;\r
417     len[0] = ((i--) >> 2);\r
418     len[1] = ((i--) >> 2);\r
419     len[2] = ((i--) >> 2);\r
420     len[3] = (i >> 2) + 1;\r
421 \r
422     for (i=temp; i < 3; i++) {\r
423         len[i]++;\r
424     }\r
425 \r
426     if ((DeltaX >> 2) >= DeltaY) {\r
427         // X-Major line (0.00 < slope <= 0.25)\r
428         ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));\r
429         TinyAdj = (ErrorAdj >> 2);\r
430         while (i--) {\r
431             outpw(SEQU_ADDR, plane_mask[temp]);\r
432             internal_xmajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
433             if (temp == 4) {\r
434                 temp = 0;\r
435                 vga_ptr++;\r
436             }\r
437             ErrorAcc += TinyAdj;\r
438             if (ErrorAcc & ~0xFFFFL) {\r
439                 ErrorAcc &= 0xFFFFL;\r
440                 vga_ptr += yskip;\r
441             }\r
442         }\r
443         outpw(SEQU_ADDR, plane_mask[temp]);\r
444         internal_xmajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
445     } else if (DeltaX >= DeltaY) {\r
446         // Middle line (0.25 < slope <= 1.00)\r
447         ErrorAdj = ((((unsigned long)DeltaY << 18) / (unsigned long)DeltaX));\r
448         TinyAdj = (ErrorAdj >> 2);\r
449         while (i--) {\r
450             outpw(SEQU_ADDR, plane_mask[temp]);\r
451             internal_middle(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
452             if (temp == 4) {\r
453                 temp = 0;\r
454                 vga_ptr++;\r
455             }\r
456             ErrorAcc += TinyAdj;\r
457             if (ErrorAcc & ~0xFFFFL) {\r
458                 vga_ptr += yskip;\r
459                 ErrorAcc &= 0xFFFFL;\r
460             }\r
461         }\r
462         outpw(SEQU_ADDR, plane_mask[temp]);\r
463         internal_middle(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
464     } else {\r
465         // Y-Major line (slope > 1)\r
466         ErrorAdj = ((((unsigned long)(DeltaY+1) << 18) /\r
467                       (unsigned long)(DeltaX+1)));\r
468         TinyAdj = (ErrorAdj >> 2);\r
469         while (i--) {\r
470             outpw(SEQU_ADDR, plane_mask[temp]);\r
471             internal_ymajor(vga_ptr, len[temp++], yskip, ErrorAcc, ErrorAdj, color);\r
472             if (temp == 4) {\r
473                 temp = 0;\r
474                 vga_ptr++;\r
475             }\r
476             ErrorAcc += TinyAdj;\r
477             vga_ptr += (yskip * (ErrorAcc >> 16));\r
478             ErrorAcc &= 0xFFFFL;\r
479         }\r
480         outpw(SEQU_ADDR, plane_mask[temp]);\r
481         internal_ymajor(vga_ptr, len[temp], yskip, ErrorAcc, ErrorAdj, color);\r
482     }\r
483 }\r
484 \r
485 \r
486 int\r
487 loadfontX(char *fname)\r
488 {\r
489     FILE *fp;\r
490 \r
491     fp = fopen(fname, "rb");\r
492 \r
493     if (fp == NULL) {\r
494         return 0;\r
495     } else {\r
496         fread(Xfont, 8, 256, fp);\r
497         fclose(fp);\r
498         return 1;\r
499     }\r
500 }\r
501 \r
502 \r
503 void\r
504 putchX(COORD x, COORD y, char c, BYTE color)\r
505 {\r
506     int i;\r
507     BYTE *vga_ptr;\r
508     BYTE *font_ptr;\r
509     BYTE temp;\r
510 \r
511     // 8x8 font\r
512     vga_ptr = RowsX[y << 3] + (x << 1) + activeStart;\r
513     write_plane = -1;\r
514 \r
515     font_ptr = Xfont + (c << 3);\r
516 \r
517     i=8;\r
518     while (i--) {\r
519         temp = *font_ptr++;\r
520         outpw(SEQU_ADDR, text_mask[temp & 0x0F]);\r
521         *vga_ptr++ = color;\r
522 \r
523         outpw(SEQU_ADDR, text_mask[temp >> 4]);\r
524         *vga_ptr-- = color;\r
525         vga_ptr += widthBytes;\r
526     }\r
527 }\r
528 \r
529 \r
530 void\r
531 putstringX(COORD x, COORD y, char *str, BYTE color)\r
532 {\r
533     int i, skip;\r
534     BYTE *vga_ptr;\r
535     BYTE *font_ptr;\r
536     BYTE c, temp;\r
537 \r
538     // 8x8 font\r
539     vga_ptr = RowsX[y << 3] + (x << 1) + activeStart;\r
540     write_plane = -1;\r
541 \r
542     skip = 2 - (widthBytes << 3);\r
543 \r
544     while (c = *str++) {\r
545         font_ptr = Xfont + (c << 3);\r
546 \r
547         i=8;\r
548         while (i--) {\r
549             temp = *font_ptr++;\r
550             outpw(SEQU_ADDR, text_mask[temp & 0x0F]);\r
551             *vga_ptr++ = color;\r
552 \r
553             outpw(SEQU_ADDR, text_mask[temp >> 4]);\r
554             *vga_ptr-- = color;\r
555             vga_ptr += widthBytes;\r
556         }\r
557 \r
558         vga_ptr += skip;\r
559     }\r
560 }\r
561 \r