]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_us.c_
XCROLL IS MYSTERIOUSLY NOT WORKING
[16.git] / src / lib / 16_us.c_
1 //\r
2 //      ID Engine\r
3 //      ID_US_1.c - User Manager - General routines\r
4 //      v1.1d1w\r
5 //      By Jason Blochowiak\r
6 //      Hacked up for Catacomb 3D\r
7 //      Open Watcom port by sparky4\r
8 //\r
9 \r
10 //\r
11 //      This module handles dealing with user input & feedback\r
12 //\r
13 //      Depends on: Input Mgr, View Mgr, some variables from the Sound, Caching,\r
14 //              and Refresh Mgrs, Memory Mgr for background save/restore\r
15 //\r
16 //      Globals:\r
17 //              ingame - Flag set by game indicating if a game is in progress\r
18 //      abortgame - Flag set if the current game should be aborted (if a load\r
19 //                      game fails)\r
20 //              loadedgame - Flag set if a game was loaded\r
21 //              abortprogram - Normally nil, this points to a terminal error message\r
22 //                      if the program needs to abort\r
23 //              restartgame - Normally set to gd_Continue, this is set to one of the\r
24 //                      difficulty levels if a new game should be started\r
25 //              PrintX, PrintY - Where the User Mgr will print (global coords)\r
26 //              WindowX,WindowY,WindowW,WindowH - The dimensions of the current\r
27 //                      window\r
28 //\r
29 \r
30 #include "src/lib/16_us.h"\r
31 \r
32 #pragma hdrstop\r
33 \r
34 #pragma warn    -pia\r
35 \r
36 static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */\r
37 \r
38 //undeced vars\r
39 boolean compatability; word px,py;\r
40 \r
41 //      Global variables\r
42                 char            *abortprogram;\r
43                 boolean         NoWait;\r
44                 word            PrintX,PrintY;\r
45                 word            WindowX,WindowY,WindowW,WindowH;\r
46 \r
47 //      Internal variables\r
48 #define ConfigVersion   1\r
49 \r
50 static  char            *ParmStrings[] = {"TEDLEVEL","NOWAIT"},\r
51                                         *ParmStrings2[] = {"COMP","NOCOMP"};\r
52 static  boolean         US_Started;\r
53 \r
54                 boolean         Button0,Button1,\r
55                                         CursorBad;\r
56                 int                     CursorX,CursorY;\r
57 \r
58                 void            (*USL_MeasureString)(char far *,word *,word *) = VW_MeasurePropString,\r
59                                         (*USL_DrawString)(char far *) = VWB_DrawPropString;\r
60 \r
61                 SaveGame        Games[MaxSaveGames];\r
62                 HighScore       Scores[MaxScores] =\r
63                                         {\r
64                                                 {"id software-'92",10000,1},\r
65                                                 {"Adrian Carmack",10000,1},\r
66                                                 {"John Carmack",10000,1},\r
67                                                 {"Kevin Cloud",10000,1},\r
68                                                 {"Tom Hall",10000,1},\r
69                                                 {"John Romero",10000,1},\r
70                                                 {"Jay Wilbur",10000,1},\r
71                                         };\r
72 \r
73 //      Internal routines\r
74 \r
75 //      Public routines\r
76 \r
77 ///////////////////////////////////////////////////////////////////////////\r
78 //\r
79 //      USL_HardError() - Handles the Abort/Retry/Fail sort of errors passed\r
80 //                      from DOS.\r
81 //\r
82 ///////////////////////////////////////////////////////////////////////////\r
83 #pragma warn    -par\r
84 #pragma warn    -rch\r
85 int\r
86 USL_HardError(word errval,int ax,int bp,int si)\r
87 {\r
88 #define IGNORE  0\r
89 #define RETRY   1\r
90 #define ABORT   2\r
91 extern  void    ShutdownId(void);\r
92 \r
93 static  char            buf[32];\r
94 static  WindowRec       wr;\r
95                 int                     dival=0;\r
96                 char            c,*s,*t;\r
97 \r
98         __asm {\r
99                 mov     [dival],di\r
100         }\r
101         //dival = _DI;\r
102 \r
103         if (ax < 0)\r
104                 s = "Device Error";\r
105         else\r
106         {\r
107                 if ((dival & 0x00ff) == 0)\r
108                         s = "Drive ~ is Write Protected";\r
109                 else\r
110                         s = "Error on Drive ~";\r
111                 for (t = buf;*s;s++,t++)        // Can't use sprintf()\r
112                         if ((*t = *s) == '~')\r
113                                 *t = (ax & 0x00ff) + 'A';\r
114                 *t = '\0';\r
115                 s = buf;\r
116         }\r
117 \r
118         c = peekb(0x40,0x49);   // Get the current screen mode\r
119         if ((c < 4) || (c == 7))\r
120                 goto oh_kill_me;\r
121 \r
122         // DEBUG - handle screen cleanup\r
123 \r
124         US_SaveWindow(&wr);\r
125         US_CenterWindow(30,3);\r
126         US_CPrint(s);\r
127         US_CPrint("(R)etry or (A)bort?");\r
128         //++++VW_UpdateScreen();\r
129         IN_ClearKeysDown();\r
130 \r
131 __asm   sti     // Let the keyboard interrupts come through\r
132 \r
133         while (true)\r
134         {\r
135                 switch (IN_WaitForASCII())\r
136                 {\r
137                 case key_Escape:\r
138                 case 'a':\r
139                 case 'A':\r
140                         goto oh_kill_me;\r
141                         break;\r
142                 case key_Return:\r
143                 case key_Space:\r
144                 case 'r':\r
145                 case 'R':\r
146                         US_ClearWindow();\r
147                         //++++VW_UpdateScreen();\r
148                         US_RestoreWindow(&wr);\r
149                         return(RETRY);\r
150                         break;\r
151                 }\r
152         }\r
153 \r
154 oh_kill_me:\r
155         abortprogram = s;\r
156         ShutdownId();\r
157         fprintf(stderr,"Terminal Error: %s\n",s);\r
158         if (tedlevel)\r
159                 fprintf(stderr,"You launched from TED. I suggest that you reboot...\n");\r
160 \r
161         return(ABORT);\r
162 #undef  IGNORE\r
163 #undef  RETRY\r
164 #undef  ABORT\r
165 }\r
166 #pragma warn    +par\r
167 #pragma warn    +rch\r
168 \r
169 \r
170 ///////////////////////////////////////////////////////////////////////////\r
171 //\r
172 //      US_Startup() - Starts the User Mgr\r
173 //\r
174 ///////////////////////////////////////////////////////////////////////////\r
175 void\r
176 US_Startup(void)\r
177 {\r
178         int     i,n;\r
179 \r
180         if (US_Started)\r
181                 return;\r
182 \r
183         //++++_harderr(USL_HardError);  // Install the fatal error handler\r
184 \r
185         US_InitRndT(true);              // Initialize the random number generator\r
186 \r
187         for (i = 1;i < _argc;i++)\r
188         {\r
189                 switch (US_CheckParm(_argv[i],ParmStrings2))\r
190                 {\r
191                 case 0:\r
192                         compatability = true;\r
193                         break;\r
194                 case 1:\r
195                         compatability = false;\r
196                         break;\r
197                 }\r
198         }\r
199 \r
200         // Check for TED launching here\r
201         for (i = 1;i < _argc;i++)\r
202         {\r
203                 n = US_CheckParm(_argv[i],ParmStrings);\r
204                 switch(n)\r
205                 {\r
206                  case 0:\r
207                    tedlevelnum = atoi(_argv[i + 1]);\r
208                    if (tedlevelnum >= 0)\r
209                      tedlevel = true;\r
210                    break;\r
211 \r
212                  case 1:\r
213                    NoWait = true;\r
214                    break;\r
215                 }\r
216         }\r
217 \r
218         US_Started = true;\r
219 }\r
220 \r
221 \r
222 ///////////////////////////////////////////////////////////////////////////\r
223 //\r
224 //      US_Shutdown() - Shuts down the User Mgr\r
225 //\r
226 ///////////////////////////////////////////////////////////////////////////\r
227 void\r
228 US_Shutdown(void)\r
229 {\r
230         if (!US_Started)\r
231                 return;\r
232 \r
233         US_Started = false;\r
234 }\r
235 \r
236 ///////////////////////////////////////////////////////////////////////////\r
237 //\r
238 //      US_CheckParm() - checks to see if a string matches one of a set of\r
239 //              strings. The check is case insensitive. The routine returns the\r
240 //              index of the string that matched, or -1 if no matches were found\r
241 //\r
242 ///////////////////////////////////////////////////////////////////////////\r
243 int\r
244 US_CheckParm(char *parm,char **strings)\r
245 {\r
246         char    cp,cs,\r
247                         *p,*s;\r
248         int             i;\r
249 \r
250         while (!isalpha(*parm)) // Skip non-alphas\r
251                 parm++;\r
252 \r
253         for (i = 0;*strings && **strings;i++)\r
254         {\r
255                 for (s = *strings++,p = parm,cs = cp = 0;cs == cp;)\r
256                 {\r
257                         cs = *s++;\r
258                         if (!cs)\r
259                                 return(i);\r
260                         cp = *p++;\r
261 \r
262                         if (isupper(cs))\r
263                                 cs = tolower(cs);\r
264                         if (isupper(cp))\r
265                                 cp = tolower(cp);\r
266                 }\r
267         }\r
268         return(-1);\r
269 }\r
270 \r
271 \r
272 //      Window/Printing routines\r
273 \r
274 ///////////////////////////////////////////////////////////////////////////\r
275 //\r
276 //      US_SetPrintRoutines() - Sets the routines used to measure and print\r
277 //              from within the User Mgr. Primarily provided to allow switching\r
278 //              between masked and non-masked fonts\r
279 //\r
280 ///////////////////////////////////////////////////////////////////////////\r
281 void\r
282 US_SetPrintRoutines(void (*measure)(char far *,word *,word *),void (*print)(char far *))\r
283 {\r
284         USL_MeasureString = measure;\r
285         USL_DrawString = print;\r
286 }\r
287 \r
288 ///////////////////////////////////////////////////////////////////////////\r
289 //\r
290 //      US_Print() - Prints a string in the current window. Newlines are\r
291 //              supported.\r
292 //\r
293 ///////////////////////////////////////////////////////////////////////////\r
294 void\r
295 US_Print(char far *s)\r
296 {\r
297         char    c,far *se;\r
298         word    w,h;\r
299 \r
300         while (*s)\r
301         {\r
302                 se = s;\r
303                 while ((c = *se) && (c != '\n'))\r
304                         se++;\r
305                 *se = '\0';\r
306 \r
307                 USL_MeasureString(s,&w,&h);\r
308                 px = PrintX;\r
309                 py = PrintY;\r
310                 USL_DrawString(s);\r
311 \r
312                 s = se;\r
313                 if (c)\r
314                 {\r
315                         *se = c;\r
316                         s++;\r
317 \r
318                         PrintX = WindowX;\r
319                         PrintY += h;\r
320                 }\r
321                 else\r
322                         PrintX += w;\r
323         }\r
324 }\r
325 \r
326 ///////////////////////////////////////////////////////////////////////////\r
327 //\r
328 //      US_PrintUnsigned() - Prints an unsigned long\r
329 //\r
330 ///////////////////////////////////////////////////////////////////////////\r
331 void\r
332 US_PrintUnsigned(word n)\r
333 {\r
334         char    buffer[32];\r
335 \r
336         US_Print(ultoa(n,buffer,10));\r
337 }\r
338 \r
339 ///////////////////////////////////////////////////////////////////////////\r
340 //\r
341 //      US_PrintSigned() - Prints a signed long\r
342 //\r
343 ///////////////////////////////////////////////////////////////////////////\r
344 void\r
345 US_PrintSigned(long n)\r
346 {\r
347         char    buffer[32];\r
348 \r
349         US_Print(ltoa(n,buffer,10));\r
350 }\r
351 \r
352 ///////////////////////////////////////////////////////////////////////////\r
353 //\r
354 //      USL_PrintInCenter() - Prints a string in the center of the given rect\r
355 //\r
356 ///////////////////////////////////////////////////////////////////////////\r
357 void\r
358 USL_PrintInCenter(char far *s,Rect r)\r
359 {\r
360         word    w,h,\r
361                         rw,rh;\r
362 \r
363         USL_MeasureString(s,&w,&h);\r
364         rw = r.lr.x - r.ul.x;\r
365         rh = r.lr.y - r.ul.y;\r
366 \r
367         px = r.ul.x + ((rw - w) / 2);\r
368         py = r.ul.y + ((rh - h) / 2);\r
369         USL_DrawString(s);\r
370 }\r
371 \r
372 ///////////////////////////////////////////////////////////////////////////\r
373 //\r
374 //      US_PrintCentered() - Prints a string centered in the current window.\r
375 //\r
376 ///////////////////////////////////////////////////////////////////////////\r
377 void\r
378 US_PrintCentered(char far *s)\r
379 {\r
380         Rect    r;\r
381 \r
382         r.ul.x = WindowX;\r
383         r.ul.y = WindowY;\r
384         r.lr.x = r.ul.x + WindowW;\r
385         r.lr.y = r.ul.y + WindowH;\r
386 \r
387         USL_PrintInCenter(s,r);\r
388 }\r
389 \r
390 ///////////////////////////////////////////////////////////////////////////\r
391 //\r
392 //      US_CPrintLine() - Prints a string centered on the current line and\r
393 //              advances to the next line. Newlines are not supported.\r
394 //\r
395 ///////////////////////////////////////////////////////////////////////////\r
396 void\r
397 US_CPrintLine(char far *s)\r
398 {\r
399         word    w,h;\r
400 \r
401         USL_MeasureString(s,&w,&h);\r
402 \r
403         if (w > WindowW)\r
404                 Quit("US_CPrintLine() - String exceeds width");\r
405         px = WindowX + ((WindowW - w) / 2);\r
406         py = PrintY;\r
407         USL_DrawString(s);\r
408         PrintY += h;\r
409 }\r
410 \r
411 ///////////////////////////////////////////////////////////////////////////\r
412 //\r
413 //      US_CPrint() - Prints a string in the current window. Newlines are\r
414 //              supported.\r
415 //\r
416 ///////////////////////////////////////////////////////////////////////////\r
417 void\r
418 US_CPrint(char far *s)\r
419 {\r
420         char    c,far *se;\r
421 \r
422         while (*s)\r
423         {\r
424                 se = s;\r
425                 while ((c = *se) && (c != '\n'))\r
426                         se++;\r
427                 *se = '\0';\r
428 \r
429                 US_CPrintLine(s);\r
430 \r
431                 s = se;\r
432                 if (c)\r
433                 {\r
434                         *se = c;\r
435                         s++;\r
436                 }\r
437         }\r
438 }\r
439 \r
440 ///////////////////////////////////////////////////////////////////////////\r
441 //\r
442 //      US_ClearWindow() - Clears the current window to white and homes the\r
443 //              cursor\r
444 //\r
445 ///////////////////////////////////////////////////////////////////////////\r
446 void\r
447 US_ClearWindow(void)\r
448 {\r
449         VWB_Bar(WindowX,WindowY,WindowW,WindowH,WHITE);\r
450         PrintX = WindowX;\r
451         PrintY = WindowY;\r
452 }\r
453 \r
454 ///////////////////////////////////////////////////////////////////////////\r
455 //\r
456 //      US_DrawWindow() - Draws a frame and sets the current window parms\r
457 //\r
458 ///////////////////////////////////////////////////////////////////////////\r
459 void\r
460 US_DrawWindow(word x,word y,word w,word h)\r
461 {\r
462         word    i,\r
463                         sx,sy,sw,sh;\r
464 \r
465         WindowX = x * 8;\r
466         WindowY = y * 8;\r
467         WindowW = w * 8;\r
468         WindowH = h * 8;\r
469 \r
470         PrintX = WindowX;\r
471         PrintY = WindowY;\r
472 \r
473         sx = (x - 1) * 8;\r
474         sy = (y - 1) * 8;\r
475         sw = (w + 1) * 8;\r
476         sh = (h + 1) * 8;\r
477 \r
478         US_ClearWindow();\r
479 \r
480         VWB_DrawTile8(sx,sy,0),VWB_DrawTile8(sx,sy + sh,5);\r
481         for (i = sx + 8;i <= sx + sw - 8;i += 8)\r
482                 VWB_DrawTile8(i,sy,1),VWB_DrawTile8(i,sy + sh,6);\r
483         VWB_DrawTile8(i,sy,2),VWB_DrawTile8(i,sy + sh,7);\r
484 \r
485         for (i = sy + 8;i <= sy + sh - 8;i += 8)\r
486                 VWB_DrawTile8(sx,i,3),VWB_DrawTile8(sx + sw,i,4);\r
487 }\r
488 \r
489 ///////////////////////////////////////////////////////////////////////////\r
490 //\r
491 //      US_CenterWindow() - Generates a window of a given width & height in the\r
492 //              middle of the screen\r
493 //\r
494 ///////////////////////////////////////////////////////////////////////////\r
495 void\r
496 US_CenterWindow(word w,word h)\r
497 {\r
498         US_DrawWindow(((MaxX / 8) - w) / 2,((MaxY / 8) - h) / 2,w,h);\r
499 }\r
500 \r
501 ///////////////////////////////////////////////////////////////////////////\r
502 //\r
503 //      US_SaveWindow() - Saves the current window parms into a record for\r
504 //              later restoration\r
505 //\r
506 ///////////////////////////////////////////////////////////////////////////\r
507 void\r
508 US_SaveWindow(WindowRec *win)\r
509 {\r
510         win->x = WindowX;\r
511         win->y = WindowY;\r
512         win->w = WindowW;\r
513         win->h = WindowH;\r
514 \r
515         win->px = PrintX;\r
516         win->py = PrintY;\r
517 }\r
518 \r
519 ///////////////////////////////////////////////////////////////////////////\r
520 //\r
521 //      US_RestoreWindow() - Sets the current window parms to those held in the\r
522 //              record\r
523 //\r
524 ///////////////////////////////////////////////////////////////////////////\r
525 void\r
526 US_RestoreWindow(WindowRec *win)\r
527 {\r
528         WindowX = win->x;\r
529         WindowY = win->y;\r
530         WindowW = win->w;\r
531         WindowH = win->h;\r
532 \r
533         PrintX = win->px;\r
534         PrintY = win->py;\r
535 }\r
536 \r
537 //      Input routines\r
538 \r
539 ///////////////////////////////////////////////////////////////////////////\r
540 //\r
541 //      USL_XORICursor() - XORs the I-bar text cursor. Used by US_LineInput()\r
542 //\r
543 ///////////////////////////////////////////////////////////////////////////\r
544 static void\r
545 USL_XORICursor(int x,int y,char *s,word cursor)\r
546 {\r
547         static  boolean status;         // VGA doesn't XOR...\r
548         char    buf[MaxString];\r
549         int             temp;\r
550         word    w,h;\r
551 \r
552         strcpy(buf,s);\r
553         buf[cursor] = '\0';\r
554         USL_MeasureString(buf,&w,&h);\r
555 \r
556         px = x + w - 1;\r
557         py = y;\r
558         if (status^=1)\r
559                 USL_DrawString("\x80");\r
560         else\r
561         {\r
562                 temp = fontcolor;\r
563                 fontcolor = backcolor;\r
564                 USL_DrawString("\x80");\r
565                 fontcolor = temp;\r
566         }\r
567 \r
568 }\r
569 \r
570 ///////////////////////////////////////////////////////////////////////////\r
571 //\r
572 //      US_LineInput() - Gets a line of user input at (x,y), the string defaults\r
573 //              to whatever is pointed at by def. Input is restricted to maxchars\r
574 //              chars or maxwidth pixels wide. If the user hits escape (and escok is\r
575 //              true), nothing is copied into buf, and false is returned. If the\r
576 //              user hits return, the current string is copied into buf, and true is\r
577 //              returned\r
578 //\r
579 ///////////////////////////////////////////////////////////////////////////\r
580 boolean\r
581 US_LineInput(int x,int y,char *buf,char *def,boolean escok,\r
582                                 int maxchars,int maxwidth)\r
583 {\r
584         boolean         redraw,\r
585                                 cursorvis,cursormoved,\r
586                                 done,result;\r
587         ScanCode        sc;\r
588         char            c,\r
589                                 s[MaxString],olds[MaxString];\r
590         word            i,\r
591                                 cursor,\r
592                                 w,h,\r
593                                 len,temp;\r
594         word    lasttime;\r
595         word TimeCount = *clockw;\r
596 \r
597         if (def)\r
598                 strcpy(s,def);\r
599         else\r
600                 *s = '\0';\r
601         *olds = '\0';\r
602         cursor = strlen(s);\r
603         cursormoved = redraw = true;\r
604 \r
605         cursorvis = done = false;\r
606         lasttime = TimeCount;\r
607         LastASCII = key_None;\r
608         LastScan = sc_None;\r
609 \r
610         while (!done)\r
611         {\r
612                 if (cursorvis)\r
613                         USL_XORICursor(x,y,s,cursor);\r
614 \r
615         asm     pushf\r
616         asm     cli\r
617 \r
618                 sc = LastScan;\r
619                 LastScan = sc_None;\r
620                 c = LastASCII;\r
621                 LastASCII = key_None;\r
622 \r
623         asm     popf\r
624 \r
625                 switch (sc)\r
626                 {\r
627                 case sc_LeftArrow:\r
628                         if (cursor)\r
629                                 cursor--;\r
630                         c = key_None;\r
631                         cursormoved = true;\r
632                         break;\r
633                 case sc_RightArrow:\r
634                         if (s[cursor])\r
635                                 cursor++;\r
636                         c = key_None;\r
637                         cursormoved = true;\r
638                         break;\r
639                 case sc_Home:\r
640                         cursor = 0;\r
641                         c = key_None;\r
642                         cursormoved = true;\r
643                         break;\r
644                 case sc_End:\r
645                         cursor = strlen(s);\r
646                         c = key_None;\r
647                         cursormoved = true;\r
648                         break;\r
649 \r
650                 case sc_Return:\r
651                         strcpy(buf,s);\r
652                         done = true;\r
653                         result = true;\r
654                         c = key_None;\r
655                         break;\r
656                 case sc_Escape:\r
657                         if (escok)\r
658                         {\r
659                                 done = true;\r
660                                 result = false;\r
661                         }\r
662                         c = key_None;\r
663                         break;\r
664 \r
665                 case sc_BackSpace:\r
666                         if (cursor)\r
667                         {\r
668                                 strcpy(s + cursor - 1,s + cursor);\r
669                                 cursor--;\r
670                                 redraw = true;\r
671                         }\r
672                         c = key_None;\r
673                         cursormoved = true;\r
674                         break;\r
675                 case sc_Delete:\r
676                         if (s[cursor])\r
677                         {\r
678                                 strcpy(s + cursor,s + cursor + 1);\r
679                                 redraw = true;\r
680                         }\r
681                         c = key_None;\r
682                         cursormoved = true;\r
683                         break;\r
684 \r
685                 case 0x4c:      // Keypad 5\r
686                 case sc_UpArrow:\r
687                 case sc_DownArrow:\r
688                 case sc_PgUp:\r
689                 case sc_PgDn:\r
690                 case sc_Insert:\r
691                         c = key_None;\r
692                         break;\r
693                 }\r
694 \r
695                 if (c)\r
696                 {\r
697                         len = strlen(s);\r
698                         USL_MeasureString(s,&w,&h);\r
699 \r
700                         if\r
701                         (\r
702                                 isprint(c)\r
703                         &&      (len < MaxString - 1)\r
704                         &&      ((!maxchars) || (len < maxchars))\r
705                         &&      ((!maxwidth) || (w < maxwidth))\r
706                         )\r
707                         {\r
708                                 for (i = len + 1;i > cursor;i--)\r
709                                         s[i] = s[i - 1];\r
710                                 s[cursor++] = c;\r
711                                 redraw = true;\r
712                         }\r
713                 }\r
714 \r
715                 if (redraw)\r
716                 {\r
717                         px = x;\r
718                         py = y;\r
719                         temp = fontcolor;\r
720                         fontcolor = backcolor;\r
721                         USL_DrawString(olds);\r
722                         fontcolor = temp;\r
723                         strcpy(olds,s);\r
724 \r
725                         px = x;\r
726                         py = y;\r
727                         USL_DrawString(s);\r
728 \r
729                         redraw = false;\r
730                 }\r
731 \r
732                 if (cursormoved)\r
733                 {\r
734                         cursorvis = false;\r
735                         lasttime = TimeCount - TickBase;\r
736 \r
737                         cursormoved = false;\r
738                 }\r
739                 if (TimeCount - lasttime > TickBase / 2)\r
740                 {\r
741                         lasttime = TimeCount;\r
742 \r
743                         cursorvis ^= true;\r
744                 }\r
745                 if (cursorvis)\r
746                         USL_XORICursor(x,y,s,cursor);\r
747 \r
748                 //++++VW_UpdateScreen();\r
749         }\r
750 \r
751         if (cursorvis)\r
752                 USL_XORICursor(x,y,s,cursor);\r
753         if (!result)\r
754         {\r
755                 px = x;\r
756                 py = y;\r
757                 USL_DrawString(olds);\r
758         }\r
759         //++++VW_UpdateScreen();\r
760 \r
761         IN_ClearKeysDown();\r
762         return(result);\r
763 }\r
764 \r
765 #if 0\r
766 \r
767 #define PaddleMinX      (CtlPanelSX + 3)\r
768 #define PaddleMaxX      (CtlPanelEX - 15)\r
769 #define BallMinX        (CtlPanelSX + 2)\r
770 #define BallMinY        (CtlPanelSY + 12 + 2)\r
771 #define BallMaxX        (CtlPanelEX - 6)\r
772 #define BallMaxY        (CtlPanelEY - 13)\r
773 #define CPaddleY        (BallMinY + 4)\r
774 #define KPaddleY        (BallMaxY - 2)\r
775 void\r
776 USL_DrawPongScore(word k,word c)\r
777 {\r
778         fontcolor = HiliteColor;\r
779         PrintY = py = CtlPanelSY + 4;\r
780         px = CtlPanelSX + 6;\r
781         VWB_Bar(px,py,42,6,BackColor);\r
782         USL_DrawString("YOU:");\r
783         PrintX = px;\r
784         US_PrintUnsigned(k);\r
785         px = CtlPanelSX + 108;\r
786         VWB_Bar(px,py,50,6,BackColor);\r
787         USL_DrawString("COMP:");\r
788         PrintX = px;\r
789         US_PrintUnsigned(c);\r
790 }\r
791 \r
792 void\r
793 USL_PlayPong(void)\r
794 {\r
795         boolean         ball,killball,revdir,done,lastscore;\r
796         word            cycle,\r
797                                 x,y,\r
798                                 kx,cx,\r
799                                 rx,\r
800                                 bx,by,\r
801                                 kscore,cscore,\r
802                                 speedup;\r
803         int                     bdx,bdy;\r
804         word        balltime,waittime;\r
805         CursorInfo      cursorinfo;\r
806 \r
807         kx = cx = PaddleMinX + ((PaddleMaxX - PaddleMinX) / 2);\r
808         bx = by = bdx = bdy = 0;\r
809         kscore = cscore = 0;\r
810         USL_DrawPongScore(0,0);\r
811         cycle = 0;\r
812         revdir = false;\r
813         killball = true;\r
814         done = false;\r
815         lastscore = false;\r
816         do\r
817         {\r
818                 waittime = TimeCount;\r
819 \r
820                 IN_ReadCursor(&cursorinfo);\r
821                 if (((cursorinfo.x < 0) || IN_KeyDown(sc_LeftArrow)) && (kx > PaddleMinX))\r
822                         kx -= 2;\r
823                 else if (((cursorinfo.x > 0) || IN_KeyDown(sc_RightArrow)) && (kx < PaddleMaxX))\r
824                         kx += 2;\r
825 \r
826                 if (killball)\r
827                 {\r
828                         ball = false;\r
829                         balltime = TimeCount + TickBase;\r
830                         speedup = 10;\r
831                         killball = false;\r
832                 }\r
833 \r
834                 if (ball && (cycle++ % 3))\r
835                 {\r
836                         x = (bx >> 2);\r
837                         if (!(x & 1))\r
838                                 x += (US_RndT() & 1);\r
839 \r
840                         if ((cx + 6 < x) && (cx < PaddleMaxX))\r
841                                 cx += 1;\r
842                         else if ((cx + 6 > x) && (cx > PaddleMinX))\r
843                                 cx -= 1;\r
844                 }\r
845 \r
846                 VWB_Bar(BallMinX,BallMinY - 1,\r
847                                 BallMaxX - BallMinX + 5,BallMaxY - BallMinY + 7,\r
848                                 BackColor);\r
849                 VWB_DrawSprite(cx,CPaddleY,PADDLESPR);\r
850                 VWB_DrawSprite(kx,KPaddleY,PADDLESPR);\r
851                 if (ball)\r
852                 {\r
853                         if\r
854                         (\r
855                                 (((bx + bdx) >> 2) > BallMaxX)\r
856                         ||      (((bx + bdx) >> 2) < BallMinX)\r
857                         )\r
858                         {\r
859                                 SD_PlaySound(BALLBOUNCESND);\r
860                                 bdx = -bdx;\r
861                         }\r
862                         bx += bdx;\r
863 \r
864                         if (((by + bdy) >> 2) > BallMaxY)\r
865                         {\r
866                                 killball = true;\r
867                                 lastscore = false;\r
868                                 cscore++;\r
869                                 SD_PlaySound(COMPSCOREDSND);\r
870                                 USL_DrawPongScore(kscore,cscore);\r
871                                 if (cscore == 21)\r
872                                 {\r
873                                         USL_CtlDialog("You lost!","Press any key",nil);\r
874                                         done = true;\r
875                                         continue;\r
876                                 }\r
877                         }\r
878                         else if (((by + bdy) >> 2) < BallMinY)\r
879                         {\r
880                                 killball = true;\r
881                                 lastscore = true;\r
882                                 kscore++;\r
883                                 SD_PlaySound(KEENSCOREDSND);\r
884                                 USL_DrawPongScore(kscore,cscore);\r
885                                 if (kscore == 21)\r
886                                 {\r
887                                         USL_CtlDialog("You won!","Press any key",nil);\r
888                                         done = true;\r
889                                         continue;\r
890                                 }\r
891                         }\r
892                         by += bdy;\r
893 \r
894                         x = bx >> 2;\r
895                         y = by >> 2;\r
896                         if (!killball)\r
897                         {\r
898                                 if\r
899                                 (\r
900                                         (bdy < 0)\r
901                                 &&      ((y >= CPaddleY) && (y < CPaddleY + 3))\r
902                                 &&      ((x >= (cx - 5)) && (x < (cx + 11)))\r
903                                 )\r
904                                 {\r
905                                         rx = cx;\r
906                                         revdir = true;\r
907                                         SD_PlaySound(COMPPADDLESND);\r
908                                 }\r
909                                 else if\r
910                                 (\r
911                                         (bdy > 0)\r
912                                 &&      ((y >= (KPaddleY - 3)) && (y < KPaddleY))\r
913                                 &&      ((x >= (kx - 5)) && (x < (kx + 11)))\r
914                                 )\r
915                                 {\r
916                                         if (((bdy >> 2) < 3) && !(--speedup))\r
917                                         {\r
918                                                 bdy++;\r
919                                                 speedup = 10;\r
920                                         }\r
921                                         rx = kx;\r
922                                         revdir = true;\r
923                                         SD_PlaySound(KEENPADDLESND);\r
924                                 }\r
925                                 if (revdir)\r
926                                 {\r
927                                         bdy = -bdy;\r
928                                         bdx = ((x + 5 - rx) >> 1) - (1 << 2);\r
929                                         if (!bdx)\r
930                                                 bdx--;\r
931                                         revdir = false;\r
932                                 }\r
933                         }\r
934                         VWB_DrawSprite(x,y,(x & 1)? BALL1PIXELTOTHERIGHTSPR : BALLSPR);\r
935                 }\r
936                 else if (TimeCount >= balltime)\r
937                 {\r
938                         ball = true;\r
939                         bdx = 1 - (US_RndT() % 3);\r
940                         bdy = 2;\r
941                         if (lastscore)\r
942                                 bdy = -bdy;\r
943                         bx = (BallMinX + ((BallMaxX - BallMinX) / 2)) << 2;\r
944                         by = (BallMinY + ((BallMaxY - BallMinY) / 2)) << 2;\r
945                 }\r
946                 //++++VW_UpdateScreen();\r
947                 while (waittime == TimeCount)\r
948                         ;       // DEBUG - do adaptiveness\r
949         } while ((LastScan != sc_Escape) && !done);\r
950         IN_ClearKeysDown();\r
951 }\r
952 \r
953 #pragma argsused\r
954 static boolean\r
955 USL_PongCustom(UserCall call,struct UserItem far *item)\r
956 {\r
957         if (call != uic_SetupCard)\r
958                 return(false);\r
959 \r
960         VWB_DrawPic(0,0,CP_MENUSCREENPIC);\r
961         VWB_DrawPic(CtlPanelSX + 56,CtlPanelSY,CP_PADDLEWARPIC);\r
962         VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,CtlPanelSY + 12,HiliteColor ^ BackColor);\r
963         VWB_Hlin(CtlPanelSX + 3,CtlPanelEX - 3,CtlPanelEY - 7,HiliteColor ^ BackColor);\r
964         USL_PlayPong();\r
965 \r
966         return(true);\r
967 }\r
968 \r
969 #endif\r