⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 console.c

📁 C++游戏开发书籍的实例非常适合初学但又又想往游戏开发方面发展的人学习哦
💻 C
📖 第 1 页 / 共 4 页
字号:
/*


#include "tdestr.h"
#include "common.h"
#include "define.h"
#include "tdefunc.h"

#include <bios.h>               /* for direct BIOS keyboard input */


/*******************************************************/
/*                                                     */
/*  1) initialize the video and keyboard structures    */
/*                                                     */
/*******************************************************/


/*
 *   BIOS Data Areas
 *
 *   See:
 *
 *      IBM Corp., _Technical Reference:  Personal Computer AT_,
 *      Boca Raton, Florida, 1984, IBM part no. 1502494,
 *      pp 5-29 thru 5-32.
 *
 *  These addresses, variable names, types, and descriptions are directly
 *   from the IBM AT Technical Reference manual, BIOS listing, copyright IBM.
 *
 *   Address  Name           Type   Description
 *   0x0449   CRT_MODE       Byte   Current CRT mode
 *   0x044a   CRT_COLS       Word   Number columns on screen
 *   0x044c   CRT_LEN        Word   length of regen buffer, video buffer, bytes
 *   0x044e   CRT_START      Word   Starting address of regen buffer
 *   0x0450   CURSOR_POSN    Word   cursor for each of up to 8 pages.
 *   0x0460   CURSOR_MODE    Word   current cursor mode setting.
 *   0x0462   ACTIVE_PAGE    Byte   Current page
 *   0x0463   ADDR_6845      Word   base address for active display card
 *   0x0465   CRT_MODE_SET   Byte   current mode of display card
 *   0x0466   CRT_PALETTE    Byte   overscan color for CGA, EGA, and VGA.
 *   0x0467   io_rom_init    Word   Pointer to optional i/o rom init routine
 *   0x0469   io_rom_seg     Word   Pointer to io rom segment
 *   0x046b   intr_flag      Byte   Flag to indicate an interrupt happened
 *   0x046c   timer_low      Word   Low word of timer count
 *   0x046e   timer_high     Word   High word of timer count
 *   0x0470   timer_ofl      Byte   Timer has rolled over since last count
 *   0x0471   bios_break     Byte   Bit 7 = 1 if Break Key has been hit
 *   0x0472   reset_flag     Word   Word = 1234h if keyboard reset underway
 *   0x0484   ROWS           Byte   Number of displayed character rows - 1
 *   0x0485   POINTS         Word   Height of character matrix
 *   0x0487   INFO           Byte   EGA and VGA display data
 *   0x0488   INFO_3         Byte   Configuration switches for EGA and VGA
 *   0x0489   flags          Byte   Miscellaneous flags
 *   0x0496   kb_flag_3      Byte   Additional keyboard flag
 *   0x048A   DCC            Byte   Display Combination Code
 *   0x04A8   SAVE_PTR       Dword  Pointer to BIOS save area
 */
void video_config( struct vcfg *cfg )
{
#pragma pack( 1 )    /* Use pragma to force packing on byte boundaries. */

struct LOWMEMVID
{
   char     vidmode;           /* 0x449 */
   unsigned scrwid;            /* 0x44A */
   unsigned scrlen;            /* 0x44C */
   unsigned scroff;            /* 0x44E */
   struct   LOCATE
   {
      unsigned char col;
      unsigned char row;
   } csrpos[8];                /* 0x450 */
   struct   CURSIZE
   {
      unsigned char end;
      unsigned char start;
   } csrsize;                  /* 0x460 */
   char      page;             /* 0x462 */
   unsigned  addr_6845;        /* 0x463 */
   char      crt_mode_set;     /* 0x465 */
   char      crt_palette;      /* 0x466 */
   char      system_stuff[29]; /* 0x467 */
   char      rows;             /* 0x484 */
   unsigned  points;           /* 0x485 */
   char      ega_info;         /* 0x487 */
   char      info_3;           /* 0x488 */
   char      skip[13];         /* 0x489 */
   char      kb_flag_3;        /* 0x496 */
} vid;
struct LOWMEMVID _far *pvid = &vid;
#pragma pack( )    /* revert to previously defined pack pragma. */

union REGS in, out;
unsigned char temp, active_display;

   /*
    * Move system information into our video structure.
    */
   _fmemmove( pvid, (void far *)0x00000449l, sizeof( vid ) );

   cfg->rescan = FALSE;
   in.x.ax =  0x1a00;
   int86( VIDEO_INT, &in, &out );
   temp = out.h.al;
   active_display = out.h.bl;
   if (temp == 0x1a && (active_display == 7 || active_display == 8))
      g_display.adapter = VGA;
   else {
      in.h.ah =  0x12;
      in.h.bl =  0x10;
      int86( VIDEO_INT, &in, &out );
      if (out.h.bl != 0x10) {         /* EGA */
         if (vid.ega_info & 0x08)
            g_display.adapter = vid.addr_6845 == 0x3d4 ? CGA : MDA;
         else
            g_display.adapter = EGA;
      } else if (vid.addr_6845 == 0x3d4)
         g_display.adapter = CGA;
      else
         g_display.adapter = MDA;
   }

   if (g_display.adapter == CGA || g_display.adapter == EGA) {
      if (g_display.adapter == CGA)
         cfg->rescan = TRUE;
      g_display.insert_cursor = mode.cursor_size == SMALL_INS ? 0x0607 : 0x0407;
      g_display.overw_cursor = mode.cursor_size == SMALL_INS ? 0x0407 : 0x0607;
   } else {
      g_display.insert_cursor = mode.cursor_size == SMALL_INS ? 0x0b0c : 0x070b;
      g_display.overw_cursor = mode.cursor_size == SMALL_INS ? 0x070b : 0x0b0c;
   }

   cfg->mode = vid.vidmode;
   if (vid.addr_6845 == 0x3D4) {
      cfg->color = TRUE;
      cfg->videomem = (void far *)0xb8000000l;
   } else {
      cfg->color = FALSE;
      cfg->videomem = (void far *)0xb0000000l;
   }

   /*
    * let save the overscan color
    */
   g_display.old_overscan = vid.crt_palette;


   /*
    * Get keyboard type.  Since there is no interrupt that determines
    * keyboard type, use this method.  Look at bit 4 in keyboard flag3.
    * This method is not always foolproof on clones.
    */
   if ((vid.kb_flag_3 & 0x10) != 0)
      mode.enh_kbd = TRUE;
   else
      mode.enh_kbd = FALSE;
   if (mode.enh_kbd == FALSE)
      simulate_enh_kbd( 1 );
}


/*********************************************/
/*                                           */
/*  2) keyboard i/o routines, PC specific    */
/*                                           */
/*********************************************/


/*
 * The next function was written by Tom Waters, twaters@relay.nswc.navy.mil, and
 * modified extensively by Frank Davis.
 *
 * "I use ANSI.SYS to redefine a few of my function keys and this causes a
 * problem when getch() is used in a program.  For example, instead of returning
 * 321 for the F7, I get the redefined string inserted in the text. So, instead
 * of using getch(), I use the following function ..."
 *
 * Tom, thanks for the info and solution.  I'm sure your function will be
 * be appreciated by everyone with ANSI key defs, Frank.
 */

/*
 * Name:    getkey
 * Purpose: use bios to get keyboard input (getch has trouble w/ ANSI
 *          redefined keys)
 * Date:    July 2, 1991
 * Modified:July 12, 1991, Frank Davis - accept ALT-xxx keyboard entry
 *          September 10, 1991, Frank Davis - add support for Ctrl+Up, etc...
 * Passed:  None
 * Notes:   Uses the BIOS to read the next keyboard character.  Service 0x00
 *           is the XT keyboard read.  Service 0x10 is the extended keyboard
 *           read.  Test for a bunch of special cases.  Allow the user to enter
 *           any ASCII or Extended ASCII code as a normal text characters.
 *
 *          Control @ is defined as 0.  we need to do a special test
 *           for this key, otherwise it's interpretted as an Alt key.  It's
 *           the only "regular" Control key that returns 0 in AL and the scan
 *           byte in AH.  The "regular" Control keys are those in the range
 *           0-31 and they return the Control character in AL and the scan
 *           code in AH.  All of the Alt + keys return 0 in AL and
 *           the scan code in ah.
 *
 *          This function was written for US keyboards.  It may have to be
 *           modified for other keyboards, eg. Belgium, Canada, Czech,
 *           Slovak, Denmark, France, Germany, etc...
 *
 *          if Ctrl-Break is pressed, it returns 0xffff as the key pressed.
 *           let's set it to CONTROL_BREAK == 269 and do nothing.
 */
int getkey( void )
{
unsigned key, num_lock, control, shift;
register scan;
register unsigned lo;

/*
 * this code is used during testing to check the amount of memory
 *    in the near heap.
 *
 * char buff[MAX_COLS];
 * ultoa( _memavl( ), buff, 10 );
 * s_output( "h=       ", g_display.mode_line, 37, g_display.mode_color );
 * s_output( buff, g_display.mode_line, 39, g_display.mode_color );
 */

   /*
    * lets spin on waitkey until the user presses a key.  waitkey polls
    *  the keyboard and returns 0 when a key is waiting.
    */
   while (waitkey( mode.enh_kbd ));

   /*
    *  _bios_keybrd == int 16.  It returns the scan code in ah, hi part of key,
    *   and the ascii key code in al, lo part of key.  If the character was
    *   entered via ALT-xxx, the scan code, hi part of key, is 0.
    */
   if (mode.enh_kbd) {
      key = _bios_keybrd( 0x10 );
      lo  = _bios_keybrd( 0x12 );

      /*
       * couple of special cases:
       *   on the numeric keypad, some keys return 0xe0 in the lo byte.
       *   1) if user enters Alt-224, then the hi byte == 0 and lo byte == 0xe0.
       *   we need to let this get thru as an Extended ASCII char.  2) although
       *   we could make the cursor pad keys do different functions than the
       *   numeric pad cursor keys, let's set the 0xe0 in the lo byte to zero
       *   and forget about support for those keys.
       */
      if ((key & 0x00ff) == 0x00e0 && (key & 0xff00) != 0)
         key = key & 0xff00;
   } else {
      key = _bios_keybrd( 0 );
      lo  = _bios_keybrd( 2 );
   }
   num_lock = lo & 0x20;
   control  = lo & 0x04;
   shift    = lo & 0x03;
   scan = (key & 0xff00) >> 8;
   lo = key & 0X00FF;

   if (lo == 0) {
      /*
       * special case for Control @, which is defined as 0 or NULL.
       */
      if (scan == 3)
         lo = 430;

      /*
       * when first byte is 0, map it above 256, so that we can
       *  let ALT-xxx keys map to their 'natural' place.  In
       *  otherwords, use 0-255 as normal text characters and
       *  those >= 256 are function keys.
       */
      else
         lo = scan | 0x100;

   /*
    * now test for Control-Break.  let's set this to do nothing in the
    *  editor.  manually map Control-Break to 269 - DO NOT assign
    *  any function to 269.
    */
   } else if (key == 0xffff)
      lo = CONTROL_BREAK;


   /*
    * Pressing Control+BackSpace generates the 0x7f character.  Instead of
    * 0x7f, make lo the ASCII backspace character.  If anyone wants the
    * 0x7f character, then they can enter it via ALT+xxx.
    */
   if (scan == 14 && lo == 0x7f)
      lo = 8;

   /*
    * At the bottom of page 195 in MASM 6.0 ref manual, "..when the keypad
    *  ENTER and / keys are read through the BIOS interrupt 16h, only E0h
    *  is seen since the interrupt only gives one-byte scan codes."
    */
   else if (scan == 0xe0) {
      /*
       * plain Grey Enter
       */
      if (lo == 13 && !shift)
         lo = 285;
      /*
       * shift Grey Enter
       */
      else if (lo == 13)
         lo = 298;
      /*
       * control Grey Enter
       */
      else if (lo == 10)
         lo = 299;
   }

   /*
    *  let's massage all of the control key combinations.
    */
   if (lo < 32) {

      /*
       * My machine at home is sorta weird.  On every machine that I've
       *  tested at the awffice, the ALT-xxx combination returns 0 for the
       *  scan byte and xxx for the ASCII code.  My machine returns 184 (decimal)
       *  as the scan code?!?!?  I added the next two lines for my machine at
       *  home.  I wonder if someone forgot to zero out ah for Alt keypad entry
       *  when they wrote my bios?
       */
      if (scan > 0x80)
         scan = 0;

      /*
       * Separate the ESC key from the ^[ key.  The scan code for the ESC
       *  key is 1.  Map this to a different index into the key function
       *  array just in case someone wants to define ESC or ^[ to different
       *  functions.  BTW, ESC and ^[ return the same ASCII code, 27.
       */
      else if (scan == 1) {
         if (shift)
            lo = 259;
         else if (control)
            lo = 260;
         else
            lo = 258;
      }

      /*
       * Scan code for Enter = 28.  Separate the various Enter keys.
       */
      else if (scan == 28) {
         if (shift)
            lo = 263;
         else if (control)
            lo = 264;
         else
            lo = 262;
      }

      /*
       * Scan code for Backspace = 14.  Separate the various BackSpace keys.
       */
      else if (scan == 14) {
         if (shift)
            lo = 266;
         else if (control)
            lo = 267;
         else
            lo = 265;
      }

      /*
       * Scan code for Tab = 15.  Separate the tab key.
       */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -