1 /*
2 Copyright (C) 1994-1995 Apogee Software, Ltd.
3 
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 as published by the Free Software Foundation; either version 2
7 of the License, or (at your option) any later version.
8 
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13 See the GNU General Public License for more details.
14 
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 
19 */
20 //******************************************************************************
21 //
22 // RT_STR.C
23 //    Contains the menu stuff!
24 //
25 //******************************************************************************
26 
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <stdarg.h>
30 #include <string.h>
31 
32 #include <string.h>
33 #include <ctype.h>
34 #include "rt_def.h"
35 #include "rt_menu.h"
36 #include "rt_util.h"
37 #include "rt_vid.h"
38 #include "rt_build.h"
39 #include "lumpy.h"
40 #include "rt_str.h"
41 #include "_rt_str.h"
42 #include "isr.h"
43 #include "rt_in.h"
44 #include "rt_menu.h"
45 #include "rt_view.h"
46 #include "w_wad.h"
47 #include "z_zone.h"
48 #include "modexlib.h"
49 #include "rt_main.h"
50 #include "rt_msg.h"
51 #include "rt_playr.h"
52 #include "rt_sound.h"
53 #include "myprint.h"
54 //MED
55 #include "memcheck.h"
56 
57 
58 //******************************************************************************
59 //
60 // GLOBALS
61 //
62 //******************************************************************************
63 
64 int fontcolor;
65 
66 //******************************************************************************
67 //
68 // LOCALS
69 //
70 //******************************************************************************
71 
72 static int BKw;
73 static int BKh;
74 
75 static char strbuf[MaxString];
76 
77 //******************************************************************************
78 //
79 // VW_DrawClippedString ()
80 //
81 // Draws a string at x, y to bufferofs
82 //
83 //******************************************************************************
84 
VW_DrawClippedString(int x,int y,const char * string)85 void VW_DrawClippedString (int x, int y, const char *string)
86 {
87    int   width,height,ht;
88    byte  *source;
89    int   ch;
90    int   oy;
91 
92    ht = CurrentFont->height;
93 
94    oy=y;
95 
96    while ((ch = (unsigned char)*string++)!=0)
97       {
98       ch -= 31;
99       width = CurrentFont->width[ch];
100       source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
101       while (width--)
102          {
103          if ((x>=0) && (x<MAXSCREENWIDTH))
104             {
105             y=oy;
106             VGAWRITEMAP(x&3);
107             height = ht;
108             while (height--)
109                {
110                if ((y>=0) && (y<MAXSCREENHEIGHT))
111                   {
112                   if (*source>0)
113 #ifdef DOS
114                      *((byte *)(bufferofs+ylookup[y]+(x>>2))) = *source;
115 #else
116                      *((byte *)(bufferofs+ylookup[y]+x)) = *source;
117 #endif
118                   }
119                source++;
120                y++;
121                }
122             }
123          x++;
124          }
125       }
126 }
127 
128 //******************************************************************************
129 //
130 // US_ClippedPrint() - Prints a string in bufferofs. Newlines are supported.
131 //
132 //******************************************************************************
133 
US_ClippedPrint(int x,int y,const char * string)134 void US_ClippedPrint (int x, int y, const char *string)
135 {
136    char  c,
137          *se;
138    char  *s;
139    int   startx;
140 
141    strcpy(strbuf, string);
142    s = strbuf;
143 
144    startx=x;
145    while (*s)
146    {
147       se = s;
148       while ((c = *se) && (c != '\n'))
149          se++;
150       *se = '\0';
151 
152       VW_DrawClippedString ( x, y, s);
153 
154       s = se;
155       if (c)
156          {
157          *se = c;
158          s++;
159          y += CurrentFont->height;
160          }
161    }
162 }
163 
164 
165 //******************************************************************************
166 //
167 // VW_DrawPropString ()
168 //
169 // Draws a string at px, py to bufferofs
170 //
171 //******************************************************************************
172 
VW_DrawPropString(const char * string)173 void VW_DrawPropString (const char *string)
174 {
175 #ifdef DOS
176    byte  pix;
177    int   width,step,height,ht;
178    byte  *source, *dest, *origdest;
179    int   ch,mask;
180 
181 
182    ht = CurrentFont->height;
183    dest = origdest = (byte *)(bufferofs+ylookup[py]+(px>>2));
184 
185 
186    mask = 1<<(px&3);
187 
188 
189    while ((ch = *string++)!=0)
190    {
191       ch -= 31;
192       width = step = CurrentFont->width[ch];
193       source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
194       while (width--)
195       {
196          VGAMAPMASK(mask);
197 
198          height = ht;
199          while (height--)
200          {
201             pix = *source;
202             if (pix)
203                *dest = pix;
204 
205             source++;
206             dest += linewidth;
207          }
208 
209          px++;
210          mask <<= 1;
211          if (mask == 16)
212          {
213             mask = 1;
214             origdest++;
215          }
216          dest = origdest;
217       }
218    }
219    bufferheight = ht;
220    bufferwidth = ((dest+1)-origdest)*4;
221 #else
222    byte  pix;
223    int   width,step,height,ht;
224    byte  *source, *dest, *origdest;
225    int   ch,mask;
226 
227    ht = CurrentFont->height;
228    dest = origdest = (byte *)(bufferofs+ylookup[py]+px);
229 
230    while ((ch = (unsigned char)*string++)!=0)
231    {
232       ch -= 31;
233       width = step = CurrentFont->width[ch];
234       source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
235       while (width--)
236       {
237          height = ht;
238          while (height--)
239          {
240             pix = *source;
241             if (pix)
242                *dest = pix;
243 
244             source++;
245             dest += linewidth;
246          }
247 
248          px++;
249 	 origdest++;
250          dest = origdest;
251       }
252    }
253    bufferheight = ht;
254    bufferwidth = ((dest+1)-origdest);
255 #endif
256 }
257 
258 
259 
260 //******************************************************************************
261 //
262 // VWB_DrawPropString ()
263 //
264 // Calls VW_DrawPropString then updates the mark block.
265 //
266 //******************************************************************************
267 
VWB_DrawPropString(const char * string)268 void VWB_DrawPropString  (const char *string)
269 {
270    int x;
271    x = px;
272    VW_DrawPropString (string);
273    VW_MarkUpdateBlock (x, py, px-1, py+bufferheight-1);
274 }
275 
276 
277 
278 //******************************************************************************
279 //
280 // VW_DrawIPropString ()
281 //
282 // Draws a string at px, py to bufferofs
283 //
284 //******************************************************************************
285 
VW_DrawIPropString(const char * string)286 void VW_DrawIPropString (const char *string)
287 {
288    byte  pix;
289    int   width,step,height,ht;
290    byte  *source, *dest, *origdest;
291    int   ch,mask;
292 
293 
294    ht = CurrentFont->height;
295 #ifdef DOS
296    dest = origdest = (byte *)(bufferofs+ylookup[py]+(px>>2));
297 #else
298    dest = origdest = (byte *)(bufferofs+ylookup[py]+px);
299 #endif
300 
301 
302    mask = 1<<(px&3);
303 
304 
305    while ((ch = (unsigned char)*string++)!=0)
306    {
307       ch -= 31;
308       width = step = CurrentFont->width[ch];
309       source = ((byte *)CurrentFont)+CurrentFont->charofs[ch];
310       while (width--)
311       {
312          VGAMAPMASK(mask);
313 
314          height = ht;
315          while (height--)
316          {
317             pix = *source;
318             if (pix)
319                *dest = pix;
320 
321             source++;
322             dest += linewidth;
323          }
324 
325          px++;
326 #ifdef DOS
327          mask <<= 1;
328          if (mask == 16)
329          {
330             mask = 1;
331             origdest++;
332          }
333 #else
334 	 origdest++;
335 #endif
336          dest = origdest;
337       }
338    }
339    bufferheight = ht;
340 #ifdef DOS
341    bufferwidth = ((dest+1)-origdest)*4;
342 #else
343    bufferwidth = ((dest+1)-origdest);
344 #endif
345 
346 }
347 
348 
349 
350 //******************************************************************************
351 //
352 // VWB_DrawIPropString ()
353 //
354 // Calls VW_DrawIPropString then updates the mark block.
355 //
356 //******************************************************************************
357 
VWB_DrawIPropString(const char * string)358 void VWB_DrawIPropString  (const char *string)
359 {
360    int x;
361    x = px;
362    VW_DrawIPropString (string);
363    VW_MarkUpdateBlock (x, py, px-1, py+bufferheight-1);
364 }
365 
366 
367 
368 //******************************************************************************
369 //
370 // VWL_MeasureString ()
371 //
372 //******************************************************************************
373 
VWL_MeasureString(const char * s,int * width,int * height,const font_t * font)374 void VWL_MeasureString (const char *s, int *width, int *height, const font_t *font)
375 {
376    *height = font->height;
377 
378    for (*width = 0; *s; s++)
379       *width += font->width[(*((byte *)s))-31];   // proportional width
380 }
381 
382 //******************************************************************************
383 //
384 // VWL_MeasureIntensityString ()
385 //
386 //******************************************************************************
387 
VWL_MeasureIntensityString(const char * s,int * width,int * height,const cfont_t * font)388 void VWL_MeasureIntensityString (const char *s, int *width, int *height, const cfont_t *font)
389 {
390    *height = font->height;
391 
392    for (*width = 0; *s; s++)
393       *width += font->width[(*((byte *)s))-31];   // proportional width
394 }
395 
396 //******************************************************************************
397 //
398 // VW_MeasureIntensityPropString ()
399 //
400 //******************************************************************************
401 
VW_MeasureIntensityPropString(const char * string,int * width,int * height)402 void VW_MeasureIntensityPropString (const char *string, int *width, int *height)
403 {
404    VWL_MeasureIntensityString (string, width, height, IFont);
405 }
406 
407 //******************************************************************************
408 //
409 // VW_MeasurePropString ()
410 //
411 //******************************************************************************
412 
VW_MeasurePropString(const char * string,int * width,int * height)413 void VW_MeasurePropString (const char *string, int *width, int *height)
414 {
415    VWL_MeasureString (string, width, height, CurrentFont);
416 }
417 
418 
419 //******************************************************************************
420 //
421 // US_MeasureStr ()
422 //
423 //******************************************************************************
424 
US_MeasureStr(int * width,int * height,const char * s,...)425 void US_MeasureStr (int *width, int *height, const char * s, ...)
426 {
427    char  c,
428          *se,
429          *ss;
430    int   w,h;
431    va_list strptr;
432    char buf[300];
433 
434    *width  = 0;
435    *height = 0;
436 
437    memset (&buf[0], 0, sizeof (buf));
438    va_start (strptr, s);
439    vsprintf (&buf[0], s, strptr);
440    va_end (strptr);
441 
442    ss = &buf[0];
443 
444    while (*ss)
445    {
446       se = ss;
447       while ((c = *se) && (c != '\n'))
448          se++;
449       *se = '\0';
450 
451       VWL_MeasureString (ss, &w, &h, CurrentFont);
452 
453       *height += h;
454 
455       if (w > *width)
456          *width = w;
457 
458       ss = se;
459       if (c)
460       {
461          *se = c;
462          ss++;
463       }
464    }
465 }
466 
467 
468 //******************************************************************************
469 //
470 // US_SetPrintRoutines() - Sets the routines used to measure and print
471 //    from within the User Mgr. Primarily provided to allow switching
472 //    between masked and non-masked fonts
473 //
474 //******************************************************************************
475 
US_SetPrintRoutines(void (* measure)(const char *,int *,int *,font_t *),void (* print)(const char *))476 void US_SetPrintRoutines (void (*measure)(const char *, int *, int *, font_t *),
477                           void (*print)(const char *))
478 {
479    USL_MeasureString = measure;
480    USL_DrawString    = print;
481 }
482 
483 
484 //******************************************************************************
485 //
486 // US_Print() - Prints a string in the current window. Newlines are
487 //    supported.
488 //
489 //******************************************************************************
490 
US_Print(const char * string)491 void US_Print (const char *string)
492 {
493    char  c,
494          *se,
495          *s;
496    int   w,h;
497 
498    strcpy(strbuf, string);
499    s = strbuf;
500 
501    while (*s)
502    {
503       se = s;
504       while ((c = *se) && (c != '\n'))
505          se++;
506       *se = '\0';
507 
508       USL_MeasureString (s, &w, &h, CurrentFont);
509       px = PrintX;
510       py = PrintY;
511       USL_DrawString (s);
512 
513       s = se;
514       if (c)
515       {
516          *se = c;
517          s++;
518 
519          PrintX = WindowX;
520          PrintY += h;
521       }
522       else
523          PrintX += w;
524    }
525 }
526 
527 //******************************************************************************
528 //
529 // US_BufPrint() - Prints a string in bufferofs. Newlines are supported.
530 //
531 //******************************************************************************
532 
US_BufPrint(const char * string)533 void US_BufPrint (const char *string)
534 {
535    char  c,
536          *se,
537          *s;
538    int   startx;
539 
540    strcpy(strbuf, string);
541    s = strbuf;
542 
543    startx=PrintX;
544    while (*s)
545    {
546       se = s;
547       while ((c = *se) && (c != '\n'))
548          se++;
549       *se = '\0';
550 
551       px = PrintX;
552       py = PrintY;
553       USL_DrawString (s);
554 
555       PrintY = py;
556       PrintX = px;
557 
558       s = se;
559       if (c)
560          {
561          *se = c;
562          s++;
563          PrintY += CurrentFont->height;
564          PrintX = startx;
565          }
566    }
567 }
568 
569 
570 //******************************************************************************
571 //
572 // US_PrintUnsigned () - Prints an unsigned long int
573 //
574 //******************************************************************************
575 
US_PrintUnsigned(unsigned long int n)576 void US_PrintUnsigned (unsigned long int n)
577 {
578    char  buffer[32];
579 
580    US_Print (ultoa (n, buffer, 10));
581 }
582 
583 //******************************************************************************
584 //
585 // US_PrintSigned() - Prints a signed long
586 //
587 //******************************************************************************
588 
US_PrintSigned(long int n)589 void US_PrintSigned (long int n)
590 {
591    char  buffer[32];
592 
593    US_Print (ltoa (n, buffer, 10));
594 }
595 
596 //******************************************************************************
597 //
598 // USL_PrintInCenter() - Prints a string in the center of the given rect
599 //
600 //******************************************************************************
601 
USL_PrintInCenter(const char * s,Rect r)602 void USL_PrintInCenter (const char *s, Rect r)
603 {
604    int   w,h,
605          rw,rh;
606 
607    USL_MeasureString (s,&w,&h, CurrentFont);
608    rw = r.lr.x - r.ul.x;
609    rh = r.lr.y - r.ul.y;
610 
611    px = r.ul.x + ((rw - w) / 2);
612    py = r.ul.y + ((rh - h) / 2);
613    USL_DrawString (s);
614 }
615 
616 //******************************************************************************
617 //
618 // US_PrintCentered() - Prints a string centered in the current window.
619 //
620 //******************************************************************************
621 
US_PrintCentered(const char * s)622 void US_PrintCentered (const char *s)
623 {
624    Rect  r;
625 
626    r.ul.x = WindowX;
627    r.ul.y = WindowY;
628    r.lr.x = r.ul.x + WindowW;
629    r.lr.y = r.ul.y + WindowH;
630 
631    USL_PrintInCenter (s, r);
632 }
633 
634 //******************************************************************************
635 //
636 // US_CPrintLine() - Prints a string centered on the current line and
637 //    advances to the next line. Newlines are not supported.
638 //
639 //******************************************************************************
640 
US_CPrintLine(const char * s)641 void US_CPrintLine (const char *s)
642 {
643    int w, h;
644 
645    USL_MeasureString (s, &w, &h, CurrentFont);
646 
647    if (w > WindowW)
648       Error("US_CPrintLine() - String exceeds width");
649 
650    px = WindowX + ((WindowW - w) / 2);
651    py = PrintY;
652    USL_DrawString (s);
653    PrintY += h;
654 }
655 
656 //******************************************************************************
657 //
658 // US_CPrint() - Prints a string in the current window. Newlines are
659 //    supported.
660 //
661 //******************************************************************************
662 
US_CPrint(const char * string)663 void US_CPrint (const char *string)
664 {
665    char  c,
666          *se,
667          *s;
668 
669    strcpy(strbuf, string);
670    s = strbuf;
671 
672    while (*s)
673    {
674       se = s;
675       while ((c = *se) && (c != '\n'))
676          se++;
677       *se = '\0';
678 
679       US_CPrintLine (s);
680 
681       s = se;
682       if (c)
683       {
684          *se = c;
685          s++;
686       }
687    }
688 }
689 
690 
691 
692 //
693 //
694 // Text Input routines
695 //
696 //
697 //
698 
699 
700 
701 //******************************************************************************
702 //
703 // USL_XORICursor() - XORs the I-bar text cursor. Used by  US_LineInput()
704 //
705 //******************************************************************************
706 
USL_XORICursor(int x,int y,const char * s,int cursor,int color)707 static void USL_XORICursor (int x, int y, const char *s, int cursor, int color)
708 {
709    static   boolean  status;     // VGA doesn't XOR...
710    char     buf[MaxString];
711 
712    int      w,h;
713    int      oldx = px;
714    int      oldy = py;
715 
716    strcpy (buf,s);
717    buf[cursor] = '\0';
718    USL_MeasureString (buf, &w, &h, CurrentFont);
719 
720 
721    if (status^=1)
722    {
723       px = x + w;
724       py = y;
725       if (color)
726          USL_DrawString ("\x80");
727       else
728          DrawMenuBufPropString (px, py, "\x80");
729    }
730    else
731    {
732       if (color)
733       {
734          VWB_Bar (px, py, BKw, BKh, color);
735          USL_DrawString (s);
736       }
737       else
738       {
739          EraseMenuBufRegion (px, py, BKw, BKh);
740 //         EraseMenuBufRegion (px, py+1, BKw, BKh-2);
741          DrawMenuBufPropString (px, py, s);
742       }
743    }
744    px = oldx;
745    py = oldy;
746 }
747 
748 
749 
750 
751 
752 
753 //******************************************************************************
754 //
755 // US_LineInput() - Gets a line of user input at (x,y), the string defaults
756 //    to whatever is pointed at by def. Input is restricted to maxchars
757 //    chars or maxwidth pixels wide. If the user hits escape (and escok is
758 //    true), nothing is copied into buf, and false is returned. If the
759 //    user hits return, the current string is copied into buf, and true is
760 //    returned
761 //
762 ///******************************************************************************
763 
764 extern byte * IN_GetScanName (ScanCode scan);
765 
US_LineInput(int x,int y,char * buf,const char * def,boolean escok,int maxchars,int maxwidth,int color)766 boolean US_LineInput (int x, int y, char *buf, const char *def, boolean escok,
767                       int maxchars, int maxwidth, int color)
768 {
769    boolean  redraw,
770             cursorvis,
771             cursormoved,
772             done,
773             result;
774    char     s[MaxString],
775             olds[MaxString];
776    int      i,
777             cursor,
778             w,h,
779             len;
780 
781    int      lasttime;
782 
783 
784    int      lastkey;
785    int      cursorwidth;
786 
787    cursorwidth = CurrentFont->width[80-31];
788 
789    memset (s, 0, MaxString);
790    memset (olds, 0, MaxString);
791    IN_ClearKeyboardQueue ();
792 
793    BKw = maxwidth;
794    BKh = CurrentFont->height;
795 
796 
797    if (def)
798       strcpy (s, def);
799    else
800       *s = '\0';
801 
802    *olds = '\0';
803 
804    cursor      = strlen (s);
805    cursormoved = redraw = true;
806    cursorvis   = done   = false;
807 
808    lasttime  = GetTicCount();
809 
810 
811    lastkey = getASCII ();
812 
813    while (!done)
814    {
815 //      if (GameEscaped==true)
816 //         PauseLoop ();
817 
818       IN_PumpEvents();
819 
820       if (cursorvis)
821          USL_XORICursor (x, y, s, cursor, color);
822 
823       LastScan = IN_InputUpdateKeyboard ();
824       if (Keyboard[sc_LShift] || Keyboard[sc_RShift])
825          lastkey = ShiftNames[LastScan];
826       else
827          lastkey = ASCIINames[LastScan];
828 
829 
830       switch (LastScan)
831       {
832       case sc_LeftArrow:
833 
834          if (cursor)
835             {
836             cursor--;
837             cursormoved = true;
838             MN_PlayMenuSnd (SD_MOVECURSORSND);
839             }
840          lastkey = key_None;
841          Keyboard[sc_LeftArrow] = 0;
842          break;
843 
844       case sc_RightArrow:
845 
846          if (s[cursor])
847             {
848             cursor++;
849             cursormoved = true;
850             MN_PlayMenuSnd (SD_MOVECURSORSND);
851             }
852          lastkey = key_None;
853          Keyboard[sc_RightArrow] = 0;
854          break;
855 
856       case sc_Home:
857 
858          if ( cursor )
859             {
860             cursor = 0;
861             cursormoved = true;
862             MN_PlayMenuSnd (SD_MOVECURSORSND);
863             }
864          Keyboard[sc_Home] = 0;
865          lastkey = key_None;
866          break;
867 
868       case sc_End:
869 
870          if ( cursor != (int)strlen (s) )
871             {
872             cursor = strlen (s);
873             cursormoved = true;
874             MN_PlayMenuSnd (SD_MOVECURSORSND);
875             }
876          lastkey = key_None;
877          Keyboard[sc_End] = 0;
878          break;
879 
880 
881       case sc_Return:
882          strcpy (buf,s);
883          done = true;
884          result = true;
885          lastkey = key_None;
886          MN_PlayMenuSnd (SD_SELECTSND);
887          break;
888 
889       case sc_Escape:
890          if (escok)
891          {
892             done = true;
893             result = false;
894             MN_PlayMenuSnd (SD_ESCPRESSEDSND);
895          }
896          lastkey = key_None;
897          break;
898 
899       case sc_BackSpace:
900 
901          if (cursor)
902             {
903             strcpy (s + cursor - 1,s + cursor);
904             cursor--;
905             redraw = true;
906             cursormoved = true;
907             MN_PlayMenuSnd (SD_MOVECURSORSND);
908             }
909          lastkey = key_None;
910          Keyboard[sc_BackSpace] = 0;
911          IN_ClearKeyboardQueue ();
912          break;
913 
914       case sc_Delete:
915 
916          if (s[cursor])
917          {
918             strcpy (s + cursor,s + cursor + 1);
919             redraw = true;
920             cursormoved = true;
921             MN_PlayMenuSnd (SD_MOVECURSORSND);
922          }
923          lastkey = key_None;
924          Keyboard[sc_Delete] = 0;
925          IN_ClearKeyboardQueue ();
926          break;
927 
928       case 0x4c:  // Keypad 5
929       case sc_UpArrow:
930       case sc_DownArrow:
931       case sc_PgUp:
932       case sc_PgDn:
933       case sc_Insert:
934          lastkey = key_None;
935          break;
936       }
937 
938 //      if (GameEscaped==true)
939 //         PauseLoop ();
940 
941       if (lastkey)
942       {
943          len = strlen (s);
944          USL_MeasureString (s, &w, &h, CurrentFont);
945 
946          if
947          (
948             isprint(lastkey)
949          && (len < MaxString - 1)
950          && ((!maxchars) || (len < maxchars))
951          && ((!maxwidth) || ((w+2) < (maxwidth-cursorwidth-2)))
952          )
953          {
954             int ls;
955             int rs;
956 
957             for (i = len + 1;i > cursor;i--)
958                s[i] = s[i - 1];
959             s[cursor++] = lastkey;
960             redraw = true;
961 
962             ls = Keyboard[sc_LShift];
963             rs = Keyboard[sc_RShift];
964             memset ((void*)Keyboard, 0, 127*sizeof(int));       // Clear printable keys
965             Keyboard[sc_LShift] = ls;
966             Keyboard[sc_RShift] = rs;
967 
968             MN_PlayMenuSnd (SD_MOVECURSORSND);
969          }
970       }
971 
972 //      if (GameEscaped==true)
973 //         PauseLoop ();
974 
975       if (redraw)
976       {
977          if (color)
978             VWB_Bar (x, y, BKw, BKh, color);
979          else
980             EraseMenuBufRegion (x, y, BKw, BKh);
981 
982          strcpy (olds, s);
983 
984          px = x;
985          py = y;
986          if (color)
987             USL_DrawString (s);
988          else
989             DrawMenuBufPropString (px, py, s);
990          px = x;
991          py = y;
992 
993          redraw = false;
994       }
995 
996       if (cursormoved)
997       {
998          cursorvis = false;
999          lasttime = GetTicCount() - VBLCOUNTER;
1000 
1001          cursormoved = false;
1002       }
1003       if (GetTicCount() - lasttime > VBLCOUNTER / 2)
1004       {
1005          lasttime = GetTicCount();
1006 
1007          cursorvis ^= true;
1008       }
1009       if (cursorvis)
1010          USL_XORICursor (x, y, s, cursor, color);
1011 
1012 //      if (GameEscaped==true)
1013 //         PauseLoop ();
1014 
1015       if (color)
1016          VW_UpdateScreen ();
1017       else
1018          RefreshMenuBuf (0);
1019    }
1020 
1021    if (cursorvis)
1022       USL_XORICursor (x, y, s, cursor, color);
1023 
1024    if (!result)
1025    {
1026       px = x;
1027       py = y;
1028       if (color)
1029          USL_DrawString (olds);
1030       else
1031          DrawMenuBufPropString (px, py, olds);
1032    }
1033 
1034 //   if (GameEscaped==true)
1035 //      PauseLoop ();
1036 
1037    if (color)
1038       VW_UpdateScreen ();
1039    else
1040       RefreshMenuBuf (0);
1041 
1042    IN_ClearKeyboardQueue ();
1043    return (result);
1044 }
1045 
1046 
1047 //******************************************************************************
1048 //
1049 // US_lineinput() - Gets a line of user input at (x,y), the string defaults
1050 //    to whatever is pointed at by def. Input is restricted to maxchars
1051 //    chars or maxwidth pixels wide. If the user hits escape (and escok is
1052 //    true), nothing is copied into buf, and false is returned. If the
1053 //    user hits return, the current string is copied into buf, and true is
1054 //    returned - PASSWORD INPUT
1055 //
1056 ///******************************************************************************
1057 
US_lineinput(int x,int y,char * buf,const char * def,boolean escok,int maxchars,int maxwidth,int color)1058 boolean US_lineinput (int x, int y, char *buf, const char *def, boolean escok,
1059                       int maxchars, int maxwidth, int color)
1060 {
1061    boolean  redraw,
1062             cursorvis,
1063             cursormoved,
1064             done,
1065             result;
1066    char     s[MaxString],
1067             xx[MaxString],
1068             olds[MaxString];
1069    int      i,
1070             cursor,
1071             w,h,
1072             len;
1073 
1074    int      lasttime;
1075 
1076 
1077    int      lastkey;
1078    int      cursorwidth;
1079 
1080    cursorwidth = CurrentFont->width[80-31];
1081 
1082    memset (s, 0, MaxString);
1083    memset (xx, 0, MaxString);
1084    memset (olds, 0, MaxString);
1085    IN_ClearKeyboardQueue ();
1086 
1087    BKw = maxwidth;
1088    BKh = CurrentFont->height;
1089 
1090 
1091    if (def)
1092       strcpy (s, def);
1093    else
1094       *s = '\0';
1095 
1096    *olds = '\0';
1097 
1098    cursor      = strlen (s);
1099    cursormoved = redraw = true;
1100    cursorvis   = done   = false;
1101 
1102    lasttime  = GetTicCount();
1103 
1104 
1105    lastkey = getASCII ();
1106 
1107    while (!done)
1108    {
1109 //      if (GameEscaped == true)
1110 //         PauseLoop ();
1111 
1112       if (cursorvis)
1113          USL_XORICursor (x, y, xx, cursor, color);
1114 
1115       LastScan = IN_InputUpdateKeyboard ();
1116       if (Keyboard[sc_LShift] || Keyboard[sc_RShift])
1117          lastkey = ShiftNames[LastScan];
1118       else
1119          lastkey = ASCIINames[LastScan];
1120 
1121 
1122       switch (LastScan)
1123       {
1124       case sc_LeftArrow:
1125 
1126          if (cursor)
1127             {
1128             cursor--;
1129             cursormoved = true;
1130             MN_PlayMenuSnd (SD_MOVECURSORSND);
1131             }
1132          lastkey = key_None;
1133          Keyboard[sc_LeftArrow] = 0;
1134          break;
1135 
1136       case sc_RightArrow:
1137 
1138          if (s[cursor])
1139             {
1140             cursor++;
1141             cursormoved = true;
1142             MN_PlayMenuSnd (SD_MOVECURSORSND);
1143             }
1144          lastkey = key_None;
1145          Keyboard[sc_RightArrow] = 0;
1146          break;
1147 
1148       case sc_Home:
1149 
1150          if ( cursor != 0 )
1151             {
1152             cursor = 0;
1153             cursormoved = true;
1154             MN_PlayMenuSnd (SD_MOVECURSORSND);
1155             }
1156          Keyboard[sc_Home] = 0;
1157          lastkey = key_None;
1158          break;
1159 
1160       case sc_End:
1161 
1162          if ( cursor != (int)strlen( s ) )
1163             {
1164             cursor = strlen (s);
1165             cursormoved = true;
1166             MN_PlayMenuSnd (SD_MOVECURSORSND);
1167             }
1168          lastkey = key_None;
1169          Keyboard[sc_End] = 0;
1170          break;
1171 
1172       case sc_Return:
1173          strcpy (buf,s);
1174          done = true;
1175          result = true;
1176          lastkey = key_None;
1177          MN_PlayMenuSnd (SD_SELECTSND);
1178          break;
1179 
1180       case sc_Escape:
1181          if (escok)
1182          {
1183             done = true;
1184             result = false;
1185             MN_PlayMenuSnd (SD_ESCPRESSEDSND);
1186          }
1187          lastkey = key_None;
1188          break;
1189 
1190       case sc_BackSpace:
1191 
1192          if (cursor)
1193             {
1194             strcpy (s + cursor - 1,s + cursor);
1195             strcpy (xx + cursor - 1,xx + cursor);
1196             cursor--;
1197             redraw = true;
1198             MN_PlayMenuSnd (SD_MOVECURSORSND);
1199             cursormoved = true;
1200             }
1201          lastkey = key_None;
1202          Keyboard[sc_BackSpace] = 0;
1203          IN_ClearKeyboardQueue ();
1204          break;
1205 
1206       case sc_Delete:
1207 
1208          if (s[cursor])
1209             {
1210             strcpy (s + cursor,s + cursor + 1);
1211             strcpy (xx + cursor,xx + cursor + 1);
1212             redraw = true;
1213             cursormoved = true;
1214             MN_PlayMenuSnd (SD_MOVECURSORSND);
1215             }
1216          lastkey = key_None;
1217          Keyboard[sc_Delete] = 0;
1218          IN_ClearKeyboardQueue ();
1219          break;
1220 
1221       case 0x4c:  // Keypad 5
1222       case sc_UpArrow:
1223       case sc_DownArrow:
1224       case sc_PgUp:
1225       case sc_PgDn:
1226       case sc_Insert:
1227          lastkey = key_None;
1228          break;
1229       }
1230 
1231 //      if (GameEscaped==true)
1232 //         PauseLoop ();
1233 
1234       if (lastkey)
1235       {
1236          len = strlen (s);
1237          USL_MeasureString (xx, &w, &h, CurrentFont);
1238 
1239          if
1240          (
1241             isprint(lastkey)
1242          && (len < MaxString - 1)
1243          && ((!maxchars) || (len < maxchars))
1244          && ((!maxwidth) || ((w+2) < (maxwidth-cursorwidth-2)))
1245          )
1246          {
1247             int ls;
1248             int rs;
1249 
1250             for (i = len + 1;i > cursor;i--)
1251                s[i] = s[i - 1];
1252             s[cursor]   = lastkey;
1253             xx[cursor++] = '*';
1254             redraw = true;
1255 
1256             ls = Keyboard[sc_LShift];
1257             rs = Keyboard[sc_RShift];
1258             memset ((void*)Keyboard, 0, 127*sizeof(int));       // Clear printable keys
1259             Keyboard[sc_LShift] = ls;
1260             Keyboard[sc_RShift] = rs;
1261             MN_PlayMenuSnd (SD_MOVECURSORSND);
1262          }
1263       }
1264 
1265 //      if (GameEscaped==true)
1266 //         PauseLoop ();
1267 
1268       if (redraw)
1269       {
1270          if (color)
1271             VWB_Bar (x, y, BKw, BKh, color);
1272          else
1273             EraseMenuBufRegion (x, y, BKw, BKh);
1274 
1275          strcpy (olds, s);
1276 
1277          px = x;
1278          py = y;
1279          if (color)
1280             USL_DrawString (xx);
1281          else
1282             DrawMenuBufPropString (px, py, xx);
1283          px = x;
1284          py = y;
1285 
1286          redraw = false;
1287       }
1288 
1289       if (cursormoved)
1290       {
1291          cursorvis = false;
1292          lasttime = GetTicCount() - VBLCOUNTER;
1293 
1294          cursormoved = false;
1295       }
1296       if (GetTicCount() - lasttime > VBLCOUNTER / 2)
1297       {
1298          lasttime = GetTicCount();
1299 
1300          cursorvis ^= true;
1301       }
1302       if (cursorvis)
1303          USL_XORICursor (x, y, xx, cursor, color);
1304 
1305       if (color)
1306          VW_UpdateScreen ();
1307       else
1308          RefreshMenuBuf (0);
1309    }
1310 
1311    if (cursorvis)
1312       USL_XORICursor (x, y, xx, cursor, color);
1313 
1314    if (!result)
1315    {
1316       px = x;
1317       py = y;
1318       if (color)
1319          USL_DrawString (xx);
1320       else
1321          DrawMenuBufPropString (px, py, xx);
1322    }
1323 
1324 //   if (GameEscaped==true)
1325 //      PauseLoop ();
1326 
1327    if (color)
1328       VW_UpdateScreen ();
1329    else
1330       RefreshMenuBuf (0);
1331 
1332    IN_ClearKeyboardQueue ();
1333    return (result);
1334 }
1335 
1336 
1337 
1338 //******************************************************************************
1339 //******************************************************************************
1340 //
1341 // WINDOWING ROUTINES
1342 //
1343 //******************************************************************************
1344 //******************************************************************************
1345 
1346 
1347 //******************************************************************************
1348 //
1349 // US_ClearWindow() - Clears the current window to white and homes the
1350 //    cursor
1351 //
1352 //******************************************************************************
1353 
US_ClearWindow(void)1354 void US_ClearWindow (void)
1355 {
1356    VWB_Bar (WindowX, WindowY, WindowW, WindowH, 13);
1357    PrintX = WindowX;
1358    PrintY = WindowY;
1359 }
1360 
1361 
1362 
1363 
1364 //******************************************************************************
1365 //
1366 // US_DrawWindow() - Draws a frame and sets the current window parms
1367 //
1368 //******************************************************************************
1369 
US_DrawWindow(int x,int y,int w,int h)1370 void US_DrawWindow (int x, int y, int w, int h)
1371 {
1372    int  i,
1373         sx,
1374         sy,
1375         sw,
1376         sh;
1377    byte * shape;
1378 
1379    pic_t *Win1;
1380    pic_t *Win2;
1381    pic_t *Win3;
1382    pic_t *Win4;
1383    pic_t *Win5;
1384    pic_t *Win6;
1385    pic_t *Win7;
1386    pic_t *Win8;
1387    pic_t *Win9;
1388 
1389 	// Cache in windowing shapes
1390 	shape = W_CacheLumpNum (W_GetNumForName ("window1"), PU_CACHE, Cvt_pic_t, 1);
1391 	Win1 = (pic_t *) shape;
1392 	shape = W_CacheLumpNum (W_GetNumForName ("window2"), PU_CACHE, Cvt_pic_t, 1);
1393 	Win2 = (pic_t *) shape;
1394 	shape = W_CacheLumpNum (W_GetNumForName ("window3"), PU_CACHE, Cvt_pic_t, 1);
1395 	Win3 = (pic_t *) shape;
1396 	shape = W_CacheLumpNum (W_GetNumForName ("window4"), PU_CACHE, Cvt_pic_t, 1);
1397 	Win4 = (pic_t *) shape;
1398 	shape = W_CacheLumpNum (W_GetNumForName ("window5"), PU_CACHE, Cvt_pic_t, 1);
1399 	Win5 = (pic_t *) shape;
1400 	shape = W_CacheLumpNum (W_GetNumForName ("window6"), PU_CACHE, Cvt_pic_t, 1);
1401 	Win6 = (pic_t *) shape;
1402 	shape = W_CacheLumpNum (W_GetNumForName ("window7"), PU_CACHE, Cvt_pic_t, 1);
1403 	Win7 = (pic_t *) shape;
1404 	shape = W_CacheLumpNum (W_GetNumForName ("window8"), PU_CACHE, Cvt_pic_t, 1);
1405 	Win8 = (pic_t *) shape;
1406 	shape = W_CacheLumpNum (W_GetNumForName ("window9"), PU_CACHE, Cvt_pic_t, 1);
1407 	Win9 = (pic_t *) shape;
1408 
1409    WindowX = x * 8;
1410    WindowY = y * 8;
1411    WindowW = w * 8;
1412    WindowH = h * 8;
1413 
1414    PrintX = WindowX;
1415    PrintY = WindowY;
1416 
1417    sx = (x - 1) * 8;
1418    sy = (y - 1) * 8;
1419    sw = (w + 1) * 8;
1420    sh = (h + 1) * 8;
1421 
1422    US_ClearWindow ();
1423 
1424 
1425    VWB_DrawPic (sx, sy, Win1);
1426 
1427    VWB_DrawPic (sx, sy + sh, Win7);
1428 
1429    for (i = sx + 8;i <= sx + sw - 8; i += 8)
1430    {
1431       VWB_DrawPic (i, sy, Win2);
1432       VWB_DrawPic (i, sy + sh, Win8);
1433    }
1434 
1435    VWB_DrawPic (i, sy, Win3);
1436    VWB_DrawPic (i, sy + sh, Win9);
1437 
1438    for (i = sy + 8;i <= sy + sh - 8; i += 8)
1439    {
1440       VWB_DrawPic (sx, i, Win4);
1441       VWB_DrawPic (sx + sw, i, Win6);
1442    }
1443 }
1444 
1445 
1446 
1447 //******************************************************************************
1448 //
1449 // US_CenterWindow() - Generates a window of a given width & height in the
1450 //    middle of the screen
1451 //
1452 //******************************************************************************
1453 
US_CenterWindow(int w,int h)1454 void US_CenterWindow (int w, int h)
1455 {
1456    US_DrawWindow (((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2, w, h);
1457 }
1458 
1459 
1460 
1461 //==============================================================================
1462 //
1463 // Intensity Font stuff
1464 //
1465 // TEXT FORMATTING COMMANDS - (Use EGA colors ONLY!)
1466 // -------------------------------------------------
1467 // /<hex digit> - Change the following word to <hex digit> color
1468 // `            - Highlights the following word with lighter color of fontcolor
1469 // /N<hex digit> - Change the fontcolor to a certain color
1470 //
1471 //==============================================================================
1472 
1473 //******************************************************************************
1474 //
1475 // GetIntensityColor ()
1476 //
1477 //******************************************************************************
1478 
GetIntensityColor(byte pix)1479 byte GetIntensityColor (byte pix)
1480 {
1481    if ((fontcolor<0) || (fontcolor>255))
1482       Error("Intensity Color out of range\n");
1483    return ((byte) intensitytable[(pix<<8)+fontcolor]);
1484 }
1485 
1486 
1487 //******************************************************************************
1488 //
1489 // DrawIntensityChar ()
1490 //
1491 // Draws an intensity character at px, py
1492 //
1493 //******************************************************************************
1494 
DrawIntensityChar(char ch)1495 void DrawIntensityChar
1496    (
1497    char ch
1498    )
1499 
1500    {
1501    byte  pix;
1502    int   width;
1503    int   height;
1504    int   ht;
1505    byte  *source;
1506    byte  *dest;
1507    byte  *origdest;
1508    int   mask;
1509 
1510    ht = IFont->height;
1511 
1512 #ifdef DOS
1513    origdest = ( byte * )( bufferofs + ylookup[ py ] + ( px >> 2 ) );
1514 #else
1515    origdest = ( byte * )( bufferofs + ylookup[ py ] + px );
1516 #endif
1517    dest = origdest;
1518 
1519    ch -= 31;
1520    width = IFont->width[ (unsigned int)ch ];
1521    source = ( ( byte * )IFont ) + IFont->charofs[ (unsigned int)ch ];
1522 
1523    mask = 1 << ( px & 3 );
1524 
1525    while( width-- )
1526       {
1527       VGAMAPMASK( mask );
1528 
1529       height = ht;
1530       while( height-- )
1531          {
1532          pix = *source;
1533          if ( pix != 0xFE )
1534             {
1535             *dest = GetIntensityColor( pix );
1536             }
1537 
1538          source++;
1539          dest += linewidth;
1540          }
1541 
1542       px++;
1543 #ifdef DOS
1544       mask <<= 1;
1545       if ( mask == 16 )
1546          {
1547          mask = 1;
1548          origdest++;
1549          }
1550 #else
1551       origdest++;
1552 #endif
1553       dest = origdest;
1554       }
1555    }
1556 
1557 
1558 //******************************************************************************
1559 //
1560 // GetColor ()
1561 //
1562 //******************************************************************************
1563 
GetColor(int num)1564 int GetColor (int num)
1565 {
1566    int returnval;
1567 
1568    if ((num >= '0') && (num <= '9'))
1569       returnval = egacolor[num - '0'];
1570    else
1571       if ((num >= 'A') && (num <= 'F'))
1572          returnval = egacolor[((num - 'A') + 10)];
1573 
1574    return (returnval);
1575 }
1576 
1577 //******************************************************************************
1578 //
1579 // DrawIString ()
1580 //
1581 //******************************************************************************
1582 
1583 static int oldfontcolor = 0;
1584 static boolean highlight = false;
1585 
DrawIString(unsigned short int x,unsigned short int y,const char * string,int flags)1586 void DrawIString (unsigned short int x, unsigned short int y, const char *string, int flags)
1587 {
1588    char ch;
1589    char temp;
1590 
1591    px = x;
1592    py = y;
1593 
1594    while ((ch = *string++) != 0)
1595    {
1596       if ( !PERMANENT_MSG( flags ) )
1597       {
1598          // Highlighting is done only for 1 word - if we get a "space"
1599          //  and highlight is on ...., reset variables.
1600          //
1601          if ((ch == ' ') && (highlight == true))
1602          {
1603             highlight = false;
1604             fontcolor = oldfontcolor;
1605             DrawIntensityChar (ch);
1606          }
1607          else
1608             // '\\' is color change to a specific EGA color (ie. egacolor)
1609             //
1610             if (ch == '\\')
1611             {
1612                temp = *string++;
1613                temp = toupper (temp);
1614 
1615                // Force fontcolor to a specific color
1616                if (temp == 'N')
1617                {
1618                   temp         = *string++;
1619                   fontcolor    = GetColor (temp);
1620                   oldfontcolor = fontcolor;
1621                }
1622 
1623                // Restore fontcolor to a previous color
1624                else if (temp == 'O')
1625                {
1626                   fontcolor    = oldfontcolor;
1627                }
1628                else
1629                {
1630                   oldfontcolor = fontcolor;           // save off old font color
1631                   highlight    = true;                // set highlight
1632                   fontcolor    = GetColor (temp);
1633                }
1634             }
1635             else
1636                // '`' is highlight the current fontcolor
1637                //
1638                if (ch == '`')
1639                {
1640                   oldfontcolor = fontcolor;        // save off old font color
1641                   highlight    = true;             // set highlight
1642                   if (fontcolor < 8)               // only highlight the
1643                      fontcolor    = fontcolor-10;  //  lower colors
1644                }
1645                else
1646                   DrawIntensityChar (ch);
1647       }
1648       else
1649          DrawIntensityChar (ch);
1650    }
1651 
1652    if (highlight == true)
1653    {
1654       highlight = false;
1655       fontcolor = oldfontcolor;
1656    }
1657 }
1658 
1659 
1660 //******************************************************************************
1661 //
1662 // DrawIntensityString ()
1663 //
1664 //******************************************************************************
1665 
DrawIntensityString(unsigned short int x,unsigned short int y,const char * string,int color)1666 void DrawIntensityString (unsigned short int x, unsigned short int y, const char *string, int color)
1667 {
1668    char ch;
1669 
1670    px = x;
1671    py = y;
1672 
1673    fontcolor=color;
1674 
1675    while ((ch = *string++) != 0)
1676       {
1677       DrawIntensityChar (ch);
1678       }
1679 }
1680 
1681 
1682 
1683 
1684 
1685 
1686 
1687 
1688 
1689 
1690 
1691 
1692 
1693 
1694 
1695 
1696 
1697 
1698 
1699 
1700 
1701 
1702 
1703 
1704 
1705 
1706 
1707 
1708 
1709 
1710 
1711 
1712 
1713 
1714 
1715 
1716 
1717 
1718 
1719 
1720 
1721 static unsigned short disp_offset = 160 * 24;
1722 
DrawRottText(int x,int y,int ch,int foreground,int background)1723 void DrawRottText
1724    (
1725    int x,
1726    int y,
1727    int ch,
1728    int foreground,
1729    int background
1730    )
1731 
1732    {
1733    char *vid;
1734 
1735    vid  = ( char * )( 0xb0000 );
1736    vid += y * 160;
1737    vid += x * 2;
1738 
1739    if ( ch != NONE )
1740       {
1741       *vid = ch;
1742       }
1743    vid++;
1744    *vid = ( ( background & 0x0f ) << 4 ) | ( foreground & 0x0f );
1745    }
1746 
TextBox(int x1,int y1,int x2,int y2,int ch,int foreground,int background)1747 void TextBox
1748    (
1749    int  x1,
1750    int  y1,
1751    int  x2,
1752    int  y2,
1753    int ch,
1754    int  foreground,
1755    int  background
1756    )
1757 
1758    {
1759    int x;
1760    int y;
1761 
1762    for( x = x1; x <= x2; x++ )
1763       {
1764       for( y = y1; y <= y2; y++ )
1765          {
1766          DrawRottText( x, y, ch, foreground, background );
1767          }
1768       }
1769    }
1770 
TextFrame(int x1,int y1,int x2,int y2,int type,int foreground,int background)1771 void TextFrame
1772    (
1773    int x1,
1774    int y1,
1775    int x2,
1776    int y2,
1777    int type,
1778    int foreground,
1779    int background
1780    )
1781 
1782    {
1783    int x;
1784    int y;
1785 
1786    if ( type == 0 )
1787       {
1788       for( x = x1 + 1; x < x2; x++ )
1789          {
1790          DrawRottText( x, y1, type, foreground, background );
1791          DrawRottText( x, y2, type, foreground, background );
1792          }
1793       for( y = y1 + 1; y < y2; y++ )
1794          {
1795          DrawRottText( x1, y, type, foreground, background );
1796          DrawRottText( x2, y, type, foreground, background );
1797          }
1798       }
1799    if ( type == SINGLE_FRAME )
1800       {
1801       DrawRottText( x1, y1, '�', foreground, background );
1802       DrawRottText( x2, y1, '�', foreground, background );
1803       DrawRottText( x1, y2, '�', foreground, background );
1804       DrawRottText( x2, y2, '�', foreground, background );
1805       for( x = x1 + 1; x < x2; x++ )
1806          {
1807          DrawRottText( x, y1, '�', foreground, background );
1808          DrawRottText( x, y2, '�', foreground, background );
1809          }
1810       for( y = y1 + 1; y < y2; y++ )
1811          {
1812          DrawRottText( x1, y, '�', foreground, background );
1813          DrawRottText( x2, y, '�', foreground, background );
1814          }
1815       }
1816    if ( type == DOUBLE_FRAME )
1817       {
1818       DrawRottText( x1, y1, '�', foreground, background );
1819       DrawRottText( x2, y1, '�', foreground, background );
1820       DrawRottText( x1, y2, '�', foreground, background );
1821       DrawRottText( x2, y2, '�', foreground, background );
1822       for( x = x1 + 1; x < x2; x++ )
1823          {
1824          DrawRottText( x, y1, '�', foreground, background );
1825          DrawRottText( x, y2, '�', foreground, background );
1826          }
1827       for( y = y1 + 1; y < y2; y++ )
1828          {
1829          DrawRottText( x1, y, '�', foreground, background );
1830          DrawRottText( x2, y, '�', foreground, background );
1831          }
1832       }
1833    }
1834 
mysetxy(int x,int y)1835 void mysetxy
1836    (
1837    int x,
1838    int y
1839    )
1840 
1841    {
1842    disp_offset = ( x * 2 ) + ( y * 160 );
1843    }
1844 
myputch(char ch)1845 void myputch
1846    (
1847    char ch
1848    )
1849 
1850    {
1851    int j;
1852    char *disp_start = (char *)( 0xb0000 );
1853 
1854    if ( disp_offset >= 160 * 24 )
1855       {
1856       for ( j = 160; j < 160 * 24; j += 2 )
1857          {
1858          *( disp_start + j - 160 ) = *( disp_start + j );
1859          }
1860 
1861       disp_offset = 160 * 23;
1862 
1863       for ( j = disp_offset; j < ( 160 * 24 ); j += 2 )
1864          {
1865          *( disp_start + j ) = ' ';
1866          }
1867       }
1868 
1869    if ( ch >= 32 )
1870       {
1871       *( disp_start + disp_offset ) = ch;
1872       disp_offset = disp_offset + 2;
1873       }
1874 
1875    if ( ch == '\r' )
1876       {
1877       disp_offset = disp_offset / 160;
1878       disp_offset = disp_offset * 160;
1879       }
1880 
1881    if ( ch == '\n' )
1882       {
1883       disp_offset = disp_offset + 160;
1884       if ( disp_offset < 160 * 24 )
1885          {
1886          for ( j = disp_offset; j < ( ( ( disp_offset / 160 ) + 1 ) *
1887             160 ); j += 2 )
1888             {
1889             *( disp_start + j ) = ' ';
1890             }
1891          }
1892       }
1893    }
1894 
printstring(char * string)1895 int printstring
1896    (
1897    char *string
1898    )
1899 
1900    {
1901    int count;
1902    char *ptr;
1903 
1904    ptr = string;
1905    count = 0;
1906 
1907    while ( *ptr )
1908       {
1909       myputch( *ptr );
1910       count++;
1911       ptr++;
1912       }
1913 
1914    return( count );
1915    }
1916 
1917 
printnum(int number)1918 int printnum
1919    (
1920    int number
1921    )
1922 
1923    {
1924    char string[ 100 ];
1925    int  count;
1926 
1927    itoa( number, string, 10 );
1928    count = printstring( string );
1929 
1930    return( count );
1931    }
1932 
printunsigned(unsigned long number,int radix)1933 int printunsigned
1934    (
1935    unsigned long number,
1936    int radix
1937    )
1938 
1939    {
1940    char string[ 100 ];
1941    int  count;
1942 
1943    ultoa( number, string, radix );
1944    count = printstring( string );
1945 
1946    return( count );
1947    }
1948 
myprintf(char * fmt,...)1949 int myprintf
1950    (
1951    char *fmt,
1952    ...
1953    )
1954 
1955    {
1956    va_list argptr;
1957    int     count;
1958    char    *ptr;
1959    if (MONOPRESENT==false)
1960       {
1961       Debug(fmt);
1962       return 0;
1963       }
1964    va_start( argptr, fmt );
1965    ptr = fmt;
1966    count = 0;
1967 
1968    while( *ptr != 0 )
1969       {
1970       if ( *ptr == '%' )
1971          {
1972          ptr++;
1973          switch( *ptr )
1974             {
1975             case 0 :
1976                return( EOF );
1977                break;
1978             case 'l' :
1979                count += printnum( va_arg( argptr, int ) );
1980                ptr++;
1981                break;
1982             case 'd' :
1983                count += printnum( va_arg( argptr, int ) );
1984                break;
1985             case 's' :
1986                count += printstring( va_arg( argptr, char * ) );
1987                break;
1988             case 'u' :
1989                count += printunsigned( va_arg( argptr, int ), 10 );
1990                break;
1991             case 'x' :
1992             case 'X' :
1993                count += printunsigned( va_arg( argptr, int ), 16 );
1994                break;
1995             }
1996          ptr++;
1997          }
1998       else
1999          {
2000          myputch( *ptr );
2001          count++;
2002          ptr++;
2003          }
2004       }
2005 
2006    va_end( argptr );
2007 
2008    return( count );
2009    }
2010