From 7fbd8d53b1932e40676a120cfd84868f3758465b Mon Sep 17 00:00:00 2001 From: Ian C Date: Thu, 12 May 2005 00:59:39 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r2, which included commits to RCS files with non-trunk default branches. --- lunar.c | 1843 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 1843 insertions(+) create mode 100644 lunar.c (limited to 'lunar.c') diff --git a/lunar.c b/lunar.c new file mode 100644 index 0000000..33d7041 --- /dev/null +++ b/lunar.c @@ -0,0 +1,1843 @@ +/* + + lunar - Simple X11 Lunar Lander + + Copyright (C) 2005 Ian Cowburn (ianc@noddybox.demon.co.uk) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + ------------------------------------------------------------------------- + + This code is rather messy as it is a quick tidy up from the K&R original. + +*/ +static char rcs_id[]="$Id$"; + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "Xbit.h" + +#define WINX 100 +#define WINY 100 +#define WINW 320 +#define WINWH 160 +#define WINH 200 +#define WINHH 100 + +#define RND(x) (rand()%(x)) + +#define ITOF(x) ((x)<<8) +#define FTOI(x) ((x)>>8) + +#define ABS(x) ((x)<0 ? (-(x)) : (x)) +#define SGN(x) ((x) ? ((x)/ABS(x)) : (0)) +#define DABS(x) ((x)<0.0 ? (-(x)) : (x)) + +#define AT(p,x,y) *((p)+(x)+(y)*WINW) + +#define HISCFILE "hisc.ll" +#define LEVELDIR "LEVELS/" + +#define CH(x,y) ((x)*SCALE),((y)*SCALE),SCALE,SCALE +#define CHSC(x,y,sx,sy) ((x)*SCALE),((y)*SCALE),SCALE*sx,SCALE*sy + +static XSizeHints size_hints; +static ulong black,white; +static Display *disp; +static Window top,sub; +static Colormap cm; +static XFontStruct *font; +static XImage *img; +static uchar *coll_data; + +static double si[3600],co[3600]; + +static XFuncControl Key(Window w, XPressRelease s, XEvent *e); +static XFuncControl ProcessTitle(void),ProcessIntro(void),ProcessGame(void), + ProcessGameOver(void),ProcessHiScore(void); + +/* Hiscore +*/ +#define NOHI 3 + +typedef struct +{ + char name[4]; + int score; + int no; +} HiSc; + +static HiSc hisc[NOHI]= + { + {"N.B",100,1}, + {"N.B",100,1}, + {"N.B",100,1}, + }; + +/* Keycontrols +*/ +static XWindowKeyCallback + key[2]= + { + {0,Key}, + {0,NULL} + }; + +#define NONE -1 +#define FINE_LEFT 0 +#define FINE_RIGHT 1 +#define THRUST 2 +#define LEFT 3 +#define RIGHT 4 +#define QUIT 5 +#define SCALE_UP 6 +#define SCALE_DOWN 7 +#define PAUSE 8 + +static int inkey=NONE; +static KeySym last_keysym; +static int keymap[PAUSE+1]= + {False,False,False,False,False, + False,False,False,False}; + + +/* Collision data codes - NB : order is important for Vector collisions - a + collision of '4' will override a collision + with '3' +*/ +#define CNONE 0 +#define CPAD 1 +#define CASTEROID 2 +#define CMOUNTAIN 3 +#define ISCMINE(c) ((c)&(0x80)) +#define CMINE(x) ((x)+0x80) + + +/* Colour vars +*/ +#define NOCOLS 8 +#define RNDCOL pix[(RND(NOCOLS-2)+2)] +#define RGB(r,g,b) {(r)*255,(g)*255,(b)*255} + +static ulong pix[NOCOLS]; +static Colour cols[NOCOLS]= + { + RGB(0,0,0), /* BLACK */ + RGB(255,255,255), /* WHITE */ + RGB(255,100,100), /* RED */ + RGB(100,255,100), /* GREEN */ + RGB(100,100,255), /* BLUE */ + RGB(255,255,0), /* YELLOW */ + RGB(0,255,255), /* CYAN */ + RGB(165,42,42) /* BROWN */ + }; + +#define IBLACK 0 +#define IWHITE 1 +#define IRED 2 +#define IGREEN 3 +#define IBLUE 4 +#define IYELLOW 5 +#define ICYAN 6 +#define IBROWN 7 + +#define BLACK pix[IBLACK] +#define WHITE pix[IWHITE] +#define RED pix[IRED] +#define GREEN pix[IGREEN] +#define BLUE pix[IBLUE] +#define YELLOW pix[IYELLOW] +#define CYAN pix[ICYAN] +#define BROWN pix[IBROWN] + + +/* 2D Vector defs +*/ +#define VECPT 32 +#define VECLN 32 + +typedef struct + { + double x,y; + } VecPt; + + +typedef struct + { + int p1,p2; + } VecLine; + + +typedef struct + { + VecPt pos; + int ang; + int no_pt; + VecPt pt[VECPT]; + int no_ln; + VecLine ln[VECLN]; + VecPt work[VECPT]; + ulong colour; + int collcode; + int coll[VECLN]; + } VecObject; + + +/* Lander vector object +*/ +static VecObject base_lander= + { + {0.0,0.0}, /* pos */ + 0, /* ang */ + + 7, /* no_pt */ + { /* pt[] */ + { 0.0, -10.0}, + {-10.0, 10.0}, + { 10.0, 10.0}, + { -7.0, 10.0}, + { 7.0, 10.0}, + {-10.0, 20.0}, + { 10.0, 20.0}, + }, + + 5, /* no_ln */ + { /* ln[] */ + {0,1}, + {1,2}, + {2,0}, + {3,5}, + {4,6}, + }, + + { /* work[] */ + {0.0,0.0}, + }, + + IWHITE, /* colour */ + CNONE, /* collcode */ + {0,}, /* coll */ + }; + +static VecObject lander; + + +/* Particle definitions +*/ +#define NOPLIST 4 +#define PSHORT 0 +#define PMID 1 +#define PLONG 2 +#define PULTRA 3 + +typedef struct + { + double x,y; + } ParticlePt; + +typedef struct part + { + int life; + ParticlePt p; + ParticlePt i; + struct part *next; + } Particle; + +static Particle *p_head[NOPLIST]; +static Particle *p_tail[NOPLIST]; + + +/* Now we are using MIT-SHM structures, there should be more than enough + power for some background stars to give the player a visual cue of bearing +*/ +#define NOBDSTAR 50 +typedef struct + { + double x,y; + } BdStar; + +static BdStar bdrop[NOBDSTAR]; + + +/* Level data - should improve this really... Using up 3Mb statically for + level definitions is probably a bit _too_ much! :-} +*/ +#define MAXLEVEL 32 +#define MAXLEVPOLY 64 + +#define MOUNTAIN 0 +#define ASTEROIDCW 1 +#define ASTEROIDACW 2 +#define PAD 3 +#define MINE 4 + +typedef struct + { + int no; + char *name; + int type[MAXLEVPOLY]; + int draw[MAXLEVPOLY]; + VecObject v[MAXLEVPOLY]; + } LevelDef; + +static int no_levels; +static char *level_set; +static LevelDef levdata[MAXLEVEL]; +static LevelDef level; + + +/* Damage vars +*/ +#define DAMAGE_NONE 0 +#define DAMAGE_LEFT 1 +#define DAMAGE_RIGHT 2 +#define DAMAGE_MAIN 3 + +static int damage; + +/* Control vars +*/ +static int FUEL =500; +static int SCORE =0; +static int FONT =1; +static int LEVEL =0; +static int SHOWVEC =0; +static double GRAVITY =0.1; +static double MAXGRAV =8.0; +static double JET =0.5; + +static int SCALE =1; +static void POKEIMG_S(XImage *img, int x, int y, ulong col); +static void POKEIMG_NS(XImage *img, int x, int y, ulong col); +static void (*POKEIMG)(XImage *img, int x, int y, ulong col); + +static int quit=False; +static int do_intro; +static int score,rot,fuel,landing,lev; +static double shipxi,shipyi; +static int offx,offy; + + +/* Protos +*/ +static void ClearKeys(void); +static void DefineLevel(void); +static void DrawObject(VecObject *o); +static void ClearParticles(void); +static void InitBdrop(void); +static int Paused(int k); +static void ReadScores(void); +static void WriteScores(void); +static void ReadLevels(void); + + +int main(int argc,char *argv[]) +{ + int f,r,x,y,arg,noshm; + unsigned long evmask; + + arg=1; + noshm=False; + + if (argc>arg) + if (!strcmp(argv[arg],"-noshm")) + { + noshm=True; + arg++; + } + + if (argc>arg) + { + SCALE=atoi(argv[arg]); + + if (SCALE<1) + { + fprintf(stderr,"scale param must be +ve\n"); + exit(1); + } + } + + if (SCALE==1) + POKEIMG=POKEIMG_NS; + else + POKEIMG=POKEIMG_S; + + for(f=0;f<3600;f++) + { + si[f]=sin(M_PI/1800.0*f); + co[f]=cos(M_PI/1800.0*f); + } + + for(f=0;f0); + + if (score>-1) + { + ClearKeys(); + XDoWindows(NULL,NULL,key,ProcessGameOver); + + ReadScores(); + if (score>hisc[NOHI-1].score) + { + XDoWindows(NULL,NULL,key,ProcessHiScore); + WriteScores(); + } + } + + ClearKeys(); + XDoWindows(NULL,NULL,key,ProcessTitle); + } + + XAutoRepeatOn(disp); + DestroyXImage(img); + XCloseDisplay(disp); +} + + +/* ----------------------------------------------- KEY AND UTILITY +*/ +static XFuncControl Key(Window w, XPressRelease s, XEvent *e) +{ + if (s==XRELEASE) + { + last_keysym=XK_VoidSymbol; + + switch(XLookupKeysym((XKeyEvent *)e,ShiftMapIndex)) + { + case XK_A: + case XK_a: + keymap[FINE_LEFT]=False; + break; + + case XK_D: + case XK_d: + keymap[FINE_RIGHT]=False; + break; + + case XK_Z: + case XK_z: + keymap[LEFT]=False; + break; + + case XK_C: + case XK_c: + keymap[RIGHT]=False; + break; + + case XK_period: + keymap[THRUST]=False; + break; + + case XK_P: + case XK_p: + keymap[PAUSE]=False; + break; + + case XK_Q: + case XK_q: + keymap[QUIT]=False; + break; + + case XK_bracketleft: + keymap[SCALE_DOWN]=False; + break; + + case XK_bracketright: + keymap[SCALE_UP]=False; + break; + + default: + keymap[NONE]=False; + break; + } + } + + if (s==XPRESS) + { + inkey=NONE; + + switch(last_keysym=XLookupKeysym((XKeyEvent *)e,ShiftMapIndex)) + { + case XK_A: + case XK_a: + inkey=FINE_LEFT; + break; + + case XK_D: + case XK_d: + inkey=FINE_RIGHT; + break; + + case XK_Z: + case XK_z: + inkey=LEFT; + break; + + case XK_C: + case XK_c: + inkey=RIGHT; + break; + + case XK_period: + inkey=THRUST; + break; + + case XK_P: + case XK_p: + inkey=PAUSE; + break; + + case XK_Q: + case XK_q: + inkey=QUIT; + break; + + case XK_bracketleft: + inkey=SCALE_DOWN; + break; + + case XK_bracketright: + inkey=SCALE_UP; + break; + + default: + inkey=NONE; + break; + } + + if (inkey!=NONE) + keymap[inkey]=True; + } + + return XFUNCCONT; +} + + +static int GetKey(void) +{ + int k=inkey; + + if ((inkey=SCALE_UP)||(inkey=SCALE_UP)||(inkey==PAUSE)|| + (inkey==QUIT)||(inkey=THRUST)) + inkey=NONE; + + return k; +} + + +static KeySym RawKey(void) + +{ + KeySym k=last_keysym; + + last_keysym=XK_VoidSymbol; + return k; +} + + +static void ClearKeys(void) +{ + int f; + + inkey=NONE; + + for(f=0;f<5;f++) + keymap[f]=False; +} + + +/* ----------------------------------------------- GRAPHICS UTILS +*/ +static void Cls(void) +{ + ClsXImage(img); + memset(coll_data,CNONE,WINW*WINH); +} + + +static void Update(void) +{ + DrawXImage(img); + XSync(disp,False); +} + + +static void Centre(int y, ulong c, const char *s) +{ + XIprintf(img,CH(WINWH-strlen(s)*4,y),c,"%s",s); +} + + +static void POKEIMG_NS(XImage *img,int x,int y,ulong c) +{ + XPutPixel(img,x,y,c); +} + + +static void POKEIMG_S(XImage *img,int x,int y,ulong c) +{ + int sx,sy; + + for(sx=0;sx=0)&&(x=0)&&(y3599) + level.v[f].ang-=3600; + break; + case ASTEROIDACW: + if ((level.v[f].ang-=20)<0) + level.v[f].ang+=3600; + break; + case PAD: + break; + case MINE: + break; + } + + DrawObject(&level.v[f]); + } +} + + +/* ----------------------------------------------- VECTOR OBJECT +*/ +static int vecscale=0; + +#define SetScale(s) vecscale=(s) + + +static void LinePlot(int x,int y,ulong c,int col,int *retcoll) +{ + if ((x<0)||(x>=WINW)||(y<0)||(y>=WINH)) + return; + + POKEIMG(img,x,y,c); + + if (AT(coll_data,x,y)>*retcoll) + *retcoll=AT(coll_data,x,y); + + if (col!=CNONE) + AT(coll_data,x,y)=col; +} + + +static void Line(VecPt *p1,VecPt *p2, ulong c, int collcode, int *coll) +{ + int f; + int dx,dy,ix,iy,incrE,incrNE,d,x,y,ymode; + int p1x,p1y,p2x,p2y; + + p1x=(int)p1->x; + p1y=(int)p1->y; + p2x=(int)p2->x; + p2y=(int)p2->y; + + if ((p1x<0)&&(p2x<0)) + return; + + if ((p1x>=WINW)&&(p2x>=WINW)) + return; + + if ((p1y<0)&&(p2y<0)) + return; + + if ((p1y>=WINH)&&(p2y>=WINH)) + return; + + dx=p2x-p1x; + dy=p2y-p1y; + + ix=SGN(dx); + iy=SGN(dy); + + dx=ABS(dx); + dy=ABS(dy); + + if (dy>dx) + { + ymode=True; + d=dx*2-dy; + incrE=dx*2; + incrNE=(dx-dy)*2; + } + else + { + ymode=False; + d=dy*2-dx; + incrE=dy*2; + incrNE=(dy-dx)*2; + } + + x=p1x; + y=p1y; + + LinePlot(x,y,c,collcode,coll); + + if (ymode) + while(y!=p2y) + { + if (d<=0) + { + d+=incrE; + y+=iy; + } + else + { + d+=incrNE; + y+=iy; + x+=ix; + } + + LinePlot(x,y,c,collcode,coll); + } + else + while(x!=p2x) + { + if (d<=0) + { + d+=incrE; + x+=ix; + } + else + { + d+=incrNE; + y+=iy; + x+=ix; + } + + LinePlot(x,y,c,collcode,coll); + } +} + + +static void Rotate(VecPt *p1,VecPt *p2,int a) +{ + double dx,dy,dco,dsi; + + dco=co[a]; + dsi=si[a]; + + dx=p1->x; + dy=p1->y; + + p2->x=(dco*dx+(-dsi)*dy); + p2->y=(dsi*dx+dco*dy); +} + + +static void Scale(VecPt *p) +{ + p->x/=vecscale; + p->y/=vecscale; +} + + +static void DrawObject(VecObject *o) +{ + int f; + + if (o->ang) + for(f=0;fno_pt;f++) + { + Rotate((o->pt)+f,(o->work)+f,o->ang); + o->work[f].x+=o->pos.x; + o->work[f].y+=o->pos.y; + + if (vecscale) + Scale(o->work+f); + + o->work[f].x+=WINWH; + o->work[f].y+=WINHH; + } + else + for(f=0;fno_pt;f++) + { + o->work[f].x=o->pt[f].x+o->pos.x; + o->work[f].y=o->pt[f].y+o->pos.y; + + if (vecscale) + Scale(o->work+f); + + o->work[f].x+=WINWH; + o->work[f].y+=WINHH; + } + + for(f=0;fno_ln;f++) + { + o->coll[f]=CNONE; + Line(&o->work[o->ln[f].p1], + &o->work[o->ln[f].p2], + o->colour, + o->collcode, + &o->coll[f]); + } +} + + +/* ----------------------------------------------- PARTICLE ROUTINES +*/ +static void ClearParticles(void) +{ + Particle *p; + int f; + + for(f=0;fnext; + free(p); + } + p_tail[f]=NULL; + } +} + + +static void AddParticle(int ang,int rad,int list,int weight) +{ + Particle *new; + + if (new=(Particle *)malloc(sizeof(Particle))) + { + new->next=NULL; + + switch(list) + { + case PSHORT: + new->life=3; + break; + + case PMID: + new->life=7; + break; + + case PLONG: + new->life=20; + break; + + case PULTRA: + new->life=40; + break; + + default: + free(new); + return; + } + + new->p.x=-(double)rad*si[ang]; + new->p.y=(double)rad*co[ang]; + new->i.x=-si[ang]/weight; + new->i.y=co[ang]/weight; + + if (p_head[list]) + { + p_tail[list]->next=new; + p_tail[list]=new; + } + else + p_head[list]=p_tail[list]=new; + } +} + + +static void DrawParticles(void) +{ + Particle *p; + int f; + + for(f=0;flife)) + { + if (!(p_head[f]=p->next)) + p_tail[f]=NULL; + free(p); + } + + p=p_head[f]; + while(p) + { + p->life--; + p->p.x+=p->i.x+shipxi; + p->p.y+=p->i.y+shipyi; + if (vecscale) + Plot(WINWH+(int)p->p.x/vecscale, + WINHH+(int)p->p.y/vecscale,RNDCOL); + else + Plot(WINWH+(int)p->p.x,WINHH+(int)p->p.y,RNDCOL); + p=p->next; + } + } +} + + +static int NoParticles(void) +{ + int f,ret; + + ret=True; + + for(f=0;f=(double)WINW) + bdrop[f].x-=(double)WINW; + + + if (bdrop[f].y<0.0) + bdrop[f].y+=(double)WINH; + + if (bdrop[f].y>=(double)WINH) + bdrop[f].y-=(double)WINH; + + Plot((int)bdrop[f].x,(int)bdrop[f].y,YELLOW); + } +} + + +/* ----------------------------------------------- TITLE SCREEN +*/ +static void DoDebugMenu(void) +{ + static int debug_menu=False; + KeySym k; + int f; + + if ((k=RawKey())=='r') + debug_menu=!debug_menu; + + if (debug_menu) + { + Cls (); + + for(f=0;f<128;f++) + XIprintf(img,CH((f%40)*8,(f/40)*8),CYAN,"%c",f); + + XIprintf(img,CH(0,150),CYAN, + "(y/u) LEVEL %2d : %s",LEVEL,levdata[LEVEL].name); + XIprintf(img,CH(0,160),CYAN, + "(s) SHOW VECTOR : %5d",SHOWVEC); + XIprintf(img,CH(0,170),CYAN, + "(f) FONT : %5d",FONT); + XIprintf(img,CH(0,180),CYAN, + "(h) SCORE : %5d",SCORE); + XIprintf(img,CH(0,190),CYAN, + "(l) FUEL : %5d",FUEL); + + XIprintf(img,CH(0,100),CYAN,"(x) SET TO DEFAULTS"); + XIprintf(img,CH(0,108),CYAN,"(o) SET TO DEBUG"); + XIprintf(img,CH(0,116),CYAN,"(w) SET TO SMALLER DEBUG"); + + switch(k) + { + case 'u': + if (--LEVEL==-1) + LEVEL=no_levels-1; + break; + case 'y': + if (++LEVEL==no_levels) + LEVEL=0; + break; + case 'f': + FONT^=1; + XISetFont(FONT); + break; + case 'h': + SCORE=hisc[0].score; + break; + case 'l': + if ((FUEL+=500)>10000) + FUEL=0; + break; + case 's': + SHOWVEC=!SHOWVEC; + break; + case 'x': + SCORE=0; + FUEL=500; + break; + case 'o': + FUEL=10000; + SCORE=hisc[0].score; + break; + case 'w': + FUEL=100; + SCORE=hisc[0].score; + break; + } + } +} + + +static XFuncControl ProcessTitle(void) +{ + static unsigned int ctr=0; + char s[80]; + int f,k; + + ctr++; + + Cls(); + + for(f=0;f<10;f++) + Centre(15+f,((ctr+f)%(NOCOLS-2))+2,"LUNAR LANDER"); + + Centre(25,WHITE,"LUNAR LANDER"); + + Centre(45,RED,level_set); + Centre(46,YELLOW,level_set); + Centre(47,WHITE,level_set); + + if ((ctr/100)%2) + { + Centre(70,RNDCOL,"TOP PILOTS"); + for(f=0;f-2.0)) + { + *land=True; + landing++; + score+=fuel; + fuel+=200; + lev=(lev+1)%no_levels; + do_intro=True; + + for(r=0;r<500;r++) + { + AddParticle(2700-RND(500),RND(10)+10,PULTRA,1); + AddParticle(900+RND(500),RND(10)+10,PULTRA,1); + } + + shipxi=0.0; + shipyi=0.0; + return; + } + else + { + for(r=0;r3599) + lander.ang-=3600; + + for(f=0;f<5;f++) + { + na=(lander.ang+800+RND(200))%3600; + AddParticle(na,8+RND(3),PSHORT,10); + } + } + } + else if ((keymap[LEFT])&&(damage3599) + lander.ang-=3600; + + for(f=0;f<5;f++) + { + na=(lander.ang+800+RND(200))%3600; + AddParticle(na,8+RND(3),PMID,10); + } + } + } + + if ((keymap[THRUST])&&(fuel>0)&&(damageMAXGRAV) + shipxi=MAXGRAV; + + if (shipyi<-MAXGRAV) + shipyi=-MAXGRAV; + + if (shipyi>MAXGRAV) + shipyi=MAXGRAV; + } + + DrawBdrop(); + DrawParticles(); + DrawLevel(); + + if (!dead) + { + DrawObject(&lander); + + if ((ctr/10)%2) + { + if (damage==DAMAGE_NONE) + dmg=NULL; + else if (damage==DAMAGE_LEFT) + dmg="LEFT THRUSTER DAMAGED"; + else if (damage==DAMAGE_RIGHT) + dmg="BOTH SIDE THRUSTERS DAMAGED"; + else + dmg="ALL THRUSTERS DAMAGED!"; + + if(dmg) + Centre(48,WHITE,dmg); + } + } + + XIprintf(img,CH(0,0),WHITE,"Fuel : %4d",fuel); + + if (SHOWVEC) + XIprintf(img,CH(0,WINH-8),WHITE,"xi: %2.3f yi: %2.3f ang: %4d", + shipxi,shipyi,lander.ang); + + /* Check collisions + */ + if ((!landed)&&(!dead)) + CheckCollisions(&landed,&dead); + + Update(); + + if (k==SCALE_UP) + { + if (--scale<2) + scale=0; + + InitBdrop(); + SetScale(scale); + } + + if (k==SCALE_DOWN) + { + if (scale) + scale++; + else + scale=2; + + InitBdrop(); + SetScale(scale); + } + + if (k==QUIT) + { + score=-1; + fuel=0; + first=True; + return XFUNCSTOP; + } + + if ((dead)&&(NoParticles())) + { + first=True; + return XFUNCSTOP; + } + + if ((landed)&&(NoParticles())) + { + first=True; + return XFUNCSTOP; + } + + return XFUNCCONT; +} + + +/* ----------------------------------------------- PAUSE CODE +*/ +static void DoPause(void) +{ + static unsigned int c=0; + + c++; + + if ((c/10)%2) + Centre(WINH/4,WHITE,"PAUSED"); + else + Centre(WINH/4,YELLOW,"PAUSED"); + + Update(); +} + + +static int Paused(int k) +{ + static int paused=False; + + if (k==PAUSE) + paused=!paused; + + if (paused) + DoPause(); + + return paused; +} + + +/* ----------------------------------------------- GAME OVER +*/ +static XFuncControl ProcessGameOver(void) +{ + static int ctr=0; + + Cls (); + + ctr++; + + if ((ctr/10)%2) + Centre(120,WHITE,"GAME OVER"); + + Update(); + + if (GetKey()==NONE) + return XFUNCCONT; + else + return XFUNCSTOP; +} + + +/* ----------------------------------------------- HI SCORES +*/ +static void ReadScores(void) +{ + int fd,f; + + if ((fd=open(HISCFILE,O_RDONLY))==-1) + return; + + for(f=0;f-1;f--) + if (hisc[f].scorepos;f--) + hisc[f]=hisc[f-1]; + + strcpy(hisc[pos].name,""); + hisc[pos].score=score; + hisc[pos].no=landing; + first=False; + } + + Cls(); + + Centre(16,WHITE,"CONGRATULATIONS!"); + Centre(30,YELLOW,"ENTER YOUR INITIALS"); + Centre(40,YELLOW,"FOR THE TOP PILOTS"); + + hisc[pos].name[len]=*let; + hisc[pos].name[len+1]=0; + + for(f=0;fMAXLEVEL)) + err("illegal no of levels"); + + for(f=0;f