port.c

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 2005 Michael K. McCarty & Fritz Bronner
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU General Public License as published by
00006     the Free Software Foundation; either version 2 of the License, or
00007     (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017 */
00018 // Interplay's BUZZ ALDRIN's RACE into SPACE
00019 //
00020 // Formerly -=> LiftOff : Race to the Moon :: IBM version MCGA
00021 // Copyright 1991 by Strategic Visions, Inc.
00022 // Designed by Fritz Bronner
00023 // Programmed by Michael K McCarty
00024 //
00025 
00026 #include "gamedata.h"
00027 #include "Buzz_inc.h"
00028 #include "externs.h"
00029 #include "macros.h"
00030 #include "av.h"
00031 #include "utils.h"
00032 
00033 #define LET_A   0x09
00034 #define LET_M   0x0A
00035 #define LET_O   0x0B
00036 #define LET_V   0x0C
00037 #define LET_R   0x08
00038 
00039 #define SPOT_ON 1 /**< turn off until everything else works - pace */
00040 #define BABYSND 1
00041 #define pNOREDRAW 0
00042 #define pREDRAW 1
00043 #define pEXIT 2
00044 #define pQUIT 3
00045 #define pNOFADE 4
00046 #define pNEWMUSIC 5
00047 
00048 int put_serial(unsigned char n);
00049 
00050 char RUSH,SUSPEND;
00051 extern int oldx,oldy;
00052 extern struct mStr Mis;
00053 extern char Option;
00054 
00055 typedef struct portoutlinerestore {
00056    ui16 loc;
00057    char val;
00058 } PORTOUTLINE;
00059 
00060 PORTOUTLINE *pPortOutlineRestore;
00061 
00062 struct FHead {
00063   char Text[28];  /**< File Copyright Notice */
00064   long oMObj;     /**< Offset to MObj data table */
00065   long oTab;      /**< Offset to Table of data */
00066   long oPal;      /**< Offset to Palette */
00067   long oPort;     /**< Offset to start of Port Images */
00068   long oMse;      /**< Offset to Mouse Objects */
00069   long oOut;      /**< Offset to port Outlines */
00070   long oAnim;     /**< Offset to start of Port Anims */
00071    } PHead;
00072 
00073 typedef struct cBoxx {
00074    i16 x1,y1,x2,y2;
00075    } BOUND;
00076 
00077 typedef struct Img {
00078   long Size;         /**<  Size of Image (bytes) */
00079   char Comp;         /**<  Type of Compression Used */
00080   i16 Width;         /**<  Width of Image */
00081   i16 Height;        /**<  Height of Image */
00082   i16 PlaceX;        /**<  Where to Place Img:X */
00083   i16 PlaceY;        /**<  Where to Place Img:Y */
00084    } IMG;
00085 
00086 typedef struct region {
00087   char qty;          /**< number of BOUNDS */
00088   BOUND CD[4];       /**< boundry coords for mouse location */
00089   char iNum;         
00090   char sNum;         /**< value for surround box */
00091   char PreDraw;      /**< Code of Special to Draw first */
00092    } REGION;
00093 
00094 
00095 typedef struct mobj {
00096   char Name[30];       /**< Name of region */
00097   char qty;            /**< Nunber of regions */
00098   char Help[3];        /**< Help Box Stuff */
00099   REGION Reg[4];       /**< At Max 4 regions */
00100    } MOBJ;
00101 
00102 #define S_QTY 43
00103 
00104 MOBJ MObj[35];
00105 
00106 /** These are the valid hotkeys */
00107 char HotKeyList[]="AIMRPVCQETB\0";
00108 
00109 int FCtr;
00110 GXHEADER flaggy;
00111 
00112 #define SPOTS 100
00113 
00114 /** SPOT structures and data structure variables */
00115 struct mSPOT {        // Main SPOT Header
00116   uint8_t ID[40];     /**< Copyright notice */
00117   uint8_t Qty;        /**< Number of Paths */
00118   uint32_t sOff;      /**< Spot Offsets */
00119   uint32_t pOff;      /**< Path Offsets */
00120 } MSPOT;
00121 
00122 struct sPATH {       // Spot Anim Path Struct
00123   uint16_t Image;        // Which image to Use
00124   int16_t  xPut,yPut;    // Where to place this image
00125   int16_t iHold;         // Repeat this # times
00126   float Scale;       // Scale object
00127 };
00128 
00129 struct sIMG {
00130   uint8_t w,h;    // Width and Height
00131 };
00132 
00133 
00134 
00135 int16_t sCount,Vab_Spot;        // sCount is the number of steps
00136 FILE *sFin;
00137 SimpleHdr hSPOT;  // Filled by Seek_sOff();
00138 struct sPATH sPath,sPathOld;
00139 struct sIMG sImg,sImgOld;
00140 uint32_t pTable,pLoc;
00141 
00142  
00143 void
00144 Seek_sOff(int where)
00145 {
00146     fseek(sFin, where * sizeof_SimpleHdr + MSPOT.sOff, SEEK_SET);
00147     fread_SimpleHdr(&hSPOT, 1, sFin);
00148     fseek(sFin, hSPOT.offset, SEEK_SET);
00149 }
00150 
00151 void Seek_pOff(int where)
00152 {
00153   fseek(sFin,where*(sizeof pTable)+(MSPOT.pOff),SEEK_SET);
00154   fread(&pTable,sizeof pTable,1,sFin);
00155     Swap32bit(pTable);
00156   fseek(sFin,pTable,SEEK_SET);
00157 }
00158 
00159 
00160 char PName[20];
00161 
00162 #define SPOT_LOAD 0
00163 #define SPOT_STEP 1
00164 #define SPOT_DONE 2
00165 #define SPOT_KILL 3
00166 
00167 void SpotCrap(char loc,char mode)
00168 {
00169   GXHEADER SP1,SP2,SP3;
00170   int w,h,i;
00171   int xx;
00172   static char turnoff=0;
00173 
00174    if (SUSPEND==1) {
00175      if (turnoff==1) StopVoice();  //Specs: suspend sound babypics 
00176      return;
00177     }
00178 
00179    if (sCount==-1  && mode!=SPOT_LOAD) return;
00180 
00181    if (mode==SPOT_LOAD) {   // Open File
00182       sFin=sOpen("SPOTS.CDR","rb",0);
00183       fread(&MSPOT,sizeof MSPOT,1,sFin);    // Read Header
00184             Swap32bit(MSPOT.sOff);
00185             Swap32bit(MSPOT.pOff);
00186 
00187       Seek_pOff(loc);  // go to correct path
00188       fread(&PName,sizeof PName,1,sFin);
00189       fread(&sCount,sizeof sCount,1,sFin);  // get number of paths parts
00190             Swap16bit(sCount);
00191       pLoc=ftell(sFin);
00192       sPath.iHold=1;
00193       memcpy(vhptr.vptr,screen,MAX_X*MAX_Y);
00194       sPathOld.xPut=-1;
00195       SpotCrap(0,SPOT_STEP);
00196       // All opened up
00197    }
00198    else if (mode==SPOT_STEP && sPath.iHold==1 && sCount>0) {  // Play Next Seq
00199       fseek(sFin,pLoc,SEEK_SET);       // position at next path
00200       fread(&sPath,sizeof(sPath),1,sFin);  // get the next sPath struct
00201             
00202             Swap16bit(sPath.Image);
00203             Swap16bit(sPath.xPut);
00204             Swap16bit(sPath.yPut);
00205             Swap16bit(sPath.iHold);
00206             
00207 #ifdef __BIG_ENDIAN__
00208             xx = *(ui32*)(&sPath.Scale);    
00209             Swap32bit(xx);
00210             *((ui32*) &sPath.Scale) = xx;
00211 #endif
00212 
00213       pLoc=ftell(sFin);                 // Path Update Locations
00214 
00215       Seek_sOff(sPath.Image);          // point to next image
00216       fread(&sImg,sizeof sImg,1,sFin);    // get image header
00217 
00218       {
00219           int expected_w = hSPOT.size / sImg.h;
00220           /* DEBUG - FIXING sImg.w */
00221           if (sImg.w != expected_w) {
00222               sImg.w = expected_w;
00223           }
00224       }
00225 
00226       sImg.w = hSPOT.size / sImg.h;
00227       GV(&SP1,sImg.w,sImg.h);          // create Virtual buffer
00228       fread(SP1.vptr,hSPOT.size,1,sFin);  // read image data
00229 
00230 
00231       if (sPath.Scale!=1.0) {
00232           w=(int) ((float) sImg.w * sPath.Scale);
00233           h=(int) ((float) sImg.h * sPath.Scale);
00234         sImg.w=w;
00235         sImg.h=h;
00236         gxVirtualScale(&SP1,&SP2);
00237       }
00238 
00239       GV(&SP3,sImg.w,sImg.h);  // background buffer
00240 
00241       gxVirtualVirtual(&vhptr,
00242               minn(sPath.xPut, 319),
00243               minn(sPath.yPut, 199),
00244               minn(sPath.xPut+sImg.w-1, 319),
00245               minn(sPath.yPut+sImg.h-1, 199),
00246               &SP3,0,0,0);
00247 
00248       if (sPath.Scale!=1.0) {
00249         xx=hSPOT.size;
00250         for (i=0;i<xx;i++) {
00251            if (SP2.vptr[i]==0) SP2.vptr[i]=SP3.vptr[i];
00252         }
00253         if (sPathOld.xPut!=-1) gxVirtualDisplay(&vhptr,sPathOld.xPut,sPathOld.yPut,sPathOld.xPut,sPathOld.yPut,sPathOld.xPut+sImgOld.w-1,sPathOld.yPut+sImgOld.h-1,0);
00254         gxPutImage(&SP2,gxSET,sPath.xPut,sPath.yPut,0);
00255       }
00256       else {
00257         xx=hSPOT.size;
00258         for (i=0;i<xx;i++) {
00259            if (SP1.vptr[i]==0) SP1.vptr[i]=SP3.vptr[i];
00260         }
00261         if (sPathOld.xPut!=-1)
00262             gxVirtualDisplay(&vhptr, sPathOld.xPut, sPathOld.yPut, sPathOld.xPut, sPathOld.yPut,
00263                     minn(sPathOld.xPut+sImgOld.w-1, 319),
00264                     minn(sPathOld.yPut+sImgOld.h-1, 199),
00265                     0);
00266         gxPutImage(&SP1,gxSET,
00267                 minn(sPath.xPut, 319),
00268                 minn(sPath.yPut, 199), 0);
00269       }
00270       sPathOld=sPath;
00271       sImgOld=sImg;
00272 
00273       DV(&SP3);DV(&SP1);
00274       if (sPath.Scale!=1.0) DV(&SP2);
00275       sCount--;
00276 
00277    }
00278    else if (mode==SPOT_STEP && sPath.iHold>1 && sCount>0) sPath.iHold--;
00279    else if (mode==SPOT_STEP && sPath.iHold==1 && sCount==0) {
00280       SpotCrap(0,SPOT_DONE);
00281    }
00282    else if ((mode==SPOT_DONE || sCount>=0) && sFin!=NULL) {  // Close damn thing down
00283        fclose(sFin);sFin=NULL;
00284        sPathOld.xPut=-1;
00285        sPath.iHold=0;
00286        sCount=-1;
00287      #if BABYSND
00288       if (turnoff==1) {StopAudio(0);turnoff=0;}
00289      #endif
00290    }
00291    else if (mode==SPOT_KILL && sFin!=NULL)
00292     {
00293      fclose(sFin);sFin=NULL;
00294    #if BABYSND
00295      if (turnoff==1) {StopAudio(0);turnoff=0;}
00296    #endif
00297     }
00298   #if BABYSND
00299    if ((loc>=0 && loc<=8) || (loc>=15 && loc<=19) || loc==12 || loc==14 || loc==11 || loc==10)
00300     if (mode==SPOT_LOAD && !IsChannelMute(AV_SOUND_CHANNEL))
00301      {
00302       switch(loc) {
00303        case 1:case 6:PlayAudio("jet.ogg",0);break;
00304        case 3:case 8:PlayAudio("vcrash.ogg",0);break;
00305        case 16:PlayAudio("train.ogg",0);break;
00306        case 4:PlayAudio("crawler.ogg",0);break;
00307        case 0:case 5:PlayAudio("vthrust.ogg",0);break;
00308        case 10:PlayAudio("gate.ogg",0);break;
00309        case 18:PlayAudio("svprops.ogg",0);break;
00310        case 2:case 7:PlayAudio("heli_00.ogg",0);break;
00311        case 17:PlayAudio("radarsv.ogg",0);break;
00312        case 11:PlayAudio("radarus.ogg",0);break;
00313        case 12:case 14:PlayAudio("lightng.ogg",0);break;
00314        case 19:PlayAudio("crane.ogg",0);break;
00315        case 15:PlayAudio("truck.ogg",0);break;
00316        default:break;
00317       };
00318       turnoff=1;
00319      };
00320   #endif
00321  return;
00322 }
00323    
00324 void WaveFlagSetup(void)
00325 {
00326   long j;
00327   FILE *fin;
00328   GV(&flaggy,230,22);
00329   fin=sOpen("FLAG.SEQ","rb",0);
00330   j=fread(vhptr.vptr,1,vhptr.h*vhptr.w,fin);
00331   fclose(fin);
00332   RLED_img(vhptr.vptr,flaggy.vptr,j,flaggy.w,flaggy.h);
00333 }
00334 
00335 void WaveFlagDel(void)
00336 {
00337   DV(&flaggy);
00338   return;                       
00339 }
00340 
00341 /* pace */
00342 /**
00343  * \note this isn't needed now that RLED automatically chops the right column
00344  * when the data is bigger than needed.  there's still a bug somewhere,
00345  * so this table is a useful list of funny images to check later
00346  */
00347 long fix_width[] = {
00348     // normal
00349     80615, // 4/0 VAB in mode 0
00350     101712, // 8/1 Medical center
00351     115262, // 16/1 L.M. Program
00352     113283, // 18/1 XMS-2 program
00353     112708, // 19/1 Apollo program
00354     112154, // 20/1 Gemini program
00355     86035, // 22/1 Research and development
00356     118301, // 33/1 Tracking station
00357     82541, // 4/2 vab
00358     88992, // 22/2 research and development
00359     92114, // 22/3 research and development
00360 
00361     // predraw 
00362     79703, // 15-1-1 "SATELLITE PROGRAMS" 
00363     0
00364 };
00365 
00366 int
00367 need_to_fix_width (long table)
00368 {
00369     int i;
00370     for (i = 0; fix_width[i]; i++) {
00371         if (fix_width[i] == table)
00372             return (1);
00373     }
00374     return (0);
00375 }
00376 
00377 void PortPlace(FILE * fin,long table)
00378 {
00379   IMG Img;
00380   GXHEADER local,local2;
00381   int ctr;
00382 
00383   fseek(fin,table,SEEK_SET);
00384   fread(&Img,sizeof Img,1,fin);
00385     Swap32bit(Img.Size);
00386     Swap16bit(Img.Width);
00387     Swap16bit(Img.Height);
00388     Swap16bit(Img.PlaceX);
00389     Swap16bit(Img.PlaceY);
00390 
00391 //  if (need_to_fix_width (table))
00392 //    Img.Width++;
00393 
00394   GV(&local,Img.Width,Img.Height);
00395   GV(&local2,Img.Width,Img.Height);
00396   gxGetImage(&local,Img.PlaceX,Img.PlaceY,Img.PlaceX+Img.Width-1,Img.PlaceY+Img.Height-1,0);
00397   fread(vhptr.vptr,Img.Size,1,fin);
00398   RLED_img(vhptr.vptr,local2.vptr,Img.Size,local2.w,local2.h);
00399   for (ctr=0;ctr<(Img.Width*Img.Height);ctr++)
00400     if (local2.vptr[ctr]!=0x00) local.vptr[ctr]=local2.vptr[ctr];
00401   gxPutImage(&local,gxSET,Img.PlaceX,Img.PlaceY,0);  // place image
00402   DV(&local2);DV(&local);
00403   return;
00404 }
00405 
00406 void PortPal(char plr)
00407 {
00408   FILE *fin;
00409   fin=sOpen((plr==0)?"USA_PORT.DAT":"SOV_PORT.DAT","rb",0);
00410   fread(&PHead,sizeof PHead,1,fin);
00411     Swap32bit(PHead.oPal);
00412   fseek(fin,PHead.oPal,SEEK_SET);
00413   fread(&pal[0],768,1,fin);
00414   fclose(fin);
00415   return;
00416 }
00417 
00418 
00419 void DrawSpaceport(char plr)
00420 {
00421   long table[S_QTY];
00422   int i,fm,idx;
00423   FILE *fin;
00424   GXHEADER local,local2;
00425   IMG Img;
00426 #ifdef __BIG_ENDIAN__
00427     int k,j;
00428 #endif
00429 
00430   fin=sOpen((plr==0) ?"USA_PORT.DAT":"SOV_PORT.DAT","rb",0);
00431 
00432   fread(&PHead,sizeof PHead,1,fin);
00433     Swap32bit(PHead.oMObj);
00434     Swap32bit(PHead.oTab);
00435     Swap32bit(PHead.oPal);
00436     Swap32bit(PHead.oPort);
00437     Swap32bit(PHead.oMse);
00438     Swap32bit(PHead.oOut);
00439     Swap32bit(PHead.oAnim);
00440 
00441   fread(&MObj[0],sizeof MObj,1,fin);
00442 #ifdef __BIG_ENDIAN__
00443     for (i = 0; i < (int)(sizeof(MObj)/sizeof(MOBJ)); i++)
00444     {
00445         for (j = 0; j < 4; j++)
00446         {
00447             for (k = 0; k < 4; k++)
00448             {
00449                 Swap16bit(MObj[i].Reg[j].CD[k].x1);
00450                 Swap16bit(MObj[i].Reg[j].CD[k].x2);
00451                 Swap16bit(MObj[i].Reg[j].CD[k].y1);
00452                 Swap16bit(MObj[i].Reg[j].CD[k].y2);
00453             }
00454         }
00455     }
00456 #endif
00457     
00458   fread(&table[0],sizeof table,1,fin);
00459 #ifdef __BIG_ENDIAN__
00460     for (i = 0; i< S_QTY; i++)
00461         Swap32bit(table[i]);
00462 #endif
00463 
00464   fseek(fin,PHead.oPal,SEEK_SET);
00465   fread(&pal[0],768,1,fin);
00466 
00467   fseek(fin,table[0],SEEK_SET);
00468   fread(&Img,sizeof Img,1,fin);  // Read in main image Header
00469     Swap32bit(Img.Size);
00470     Swap16bit(Img.Width);
00471     Swap16bit(Img.Height);
00472     Swap16bit(Img.PlaceX);
00473     Swap16bit(Img.PlaceY);
00474   fread((char *)screen,Img.Size,1,fin);  // Read in main image
00475   av_need_update_xy(0, 0, MAX_X, MAX_Y);
00476 
00477   UpdatePortOverlays();
00478 
00479   if (xMODE & xMODE_CLOUDS) 
00480         PortPlace(fin,table[1]); // Clouds
00481 
00482   // Pads
00483    for (i=0;i<3;i++) {
00484       Data->P[plr].Port[PORT_LaunchPad_A+i]=1;
00485       if (Data->P[plr].Mission[i].MissionCode>0) 
00486                 Data->P[plr].Port[PORT_LaunchPad_A+i]=2;
00487       else if (Data->P[plr].LaunchFacility[i]>1) 
00488                 Data->P[plr].Port[PORT_LaunchPad_A+i]=3;
00489       else if (Data->P[plr].LaunchFacility[i]<0) // No launch facility
00490                 Data->P[plr].Port[PORT_LaunchPad_A+i]=0;
00491       }
00492 
00493   if (Vab_Spot==1 && Data->P[plr].Port[PORT_VAB]==2)
00494    {
00495     Data->P[plr].Port[PORT_LaunchPad_A]=plr;
00496    }
00497   
00498 
00499   if (Data->P[plr].AstroCount>0) {
00500       PortPlace(fin,table[16-plr*4]); // Draw CPX
00501       HotKeyList[9]='T';
00502       HotKeyList[10]='B';
00503     } else {    // No manned program hotkeys
00504         HotKeyList[9]='\0';
00505         HotKeyList[10]='\0';
00506     }
00507   if (Data->P[plr].Pool[0].Active>=1) 
00508       PortPlace(fin,table[17-plr*4]); // Draw TRN
00509 
00510   if (Data->P[plr].Port[PORT_Research]>1) 
00511         PortPlace(fin,table[13+15*plr]);  // RD Stuff
00512   if (Data->P[plr].Port[PORT_Research]>2) 
00513         PortPlace(fin,table[14+15*plr]);
00514   if (Data->P[plr].Port[PORT_Research]==3) 
00515         PortPlace(fin,table[15+15*plr]);
00516 
00517   for (fm=0;fm<35;fm++) {
00518     idx=Data->P[plr].Port[fm];  // Current Port Level for MObj
00519 
00520     if (MObj[fm].Reg[idx].PreDraw>0)   // PreDrawn Shape
00521       PortPlace(fin,table[MObj[fm].Reg[idx].PreDraw]);
00522 
00523     if (MObj[fm].Reg[idx].iNum>0)   // Actual Shape
00524       PortPlace(fin,table[MObj[fm].Reg[idx].iNum]);
00525     }
00526 
00527   fclose(fin);
00528 
00529   ShBox(0,190,319,199);               // Base Box :: larger
00530 
00531   grSetColor(0);PrintAt(257,197,"CASH:");
00532   DispMB(285,197,Data->P[plr].Cash);
00533   grSetColor(11);PrintAt(256,196,"CASH:");
00534   DispMB(284,196,Data->P[plr].Cash);
00535  
00536   grSetColor(0);
00537   if (Data->Season==0) PrintAt(166,197,"SPRING 19");
00538   else PrintAt(166,197,"FALL 19");
00539   DispNum(0,0,Data->Year);
00540 
00541   grSetColor(11);
00542   if (Data->Season==0) PrintAt(165,196,"SPRING 19");
00543   else PrintAt(165,196,"FALL 19");
00544   DispNum(0,0,Data->Year);
00545 
00546 
00547    // FLAG DRAW
00548     FCtr=0;
00549     GV(&local,22,22);GV(&local2,22,22);
00550 
00551     if (plr==0) gxGetImage(&local,49,121,70,142,0);
00552     else gxGetImage(&local,220,141,241,162,0);
00553 
00554     if (plr==0) gxVirtualVirtual(&flaggy,FCtr*23,0,FCtr*23+21,21,&local2,0,0,gxSET);
00555     else gxVirtualVirtual(&flaggy,115+FCtr*23,0,115+FCtr*23+21,21,&local2,0,0,gxSET);
00556     for(i=0;i<(22*22);i++)
00557       if (local2.vptr[i]==0)
00558          local2.vptr[i]=local.vptr[i];
00559 
00560     if (plr==0) gxPutImage(&local2,gxSET,49,121,0);
00561     else gxPutImage(&local2,gxSET,220,141,0);
00562 
00563     DV(&local);DV(&local2);
00564 }
00565 
00566 void PortText(int x,int y,char *txt,char col)
00567 {
00568    RectFill(1,192,160,198,3);
00569    grSetColor(0);PrintAt(x+1,y+1,txt);
00570    grSetColor(col);PrintAt(x,y,txt);
00571 }
00572 
00573 
00574 void UpdatePortOverlays(void)
00575 {
00576    char i,j;
00577    for (i=0;i<NUM_PLAYERS;i++) {   // Programs
00578       for (j=0;j<5;j++) 
00579          Data->P[i].Port[PORT_Mercury-j]=(Data->P[i].Manned[j].Num>=0)?1:0;
00580 
00581 #ifdef DEADCODE
00582       // Zond thingy -- this was never implemented and available after 6 manned seasons
00583       //if (i==1 && Data->P[i].Manned[2].Seas>6) Data->P[i].Port[PORT_Zond]=1;
00584 #endif
00585 
00586       if(Data->P[i].Probe[0].Num>=0 || Data->P[i].Probe[1].Num>=0 ||
00587           Data->P[i].Probe[2].Num>=0 ) Data->P[i].Port[PORT_Satellite]=1;
00588 
00589       if (Data->P[i].Manned[5].Num>=0 || Data->P[i].Manned[6].Num>=0)
00590          Data->P[i].Port[PORT_LM]=1;
00591 
00592       // Museum
00593       if (Data->Prestige[18].Goal[i]>0)
00594          Data->P[i].Port[PORT_Museum]=maxx(Data->P[i].Port[PORT_Museum],1);   // Mus:1
00595       if (Data->Prestige[1].Goal[i]>0) 
00596          Data->P[i].Port[PORT_Museum]=maxx(Data->P[i].Port[PORT_Museum],2);   // Mus:2
00597       if (Data->Prestige[20].Goal[i]>0) 
00598          Data->P[i].Port[PORT_Museum]=maxx(Data->P[i].Port[PORT_Museum],3);   // Mus:3
00599 
00600       // R&D
00601       if (Data->P[i].Budget>=85)
00602          Data->P[i].Port[PORT_Research]=maxx(Data->P[i].Port[PORT_Research],1); // RD:1
00603       if (Data->P[i].Budget>=112)
00604          Data->P[i].Port[PORT_Research]=maxx(Data->P[i].Port[PORT_Research],2); // RD:2
00605       if (Data->P[i].Budget>=150)
00606          Data->P[i].Port[PORT_Research]=maxx(Data->P[i].Port[PORT_Research],3); // RD:3
00607 
00608       // VAB
00609 
00610       if (Data->Prestige[12].Goal[i]>0)
00611          Data->P[i].Port[PORT_VAB]=maxx(Data->P[i].Port[PORT_VAB],1);   // VAB:1
00612 
00613        if (Data->P[i].Budget>115)
00614          Data->P[i].Port[PORT_VAB]=maxx(Data->P[i].Port[PORT_VAB],2);   // VAB:2
00615 
00616       // Admin
00617       if (Data->P[i].AstroLevel>=2)
00618          Data->P[i].Port[PORT_Admin]=maxx(Data->P[i].Port[PORT_Admin],1);   // Adm:1
00619       if (Data->P[i].AstroLevel>=4)
00620          Data->P[i].Port[PORT_Admin]=maxx(Data->P[i].Port[PORT_Admin],2);   // Adm:2
00621 
00622       if (Data->Prestige[13].Goal[i]>0)
00623          Data->P[i].Port[PORT_Tracking]=maxx(Data->P[i].Port[PORT_Tracking],1); // Trk:1
00624       if (Data->Prestige[19].Goal[i]>0)
00625          Data->P[i].Port[PORT_MissionControl]=maxx(Data->P[i].Port[PORT_MissionControl],1); // MC:1
00626 
00627       if (Data->P[i].AstroCount>0)
00628          Data->P[i].Port[PORT_AstroComplex]=Data->P[i].Port[PORT_BasicTraining]=1;
00629 
00630       if (Data->P[i].Pool[0].Active>0) {  // Astros
00631          Data->P[i].Port[PORT_Helipad]=Data->P[i].Port[PORT_Pool]=Data->P[i].Port[PORT_Planetarium]=1;
00632          Data->P[i].Port[PORT_Centrifuge]=Data->P[i].Port[PORT_MedicalCtr]=Data->P[i].Port[PORT_Airfield]=1;
00633          }
00634       }
00635 }
00636 
00637 void Master(char plr)
00638 {
00639   int i,r_value,t_value=0,g_value=0;
00640   sFin=NULL;
00641   strcpy(IDT,"i000");strcpy(IKEY,"i000");
00642   WaveFlagSetup();
00643   sCount=-1;
00644   SUSPEND=Vab_Spot=0;
00645 
00646   for (i=0;i<3;i++) {
00647      GetMisType(Data->P[plr].Mission[i].MissionCode);
00648      Data->P[plr].Mission[i].Joint=Mis.Jt;
00649   }
00650 
00651     // Entering screen for the first time so fade out and in.
00652   FadeOut(2,pal,10,0,0);
00653     DrawSpaceport(plr);
00654   FadeIn(2,pal,10,0,0);
00655 
00656   memcpy(vhptr.vptr,screen,MAX_X*MAX_Y);
00657   av_need_update_xy(0, 0, MAX_X, MAX_Y);
00658 
00659 #if SPOT_ON
00660   if ((Data->P[plr].Pool[0].Active|Data->P[plr].Pool[1].Active|Data->P[plr].Pool[2].Active)>=1)
00661     g_value=1;
00662   for(i=0;i<Data->P[plr].AstroCount;i++)
00663     if (Data->P[plr].Pool[i].Status>=5) t_value=1;
00664   r_value=random(1000);
00665   if (xMODE & xMODE_CLOUDS)
00666    {
00667     if (plr==0 && Data->P[plr].Port[PORT_VAB]==0) SpotCrap(14,SPOT_LOAD);          //Usa Storm 
00668      else if (plr==1) SpotCrap(12,SPOT_LOAD);    //Sov Storm
00669    }
00670   else 
00671     if ((xMODE & xMODE_SPOT_ANIM) && g_value)
00672     {
00673      SpotCrap(3+(5*plr),SPOT_LOAD);
00674      xMODE &= ~xMODE_SPOT_ANIM;
00675     }
00676    else if (t_value && g_value) SpotCrap(0+(5*plr),SPOT_LOAD);  //Lem
00677     else if (r_value<150) {
00678      if (plr==1 && Data->P[plr].Port[PORT_MedicalCtr]==1) SpotCrap(18,SPOT_LOAD);   
00679       else SpotCrap(1+(5*plr),SPOT_LOAD);
00680     }
00681     else if (r_value>850) SpotCrap(2+(5*plr),SPOT_LOAD);       //Heli
00682 #endif
00683   
00684   Port(plr);
00685   strcpy(IDT,"i000");strcpy(IKEY,"i000");
00686   WaveFlagDel();
00687   if (sFin) {fclose(sFin);sFin=NULL;}
00688 }
00689 
00690 void GetMse(char plr,char fon)
00691 {
00692   int i;
00693   GXHEADER local,local2;
00694   static double last_wave_step;
00695   double now;
00696 
00697   now = get_time ();
00698   if (now - last_wave_step > .125) {
00699       last_wave_step = now;
00700 
00701       if (plr == 0)
00702           DoCycle ();
00703 
00704       if (fon != 1)
00705           goto done;
00706 #if SPOT_ON
00707     SpotCrap(0,SPOT_STEP);
00708 #endif
00709     FCtr=FCtr%5;
00710     GV(&local,22,22);GV(&local2,22,22);
00711 
00712     if (plr==0) gxGetImage(&local,49,121,70,142,0);
00713     else gxGetImage(&local,220,141,241,162,0);
00714     if (plr==0)
00715       gxVirtualVirtual(&flaggy,FCtr*23,0,FCtr*23+21,21,&local2,0,0,gxSET);
00716     else
00717       gxVirtualVirtual(&flaggy,115+FCtr*23,0,115+FCtr*23+21,21,&local2,0,0,gxSET);
00718     for(i=0;i<(22*22);i++)
00719       if (local2.vptr[i]==0)
00720          local2.vptr[i]=local.vptr[i];
00721 
00722     if (plr==0) gxPutImage(&local2,gxSET,49,121,0);
00723     else gxPutImage(&local2,gxSET,220,141,0);
00724 
00725     DV(&local);DV(&local2);
00726 
00727   done:
00728     FCtr++;
00729   }
00730   GetMouse_fast();
00731 }
00732 
00733 void
00734 DoCycle(void)                   // Three ranges of color cycling
00735 {
00736     int i, tmp1, tmp2, tmp3, j;
00737     /* hardcoded rectangles with water */
00738     struct rectangle {
00739         int x1, y1, x2, y2;
00740     } r[] = {
00741         {141, 163, 156, 175},
00742         {0, 50, 71, 72},
00743         {168, 16, 294, 32},
00744         {109, 11, 170, 39},
00745         {116,114, 157,145}
00746     };
00747 
00748     j = 384;
00749 
00750     i = 0;
00751     tmp1 = pal[j + 3 * i + 0];
00752     tmp2 = pal[j + 3 * i + 1];
00753     tmp3 = pal[j + 3 * i + 2];
00754     for (; i < 3; i++)
00755     {
00756         pal[j + i * 3 + 0] = pal[j + (i + 1) * 3 + 0];
00757         pal[j + i * 3 + 1] = pal[j + (i + 1) * 3 + 1];
00758         pal[j + i * 3 + 2] = pal[j + (i + 1) * 3 + 2];
00759     };
00760     pal[j + 3 * i] = tmp1;
00761     pal[j + 3 * i + 1] = tmp2;
00762     pal[j + 3 * i + 2] = tmp3;
00763 
00764     i = 4;
00765     tmp1 = pal[j + 3 * i + 0];
00766     tmp2 = pal[j + 3 * i + 1];
00767     tmp3 = pal[j + 3 * i + 2];
00768     for (; i < 11; i++)
00769     {
00770         pal[j + i * 3 + 0] = pal[j + (i + 1) * 3 + 0];
00771         pal[j + i * 3 + 1] = pal[j + (i + 1) * 3 + 1];
00772         pal[j + i * 3 + 2] = pal[j + (i + 1) * 3 + 2];
00773     };
00774     pal[j + 3 * i] = tmp1;
00775     pal[j + 3 * i + 1] = tmp2;
00776     pal[j + 3 * i + 2] = tmp3;
00777 
00778     i = 12;
00779     tmp1 = pal[j + 3 * i + 0];
00780     tmp2 = pal[j + 3 * i + 1];
00781     tmp3 = pal[j + 3 * i + 2];
00782     for (; i < 15; i++)
00783     {
00784         pal[j + i * 3 + 0] = pal[j + (i + 1) * 3 + 0];
00785         pal[j + i * 3 + 1] = pal[j + (i + 1) * 3 + 1];
00786         pal[j + i * 3 + 2] = pal[j + (i + 1) * 3 + 2];
00787     };
00788     pal[j + 3 * i] = tmp1;
00789     pal[j + 3 * i + 1] = tmp2;
00790     pal[j + 3 * i + 2] = tmp3;
00791 
00792     gxSetDisplayPalette(pal);
00793 
00794     for (i = 0; i < (int) ARRAY_LENGTH(r); ++i)
00795     {
00796         av_need_update_xy(r[i].x1, r[i].y1, r[i].x2, r[i].y2);
00797     }
00798 }
00799 
00800 /** ???
00801  * 
00802  * \param mode ...  0 = ?   1 = copy stored outline ?
00803  */
00804 void
00805 PortOutLine(unsigned int Count, ui16 * outline, char mode)
00806 {
00807     int min_x = MAX_X, min_y = MAX_Y, max_x = 0, max_y = 0;
00808     unsigned int i;
00809 
00810     pPortOutlineRestore = xrealloc(pPortOutlineRestore,
00811         sizeof(PORTOUTLINE) * Count);
00812 
00813     for (i = 0; i < Count; i++)
00814     {
00815         if (mode == 1)
00816         {                          // Save value from the screen 
00817             pPortOutlineRestore[i].loc = outline[i];    // Offset of the outline into the buffer
00818             pPortOutlineRestore[i].val = screen[outline[i]];    // Save original pixel value
00819         }
00820         else                       // dunno
00821             outline[i] = pPortOutlineRestore[i].loc;
00822         screen[outline[i]] = 11;   // Color the outline index 11, which should be Yellow
00823         min_x = min(min_x, outline[i] % MAX_X);
00824         min_y = min(min_y, outline[i] / MAX_X);
00825         max_x = max(max_x, outline[i] % MAX_X);
00826         max_y = max(max_y, outline[i] / MAX_X);
00827     }
00828     if (Count)
00829         av_need_update_xy(min_x, min_y, max_x, max_y);
00830 }
00831 
00832 void
00833 PortRestore(unsigned int Count)
00834 {
00835     int min_x = MAX_X, min_y = MAX_Y, max_x = 0, max_y = 0;
00836     unsigned int i;
00837     int loc;
00838 
00839     for (i = 0; i < Count; i++)
00840     {
00841         loc = pPortOutlineRestore[i].loc;
00842         screen[loc] = pPortOutlineRestore[i].val;
00843         min_x = min(min_x, loc % MAX_X);
00844         min_y = min(min_y, loc / MAX_X);
00845         max_x = max(max_x, loc % MAX_X);
00846         max_y = max(max_y, loc / MAX_X);
00847     }
00848     if (Count)
00849         av_need_update_xy(min_x, min_y, max_x, max_y);
00850     free(pPortOutlineRestore);
00851     pPortOutlineRestore = NULL;
00852 }
00853 
00854 
00855 /** Map a keypress to a spaceport building selection
00856  */
00857 int MapKey(char plr,int key,int old) 
00858 {
00859   int val,j,found=0;
00860   char high=-1,low=-1;
00861   for (j=0;j<35;j++)
00862    {
00863     if (MObj[j].Reg[Data->P[plr].Port[j]].sNum>0)
00864      {
00865       if (low==-1) low=j;
00866       high=j;
00867      }
00868    }
00869 
00870   val=old;
00871   switch(key) {
00872     case 'A': if (MObj[6].Reg[Data->P[plr].Port[PORT_Admin]].sNum>0) val=6;mousebuttons=1; break;
00873     case 'I': if (MObj[1].Reg[Data->P[plr].Port[PORT_Pentagon]].sNum>0) val=1;mousebuttons=1; break;
00874     case 'M': if (MObj[5].Reg[Data->P[plr].Port[PORT_Museum]].sNum>0) val=5;mousebuttons=1; break;
00875     case 'R': if (MObj[22].Reg[Data->P[plr].Port[PORT_Research]].sNum>0) val=22;mousebuttons=1; break;
00876     case 'P': if (MObj[2].Reg[Data->P[plr].Port[PORT_Capitol]].sNum>0) val=2;mousebuttons=1; break;
00877     case 'V': if (MObj[4].Reg[Data->P[plr].Port[PORT_VAB]].sNum>0) val=4;mousebuttons=1; break;
00878     case 'C': if (MObj[26].Reg[Data->P[plr].Port[PORT_MissionControl]].sNum>0) val=26;mousebuttons=1; break;
00879     case 'Q': if (MObj[29].Reg[Data->P[plr].Port[PORT_Gate]].sNum>0) val=29;mousebuttons=1; break;
00880     case 'E': if (MObj[28].Reg[Data->P[plr].Port[PORT_FlagPole]].sNum>0) val=28;mousebuttons=1; break;
00881     case 'T': if (MObj[7].Reg[Data->P[plr].Port[PORT_AstroComplex]].sNum>0) val=7;mousebuttons=1; break;
00882     case 'B': if (MObj[9].Reg[Data->P[plr].Port[PORT_BasicTraining]].sNum>0) val=9;mousebuttons=1; break;
00883 
00884 #if 0
00885         // Possibly hotkeys for astronaut training buildings
00886     case '1': if (MObj[9].Reg[Data->P[plr].Port[PORT_BasicTraining]].sNum>0) val=9;mousebuttons=1; break;
00887     case '2': if (MObj[9].Reg[Data->P[plr].Port[PORT_BasicTraining]].sNum>0) val=9;mousebuttons=1; break;
00888     case '3': if (MObj[9].Reg[Data->P[plr].Port[PORT_BasicTraining]].sNum>0) val=9;mousebuttons=1; break;
00889     case '4': if (MObj[9].Reg[Data->P[plr].Port[PORT_BasicTraining]].sNum>0) val=9;mousebuttons=1; break;
00890     case 'S': if (MObj[9].Reg[Data->P[plr].Port[PORT_BasicTraining]].sNum>0) val=9;mousebuttons=1; break;
00891 #endif
00892     case UP_ARROW:if (old==high) old=0; else old=old+1;
00893                   found=0;for (j=old;j<high+1;j++)
00894                    if (MObj[j].Reg[Data->P[plr].Port[j]].sNum>0) {
00895                      if (found==0) {val=j;found=1;}
00896                      }
00897                   break;
00898     case DN_ARROW:if (old==low) old=34; else old=old-1;
00899                   found=0;for (j=old;j>low-1;j--)
00900                    if (MObj[j].Reg[Data->P[plr].Port[j]].sNum>0) {
00901                      if (found==0) {val=j;found=1;}
00902                      }
00903                   break;
00904     default: val=old;break;
00905     }
00906 
00907   return val;
00908 }
00909 
00910 void Port(char plr)
00911 {
00912 double last_secs;
00913 int i,j,kMode,kEnt,k;
00914 char good, res;
00915 int kPad,pKey,gork;
00916 FILE *fin;
00917 long stable[55];
00918 ui16 Count,*bone;
00919 
00920   strcpy(IDT,"i043");strcpy(IKEY,"k043");
00921   bone=(ui16 *) buffer;
00922 
00923   fin=sOpen((plr==0)?"USA_PORT.DAT":"SOV_PORT.DAT","rb",0);
00924   fread(&PHead,sizeof PHead,1,fin);
00925     Swap32bit(PHead.oMObj);
00926     Swap32bit(PHead.oTab);
00927     Swap32bit(PHead.oPal);
00928     Swap32bit(PHead.oPort);
00929     Swap32bit(PHead.oMse);
00930     Swap32bit(PHead.oOut);
00931     Swap32bit(PHead.oAnim);
00932   fseek(fin,PHead.oOut,SEEK_SET);
00933   fread(&stable[0],sizeof stable,1,fin);
00934     for (i=0; i< 55; i++) {
00935         Swap32bit(stable[i]);
00936     }
00937   if (plr==0 && Data->Year>65) PortText(5,196,"CAPE KENNEDY",12);
00938   else if (plr==0) PortText(5,196,"THE CAPE",12);
00939   else PortText(5,196,"BAIKONOUR",12);
00940 
00941   pKey=0;
00942   
00943   music_start((plr==0)?M_USPORT:M_SVPORT);
00944   kMode=kPad=kEnt=0;
00945   last_secs = get_time ();
00946     i = 0; // this is used to loop through all the selection regions on the port
00947   while (1)
00948    {
00949        av_block ();
00950     #if 0
00951       if (get_time ()- last_secs > 25)   
00952       {
00953        SpotCrap(0,SPOT_KILL);
00954        gork=random(100);
00955        if (gork<50)
00956         {
00957          if (plr==1 && Data->P[plr].Port[PORT_MedicalCtr]==1)
00958           SpotCrap(18,SPOT_LOAD);
00959            else SpotCrap(1+(5*plr),SPOT_LOAD);
00960         }
00961        else if (plr==1 && gork<90) SpotCrap(10,SPOT_LOAD);
00962         else if (plr==0 && gork<90) SpotCrap(2+(5*plr),SPOT_LOAD);
00963          else SpotCrap(1+(5*plr),SPOT_LOAD); //Specs: Default
00964        last_secs = get_time ();
00965       }
00966     #endif
00967             if (kMode==0)
00968                 i=0;
00969             else if (kMode==1) 
00970                 kEnt=0;
00971 
00972     do
00973      {
00974       #if BABYSND
00975        UpdateAudio();
00976       #endif  
00977       if (pKey==0) {key=0;GetMse(plr,1);}
00978       else pKey=0;
00979       if (kPad>0 && kMode==1) key=kPad;
00980       if (kMode==1 && !(x==319 && y==199)) kMode=0;
00981       if (key>0) // this was only looking for the low byte
00982        {
00983         i=MapKey(plr,key,i);    // Get Port offset for keyboard input
00984         grSetMousePos(319,199);x=319;y=199;
00985         if (key==K_ESCAPE) {kMode=0;i=0;}
00986          else {kMode=1;}
00987         if (MObj[i].Reg[Data->P[plr].Port[i]].sNum>0)
00988          {
00989           x=MObj[i].Reg[Data->P[plr].Port[i]].CD[0].x1;
00990           y=MObj[i].Reg[Data->P[plr].Port[i]].CD[0].y1;
00991           kEnt=i;
00992          }
00993        }
00994       if (kMode==1 && kEnt==i)
00995        {
00996         x=MObj[i].Reg[Data->P[plr].Port[i]].CD[0].x1;
00997         y=MObj[i].Reg[Data->P[plr].Port[i]].CD[0].y1;
00998        }
00999       else if (kMode==1 && kEnt!=i)
01000        {
01001         x=-1;y=-1;
01002        }
01003 
01004             for (j=0;j<MObj[(kMode==0) ? i : kEnt].Reg[Data->P[plr].Port[(kMode==0) ? i : kEnt]].qty;j++) 
01005          if (x>=MObj[(kMode==0) ? i : kEnt].Reg[Data->P[plr].Port[(kMode==0) ? i : kEnt]].CD[j].x1 &&
01006           y>=MObj[(kMode==0) ? i : kEnt].Reg[Data->P[plr].Port[(kMode==0) ? i : kEnt]].CD[j].y1 &&
01007           x<=MObj[(kMode==0) ? i : kEnt].Reg[Data->P[plr].Port[(kMode==0) ? i : kEnt]].CD[j].x2 &&
01008           y<=MObj[(kMode==0) ? i : kEnt].Reg[Data->P[plr].Port[(kMode==0) ? i : kEnt]].CD[j].y2)
01009          {
01010           PortText(5,196,MObj[i].Name,11);
01011           if (MObj[i].Reg[Data->P[plr].Port[i]].sNum>0) {
01012                fseek(fin,stable[MObj[i].Reg[Data->P[plr].Port[i]].sNum],SEEK_SET);
01013                fread_uint16_t(&Count,1,fin);
01014                fread_uint16_t(bone,Count,fin);
01015                PortOutLine(Count,bone,1);
01016                strncpy(&IDT[1],MObj[i].Help,3);
01017               }
01018           good=0;
01019                     // Search hotkey string for valid selection
01020           for (k=0;k<(int)strlen(HotKeyList);k++)
01021            if (HotKeyList[k]==((char)(0x00ff&key))) good=1;
01022 
01023           while (x>=MObj[i].Reg[Data->P[plr].Port[i]].CD[j].x1 &&
01024              y>=MObj[i].Reg[Data->P[plr].Port[i]].CD[j].y1 &&
01025              x<=MObj[i].Reg[Data->P[plr].Port[i]].CD[j].x2 &&
01026              y<=MObj[i].Reg[Data->P[plr].Port[i]].CD[j].y2)
01027             {
01028             av_block ();
01029           #if BABYSND
01030            UpdateAudio();
01031           #endif
01032              kPad=0;key=0;
01033              GetMse(plr,1);
01034               if (kMode==0 && key>0) {x=y=0;pKey=key;};
01035 
01036               if (kMode==1 && !(x==319 && y==199)) {kMode=0;}
01037                if (kMode==1)
01038                 {
01039                  x=MObj[i].Reg[Data->P[plr].Port[i]].CD[0].x1;
01040                  y=MObj[i].Reg[Data->P[plr].Port[i]].CD[0].y1;
01041                 }
01042 
01043                if (key>0 && kMode==1)  // got a keypress
01044                 if (key!=K_ENTER) // not return
01045                  {
01046                   x=-1;y=-1;kPad=key;
01047                  }
01048 
01049                if (good==1 || (kMode==0 && mousebuttons==1) || (kMode==1 && key==K_ENTER) 
01050                   || (kMode==0 && key==K_ENTER))
01051                 {
01052                  PortRestore(Count);Count=0;
01053 
01054                   // || i==33
01055 
01056                   if (!(i==28 || i==29 || i==0 || i==31 
01057                        || (Data->Year==57 || (Data->Year==58 && Data->Season==0))))
01058                      {
01059 #if SPOT_ON
01060                        SpotCrap(0,SPOT_KILL);  // remove spots
01061 #endif
01062                        music_stop();
01063                     }
01064                   else SUSPEND=1;
01065 
01066                   res = PortSel(plr, i);
01067                   switch(res) {
01068                       case pNOREDRAW:
01069 #ifdef DEAD_CODE
01070                           if (!(i==28 || i==29 || i==0 || i==31 || i==33 
01071                             || (Data->Year==57 || (Data->Year==58 && Data->Season==0)))) {
01072                             PreLoadMusic((plr==0)?M_USPORT:M_SVPORT);
01073 #if SPOT_ON
01074                           memcpy(screen,vhptr.vptr,MAX_X*MAX_Y);
01075                           av_need_update_xy(0, 0, MAX_X, MAX_Y);
01076 #endif
01077                           }
01078 #endif
01079 
01080                           PortText(5,196,MObj[i].Name,11);
01081 #ifdef DEAD_CODE
01082                           if (!(i==28 || i==29 || i==0 || i==31 || i==33 
01083                              || (Data->Year==57 || (Data->Year==58 && Data->Season==0))))
01084                             PlayMusic(0);
01085 #endif
01086                             break;
01087                       case pREDRAW:
01088                       case pNEWMUSIC:
01089                       case pNOFADE:
01090                           if (res != pNOFADE)
01091                           {
01092                                                             music_stop();
01093                               music_start((plr==0)?M_USPORT:M_SVPORT);
01094                           }
01095 
01096                           SpotCrap(0,SPOT_KILL);  // remove spots
01097                                                     // Returning to spaceport so fade between redraws
01098                         if (res == pREDRAW)
01099                             FadeOut(2,pal,10,0,0);
01100 
01101                         DrawSpaceport(plr);
01102 
01103                         if (res == pREDRAW)
01104                             FadeIn(2,pal,10,0,0);
01105 
01106 #if SPOT_ON
01107                           memcpy(vhptr.vptr,screen,MAX_X*MAX_Y);
01108                           gork=random(100);
01109                           if (Vab_Spot==1 && Data->P[plr].Port[PORT_VAB]==2) 
01110                            {
01111                             Data->P[plr].Port[PORT_LaunchPad_A]=1;
01112                             if (plr==0) {
01113                                if (gork<=60) SpotCrap(4,SPOT_LOAD); //Rocket to Pad
01114                                 else SpotCrap(15,SPOT_LOAD); //Rocket&Truck/Door
01115                               }
01116                              else if (plr==1) SpotCrap(16,SPOT_LOAD);
01117                            }
01118                            else if (Vab_Spot==4 && plr==0 && Data->P[plr].Port[PORT_VAB]==0)
01119                             {
01120                              SpotCrap(19,SPOT_LOAD);
01121                             }
01122                            else if (Vab_Spot==2 && plr==1)
01123                             {
01124                              SpotCrap(10,SPOT_LOAD);
01125                             }
01126                            else if (Vab_Spot==3)
01127                             {
01128                              if (plr==1) SpotCrap(17,SPOT_LOAD);
01129                               else if (plr==0) SpotCrap(11,SPOT_LOAD);
01130                             }
01131                            else if (gork<30) {
01132                             if (plr==1 && Data->P[plr].Port[PORT_MedicalCtr]==1)
01133                              SpotCrap(18,SPOT_LOAD);
01134                               else SpotCrap(1+(5*plr),SPOT_LOAD);
01135                             }
01136                            else if (plr==1 && gork<40) SpotCrap(10,SPOT_LOAD);
01137                             else if (gork<60) SpotCrap(2+(5*plr),SPOT_LOAD);
01138 #endif              
01139                           Vab_Spot=0;
01140 #ifdef DEADCODE
01141                                             // I'm not sure why we're redrawing the outlines here, 
01142                                             //commenting it out for now.  if no problems are seen 
01143                                             // with the port outlines then restore thiss
01144                        //   if (pPortOutlineRestore) 
01145                                                 //      PortOutLine(Count,bone,0);
01146 #endif
01147                           PortText(5,196,MObj[i].Name,11);
01148                           break;
01149                    case pEXIT:
01150                           FadeOut(2,pal,10,0,0);
01151                           fclose(fin);
01152                         #if BABYSND
01153                           if (i==28 || i==29) SUSPEND=0;
01154                         #endif
01155                           SpotCrap(0,SPOT_KILL);  // remove spots
01156                           music_stop();
01157               save_game ("AUTOSAVE.SAV");
01158                           return;
01159                       case pQUIT:
01160                           FadeOut(2,pal,10,0,0);
01161                           fclose(fin);
01162                          #if BABYSND
01163                            if (i==28 || i==29) SUSPEND=0;
01164                          #endif
01165                           SpotCrap(0,SPOT_KILL);  // remove spots
01166                           music_stop();
01167                           return;
01168                       } // switch
01169                   kMode=good=SUSPEND=0;
01170                  if (MObj[i].Reg[Data->P[plr].Port[i]].sNum>0) {
01171                     fseek(fin,stable[MObj[i].Reg[Data->P[plr].Port[i]].sNum],SEEK_SET);
01172                     fread_uint16_t(&Count,1,fin);
01173                     fread_uint16_t(bone,Count,fin);
01174                     //pPortOutlineRestore = (PORTOUTLINE *) malloc((sizeof (PORTOUTLINE))*Count);
01175                     PortOutLine(Count,bone,1);
01176                     }
01177                    while(mousebuttons==1) GetMse(plr,1);
01178                   } // if
01179                 } //while
01180                if (plr==0 && Data->Year>65) PortText(5,196,"CAPE KENNEDY",12);
01181                else if (plr==0) PortText(5,196,"THE CAPE",12);
01182                else PortText(5,196,"BAIKONOUR",12);
01183                PortRestore(Count);Count=0;
01184                strcpy(IDT,"i043");strcpy(IKEY,"k043");
01185           } // if
01186       if (kMode==0 && XMAS==1) i++;if (kMode==1) kEnt++;
01187    } while ((kMode==0 && i<35 && i>=0) || (kMode==1 && kEnt<35 && kEnt>=0));
01188   } // while
01189 }
01190 
01191 
01192 /** This is the code that controls the jump off point from the Space Ports to the
01193  * various areas.  It basically assigns a help message then makes a call into
01194  * the module which would have it's own event loop
01195  */
01196 char PortSel(char plr,char loc)
01197 {
01198   int i,MisOK=0;
01199   Vab_Spot=0;  // clear the damn thing.
01200 
01201   switch(loc) {
01202    case PORT_Monument:  Help((plr==0)?"i023":"i022");
01203             strcpy(IKEY,"k022");
01204             return pNOREDRAW;// Monuments
01205     case PORT_Pentagon: 
01206         if (Data->Year==57 || (Data->Year==58 && Data->Season==0)) {
01207            Help("i108");
01208            return pNOREDRAW;
01209         }
01210         strcpy(IDT,"i027\0");
01211         Intel(plr); return pNEWMUSIC;
01212     case PORT_Capitol: strcpy(IDT,(plr==0)?"i021":"i532");strcpy(IKEY,(plr==0)?"k021":"k532");
01213             Review(plr); return pREDRAW;
01214     case PORT_Cemetery: strcpy(IDT,"i020");Hospital(plr,1); return pREDRAW;
01215     case PORT_VAB: if (Option!=-1) {put_serial(LET_V);put_serial(LET_V);put_serial(LET_V);}
01216             strcpy(IDT,"i015");MisOK=0;VAB(plr); return pREDRAW;
01217     case PORT_Museum: if (Option!=-1) {put_serial(LET_M);put_serial(LET_M);put_serial(LET_M);}
01218             strcpy(IDT,"i027");Museum(plr); return pNEWMUSIC;
01219     case PORT_Admin: if (Option!=-1) {put_serial(LET_A);put_serial(LET_A);put_serial(LET_A);}
01220             strcpy(IDT,"i027");Admin(plr);
01221             if (LOAD==1) return pEXIT;
01222             else if (QUIT==1) return pQUIT;
01223             else {if (plr==0) Vab_Spot=4;return pNEWMUSIC;}
01224     case PORT_AstroComplex: strcpy(IDT,"i039");Limbo(plr);return pREDRAW;// Astro Complex
01225     case PORT_MedicalCtr: strcpy(IDT,"i041");Hospital(plr,0); return pREDRAW;
01226     case PORT_BasicTraining: strcpy(IDT,"i038");Train(plr,0);return pREDRAW;
01227     case PORT_Helipad: strcpy(IDT,"i037");Train(plr,2);return pREDRAW;
01228     case PORT_Pool: strcpy(IDT,"i037");Train(plr,3);return pREDRAW;
01229     case PORT_Planetarium: strcpy(IDT,"i037");Train(plr,4);return pREDRAW;
01230     case PORT_Centrifuge: strcpy(IDT,"i037");Train(plr,5);return pREDRAW;
01231     case PORT_Airfield: strcpy(IDT,"i037");Train(plr,1);return pREDRAW;
01232     case PORT_Satellite: strcpy(IDT,"i019");SatBld(plr);return pREDRAW;
01233     case PORT_LM: strcpy(IDT,"i044");strcpy(IKEY,"k209");LMBld(plr);return pREDRAW;// LM Program
01234     case PORT_Jupiter: strcpy(IDT,"i036");Programs(plr,5);return pREDRAW;
01235     case PORT_XMS: strcpy(IDT,"i036");Programs(plr,4);return pREDRAW;
01236     case PORT_Apollo: strcpy(IDT,"i036");Programs(plr,3);return pREDRAW;
01237     case PORT_Gemini: strcpy(IDT,"i036");Programs(plr,2);return pREDRAW;
01238     case PORT_Mercury: strcpy(IDT,"i036");Programs(plr,1);return pREDRAW;
01239     case PORT_Research: if (Option!=-1) {put_serial(LET_R);put_serial(LET_R);put_serial(LET_R);}
01240              strcpy(IDT,"i009");RD(plr);if (plr==1) Vab_Spot=2;return pREDRAW;
01241     case PORT_LaunchPad_A:
01242     case PORT_LaunchPad_B:
01243     case PORT_LaunchPad_C: strcpy(IDT,"i028");ShowPad(plr,loc-23);return pREDRAW;
01244     case PORT_MissionControl: strcpy(IDT,"i018");strcpy(IKEY,"k018");
01245              MisOK=0;
01246              for (i=0;i<3;i++) {
01247                if (Data->P[plr].Mission[i].MissionCode>0 && 
01248                                      Data->P[plr].Mission[i].Hard[Mission_PrimaryBooster]==0) 
01249                                  MisOK=10;
01250                if (Data->P[plr].Mission[i].MissionCode>0) MisOK++;
01251                }
01252              if (MisOK>=10) Help("i005");
01253              else if (MisOK>0) {
01254                Rush(plr);RUSH=1;
01255                return pREDRAW;
01256                }
01257              else  Help("i104");
01258              return pNOFADE;
01259 
01260     case PORT_ViewingStand: strcpy(IDT,"i017");strcpy(IKEY,"k017");Viewing(plr);return pREDRAW;
01261     case PORT_FlagPole: // Flag Pole : End turn
01262              MisOK=0;
01263                         // Check to see if missions are good to go
01264              for (i=0;i<3;i++) {
01265                if (Data->P[plr].Mission[i].MissionCode>0 &&
01266                    Data->P[plr].Mission[i].Hard[Mission_PrimaryBooster]==0) 
01267                                     MisOK=10;
01268                if (Data->P[plr].Mission[i].MissionCode>0) MisOK++;
01269               }    
01270 
01271             if (MisOK>=10) {Help("i005");return pNOREDRAW;}
01272              else if (MisOK==0) {
01273                  MisOK=0;
01274                  i=Request(plr,"END TURN",1);
01275                if (i) return pEXIT;
01276                  }
01277              else if (RUSH==1 && MisOK>0 && MisOK<10) {
01278                MisOK=Help("i004");             // Mission Control
01279                  if (MisOK>=0) {
01280                 if (Option!=-1) {put_serial(LET_O);put_serial(LET_O);put_serial(LET_O);}
01281                 RUSH=0;return pEXIT;
01282                };
01283               }
01284              else if (RUSH==0) {
01285                Help("i103");
01286               }
01287             return pNOREDRAW;
01288     case PORT_Gate: // Secutity Gate : Quit
01289             QUIT=Request(plr,"QUIT",1);
01290               if(QUIT)
01291              {
01292               if (Option!=-1) DoModem(2);
01293               return pQUIT;
01294              }
01295               return pNOREDRAW; 
01296     case PORT_Moon: strcpy(IDT,"i029");Moon(plr);return pREDRAW; // Moon
01297     case PORT_SovMonumentAlt: Help("i025");return pNOREDRAW; // Sov Mon #2
01298     case PORT_Zond: strcpy(IDT,"i036");Programs(plr,3);return pREDRAW; // Zond
01299     case PORT_Tracking: if (Option!=-1) {MesCenter();Vab_Spot=3;return pREDRAW;} // Tracking
01300               else {Help("i042");Vab_Spot=3;return pNOFADE;}
01301     case PORT_SVHQ: return pNOREDRAW; // SV
01302     default: return pNOREDRAW;
01303   }
01304 }
01305 
01306 
01307 char Request(char plr,char *s,char md)
01308 {
01309   char i;
01310   GXHEADER local;
01311 
01312   if (md>0) {  // Save Buffer
01313     GV(&local,196,84);
01314     gxGetImage(&local,85,52,280,135,0);
01315   }
01316   i=strlen(s)>>1;
01317   grSetColor(0);
01318   ShBox(85,52,249,135);
01319   IOBox(170,103,243,130);
01320   IOBox(91,103,164,130);
01321   InBox(92,58,243,97);
01322   grSetColor(1);
01323   DispBig(109,110,"YES",0,0);
01324   DispBig(196,110,"NO",0,0);
01325 
01326   grSetColor(11);
01327   if (md==6)  PrintAt(166-i*7,65,s);
01328   else DispBig(166-i*10,65,&s[0],0,-1);
01329   PrintAt(138,94,"ARE YOU SURE");
01330 
01331   while(1){
01332      if (md!=6) GetMse(plr,1);
01333      else GetMouse();
01334      if (mousebuttons==0) break;
01335      }
01336   i=2;
01337   while(i==2) {
01338     if (md!=6) GetMse(plr,1);
01339     else GetMouse();
01340      if ((x>=172 && y>=105 && x<=241 && y<=128 && mousebuttons!=0)||(key=='N')) {
01341        InBox(172,105,241,128);i=0;
01342        delay(50);key=0;
01343      };
01344      if ((x>93 && y>=105 && x<=162 && y<=128&& mousebuttons!=0)||(key=='Y')) {
01345        InBox(93,105,162,128);i=1;
01346        delay(50);key=0;
01347      };
01348      delay(50);
01349   }; /* End while */
01350 
01351   if (md>0) {
01352     gxPutImage(&local,gxSET,85,52,0);
01353     DV(&local);
01354   }
01355   return i;
01356 }
01357 
01358 char MisReq(char plr)
01359 {
01360   int i,num=0;
01361   GXHEADER local;
01362 
01363   GV(&local,184,132);
01364   gxGetImage(&local,53,29,236,160,0);
01365 
01366   for (i=0;i<3;i++)
01367     if ((Data->P[plr].Mission[i].MissionCode>0)&&
01368     (Data->P[plr].Mission[i].Hard[Mission_PrimaryBooster]==0)) num++;
01369   ShBox(53,29,236,160);
01370   ShBox(60,34,229,44);
01371   InBox(60,47,229,120);
01372   // RectFill(61,48,228,119,0);
01373   ShBox(63,50,226,117);
01374   if (num==0) {
01375     IOBox(60,141,141,155);
01376     IOBox(148,141,229,155);
01377     grSetColor(1);
01378     PrintAt(70,129,"CONFIRM LAUNCH SCHEDULE OR");
01379     PrintAt(80,136,"CHOOSE TO REVIEW IT.");
01380     grSetColor(8);PrintAt(85,150,"C");grSetColor(1);PrintAt(0,0,"ONFIRM");
01381     grSetColor(8);PrintAt(179,150,"R");grSetColor(1);PrintAt(0,0,"EVIEW");
01382   } else {
01383     IOBox(60,141,229,155);
01384     grSetColor(1);
01385     PrintAt(62,129,"ALL MISSIONS DO NOT HAVE");
01386     PrintAt(62,136,"ASSIGNMENTS. NO COMMIT POSSIBLE");
01387     PrintAt(120,150,"REVIEW MISSIONS");
01388   };
01389 
01390   grSetColor(10);
01391   PrintAt(94,41,"LAUNCH CONFIRMATION");
01392   grSetColor(1);
01393   for (i=0;i<3;i++) {
01394     PrintAt(68,59+20*i,"PAD ");DispChr(0x41+i);PrintAt(0,0,": ");
01395     if (Data->P[plr].Mission[i].MissionCode!=0) {
01396       PrintAt(0,0,&Data->P[plr].Mission[i].Name[0]);
01397       if (Data->P[plr].Mission[i].Men>0) {
01398     PrintAt(86,65+20*i,"MANNED MISSION");
01399       } else {
01400     PrintAt(86,65+20*i,"UNMANNED MISSION");
01401       };
01402 
01403       if (Data->P[plr].Mission[i].Hard[Mission_PrimaryBooster]==0) {
01404     grSetColor(9);
01405     PrintAt(86,71+20*i,"HARDWARE UNASSIGNED");
01406       } else {
01407     PrintAt(86,71+20*i,"HARDWARE ASSIGNED");
01408       };
01409       grSetColor(1);
01410     }
01411   };
01412 
01413   while(1)
01414     {if (plr==0) GetMse(plr,1);else GetMouse();if (mousebuttons==0) break;}
01415   i=2;
01416   while(i==2) {
01417    if (plr==0) GetMse(plr,1); else GetMouse();
01418      if ((x>=62 && y>=143 && x<=139 && y<=153 && mousebuttons!=0 && num==0)
01419     || (key=='C' && num==0)) {
01420        InBox(62,143,139,153);i=1;
01421        delay(50);key=0;
01422        Rush(plr);
01423      };
01424      if ((x>150 && y>=143 && x<=227 && y<=153 && mousebuttons!=0 && num==0)
01425        || (key=='R' && num==0)) {
01426        InBox(150,143,227,153);i=0;
01427        delay(50);key=0;
01428      };
01429      if ((x>62 && y>=143 && x<=227 && y<=153 &&mousebuttons!=0 && num>0)
01430        || (key=='R' && num>0)) {
01431        InBox(62,143,227,153);i=0;
01432        delay(50);key=0;
01433      };
01434   }; /* End while */
01435   gxPutImage(&local,gxSET,53,29,0);
01436   DV(&local);
01437   return i;
01438 }
01439 
01440 // Editor settings {{{
01441 // ex: ts=4 noet sw=2 
01442 // ex: foldmethod=marker
01443 // }}}
01444 
01445 
01446 
01447 

Generated on Fri Sep 28 00:35:45 2007 for raceintospace by  doxygen 1.5.3