1 #include <string.h>
2 #ifdef NCURSES
3 #include <curses.h>
4 #else
5 #include "xfcurses.h"
6 #endif
7 #include "port.h"
8 #include "prototyp.h"
9 /*
10 * This file contains Unix versions of the routines in video.asm
11 * Copyright 1992 Ken Shirriff
12 */
13
14 extern WINDOW *curwin;
15
16 extern unsigned char *xgetfont (void);
17 extern int startdisk (void);
18 extern int waitkeypressed (int);
19 extern int ctrl_window;
20
21 #ifndef NCURSES
22 extern unsigned long pixel[48];
23 #endif
24
25 int fake_lut = 0;
26 int istruecolor = 0;
27 int daclearn = 0;
28 int dacnorm = 0;
29 int daccount = 0;
30 int ShadowColors;
31 int goodmode = 0; /* if non-zero, OK to read/write pixels */
32 void (*dotwrite) (int, int, int);
33 /* write-a-dot routine */
34 int (*dotread) (int, int); /* read-a-dot routine */
35 void (*linewrite) (); /* write-a-line routine */
36 void (*lineread) (); /* read-a-line routine */
37 int andcolor = 0; /* "and" value used for color selection */
38 int diskflag = 0; /* disk video active flag */
39
40 int videoflag = 0; /* special "your-own-video" flag */
41
42 void (*swapsetup) (void) = NULL; /* setfortext/graphics setup routine */
43 int color_dark = 0; /* darkest color in palette */
44 int color_bright = 0; /* brightest color in palette */
45 int color_medium = 0; /* nearest to medbright grey in palette
46 Zoom-Box values (2K x 2K screens max) */
47 extern int boxcolor; /* Zoom-Box color */
48 int reallyega = 0; /* 1 if its an EGA posing as a VGA */
49 int gotrealdac = 0; /* 1 if loaddac has a dacbox */
50 int rowcount = 0; /* row-counter for decoder and out_line */
51 int video_type = 0; /* actual video adapter type:
52 0 = type not yet determined
53 1 = Hercules
54 2 = CGA (assumed if nothing else)
55 3 = EGA
56 4 = MCGA
57 5 = VGA
58 6 = VESA (not yet checked)
59 11 = 8514/A (not yet checked)
60 12 = TIGA (not yet checked)
61 13 = TARGA (not yet checked)
62 100 = x monochrome
63 101 = x 256 colors
64 */
65 int svga_type = 0; /* (forced) SVGA type
66 1 = ahead "A" type
67 2 = ATI
68 3 = C&T
69 4 = Everex
70 5 = Genoa
71 6 = Ncr
72 7 = Oak-Tech
73 8 = Paradise
74 9 = Trident
75 10 = Tseng 3000
76 11 = Tseng 4000
77 12 = Video-7
78 13 = ahead "B" type
79 14 = "null" type (for testing only) */
80 int mode7text = 0; /* nonzero for egamono and hgc */
81 int textaddr = 0xb800; /* b800 for mode 3, b000 for mode 7 */
82 int textsafe = 0; /* 0 = default, runup chgs to 1
83 1 = yes
84 2 = no, use 640x200
85 3 = bios, yes plus use int 10h-1Ch
86 4 = save, save entire image */
87 #ifdef NCURSES
88 int text_type = 1;
89 #else
90 int text_type = 0;
91 #endif
92 /* current mode's type of text:
93 0 = real text, mode 3 (or 7)
94 1 = 640x200x2, mode 6
95 2 = some other mode, graphics */
96 int textrow = 0; /* for putstring(-1,...) */
97 int textcol = 0; /* for putstring(..,-1,...) */
98 int textrbase = 0; /* textrow is relative to this */
99 int textcbase = 0; /* textcol is relative to this */
100
101 int vesa_detect = 1; /* set to 0 to disable VESA-detection */
102 int virtual = 0; /* no virtual screens, it's a DOS thing */
103 int video_scroll = 0;
104 int video_startx = 0;
105 int video_starty = 0;
106 int vesa_xres;
107 int vesa_yres;
108 int chkd_vvs = 0;
109 int video_vram = 0;
110
111 /*
112
113 ; |--Adapter/Mode-Name------|-------Comments-----------|
114
115 ; |------INT 10H------|Dot-|--Resolution---|
116 ; |key|--AX---BX---CX---DX|Mode|--X-|--Y-|Color|
117 */
118
119 struct videoinfo videotable[MAXVIDEOTABLE] = {
120 {"xfractint mode ", " ",
121 999, 0, 0, 0, 0, 19, 800, 600, 256},
122 {"unused mode ", " ",
123 0, 0, 0, 0, 0, 0, 0, 0, 0},
124 };
125
126 void setforgraphics ();
127
128 void
nullwrite(a,b,c)129 nullwrite (a, b, c)
130 int a, b, c;
131 {
132 }
133
134 int
nullread(a,b)135 nullread (a, b)
136 int a, b;
137 {
138 return 0;
139 }
140
141 void
setnullvideo(void)142 setnullvideo (void)
143 {
144 dotwrite = nullwrite;
145 dotread = nullread;
146 }
147
148 void normalineread ();
149 void normaline ();
150
151 void
putprompt(void)152 putprompt (void)
153 {
154 wclear (curwin); /* ???? */
155 #ifdef NCURSES
156 putstring (0, 0, 15, "Press operation key ('d' = redraw), or <Esc> to return to Main Menu");
157 wrefresh (curwin);
158 #else
159 if (ctrl_window)
160 putstring (0, 0, 15, "Press operation key ('d' = redraw), or <Esc> to return to Main Menu");
161 #endif
162 return;
163 }
164
165 /*
166 ; ********************** Function setvideotext() ************************
167
168 ; Sets video to text mode, using setvideomode to do the work.
169 */
170 void
setvideotext(void)171 setvideotext (void)
172 {
173 initmode = adapter;
174 dotmode = 0;
175 setvideomode (3, 0, 0, 0);
176 }
177
178 void
loaddac(void)179 loaddac (void)
180 {
181 readvideopalette ();
182 }
183
184 /*
185 ; **************** Function setvideomode(ax, bx, cx, dx) ****************
186 ; This function sets the (alphanumeric or graphic) video mode
187 ; of the monitor. Called with the proper values of AX thru DX.
188 ; No returned values, as there is no particular standard to
189 ; adhere to in this case.
190
191 ; (SPECIAL "TWEAKED" VGA VALUES: if AX==BX==CX==0, assume we have a
192 ; genuine VGA or register compatable adapter and program the registers
193 ; directly using the coded value in DX)
194
195 ; Unix: We ignore ax,bx,cx,dx. dotmode is the "mode" field in the video
196 ; table. We use mode 19 for the X window.
197 */
198 void
setvideomode(ax,bx,cx,dx)199 setvideomode (ax, bx, cx, dx)
200 int ax, bx, cx, dx;
201 {
202 if (diskflag)
203 {
204 enddisk ();
205 }
206 if (videoflag)
207 {
208 endvideo ();
209 videoflag = 0;
210 }
211 goodmode = 1;
212 switch (dotmode)
213 {
214 case 0: /* text */
215 clear ();
216 /*
217 touchwin(curwin);
218 */
219 wrefresh (curwin);
220 break;
221 case 11:
222 startdisk ();
223 dotwrite = writedisk;
224 dotread = readdisk;
225 lineread = normalineread;
226 linewrite = normaline;
227 break;
228 case 19: /* X window */
229 putprompt ();
230 dotwrite = writevideo;
231 dotread = readvideo;
232 lineread = readvideoline;
233 linewrite = writevideoline;
234 videoflag = 1;
235 startvideo ();
236 setforgraphics ();
237 break;
238 default:
239 printf ("Bad mode %d\n", dotmode);
240 exit (-1);
241 }
242 if (dotmode != 0)
243 {
244 loaddac ();
245 andcolor = colors - 1;
246 boxcount = 0;
247 }
248 vesa_xres = sxdots;
249 vesa_yres = sydots;
250 }
251
252
253 /*
254 ; **************** Function getcolor(xdot, ydot) *******************
255
256 ; Return the color on the screen at the (xdot,ydot) point
257 */
258 int
getcolor(xdot,ydot)259 getcolor (xdot, ydot)
260 int xdot, ydot;
261 {
262 int x1, y1;
263 x1 = xdot + sxoffs;
264 y1 = ydot + syoffs;
265 if (x1 < 0 || y1 < 0 || x1 >= sxdots || y1 >= sydots)
266 return 0;
267 return dotread (x1, y1);
268 }
269
270 /*
271 ; ************** Function putcolor_a(xdot, ydot, color) *******************
272
273 ; write the color on the screen at the (xdot,ydot) point
274 */
275 void
putcolor_a(xdot,ydot,color)276 putcolor_a (xdot, ydot, color)
277 int xdot, ydot, color;
278 {
279 dotwrite (xdot + sxoffs, ydot + syoffs, color & andcolor);
280 }
281
282 /*
283 ; **************** Function movecursor(row, col) **********************
284
285 ; Move the cursor (called before printfs)
286 */
287 void
movecursor(row,col)288 movecursor (row, col)
289 int row, col;
290 {
291 if (row == -1)
292 {
293 row = textrow;
294 }
295 else
296 {
297 textrow = row;
298 }
299 if (col == -1)
300 {
301 col = textcol;
302 }
303 else
304 {
305 textcol = col;
306 }
307 wmove (curwin, row, col);
308 }
309
310 /*
311 ; **************** Function keycursor(row, col) **********************
312
313 ; Subroutine to wait cx ticks, or till keystroke pending
314 */
315 int
keycursor(row,col)316 keycursor (row, col)
317 int row, col;
318 {
319 movecursor (row, col);
320 wrefresh (curwin);
321 waitkeypressed (0);
322 return getakey ();
323 }
324
325 /*
326 ; PUTSTR.asm puts a string directly to video display memory. Called from C by:
327 ; putstring(row, col, attr, string) where
328 ; row, col = row and column to start printing.
329 ; attr = color attribute.
330 ; string = far pointer to the null terminated string to print.
331 ; Written for the A86 assembler (which has much less 'red tape' than MASM)
332 ; by Bob Montgomery, Orlando, Fla. 7-11-88
333 ; Adapted for MASM 5.1 by Tim Wegner 12-11-89
334 ; Furthur mucked up to handle graphics
335 ; video modes by Bert Tyler 1-07-90
336 ; Reworked for: row,col update/inherit;
337 ; 620x200x2 inverse video; far ptr to string;
338 ; fix to avoid scrolling when last posn chgd;
339 ; divider removed; newline ctl chars; PB 9-25-90
340 */
341 void
putstring(row,col,attr,msg)342 putstring (row, col, attr, msg)
343 int row, col, attr;
344 CHAR far *msg;
345 {
346 int so = 0;
347 if (row != -1)
348 textrow = row;
349 if (col != -1)
350 textcol = col;
351
352 #ifndef NCURSES
353 curwin->_cur_attr = attr;
354 #endif
355
356 if (attr & INVERSE || attr & BRIGHT)
357 {
358 wstandout (curwin);
359 so = 1;
360 }
361
362 wmove (curwin, textrow + textrbase, textcol + textcbase);
363 while (1)
364 {
365 if (*msg == '\0')
366 break;
367 if (*msg == '\n')
368 {
369 textcol = 0;
370 textrow++;
371 wmove (curwin, textrow + textrbase, textcol + textcbase);
372 }
373 else
374 {
375 char *ptr;
376 ptr = strchr (msg, '\n');
377 if (ptr == NULL)
378 {
379 waddstr (curwin, msg);
380 break;
381 }
382 else
383 {
384 waddch (curwin, *msg);
385 }
386 }
387 msg++;
388 }
389 if (so)
390 {
391 wstandend (curwin);
392 }
393
394 #ifdef NCURSES
395 wrefresh (curwin);
396 fflush (stdout);
397 #else
398 XFlush(Xdp);
399 #endif
400 getyx (curwin, textrow, textcol);
401 textrow -= textrbase;
402 textcol -= textcbase;
403 }
404
405 /*
406 ; setattr(row, col, attr, count) where
407 ; row, col = row and column to start printing.
408 ; attr = color attribute.
409 ; count = number of characters to set
410 ; This routine works only in real color text mode.
411 */
412 void
setattr(row,col,attr,count)413 setattr (row, col, attr, count)
414 int row, col, attr, count;
415 {
416 int i;
417 int so = 0;
418 if (row != -1)
419 textrow = row;
420 if (col != -1)
421 textcol = col;
422
423 if (attr & INVERSE || attr & BRIGHT)
424 {
425 wstandout (curwin);
426 so = 1;
427 }
428
429 wmove (curwin, textrow + textrbase, textcol + textcbase);
430
431 #ifndef NCURSES
432 curwin->_cur_attr = attr;
433 for (i=0; i<count; i++)
434 waddch (curwin, '\0');
435 #endif
436 if (so)
437 {
438 wstandend (curwin);
439 }
440
441 }
442
443 /*
444 ; **************** Function home() ********************************
445
446 ; Home the cursor (called before printfs)
447 */
448 void
home(void)449 home (void)
450 {
451 wmove (curwin, 0, 0);
452 textrow = 0;
453 textcol = 0;
454 }
455
456
457 /*
458 ; ************* Function scrollup(toprow, botrow) ******************
459
460 ; Scroll the screen up (from toprow to botrow)
461 */
462 void
scrollup(top,bot)463 scrollup (top, bot)
464 int top, bot;
465 {
466 wmove (curwin, top, 0);
467 wdeleteln (curwin);
468 wmove (curwin, bot, 0);
469 winsertln (curwin);
470 #ifdef NCURSES
471 wrefresh (curwin);
472 #else
473 refresh(top, bot+1);
474 #endif
475 }
476
477 /*
478 ; *************** Function spindac(direction, rstep) ********************
479
480 ; Rotate the MCGA/VGA DAC in the (plus or minus) "direction"
481 ; in "rstep" increments - or, if "direction" is 0, just replace it.
482 */
483 void
spindac(dir,inc)484 spindac (dir, inc)
485 int dir, inc;
486 {
487 int i, top;
488 unsigned char tmp[3];
489 unsigned char *dacbot;
490 int len;
491 if (colors < 16)
492 return;
493 if (!(gotrealdac || fake_lut))
494 return;
495 if (istruecolor)
496 return;
497 if (dir != 0 && rotate_lo < colors && rotate_lo < rotate_hi)
498 {
499 top = rotate_hi > colors ? colors - 1 : rotate_hi;
500 dacbot = (unsigned char *) dacbox + 3 * rotate_lo;
501 len = (top - rotate_lo) * 3 * sizeof (unsigned char);
502 if (dir > 0)
503 {
504 for (i = 0; i < inc; i++)
505 {
506 bcopy (dacbot, tmp, 3 * sizeof (unsigned char));
507 bcopy (dacbot + 3 * sizeof (unsigned char), dacbot, len);
508 bcopy (tmp, dacbot + len, 3 * sizeof (unsigned char));
509 }
510 }
511 else
512 {
513 for (i = 0; i < inc; i++)
514 {
515 bcopy (dacbot + len, tmp, 3 * sizeof (unsigned char));
516 bcopy (dacbot, dacbot + 3 * sizeof (unsigned char), len);
517 bcopy (tmp, dacbot, 3 * sizeof (unsigned char));
518 }
519 }
520 }
521 writevideopalette ();
522 delay (colors - daccount - 1);
523 }
524
525 /*
526 ; ---- Help (Video) Support
527 ; ********* Functions setfortext() and setforgraphics() ************
528
529 ; setfortext() resets the video for text mode and saves graphics data
530 ; setforgraphics() restores the graphics mode and data
531 ; setclear() clears the screen after setfortext()
532 */
533 void
setfortext(void)534 setfortext (void)
535 {
536 }
537
538 void
setclear(void)539 setclear (void)
540 {
541 wclear (curwin);
542 wrefresh (curwin);
543 }
544
545 void
setforgraphics()546 setforgraphics ()
547 {
548 startvideo ();
549 spindac (0, 1);
550 }
551
552 unsigned char *fontTab = NULL;
553
554 /*
555 ; ************** Function findfont(n) ******************************
556
557 ; findfont(0) returns far pointer to 8x8 font table if it can
558 ; find it, NULL otherwise;
559 ; nonzero parameter reserved for future use
560 */
561 BYTE *
findfont(fontparm)562 findfont (fontparm)
563 int fontparm;
564 {
565 if (fontTab == NULL)
566 {
567 fontTab = xgetfont ();
568 }
569 return (BYTE *) fontTab;
570 }
571
572 /*
573 ; ******************** Zoombox functions **************************
574 */
575
576 /*
577 * The IBM method is that boxx[],boxy[] is a set of locations, and boxvalues
578 * is the values in these locations.
579 * Instead of using this box save/restore technique, we'll put the corners
580 * in boxx[0],boxy[0],1,2,3 and then use xor.
581 */
582
583 void
dispbox(void)584 dispbox (void)
585 {
586 if (boxcount)
587 {
588 setlinemode (1);
589 drawline (boxx[0], boxy[0], boxx[1], boxy[1]);
590 drawline (boxx[1], boxy[1], boxx[2], boxy[2]);
591 drawline (boxx[2], boxy[2], boxx[3], boxy[3]);
592 drawline (boxx[3], boxy[3], boxx[0], boxy[0]);
593 setlinemode (0);
594 xsync ();
595 }
596 }
597
598 void
clearbox(void)599 clearbox (void)
600 {
601 dispbox ();
602 }
603
604 int
CheckForTPlus(void)605 CheckForTPlus (void)
606 {
607 return 0;
608 }
609
610 /*
611 ; Passing this routine 0 turns off shadow, nonzero turns it on.
612 */
613 int
ShadowVideo(on)614 ShadowVideo (on)
615 int on;
616 {
617 return 0;
618 }
619
620 int
SetupShadowVideo(void)621 SetupShadowVideo (void)
622 {
623 return 0;
624 }
625
626 /*
627 ; adapter_detect:
628 ; This routine performs a few quick checks on the type of
629 ; video adapter installed.
630 ; It sets variables video_type and textsafe,
631 ; and fills in a few bank-switching routines.
632 */
633 int done_detect = 0;
634
635 void
adapter_detect(void)636 adapter_detect (void)
637 {
638 if (done_detect)
639 return;
640 done_detect = 1;
641 textsafe = 2;
642 if (colors == 2)
643 {
644 video_type = 100;
645 }
646 else
647 {
648 video_type = 101;
649 }
650 }
651
652 /*
653 ; **************** internal Read/Write-a-line routines *********************
654 ;
655 ; These routines are called by out_line(), put_line() and get_line().
656 */
657
658 void
normaline(y,x,lastx,pixels)659 normaline (y, x, lastx, pixels)
660 int x, y, lastx;
661 BYTE *pixels;
662 {
663 int i, width;
664 width = lastx - x + 1;
665 for (i = 0; i < width; i++)
666 {
667 dotwrite (x + i, y, pixels[i]);
668 }
669 }
670
671 void
normalineread(y,x,lastx,pixels)672 normalineread (y, x, lastx, pixels)
673 int x, y, lastx;
674 BYTE *pixels;
675 {
676 int i, width;
677 width = lastx - x + 1;
678 for (i = 0; i < width; i++)
679 {
680 pixels[i] = dotread (x + i, y);
681 }
682 }
683
684 /*
685 ; *************** Function find_special_colors ********************
686
687 ; Find the darkest and brightest colors in palette, and a medium
688 ; color which is reasonably bright and reasonably grey.
689 */
690 void
find_special_colors(void)691 find_special_colors (void)
692 {
693 int maxb = 0;
694 int minb = 9999;
695 int med = 0;
696 int maxgun, mingun;
697 int brt;
698 int i;
699
700 color_dark = 0;
701 color_medium = 7;
702 color_bright = 15;
703
704 if (colors == 2)
705 {
706 color_medium = 1;
707 color_bright = 1;
708 return;
709 }
710
711 if (!(gotrealdac || fake_lut))
712 return;
713
714 for (i = 0; i < colors; i++)
715 {
716 brt = (int) dacbox[i][0] + (int) dacbox[i][1] + (int) dacbox[i][2];
717 if (brt > maxb)
718 {
719 maxb = brt;
720 color_bright = i;
721 }
722 if (brt < minb)
723 {
724 minb = brt;
725 color_dark = i;
726 }
727 if (brt < 150 && brt > 80)
728 {
729 maxgun = mingun = (int) dacbox[i][0];
730 if ((int) dacbox[i][1] > (int) dacbox[i][0])
731 {
732 maxgun = (int) dacbox[i][1];
733 }
734 else
735 {
736 mingun = (int) dacbox[i][1];
737 }
738 if ((int) dacbox[i][2] > maxgun)
739 {
740 maxgun = (int) dacbox[i][2];
741 }
742 if ((int) dacbox[i][2] < mingun)
743 {
744 mingun = (int) dacbox[i][2];
745 }
746 if (brt - (maxgun - mingun) / 2 > med)
747 {
748 color_medium = i;
749 med = brt - (maxgun - mingun) / 2;
750 }
751 }
752 }
753 }
754
755 /*
756 ; *************** Functions get_a_char, put_a_char ********************
757
758 ; Get and put character and attribute at cursor
759 ; Hi nybble=character, low nybble attribute. Text mode only
760 */
761 char
get_a_char(void)762 get_a_char (void)
763 {
764 return (char) getakey ();
765 }
766
767 void
put_a_char(ch)768 put_a_char (ch)
769 int ch;
770 {
771 }
772
773 /*
774 ; ***Function get_line(int row,int startcol,int stopcol, unsigned char *pixels)
775
776 ; This routine is a 'line' analog of 'getcolor()', and gets a segment
777 ; of a line from the screen and stores it in pixels[] at one byte per
778 ; pixel
779 ; Called by the GIF decoder
780 */
781
782 void
get_line(row,startcol,stopcol,pixels)783 get_line (row, startcol, stopcol, pixels)
784 int row, startcol, stopcol;
785 BYTE *pixels;
786 {
787 if (startcol + sxoffs >= sxdots || row + syoffs >= sydots)
788 return;
789 lineread (row + syoffs, startcol + sxoffs, stopcol + sxoffs, pixels);
790 }
791
792 /*
793 ; ***Function put_line(int row,int startcol,int stopcol, unsigned char *pixels)
794
795 ; This routine is a 'line' analog of 'putcolor()', and puts a segment
796 ; of a line from the screen and stores it in pixels[] at one byte per
797 ; pixel
798 ; Called by the GIF decoder
799 */
800
801 void
put_line(row,startcol,stopcol,pixels)802 put_line (row, startcol, stopcol, pixels)
803 int row, startcol, stopcol;
804 BYTE *pixels;
805 {
806 if (startcol + sxoffs >= sxdots || row + syoffs > sydots)
807 return;
808 linewrite (row + syoffs, startcol + sxoffs, stopcol + sxoffs, pixels);
809 }
810
811 /*
812 ; ***************Function out_line(pixels,linelen) *********************
813
814 ; This routine is a 'line' analog of 'putcolor()', and sends an
815 ; entire line of pixels to the screen (0 <= xdot < xdots) at a clip
816 ; Called by the GIF decoder
817 */
818 int
out_line(pixels,linelen)819 out_line (pixels, linelen)
820 BYTE *pixels;
821 int linelen;
822 {
823 if (rowcount + syoffs >= sydots)
824 return 0;
825 linewrite (rowcount + syoffs, sxoffs, linelen + sxoffs - 1, pixels);
826 rowcount++;
827 return 0;
828 }
829
830 /*
831 ; far move routine for savegraphics/restoregraphics
832 */
833 void
movewords(len,fromptr,toptr)834 movewords (len, fromptr, toptr)
835 int len;
836 BYTE *fromptr, *toptr;
837 {
838 bcopy (fromptr, toptr, len);
839 }
840
841 void
swapnormread(void)842 swapnormread (void)
843 {
844 }
845 void
swapnormwrite(void)846 swapnormwrite (void)
847 {
848 }
849
850 /*
851 * Implement stack and unstack window functions by using multiple curses
852 * windows.
853 */
854 void
savecurses(ptr)855 savecurses (ptr)
856 WINDOW **ptr;
857 {
858 ptr[0] = curwin;
859 #ifdef NCURSES
860 curwin = newwin (0, 0, 0, 0);
861 #else
862 curwin = newwin (LINES, COLS, 0, 0);
863 #endif
864 touchwin (curwin);
865 wrefresh (curwin);
866 }
867
868 void
restorecurses(ptr)869 restorecurses (ptr)
870 WINDOW **ptr;
871 {
872 delwin (curwin);
873 curwin = ptr[0];
874 touchwin (curwin);
875 wrefresh (curwin);
876 #ifndef NCURSES
877 refresh(0, LINES);
878 #endif
879 }
880
881 /* Moved the following from realdos.c to more cleanly separate the XFRACT
882 * code. Now curses.h is only required in the unix directory. JCO 11/26/2005
883 */
884
885 /*
886 * The stackscreen()/unstackscreen() functions were originally
887 * ported to Xfractint.
888 * These functions are useful for switching between different text screens.
889 * For example, looking at a parameter entry using F2.
890 */
891
892 int screenctr = 0;
893
894 #define MAXSCREENS 3
895
896 static BYTE far *savescreen[MAXSCREENS];
897 static int saverc[MAXSCREENS+1];
898
stackscreen()899 void stackscreen()
900 {
901 int i;
902 BYTE far *ptr;
903 saverc[screenctr+1] = textrow*80 + textcol;
904 if (++screenctr) { /* already have some stacked */
905 static char far msg[]={"stackscreen overflow"};
906 if ((i = screenctr - 1) >= MAXSCREENS) { /* bug, missing unstack? */
907 stopmsg(1,msg);
908 exit(1);
909 }
910 if ((ptr = (savescreen[i] = (BYTE far *)farmemalloc(sizeof(int *)))))
911 savecurses((WINDOW **)ptr);
912 else {
913 stopmsg(1,msg);
914 exit(1);
915 }
916 setclear();
917 }
918 else
919 setfortext();
920 }
921
unstackscreen()922 void unstackscreen()
923 {
924 BYTE far *ptr;
925 textrow = saverc[screenctr] / 80;
926 textcol = saverc[screenctr] % 80;
927 if (--screenctr >= 0) { /* unstack */
928 ptr = savescreen[screenctr];
929 restorecurses((WINDOW **)ptr);
930 farmemfree(ptr);
931 }
932 else
933 setforgraphics();
934 movecursor(-1,-1);
935 }
936
discardscreen()937 void discardscreen()
938 {
939 if (--screenctr >= 0) { /* unstack */
940 if (savescreen[screenctr]) {
941 farmemfree(savescreen[screenctr]);
942 }
943 }
944 else
945 discardgraphics();
946 }
947