#define  Hyp_Ver  "Version  v.2.11"  // 03.26.02

// Hyper Lander 2 -- Classic
// Filename: HYPER2.C
// UPDATE VERSION IN GLOBALS EACH TIME SOMETHING IS CHANGED
// Program by Thomas Ballard
// Copyright 1997, 1998, 1999, 2000, 2001, 2002  E.S.Q. Software
// All Rights Reserved
//
// SMIXC is Copyright 1995 by Ethan Brodsky.  
// All rights reserved

/*
// NOTES
// ================================================================
//
*/

/*
    Latest Update 03/26/02 03:02 PM
    Consolidating code for FULL VERSION open release.  (Visit http://esqsoft.com/hyper.html)
    Graphics changes and text changes... some minor changes to logic and timing... 

    Cleared out prior TO DO's and NOTES (see external file NOTES.txt for them if necessary)

    Yeah so I've learned a lot since this code was written. Notice the MASSIVE use of globals and 
    procedure oriented code.... yuck!  ...but this -was- GAME PROGRAMMING at the time I started this 
    project. At that time I was developing on a 486 running DOS 6.22 I think... since this code doesn't
    use a Dos Extender I had to fit everything into a medium memory model, and a big part of the 
    hardcoded properties are related to overflows I kept experiencing when using more variables in that memory model. 

    Some game and programming notes:
    -Globals are faster to access than passing variables into functions. 
    -Since this originally released in a shareware/registered format, I wanted to attempt to protect the registration code model.... it 
      was a pathetic attempt at obscurity... it only served to confuse me though.... :-)  so I've got a different schema in mind for 
      registration models -IF- I do another shareware/registered version product in the future.  Anyway.... obscurity "bad"!
*/    





// includes /////////////////////////////////////////////////////////////////

  #include <time.h>
  #include <io.h>
  #include <ctype.h>
  #include <conio.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <dos.h>
  #include <bios.h>
  #include <fcntl.h>
  #include "sys\stat.h"
  #include <memory.h>
  #include <malloc.h>
  #include <math.h>
  #include <string.h>
  #include "gamelib.h"
  #include "detect.h"     // sound system (finds card settings)
  #include "smix.h"       // sound system (actual mixing routines)





// prototypes ///////////////////////////////////////////////////////////////

  unsigned char Buttons_Bios(unsigned char button);
  unsigned int Joystick_Bios(unsigned char stick);
  unsigned char Buttons(unsigned char button);
  void  (_interrupt _far *Old_Key_Isr)();
  void  Refuel_Ship(void);
  void  Behind_Sprite(sprite_ptr sprite);  // FOR STATUS BOX
  void  Erase_Sprite(sprite_ptr sprite);
  void  Draw_Sprite(sprite_ptr sprite);
  int   Joystick_Available(int stick_num);
  int   Joystick_Calibrate_Method1(void);
  void  Blit_Char(int xc,int yc,char c,int color/*,int trans_flag*/,int sound,int scheme,int where);
  void  Blit_String(int x,int y,int color, char *string/*,int trans_flag*/, int speed, int scheme);
  void  Blit_String_DB(int x,int y,int color, char *string/*,int trans_flag*/, int speed, int scheme);
  void  Display_Message(int message);
  int   Check_For_Input(int local_delay);
  void  Load_Radio_Box(int option);
  void  Await_Exit_Request(int counter);
  void  Handle_Pause(void);
  int   Check_Collision(void);
  void  Status_Box(void);
  void  Handle_Draw(void);
  int   Change_Board(void);
  int   Check_Controller_Input(void);   
  int   Handle_Start(void);
  int   Handle_Copyright(void);
  int   Handle_Screen(void);
  int   Handle_Game_Data(void);
  int   Handle_Game_Speed(int option);
  int   Handle_Intro(void);
  void  Joystick_Driver(void);
  int   Handle_Keyboard_Driver(void);
  int   Handle_Joystick_Driver(void);
  void  Update_Variables(void);
  int   Handle_Sound_Driver(void);
  void  Handle_Earth_Quake(void);
  void  Handle_Display(void);
  void  Handle_Main_Menu(void);
  int   Handle_Ending(void);
  int   Handle_Win(void);
  int   Handle_Options_Menu(int Option);
  void  Close_Everything(void);
  void  Behind_Sprite_Clipped_DB(void); // optimization - replace passed parameters with globals.
  void  Erase_Sprite_Clipped_DB(void);  // optimization - replace passed parameters with globals.
  void  Draw_Sprite_Clipped_DB(void);   // optimization - replace passed parameters with globals.
  int   a(char *bh, int be);
  int   e(char *bh, int be);
  int   h(char *bh, int be);
  int   s(char *bh, int be);
  int   t(char *bh, int be);
  int   w(char *bh, int be);
  int   registration(void);
  int   getinputstring(int text_x, int text_y); // requires global string called tstring
  void  Handle_Wrecked_Facility(void);
  void  Open_Ship(void);
  void  Close_Ship(void);
  int   Read_GameData_File(void);





// globals /////////////////////////////////////////////////////////////////

  extern unsigned char far
    *video_buffer;
  extern unsigned char
    key_table[15]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; //NUM_KEYS
  unsigned char
    keystroke,
    data = NULL,
    joy_table[7]={0,0,0,0,0,0,0};
  char far
    *work_back;
  char
    tstring[30],
    graphics_file_name[12],
    data_file_name[12],
    error_file_name[12],   
    boardname[8],        
    *resource_file="H20C",
    *sound_key[21]={
      "phase","explode","thrumain","thrulat","collide","gear","register","theme6","revfade2","test3",
      "fade","graph3","earth","wind","land","alert","accept","blit","alarm","yikes","bding"};
  extern int far
    error_code        = 0;
  int
    newgame           = 0,  // used mostly for opening animation, when not loading game, doing new instead.
    gender            = 0,
    lander_off_screen = 0,
    sound_available   = 0;
  extern int
    work_offset       = 0, 
    x_off             = 0, 
    offset            = 0, 
    xs                = 0, 
    ys                = 0,
    xe                = 0,
    ye                = 0,
    clip_width        = 0,
    clip_height       = 0,
    other_offset      = 0,
    temp_offset       = 0;
  unsigned int
    sprite_overlap    = 0,
    backgroundname[9][9],
    joy_up_half       = 0,
    joy_up_full       = 0,
    joy_down_full     = 10000,
    joy_left_full     = 0,
    joy_right_full    = 10000,
    drawn             = 0,
    joy_1_max_x,
    joy_1_max_y,
    joy_1_min_x,
    joy_1_min_y,
    joy_1_cx,
    joy_1_cy;
  int
    number_of_messages = 0,
    _message[9]       = {0,0,0,0,0,0,0,0,0},
    main_engine       = 0,
    micro_engine      = 0,
    left_engine       = 0,
    right_engine      = 0,
    lander_frames     = 27,
    frame_index       = 50,
    shake_screen      = 0,
    shake_screen_state= 0,
    collision         = 0,
    mode_ready        = 1,
    win               = 0,
    collision_check   = 1,
    tally_shield      = 1,
    tally_fuel        = 1,
    animation_speed   = 0,
    iintro            = 0,
    imenu             = 0,
    ipause            = 0,
    igameplay         = 0,
    iscreen           = 0,
    isound            = 0,
    ikeyboard         = 0,
    ijoystick         = 0,
    isprites          = 0,
    ibuffer           = 0,
    icopyright        = 0,
    igamedata         = 0,
    joystick_calibrated=0,
    baseio,
    irq,
    dma,
    dma16,
    raw_key           = 0,
    controller        = 1,
    show_messages     = 1,
    screen_number     = 0,
    display_message   = 0,
    message           = 0,
    show_message_now  = 5000,
    last_earth_quake  = 0,
    text_y            = 0,
    text_x            = 0,
    done              = 0,
    index             = 0,
    index_x           = 0,
    index_y           = 0,
    global_delay      = 0,
    screen_show_index = 0,
    screen_show       = 0,
    old_screen_show   = 0,
    board_x           = 0,
    board_y           = 0,
    board_min_x       = 0,
    board_min_y       = 0,
    //temp1_hspd        = 8, //disable 03/28/02
    temp2_hspd        = 0;  //this is a dummy variable only used for legacy purposes.
    //temp3_hspd        = 8; //disabled 03/28/02
  long far
    message_counter   = 0;
  float
    x                 = 0,
    y                 = 0,
    fuel              = 0,
    shield            = 0,
    gravity           = 0,
    delta_x           = 0,
    delta_y           = 0;
  pcx_picture
    background_pcx;
  sprite
    lander,   
    textbox,
    explosions,
    pilot;
  sprite_ptr
    curr_sprite;
  MIX_SOUND
    *sound_effect[21];





// functions ////////////////////////////////////////////////////////////////

void Behind_Sprite(sprite_ptr sprite){
  char far *work_back;
  int work_offset=0,offset,y;
  work_back = sprite->background;
  offset = (sprite->y << 8) + (sprite->y << 6) + sprite->x;
  for (y=0; y<sprite_height; y++){
    _fmemcpy((char far *)&work_back[work_offset],(char far *)&double_buffer[offset],sprite_width);
    offset+=320; work_offset+=sprite_width;
  }
}
//////////////////////////////////////////////////////////////////////////////


void Erase_Sprite(sprite_ptr sprite){
  char far *work_back;
  int work_offset=0,offset,y;
  work_back = sprite->background;
  offset = (sprite->y << 8) + (sprite->y << 6) + sprite->x;
  for (y=0; y<sprite_height; y++){
    _fmemcpy((char far *)&double_buffer[offset],(char far *)&work_back[work_offset],sprite_width);
    offset+=320; work_offset+=sprite_width;
  } 
}
//////////////////////////////////////////////////////////////////////////////


void Draw_Sprite(sprite_ptr sprite){
  char far *work_sprite;
  int work_offset=0,offset,x,y;
  unsigned char data;
  work_sprite = sprite->frames[sprite->curr_frame];
  offset = (sprite->y << 8) + (sprite->y << 6) + sprite->x;
  for (y=0; y<sprite_height; y++){
    for (x=0; x<sprite_width; x++){
      data=work_sprite[work_offset+x];
      if (data) double_buffer[offset+x] = data;
    }
    offset+=320;
    work_offset += sprite_width;
  }
}
//////////////////////////////////////////////////////////////////////////////


void Behind_Sprite_Clipped_DB(void){
  work_back   = curr_sprite->background;
  xs          = curr_sprite->x;
  ys          = curr_sprite->y;
  xe          = xs+curr_sprite->width-1;
  ye          = ys+curr_sprite->height-1;	
  if (xs<POLY_CLIP_MIN_X){
    xs=POLY_CLIP_MIN_X;
  } 
  else if (xe>=POLY_CLIP_MAX_X){
    xe=POLY_CLIP_MAX_X-1;
  }

  if (ys<POLY_CLIP_MIN_Y){
    ys=POLY_CLIP_MIN_Y;
  }
  else if (ye>=POLY_CLIP_MAX_Y){
    ye=POLY_CLIP_MAX_Y-1;
  }

  clip_width  = xe-xs+1; 
  clip_height = ye-ys+1;
  x_off       = (xs - curr_sprite->x); 
  temp_offset = work_offset = (ys - curr_sprite->y)*curr_sprite->width;
  other_offset= offset      = (ys << 8) + (ys << 6 ) + curr_sprite->x;	
  for (index=0; index<clip_height; index++){  
    _fmemcpy((char far *)&work_back[temp_offset+x_off],(char far *)&double_buffer[other_offset+x_off],clip_width);  
    other_offset+=320; temp_offset+=curr_sprite->width;
  }
} // end Behind_Sprite_Clipped_DB
//////////////////////////////////////////////////////////////////////////////


void Erase_Sprite_Clipped_DB(void){
  xs          = curr_sprite->x;
  ys          = curr_sprite->y;
  xe          = xs+curr_sprite->width-1;
  ye          = ys+curr_sprite->height-1;	
  clip_width  = xe-xs+1;
  clip_height = ye-ys+1;
  x_off       = (xs - curr_sprite->x); 
  temp_offset = work_offset = (ys - curr_sprite->y)*curr_sprite->width;
  other_offset= offset      = (ys << 8) + (ys << 6 ) + curr_sprite->x;

  for (index=0; index<clip_height; index++){  
    _fmemcpy((char far *)&double_buffer[other_offset+x_off],(char far *)&work_back[temp_offset+x_off],clip_width);
    other_offset+=320; temp_offset+=curr_sprite->width;
  }
}
//////////////////////////////////////////////////////////////////////////////


void Draw_Sprite_Clipped_DB(void){
  int
    duration,
    y = 0,
    x = 0;

  char far *work_sprite=curr_sprite->frames[curr_sprite->curr_frame];
  xs=curr_sprite->x;
  ys=curr_sprite->y;
  xe=xs+curr_sprite->width-1;
  ye=ys+curr_sprite->height-1;

  lander_off_screen=0;
  if (xs<POLY_CLIP_MIN_X){
    xs=POLY_CLIP_MIN_X; 
    lander_off_screen=1;
  }
  else if (xe>=POLY_CLIP_MAX_X){
    xe=POLY_CLIP_MAX_X-1; 
    lander_off_screen=1;
  }
  if (ys<POLY_CLIP_MIN_Y){
    ys=POLY_CLIP_MIN_Y; 
    lander_off_screen=1;
  }
  else if (ye>=POLY_CLIP_MAX_Y){
    ye=POLY_CLIP_MAX_Y-1; 
    lander_off_screen=1;
  }

  clip_width=xe-xs+1; 
  clip_height=ye-ys+1; 
  x_off=(xs-curr_sprite->x);
  temp_offset=work_offset=(ys-curr_sprite->y)*curr_sprite->width;
  other_offset= offset=(ys<<8)+(ys<<6)+curr_sprite->x; 

  for (y=0; y<clip_height; y++){
    for (x=0; x<clip_width; x++){
      data=work_sprite[temp_offset+x+x_off];
      if (data){
        if (sprite_overlap==1){
          double_buffer[other_offset+x+x_off]=data;
        }
        if (data<5){
          if ((double_buffer[other_offset+x+x_off]>222)&&(collision_check==1)){
            collision++;
            if (data==1) delta_x=.5;
            if (data==2) delta_y=.5;
            if (data==3) delta_x=-.75;
            if (data==4) delta_y=-.75;
          }                
        }
        else if (double_buffer[other_offset+x+x_off]<72) double_buffer[other_offset+x+x_off]=data;
      }
    }
    other_offset+=320; 
    temp_offset+=curr_sprite->width;
  }
  if (lander.state==1){
    // check for a landing
    if (((delta_y>0)&&(delta_y<.3)) &&
        (video_buffer[(((lander.y+22)<<8)+((lander.y+22)<<6))+lander.x+16]==32) &&
        (video_buffer[(((lander.y+23)<<8)+((lander.y+23)<<6))+lander.x+16]==167) &&
        (video_buffer[(((lander.y+23)<<8)+((lander.y+23)<<6))+lander.x+1]==167) &&
        (video_buffer[(((lander.y+23)<<8)+((lander.y+23)<<6))+lander.x+33]==167) &&
        (!sound_playing(SOUND_EARTH)||(shake_screen<1980)) &&
        (!main_engine)){
      // this handles the landing
      delta_y=0; delta_x=0; lander.state=0; //landed=0;
      if (collision_check==1) collision_check=2;

      // shut off all engines
      main_engine=0;
      micro_engine=0;
      left_engine=0;
      right_engine=0;
                  
      // make the landing sound AND draw the lander on the pad (otherwise a blank appears.)
      start_sound(sound_effect[SOUND_LAND], SOUND_LAND, 0, sound_available);
      curr_sprite=&lander; lander.curr_frame=1; Draw_Sprite_Clipped_DB();
      screen_show_index=screen_show; 
      Handle_Display();
      Handle_Game_Speed(1);

      // delay a moment on the landing pad and then open the lander
      lander.state=0; // landed
      Open_Ship();
      // just landed, check for special scenes
      if (board_x==9 && board_y==6) Handle_Wrecked_Facility();

      // each landing results in full refueling reward
      // added while trying to fix stats box from drawing during win
      if (!win){
        // end added while trying to fix stats box from drawing during win
        // make sure status box is on screen
        SET_SPRITE_SIZE(85,26)    
        if (lander.y<82){
          textbox.x=230;
          textbox.y=169;
        }
        if (lander.y>81){
          textbox.x=5; 
          textbox.y=5;
        }
        textbox.curr_frame=0;
        Behind_Sprite((sprite_ptr)&textbox);
        Draw_Sprite((sprite_ptr)&textbox);
        for (index=textbox.x+41; index<(textbox.x+80); index++){
          if (index<=textbox.x+41+fuel){
            V_Line(textbox.y+4,textbox.y+4,index,134);
            V_Line(textbox.y+5,textbox.y+8,index,135);
            V_Line(textbox.y+9,textbox.y+9,index,136);
          }
          if (index<=textbox.x+41+shield){
            V_Line(textbox.y+15,textbox.y+15,index,136);
            V_Line(textbox.y+16,textbox.y+19,index,137);
            V_Line(textbox.y+20,textbox.y+20,index,138);
          }
        }
        Show_Double_Buffer(double_buffer);                            
        Refuel_Ship();
        Close_Ship();
      }
    }
  }
  sprite_overlap=0;
  return;
} /* end Draw_Sprite_Clipped_DB */
//////////////////////////////////////////////////////////////////////////////


void Refuel_Ship(void){
  int
    index = 0;

  Delay(20);

  // make a box to put 'fueling' over
  V_Line(92,105,120,169);
  for (index=121; index<204; index++){
    V_Line(92,92,index,169);
    V_Line(93,104,index,168);
    V_Line(105,105,index,167);        
  }
  V_Line(92,105,204,167);
  Blit_String_DB(135,95,159,"FUELING",0,2);  
  Show_Double_Buffer(double_buffer);  

  //idea to pursue- based on difficulty level, alter fuel and shield repair
  while(fuel<38){
    if ((fuel+.25)<38.5) fuel+=1;
    else fuel=38.5;

    for (index=textbox.x+41; index<(textbox.x+80); index++){
      if (index<=textbox.x+41+fuel){
        V_Line(textbox.y+4,textbox.y+4,index,134);
        V_Line(textbox.y+5,textbox.y+8,index,135);
        V_Line(textbox.y+9,textbox.y+9,index,136);
        Show_Double_Buffer(double_buffer);  
      }                                                
    }
    start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);  
  }
  return;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Win(void){
  Restore_Palette((pcx_picture_ptr)&background_pcx,1);

  strcpy(graphics_file_name,"H2WE");
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)){error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);

  strcpy(graphics_file_name,"H2WE2");
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)){error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  _fmemcpy((char far *)back1_buffer,(char far *)(background_pcx.buffer),64000);

  //load guy or girl based on pilot gender
  if(gender==1){
    strcpy(graphics_file_name,"H2024");
  } // load girl
  else{
    strcpy(graphics_file_name,"H2026");
  } // load guy
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  TransparentTransfer(background_pcx.buffer,double_buffer);
  TransparentTransfer(background_pcx.buffer,back1_buffer);
  start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
  Delay(2); Melt_to_Buffer(double_buffer, 0,1); Delay(50);

  if(_message[1]==0){ // This means the player FOUND the hidden city
    strcpy(graphics_file_name,"H2WNT1");
  }
  else{
    strcpy(graphics_file_name,"H2WNT2");
  }
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  TransparentTransfer(background_pcx.buffer,double_buffer);
  TransparentTransfer(background_pcx.buffer,back1_buffer);
  start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
  Delay(2); Melt_to_Buffer(double_buffer, 1,1);

  done=0; index=0;
  while(!done){
    //SHOW PAGE 2 (back1_buffer)
    Fade_Modulate(79,0,2);
    Wait_For_Vsync();
    Show_Double_Buffer(back1_buffer);
    Delay(4);

    //SHOW PAGE 1 (double buffer)
    Fade_Modulate(79,0,2);
    Wait_For_Vsync();
    Show_Double_Buffer(double_buffer);
    Delay(4);

    if (index>100){
      index=0; 
      start_sound(sound_effect[SOUND_REVFADE2], SOUND_REVFADE2, 0, sound_available);
    }
    done=keystroke;                
    if (controller==2) {if (Buttons_Bios(0x10)) done=1;}
  }
  Fade_Lights_Down(10,0);
  Fill_Double_Buffer(0);
  Transfer_Buffer(double_buffer, back1_buffer);
  Transfer_Buffer(double_buffer, back2_buffer);
  Transfer_Buffer(double_buffer, back3_buffer);

  win=0; //force the non-animated ending
  return;
}



int Change_Board(void){
  int
    index,
    index_y=0,
    index_x=0;

  // as of 11/28/97 this function loads a background into 1 buffer,
  // the foreground into another buffer and then combines the two
  // into another buffer a NON-EARTHQUAKE version, and into the
  // buffer holding the backgound an EARTHQUAKE version for an awesome
  // effect of psuedo parallax scrolling

  strcpy(graphics_file_name,"");
  strcpy(graphics_file_name,boardname);
  strcat(graphics_file_name,itoa((backgroundname[board_x][board_y]),tstring,10));

  //03/28/02 01:13 AM Disabled
  // test to prevent registered saved games from running on shareware versions.
  //  if (temp3_hspd!=temp1_hspd-temp2_hspd) {if ((board_x<5)||(board_y<5)) {fuel=.1; shield=.1; collision_check=1;}}

  //03/28/02 01:13 AM Disabled
  //If shareware version load unfinished looking grid on last screen before win
  //  if ((board_x==5 && board_y==7) && (!win)){  //load grid over background
  //    if (temp3_hspd!=temp1_hspd-temp2_hspd){
  //      strcpy(graphics_file_name,"H2015");
  //    }
  //  }

  if (!win){
    if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
    _fmemcpy((char far *)back1_buffer,(char far *)(background_pcx.buffer),64000);
    _fmemcpy((char far *)back2_buffer,(char far *)(background_pcx.buffer),64000);
    _fmemcpy((char far *)back3_buffer,(char far *)(background_pcx.buffer),64000);
  }
  else{
    _fmemcpy((char far *)back1_buffer,(char far *)(double_buffer),64000);
    _fmemcpy((char far *)back2_buffer,(char far *)(double_buffer),64000);
    _fmemcpy((char far *)back3_buffer,(char far *)(double_buffer),64000);
  }

  //03/28/02 01:13 AM Disabled
  // prevent boards beyond the allowable shareware boundary limit from functioning (in the shareware version)
  //  if (temp3_hspd!=temp1_hspd-temp2_hspd){
  //    if ((board_x<board_min_x)||(board_y<board_min_y)){
  //      error_code=11; strcpy(error_file_name,graphics_file_name); Close_Everything();
  //    }
  //  }

  // build the board name string based on H and V values
  if (win){
  //03/28/02 01:14 AM Disabled (both versions now share the win routine
  //    if (temp3_hspd!=temp1_hspd-temp2_hspd){
      Restore_Palette((pcx_picture_ptr)&background_pcx,1);
      strcpy(graphics_file_name,"H2018");
  //    }
  //    else{   // registered win
  //    }
  }
  else{ // load the regular screens
    strcpy(graphics_file_name,"");
    strcpy(graphics_file_name,boardname);
    strcat(graphics_file_name,itoa(board_x,tstring,10));
    strcat(graphics_file_name,itoa(board_y,tstring,10));
  }

  //different difficulty levels- first load the combined fore/back board,
  //stuff in a buffer, then load the collision file based on the difficulty
  //level and overlay on the buffer, then create the three earthquakes.

  //foreground
  //printf("file=%s",graphics_file_name); Delay(50);
  if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);

  //collision
  if (!win){
    strcat(graphics_file_name,itoa((gender+1),tstring,10));
    if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}

    // combine the two
    for (index_y=0; index_y<200; index_y++){
      for (index_x=0; index_x<320; index_x++){
        data=background_pcx.buffer[((index_y<<8) + (index_y<<6)) + index_x]; // foreground
        if (data>0) double_buffer[(((index_y)<<8)+((index_y)<<6))+index_x]=data;
      }
    }
  }

  // combine the two into a NON-EARTHQUAKE version
  for (index_y=0; index_y<200; index_y++){
    for (index_x=0; index_x<320; index_x++){
      data=double_buffer[((index_y<<8) + (index_y<<6)) + index_x]; // foreground
      if (data>0) back1_buffer[((index_y<<8)+(index_y<<6))+index_x]=data; 
    }
  }

  // combine the two into a LEFT-EARTHQUAKE version
  for (index_y=1; index_y<200; index_y++){
    for (index_x=1; index_x<320; index_x++){
      data=double_buffer[((index_y<<8) + (index_y<<6)) + index_x]; // foreground
      if (data>0) back3_buffer[((index_y<<8)+(index_y<<6))+(index_x-1)]=data; 
    }
  }

  // combine the two into an UP-EARTHQUAKE version
  for (index_y=1; index_y<200; index_y++){
    for (index_x=1; index_x<320; index_x++){
      data=double_buffer[((index_y<<8) + (index_y<<6)) + index_x]; // foreground
      if (data>0) back2_buffer[(((index_y-1)<<8)+((index_y-1)<<6))+index_x]=data;
    }
  }

  // if on hidden city board set message display to show radio message
  if (board_x==9 && board_y==6 && _message[1] && fuel>0) {message_counter=show_message_now-100; message=1; start_sound(sound_effect[SOUND_BDING], SOUND_BDING, 0, sound_available);}
  if (board_x==9 && board_y==9 && _message[2] && fuel>0) {message_counter=show_message_now-100; message=2; start_sound(sound_effect[SOUND_BDING], SOUND_BDING, 0, sound_available);}

  //03/28/02 01:14 AM Disabled
  // test to prevent registered saved games from running on shareware versions.
  //  if ((temp3_hspd!=temp1_hspd-temp2_hspd) && (board_x<5||board_y<5)) {message_counter=show_message_now; message=8; start_sound(sound_effect[SOUND_BDING], SOUND_BDING, 0, sound_available);}

  return 1; // return success
} /* end Change_Board */
//////////////////////////////////////////////////////////////////////////////


int Handle_Ending(void){
  unsigned int far  
    *game_clock       = (unsigned int far *)0x0000046CL;
  unsigned int 
    start_clock       = NULL;
  int
    thruster,
    xx,
    yy,
    frame,
    index                = 0,
    index2               = 0,
    d_x,
    d_y;
  FILE  *fp;

  Restore_Palette((pcx_picture_ptr)&background_pcx,1);

  done = 0;    
  if (win){   
  //03/28/02 01:15 AM Disabled
  //    if (temp3_hspd==temp1_hspd-temp2_hspd){
  //    }    
  //    else{   // regular win
      SET_SPRITE_SIZE(32,24)
      index=0; y=(205-(sprite_height+1));

      // set variables in prep for landing animation   
      gravity=0; lander.x_old=lander.x=x=30; lander.y_old=lander.y=y=185;
      curr_sprite=&lander; 

      if (lander.state==-1) lander.curr_frame=10;  // gear up, already in flight
      else lander.curr_frame=1;                    // gear down, inflight or landed

      screen_show_index=screen_show; Draw_Sprite_Clipped_DB();
      if (lander.state==-1) {lander.state*=-1; frame_index=0; mode_ready=0;}

      // begin the animation bringing the lander in flight to the pad
      strcpy(data_file_name,""); strcpy(data_file_name, "H2022");
      if ((fp=fopen(data_file_name,"rb"))==NULL) {error_code=9; strcpy(error_file_name,data_file_name); Close_Everything();}            
      index=0;
      while(!feof(fp)){  
        fscanf(fp,"%i %i %i",&d_x, &d_y, &thruster);
        delta_x=d_x; // this data set in array above
        delta_y=d_y; // this data set in array above
        index++;
        lander.x_earth=lander.x; lander.y_earth=lander.y;  // set these before earth quake
        screen_show_index=screen_show; 
        shake_screen=1990; Handle_Earth_Quake(); // force earth quake
        Update_Variables();
        Handle_Draw();
        if (thruster){ 
          start_sound(sound_effect[SOUND_THRULAT], SOUND_THRULAT, 0, sound_available);
          lander.curr_frame=3; Draw_Sprite_Clipped_DB(); 
        }
        screen_show_index=screen_show; 
        Handle_Display();
        Handle_Game_Speed(1);
        d_x=0; d_y=0; thruster=0; // reset each ready for next load
      }
      fclose(fp);

      // make the landing sound AND draw the lander on the pad (otherwise a blank appears.)
      start_sound(sound_effect[SOUND_LAND], SOUND_LAND, 0, sound_available);
      curr_sprite=&lander; lander.curr_frame=1; Draw_Sprite_Clipped_DB();
      screen_show_index=screen_show; 
      Handle_Display();
      Handle_Game_Speed(1);
      // end make sound and draw

      // delay a moment on the landing pad and then open the lander
      Open_Ship();

      // draw the pilot emerging from lander
      /* draw lander first */			
      screen_show_index=screen_show;
      lander.x_earth=lander.x; lander.y_earth=lander.y;  // set these before earth quake
      curr_sprite=&lander; Draw_Sprite_Clipped_DB();

      pilot.x=lander.x; pilot.y=lander.y-11; pilot.curr_frame=3;
      start_sound(sound_effect[SOUND_EARTH], SOUND_EARTH, 0, sound_available); shake_screen=1980;

      strcpy(data_file_name,""); strcpy(data_file_name, "H2019");
      if ((fp=fopen(data_file_name,"rb"))==NULL) {error_code=9; strcpy(error_file_name,data_file_name); Close_Everything();}

      index=0; screen_show_index=screen_show;
      while(!feof(fp)){  
        start_clock=*game_clock;
        fscanf(fp,"%i %i %i %i",&frame, &xx, &yy, &pilot.state);
        pilot.curr_frame=frame; pilot.x=(lander.x+xx); pilot.y=(lander.y-11)+yy;
        if (index==5 || index==30) start_sound(sound_effect[SOUND_PLREGISTER], SOUND_PLREGISTER, 0, sound_available);
        index++;
        screen_show_index=screen_show; 
        lander.x_earth=lander.x; lander.y_earth=lander.y;  // set these in case earth quake moved them
        pilot.x_earth=pilot.x; pilot.y_earth=pilot.y;  // set these in case earth quake moved them
        shake_screen=1990; Handle_Earth_Quake();
        SET_SPRITE_SIZE(32,24)
        curr_sprite=&lander; Draw_Sprite_Clipped_DB();
        lander.x=lander.x_earth; lander.y=lander.y_earth;  // set these in case earth quake moved them

        sprite_overlap=1;
        curr_sprite=&pilot; pilot.curr_frame=frame; Draw_Sprite_Clipped_DB();

        pilot.x=pilot.x_earth; pilot.y=pilot.y_earth;  // set these in case earth quake moved them
        Handle_Display();
        Handle_Game_Speed(1);
        while(abs(*game_clock-start_clock)<1){}  // to slow down ultra fast graphics
      }
      fclose(fp);
      Delay(10);
      start_sound(sound_effect[SOUND_PLREGISTER], SOUND_PLREGISTER, 0, sound_available);

      // close the ship now
      //            Close_Ship();
      start_sound(sound_effect[SOUND_GEAR], SOUND_GEAR, 0, sound_available);
      index=24;
      while(index>16){
        lander.curr_frame=index;
        if (index==17) lander.curr_frame=1;
        lander.x_earth=lander.x; lander.y_earth=lander.y;  // set these in case earth quake moved them
        screen_show_index=screen_show; Handle_Earth_Quake();
        curr_sprite=&lander; Draw_Sprite_Clipped_DB();

        //draw the pilot too
        sprite_overlap=1;
        curr_sprite=&pilot; pilot.curr_frame=frame; Draw_Sprite_Clipped_DB();
        pilot.x=pilot.x_earth; pilot.y=pilot.y_earth;  // set these in case earth quake moved them

        lander.x=lander.x_earth; lander.y=lander.y_earth;  // set these in case earth quake moved them
        screen_show_index=screen_show; Handle_Display();
        Handle_Game_Speed(1);
        index--;
      }

      if (!ikeyboard){
        //printf("\nerror=%i",error_code); Delay(100);
        //error_code=0;
        Handle_Keyboard_Driver();  // allocate driver (if present)
      }

      Delay(5);
      win=0;
      index=0;
      index2=0;
      while ((!done)&&(index<2500)){ 
        index++;
        Fade_Modulate(175,0,2); //new palette 2/99
        //Fade_Modulate(30,0,2); this was for the old palette
        Delay(1);

        // gotoxy(1,1); printf("ikeyboard=%i keystroke=%i",ikeyboard,keystroke); Delay(5);
        done=keystroke; // if (keystroke>0) {printf("blee"); Delay(20); Close_Everything();}
        if (controller==2){
          if (Buttons_Bios(0x10)) {printf("blah"); Delay(20); done=1;}
        }

        index2++;
        if (index2==90){
          index2=-1; screen_show_index=screen_show;
          frame=pilot.curr_frame;
          while(index2<22){  
            // periodically repeat frames 5 to 9 of the pilot
            start_clock=*game_clock;
            //Fade_Modulate(30,0,2); old palette
            Fade_Modulate(175,0,2); // new palette
            index2++;
            if (index2==0 || index2==30) start_sound(sound_effect[SOUND_PLREGISTER], SOUND_PLREGISTER, 0, sound_available);
            if (index2==1 || index2==10 || index2==11 || index2==20) frame=0;
            if (index2==2 || index2==9 || index2==12 || index2==19) frame=4;
            if (index2==3 || index2==8 || index2==13 || index2==18) frame=5;
            if (index2==4 || index2==7 || index2==14 || index2==17) frame=6;
            if (index2==5 || index2==6 || index2==15 || index2==16) frame=7;
            if (index2==21) frame=0;
            pilot.curr_frame=frame;

            screen_show_index=screen_show;
            Transfer_Buffer(back1_buffer, double_buffer); // erase old pilot
            SET_SPRITE_SIZE(32,24)

            //Draw_Sprite_DB((sprite_ptr)&pilot,1);
            sprite_overlap=1;
            curr_sprite=&pilot; pilot.curr_frame=frame; Draw_Sprite_Clipped_DB();

            curr_sprite=&lander; Draw_Sprite_Clipped_DB();
            Handle_Display();
            Handle_Game_Speed(1);
            while(abs(*game_clock-start_clock)<1){}  // to slow down ultra fast graphics

            done=keystroke; // if (keystroke>0) {printf("blee"); Delay(20); Close_Everything();}
            if (controller==2) {if (Buttons_Bios(0x10)) done=1;}
          }
          index2=0;
        }
      }
  //03/28/02 01:15 AM Disabled
  //    }
  }
  // end of ending section for the win animation	

  //03/28/02 01:16 AM Disabled
  //show final screen before returning to DOS
  //if (temp3_hspd==temp1_hspd-temp2_hspd){
  //  Fade_Lights_Down(10,0);
  //}
  //else{
    // regular ending section
    strcpy(graphics_file_name,"H2023"); // GRID
    if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
    _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);

    // load guy or girl based on gender of pilot
    if (gender==1) {strcpy(graphics_file_name,"H2024");} // load girl
    else {strcpy(graphics_file_name,"H2026");} // load guy
    if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
    TransparentTransfer(background_pcx.buffer, double_buffer);

    strcpy(graphics_file_name,"H2009"); // plea2
    if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
    TransparentTransfer(background_pcx.buffer, double_buffer);

    start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
    Melt_to_Buffer(double_buffer,0,1);

    done=0; index=0;
    while(!done){
      Fade_Modulate(175,0,2); //old palette was 30
      Delay(1);

      if (index>100){
        index=0; 
        start_sound(sound_effect[SOUND_REVFADE2], SOUND_REVFADE2, 0, sound_available);
      }
      done=keystroke;                
      if (controller==2) {if (Buttons_Bios(0x10)) done=1;}
    }
    Fade_Lights_Down(10,0);
  //  } disabled 03/28/02
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Intro(void){
  int   
    fade_color     = 0,
    fade_in        = 0,
    fade_out       = 0,
    sound_1        = 0,
    sound_2        = 0,
    load_buffer    = 0;
    char far         
    *temp_buffer   = NULL;

  iintro=1;
  done=0;    
  strcpy(data_file_name,"H2017");
  if (!Retrieve_Graphics_Header(data_file_name,(pcx_picture_ptr)&background_pcx)){error_code=9; strcpy(error_file_name,data_file_name); Close_Everything();}
  if (screen_number==1) {Fill_Double_Buffer(0); Wait_For_Vsync(); Show_Double_Buffer(double_buffer);}	
  Delay(10);

  while(!done && !error_code){
    screen_number++; if (screen_number>9) screen_number=1;
    if (screen_number==1){load_buffer=1; fade_color=172; fade_in=2; fade_out=1; sound_1=0; sound_2=0;}
    if (screen_number==2){load_buffer=1; fade_color=255; fade_in=2; fade_out=1; sound_1=0; sound_2=0;}
    if (screen_number==3){load_buffer=1; fade_color=149; fade_in=4; fade_out=4; sound_1=0; sound_2=SOUND_REVFADE2;}
    if (screen_number==4){load_buffer=1; fade_color=78; fade_in=2; fade_out=0; sound_1=0; sound_2=0;}
    if (screen_number==5){load_buffer=0; fade_color=78; fade_in=3; fade_out=0; sound_1=SOUND_THEME6; sound_2=SOUND_REVFADE2;}
    if (screen_number==6){load_buffer=1; fade_color=255; fade_in=4; fade_out=0; sound_1=0; sound_2=0;}
    if (screen_number==7){load_buffer=0; fade_color=255; fade_in=3; fade_out=2; sound_1=SOUND_WIND; sound_2=0;}
    if (screen_number==8){load_buffer=0; fade_color=135;  fade_in=3; fade_out=1; sound_1=SOUND_REVFADE2; sound_2=0;}
    if (screen_number==9){load_buffer=1; fade_color=199;  fade_in=2; fade_out=1; sound_1=SOUND_THEME6; sound_2=0;}
    if (controller==2) {if (Buttons_Bios(0x10)) imenu=-1;}
    if (imenu==-1) {done=1; break;}
    Delay(10);
    strcpy(graphics_file_name,"H200"); strcat(graphics_file_name,itoa(screen_number-1,tstring,10)); 
    if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
    Restore_Palette((pcx_picture_ptr)&background_pcx,1);
    if (load_buffer){    // load opaque or transparent?
      _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
      temp_buffer=double_buffer;
    }
    else{
      _fmemcpy((char far *)back1_buffer,(char far *)(background_pcx.buffer),64000);
      temp_buffer=back1_buffer;
    }
    Restore_Palette((pcx_picture_ptr)&background_pcx,0);
    if (controller==2) {if (Buttons_Bios(0x10)) imenu=-1;}
    if (imenu==-1) {done=1; break;}  // if user requesting mainmenu handle it
    if (fade_in==1) {Wait_For_Vsync(); Show_Double_Buffer(temp_buffer);}
    if (fade_in==2){
      start_sound(sound_effect[SOUND_PHASE], SOUND_PHASE, 0, sound_available);
      Delay(2); Fade_White(temp_buffer, 0);
    }
    if (fade_in==3){
      start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
      Delay(2); Sheer(temp_buffer,1,2);
    }                      
    if (fade_in==4){
      start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
      Delay(2); Melt_to_Buffer(temp_buffer, 0,1);
    }
    if (controller==2) {if (Buttons_Bios(0x10)) imenu=-1;}
    if (imenu==-1) {done=1; break;}  // if user requesting mainmenu handle it
    global_delay=15;
    if (sound_1){
      start_sound(sound_effect[sound_1], sound_1, 0, sound_available);
      if (!sound_available) {global_delay=100; sound_1=0;}
    }
    if (screen_number==1) {global_delay=80;}
    while(global_delay>0){
      if (sound_1) global_delay=sound_playing(sound_1);
      else global_delay--;
      if (controller==2) {if (Buttons_Bios(0x10)) imenu=-1;}
      if (imenu==-1) {done=1; break;}  // if user requesting mainmenu handle it
      if (screen_number==1){
        Fade_Modulate(fade_color,2,1);
      }
      else if (screen_number!=3){
        Fade_Modulate(fade_color,2,1);
      }
      Delay(1);                
    }
    if (controller==2) {if (Buttons_Bios(0x10)) imenu=-1;}
    if (imenu==-1) {done=1; break;}  // if user requesting mainmenu handle it
    if (!done){
      global_delay=15;
      if (sound_2){
        start_sound(sound_effect[sound_2], sound_2, 0, sound_available);
        if (!sound_available) {global_delay=100; sound_2=0;}
        if (screen_number==3) {Delay(20); start_sound(sound_effect[SOUND_YIKES], SOUND_YIKES, 0, sound_available); Delay(50);}
      }
      while(global_delay>0){
        if (sound_2){
          global_delay=sound_playing(sound_2);
          if (screen_number==3){
            Fade_Modulate(fade_color,2,1);
            global_delay=sound_playing(SOUND_YIKES);
          }
        }
        else{
          global_delay--;
          Fade_Modulate(fade_color,0,1);
        }
        if (controller==2) {if (Buttons_Bios(0x10)) imenu=-1;}
        if (imenu==-1) {done=1; break;}  // if user requesting mainmenu handle it
        Delay(1);
      }
    }
    if (!done){
      if (screen_number==3) Fill_Double_Buffer(0);
      if (fade_out==1) {Fade_Lights_Down(25,0);}
      if (fade_out==2){
        start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
        Delay(2); Sheer(double_buffer,0,2); Delay(2);
        while(sound_playing(SOUND_FADE)){}
      }
      if (fade_out==4){
        start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
        Delay(2); Melt_to_Buffer(double_buffer, 0,1);
      }
    }
  }	
  iintro=0;
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Start(void){
  unsigned int far  
    *game_clock       = (unsigned int far *)0x0000046CL;
  int   
    temp_lander_y     = lander.y,
    loop_counter      = 0,
    direction         = 0,
    duration          = 50;
  unsigned int 
    start_clock       = NULL;

  global_delay=1;

  // wait for current sounds to end or put them out before starting
  if (sound_available==1){
    for (index=0; index<21; index++){
      if (sound_playing(index)){
        start_clock = *game_clock;   
        while(sound_playing(index)){
          if ((abs(*game_clock-start_clock))>20) stop_sound(index);
        }
      }
    }
  }

  Change_Board();
  Transfer_Buffer(back1_buffer, double_buffer);
  SET_SPRITE_SIZE(32,24)

  //if (strcmp(data_file_name,"H20H")==0)  // if a new game do opening animation

  // HANDLE NEW GAME (PLAY THE OPENING ANIMATION)
  if (newgame){            
    // this section raises lander onto pad, opens and closes it
    lander.y=lander.y+25;
    curr_sprite = &lander; 
    lander.curr_frame=1;
    Transfer_Buffer(back1_buffer, double_buffer);
    Draw_Sprite_Clipped_DB();
    start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
    Melt_to_Buffer(double_buffer,0,1);
    start_sound(sound_effect[SOUND_EARTH], SOUND_EARTH, 0, sound_available); shake_screen=1980;
    Delay(10);

    if (ikeyboard) Handle_Keyboard_Driver();  // deallocate driver (if present)

    while (loop_counter<duration){
      start_sound(sound_effect[SOUND_ALARM], SOUND_ALARM, 0, sound_available);
      loop_counter++;
      if (lander.y>temp_lander_y) lander.y--;
      curr_sprite=&lander;
      lander.curr_frame+=direction;
      if (loop_counter==(duration-19)){
        lander.curr_frame=19; 
        direction=1; 
        start_sound(sound_effect[SOUND_GEAR], SOUND_GEAR, 0, sound_available);
      }
      if (loop_counter==(duration-14)) {direction=0;}
      if (loop_counter==(duration-11)) {direction=-1;}
      if (loop_counter==(duration-4))  {direction=0; lander.curr_frame=1;}

      lander.x_earth=lander.x; lander.y_earth=lander.y;
      screen_show_index=screen_show;
      Handle_Earth_Quake();

      curr_sprite=&lander;
      Draw_Sprite_Clipped_DB();
      Handle_Display();
      lander.x=lander.x_earth; lander.y=lander.y_earth;
      Handle_Game_Speed(1);
      if (keystroke || (controller==2 && Buttons_Bios(0x10))) loop_counter=duration;
    }

    if (!ikeyboard) Handle_Keyboard_Driver();  // allocate driver (if present)      
  }

  // START A LOADED GAME (SKIP OPENING ANIMATION OF NEW GAME)
  else{  // a loaded game, just display ship and start
    curr_sprite = &lander;
    if (lander.state==-1) lander.curr_frame=10;  // gear up, already in flight
    else lander.curr_frame=1;                    // gear down, inflight or landed
    Transfer_Buffer(back1_buffer, double_buffer);
    Draw_Sprite_Clipped_DB();
    start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
    Melt_to_Buffer(double_buffer,0,1);
    Delay(10);
  }

  lander.y=temp_lander_y;
  Transfer_Buffer(back1_buffer, double_buffer);
  Draw_Sprite_Clipped_DB();
  delta_x=0; delta_y=0;
  //    textbox.state=0; Status_Box();
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


void Handle_Display(void){
  // for improved speed use the following conditional
  if (screen_show_index>=screen_show){
    screen_show_index=0;

    // do the status box when displaying the buffer
    SET_SPRITE_SIZE(85,26)    
    if (lander.y<82){textbox.x=230; textbox.y=169;}
    if (lander.y>81){textbox.x=5; textbox.y=5;}
    textbox.curr_frame=0;
    Behind_Sprite((sprite_ptr)&textbox);
    Draw_Sprite((sprite_ptr)&textbox);
    // now fill in the fuel and shield
    for (index=textbox.x+41; index<(textbox.x+80); index++){
      if (index<=textbox.x+41+fuel){
        V_Line(textbox.y+4,textbox.y+4,index,134);
        V_Line(textbox.y+5,textbox.y+8,index,135);
        V_Line(textbox.y+9,textbox.y+9,index,136);
      }
      if (index<=textbox.x+41+shield){
        V_Line(textbox.y+15,textbox.y+15,index,136);
        V_Line(textbox.y+16,textbox.y+19,index,137);
        V_Line(textbox.y+20,textbox.y+20,index,138);
      }
    }

    Wait_For_Vsync();
    _asm{
      push ds;
      mov cx,buffer_size;
      les di,video_buffer;
      lds si,double_buffer;
      cld;
      rep movsw;
      pop ds;
    }
  }
  drawn=0;
  return;
}
/////////////////////////////////////////////////////////////////////////////


void  Handle_Earth_Quake(void){
  screen_show_index++;
  if (screen_show_index>=screen_show){
    if (!shake_screen_state){
      shake_screen++;
      if (shake_screen>2000) shake_screen=rand()%1700;
    }
    if (sound_playing(SOUND_EARTH)) shake_screen=1990;
    if (shake_screen<1980){
      if (!sound_available) shake_screen++;
      Transfer_Buffer(back1_buffer, double_buffer);
      //if (!win)
      //{textbox.state=0; Status_Box();}
    }   
    else{
      shake_screen_state++; 
      if (shake_screen_state>9){
        if (shake_screen_state>12) shake_screen_state=0;
        Transfer_Buffer(back3_buffer, double_buffer);

        // if on the ground, move the pilot/ship with the earth quake
        if (lander.state==0) lander.x=lander.x_earth-1;
        if (pilot.state==0) pilot.x=pilot.x_earth-1;

        //if (!win) {textbox.state=0; Status_Box();}
      }
      else if (shake_screen_state>6){
        Transfer_Buffer(back1_buffer, double_buffer);
        //if (!win) {textbox.state=0; Status_Box();}
      }
      else if (shake_screen_state>3){
        Transfer_Buffer(back2_buffer, double_buffer);

        // if on the ground, move the pilot/ship with the earth quake
        if (lander.state==0) lander.y=lander.y_earth-1;
        if (pilot.state==0) pilot.y=pilot.y_earth-1;

        //if (!win) {textbox.state=0; Status_Box();}
      }
      else if (shake_screen_state>0){
        Transfer_Buffer(back1_buffer, double_buffer);
        //if (!win) {textbox.state=0; Status_Box();}
      }
    }
  }
}
/////////////////////////////////////////////////////////////////////////////


void _interrupt _far New_Key_Int(){   //int raw_key=0;
  _asm{
    sti;
    in al, 0x60;
    xor ah,ah;
    mov raw_key, ax;
    in al, 0x61;
    or al, 82h;
    out 0x61,al;
    and al,7fh
    out 0x61,al;
    mov al,20h
    out 0x20,al;
  }
  keystroke=0;
  if ((raw_key>0)&&(raw_key<129)) keystroke=raw_key;
  switch(raw_key){
    case 1:           key_table[9]=1; break; //INDEX_ESC
    case 74:          key_table[8]=1; break; //INDEX_MINUS
    case 78:          key_table[14]=1; break; //INDEX_PLUS
    case 13:          key_table[14]=1; break; //INDEX_PLUS
    case 12:          key_table[8]=1; break; //INDEX_MINUS
    //        case 15:          key_table[16]=1; break; //INDEX_TAB
    case 21:          key_table[10]=1; break; //INDEX_Y
    case 22:          key_table[13]=1; break; //INDEX_U
    case 25:          key_table[12]=1; break; //INDEX_P
    case 28:          key_table[4]=1; break; //INDEX_ENTER
    case 29:          key_table[7]=1; break; //INDEX_CTRL
    case 36:          key_table[5]=1; break; //INDEX_J
    case 49:          key_table[11]=1; break; //INDEX_N
    //        case 56:          key_table[15]=1; break; //INDEX_ALT
    case 57:          key_table[6]=1; break; //INDEX_SPACE
    case 72:          key_table[0]=frame_index=50; break;
    case 75:          key_table[3]=1; break; //INDEX_LEFT
    case 77:          key_table[2]=1; break; //INDEX_RIGHT
    case 80:          key_table[1]=frame_index=50; break; //INDEX_DOWN
    case 129:         key_table[9]=0; break; //INDEX_ESC
    case 202:         key_table[8]=0; break; //INDEX_MINUS
    case 206:         key_table[14]=0; break; //INDEX_PLUS
    case 140:         key_table[8]=0; break; //INDEX_MINUS
    case 141:         key_table[14]=0; break; //INDEX_PLUS
    //        case 143:         key_table[16]=0; break; //INDEX_TAB
    case 149:         key_table[10]=0; break; //INDEX_Y
    case 150:         key_table[13]=0; break; //INDEX_U
    case 153:         key_table[12]=0; break; //INDEX_P
    case 156:         key_table[4]=0; break; //INDEX_ENTER
    case 157:         key_table[7]=0; break; //INDEX_CTRL
    case 164:         key_table[5]=0; break; //INDEX_J
    case 177:         key_table[11]=0; break; //INDEX_N
    //        case 184:         key_table[15]=0; break; //INDEX_ALT
    case 185:         key_table[6]=0; break; //INDEX_SPACE
    case 200:         key_table[0]=0; main_engine=0; break;
    case 203:         key_table[3]=0; left_engine=0; break; //INDEX_LEFT
    case 205:         key_table[2]=0; right_engine=0; break; //INDEX_RIGHT
    case 208:         key_table[1]=0; micro_engine=0; break; //INDEX_DOWN
    default: break;
  }	
  if ((key_table[9] && imenu<1)||(iintro && keystroke)){ //INDEX_ESC
    imenu=-1;
  }
  if (key_table[12]){ //INDEX_P
    ipause=1;
  }	
  if (key_table[7] && key_table[11]) Close_Everything(); //INDEX_CTRL, INDEX_N
}
/////////////////////////////////////////////////////////////////////////////


void  Clear_Joystick(void){
  int 
    index=0;
  while(Buttons_Bios(0x10)||Buttons_Bios(0x20)){}
  for (index=0; index<7; index++) {joy_table[index]=0;}
}
/////////////////////////////////////////////////////////////////////////////


void  Joystick_Driver(void){
    int raw_key;
    union REGS inregs,outregs;

    inregs.h.ah = 0x84; // joystick function 84h
    inregs.x.dx = 0x01; // read joysticks subfunction 1h
    int86(0x15, &inregs, &outregs);
    raw_key=outregs.x.ax;
    if (raw_key>joy_left_full && raw_key<joy_right_full)
    {   joy_table[3]=0; //LEFT_FULL
        joy_table[4]=0; //RIGHT_FULL
    }
    if (raw_key<joy_left_full)
    {   joy_table[3]=1; //LEFT_FULL
        joy_table[4]=0; //RIGHT_FULL
    }
    else if (raw_key>joy_right_full)
         {  joy_table[4]=1; //RIGHT_FULL
            joy_table[3]=0; //LEFT_FULL
         }
    raw_key=outregs.x.bx;
    if (raw_key>joy_up_half && raw_key<joy_down_full)
    {   joy_table[0]=0; //UP_FULL
        joy_table[2]=0; //DOWN_FULL
        joy_table[1]=0; //UP_HALF
    }
    if (raw_key<joy_up_full)
    {   joy_table[0]=1; //UP_FULL
        joy_table[2]=0; //DOWN_FULL
        joy_table[1]=0; //UP_HALF
    }
    else if (raw_key<joy_up_half)
         {  joy_table[1]=1; //UP_HALF
            joy_table[0]=0; //UP_FULL
            joy_table[2]=0; //DOWN_FULL
         }
    if (raw_key>joy_down_full)
    {   joy_table[2]=1; //DOWN_FULL
        joy_table[0]=0; //UP_FULL
        joy_table[1]=0; //UP_HALF
    }
    raw_key=0;
    outp(0x201,0);
    raw_key=(~inp(0x201) & 0x10);
    if (raw_key) joy_table[5]=1;
    else joy_table[5]=0;         
    raw_key=0;
    outp(0x201,0);
    raw_key=(~inp(0x201) & 0x20);
    if (raw_key) joy_table[6]=1;
    else joy_table[6]=0;
    if (joy_table[6]) imenu=-1;
}
/////////////////////////////////////////////////////////////////////////////


void Status_Box(void){
//    index_x = 0;
//    index_y = 0;

//    global_delay = 2; 
    SET_SPRITE_SIZE(85,26)    

//    if (textbox.state<0)    // used to be -1 not <0 but added for wierd problems happening
//    {       curr_sprite=&textbox;
//            Erase_Sprite_Clipped_DB();
//            if (textbox.state<-1) Show_Double_Buffer(double_buffer);        
//    }
    
//    if (textbox.state==0 && lander_off_screen==0)
//    {
    // set x,y based on location of lander
        textbox.x=230; textbox.y=169; textbox.state=2; // this says box is at the bottom/right
        if (lander.y>81)
        {   textbox.x=5;
            textbox.y=5;
            textbox.state=1;    // this says box is at the top/left
        }

    // put the box on the screen (in the buffer)
        textbox.curr_frame=0;
//        curr_sprite=&textbox;

    //Behind_Sprite(sprite_ptr(&textbox));
    //Draw_Sprite(sprite_ptr(&textbox));
//    Behind_Sprite((sprite_ptr)&textbox);
//    Draw_Sprite((sprite_ptr)&textbox);

    // now fill in the fuel and shield
//        for (index=textbox.x+41; index<(textbox.x+80); index++)
//        {   if (index<=textbox.x+41+fuel) 
//            {   V_Line(textbox.y+4,textbox.y+4,index,134);
//                V_Line(textbox.y+5,textbox.y+8,index,135);
//                V_Line(textbox.y+9,textbox.y+9,index,136);
//            }
//            if (index<=textbox.x+41+shield) 
//            {   V_Line(textbox.y+15,textbox.y+15,index,136);
//                V_Line(textbox.y+16,textbox.y+19,index,137);
//                V_Line(textbox.y+20,textbox.y+20,index,138);
//            }
//        }
        return;
//    }

    // now handle the load/save/quit boxes
//    return;
}
/////////////////////////////////////////////////////////////////////////////


void Calibrate_Joystick(void){
  Load_Radio_Box(1);
  Clear_Joystick();
  key_table[5]=0; //INDEX_J
  text_y=45;
  if (Joystick_Available(1)){
    if (Joystick_Calibrate_Method1()==1){
      joy_up_half    = (joy_1_cy-((joy_1_cy-joy_1_min_y)/2));
      joy_up_full    = (joy_1_min_y+5);
      joy_down_full  = (joy_1_max_y-5);
      joy_left_full  = (joy_1_min_x+5);
      joy_right_full = (joy_1_max_x-5);
      joystick_calibrated = 1;
    }
  }
  else{
    controller=1;
    start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
  }			
  Load_Radio_Box(0);
  done=0;    
  return;
}
/////////////////////////////////////////////////////////////////////////////

 
int Check_Controller_Input(void){
  static int  
    counter     = 0,
    sound_delay = 0;

  if (controller==2){
    counter++;
    if (counter>screen_show+1){
      counter=0;
      Joystick_Driver();
    }
  }	

  done = 0;

  if (key_table[7] && key_table[0]){ //INDEX_CTRL
    if (screen_show<10){
      start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
      screen_show++;
    }
    else start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
    key_table[0]=0;
  }	

  if (key_table[7] && key_table[1]){ //INDEX_DOWN, INDEX_CTRL
    if (screen_show>0){
      start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
      screen_show--;
    }
    else start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
    key_table[1]=0; //INDEX_DOWN
  }	

  if (key_table[13]){ //INDEX_U
    key_table[13]=0; //INDEX_U
    text_y=45;
    Load_Radio_Box(1);
    text_y=47;
    Blit_String(37,text_y,122,"CODE:",1,1); 

    // disable the joystick and keyboard routines
    if (ijoystick) Handle_Joystick_Driver();  // deallocate driver (if present)
    if (ikeyboard) Handle_Keyboard_Driver();  // deallocate driver (if present)			

    getinputstring(80,47);

    // re-enable the joystick and keyboard routines
    if (!ikeyboard) Handle_Keyboard_Driver();
    if (!ijoystick) Handle_Joystick_Driver();

    text_y+=9;
    done=0;
    if (strcmp(tstring,"SOGGLE")==0){
      tally_shield*=-1;
      Blit_String(37,text_y,122,"SHIELD TOGGLE",1,1); text_y+=9;
      strcpy(tstring,"CURRENT SETTING = "); 
      if (tally_shield==-1) strcat(tstring,"OFF");
      else strcat(tstring,"ON");
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      done=500; keystroke=0;
      while (!keystroke && done) {done--; Delay(1);}
    }

    if (strcmp(tstring,"SILLERUP")==0){
      shield=38.5;
      Blit_String(37,text_y,122,"SHIELD RESTORED",1,1); text_y+=9;
      done=500; keystroke=0;
      while (!keystroke && done) {done--; Delay(1);}
    }

    //03/28/02 01:23 AM Disabled
    //if (temp3_hspd==temp1_hspd-temp2_hspd)
    //{
    if (strcmp(tstring,"FILLERUP")==0){
      fuel=38.5;
      Blit_String(37,text_y,122,"FUEL TANK RESTORED",1,1); text_y+=9;
      done=500; keystroke=0;
      while (!keystroke && done) {done--; Delay(1);}
    }

    if (strcmp(tstring,"FOGGLE")==0){
      tally_fuel*=-1;
      Blit_String(37,text_y,122,"FUEL BURN TOGGLE",1,1); text_y+=9;
      strcpy(tstring,"CURRENT SETTING = "); 
      if (tally_fuel==-1) strcat(tstring,"OFF");
      else strcat(tstring,"ON");
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      done=500; keystroke=0;
      while (!keystroke && done) {done--; Delay(1);}
    }

    if (strcmp(tstring,"QUAKE")==0){
      start_sound(sound_effect[SOUND_EARTH], SOUND_EARTH, 0, sound_available);
    }

    //03/28/02 01:24 AM Disabled
    //}

    if (strcmp(tstring,"GHOST")==0){
      if (collision_check!=-1) collision_check=-1;
      else{
        if (lander.state==0) collision_check=2;
        else collision_check=1;
      }
      Blit_String(37,text_y,122,"COLLISION TOGGLE",1,1); text_y+=9;
      strcpy(tstring,"CURRENT SETTING = "); 
      if (collision_check==-1) strcat(tstring,"OFF");
      else strcat(tstring,"ON");
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      done=500; keystroke=0;
      while (!keystroke && done) {done--; Delay(1);}
    }

    if (strcmp(tstring,"DUMP")==0)       {fuel=3;}
    if (strcmp(tstring,"QUIT")==0)       {error_code=-2;} //EXIT_TO_DOS
    if (strcmp(tstring,"FASTER")==0)     {screen_show++; if (screen_show>10) screen_show=10;}
    if (strcmp(tstring,"SLOWER")==0)     {screen_show--; if (screen_show<0) screen_show=0;}
    if (strcmp(tstring,"TALK")==0)       {message_counter=show_message_now-1;}

    if (strcmp(tstring,"LOWDOWN")==0){
      strcpy(tstring,"ANIMATION_SPEED = "); strcat(tstring,itoa(animation_speed,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      strcpy(tstring,"SCREEN_SHOW = "); strcat(tstring,itoa(screen_show,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      strcpy(tstring,"MESSAGE_COUNTER = "); strcat(tstring,itoa(message_counter,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      strcpy(tstring,"LANDER.STATE = "); strcat(tstring,itoa(lander.state,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      strcpy(tstring,"CONTROLLER = "); strcat(tstring,itoa(controller,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      strcpy(tstring,"BLASTER BASEIO = "); strcat(tstring,itoa(baseio,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      strcpy(tstring,"BLASTER IRQ = "); strcat(tstring,itoa(irq,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      strcpy(tstring,"BLASTER DMA = "); strcat(tstring,itoa(dma,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      strcpy(tstring,"BLASTER DMA16 = "); strcat(tstring,itoa(dma16,tstring,10));
      Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
      done=500; keystroke=0;
      if (controller==2 && Buttons_Bios(0x10)) keystroke=13;
      while (!keystroke && done) {done--; Delay(1);}
    }

    //  if (strcmp(tstring,"GFB")==0){
    //    strcpy(tstring,"TEMP1 = "); strcat(tstring,itoa(temp1_hspd,tstring,10));
    //    Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
    //    strcpy(tstring,"TEMP2 = "); strcat(tstring,itoa(temp2_hspd,tstring,10));
    //    Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
    //    strcpy(tstring,"TEMP3 = "); strcat(tstring,itoa(temp3_hspd,tstring,10));
    //    Blit_String(37,text_y,122,tstring,1,1); text_y+=9;
    //    done=500; keystroke=0;
    //    if (controller==2 && Buttons_Bios(0x10)) keystroke=13;
    //    while (!keystroke && done) {done--; Delay(1);}
    //  }

    Load_Radio_Box(0);
    done=0;
  }

  if (key_table[5]){ //calbrate joystick (INDEX_J)
    if (controller!=2) start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
    else{
      start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
      //textbox.state=-1; Status_Box();
      Calibrate_Joystick();
      Change_Board();   
      Transfer_Buffer(back1_buffer, double_buffer);
      SET_SPRITE_SIZE(32,24)
      curr_sprite=&lander; 
      Draw_Sprite_Clipped_DB();			
      Sheer(double_buffer,0,2);
      //textbox.state=0; Status_Box();
    }
  }	

  if (fuel>0){
    if ((controller==1 && key_table[0])||(controller==2 && joy_table[0])){ //UP_FULL
      if (lander.state==0){
        if (collision_check==2) collision_check=1;
        lander.state=1;
      }
      main_engine=1;
    }
    if (lander.state!=0){
      if (controller==1){
        if (key_table[2]) right_engine=1; //INDEX_RIGHT
        if (key_table[3]) left_engine=1;  //INDEX_LEFT
        if (key_table[1]) micro_engine=1; //INDEX_DOWN
        if (key_table[4] && mode_ready){  //INDEX_ENTER
          lander.state*=-1; frame_index=0; mode_ready=0;
        }
      }
      if (controller==2){
        if (joy_table[1]) joy_table[2]=1; //UP_HALF, DOWN_FULL
        if (joy_table[4]) right_engine=1; //RIGHT_FULL
        if (joy_table[3]) left_engine=1;  //LEFT_FULL
        if (joy_table[2]) micro_engine=1; //DOWN_FULL
        if (joy_table[5] && mode_ready){lander.state*=-1; frame_index=0; mode_ready=0;}
      }
    }
    else{
      if (!sound_playing(SOUND_WIND)){
        sound_delay++;
        if (sound_delay==1000){
          sound_delay=0;
          start_sound(sound_effect[SOUND_WIND], SOUND_WIND, 0, sound_available);
        }
      }
    }
  }
  return done;
}
/////////////////////////////////////////////////////////////////////////////


void Update_Variables(void){
  // factor in friction
  if (delta_x<0) delta_x+=.001;
  if (delta_x>0) delta_x-=.001;
  if (delta_y<0) delta_y+=.001;
  if (delta_y>0) delta_y-=.001;

  // factor in gravity
  if (lander.state) delta_y+=gravity;

  // factor in terminal velocity
  if (delta_y>2) delta_y=2;

  // restore old position in event of collision
  if (collision){
    lander.x=lander.x_old; lander.y=lander.y_old;
  }

  lander.x_old=lander.x; 
  lander.y_old=lander.y;
  if (lander.state){
    x+=delta_x; 
    y+=delta_y;
  }

  lander.x=x; 
  lander.y=y; 
  collision=0;
  SET_SPRITE_SIZE(32,24)

  if (!win){ // are we off the left side of screen? (if not, check for right side of screen)
    if ((lander.x+delta_x)<-15){
      if (board_x>=board_min_x){  //we can win by flying off the left side as well

        if(
          (board_x==1)&&
          (board_y<3)&&
          (!win)
          ){
            win=1; 
            error_code=-2;
            Handle_Win();
            return;
        }

        x=(330-sprite_width); board_x--;
        Change_Board();
        Transfer_Buffer(back1_buffer, double_buffer);
        lander.x_old=lander.x=x; 
        lander.y_old=lander.y=y;
        SET_SPRITE_SIZE(32,24)
        curr_sprite=&lander;
        if (lander.state==-1) lander.curr_frame=10;
        else lander.curr_frame=1;
        Draw_Sprite_Clipped_DB();
        Melt_to_Buffer(double_buffer,0,0);

        // now fill in the fuel and shield
        for (index=textbox.x+41; index<(textbox.x+80); index++){   
          if (index<=textbox.x+41+fuel){
            V_Line(textbox.y+4,textbox.y+4,index,134);
            V_Line(textbox.y+5,textbox.y+8,index,135);
            V_Line(textbox.y+9,textbox.y+9,index,136);
          }
          if (index<=textbox.x+41+shield){
            V_Line(textbox.y+15,textbox.y+15,index,136);
            V_Line(textbox.y+16,textbox.y+19,index,137);
            V_Line(textbox.y+20,textbox.y+20,index,138);
          }
        }
      }
      else{
        delta_x=0; 
        x=-10;
      }
    }
    else if ((lander.x+delta_x)>(335-sprite_width)){
      if (board_x<9){ //BOARD_MAX_X
        x=-10; 
        board_x++;
        //curr_sprite=&textbox; Erase_Sprite_Clipped_DB(); Show_Double_Buffer(double_buffer);
        Change_Board(); 
        Transfer_Buffer(back1_buffer, double_buffer);
        lander.x_old=lander.x=x; lander.y_old=lander.y=y;
        SET_SPRITE_SIZE(32,24)
        curr_sprite=&lander; //Behind_Sprite_Clipped_DB();
        if (lander.state==-1) lander.curr_frame=10;
        else lander.curr_frame=1;
        Draw_Sprite_Clipped_DB();
        Melt_to_Buffer(double_buffer,0,0);
        //               textbox.state=0; Status_Box();
      }
      else{
        delta_x=0; 
        x=(330-(sprite_width+1));
      }
    }

    // are we off the top? (if not, check the bottom too.)
    if ((lander.y+delta_y)<-15){
      if (board_y>=board_min_y){
        // we win by flying off the top of the screen, check for win
        //03/28/02 01:25 AM Disabled
        //        if (temp3_hspd!=temp1_hspd-temp2_hspd){

          if(
            (board_y==1)&&
            (!win)
            ){
              win=1; 
              error_code=-2;
              Handle_Win();
              return;
          }

        //03/28/02 01:25 AM Disabled
        //        }
        //        else{
        //          if ((board_x==1)&&(board_y==1)&&(!win)){
        //            win=1; 
        //            error_code=-2;
        //          } //EXIT_TO_DOS
        //        }
        //delta_y=0; y=-10;
        y=(210-sprite_height); board_y--;
        Change_Board();
        Transfer_Buffer(back1_buffer, double_buffer);
        lander.x_old=lander.x=x; lander.y_old=lander.y=y;
        SET_SPRITE_SIZE(32,24)
        curr_sprite=&lander;
        lander.curr_frame=1;
        if (lander.state==-1) lander.curr_frame=10;
        Draw_Sprite_Clipped_DB();
        Melt_to_Buffer(double_buffer,0,0);
        //                textbox.state=0; Status_Box();
      }
    }
    else if ((lander.y+delta_y)>(215-sprite_height)){
      if (board_y<9){ //BOARD_MAX_Y
        y=-10; board_y++;
        //curr_sprite=&textbox; Erase_Sprite_Clipped_DB(); Show_Double_Buffer(double_buffer);
        Change_Board();
        Transfer_Buffer(back1_buffer, double_buffer);
        lander.x_old=lander.x=x; lander.y_old=lander.y=y;
        SET_SPRITE_SIZE(32,24)
        curr_sprite=&lander;
        if (lander.state==-1) lander.curr_frame=10;
        else lander.curr_frame=1;
        Draw_Sprite_Clipped_DB();
        Melt_to_Buffer(double_buffer,0,0);
        //                textbox.state=0; Status_Box();
      }
      else{
        delta_y=0; y=(210-(sprite_height+1));
      }
    } //end (!win)
  }

  return;
}
/////////////////////////////////////////////////////////////////////////////


void Handle_Draw(void){
  // for pulsing color effects
  static int   
    index    = 0;  // set once, holds value on susequent calls

  index++;
  if (index>5){
    index=0;
    Fade_Modulate(14,0,2);
  }    

  frame_index++;
  if (frame_index>150) {frame_index=50; mode_ready=1;}  // can do lander gear change again.

  if (!collision){
    if (frame_index<50){    // handles gear transition over time (val 0-50 mean gear is moving)
      if (lander.state==-1){  // transition to gear up
        start_sound(sound_effect[SOUND_GEAR], SOUND_GEAR, 0, sound_available);
        lander.curr_frame=9;
        if (frame_index>40) lander.curr_frame=10;
      }
      if (lander.state==1){
        start_sound(sound_effect[SOUND_GEAR], SOUND_GEAR, 0, sound_available);
        lander.curr_frame=9;
        if (frame_index>40) lander.curr_frame=0;
      }
    }
    if (frame_index>49){
      if (lander.state<=1){ // gear down flash landing light
        lander.curr_frame=0;
        if (frame_index>100) lander.curr_frame=1;
      }
      if (lander.state==-1) lander.curr_frame=10;
    }
  }

  SET_SPRITE_SIZE(32,24)
  curr_sprite = &lander; 
  if (!drawn){
    Draw_Sprite_Clipped_DB();
    drawn=1;
  }
  if (!lander.state) return;
  if (micro_engine){
    delta_y-=(gravity+.0075);
    if (tally_fuel==1) fuel-=.0075; 
    if (lander.state>=0){
      lander.curr_frame=3;
      if (frame_index<60) lander.curr_frame=2;
      if (drawn) Draw_Sprite_Clipped_DB();
    }
    else if (lander.state==-1){
      lander.curr_frame=12;
      if (frame_index<60) lander.curr_frame=11;
      if (drawn) Draw_Sprite_Clipped_DB();
    }
  }
  if (main_engine){
    delta_y-=(gravity+.019);
    if (tally_fuel==1) fuel-=.01; 
    if (lander.state==1){
      lander.curr_frame=4;
      if (frame_index<70) lander.curr_frame=3;
      if (frame_index<60) lander.curr_frame=2;
      if (drawn) Draw_Sprite_Clipped_DB();
    }
    else if (lander.state==-1){
      lander.curr_frame=13;
      if (frame_index<70) lander.curr_frame=12;
      if (frame_index<60) lander.curr_frame=11;
      if (drawn) Draw_Sprite_Clipped_DB();
    }
  }
  if (right_engine){
    delta_x+=.02;
    if (tally_fuel==1) fuel-=.0075; 
    if (drawn){
      if (lander.state==1){
        lander.curr_frame=7; Draw_Sprite_Clipped_DB();
      }
      else if (lander.state==-1){
        lander.curr_frame=16; Draw_Sprite_Clipped_DB();
      }
    }
  }
  if (left_engine){
    delta_x-=.02;
    if (tally_fuel==1) fuel-=.0075;
    if (drawn){
      if (lander.state==1){
        lander.curr_frame=8; Draw_Sprite_Clipped_DB();
      }
      else if (lander.state==-1){
        lander.curr_frame=17; Draw_Sprite_Clipped_DB();
      }
    }
  }
  if ((left_engine)||(right_engine)||(micro_engine))
  start_sound(sound_effect[SOUND_THRULAT], SOUND_THRULAT, 0, sound_available);
  if (main_engine)
    start_sound(sound_effect[SOUND_THRUMAIN], SOUND_THRUMAIN, 0, sound_available);
  left_engine=right_engine=main_engine=micro_engine=0;    
  return;
}
/////////////////////////////////////////////////////////////////////////////


int Check_Collision(void){
  int   
    color_counter     = 0,
    temp_fade         = 5,
    counter           = 0,
    index_y           = 0,
    index_x           = 0,
    vector            = 0,
    frame[40];

  RGB_color   color;

  if(collision_check==1){
    if(sound_playing(SOUND_EARTH)) stop_sound(SOUND_EARTH);
    start_sound(sound_effect[SOUND_COLLIDE], SOUND_COLLIDE, 0, sound_available);
    SET_SPRITE_SIZE(32,24)

    curr_sprite=&lander; lander.old_frame=lander.curr_frame;
    if(lander.state==1)    lander.curr_frame=6;    //gear up
    if(lander.state==-1)   lander.curr_frame=14;   //gear down

    shake_screen=1998;
    screen_show_index=screen_show;
    Handle_Earth_Quake();
    curr_sprite=&lander;
    Draw_Sprite_Clipped_DB();
    Handle_Display();

    lander.curr_frame++;
    screen_show_index=screen_show;
    Handle_Earth_Quake();
    curr_sprite=&lander;
    Draw_Sprite_Clipped_DB();
    Handle_Display();
    lander.curr_frame=lander.old_frame;

    if(tally_shield==1){shield-=(2*collision);}
    for(index_x=textbox.x+79; index_x>(textbox.x+41+shield); index_x--){
      if(index_x>=textbox.x+41) V_Line(textbox.y+15,textbox.y+20,index_x,50);
    }
  }	

  if(shield<0){   // explode the lander (shield is gone)
    if(sound_playing(SOUND_EARTH)) stop_sound(SOUND_EARTH);		
    if(lander.state==1) lander.curr_frame=0;
    else lander.curr_frame=10;		
    Restore_Palette((pcx_picture_ptr)&background_pcx,0);   
    color_counter=0;
    start_sound(sound_effect[SOUND_EXPLODE], SOUND_EXPLODE, 0, sound_available);
    while(sound_playing(SOUND_EXPLODE) && color_counter<256){

      //pick random x,y coordinates on the lander to place the explosion
      if((abs(delta_x))>0) delta_x*=.9;
      if((abs(delta_y))>0) delta_y*=.9;
      x+=delta_x; y+=delta_y;
      lander.x=x; lander.y=y;
      explosions.x=(lander.x+(rand()%6)-3);
      explosions.y=(lander.y+(rand()%6)-3);				

      //begin the explosion animation
      for(index_x=0; index_x<8; index_x+=1){
        explosions.curr_frame=index_x;
        if((rand()%10)>2){
          screen_show_index=screen_show; 
          shake_screen=1998; 
          Handle_Earth_Quake();
        }
        explosions.x=(lander.x+(rand()%6)-3);
        explosions.y=(lander.y+(rand()%6)-3);
        curr_sprite = &explosions; 
        if(color_counter<250) Draw_Sprite_Clipped_DB();
        curr_sprite = &lander; 
        if(color_counter<250) Draw_Sprite_Clipped_DB();

        explosions.x=(lander.x+(rand()%10)-5);
        explosions.y=(lander.y+(rand()%10)-5);
        curr_sprite = &explosions; 
        if(color_counter<250) Draw_Sprite_Clipped_DB();

        //fade the palette toward full intensity... white out effect
        if(counter++>temp_fade*2){
          counter=0;
          if(temp_fade>0) temp_fade--; 
          else temp_fade=0;

          //visit each entry on the palette
          for(index_y=1; index_y<255; index_y++){
            Get_Palette_Register(index_y,(RGB_color_ptr)&color);

      // disabled 3/28/02 to alter the characteristics through the explosion of the lander
      //            vector=(rand()%3)-1;
      //            if(vector<1) vector=1;
      //            if(vector>2) vector=2;
            vector=1;

            if(color.red< 62) color.red+=vector;
            else if(color.red==62) {color.red=63; color_counter+=1;}
            else color.red = 63;
            if(color.green< 62) color.green+=vector;
            else if(color.green==62) {color.green=63; color_counter+=1;}
            else color.green = 63;
            if(color.blue< 62) color.blue+=vector;
            else if(color.blue==62) {color.blue=63; color_counter+=1;}
            else color.blue = 63;

            Set_Palette_Register(index_y,(RGB_color_ptr)&color);
          }
        }
        screen_show_index=screen_show; 
        Handle_Display();
        // Handle_Game_Speed(1);  // (ouch, the timing on old machines held up ok using this, but my timing mechanism is flawed on faster machines (they dont scale as anticipated)
      }
    }
    Transfer_Buffer(back1_buffer,double_buffer);
    screen_show_index=screen_show; Handle_Display();		
    Delay(10);
    start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
    Fill_Double_Buffer(0);  
    Melt_to_Buffer(double_buffer,0,1);
    Restore_Palette((pcx_picture_ptr)&background_pcx,0);
    error_code=-1;
    return 1;
  }
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Keyboard_Driver(void){
  int   
    index = 0;

  if (!ikeyboard && error_code<1){
    Old_Key_Isr = _dos_getvect(0x09);
    _dos_setvect(0x09, New_Key_Int);
    ikeyboard=1;
  }
  else{
    _dos_setvect(0x09, Old_Key_Isr);
    ikeyboard=0;
    for (index=0; index<17; index++) {key_table[index]=0;} //NUM_KEYS
  }
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Joystick_Driver(void){
  // test for the presence of the joystick before setting interrupt
  if (!Joystick_Available(1)) return 0;

  if (!ijoystick && !error_code){
    ijoystick=1;
  }
  else{
    ijoystick=0;
    Clear_Joystick();
  }
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Screen(void){
  if (!iscreen && !error_code){
    printf("\nInitializing Screen.."); clreol(); Delay(10);
    gotoxy(1,wherey()); printf("..Screen Initialized"); clreol();
    Fade_Lights_Down(20,0); 
    Set_Video_Mode(0x13); Delay(10);
    iscreen=1;
  }
  else{
    Set_Video_Mode(0x03);
    printf("\nReleasing Screen.."); clreol(); Delay(10);
    iscreen=0;
    gotoxy(1,wherey()); printf("..Screen Released"); clreol();
  }
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Buffer(void){
  if (!ibuffer && !error_code){
    printf("\nInitializing Buffers.."); clreol(); Delay(10);
    if (!Create_Buffers(200)){ //SCREEN_HEIGHT
      printf("\nError allocating graphics buffer");
      return 40;  // error_code set to this number
    }
    if (!PCX_Init((pcx_picture_ptr)&background_pcx)) {error_code=2; Close_Everything();}
    ibuffer=1;
    gotoxy(1,wherey()); printf("..Buffers Initialized"); clreol();
  }
  else{ // delete buffer
    printf("\nReleasing Buffers.."); clreol(); Delay(10);
    Delete_Buffers();
    PCX_Delete((pcx_picture_ptr)&background_pcx); // the contents are in the double buffer so free this
    ibuffer=0;
    gotoxy(1,wherey()); printf("..Buffers Released"); clreol();
  }
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Sound_Driver(void){
  if (!isound && !error_code){    // initialize sound
    printf("\nInitializing Sounds.."); clreol(); Delay(10);
    printf("\nInitializing Extended Memory.."); clreol(); Delay(10);

    if (!detect_settings(&baseio, &irq, &dma, &dma16)){
      printf("\n\nBLASTER environment variable missing or invalid.");
      printf("\nSound Disabled\n");
      sound_available=0; // no sound
      return 0;
    }		
    else{
      if (!init_sb(baseio, irq, dma, dma16)){
        printf("\n\nError initializing sound card!");
        printf("\nSound Disabled\n");
        sound_available=0; // no sound
        return 0;
      }
    }
    init_mixing();

    if (!init_xms()){
      printf("\n\nUnable to initialize extended memory.");
      printf("\nHIMEM.SYS must be installed.");
      printf("\nSound Disabled\n");
      sound_available=0; // no sound
      return 0;
    }

    if (getfreexms() < XMSREQUIRED){
      printf("\n\nInsufficient free XMS to initialize sound");
      printf("\nSound Disabled\n");
      sound_available=0; // no sound
      return 0;
    }

    #ifdef SHAREDEMB
    init_sharing();
    #endif

    if (!open_sound_resource_file(resource_file)){
      printf("\n\nUnable to load sound resource file");
      printf("\nSound Disabled\n");
      sound_available=0; // no sound
      return 0;
    }
    for (index=0; index < 21; index++)
      load_sound(&(sound_effect[index]), sound_key[index]);
    close_sound_resource_file();

    gotoxy(1,(wherey()-1)); printf("..Sounds Initialized"); clreol(); Delay(10);
    gotoxy(1,(wherey()+1)); printf("..Extended Memory Initialized"); clreol(); Delay(10);

    sound_available=1;
    isound=1;
  }
  else{ // delete sound (if isound==1)
    // deallocate sounds
    shutdown_mixing();
    shutdown_sb();
    for (index=0; index<21; index++)         
      free_sound(sound_effect+index);
    #ifdef SHAREDEMB
    printf("\nReleasing Extended Memory.."); clreol(); Delay(10);
    shutdown_sharing();
    gotoxy(1,wherey()); printf("..Extended Memory Released"); clreol();
    #endif

    // start ourexitproc()
    printf("\nReleasing Sounds.."); clreol(); Delay(10);
    for (index=0; index<21; ++index)
      if (sound_effect[index] != NULL)
        free_sound(sound_effect+index);
    gotoxy(1,wherey()); printf("..Sounds Released"); clreol();

    #ifdef SHAREDEMB
    shutdown_sharing();
    #endif

    sound_available=0;
    isound=0;
  }
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Sprite_Init(int option){

  // NOTE: entire game palette is set based on the SPRITES palette  (Filename: H2011)

  if (option){
    strcpy(data_file_name,"H2025");
    if (!Graphic_Load(data_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,data_file_name); Close_Everything();} //error
    SET_SPRITE_SIZE(32,24)
    if (!Sprite_Init((sprite_ptr)&pilot,0,0)) {error_code=4; Close_Everything();} //error
    for (index=0; index<9; index++){
      if (gender==1){
        if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&pilot,index,index,0)){
          error_code=4; 
          Close_Everything(); 
          /* handle error */
        }
      }
      if (gender==0){
        if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&pilot,index,index,1)){
          error_code=4; 
          Close_Everything();
          /* handle error */
        }
      }
    }
  }
  else{
    if(!isprites && !error_code){
      printf("\nInitializing Sprites.."); clreol(); Delay(10);
      SET_SPRITE_SIZE(32,24)
      if (!Sprite_Init((sprite_ptr)&lander,0,0)) {error_code=4; Close_Everything();} //error
      strcpy(data_file_name,"H2011");
      if(!Graphic_Load(data_file_name, (pcx_picture_ptr)&background_pcx)){
        error_code=9; 
        strcpy(error_file_name,data_file_name); 
        Close_Everything();
      } //error

      for (index=0; index<9; index++){
        if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&lander,index,index,0)){
          error_code=4; 
          Close_Everything();
        }
        if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&lander,index+9,index,1)){
          error_code=4; 
          Close_Everything();
        }
        if (index<8){
          if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&lander,index+18,index,3)){
            error_code=4; 
            Close_Everything();
          }
        }
      }
      lander.curr_frame=0;
      lander.state=0; // 0=landed, 1=flying/gear down, -1=flying/gear up
      if (collision_check==1) collision_check=2; // ghost sets to -1, landing should also disable (by setting to 2)

      SET_SPRITE_SIZE(32,24)     
      if (!Sprite_Init((sprite_ptr)&explosions,0,0)){
        error_code=4; 
        Close_Everything();
      } //error
      for (index=0; index<9; index++)
        if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&explosions,index,index,2)){
          error_code=4; 
          Close_Everything();
        } //error

      //        SET_SPRITE_SIZE(32,24)
      //        if (!Sprite_Init((sprite_ptr)&pilot,0,0)) {error_code=4; Close_Everything();} //error
      //        for (index=0; index<9; index++)
      //            if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&pilot,index,index,4)) {error_code=4; Close_Everything();} //error

      #define TEXTBOXES 3
      SET_SPRITE_SIZE(85,26)     
      if (!Sprite_Init((sprite_ptr)&textbox,0,0)){
        error_code=4; 
        Close_Everything();
      } //error

      for (index=0; index<TEXTBOXES; index++){
        if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&textbox,index,index,5)) {error_code=4; Close_Everything();} //error
        if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&textbox,index+TEXTBOXES,index,6)) {error_code=4; Close_Everything();} //error
      }

      strcpy(data_file_name,"H2025");
      if (!Graphic_Load(data_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,data_file_name); Close_Everything();} //error
      SET_SPRITE_SIZE(32,24)
      if (!Sprite_Init((sprite_ptr)&pilot,0,0)) {error_code=4; Close_Everything();} //error
      for (index=0; index<9; index++){
        if (gender==1){
          if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&pilot,index,index,0)){
            error_code=4; 
            Close_Everything(); 
          } //error
        }
        if (gender==0){
          if (!PCX_Grab_Bitmap((pcx_picture_ptr)&background_pcx,(sprite_ptr)&pilot,index,index,1)){
            error_code=4; 
            Close_Everything();
          } //error
        }
      }
      isprites=1;
      gotoxy(1,wherey()); printf("..Sprites Initialized"); clreol();
    }
    else{
      printf("\nReleasing Sprites.."); clreol(); Delay(10);
      Sprite_Delete(&textbox);
      Sprite_Delete(&pilot);
      Sprite_Delete(&explosions);
      Sprite_Delete(&lander);
      isprites=0;
      gotoxy(1,wherey()); printf("..Sprites Released"); clreol();
    }
  }
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Extended_Memory(int option){
  // option is set if we are modifying the files, reset if reading only

  // this function is run very first before even putting
  // the shareware/registered screen and loading the game elements

  int 
    fp, 
    throwaway;
  FILE 
    *FP;
  unsigned char
    data,
    name1[30];

  strcpy(data_file_name,""); strcpy(data_file_name,"H20H");
  if (!option){
    if ((fp = open(data_file_name,O_BINARY|O_RDONLY))==-1){ // game data file
      close(fp);
      error_code=9;
      strcpy(error_file_name,data_file_name);
      Close_Everything();
    }
    else{
      if (!read(fp,&throwaway,sizeof(throwaway))) {strcpy(error_file_name,"-pilot gender"); return 0;}
      if (!read(fp,&board_x,sizeof(board_x))) {strcpy(error_file_name,"-board_x"); return 0;}
      if (!read(fp,&board_y,sizeof(board_y))) {strcpy(error_file_name,"-board_y"); return 0;}
      if (!read(fp,&boardname,sizeof(boardname))) {strcpy(error_file_name,"-boardname"); return 0;} // this one is a throwaway (for saved games background)
      if (!read(fp,&boardname,sizeof(boardname))) {strcpy(error_file_name,"-boardname"); return 0;}
      if (!read(fp,&board_min_x,sizeof(board_min_x))) {strcpy(error_file_name,"-board_min_x"); return 0;}
      if (!read(fp,&board_min_y,sizeof(board_min_y))) {strcpy(error_file_name,"-board_min_y"); return 0;}
      if (!read(fp,&temp2_hspd,sizeof(temp2_hspd))) {strcpy(error_file_name,"-start2_y"); return 0;} //for shareware vs registered version.
    }
    close(fp);

    // test h2028, or h2029 for our url
    if ((FP=fopen("H2028","rt"))==NULL){
      if ((FP=fopen("H2029","rt"))==NULL){
        error_code=10; strcpy(error_file_name,data_file_name); Close_Everything();
      }
    }
    if (!feof(FP)) {fscanf(FP,"%s",&name1);}
    if ((strstr(name1,"esqsoft")==NULL)&&(strstr(name1,"ESQSOFT")==NULL)){
      if (!feof(FP)) {fscanf(FP,"%s",&name1);}
      if ((strstr(name1,"esqsoft")==NULL)&&(strstr(name1,"ESQSOFT")==NULL)){
        if (!feof(FP)) {fscanf(FP,"%s",&name1);}
        if ((strstr(name1,"esqsoft")==NULL)&&(strstr(name1,"ESQSOFT")==NULL)){
          error_code=12; strcpy(error_file_name,data_file_name); Close_Everything();
        }
      }
    }
    fclose(FP);
    // end of test for our url

    // 2/6/99 obsolete, replaced with scanner above (looks for string)
    //if (access("H2028",00)==-1 && access("H2029",00)==-1)
    //{
    //    error_code=9;
    //    strcpy(error_file_name,"H2028");
    //    Close_Everything();
    //}        

    //03/28/02 02:00 AM Disabled
    // what version are we dealing with?
    //      temp1_hspd=114; //assume sarewareh
    //      if (access("H2029",00)==0) temp1_hspd=115;
    
    //printf("temp1=%i temp2=%i temp3=%i",temp1_hspd,temp2_hspd,temp3_hspd); Delay(150);
  }
  else{ // option IS set
    if ((fp = open(data_file_name,O_CREAT|O_BINARY|O_WRONLY,S_IREAD|S_IWRITE))==-1){
      close(fp);
      error_code=9;
      strcpy(error_file_name,data_file_name);
      Close_Everything();
    }
    else{
      if (write(fp,&gender,sizeof(gender))==-1) {strcpy(error_file_name,"-writing pilot gender"); return 0;}
      // printf("gender=%i",gender); Delay(10);
      if (write(fp,&board_x,sizeof(board_x))==-1) {strcpy(error_file_name,"-writing board_x"); return 0;}
      // printf("board_x=%i",board_x); Delay(100);
      if (write(fp,&board_y,sizeof(board_y))==-1) {strcpy(error_file_name,"-writing board_y"); return 0;}
      if (write(fp,&boardname,sizeof(boardname))==-1) {strcpy(error_file_name,"-writing boardbackname"); return 0;}
      if (write(fp,&boardname,sizeof(boardname))==-1) {strcpy(error_file_name,"-writing boardname"); return 0;}
      if (write(fp,&board_min_x,sizeof(board_min_x))==-1) {strcpy(error_file_name,"-writing board_min_x"); return 0;}
      if (write(fp,&board_min_y,sizeof(board_min_y))==-1) {strcpy(error_file_name,"-writing board_min_y"); return 0;}
      if (write(fp,&temp2_hspd,sizeof(temp2_hspd))==-1) {strcpy(error_file_name,"-writing structural integrity"); return 0;}
      if (write(fp,&x,sizeof(x))==-1) {strcpy(error_file_name,"-writing x"); return 0;}
      if (write(fp,&y,sizeof(y))==-1) {strcpy(error_file_name,"-writing y"); return 0;}
      if (write(fp,&fuel,sizeof(fuel))==-1) {strcpy(error_file_name,"-writing fuel"); return 0;}
      if (write(fp,&shield,sizeof(shield))==-1) {strcpy(error_file_name,"-writing shield"); return 0;}
      if (write(fp,&gravity,sizeof(gravity))==-1) {strcpy(error_file_name,"-writing gravity"); return 0;}
      if (write(fp,&lander.state,sizeof(lander.state))==-1) {strcpy(error_file_name,"-writing lander_state"); return 0;}
      if (write(fp,&number_of_messages,sizeof(number_of_messages))==-1) {strcpy(error_file_name,"-writing number_of_messages"); return 0;}
      for (index_x=1; index_x<=number_of_messages; index_x++){
        if (write(fp,&_message[index_x],sizeof(_message[index_x]))==-1) {strcpy(error_file_name,"-writing messages"); return 0;}
      }
      for (index_y=1; index_y<=9; index_y++){
        for (index_x=1; index_x<=9; index_x++){
          if (write(fp,&backgroundname[index_x][index_y],sizeof(backgroundname[index_x][index_y]))==-1) {strcpy(error_file_name,"-writing backgroundname"); return 0;}
        }
      }
    }
    close(fp);

    if (access("H2028",00)==-1){ // does file exist, if not crash
      error_code=9;
      strcpy(error_file_name,"H2028");
      Close_Everything();
    }        
    if (rename("H2028","H2029")==-1){ // can it be renamed, if not crash
      error_code=9;
      strcpy(error_file_name,"H2029");
      Close_Everything();
    }
  }
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Copyright(void){
  int    
    fc1     = 8,
    bc1     = 7,
    fc2     = 15,
    bc2     = 3;
  char
    name1[25],
    name2[25];
  FILE  *fp;

  if(!icopyright){
    textbackground(0); textcolor(7); cprintf("\r\n\r\n");
    textbackground(bc1); textcolor(fc1); cprintf("//////////////////////////////////////////////////////////////////////"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                                                  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Hyper Lander 2 -- Classic  (%s",Hyp_Ver);Gamelib_Ver();cprintf(")                 ");textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  By: Thomas Ballard and Brian Ballard                            "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Copr. 1998-2002, E.S.Q. Software                                "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                                                  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Full Registered Version (Recently Open Released)                "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                                                  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Support open software releases by sending a donation...         "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  >> PAYPAL: Email to Hyper2@ESQSoft.com                          "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  >> MAIL:   PO Box 2444, Sandy Utah USA  84091-2444              "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Your support helps us create more open software!  Thank You!    "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                                                  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//////////////////////////////////////////////////////////////////////"); 
    textbackground(0); textcolor(7); cprintf("\r\n");

  //disable for open release 03/28/02
  //    textbackground(0); textcolor(7); cprintf("\r\n\r\n");
  //    textbackground(bc1); textcolor(fc1); cprintf("/////////////////////////////////////////////"); textbackground(0); textcolor(7); cprintf("\r\n"); 
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                         "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Hyper Lander 2 -- Classic              "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
  //    textbackground(bc1); textcolor(fc1); gotoxy(1, wherey()); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                         "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7);
  //
  //    //03/28/02 01:26 AM Disabled
  //    //  if (temp3_hspd==(temp1_hspd-temp2_hspd)) {
  //
  //    gotoxy(5, wherey()); textbackground(bc2); textcolor(fc2); cprintf("Registered %s",Hyp_Ver);Gamelib_Ver(); textbackground(0); textcolor(7); cprintf("\r\n");
  //
  //    //03/28/02 01:26 AM Disabled
  //    //  }
  //    //  else {gotoxy(5, wherey()); textbackground(bc2); textcolor(fc2); cprintf("Shareware %s",Hyp_Ver);Gamelib_Ver(); textbackground(0); textcolor(7); cprintf("\r\n");}
  //
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Copyright 2000  E.S.Q. Software        "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Loading .. Please Wait                 "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n");
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                         "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n");
  //    textbackground(bc1); textcolor(fc1); cprintf("/////////////////////////////////////////////");
  //    textbackground(0); textcolor(7); cprintf("\r\n");
    Delay(25);
    icopyright=1;
  }
  else{
    textbackground(0); textcolor(7); cprintf("\r\n\r\n");
    textbackground(bc1); textcolor(fc1); cprintf("//////////////////////////////////////////////////////////////////////"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                                                  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Hyper Lander 2 -- Classic  (%s",Hyp_Ver);Gamelib_Ver();cprintf(")                 ");textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  By: Thomas Ballard and Brian Ballard                            "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Copr. 1998-2002, E.S.Q. Software                                "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                                                  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Thanks for playing, give us your feedback at www.esqsoft.com    "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                                                  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Support open software releases by sending a donation...         "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  >> PAYPAL: Email to Hyper2@ESQSoft.com                          "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  >> MAIL:   PO Box 2444, Sandy Utah USA  84091-2444              "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Your support helps us create more open software!  Thank You!    "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                                                  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
    textbackground(bc1); textcolor(fc1); cprintf("//////////////////////////////////////////////////////////////////////"); 
    textbackground(0); textcolor(7); cprintf("\r\n");

  //disable for open release 03/28/02
  //    textbackground(0); textcolor(7); cprintf("\r\n\r\n");
  //    textbackground(bc1); textcolor(fc1); cprintf("/////////////////////////////////////////////"); textbackground(0); textcolor(7); cprintf("\r\n"); 
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                         "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Hyper Lander 2 -- Classic              "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n"); 
  //    textbackground(bc1); textcolor(fc1); gotoxy(1, wherey()); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                         "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7);
  //
  //    //03/28/02 01:26 AM Disabled
  //    //  if(temp3_hspd==(temp1_hspd-temp2_hspd)){
  //
  //      gotoxy(5, wherey()); textbackground(bc2); textcolor(fc2); cprintf("Registered %s",Hyp_Ver);Gamelib_Ver(); textbackground(0); textcolor(7); cprintf("\r\n");
  //
  //    //03/28/02 01:26 AM Disabled
  //    //  }
  //    //  else{
  //    //    gotoxy(5, wherey()); textbackground(bc2); textcolor(fc2); cprintf("Shareware %s",Hyp_Ver);Gamelib_Ver(); textbackground(0); textcolor(7); cprintf("\r\n");
  //    //  }
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Copyright 2000  E.S.Q. Software        "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n");
  //    //03/28/02 01:26 AM Disabled
  //    //  if(temp3_hspd!=temp1_hspd-temp2_hspd){
  //    //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Thanks for Playing .. Please Register  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n");
  //    //  }
  //    //  else{
  //
  //      textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("  Games/Tools, visit http://ESQSoft.com  "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n");
  //
  //    //03/28/02 01:26 AM Disabled
  //    //  }
  //
  //    textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(bc2); textcolor(fc2); cprintf("                                         "); textbackground(bc1); textcolor(fc1); cprintf("//"); textbackground(0); textcolor(7); cprintf("\r\n");
  //    textbackground(bc1); textcolor(fc1); cprintf("/////////////////////////////////////////////"); 
  //    textbackground(0); textcolor(7); cprintf("\r\n\r\n");
    Delay(25);
    icopyright=0;
  }
  return 0; // success
}
/////////////////////////////////////////////////////////////////////////////


void Handle_Error_Code(void){
  printf("\n\nThe following ERROR occured during execution");
  switch(error_code){
    case 4:  
      printf("\nUnable to allocate sufficient sprite memory");
      printf("\n - Requires 525K of conventional memory");
      break;
    case 2:  
      printf("\nUnable to allocate screen buffer");
      printf("\n - Requires 525K of conventional memory");
      break;
    case 5:  
      printf("\nError Loading %s",graphics_file_name);
      printf("\n - Is file corrupt?  Is file in directory?");
      break;
    case 9:  
      printf("\nError Loading %s",error_file_name);
      printf("\n - Is file corrupt?  Is file in directory?");
      break;
    case 10: 
      printf("\nError Loading Registration Menu");
      printf("\n - Unable to find either H2028 or H2029.");
      break;
    case 11: 
      printf("\nShareware version unable to load");
      printf("\nRegistered version data.  Please register.");
      break;
    case 12: 
      printf("\nError Loading Registration Menu");
      printf("\n - H2028 or H2029 is corrupted or missing.");
      break;
    default: 
      break;
  }
  printf("\n\n");
  return;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Game_Speed(int option){
  // function determines the speed of the CPU/Graphics adapter
  // done by timing the drawing of a loading bar graph

  unsigned int far
    *game_clock       = (unsigned int far *)0x0000046CL,
    start_clock       = NULL, 
    finish_clock      = NULL;				

  if(option==1){
    if(animation_speed<1)   {Delay(1);}
    if(animation_speed<2)   {Delay(1);}
    if(animation_speed<3)   {Delay(1);}
    //    if(animation_speed<20)  {Delay(1);} // disabled to try and compensate for faster machines
    if(animation_speed<40)  {}
    if(animation_speed<53)  {Delay(1);}
    if(animation_speed<67)  {}
    if(animation_speed<80)  {}
    if(animation_speed<100) {}
    if(animation_speed<150) {}
    return 1;
  }
  else{
    start_clock=*game_clock;				

    SET_SPRITE_SIZE(85,26)    
    textbox.x=120; textbox.y=85; textbox.curr_frame=3;
    Behind_Sprite((sprite_ptr)&textbox);
    Draw_Sprite((sprite_ptr)&textbox);
    Show_Double_Buffer(double_buffer);

    for (index=textbox.x+5; index<textbox.x+80; index++){
      V_Line(textbox.y+16,textbox.y+16,index,46);
      V_Line(textbox.y+17,textbox.y+20,index,43);
      V_Line(textbox.y+21,textbox.y+21,index,40);
      Show_Double_Buffer(double_buffer);
    }

    finish_clock=*game_clock;  // for determining speed of CPU/Graphics
    animation_speed=(abs(start_clock-finish_clock));

    // note, best speed on pentium with pci card was screen_show=2;
    //       this computer timed animation_speed at 4;  (Brian's machine - confirmed 11/97)

    // on my 486DX/66 w/VL card was screen_show=4;
    //       this computer timed animation_speed at 13;

    screen_show=-1;
    if(animation_speed>1)   screen_show++;
    if(animation_speed>2)   screen_show++;
    if(animation_speed>3)   screen_show++; // animation_speed=4,  screen_show=2 (verified.)
    if(animation_speed>9)   screen_show++; // animation_speed=12, screen_show=3 (verified.)
    if(animation_speed>13)  screen_show++; 
    if(animation_speed>40)  screen_show++; // animation_speed=49, screen_show=5 (verified.)
    if(animation_speed>53)  screen_show++;
    if(animation_speed>67)  screen_show++;
    if(animation_speed>80)  screen_show++; // animation_speed=86, screen_show=8 (verified.)
    if(animation_speed>100) screen_show++;
    if(animation_speed>150) screen_show++;

    // load saturn background into double buffer
    strcpy(graphics_file_name,"H2003");
    if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; Close_Everything();} // error has occured
    _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);

    return 1; // successful operation
  }
}
/////////////////////////////////////////////////////////////////////////////


int Read_GameData_File(void){
  int 
    fp,
    throwaway;

  // the file named H20H will contain the shareware/reg game data
  // leave this configuration this way so if game loading allows
  // multiple saved games like DOOM does we can simply change the
  // variable filename and this can load whatever the filename is.

  if ((fp = open(data_file_name,O_BINARY|O_RDONLY))==-1){
    close(fp);
    error_code=9;
    strcpy(error_file_name,data_file_name);
    Close_Everything();
  }
  else{

    //if (strcmp(data_file_name,"H20H")!=0)  // if a new game do opening animation                
    //{

    if(gender>1){  // set gender only if not selected
      if(!read(fp,&throwaway,sizeof(throwaway))) {strcpy(error_file_name,"-pilot gender"); return 0;}
      gender=gender-2;
    }
    else{
      if(!read(fp,&gender,sizeof(gender))) {strcpy(error_file_name,"-pilot gender"); return 0;}
    }
    if(!read(fp,&board_x,sizeof(board_x))) {strcpy(error_file_name,"-board_x"); return 0;}
    if(!read(fp,&board_y,sizeof(board_y))) {strcpy(error_file_name,"-board_y"); return 0;}
    if(!read(fp,&boardname,sizeof(boardname))) {strcpy(error_file_name,"-boardname"); return 0;}
    if(!read(fp,&boardname,sizeof(boardname))) {strcpy(error_file_name,"-boardname"); return 0;}
    if(!read(fp,&board_min_x,sizeof(board_min_x))) {strcpy(error_file_name,"-board_min_x"); return 0;}
    if(!read(fp,&board_min_y,sizeof(board_min_y))) {strcpy(error_file_name,"-board_min_y"); return 0;}
    if(!read(fp,&temp2_hspd,sizeof(temp2_hspd))) {strcpy(error_file_name,"-start2_y"); return 0;}
    if(!read(fp,&x,sizeof(x))) {strcpy(error_file_name,"-x"); return 0;}
    if(!read(fp,&y,sizeof(y))) {strcpy(error_file_name,"-y"); return 0;}
    if(!read(fp,&fuel,sizeof(fuel))) {strcpy(error_file_name,"-fuel"); return 0;}
    if(!read(fp,&shield,sizeof(shield))) {strcpy(error_file_name,"-shield"); return 0;}
    if(!read(fp,&gravity,sizeof(gravity))) {strcpy(error_file_name,"-gravity"); return 0;}
    if(!read(fp,&lander.state,sizeof(lander.state))) {strcpy(error_file_name,"-lander.state"); return 0;}
    if(!read(fp,&number_of_messages,sizeof(number_of_messages))) {strcpy(error_file_name,"-number_of_messages"); return 0;}

    // read in the messages to display on the blue message box at periodic intervals
    for(index_x=1; index_x<=number_of_messages; index_x++){
      if(!read(fp,&_message[index_x],sizeof(_message[index_x]))) {strcpy(error_file_name,"-_message[x]"); return 0;}
    }

    // read in all of the individual board data
    for(index_y=1; index_y<=9; index_y++){  
      for(index_x=1; index_x<=9; index_x++){
        if(!read(fp,&backgroundname[index_x][index_y],sizeof(backgroundname[index_x][index_y]))) {strcpy(error_file_name,"-background[x][y]"); return 0;}
      }
    }
    close(fp);

    //03/28/02 01:26 AM Disabled
    // if shareware version make sure mins are correct
    //  if(temp3_hspd!=temp1_hspd-temp2_hspd){
    //    board_min_x=5; board_min_y=5;
    //  }

  }
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Game_Data(void){
  // NOTE- the filename must have been stored in data_file_name

  int 
    fp,
    index_x,
    index_y;
  FILE 
    *file;

  // reset these to prevent main game loop from becoming endless
  screen_number     = 0;  // if not reset problems happen in mainmenu
  main_engine       = 0;
  micro_engine      = 0;
  left_engine       = 0;
  right_engine      = 0;
  collision         = 0;
  mode_ready        = 1;
  delta_x           = 0;
  delta_y           = 0;
  message_counter   = 0;

  if (!igamedata){  // initialize
    Read_GameData_File();
    Handle_Game_Speed(0);
    lander.x=lander.x_old=x;
    lander.y=lander.y_old=y;
    if (!lander.state) collision_check=2;
    if (lander.state && collision_check==2) collision_check=1;
    igamedata =  1;
  }
  else{             // uninitialize
    igamedata =  0;
  }
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


void Select_Pilot(void){
  int
    internal_counter  = 0,                  // for playing sound effects during long waits
    done              = 0,
    button_size_x     = 102,                //99,//129,
    button_size_y     = 85,                 //93,//110,
    move              = 0,                  // used for moving the selection button
    index_x           = 0,
    index_y           = 0,
    starting_button_x = 101,                //60,//31,
    starting_button_y = 96,                 //48,//43,
    button_x          = starting_button_x,  // the x coordinate for the selection button
    button_y          = starting_button_y;  // the y coordinate for the selection button

  // load saturn background into double buffer
  strcpy(graphics_file_name,"H2003");
  if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;}
  _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
  start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
  Wait_For_Vsync();
  Sheer(double_buffer,0,2);
  Delay(4);

  // load pilot select background into double buffer over saturn
  strcpy(graphics_file_name,"H2027");
  if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;}
  TransparentTransfer(background_pcx.buffer,double_buffer);
  start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
  Wait_For_Vsync();
  Sheer(double_buffer,0,2);

  while(!done){
    // this section allows the up and down arrows to direct
    // the selection window up and down, and the enter key to select

    if(move) {button_x+=move; move=0;}

    // draw selection on button 
    for(index_y=button_y; index_y<button_y+button_size_y; index_y++){  
      for(index_x=button_x; index_x<button_x+button_size_x; index_x++){  
        data=video_buffer[((index_y<<8)+(index_y<<6))+index_x];
        if(data==168) video_buffer[((index_y<<8)+(index_y<<6))+index_x]=128;
      }        
    }

    while(!done){
      Fade_Modulate(78,0,2); // pulsar stars fading in and out
      Clear_Joystick();
      if(controller==2) Joystick_Driver();

      // play a sound after some period of inactivity
      global_delay--;
      if(global_delay<1){
        global_delay=500;
        internal_counter++; 
        start_sound(sound_effect[SOUND_REVFADE2], SOUND_REVFADE2, 0, sound_available);
      }

      if(key_table[0]||key_table[3]||joy_table[0]){ //INDEX_LEFT, INDEX_LEFT, UP_FULL
        if(!sound_playing(SOUND_LAND)){  
          internal_counter=0;
          if(!sound_available) Delay(5);
          start_sound(sound_effect[SOUND_LAND],SOUND_LAND,0, sound_available);
          if(button_x==starting_button_x) {move=button_size_x;}
          else{move=button_size_x*-1;}
        }
        done=1;
      }
      if(key_table[1]||key_table[2]||joy_table[2]){ //INDEX_DOWN, INDEX_RIGHT, DOWN_FULL
        if(!sound_playing(SOUND_LAND)){  
          internal_counter=0;
          if(!sound_available) Delay(5);
          start_sound(sound_effect[SOUND_LAND],SOUND_LAND,0, sound_available);
          if(button_x==(starting_button_x+(button_size_x*1))) {move=button_size_x*-1;}
          else{move=button_size_x;}
        }
        done=1;
      }
      if(key_table[4] || joy_table[5] || key_table[9] || joy_table[6]){ //INDEX_ENTER
        if(!sound_available) Delay(5);
        start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
        done=3;
      }
      Delay(1);
    }

    // erase selection on button 
    for(index_y=button_y; index_y<button_y+button_size_y; index_y++){
      for(index_x=button_x; index_x<button_x+button_size_x; index_x++){  
        data=video_buffer[((index_y<<8)+(index_y<<6))+index_x];
        if (data==128) video_buffer[((index_y<<8)+(index_y<<6))+index_x]=168;
      }        
    }
    done--;
  }
  if(done==2){ // ENTER was pressed earlier
    if(button_x==starting_button_x) gender=2; // button 1
    if(button_x==starting_button_x+(button_size_x*1)) gender=3; // button 2
  }
}
/////////////////////////////////////////////////////////////////////////////


void Handle_Main_Menu(void){
  int
    internal_counter  = 0,  // for playing sound effects during long waits
    move              = 0,  // used for moving the selection button
    done              = 0,
    index_x           = 0,
    index_y           = 0,
    button_x          = 0,  // the x coordinate for the selection button
    button_y          = 0;  // the y coordinate for the selection button

  imenu=0;
  //    if (igameplay) {textbox.state=-1; Status_Box();} // erase the old box
  // the above line is necessary because if Status_Box() is called from
  // anywhere in this function or the options menu when/if the game
  // is returned to, the status box will no longer work until the next
  // screen change occurs at which time its restored.

  // the following loop draws the box, allows user interface, erases box

  // load saturn background into double buffer
  strcpy(graphics_file_name,"H2003");
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;}
  _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
  Wait_For_Vsync();
  start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
  Melt_to_Buffer(double_buffer,0,1);
  Restore_Palette((pcx_picture_ptr)&background_pcx,1);

  key_table[4]=0; // make sure its clear first. (INDEX_ENTER)
  while(!done){

  //03/28/02 01:26 AM Disabled
  //  if(temp3_hspd==temp1_hspd-temp2_hspd){

      button_x=215; button_y=92; move=0;
      strcpy(graphics_file_name,"H2013");

  //03/28/02 01:26 AM Disabled
  //  }    
  //  else{
  //    button_x=215; button_y=77; move=0;
  //    strcpy(graphics_file_name,"H2012");
  //  }

    if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;} // error has occured
    _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
    start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
    Wait_For_Vsync();
    Sheer(double_buffer,0,2);
    while(!done){
      // this section allows the up and down arrows to direct
      // the selection window up and down, and the enter key to select

      if(move) {button_y+=move; move=0;}

      // draw selection on button
      for(index_y=button_y; index_y<button_y+18; index_y++){
        for(index_x=button_x; index_x<button_x+88; index_x++){
          data=video_buffer[((index_y<<8)+(index_y<<6))+index_x];
          if(data==169) video_buffer[((index_y<<8)+(index_y<<6))+index_x]=128;
        }        
      }

      while(!done){
        Fade_Modulate(78,0,2); // pulsar stars fading in and out
        Clear_Joystick();
        if(controller==2) Joystick_Driver();

        // play a sound after some period of inactivity
        global_delay--;
        if(global_delay<1){
          global_delay=500;
          internal_counter++; 
          start_sound(sound_effect[SOUND_REVFADE2], SOUND_REVFADE2, 0, sound_available);
        }

        if (key_table[0]||key_table[3]||joy_table[0]){ //INDEX_LEFT, INDEX_LEFT, UP_FULL
          if(!sound_playing(SOUND_LAND)){  
            internal_counter=0;
            if(!sound_available) Delay(5);
            start_sound(sound_effect[SOUND_LAND],SOUND_LAND,0, sound_available);

  //03/28/02 01:26 AM Disabled
  //          if(temp3_hspd==temp1_hspd-temp2_hspd){

              if(button_y==92) move=75;
              else move=-15;

  //03/28/02 01:26 AM Disabled
  //          }    
  //          else{
  //            if(button_y==77) move=90;
  //            else move=-15;
  //          }

          }
          done=1;
        }
        if(key_table[1]||key_table[2]||joy_table[2]){ //INDEX_DOWN, INDEX_RIGHT, DOWN_FULL
          if(!sound_playing(SOUND_LAND)){  
            internal_counter=0;
            if(!sound_available) Delay(5);
            start_sound(sound_effect[SOUND_LAND],SOUND_LAND,0, sound_available);

  //03/28/02 01:26 AM Disabled
  //          if(temp3_hspd==temp1_hspd-temp2_hspd){ //REGISTRATION BUTTON?

              if(button_y==167) move=-75;
              else move=15;

  //03/28/02 01:26 AM Disabled
  //          }    
  //          else{
  //            if(button_y==167) move=-90;
  //            else move=15;
  //          }

          }
          done=1;
        }
        if(key_table[9] || joy_table[6]){ //INDEX_ESC
          if(!sound_available) Delay(5);
          start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
          done=2;
        }
        if(key_table[4] || joy_table[5]){ //INDEX_ENTER
          if(!sound_available) Delay(5);
          start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
          done=3;
        }
        Delay(1);
      }

      // erase selection on button 
      for(index_y=button_y; index_y<button_y+18; index_y++){
        for(index_x=button_x; index_x<button_x+88; index_x++){
          data=video_buffer[((index_y<<8)+(index_y<<6))+index_x];
          if(data==128) video_buffer[((index_y<<8)+(index_y<<6))+index_x]=169;
        }        
      }
      done--;
    }

    // close down the mainmenu and do the mechanics required after the
    // selection is made.

    if(done==2){
      if(button_y==77){   // REGISTER NOW
        start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
        if(igamedata) Handle_Game_Data(); // deallocate any existing data
        igameplay=0;
        registration();
        //igamedata=10;
        done=0;
      }
      if(button_y==92){   // NEW GAME
        start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
        if(igamedata) Handle_Game_Data(); // deallocate any existing data
        Select_Pilot();
        igameplay=0;
        igamedata=10;
        done=1;
      }
      if(button_y==107){  // LOAD GAME
        start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
        strcpy(data_file_name,""); // start by clearing the var used to load a game
        Handle_Options_Menu(2); // let player select game from graphical representation of saved games
        if(strlen(data_file_name)>1) done=1; // if the var has data in it the game is ok to load
        else done=0;
      }
      if(button_y==122){  // SAVE GAME
        done=0;
        if(!igameplay){ // not in a game, save what?
          // load saturn background into double buffer
          strcpy(graphics_file_name,"H2003");
          if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;} // error has occured
          _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
          Wait_For_Vsync();
          Sheer(double_buffer,0,0);

          start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
          SET_SPRITE_SIZE(85,26)    
          textbox.x=120; textbox.y=85; textbox.curr_frame=5;
          Behind_Sprite((sprite_ptr)&textbox);
          Draw_Sprite((sprite_ptr)&textbox);
          Show_Double_Buffer(double_buffer);

          while(!done){
            if(keystroke) done=1; 
            if(joy_table[5]) done=1;
          }
        }
        else{
          start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
          Handle_Options_Menu(1); // save game
        }
        done=0;
      }
      if(button_y==137){  // OPTIONS
        start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
        Handle_Options_Menu(0); // options 
        done=0;
      }
      if(button_y==152){  // INTRODUCTION
        start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
        if(igamedata) Handle_Game_Data();
        if(!iintro){
          imenu=2; 
          done=1;
        }
        else done=10; // just exit out, the intro in already running
        igameplay=0;   // reset just in case game is running
        error_code=-3; // this is set here only and it tells the game to run the intro
      }
      if(button_y==167){  // QUIT GAME
        start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);

        // load saturn background into double buffer
        strcpy(graphics_file_name,"H2003");
        if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;} // error has occured
        _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
        Wait_For_Vsync();
        Sheer(double_buffer,0,0);

        SET_SPRITE_SIZE(85,26)    
        textbox.x=120; textbox.y=85; textbox.curr_frame=4;
        Behind_Sprite((sprite_ptr)&textbox); 
        Draw_Sprite((sprite_ptr)&textbox);
        Show_Double_Buffer(double_buffer);

        done=0;
        while(!done){
          if(controller==2) {Clear_Joystick();Joystick_Driver();}
          if(key_table[10] || joy_table[5]) {done=2; error_code=-2;} //EXIT_TO_DOS (INDEX_Y)
          if(key_table[11] || joy_table[6]) {done=1;} //INDEX_N
        }
        done--;
      }
    }
  }

  if(error_code!=-2){ //EXIT_TO_DOS
    if(igameplay){ // esc back into a game
      Change_Board(); 
      Transfer_Buffer(back1_buffer, double_buffer);
      SET_SPRITE_SIZE(32,24)
      curr_sprite=&lander; //Behind_Sprite_Clipped_DB();

      // if thruster was displayed last these lines ensure that the lander is drawn, not the thruster.
      if (lander.state==-1) lander.curr_frame=10;  // gear up, already in flight
      else lander.curr_frame=1;                    // gear down, inflight or landed

      Draw_Sprite_Clipped_DB();
      Melt_to_Buffer(double_buffer,0,1);
    }

    //commented with FULL VERSION relese 03/26/02 01:23 PM
    //        else if (error_code==-3)
    //        {   Fill_Double_Buffer(0);
    //            Melt_to_Buffer(double_buffer,0,1);
    //            error_code=0;   // added 12/98
    //		}
    else{
      strcpy(graphics_file_name,"H2003");
      if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;} // error has occured
      _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
      Sheer(double_buffer,0,0);
    }
    if(igamedata!=10){
      if(screen_number==6||screen_number==7){
        strcpy(graphics_file_name,"H205");
        if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;} // error has occured
        _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
        Melt_to_Buffer(double_buffer,0,1);
      }				
      if(screen_number==4){
        strcpy(graphics_file_name,"H2003");
        if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return;} // error has occured
        _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
        Melt_to_Buffer(double_buffer,0,1);
      }
    }

    // this is where the new game or load game is done
    if (igamedata>5){        // we must have selected NEW GAME or LOAD GAME from mainmenu
      if (igamedata==10){
        strcpy(data_file_name,"H20H");
        newgame=1;
      } // NEW GAME                
      else{
        newgame=0;
      }
      igamedata=0;        // reset so the game data function will ALLOCATE and not DEALLOCATE
      Handle_Game_Data(); // get new data
      Handle_Sprite_Init(1);  // load pilot character based new game data
      Handle_Start();     // this is done here because if we're restoring an
      // existing game we don't do the earth quake.
    }
    // end of section
  }

  imenu=0;
  return;
}
/////////////////////////////////////////////////////////////////////////////


int Handle_Options_Menu(int Option){
  char
    temp_back_name[8],
    temp_file_name[8],
    temp_board_name[8];
  int
    throwaway,
    fp,
    graph_to          = 0,     // the y_to coordinate for the above graph
    index             = 0,     // general purpose for loops
    index_x           = 0,
    index_y           = 0, 
    done              = 0,     // gerenal purpose for exitting whiles
    internal_counter  = 0,     // for playing sound effects during long waits
    move_x            = 0,     // used for moving the selection button
    move_y            = 0,
    options_button_x  = 0,     // the x coordinate for the selection button
    options_button_y  = 0,     // the y coordinate for the selection button
    button_size_x     = 0,
    button_size_y     = 0,
    temp_x            = 0,
    temp_y            = 0,
    temp_board_x      = 0,
    temp_board_y      = 0;
  float
    temp_ox           = 0,
    temp_oy           = 0,
    temp_lx           = 0,
    temp_ly           = 0;

  // set button x,y's and sizes based on purpose of entry
  if(Option==0){ // we've entered function to set options
    button_size_x=82; 
    button_size_y=25; 
    options_button_x=96; 
    options_button_y=104;
  }
  if(Option==1 || Option==2){ // we've entered function to load or save game
    button_size_x=39; 
    button_size_y=26; 
    options_button_x=97; 
    options_button_y=159;
  }

  start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available); // play only on first entry
  while(!done){   // load and display OPTIONS DATA, exit on successful load or esc
    // load menu box into double buffer
    strcpy(graphics_file_name,"H2014");
    if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();} // handle error
    _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
    Wait_For_Vsync();
    Sheer(double_buffer,0,2);

    // store current game x,y so they can be restored
    temp_ox=lander.x; temp_oy=lander.y;

    // load and display saved games at 1/10 scale
    for (index=1; index<=5; index++){
      strcpy(temp_file_name,"H2S0"); strcat(temp_file_name,itoa(index,tstring,10));

      // check each slot for an available saved game
      if((fp = open(temp_file_name,O_BINARY|O_RDONLY)) != -1){
        if(!read(fp,&throwaway,sizeof(throwaway))) {strcpy(error_file_name,"-gender"); return 0;}
        if(!read(fp,&temp_board_x,sizeof(temp_board_x))) {strcpy(error_file_name,"-board_x"); return 0;}
        if(!read(fp,&temp_board_y,sizeof(temp_board_y))) {strcpy(error_file_name,"-board_y"); return 0;}
        if(!read(fp,&temp_back_name,sizeof(temp_back_name))) {strcpy(error_file_name,"-backname"); Close_Everything();/*return 0;*/}
        if(!read(fp,&temp_board_name,sizeof(temp_board_name))) {strcpy(error_file_name,"-boardname"); Close_Everything(); /*return 0; */}
        if(!read(fp,&throwaway,sizeof(throwaway))) {strcpy(error_file_name,"-board_min_x"); return 0;}
        if(!read(fp,&throwaway,sizeof(throwaway))) {strcpy(error_file_name,"-board_min_y"); return 0;}
        if(!read(fp,&throwaway,sizeof(throwaway))) {strcpy(error_file_name,"-start2_y"); return 0;}
        if(!read(fp,&temp_lx,sizeof(temp_lx))) {strcpy(error_file_name,"-x"); return 0;}
        if(!read(fp,&temp_ly,sizeof(temp_ly))) {strcpy(error_file_name,"-y"); return 0;}
        close(fp);

        // load the background board first
        strcpy(temp_file_name,temp_back_name);
        if (Graphic_Load(temp_file_name, (pcx_picture_ptr)&background_pcx)){
          _fmemcpy((char far *)back2_buffer,(char far *)(background_pcx.buffer),64000);
          lander.x=temp_lx; 
          lander.y=temp_ly;                    
          lander.x=temp_ox; 
          lander.y=temp_oy;
          if(index==1) temp_x=100;
          if(index==2) temp_x=142;
          if(index==3) temp_x=184;
          if(index==4) temp_x=226;
          if(index==5) temp_x=268;
          temp_y=162;
          for(index_y=0; index_y<200; index_y+=10){
            for(index_x=0; index_x<320; index_x+=10){
              data=back2_buffer[((index_y<<8)+(index_y<<6))+index_x];
              video_buffer[((temp_y<<8)+(temp_y<<6))+temp_x]=data;
              temp_x++;
            }
            temp_y++; 
            temp_x-=32;
          }
        }

        // now load the foreground over the background
        strcpy(temp_file_name,"");
        strcpy(temp_file_name,temp_board_name);
        strcat(temp_file_name,itoa(temp_board_x,tstring,10));                
        strcat(temp_file_name,itoa(temp_board_y,tstring,10));
        if (Graphic_Load(temp_file_name, (pcx_picture_ptr)&background_pcx)){
          _fmemcpy((char far *)back2_buffer,(char far *)(background_pcx.buffer),64000);
          lander.x=temp_lx; 
          lander.y=temp_ly;
          temp_buffer=double_buffer;
          double_buffer=back2_buffer;
          sprite_overlap=1;
          curr_sprite=&lander; 
          lander.curr_frame=1; 
          Draw_Sprite_Clipped_DB();
          double_buffer=temp_buffer;
          if(index==1) temp_x=100;
          if(index==2) temp_x=142;
          if(index==3) temp_x=184;
          if(index==4) temp_x=226;
          if(index==5) temp_x=268;
          temp_y=162;
          for(index_y=0; index_y<200; index_y+=10){
            for(index_x=0; index_x<320; index_x+=10){
              data=back2_buffer[((index_y<<8)+(index_y<<6))+index_x];
              video_buffer[((temp_y<<8)+(temp_y<<6))+temp_x]=data;
              temp_x++;
            }
            temp_y++;
            temp_x-=32;
          }
        }
      }
      else{  // no saved game exists at this slot
      }
    }
    Transfer_Buffer(video_buffer, double_buffer);
    // end of load and display saved games

    //restore the game variables previously protected
    lander.x=temp_ox; lander.y=temp_oy;

    while(!done){   // moving the selected button, exit on esc or enter
      if(move_y || move_x){
        options_button_y+=move_y; 
        move_y=0; 
        options_button_x+=move_x; 
        move_x=0;
      }
      Wait_For_Vsync();
      Transfer_Buffer(double_buffer, video_buffer);
      // highlight selected button
      for(index_y=options_button_y; index_y<options_button_y+button_size_y; index_y++){
        for(index_x=options_button_x; index_x<options_button_x+button_size_x; index_x++){
          data=video_buffer[((index_y<<8)+(index_y<<6))+index_x];
          if (Option==0) {if (data==169) video_buffer[((index_y<<8)+(index_y<<6))+index_x]=128;}
          else if (data==169) video_buffer[((index_y<<8)+(index_y<<6))+index_x]=128;
        }        
      }

      // show graph of selected options current setting
      if(Option==0){ // if we've entered this function to select options (not load or save)
        graph_to=0;
        if(options_button_y==104 && options_button_x==96){ // sound on/off
          if(sound_available) graph_to=70;
        }
        if(options_button_y==131 && options_button_x==96 && igameplay){   // speed
          graph_to=((screen_show+1)*7);
          if(graph_to<0) graph_to=0;
          if(graph_to>70) graph_to=70;
        }
        if(options_button_y==77 && options_button_x==180){  // keyboard active
          if(controller==1) graph_to=70;
        }
        if(options_button_y==104 && options_button_x==180){  // jystick active
          if(controller==2) graph_to=70;
        }
        if(options_button_y==131 && options_button_x==180){  // messages on/off
          if(show_messages==1) graph_to=70;
        }
        // make sure to erase anything that was there
        for (index=152; index>=82; index--){
          video_buffer[((index<<8)+(index<<6))+268]=168;
          video_buffer[((index<<8)+(index<<6))+269]=168;
          video_buffer[((index<<8)+(index<<6))+270]=168;
          video_buffer[((index<<8)+(index<<6))+271]=168;
          video_buffer[((index<<8)+(index<<6))+272]=168;
          video_buffer[((index<<8)+(index<<6))+273]=168;
        }
        if(graph_to>0){
          for(index=152; index>=(152-graph_to); index--){
            video_buffer[((index<<8)+(index<<6))+268]=159;
            video_buffer[((index<<8)+(index<<6))+269]=156;
            video_buffer[((index<<8)+(index<<6))+270]=156;
            video_buffer[((index<<8)+(index<<6))+271]=156;
            video_buffer[((index<<8)+(index<<6))+272]=156;
            video_buffer[((index<<8)+(index<<6))+273]=153;
          }
        }
      }
      // end graph

      while (!done){
        Fade_Modulate(78,0,2);
        if(controller==2){
          Clear_Joystick();
          Joystick_Driver();
        }

      global_delay--;
      if(global_delay<1){
        internal_counter++; 
        global_delay=500;
        start_sound(sound_effect[SOUND_REVFADE2], SOUND_REVFADE2, 0, sound_available);
      }

      if(key_table[0]||key_table[3]||joy_table[0]||joy_table[3]){ //INDEX_LEFT, UP_FULL, LEFT_FULL
        if(!sound_playing(SOUND_LAND)){
          if(!sound_available) Delay(5);
          start_sound(sound_effect[SOUND_LAND],SOUND_LAND,0, sound_available);
          internal_counter=0;

          if(Option==0){ // when we're here to set options
            if (options_button_y==104 && options_button_x==96) {move_y=27; move_x=84;}
            else if (options_button_y==77 && options_button_x==180) {move_y=54; move_x=-84;}
            else {move_y=-27;}
          }
          if(Option==1 || Option==2){ // here to load or save
            if(options_button_x==97) move_x=168;
            else move_x=-42;
          }
        }
        done=1;  // exit to previous loop to move button
      }
      if (key_table[1]||key_table[2]||joy_table[2]||joy_table[4]){ //INDEX_DOWN, INDEX_RIGHT, DOWN_FULL, RIGHT_FULL
        if(!sound_playing(SOUND_LAND)){
          if(!sound_available) Delay(5);
            internal_counter=0;
            start_sound(sound_effect[SOUND_LAND],SOUND_LAND,0, sound_available);

            if(Option==0){ // here to set options
              if(options_button_y==131 && options_button_x==96){
                move_y=-54; 
                move_x=84;
              }
              else if(options_button_y==131 && options_button_x==180){
                move_y=-27; 
                move_x=-84;
              }
              else move_y=27;
            }
            if(Option==1 || Option==2){   // here to load or save
              if(options_button_x==265) move_x=-168;
              else move_x=42;
            }
          }
          done=1;  // exit to previous loop to move button
        }
        if(key_table[9] || joy_table[6]){ //INDEX_ESC
          if(!sound_available) Delay(5);
          start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
          done=3; // exit all three previous loops to mainmenu
        }
        if (key_table[4] || joy_table[5]){ //INDEX_ENTER
          key_table[4]=0; 
          joy_table[5]=0; //INDEX_ENTER
          if (Option==1 || Option==2){ // here to load or save
            strcpy(data_file_name,"");
            if(options_button_x==97)  strcpy(data_file_name,"H2S01");
            if(options_button_x==139) strcpy(data_file_name,"H2S02");
            if(options_button_x==181) strcpy(data_file_name,"H2S03");
            if(options_button_x==223) strcpy(data_file_name,"H2S04");
            if(options_button_x==265) strcpy(data_file_name,"H2S05");
            if (Option==2){ // load game
              if ((strlen(data_file_name)<1) || (fp = open(data_file_name,O_BINARY|O_RDONLY))==-1){ // UNSUCCESSFUL ATTEMPT TO LOAD
                strcpy(data_file_name,""); // used in mainmenu to determine success of load

                // load saturn background into double buffer
                strcpy(graphics_file_name,"H2003");
                if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return 0;} // error has occured
                _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
                Wait_For_Vsync();
                Sheer(double_buffer,0,0);

                // display the NOT AVAILABLE button
                SET_SPRITE_SIZE(85,26)    
                textbox.x=120; 
                textbox.y=85; 
                textbox.curr_frame=2;
                Behind_Sprite((sprite_ptr)&textbox);
                Draw_Sprite((sprite_ptr)&textbox);
                Show_Double_Buffer(double_buffer);

                start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
                while(!done){
                  if(keystroke) done=1;
                  if(controller==2 && joy_table[5]) done=1;
                }
                done=2; // exit previous loop into reload DA5 data
              }
              else{  // SUCCESSFUL ATTEMPT TO LOAD                     
                close(fp);
                start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
                if(igamedata) Handle_Game_Data(); // clear old data
                igamedata=9;  // used to tell mainmenu to load game before exitting
                igameplay=0;  // reset current game (if there was one) so the status box isn't put on screen during load
                done=3;       // exit all (3) previous loops to return to mainmenu
              }
            }
            if (Option==1){ // save game
              // this location is reached after a specific slot
              // for saving the game has been selected

              strcpy(temp_back_name,"");
              strcpy(temp_back_name,boardname);
              strcat(temp_back_name,itoa((backgroundname[board_x][board_y]),tstring,10));

              if((strlen(data_file_name)>0) && ((fp = open(data_file_name,O_CREAT|O_BINARY|O_WRONLY,S_IREAD|S_IWRITE))!=-1)){   // SUCCESSFUL ATTEMPT TO SAVE FILE
                start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
                if(write(fp,&gender,sizeof(gender))==-1) {strcpy(error_file_name,"-writing pilot gender"); return 0;}
                if(write(fp,&board_x,sizeof(board_x))==-1) {strcpy(error_file_name,"-writing board_x"); return 0;}
                if(write(fp,&board_y,sizeof(board_y))==-1) {strcpy(error_file_name,"-writing board_y"); return 0;}
                if(write(fp,&temp_back_name,sizeof(temp_back_name))==-1) {strcpy(error_file_name,"-writing temp_back_name"); return 0;}
                if(write(fp,&boardname,sizeof(boardname))==-1) {strcpy(error_file_name,"-writing boardname"); return 0;}
                if(write(fp,&board_min_x,sizeof(board_min_x))==-1) {strcpy(error_file_name,"-writing board_min_x"); return 0;}
                if(write(fp,&board_min_y,sizeof(board_min_y))==-1) {strcpy(error_file_name,"-writing board_min_y"); return 0;}
                if(write(fp,&temp2_hspd,sizeof(temp2_hspd))==-1) {strcpy(error_file_name,"-writing structural integrity"); return 0;}
                if(write(fp,&x,sizeof(x))==-1) {strcpy(error_file_name,"-writing x"); return 0;}
                if(write(fp,&y,sizeof(y))==-1) {strcpy(error_file_name,"-writing y"); return 0;}
                if(write(fp,&fuel,sizeof(fuel))==-1) {strcpy(error_file_name,"-writing fuel"); return 0;}
                if(write(fp,&shield,sizeof(shield))==-1) {strcpy(error_file_name,"-writing shield"); return 0;}
                if(write(fp,&gravity,sizeof(gravity))==-1) {strcpy(error_file_name,"-writing gravity"); return 0;}
                if(write(fp,&lander.state,sizeof(lander.state))==-1) {strcpy(error_file_name,"-writing lander_state"); return 0;}
                if(write(fp,&number_of_messages,sizeof(number_of_messages))==-1) {strcpy(error_file_name,"-writing number_of_messages"); return 0;}
                for(index_x=1; index_x<=number_of_messages; index_x++){
                  if(write(fp,&_message[index_x],sizeof(_message[index_x]))==-1) {strcpy(error_file_name,"-writing messages"); return 0;}
                }
                for(index_y=1; index_y<=9; index_y++){
                  for(index_x=1; index_x<=9; index_x++){
                    if(write(fp,&backgroundname[index_x][index_y],sizeof(backgroundname[index_x][index_y]))==-1) {strcpy(error_file_name,"-writing backgroundname"); return 0;}
                  }
                }
                close(fp);

                // load saturn background into double buffer
                strcpy(graphics_file_name,"H2003");
                if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return 0;}
                _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
                Wait_For_Vsync();
                Sheer(double_buffer,0,0);

                // display Save Game button and graph
                SET_SPRITE_SIZE(85,26)    
                textbox.x=120; textbox.y=85; textbox.curr_frame=1;
                sprite_overlap=1;
                Behind_Sprite((sprite_ptr)&textbox);
                Draw_Sprite((sprite_ptr)&textbox);
                Show_Double_Buffer(double_buffer);
                for(index=textbox.x+5; index<textbox.x+80; index++){
                  V_Line(textbox.y+16,textbox.y+16,index,159); // fileio highlight color
                  V_Line(textbox.y+17,textbox.y+20,index,156); // fileio color (bar graph)
                  V_Line(textbox.y+21,textbox.y+21,index,153); // fileio shadow color
                  Show_Double_Buffer(double_buffer);
                }
                done=3;  // exit back to game (?)
              }  // end successful save attempt
              else{  // UNSUCCESSFUL ATTEMPT TO SAVE FILE (possibly write protected, bad disk, but serious!!)                   
                strcpy(data_file_name,""); // used in mainmenu to track success of save

                // load saturn background into double buffer
                strcpy(graphics_file_name,"H2003");
                if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; return 0;}
                _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
                Wait_For_Vsync();
                Sheer(double_buffer,0,0);

                // display the NOT AVAILABLE button
                SET_SPRITE_SIZE(85,26)    
                textbox.x=120; textbox.y=85; textbox.curr_frame=2;
                Behind_Sprite((sprite_ptr)&textbox);
                Draw_Sprite((sprite_ptr)&textbox);
                Show_Double_Buffer(double_buffer);

                start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
                while(!done){
                  if(keystroke) done=1;
                  if(controller==2 && joy_table[5]) done=1;
                }
                done=1; // exit previous loop into reload DA5 data
              }
            }  // end options==1
          }  // end options==1 or options==2
        }  // end INDEX_ENTER
        if(key_table[14]){ //INDEX_PLUS
          key_table[14]=0; //INDEX_PLUS
          if(options_button_y==104 && options_button_x==96){ // sound on
            start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
            if(!sound_available && isound) sound_available=1;
          }
          if(options_button_y==131 && options_button_x==96){ // speed up
            if(!igameplay){
              start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
            }
            else{
              start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
              if(screen_show<10) screen_show++;
            }
          }
          if(options_button_y==77 && options_button_x==180){  // keyboard on
            start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
            controller=1;
          }
          if(options_button_y==104 && options_button_x==180){  // jystick on
            start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
            controller=2;
            // test for jystick
            if (Joystick_Available(1)){  
              if (!joystick_calibrated){
                start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
                _fmemcpy((char far *)back3_buffer,(char far *)(video_buffer),64000);
                Calibrate_Joystick();
                _fmemcpy((char far *)double_buffer,(char far *)(back3_buffer),64000);
                Sheer(double_buffer,0,2);
              }
            }
            else{
              controller=1;
              start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
            }
            // end test for jystick
          }
          if(options_button_y==131 && options_button_x==180){  // radio messages on
            start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
            show_messages=1;
          }
          done=1;  // exit into loop to display new graph settings
        }  // end INDEX_PLUS
        if(key_table[8]){ //INDEX_MINUS
          key_table[8]=0; //INDEX_MINUS
          if(options_button_y==104 && options_button_x==96){ // sound on
            start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
            // shut down any sounds that are playing currently
            if(sound_available==1){
              for(index=0; index<21; index++){
                if(sound_playing(index)) stop_sound(index);
              }
            }
            sound_available=0;
          }
          if(options_button_y==131 && options_button_x==96){ // speed up
            if(!igameplay){
              start_sound(sound_effect[SOUND_ALERT],SOUND_ALERT,0, sound_available);
            }
            else{
              start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
              if(screen_show>-1) screen_show--;
            }
          }
          if(options_button_y==77 && options_button_x==180){  // keyboard off
            start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
            controller=2;
            // test for jystick
            if (Joystick_Available(1)){  // Joystick_Calibrate(1);
              start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
              if(!joystick_calibrated){
                _fmemcpy((char far *)back3_buffer,(char far *)(video_buffer),64000);
                start_sound(sound_effect[SOUND_ACCEPT], SOUND_ACCEPT, 0, sound_available);
                Calibrate_Joystick();
                _fmemcpy((char far *)double_buffer,(char far *)(back3_buffer),64000);
                Sheer(double_buffer,0,2);
              }
            }
            else{
              controller=1;
              start_sound(sound_effect[SOUND_ALERT], SOUND_ALERT, 0, sound_available);
            }
            // end test for jystick
          }
          if(options_button_y==104 && options_button_x==180){  // jystick off
            start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
            controller=1;
          }
          if(options_button_y==131 && options_button_x==180){  // radio messages on
            start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
            show_messages=0;
          }
          done=1;  // exit into loop to display new graph settings
        }  // end INDEX_MINUS
        Delay(1);
      }  // end while waiting for a keystroke

      done--;
    }  // end while move button and graph
    done--;
  }  // end display DA5 and saved games
  return 1;
}  // end handle options menu
/////////////////////////////////////////////////////////////////////////////


void Display_Message(int message){
  int
    local_delay    = 1,     // used for when user is impatient and hits key
    text_y         = 47;

  if (message==8){
    Load_Radio_Box(1);
    Blit_String(36,text_y,122,"YOU ARE ATTEMPTING TO ENTER",local_delay,1); text_y+=9;
    Blit_String(36,text_y,122,"AN AREA OF THE MISSION WHICH",local_delay,1); text_y+=9;
    Blit_String(36,text_y,122,"IS AVAILABLE ONLY AFTER THE",local_delay,1); text_y+=9;
    Blit_String(36,text_y,122,"GAME HAS BEEN REGISTERED.",local_delay,1); text_y+=9;
    Blit_String(36,text_y,122,"YOU ARE INVITED TO PLAY THIS",local_delay,1); text_y+=9;
    Blit_String(36,text_y,122,"SECTION BUT YOU MUST REGISTER",local_delay,1); text_y+=9;
    Blit_String(36,text_y,122,"YOUR COPY FIRST.  THANKS.",local_delay,1); text_y+=9;
    Delay(100);
    Await_Exit_Request(400);
    Load_Radio_Box(0);
    message=0;
    Delay(10);
    start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
    Fill_Double_Buffer(0);  
    Melt_to_Buffer(double_buffer,0,1);
    Restore_Palette((pcx_picture_ptr)&background_pcx,0);
    error_code=-1;
  }
  else if (message==7 && _message[7]){
    _message[7]--;
    Load_Radio_Box(1);
    Blit_String(36,text_y,122,"ORBITAL, COME IN",local_delay,1); text_y+=9;    
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"WE'RE OUT OF FUEL !!!      ",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"I AM ATTEMPTING TO MAKE A  ",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"CRASH LANDING !!!  IF WE      ",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"SURVIVE WE'RE GOING TO NEED.. ",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"SKRC ....... CHV .. SVQ      ",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    text_y+=8; if (local_delay) Await_Exit_Request(local_delay*10);
    Blit_String(36,text_y,169,"COMMANDER !!   COMMANDER !!  ",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"SIR WE'VE LOST THE COMM !!",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"THEIR SIGNAL IS GONE...  ",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"GOD HELP THEM  ",local_delay,1); text_y+=9;
    Await_Exit_Request(300);
    Load_Radio_Box(0);
  }
  else if(fuel<=0) return;
  else if(message==1 && _message[1]){
    _message[1]--; // prevent message from being shown again
    Load_Radio_Box(1);
    Blit_String(36,text_y,122,"ORBITAL, COME IN",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"WE'RE SEEING A DAMAGED FACILITY",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"IT APPEARS TO HAVE SOME",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"WREAKAGE FROM ANOTHER PROTOTYPE",local_delay,1); text_y+=9;
    text_y+=8; 
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"HYPER LANDER?!  THAT CAN'T BE",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"ALL FIRST GENERATIONS",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"ACCOUNTED FOR AND THERE ISN'T",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"ANY RECORD OF OTHER FACILITIES.",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"WE'RE THE FIRST, AND THE ONLY",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"TEAM SUPPOSED TO BE HERE.",local_delay,1); text_y+=9;
    Await_Exit_Request(350);
    Load_Radio_Box(0);
  }
  else if(message==2 && _message[2]){
    _message[2]--;
    Load_Radio_Box(1);
    Blit_String(36,text_y,122,"ORBITAL, COME IN",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"WE'RE FLYING IN A PREVIOUSLY   ",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"UNRECORDED TUNNEL.  IT WOULD",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"APPEAR THAT THE SHAKING HAS",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"OPENED THIS FISSURE.   ",local_delay,1); text_y+=9;
    text_y+=8; if (local_delay) Delay(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"MAYBE IT VENTS AT THE SURFACE",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"IT MAY BE THE FASTEST WAY OUT",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"IF YOU HAVE ROOM TO NAVIGATE.",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"DON'T ENDANGER YOUR CREW WITH",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"MISDIRECTED HEROICS THOUGH.",local_delay,1); text_y+=9;
    Await_Exit_Request(350);
    Load_Radio_Box(0);
  }
  else if(_message[3]){
    _message[3]--;
    Load_Radio_Box(1);
    Blit_String(36,text_y,122,"ORBITAL, COME IN",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"OUR SENSORS SHOW UNUSUALLY",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"HIGH LEVELS OF IONIZATION",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"CAN YOU RUN REMOTE DIAGNOSTICS?",local_delay,1); text_y+=9;
    text_y+=8; 
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"OK, SYSTEMS CHECK IN PROGRESS",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"SYSTEMS GREEN ACROSS THE BOARD",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"YOUR SENSORS ARE OPERATING",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"WITHIN ACCEPTABLE PARAMETERS.",local_delay,1); text_y+=9;
    Await_Exit_Request(350);
    Load_Radio_Box(0);
  }
  else if(_message[4]){
    _message[4]--;
    Load_Radio_Box(1);
    Blit_String(36,text_y,122,"ORBITAL, COME IN",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"SCANNING GRAVITON EMISSIONS",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"IN THE UPPER BAND...",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"CAN YOU CONFIRM THESE READINGS?",local_delay,1); text_y+=9;
    text_y+=8; if (local_delay) Delay(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"READINGS CONFIRMED COMMANDER",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"THAT GRAVITY IS NOT SATURN'S..",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Delay(local_delay*20);
    Blit_String(36,text_y,169,"AND TITAN IS ORBITTING ON THE",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"FAR SIDE OF SATURN CURRENTLY..",local_delay,1); text_y+=9;
    Await_Exit_Request(350);
    Load_Radio_Box(0);
  }
  else if(_message[5]){
    _message[5]--;
    Load_Radio_Box(1);
    Blit_String(36,text_y,122,"ORBITAL, COME IN",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"WE'RE SCANNING PHASED VARIANCE!",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"SOMETHING HAS TO BE WRONG WITH",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"THESE SENSORS, ARE YOU READING",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"ANY KIND OF LOCAL DISTURBANCE?",local_delay,1); text_y+=9;
    text_y+=8; 
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"YES, OFF THE SCALE..  THIS MOON",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"IS FALLING INTO SATURNS GRAVITY",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"WELL ... NOT SURE WHY THOUGH.",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"ORBITAL VELOCITY DOESN'T",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"APPEAR TO HAVE SLOWED ANY.",local_delay,1); text_y+=9;
    Await_Exit_Request(350);
    Load_Radio_Box(0);
  }
  else if(_message[6]){
    _message[6]--;
    Load_Radio_Box(1);
    Blit_String(36,text_y,122,"ORBITAL, COME IN",local_delay,1); text_y+=9;
    if (local_delay) Await_Exit_Request(local_delay*30);
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"GRAVITATION IS.. SHIFTING ?!",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"A ROCK CAN'T GO NOVA!  WHAT",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"ASIDE FROM A SINGULARITY COULD",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,122,"CAUSE A GRAVITATIONAL SHIFT..?",local_delay,1); text_y+=9;
    text_y+=8; 
    if (local_delay) Await_Exit_Request(local_delay*30); 
    Blit_String(36,text_y,169,"NO KNOWN PHENOMENON..",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"BUT SOMEHOW THE GRAVITATIONAL",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"PULL HAS INCREASED. OUR NUMBERS",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"NOW INDICATE THAT MOON IS",local_delay,1); text_y+=9;
    local_delay=Check_For_Input(local_delay);
    Blit_String(36,text_y,169,"GOING TO CRASH INTO SATURN!",local_delay,1); text_y+=9;
    Await_Exit_Request(350);
    Load_Radio_Box(0);
  }
} // end display message
/////////////////////////////////////////////////////////////////////////////


int Check_For_Input(int local_delay){
  // word of warning- an error was occuring in calling this function
  // because I wanted to have a slightly longer delay during different
  // lines of dialog to provide a realistic pause between the dialog.
  // But I was calling this function with the parameter (local_delay*30)
  // then in this function any changes to local_delay get returned
  // to the calling function.  Well the change in this case was that
  // we increased local_delay to local_delay*30 right at the call.  It
  // was causing the text to appear one character at a time, very slowly.

	if(controller==2) Joystick_Driver();
	if(controller==1 && keystroke) local_delay=0;
  if((controller==2)&&(joy_table[5]||joy_table[6])) local_delay=0;
	return local_delay;
}           
/////////////////////////////////////////////////////////////////////////////


void  Load_Radio_Box(int option){
  switch(option){
    case 0:
      //remove box
      start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
      Delay(2); Melt_to_Buffer(double_buffer, 0,1); Delay(5);
      break;
    case 1:
      // put box on screen, after loading character
      // load guy or girl based on gender of pilot
      if (gender==1) {strcpy(graphics_file_name,"H2024");} // load girl
      else {strcpy(graphics_file_name,"H2026");} // load guy
      if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
      start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
      Delay(2); Melt_to_Buffer(background_pcx.buffer, 1,1); Delay(30);
      // load the radio box
      strcpy(graphics_file_name,"H2016");
      if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
      start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
      Sheer(background_pcx.buffer,1,2);  //1
      break;
    case 2:
      // just overlay the empty radio box
      // load the radio box
      strcpy(graphics_file_name,"H2016");
      if (!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
      start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
      Sheer(background_pcx.buffer,1,2);  //1
      break;
    default:
      break;
  }
  return;
}
/////////////////////////////////////////////////////////////////////////////


void  Await_Exit_Request(int counter){
  extern unsigned char
    keystroke,
    joy_table[7];

  while (keystroke) {}    // clear any existing keystrokes before starting
  keystroke=0; joy_table[5]=0; joy_table[6]=0;    // clear vars also

  while(counter>0){
    counter--;
    Delay(1);
    if(controller==2) Joystick_Driver();
    if(controller==1 && keystroke) counter=0;
    if((controller==2)&&(joy_table[5]||joy_table[6])) counter=0;
  }
  return;
}
/////////////////////////////////////////////////////////////////////////////
 

void Handle_Pause(void){
  int
    pal_reg=0,
    index=0,
    done=0;
  RGB_color   
    color,
    temp_palette[256];

  Delay(5);  // pause to give effect of inertia of mechanism halting the game

  // stuff the palette with the contents of the double buffer registers
  for (pal_reg=0; pal_reg<256; pal_reg++){
    Get_Palette_Register(pal_reg,(RGB_color_ptr)&color);
    temp_palette[pal_reg].red=color.red;
    temp_palette[pal_reg].green=color.green;
    temp_palette[pal_reg].blue=color.blue;
  }

  // fade down slightly
  for (index=0; index<10; index++){
    Wait_For_Vsync();
    for (pal_reg=0; pal_reg<256; pal_reg++){  
      Get_Palette_Register(pal_reg,(RGB_color_ptr)&color);
      if(color.red>0) color.red-=1;
      else color.red = 0;
      if(color.green>0) color.green-=1;
      else color.green = 0;
      if(color.blue>0) color.blue-=1;
      else color.blue = 0;
      Set_Palette_Register(pal_reg,(RGB_color_ptr)&color);
    }
    Delay(1);
  }

  // shut down the sounds playing      
  if (sound_available==1){
    for (index=0; index<21; index++){
      if (sound_playing(index)) stop_sound(index);
    }
  }

  // make a box to put "paused" over
  V_Line(92,105,120,169);
  for (index=121; index<204; index++){
    V_Line(92,92,index,169);
    V_Line(93,104,index,168);
    V_Line(105,105,index,167);
  }
  V_Line(92,105,204,167);
  Show_Double_Buffer(double_buffer);
  Blit_String(140,95,159,"PAUSED",0,2);

  // need to wait until pause key is pressed again
  done=0; key_table[12]=0; //INDEX_P
  while(!done){
    if(key_table[12]) done=1; //INDEX_P
    if(controller==2) if (Buttons_Bios(0x20)) done=1;
  }

  // fade back up (I need a copy of the palette)
  for(index=0; index<10; index++){
    Wait_For_Vsync();
    for(pal_reg=0; pal_reg<256; pal_reg++){
      Get_Palette_Register(pal_reg,(RGB_color_ptr)&color);
      if(color.red<temp_palette[pal_reg].red) color.red+=1;
      else color.red=temp_palette[pal_reg].red;
      if(color.green<temp_palette[pal_reg].green) color.green+=1;
      else color.green=temp_palette[pal_reg].green;
      if(color.blue<temp_palette[pal_reg].blue) color.blue+=1;
      else color.blue=temp_palette[pal_reg].blue;
      Set_Palette_Register(pal_reg,(RGB_color_ptr)&color);
    }
    Delay(1);
  }
  key_table[12]=0;  // reset the pause request key (INDEX_P)
  key_table[9]=0; imenu=0; // prevents odd appearance of main menu (INDEX_ESC)
  ipause=0;   
  return;
} // end handle pause
/////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////
/*
	// Joystick Driver Library
	// Filename: JOYSTICK.C (and JOYSTICK.H if in existence)
  // UPDATE Hyp_Ver IN GLOBALS EACH TIME SOMETHING IS CHANGED
	// Program by Thomas Ballard (based on functions by Andre LaMothe)
	// Copyright 1997, 1998   E.S.Q. Software
	// All Rights Reserved
*/
//////////////////////////////////////////////////////////////////////


unsigned char Buttons(unsigned char button){  
  // read the joystick buttons by peeking the port 
  // that the switches are attached to.
  outp(0x201,0); // clear the latch and request a sample

  // invert buttons then mask with request
  return( ~inp(0x201) & button);
}
/////////////////////////////////////////////////////////////////////////////


unsigned int Joystick_Bios(unsigned char stick){
  union REGS inregs,outregs;

  inregs.h.ah = 0x84; // joystick function 84h
  inregs.x.dx = 0x01; // read joysticks subfunction 1h

  // call dos
  int86(0x15, &inregs, &outregs);
  // return proper value depending on sent command
  switch(stick){
    case 0x01: return(outregs.x.ax);
    case 0x02: return(outregs.x.bx);
    default:break;
  }
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


unsigned char Buttons_Bios(unsigned char button){
  union REGS inregs,outregs;

  inregs.h.ah = 0x84; // joystick function 84h
  inregs.x.dx = 0x00; // read buttons subfunction 0h

  // call dos
  int86(0x15, &inregs, &outregs);
  // invert buttons then mask with request
  return( (~outregs.h.al) & button);
}
/////////////////////////////////////////////////////////////////////////////


int Joystick_Calibrate_Method1(void){  
  union REGS inregs,outregs;
  unsigned int 
    x_new_1, 
    y_new_1,
    x_new_2,
    y_new_2; // temp joystick positions

  int   
    text_y   = 47;

  inregs.h.ah = 0x84; // joystick function 84h
  inregs.x.dx = 0x01; // read joysticks subfunction 1h

  // set vars so that we can find there actual values
  Blit_String(37,text_y,122,"CALIBRATING JOYSTICK",1,1); text_y+=9;
  text_y+=9;

  while(Buttons(0x10 | 0x20)){
    delay(10);
  }
  Blit_String(37,text_y,122,"CENTER JOYSTICK AND PRESS FIRE",1,1); text_y+=9;
  while(!Buttons(0x10 | 0x20)){
    if(key_table[9]==1){
      key_table[9]=0; 
      return 0;
    }
    int86(0x15, &inregs, &outregs);
  }
  x_new_1 = outregs.x.ax;
  y_new_1 = outregs.x.bx;

  while(Buttons(0x10 | 0x20)){
    delay(10);
  }
  Blit_String(37,text_y,122,"MOVE TO UPPER/LEFT AND FIRE",1,1); text_y+=9;
  while(!Buttons(0x10 | 0x20)){
    if(key_table[9]==1){
      key_table[9]=0; 
      return 0;
    }
    int86(0x15, &inregs, &outregs);
  }
  joy_1_min_x = outregs.x.ax;
  joy_1_min_y = outregs.x.bx;

  while(Buttons(0x10 | 0x20)){
    delay(10);
  }
  Blit_String(37,text_y,122,"MOVE TO LOWER/RIGHT AND FIRE",1,1); text_y+=9;
  while(!Buttons(0x10 | 0x20)){
    if (key_table[9]==1){
      key_table[9]=0; 
      return 0;
    }
    int86(0x15, &inregs, &outregs);
  }
  joy_1_max_x = outregs.x.ax;
  joy_1_max_y = outregs.x.bx;

  while(Buttons(0x10 | 0x20)){
    delay(10);
  }
  Blit_String(37,text_y,122,"CENTER JOYSTICK AND PRESS FIRE",1,1); text_y+=9;
  while(!Buttons(0x10 | 0x20)){
    if(key_table[9]==1){
      key_table[9]=0; 
      return 0;
    }
    int86(0x15, &inregs, &outregs);
  }
  x_new_2 = outregs.x.ax;
  y_new_2 = outregs.x.bx;

  if((abs(x_new_1-x_new_2)>30)||(abs(y_new_1-y_new_2)>20)){
    joy_1_cx = (joy_1_min_x+((joy_1_max_x-joy_1_min_x)/2));
    joy_1_cy = (joy_1_min_y+((joy_1_max_y-joy_1_min_y)/2));
    text_y+=9;
    Blit_String(37,text_y,122,"THE RESULTS VARIED AND MAY NOT",1,1); text_y+=9;
    Blit_String(37,text_y,122,"BE RELIABLE (RETRY RECOMMENDED)",1,1); text_y+=9;
    while(!Buttons(0x10 | 0x20)){}
  }
  else{
    joy_1_cx = (x_new_1+x_new_2)/2;
    joy_1_cy = (y_new_1+y_new_2)/2;
    text_y+=9;
    Blit_String(37,text_y,122,"CALIBRATION IS COMPLETE",1,1); text_y+=9;
    while(!Buttons(0x10 | 0x20)){}
  }
  return 1;
} // end joystick calibrate method1
/////////////////////////////////////////////////////////////////////////////


int Joystick_Available(int stick_num){
  // test if the joystick is plugged in that the user is requesting tested
  if(stick_num == 0x01){
    // test if joystick 1 is plugged in by testing the port values
    // they will be 0,0 if there is no stick
    return(Joystick_Bios(0x01)+Joystick_Bios(0x02));
  } // end if joystick 1
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////
/*
	// Text and Graphics Character Display Functions
	// Filename: GRAPH3.C (and GRAPH3.H if in existence)
    // UPDATE Hyp_Ver IN GLOBALS EACH TIME SOMETHING IS CHANGED
	// Program by Thomas Ballard (based on Graph3.C by Andre LaMothe)
	// Copyright 1997, 1998   E.S.Q. Software
	// All Rights Reserved
*/
//////////////////////////////////////////////////////////////////////


void Blit_Char( int xc, int yc, char c, int color, int sound, int scheme, int where){
  // trans_flag
  //      0= cover the background regardless of its color with
  //          any part of the character that shows, spacing is
  //          still transparent, showing the background through
  //      1= this is for the effect where the character is not
  //          supposed to show through certain colors, for example
  //          in Hyper2 the psuedo dialog display has some dust on
  //          it and some cracks, when the character crosses one of
  //          these items, the character is NOT blitted over the top
  //          of the background, allowing the appearance of the character
  //          disappearing behind the obstruction.
  // scheme
  //      0= flat character, no color scheme
  //      1= camoflage effect randomly placing color+1 in blitted char
  //      2= horizontal lines descending a color on each line

  int
    //            screen_color   = 0,
    temp_color     = 0,
    offset         = 0,
    x              = 0,
    y              = 0,
    index          = 0;
  char far 
    *work_char;
  unsigned char 
    bit_mask       = 0x80;

  work_char=(char far *)0xF000FA6EL+c*8; // starting offset in char set
  offset=(yc<<8)+(yc<<6)+xc;  // offset character in video buffer

  for(y=0; y<8; y++){
    if(scheme==2) temp_color=color-(y*2);
    bit_mask = 0x80;
    for(x=0; x<8; x++){
      if(scheme==1){   // handle a scheme to do camo coloring
        if(!index)     {index=(rand()%10)-5; temp_color=color;}
        if(index<1)    {index--; temp_color=color+2;}
        if(index<-10)  index=0;
      }
      if(scheme==0) temp_color=color;    // flat characters
      if ((*work_char & bit_mask)){
        if(temp_color>0)
        if(!where) video_buffer[offset+x]=temp_color;
        if(where) double_buffer[offset+x]=temp_color;
      }
      bit_mask=(bit_mask>>1);
    }
    // move to next line in video buffer and in rom character data area
    offset+=320;
    work_char++;
  }
  if (sound) start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
}
/////////////////////////////////////////////////////////////////////////////


void Blit_String(int x,int y,int color,char *string,int speed,int scheme){  
  // this function blits an entire string on the screen with fixed spacing
  // between each character.  it calls blit_char.

  int 
    index       = 0,
    sound       = 0;

  if (speed>0) sound=1;
  if (scheme==0) scheme=0; // prevents compiler warning
  for (index=0; string[index]!=0; index++){
    Blit_Char(x+(index<<3),y,string[index],color,sound,scheme,0);
    if(speed) Delay(speed);
  }
}
/////////////////////////////////////////////////////////////////////////////


void Blit_String_DB(int x,int y,int color,char *string/*,int trans_flag*/,int speed,int scheme){  
  // this function blits an entire string on the screen with fixed spacing
  // between each character.  it calls blit_char.

  int 
    index       = 0,
    sound       = 0;

  if(speed>0) sound=1;
  if(scheme==0) scheme=0; // prevents compiler warning
  for(index=0; string[index]!=0; index++){
    Blit_Char(x+(index<<3),y,string[index],color/*,trans_flag*/,sound,scheme,1);
    if(speed){
      Delay(speed);
    }
  }
}
/////////////////////////////////////////////////////////////////////////////


void Plot_Pixel_Fast(int x,int y,unsigned char color){
  video_buffer[((y<<8) + (y<<6)) + x] = color;
}
/////////////////////////////////////////////////////////////////////////////

                                                                            
void Close_Everything(void){
  if (igamedata)    Handle_Game_Data();
  if (iscreen)      Handle_Screen();
  if (ikeyboard)    Handle_Keyboard_Driver();
  if (ijoystick)    Handle_Joystick_Driver();
  if (ibuffer)      Handle_Buffer();
  if (isprites)     Handle_Sprite_Init(0);
  if (isound)       Handle_Sound_Driver();
  if (error_code>0) Handle_Error_Code();
  else if (icopyright) Handle_Copyright();
  exit(0);
}
/////////////////////////////////////////////////////////////////////////////


//Copy protection through obfuscation.... pretty pathetic, sorry, I must have been up too late. (disabled all this junk with the open release)
//int a(char *pointer, int option){
//    if (option) strcat(pointer,"17");
//    else strcat(pointer,"a");
//    return 1;
//}
/////////////////////////////////////////////////////////////////////////////


int e(char *pointer, int option){
  if (option==0) strcat(pointer,"e");
  if (option==1) strcat(pointer,"03");
  //if (option==2) temp2_hspd=123; //disable 03/28/02
  if (option==3) strcat(pointer,"d");
  if (option==4) strcat(pointer,"i");
  if (option==5) strcat(pointer,"r");
  if (option==6) strcat(pointer,"g");
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int h(char *pointer, int option){
  if(option){
    strcat(pointer,"98");
  //  if(option==2) temp1_hspd=114; //disabled 03/28/02
  }
  else strcat(pointer,"h");
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int s(char *pointer, int option){
  if(option){
    strcat(pointer,"01");
  //  if(option==2) temp1_hspd=115; //disabled 03/28/02
  }
  else strcat(pointer,"s");
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


int t(char *pointer, int option){
  if(option){
    strcat(pointer,"05");
    if(option==2){
      h(pointer,1);
    }
  }
  else strcat(pointer,"t");
  return 0;
}
/////////////////////////////////////////////////////////////////////////////


int w(char *pointer, int option){
  if(option){
    strcat(pointer,"21");
  //  if(option==2) temp2_hspd=107; //disabled 03/28/02
  }
  else strcat(pointer,"w");
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


int getinputstring(int text_x, int text_y){
  int         
    done=0,
    keystroke=0,
    mfield_keys=0;

  // NOTE entry conditions.  If a keyboard handler routine is running
  // then it needs to be disable prior to entry and reenabled after
  // after exitting this routine.  10/98

  strcpy(tstring,""); // this global string is required, (its reset on each entry)
  while(kbhit()){
    keystroke=getch();
  }
  while(!done){
    keystroke=Get_Ascii_Key(); 
    keystroke=toupper(keystroke);

    if (keystroke==27) done=1;
    if (keystroke==48) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"0"); Blit_String(text_x,text_y,159,"0",1,2); text_x+=9;}}
    if (keystroke==49) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"1"); Blit_String(text_x,text_y,159,"1",1,2); text_x+=9;}}
    if (keystroke==50) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"2"); Blit_String(text_x,text_y,159,"2",1,2); text_x+=9;}}
    if (keystroke==51) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"3"); Blit_String(text_x,text_y,159,"3",1,2); text_x+=9;}}
    if (keystroke==52) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"4"); Blit_String(text_x,text_y,159,"4",1,2); text_x+=9;}}
    if (keystroke==53) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"5"); Blit_String(text_x,text_y,159,"5",1,2); text_x+=9;}}
    if (keystroke==54) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"6"); Blit_String(text_x,text_y,159,"6",1,2); text_x+=9;}}
    if (keystroke==55) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"7"); Blit_String(text_x,text_y,159,"7",1,2); text_x+=9;}}
    if (keystroke==56) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"8"); Blit_String(text_x,text_y,159,"8",1,2); text_x+=9;}}
    if (keystroke==57) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"9"); Blit_String(text_x,text_y,159,"9",1,2); text_x+=9;}}
    if (keystroke==65) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"A"); Blit_String(text_x,text_y,159,"A",1,2); text_x+=9;}}
    if (keystroke==66) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"B"); Blit_String(text_x,text_y,159,"B",1,2); text_x+=9;}}
    if (keystroke==67) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"C"); Blit_String(text_x,text_y,159,"C",1,2); text_x+=9;}}
    if (keystroke==68) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"D"); Blit_String(text_x,text_y,159,"D",1,2); text_x+=9;}}
    if (keystroke==69) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"E"); Blit_String(text_x,text_y,159,"E",1,2); text_x+=9;}}
    if (keystroke==70) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"F"); Blit_String(text_x,text_y,159,"F",1,2); text_x+=9;}}
    if (keystroke==71) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"G"); Blit_String(text_x,text_y,159,"G",1,2); text_x+=9;}}
    if (keystroke==72) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"H"); Blit_String(text_x,text_y,159,"H",1,2); text_x+=9;}}
    if (keystroke==73) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"I"); Blit_String(text_x,text_y,159,"I",1,2); text_x+=9;}}
    if (keystroke==74) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"J"); Blit_String(text_x,text_y,159,"J",1,2); text_x+=9;}}
    if (keystroke==75) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"K"); Blit_String(text_x,text_y,159,"K",1,2); text_x+=9;}}
    if (keystroke==76) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"L"); Blit_String(text_x,text_y,159,"L",1,2); text_x+=9;}}
    if (keystroke==77) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"M"); Blit_String(text_x,text_y,159,"M",1,2); text_x+=9;}}
    if (keystroke==78) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"N"); Blit_String(text_x,text_y,159,"N",1,2); text_x+=9;}}
    if (keystroke==79) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"O"); Blit_String(text_x,text_y,159,"O",1,2); text_x+=9;}}
    if (keystroke==80) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"P"); Blit_String(text_x,text_y,159,"P",1,2); text_x+=9;}}
    if (keystroke==81) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"Q"); Blit_String(text_x,text_y,159,"Q",1,2); text_x+=9;}}
    if (keystroke==82) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"R"); Blit_String(text_x,text_y,159,"R",1,2); text_x+=9;}}
    if (keystroke==83) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"S"); Blit_String(text_x,text_y,159,"S",1,2); text_x+=9;}}
    if (keystroke==84) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"T"); Blit_String(text_x,text_y,159,"T",1,2); text_x+=9;}}
    if (keystroke==85) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"U"); Blit_String(text_x,text_y,159,"U",1,2); text_x+=9;}}
    if (keystroke==86) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"V"); Blit_String(text_x,text_y,159,"V",1,2); text_x+=9;}}
    if (keystroke==87) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"W"); Blit_String(text_x,text_y,159,"W",1,2); text_x+=9;}}
    if (keystroke==88) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"X"); Blit_String(text_x,text_y,159,"X",1,2); text_x+=9;}}
    if (keystroke==89) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"Y"); Blit_String(text_x,text_y,159,"Y",1,2); text_x+=9;}}
    if (keystroke==90) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"Z"); Blit_String(text_x,text_y,159,"Z",1,2); text_x+=9;}}
    if (keystroke==95) {if (mfield_keys<=19) {mfield_keys++; strcat(tstring,"_"); Blit_String(text_x,text_y,159,"_",1,2); text_x+=9;}}
    if (keystroke==13) {done=1;}
  }
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


int registration(void){
  unsigned char
    mfield_2[25],
    name1[30],
    name2[30],
    name3[30],
    name4[30];
    FILE    *fp;

  done=0;

  // GET WEBSITE URLS
  if ((fp=fopen("H2028","rt"))==NULL){
    if ((fp=fopen("H2029","rt"))==NULL){
      error_code=10; 
      strcpy(error_file_name,data_file_name); 
      Close_Everything();
    }
  }

  if (!feof(fp)) {fscanf(fp,"%s",&name1);}
  if (!feof(fp)) {fscanf(fp,"%s",&name2);}
  if (!feof(fp)) {fscanf(fp,"%s",&name3);}
  fclose(fp);

  // test to make sure at least one url contains our name, come on, we worked
  // our butts off on this damn thing, don't remove our name from the url list
  if ((strstr(name1,"esqsoft")==NULL)&&(strstr(name1,"ESQSOFT")==NULL)){
    if ((strstr(name2,"esqsoft")==NULL)&&(strstr(name2,"ESQSOFT")==NULL)){
      if ((strstr(name3,"esqsoft")==NULL)&&(strstr(name3,"ESQSOFT")==NULL)){
        error_code=12; 
        strcpy(error_file_name,data_file_name); 
        Close_Everything();
      }
    }
  }

  // load saturn background into double buffer
  strcpy(graphics_file_name,"H2003");
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=5; Close_Everything();} // error has occured
  _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
  Sheer(double_buffer,0,1);

  Load_Radio_Box(1);
  text_y=47;
  Blit_String(37,text_y,122,"TO REGISTER YOU WILL NEED",1,1); text_y+=9;
  Blit_String(37,text_y,122,"YOUR SPECIFIC REGISTRATION",1,1); text_y+=9;
  Blit_String(37,text_y,122,"CODE. YOU CAN GET IT BY MAIL",1,1); text_y+=9;
  Blit_String(37,text_y,122,"OR -MORE QUICKLY- BY VISITING",1,1); text_y+=9;
  Blit_String(37,text_y,122,"ONE OF THE FOLLOWING WEBSITES.",1,1); text_y+=9;
  text_y+=9;
  if(strlen(name1)>2){
    if(strlen(name1)>30){
      strcpy(name4,name1);
      for(index=0; index<30&&name1[index]!=0; index++){
        name1[index]=name4[index];
      }
      name1[index]=0; strcpy(name4,"");
    }   
    Blit_String(37,text_y,122,name1,1,1); text_y+=9;
  }
  if(strlen(name2)>2){
    if(strlen(name2)>30){
      strcpy(name4,name2);
      for(index=0; index<30&&name2[index]!=0; index++){
        name2[index]=name4[index];
      }
      name2[index]=0; strcpy(name4,"");
    }   
    Blit_String(37,text_y,122,name2,1,1); text_y+=9;
  }
  if(strlen(name3)>2){
    if(strlen(name3)>30){
      strcpy(name4,name3);
      for(index=0; index<30&&name3[index]!=0; index++){
        name3[index]=name4[index];
      }
      name3[index]=0; strcpy(name4,"");
    }    
    Blit_String(37,text_y,122,name3,1,1); text_y+=9;
  }

  text_y+=9;
  Blit_String(37,text_y,122,"DO YOU HAVE YOUR CODE? (Y/N)",1,1); text_y+=9;

  done=0;
  while(!done){
    if(controller==2){
      Clear_Joystick();
      Joystick_Driver();
    }
    if (key_table[10] || joy_table[5]) {done=1;} //INDEX_Y
    if (key_table[11] || joy_table[6]) {done=2;} //INDEX_N
  }
  done--;

  if (!done){
    Load_Radio_Box(2);
    text_y=47;
    Blit_String(37,text_y,122,"PLEASE ENTER YOUR REGISTRATION",1,1); text_y+=9;
    Blit_String(37,text_y,122,"CODE IN THE FIELD BELOW.",1,1); text_y+=9;text_y+=9;
    _fmemcpy((char far *)double_buffer,(char far *)(video_buffer),64000);

    V_Line(90,105,65,159);
    for(index=66; index<254; index++){
      V_Line(90,90,index,159);
      V_Line(91,104,index,156);
      V_Line(105,105,index,153);
    }
    V_Line(90,105,254,153);

    start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
    Sheer(double_buffer,0,1);

    if (ijoystick) Handle_Joystick_Driver();  // deallocate driver (if present)
    if (ikeyboard) Handle_Keyboard_Driver();  // deallocate driver (if present)      

    text_y=94; text_x=70;

    getinputstring(70,94);
    Delay(10);            

    if (!ikeyboard) Handle_Keyboard_Driver();
    if (!ijoystick) Handle_Joystick_Driver();

    strcpy(mfield_2,""); w(mfield_2,1); s(mfield_2,1); t(mfield_2,2); e(mfield_2,1);
    for (index=0; index<425; index++){                
      Fade_Modulate(156,1,1);
      Delay(1);
      done--;
      if (done<1){
        start_sound(sound_effect[SOUND_BLIT], SOUND_BLIT, 0, sound_available);
        done=70;
      }
    }
    Restore_Palette((pcx_picture_ptr)&background_pcx,1);
    done=0;            

    if (strnicmp(tstring,mfield_2,10)==0){
      strcpy(data_file_name,"H20H");
      Read_GameData_File();
      e(mfield_2,2); s(mfield_2,2); w(mfield_2,2);
      board_min_y=1;
      board_min_x=1;
      Handle_Extended_Memory(1);
      Load_Radio_Box(2);  //just clear the existing radio box
      text_y=47;
      Blit_String(37,text_y,122,"YOUR CODE VALIDATED.       ",1,1); text_y+=9;
      Blit_String(37,text_y,122,"YOUR COPY IS NOW REGISTERED.",1,1); text_y+=9;
      Blit_String(37,text_y,122,"(OUR FAMILIES THANK YOU!)   ",1,1); text_y+=9;
      Blit_String(37,text_y,122,"IMPORTANT INFORMATION IS    ",1,1); text_y+=9;
      Blit_String(37,text_y,122,"CONTAINED IN THE 'README.TXT'",1,1); text_y+=9;
      Blit_String(37,text_y,122,"FILE SO REMEMBER TO CHECK",1,1); text_y+=9;
      Blit_String(37,text_y,122,"IT AFTER YOU'RE DONE PLAYING.",1,1); text_y+=9;
      Blit_String(37,text_y,122,"GOOD LUCK ON COMPLETING",1,1); text_y+=9;
      Blit_String(37,text_y,122,"YOUR MISSION. SEE YOU AT",1,1); text_y+=9;
      Blit_String(37,text_y,122,"THE ORBITAL PLATFORM!",1,1); text_y+=9;

      done=0; keystroke=0;
      while(!done){
        done=keystroke;
        if(controller==2){
          if (Buttons_Bios(0x10)) done=1;
        }
      }
    }
    else{
      text_y=132;
      Blit_String(37,text_y,122,"THAT CODE DOES NOT VALIDATE.",1,1); text_y+=9;
      Blit_String(37,text_y,122,"PLEASE CHECK YOUR CODE.",1,1); text_y+=9;text_y+=9;
      done=0; keystroke=0;
      while(!done){
        done=keystroke;
        if (controller==2){
          if (Buttons_Bios(0x10)) done=1;
        }
      }
    }
  }
  //       Load_Radio_Box(0);
  done=0;
  return 1;
}
/////////////////////////////////////////////////////////////////////////////


void Handle_Wrecked_Facility(void){
  int
    duration,
    index;

  //change the screen to h2020
  strcpy(graphics_file_name,"H2020");
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)){error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  Restore_Palette((pcx_picture_ptr)&background_pcx,1);
  _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);

  //load guy or girl based on pilot gender
  if(gender==1){strcpy(graphics_file_name,"H2024");} // load girl
  else {strcpy(graphics_file_name,"H2026");} // load guy
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  TransparentTransfer(background_pcx.buffer,double_buffer);
  start_sound(sound_effect[SOUND_GRAPH3], SOUND_GRAPH3, 0, sound_available);
  Delay(2); Melt_to_Buffer(double_buffer, 0,1); Delay(50);

  //overlay screen h2021 text
  strcpy(graphics_file_name,"H2021");
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);
  start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
  Delay(2); Melt_to_Buffer(double_buffer, 1,1);
  Await_Exit_Request(1000); // loop or keypress

  //change the screen to h2020
  strcpy(graphics_file_name,"H2020");
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  Restore_Palette((pcx_picture_ptr)&background_pcx,1);
  _fmemcpy((char far *)double_buffer,(char far *)(background_pcx.buffer),64000);

  //load guy or girl based on pilot gender
  if(gender==1) {strcpy(graphics_file_name,"H2024");} // load girl
  else {strcpy(graphics_file_name,"H2026");} // load guy
  if(!Graphic_Load(graphics_file_name, (pcx_picture_ptr)&background_pcx)) {error_code=9; strcpy(error_file_name,graphics_file_name); Close_Everything();}
  TransparentTransfer(background_pcx.buffer,double_buffer);
  start_sound(sound_effect[SOUND_FADE], SOUND_FADE, 0, sound_available);
  Delay(2); Melt_to_Buffer(double_buffer, 0,1);

  //return to screen and close lander
  _fmemcpy((char far *)double_buffer,(char far *)(back1_buffer),64000);
  //        textbox.state=0; Status_Box();
  curr_sprite=&lander; Draw_Sprite_Clipped_DB();
  Delay(2); Melt_to_Buffer(double_buffer, 0,1);
  return;
}
/////////////////////////////////////////////////////////////////////////////

 
void Game_Loop(void){
  igameplay=1;
    // this is used for a variety of reasons outside of this function
    // the primary reason though is to keep track of the Status_Box()
  ipause=0;
    // clear the any pause requests that we set prior to game play

  while(!error_code){  // quit/gameover error_code=-1
    if(ipause) Handle_Pause();
    // had problem where pause could be hit during the
    // explosion and cause a pause while screen was black
    // making it look like machine locked up. To resolve process
    // pause requests before anything else.

    // TESTING : fake the earth quake for testing
    // tally_shield=-1; // turn off collision 
    // if(!sound_playing(SOUND_EARTH)) start_sound(sound_effect[SOUND_EARTH], SOUND_EARTH, 0, sound_available);
    // END TESTING

    // handle the message counter and display message 
    message_counter++; // used for maxout on message displays.
    if(message_counter>show_message_now){
      message_counter=0;
      if(show_messages){ // messages on/off set using "show_messages"
        //Transfer_Buffer(back1_buffer, double_buffer);                        
        Display_Message(message);
        message=0;
        //textbox.state=0; Status_Box();   // restore statsbox
      }
    }
    // end handle the message counter and display message 

    Update_Variables(); 
    if(error_code) break; // Problem was happening during return from Handle_Win... was getting the status box drawn again.

    //lander.x_earth=lander.x; lander.y_earth=lander.y;
    // set these in case earth quake moved them
    Handle_Earth_Quake();
    // this also puts a background into the double
    // buffer where we're working
    Handle_Draw();

    Handle_Display();
    //lander.x=lander.x_earth; lander.y=lander.y_earth; //1/3/00
    // restore these in case earth quake moved them

    if(sound_available){
      if(board_x==7 && board_y==9) start_sound(sound_effect[SOUND_ALARM], SOUND_ALARM, 0, sound_available);
      if(!sound_playing(SOUND_EARTH)){
        last_earth_quake++;
        if(last_earth_quake>100){
          last_earth_quake=0;
          index=(rand()%20)-18;
          if(index>0) start_sound(sound_effect[SOUND_EARTH], SOUND_EARTH, 0, sound_available);
        }
      }
    }
    // end display the double buffer on screen ///////////////////

    // time consumers while ship is on screen ////////////////////            
    if (collision) Check_Collision(); 
    Check_Controller_Input();

    // handle random sounds at random intervals for personality
    if(sound_available){
      index=(rand()%7000)-6995;
      if(index>0){
        if((!sound_playing(SOUND_REVFADE2))&&
          (!sound_playing(SOUND_EARTH))&&
          (!sound_playing(SOUND_WIND)))
          start_sound(sound_effect[SOUND_REVFADE2], SOUND_REVFADE2, 0, sound_available);
      }
    }
    // end handle random sounds at random intervals for personality

    // if out of fuel display message
    if(fuel<=0){
      message_counter=show_message_now-50;
      message=7;
      start_sound(sound_effect[SOUND_BDING], SOUND_BDING, 0, sound_available);
    }

    // continually restore shield if difficulty level is low
    if(gender==0){
      if((shield+.25)<38.5) shield+=.005;
    }

    if(imenu==-1){
      // process main_menu requests if any exist
      screen_show_index=screen_show; Handle_Display();
      Handle_Main_Menu(); if (!igameplay) igameplay=1;
    }

    // end time consumers while ship is on screen ////////////////
  }
  igameplay=0;
  return;
} // end game play loop
/////////////////////////////////////////////////////////////////////////////


void Close_Ship(void){
  int index;

  Delay(20);

  // shut off the keyboard routine momentarily
  if (ikeyboard) Handle_Keyboard_Driver();  // deallocate driver (if present)

  start_sound(sound_effect[SOUND_GEAR], SOUND_GEAR, 0, sound_available);
  index=24;
  while(index>16){
    lander.curr_frame=index;
    if(index==17) lander.curr_frame=1;
    lander.x_earth=lander.x; lander.y_earth=lander.y;  // set these in case earth quake moved them
    screen_show_index=screen_show; Handle_Earth_Quake();
    curr_sprite=&lander; Draw_Sprite_Clipped_DB();

    lander.x=lander.x_earth; lander.y=lander.y_earth;  // set these in case earth quake moved them
    screen_show_index=screen_show; Handle_Display();
    Handle_Game_Speed(1);
    index--;
  }

  // re-enable keyboard routine
  if(!ikeyboard) Handle_Keyboard_Driver();  // allocate driver
} // end close ship
/////////////////////////////////////////////////////////////////////////////


void Open_Ship(void){
  int
    duration,
    played_gear,
    index;

  // disable keyboard routine
  if(ikeyboard) Handle_Keyboard_Driver();

  duration=30; index=0; lander.state=0; // landed
  while(index<duration){
    // set the animation frame
    if(index==10){
      if(!sound_playing(SOUND_EARTH)) start_sound(sound_effect[SOUND_EARTH],SOUND_EARTH,0, sound_available);
    }
    if(index==(duration-12)){
      lander.curr_frame=19; 
      if(!played_gear){
        played_gear++; 
        start_sound(sound_effect[SOUND_GEAR], SOUND_GEAR, 0, sound_available);
      }
    }
    if(index>(duration-12)){
      if(lander.curr_frame<24){
        lander.curr_frame++;
      }
    }
    index++;
    screen_show_index=screen_show;
    lander.x_earth=lander.x; lander.y_earth=lander.y;  // set these in case earth quake moved them
    shake_screen=1990; Handle_Earth_Quake();
    curr_sprite=&lander; Draw_Sprite_Clipped_DB();
    lander.x=lander.x_earth; lander.y=lander.y_earth;  // set these in case earth quake moved them
    Handle_Display();
    Handle_Game_Speed(1);
  }

  if (!ikeyboard) Handle_Keyboard_Driver();  // allocate driver
} // end open ship
/////////////////////////////////////////////////////////////////////////////


//void main(int argc, char *argv[])
void main(void){
  // if (argc) {}

  // initialize everything
  Handle_Extended_Memory(0);  // initialize memory
  if (!icopyright)    Handle_Copyright();         // display intro text
  if (!ibuffer)       Handle_Buffer();            // initialize buffer
  if (!ijoystick)     Handle_Joystick_Driver();   // initialize joystick
  if (!ikeyboard)     Handle_Keyboard_Driver();   // initialize keyboard
  if (!isprites)      Handle_Sprite_Init(0);      // initialize sprites
  if (!isound)        Handle_Sound_Driver();      // initialize sounds
  if (!iscreen)       Handle_Screen();            // initialize screen

  while(!error_code){ // this loop is for intro/ending
    while((!igamedata)&&(!error_code)){
      Handle_Intro();
      if(imenu==-1) Handle_Main_Menu();
    }

    if(!error_code) Game_Loop();

    if(error_code<0){  
      if(error_code==-2) Handle_Ending(); //EXIT_TO_DOS
      else error_code=0;
    }

    if(igamedata) Handle_Game_Data();  // deallocate driver (if present)
  }
  if(error_code==101) error_code=0; // reset the quit condition to prevent an error from listing
  Close_Everything();   
}
/////////////////////////////////////////////////////////////////////////////