Subversion Repositories svn1

Rev

Rev 1 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1 root 1
/*************************************************************************
2
*           Copyright (C) 1995 Embedded Solutions
3
*                       All rights reserved
4
*
5
* file:     src\vduW32.c
6
*
7
* purpose:  This module contains all the VDU interface routines
8
*
9
*           This instance of this file implements the functions
10
*           in a Win32 platform.
11
*
12
*           A small number of routines are provided. These can be emulated
13
*           on other machines to provide similar functions
14
*
15
*           A number of general purpose I/O routines are also provided
16
*
17
* functions
18
*       init_screen             - Initialize the screen
19
*       cur                     - Position the cursor on the screen
20
*       clearscreen             - Clears the vdu screen
21
*       beep                    - Generate a bell character
22
*       flush_out               - Flush terminal output
23
*       getinp                  - Get one character of input
24
*       getnum                  - Get a number from the operator
25
*       getstring               - Get and edit a string
26
*       getsex                  - Get a sex type from the operator
27
*       getclass                - Get a class descriptor
28
*       getcountry              - Get a country descriptor
29
*       getfnc                  - Get menu selector
30
*       getyes                  - Prompt for YES / NO
31
*       to_upper                - Convert character to upper case
32
*       to_lower                - Convert character to lower case
33
*       sleep                   - Wait a bit
34
*       printf                  - Text display routines
35
*       putchar                 - Text display routines
36
*       console_clreol          - Clear to end of the line
37
*       console_prompt          - Display a hightlighted prompt
38
*
39
* programmer: David Purdie
40
*
41
* revision  date        by      reason
42
*   00.0    17/09/2002  DDP     Created
43
*
44
**************************************************************************/
45
 
46
#include    <stdio.h>
47
#include    <ctype.h>
48
#include    <windows.h>
49
#include    <wincon.h>
50
 
51
#include    "consts.h"
52
#include    "structs.h"
53
#include    "proto.h"
54
 
55
/* variables used by the routines */
56
 
57
int         n_lines;                             /* Number of lines on the screen */
58
int         n_cols;
59
 
60
int         rubout = '\010';                     /* users rubout character */
61
char        escape = '\033';                     /* Escape character */
62
int         abort_flag = FALSE;                  /* Abort character detected */
63
int         fnc_opr;                             /* Function key pushed */
64
 
65
 
66
HANDLE      h_console;                          /* Output handle */
67
 
68
/*
69
**  Prototypes
70
*/
71
int get_kb_character( void );
72
 
73
 
74
/*========================================================================
75
 *
76
 *  Initialize the screen
77
 *
78
 *  Purpose:
79
 *      This function is called to Initialize the screen
80
 *
81
 *  Parameters:
82
 *      None
83
 *
84
 *  Returns:
85
 *      Nothing
86
 *
87
 *========================================================================*/
88
 
89
void init_screen( void )
90
{
91
    /*
92
    **  Save a handle to the console
93
    */
94
    h_console = GetStdHandle(STD_OUTPUT_HANDLE);
95
 
96
    /*
97
    **  Operate within a virtual console area of 24 * 80
98
    **  Ignore the real console area
99
    */
100
    n_lines = 24;                                /* Fix number of lines for export */
101
    n_cols = 80;                                 /* Number of cols */
102
}
103
 
104
 
105
/*========================================================================
106
 *
107
 *  Restore screen to normal
108
 *
109
 *  Purpose:
110
 *      This function is called to Restore screen to normal
111
 *
112
 *  Parameters:
113
 *      None
114
 *
115
 *  Returns:
116
 *      Nothing
117
 *
118
 *========================================================================*/
119
 
120
void fix_screen( void )                          /* Restore screen to normal */
121
{
122
    flush_out();
123
}
124
 
125
/*========================================================================
126
 *
127
 *  Position the cursor on the screen
128
 *
129
 *  Purpose:
130
 *      This function is called to Position the cursor on the screen
131
 *
132
 *  Parameters:
133
 *      x               col number
134
 *      y               line number
135
 *
136
 *  Returns:
137
 *      Nothing
138
 *
139
 *========================================================================*/
140
 
141
void cur( int x, int y )
142
{
143
    COORD cursor;
144
 
145
    cursor.Y = y;
146
    cursor.X = x;
147
    SetConsoleCursorPosition ( h_console, cursor );
148
}
149
 
150
/*========================================================================
151
 *
152
 *  Position the cursor on the screen
153
 *
154
 *  Purpose:
155
 *      This function is called to save the current cursor location
156
 *      A single level save - for debug
157
 *
158
 *  Parameters:
159
 *      None
160
 *
161
 *  Returns:
162
 *      Nothing
163
 *
164
 *========================================================================*/
165
int save_x,save_y;
166
void save_cur(void)
167
{
168
 
169
    CONSOLE_SCREEN_BUFFER_INFO console_info;
170
 
171
    /*
172
    **  Determine the screen size and the current location of the
173
    **  cursor within the screen
174
    */
175
    GetConsoleScreenBufferInfo( h_console, &console_info );
176
    save_x = console_info.dwCursorPosition.X;
177
    save_y = console_info.dwCursorPosition.Y;
178
}
179
 
180
void restore_cur(void)
181
{
182
    cur( save_x, save_y);
183
}
184
 
185
 
186
/*========================================================================
187
 *
188
 *  Clears the vdu screen 
189
 *
190
 *  Purpose:
191
 *      This function is called to Clears the vdu screen
192
 *      From the Microsoft Web Site 
193
 *
194
 *  Parameters:
195
 *      None
196
 *
197
 *  Returns:
198
 *      Nothing
199
 *
200
 *========================================================================*/
201
 
202
void clearscreen( void )
203
{
204
    COORD coordScreen = { 0, 0 };        /* home for the cursor  */
205
    DWORD cCharsWritten;
206
    CONSOLE_SCREEN_BUFFER_INFO csbi;
207
    DWORD dwConSize;
208
 
209
    /*
210
    **   Get the number of character cells in the current buffer.
211
    */
212
 
213
    if( !GetConsoleScreenBufferInfo( h_console, &csbi ))
214
        return;
215
    dwConSize = csbi.dwSize.X * csbi.dwSize.Y;
216
 
217
    /*
218
    **   Fill the entire screen with blanks.
219
    */
220
    if( !FillConsoleOutputCharacter( h_console, (TCHAR) ' ',
221
                                dwConSize, coordScreen, &cCharsWritten ))
222
        return;
223
 
224
    /*
225
    **    Get the current text attribute.
226
    */
227
    if( !GetConsoleScreenBufferInfo( h_console, &csbi ))
228
        return;
229
 
230
    /*
231
    **  Set the buffer's attributes accordingly.
232
    */
233
    if( !FillConsoleOutputAttribute( h_console, csbi.wAttributes,
234
                                dwConSize, coordScreen, &cCharsWritten ))
235
        return;
236
 
237
    /*
238
    **   Put the cursor at its home coordinates.
239
    */
240
    SetConsoleCursorPosition( h_console, coordScreen );
241
}
242
 
243
/*========================================================================
244
 *
245
 *  Generate a bell character
246
 *
247
 *  Purpose:
248
 *      This function is called to Generate a bell character
249
 *
250
 *  Parameters:
251
 *      None
252
 *
253
 *  Returns:
254
 *      Nothing
255
 *
256
 *========================================================================*/
257
 
258
void beep( void )
259
{
260
    putchar( '\007' );
261
}
262
 
263
 
264
/*========================================================================
265
 *
266
 *  Flush terminal output
267
 *
268
 *  Purpose:
269
 *      This function is called to Flush terminal output
270
 *
271
 *  Parameters:
272
 *      None
273
 *
274
 *  Returns:
275
 *      Nothing
276
 *
277
 *========================================================================*/
278
 
279
void flush_out( void )
280
{
281
}
282
 
283
 
284
/*========================================================================
285
 *
286
 *  Get one character of input
287
 *
288
 *  Purpose:
289
 *      This function is called to Get one character of input
290
 *
291
 *  Parameters:
292
 *      None
293
 *
294
 *  Returns:
295
 *      Ascii code or internal control code which will be greater than
296
 *      a byte
297
 *
298
 *========================================================================*/
299
 
300
int getinp( void )
301
{
302
 
303
    /*
304
     * General input routine
305
     * Will intercept function keys and set flags
306
     */
307
 
308
    int         c;
309
 
310
    c = get_kb_character();
311
    if( c & 0xff )
312
    {
313
        c = c & 0xff;
314
        if( c == '\r' )
315
            c = '\n';
316
        if( c == ABORT_CHAR || c == ABORT_CHAR_1 )
317
        {
318
            abort_flag = TRUE;
319
            c = ABORT_CHAR;
320
        }
321
        return ( c );                            /* Input is ascii char */
322
    }
323
    c >>= 8;                                     /* Upper byte */
324
    if( c >= 59 && c <= 68 )
325
    {
326
        fnc_opr = FNC1 + c - 59;
327
        return ( 0 );
328
    }
329
    switch ( c )
330
    {
331
    case 71:    return ( HOME_KEY );
332
    case 72:    return ( UPARROW );
333
    case 75:    return ( LEFTARROW );
334
    case 77:    return ( RIGHTARROW );
335
    case 80:    return ( DOWNARROW );
336
    case 73:    return ( PAGE_UP );
337
    case 81:    return ( PAGE_DOWN );
338
    case 79:    return ( END_KEY );
339
    case 82:    return ( INSERT_KEY );
340
    case 83:    return ( DELETE_KEY );
341
    case 15:    return ( BACKTAB );
342
    }
343
    return ( 0 );
344
}
345
 
346
 
347
/*========================================================================
348
 *
349
 *  Get a number from the operator
350
 *
351
 *  Purpose:
352
 *      This function is called to get a number from the operator
353
 *      
354
 *      This routine will accept numeric data entry from the operator
355
 *      the routine will limit the operator input to a limited number
356
 *      of characters. This allowes fixed format input
357
 *      
358
 *  Parameters:
359
 *      max_len         Max field width allowed
360
 *      final_buf       pointer to the final resting place of the number
361
 *
362
 *  Returns:
363
 *      This routine will return an indication of operator input
364
 *          0 - No valid entry
365
 *          1 - data entered and transfered to number.
366
 *
367
 *========================================================================*/
368
 
369
bool getnum( int max_len, int *final_buf )
370
{
371
    char        n_buf[30];                       /* Convert number here */
372
 
373
    n_buf[0] = '\0';
374
    if ( *final_buf )
375
        sprintf( n_buf, "%*.*d", max_len,max_len, *final_buf );
376
    if( getstring( max_len, n_buf, Digit ) )
377
    {
378
        sscanf( n_buf, "%d", final_buf );
379
        return ( TRUE );
380
    }
381
    else
382
        return ( FALSE );
383
}
384
 
385
/*========================================================================
386
 *
387
 *  Get and edit a string
388
 *
389
 *  Purpose:
390
 *      This function is called to Get and edit a string
391
 *
392
 *  Parameters:
393
 *      len                 Max length of the string
394
 *      str                 Address of the string
395
 *      limit               Types of chars allowed
396
 *
397
 *  Returns:
398
 *      Length of the input string
399
 *
400
 *========================================================================*/
401
 
402
int getstring( int len, char *str, enum class_enum limit )
403
{
404
    char        buf[100];                        /* Internal edit buffer */
405
    int         i;                               /* Current index into buf */
406
    int         ii;                              /* Number of characters in buf */
407
    int         j;                               /* Loooopy variable */
408
    int         ch;                              /* Current input character */
409
 
410
    ( void ) memset( buf, 0, 100 );              /* Init the buffer */
411
    ( void ) strcpy( buf, str );                 /* Copy in the original string */
412
    ii = i = strlen( str );                      /* i is at the end of the string */
413
    printf( "%s", buf );                         /* Display the current string */
414
 
415
    /*
416
     * This routine assumes that the cursor is at the end of
417
     * the string as it is displayed on the screen
418
     */
419
 
420
    while( !abort_flag )
421
    {
422
        ch = getinp();                           /* Get the next character */
423
 
424
        if( ch == '\n' || ch == '\t' || fnc_opr || abort_flag )/* RETURN */
425
            break;                               /* Finish the edit */
426
 
427
        else if( ch == rubout && i )             /* Users rubout character */
428
        {
429
            i--;
430
            putchar( '\010' );
431
            for( j = i; j <= ii; j++ )
432
                buf[j] = buf[j + 1];
433
            printf( "%s ", &buf[i] );            /* Print remainder of the buffer */
434
            ii--;                                /* One less in the buffer */
435
            for( j = i; j <= ii; j++ )
436
                putchar( '\010' );
437
        }
438
 
439
        else if( ch == DELETE_KEY && i != ii )   /* Delete char under cursor */
440
        {
441
            for( j = i; j <= ii; j++ )
442
                buf[j] = buf[j + 1];
443
            printf( "%s ", &buf[i] );
444
            ii--;
445
            for( j = i; j <= ii; j++ )
446
                putchar( '\010' );
447
        }
448
 
449
        else if( ( ch == '\010' || ch == LEFTARROW ) && i ) /* Back-space */
450
        {
451
            i--;
452
            putchar( '\010' );
453
        }
454
 
455
        else if( ch == RIGHTARROW && i < ii )    /* forward */
456
            putchar( buf[i++] );
457
 
458
        else if( ( ii < len ) && ( ( ( limit == Alphanum  || limit == AlphnumUpper) && isprint( ch ) ) || ( ( limit == Digit ) && isascii( ch ) && isdigit( ch ) ) || ( ( limit == Alpha ) && isalpha( ch ) ) ) )    /* Insert the char */
459
        {
460
            if ( limit == AlphnumUpper )
461
                ch = toupper(ch);
462
 
463
            for( j = ii + 1; j > i; j-- )
464
                buf[j] = buf[j - 1];
465
            buf[i] = ch;
466
            ii++;
467
            printf( "%s", &buf[i++] );  /* Print remainder of the buffer */
468
            for( j = i; j < ii; j++ )
469
                putchar( '\010' );
470
        }
471
        else
472
        {
473
            beep();
474
        }
475
    }
476
 
477
    /*
478
     * Edit complete - transfer the data to the user 
479
     */
480
 
481
    printf( "%s", &buf[i] );            /* Cursor to end of the buffer */
482
    if( !abort_flag )
483
        strcpy( str, buf );             /* Copy buffer to the user */
484
    else
485
        ii = 0;
486
    return ( ii );                               /* Return length of input */
487
}
488
 
489
/*========================================================================
490
 *
491
 *  Get a sex type from the operator
492
 *
493
 *  Purpose:
494
 *      This function is called to Get a sex type from the operator
495
 *
496
 *  Parameters:
497
 *      None
498
 *
499
 *  Returns:
500
 *      A sex type
501
 *      The unknown sex type is used to signal no change in state
502
 *
503
 *========================================================================*/
504
 
505
sex_type getsex( void )
506
{
507
    sex_type    curr = unknown;                  /* current sex type in display */
508
    char        c;
509
 
510
    while( ( c = getinp() ) != ABORT_CHAR )
511
    {
512
        if( c == '\n' || c == '\t' )
513
        {
514
            return ( curr );
515
        }
516
        if( c == 'M' )
517
        {
518
            printf( "Male  \010\010\010\010\010\010" );
519
            curr = male;
520
        }
521
        else if( c == 'F' )
522
        {
523
            printf( "Female\010\010\010\010\010\010" );
524
            curr = female;
525
        }
526
        else
527
        {
528
            beep();
529
        }
530
    }
531
    return ( unknown );
532
}
533
 
534
/*========================================================================
535
 *
536
 *  Get a class descriptor
537
 *
538
 *  Purpose:
539
 *      This function is called to Get a class descriptor
540
 *
541
 *  Parameters:
542
 *      None
543
 *
544
 *  Returns:
545
 *      An integer which is the index into the  config.team_class array
546
 *
547
 *========================================================================*/
548
 
549
int getclass( void )
550
{
551
    char        cc[3];                           /* Input character */
552
    int         i, j;                            /* One those loopy things */
553
 
554
 
555
    cc[0] = '\0';
556
    while( ( j = getstring( 2, cc, AlphnumUpper ) ) != 0 )
557
    {
558
        /*
559
        **  Is this a valid class
560
        */
561
        if ( (i = lookup_class(cc, NULL)) > 0 )
562
            return (i);
563
 
564
        /*
565
        **  Invalid
566
        **  Rubout and try again
567
        */
568
        beep();
569
        for( i = 0; i < j; i++ )
570
            putchar( '\010' );
571
    }
572
    return ( 0 );
573
}
574
 
575
/*========================================================================
576
 *
577
 *  Get a country descriptor
578
 *
579
 *  Purpose:
580
 *      This function is called to Get a country descriptor
581
 *
582
 *  Parameters:
583
 *      None
584
 *
585
 *  Returns:
586
 *      An integer which is the index into the config.country_name array.
587
 *
588
 *========================================================================*/
589
 
590
int getcountry( void )
591
{
592
    char        cc[5];                           /* Input character */
593
    int         i, j, k;                         /* One those loopy things */
594
 
595
    cc[0] = '\0';
596
    while( ( j = getstring( 4, cc, Alphanum ) ) != 0 )
597
    {
598
 
599
        /*
600
         * Attempt to locate the entered country in the list of defined countries
601
         */
602
 
603
        for( i = 0; i < MAX_COUNTRY; i++ )
604
        {
605
            for( k = 0; k <= j; k++ )
606
            {
607
                if( cc[k] == '\000' )
608
                    return ( ++i );              /* Found it */
609
 
610
                if( toupper( cc[k] ) !=
611
                    toupper( config.country_name[i].abr[k] ) )
612
                    break;
613
            }
614
        }
615
        beep();
616
        for( i = 0; i < j; i++ )
617
            putchar( '\010' );
618
    }
619
    return ( 0 );
620
}
621
 
622
/*========================================================================
623
 *
624
 *  Get menu selector
625
 *
626
 *  Purpose:
627
 *      This function is called to Get menu selector
628
 *
629
 *      This function will accept characters until one in
630
 *      "list" is encountered. This is returned to the user
631
 *      RETURN is valid if the first character of the list is not a "*"
632
 *      it will return the first charcater of the list;
633
 *      ABORT will return a zero
634
 *
635
 *  Parameters:
636
 *      List        A string of valid responses
637
 *
638
 *  Returns:
639
 *      Selected character
640
 *
641
 *========================================================================*/
642
 
643
char getfnc( char *list )
644
{
645
    char       *copylist;
646
    char        c;
647
    char        result = 0;
648
 
649
    copylist = ( *list == '*' ) ? list + 1 : list;
650
    while( ( c = getinp() ) != ABORT_CHAR )
651
    {
652
        c = toupper( c );                        /* Get a character */
653
        if( strchr( copylist, c ) )
654
        {
655
            result = c;
656
            break;
657
        }
658
 
659
        if( c == '\n' && *list != '*' )
660
        {
661
            result = *list;
662
            break;
663
        }
664
 
665
        beep();
666
    }
667
 
668
    /*
669
    **  Display the option selected
670
    **  Not ready for this yet. Looks a bit ugle in a few places
671
    */
672
    /*    if ( result )
673
    **    putchar(result);
674
    */
675
 
676
    return ( result );
677
}
678
 
679
/*========================================================================
680
 *
681
 *  Prompt for YES / NO
682
 *
683
 *  Purpose:
684
 *      This function is called to Prompt for YES / NO
685
 *
686
 *  Parameters:
687
 *      prompt      Prompt to display to the user
688
 *
689
 *  Returns:
690
 *      TRUE for Yes, FALSE for No
691
 *
692
 *========================================================================*/
693
 
694
bool getyes( char *prompt )
695
{
696
    char        c;
697
 
698
    printf( "%s ? ", prompt );
699
    c = getfnc( "*YN" );
700
    putchar( '\n' );
701
    return ( c == 'Y' );
702
}
703
 
704
/*========================================================================
705
 *
706
 *  Convert character to upper case
707
 *
708
 *  Purpose:
709
 *      This function is called to convert character to upper case
710
 *
711
 *  Parameters:
712
 *      ch      Character to convert
713
 *
714
 *  Returns:
715
 *      Converted character
716
 *
717
 *========================================================================*/
718
 
719
char to_upper( char ch )
720
{
721
    if( islower( ch ) )
722
        return ( ch + 'A' - 'a' );
723
    return ( ch );
724
}
725
 
726
/*========================================================================
727
 *
728
 *  Convert character to lower case
729
 *
730
 *  Purpose:
731
 *      This function is called to convert character to lower case
732
 *
733
 *  Parameters:
734
 *      ch      Character to convert
735
 *
736
 *  Returns:
737
 *      Converted character
738
 *
739
 *========================================================================*/
740
 
741
char to_lower( char ch )
742
{
743
    if( isupper( ch ) )
744
        return ( ch + 'a' - 'A' );
745
    return ( ch );
746
}
747
 
748
 
749
/*========================================================================
750
 *
751
 *  Wait a bit
752
 *
753
 *  Purpose:
754
 *      This function is called to idle and to nothing for a while
755
 *
756
 *  Parameters:
757
 *      t           Time to wait
758
 *
759
 *  Returns:
760
 *      Nothing
761
 *
762
 *========================================================================*/
763
 
764
void sleep( int t )
765
{
766
    Sleep ( t * 1000 );
767
}
768
 
769
 
770
/*========================================================================
771
 *
772
 *  Clear to the end of the current display line
773
 *
774
 *  Purpose:
775
 *      Clears to the end of the line
776
 *
777
 *  Parameters:
778
 *      None
779
 *
780
 *  Returns:
781
 *      Nothing
782
 *
783
 *========================================================================*/
784
void console_clreol( void )
785
{
786
 
787
    CONSOLE_SCREEN_BUFFER_INFO console_info;
788
    DWORD                      rlen;
789
 
790
    int ii;
791
    int top;
792
 
793
 
794
    /*
795
    **  Determine the screen size and the current location of the
796
    **  cursor within the screen
797
    */
798
    GetConsoleScreenBufferInfo( h_console, &console_info );
799
 
800
    /*
801
    **  Clear all of it
802
    */
803
    top = console_info.dwSize.X - console_info.dwCursorPosition.X;
804
 
805
    for ( ii = 0; ii < top ; ii++ )
806
    {
807
        WriteConsole( h_console, " ", 1, &rlen, NULL );
808
    }
809
    cur ( console_info.dwCursorPosition.X, console_info.dwCursorPosition.Y );
810
}
811
 
812
/*========================================================================
813
 *
814
 *  printf - Text display routines
815
 *  putchar - Text display routines
816
 *
817
 *
818
 *  Purpose:
819
 *      Intercept standard output calls and direct output to the
820
 *      console.
821
 *
822
 *  Parameters: As per standard function definitions
823
 *      None
824
 *
825
 *  Returns:
826
 *      As per standard function definitions
827
 *
828
 *========================================================================*/
829
 
830
 
831
int putchar(int cc)
832
{
833
    printf( "%c", cc );
834
    return 1;
835
}
836
 
837
// void gross_error_message(void)
838
// {
839
//     LPVOID lpMsgBuf;
840
//
841
//     FormatMessage(
842
//         FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
843
//         NULL,
844
//         GetLastError(),
845
//         MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
846
//         (LPTSTR) &lpMsgBuf,
847
//         0,
848
//         NULL
849
//     );
850
//
851
//     // Display the string.
852
//     MessageBox( NULL, lpMsgBuf, "GetLastError", MB_OK|MB_ICONINFORMATION );
853
//
854
//     // Free the buffer.
855
//     LocalFree( lpMsgBuf );
856
// }
857
 
858
int printf( const char *format, ... )
859
{
860
    va_list     ap;
861
    char        pp[200];
862
    int         len;
863
    BOOL        result;
864
    HANDLE      h_console;
865
 
866
    DWORD       llen;
867
    DWORD       rlen;
868
 
869
 
870
    va_start( ap, format );
871
    len = vsprintf( pp, format, ap );
872
    va_end( ap );
873
 
874
    llen = len;
875
    h_console = GetStdHandle(STD_OUTPUT_HANDLE);
876
    result = WriteConsole( h_console, pp, llen, &rlen, NULL );
877
    return ( len );
878
}
879
 
880
/*========================================================================
881
 *
882
 *  Display a prompt character in a highlight
883
 *
884
 *  Purpose:
885
 *      USed to highlight menu entries
886
 *
887
 *  Parameters:
888
 *      None
889
 *
890
 *  Returns:
891
 *      Nothing
892
 *
893
 *========================================================================*/
894
void console_prompt( char prompt )
895
{
896
    SetConsoleTextAttribute( h_console, FOREGROUND_GREEN );
897
    putchar( prompt );
898
    SetConsoleTextAttribute( h_console, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE );
899
}
900
 
901
/*------------------------------------------------------------------------------
902
Name:           get_kb_character
903
Description:    Extract a keyboard character - including cursor and function
904
                keys.
905
Parameters:     None
906
Global Refs:
907
Returns:        a 16 bit value that encodes ascii character and scan code
908
Side-effects:
909
------------------------------------------------------------------------------*/
910
 
911
int get_kb_character( void )
912
{
913
    HANDLE          hConsoleInput;
914
    INPUT_RECORD    Buffer;
915
    DWORD           NumberOfEventsRead;
916
 
917
    hConsoleInput = GetStdHandle(STD_INPUT_HANDLE);
918
 
919
    /*
920
    **  Process console events until we get a suitable keystroke event
921
    */
922
    FlushFileBuffers( h_console );
923
    for (;;)
924
    {
925
        if (ReadConsoleInput( hConsoleInput, &Buffer, 1, &NumberOfEventsRead ))
926
        {
927
            /*
928
            **  Only want keyboard depression - ignore other events
929
            */
930
            if (Buffer.EventType == KEY_EVENT && Buffer.Event.KeyEvent.bKeyDown)
931
            {
932
                /*
933
                **  Ignore several scan codes
934
                **  CNTRL, ALT, SHIFT, CAPLOCK
935
                */
936
                if (Buffer.Event.KeyEvent.wVirtualScanCode == 0x38 ||
937
                    Buffer.Event.KeyEvent.wVirtualScanCode == 0x1D ||
938
                    Buffer.Event.KeyEvent.wVirtualScanCode == 0x2A ||
939
                    Buffer.Event.KeyEvent.wVirtualScanCode == 0x3A)
940
                {
941
                    continue;
942
                }
943
 
944
                return ( (int) (Buffer.Event.KeyEvent.uChar.AsciiChar + (Buffer.Event.KeyEvent.wVirtualScanCode << 8)));
945
            }
946
        }
947
    }
948
 
949
}
950
 
951
/********************************* EOF ***********************************/
952