home *** CD-ROM | disk | FTP | other *** search
/ Nitro Shareware / NitroShareware_1996.iso / sims / sledacer / sledacer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-13  |  24.9 KB  |  1,157 lines

  1. /* Super Sled Acer - Yet another silly SSA game! */
  2.  
  3. /* modified version of put routines */
  4. #include "slmikes.c"
  5.  
  6. /* externs for PCC's _doint function */
  7.  
  8. extern unsigned _rax, _rbx, _rcx, _rdx, _rsi, _rdi, _res, _rds;
  9. extern char _carryf, _zerof;
  10.  
  11. /* buffer space for shapes */
  12.  
  13. char sled[810],
  14.      enemy[7560],
  15.      man[540],
  16.      blank[270];
  17.  
  18. /* constants */
  19. int tankx[8]={ 0,1,1,1,0,-1,-1,-1 };
  20. int tanky[8]={ -1,-1,0,1,1,1,0,-1 };
  21.  
  22. #define AHEAD 0
  23. #define LEFTS 270
  24. #define RIGHTS 540
  25. #define STEP 270
  26. #define SMALL_STEP 66
  27. #define MID_STEP 130
  28. #define SHOT 738
  29. #define NUMEN 10
  30.  
  31. /* variables */
  32.  
  33. int GAMEON,CGA;
  34. unsigned FIRE,LEFT,RIGHT;
  35. unsigned MAXx,MINx,SCALE;
  36. unsigned LTHRES,RTHRES;
  37. int JOYCAL,KEYMODE;
  38. char LKEY,RKEY,SKEY;
  39. char gp[768];      /* game palette - we get this from the grid .BMP */
  40. int x,y,dist,slspeed,anim;
  41. int level,lives,score,brake,jump;
  42. int ex[NUMEN],ey[NUMEN],et[NUMEN],exd[NUMEN],eyd[NUMEN];
  43. int sizex[NUMEN],sizey[NUMEN];
  44. int time,perfecttime,diff,cheat;
  45. int brakefail,Perfect;
  46.  
  47. main(argc,argv) int argc; char *argv[];
  48. { /* main function */
  49. if (strcmp(argv[1],"-greet")==0)
  50.   greet();
  51.  
  52. mike_init();
  53.  
  54. CGA=0;
  55. if ((*argv[1]=='C')||(*argv[1]=='c'))
  56. { CGA=1;
  57.   puts("\nCGA MODE!\n\n");
  58. }
  59.  
  60. if (CGA)
  61.   set_cga();
  62. else
  63.   set_vga();
  64.  
  65. readdat();
  66. JOYCAL=0;
  67. KEYMODE=0;
  68. MAXx=130;
  69. MINx=126;
  70. LTHRES=127;
  71. RTHRES=129;
  72. SCALE=1;
  73. LKEY='S';
  74. RKEY='D';
  75. SKEY=' ';
  76. diff=2;
  77. score=0;
  78. GAMEON=1;
  79. while(GAMEON)
  80. { if (CGA)
  81.     set_cga();
  82.   else
  83.     set_vga();
  84.  
  85.   load_bmp("sledacer.bmp");
  86.   fade_in(5);
  87.  
  88.   if (score!=0)
  89.   { vprint(232,192,255|0x100,"Score:");
  90.     numprint(280,192,255,score);
  91.   }
  92.  
  93.   waitkey();
  94.  
  95.   if (GAMEON)
  96.   { fade_out(3);
  97.  
  98.     options();
  99.  
  100.     if (GAMEON)
  101.       game();
  102.   }
  103. }
  104. sound_off();
  105. set_txt();
  106. printf("\nSuper Sled Acer - (c)1991-1996 by M.Brent\n\n");
  107. printf("*** SHAREWARE BEG ***\n");
  108. printf("If'n y'all likes this proggie, send a dollar or so of yer local\n");
  109. printf("currency my way, will'ya? If that's too cheap, I 'spose I could be\n");
  110. printf("persuaded to accept more. If that's too rich, send me something\n");
  111. printf("else. I like dolphins. You can get on my good side sending me something\n");
  112. printf("dolphinish. Or send me something neat. Or weird. Or wacky. Send a picture,\n");
  113. printf("a pebble, a piece of a spy satelitte, your car, your cat (especially if\n");
  114. printf("it's a tiger or a lion), your autographed Babe Ruth rookie card, your\n");
  115. printf("non-autographed photo of your best friend, anything to do with Weird Al,\n");
  116. printf("Lion King, video games, electronics. Or just send me a note, via\n");
  117. printf("Email, snail-mail, or fax. And visit my web page. And bug me frequently\n");
  118. printf("to update it. Thanks.\n\n");
  119. printf("M.Brent\n");
  120. printf("113-437 Martin St  Suite 245\n");
  121. printf("Penticton, BC, Canada\n");
  122. printf("V2A 5L1\n\n");
  123. printf("Fax: (604)493-0099 - Specify for Unit 245 on the cover sheet!!\n");
  124. printf("Email: mbrent@awinc.com\n");
  125. printf("WWW: http://www2.awinc.com/users/mbrent\n");
  126. }
  127.  
  128. input()
  129. { /* read the joystick/keyboard and return LEFT,RIGHT (1-8) and FIRE */
  130. int x;
  131. char c;
  132.  
  133. if (JOYCAL)
  134.   LEFT=RIGHT=0;     /* reset values if joystick */
  135.  
  136. FIRE=0;
  137.  
  138. c=scr_csts();
  139. if (c)
  140. { if ((c>='a')&&(c<='z'))
  141.     c=c-32;  /* make uppercase */
  142.  
  143.   if (c==27)
  144.     GAMEON=0;  /* end game on ESC */
  145.  
  146.   if (c==LKEY)
  147.   { if (KEYMODE)
  148.     { if (LEFT<8)
  149.         LEFT++;
  150.     }
  151.     else
  152.       LEFT=8;
  153.     RIGHT=0;
  154.   }
  155.   if (c==RKEY)
  156.   { if (KEYMODE)
  157.     { if (RIGHT<8)
  158.         RIGHT++;
  159.     }
  160.     else
  161.       RIGHT=8;
  162.     LEFT=0;
  163.   }
  164.   if (c==SKEY)
  165.   { LEFT=0;
  166.     RIGHT=0;
  167.   }
  168. }
  169.  
  170. cheat=0;
  171.  
  172. /* use BIOS to read keyboard flags and check for shift keys */
  173. _rax=0x0200;  /* routine 02 */
  174. _doint(0x16);  /* keyboard BIOS int 16h */
  175. if (_rax&0x03) /* either shift key */
  176.   FIRE=1;
  177.  
  178. if ((_rax&0x03)==0x03)
  179. { cheat=1;  /* both shift keys at once activates cheat */
  180.   FIRE=0; /* if you want to slow down, don't cheat :) */
  181. }
  182.  
  183. if (JOYCAL)
  184. { /* read joystick if it was used */
  185.   x=stickx();
  186.   /* now figure out the return values */
  187.   if (x<LTHRES)
  188.   { LEFT=(LTHRES-x)/SCALE;   /* result should be 0-8 */
  189.     if (LEFT>8) LEFT=8;
  190.   }
  191.   if (x>RTHRES)
  192.   { RIGHT=(x-RTHRES)/SCALE;  /* same here */
  193.     if (RIGHT>8) RIGHT=8;
  194.   }
  195.  
  196.   if (joybut())
  197.     FIRE=1;        /* one of the 4 buttons was pressed */
  198. }
  199. /* done */
  200. }
  201.  
  202. waitkey()
  203. { /* wait for space or fire button to be pressed - this does joycal, too */
  204. int wait;
  205. char c;
  206.  
  207. wait=1;
  208. while (wait)
  209. { c=scr_csts();
  210.   if (c==' ')
  211.     wait=0;
  212.   if (c==27)
  213.   { wait=0;
  214.     GAMEON=0;
  215.   }
  216.  
  217.   /* check joystick button */
  218.   if (joybut())  
  219.   { wait=0;        /* one of the 4 buttons was pressed */
  220.     if (JOYCAL==0)
  221.       calibrate();
  222.   }
  223. }
  224. }
  225.  
  226. calibrate()
  227. { /* calibrate the joystick */
  228. int x,y,z,z2,div;
  229.  
  230. JOYCAL=1;
  231. set_txt();
  232. scr_cursoff();
  233.  
  234. puts("\n\nFirst we must calibrate your joystick. This won't hurt.. much..\n");
  235.  
  236. while (joybut());
  237. /* wait for button release */
  238.  
  239. puts("\nJust swirl your joystick in a full circle several times, ensuring\n");
  240. puts("that you reach it's entire maximum range. Press a button when done.\n");
  241. puts("\n(Press <ESC> to abort this if you have no joystick!)\n");
  242. MAXx=0; MINx=9999;
  243. FIRE=0; div=2;
  244. while (FIRE==0)
  245. { x=stickx();
  246.   if (x>MAXx)
  247.     MAXx=x;
  248.   if (x<MINx)
  249.     MINx=x;
  250.  
  251.   while((MAXx-MINx)/div>60)
  252.     div=div*2;
  253.  
  254.   scr_rowcol(12,1);
  255.   scr_clrl();
  256.  
  257.   if (MINx!=9999)
  258.   { z2=40-((mid(MINx,MAXx)-MINx)/div);
  259.     scr_rowcol(12,z2);
  260.     putchar('<');
  261.   }
  262.   else
  263.   { z2=40;
  264.     scr_rowcol(12,40);
  265.     putchar('<');
  266.   }
  267.  
  268.   if (MAXx!=0)
  269.   { scr_rowcol(12,41+((MAXx-mid(MINx,MAXx))/div));
  270.     putchar('>');
  271.   }
  272.  
  273.   scr_rowcol(12,z2+((x-MINx)/div));
  274.   putchar('*');
  275.  
  276.   /* check joystick button */
  277.   if (joybut())   
  278.     FIRE=1;
  279.  
  280.   /* emergency escape */
  281.   if (scr_csts()==27)
  282.     FIRE=2;
  283. }
  284. if (FIRE==1)
  285. { y=MAXx-MINx;   /* get the range */
  286.   x=y/3;         /* three parts... left, right and centered */
  287.   LTHRES=((y/2)+MINx)-(x/2); /* center minus 1/2 one area */
  288.   RTHRES=((y/2)+MINx)+(x/2); /* center plus 1/2 one area */
  289.   SCALE=x/8;               /* 8 positions in one section */
  290.   if (SCALE==0) SCALE=1;  /* just in case it's too low */
  291. }
  292. }
  293.  
  294. int mid(x,y) int x,y;
  295. { /* return the midrange of x->y */
  296. int z;
  297.  
  298. z=y-x;
  299. z=z/2;
  300. z=z+x;
  301. return(z);
  302. }
  303.  
  304. int stickx()
  305. { /* read the joystick x position myself */
  306. /* using inline assembly!! */
  307. #asm
  308.   cli
  309.  
  310.   mov ah,1
  311.   xor al,al
  312.   xor cx,cx
  313.   mov dx,513
  314.   out dx,al
  315. discharge:
  316.   in al,dx
  317.   test al,ah
  318.   loopne discharge
  319.  
  320.   sti
  321.   xor ax,ax
  322.   sub ax,cx
  323. #
  324. /* routine from book 'Tricks of the Game Programming Gurus' */
  325. }
  326.  
  327. int joybut()
  328. { /* directly check the buttons */
  329. int x;
  330.  
  331. _outb(0x201,0);   /* clear the latch */
  332. if ((_inb(0x201)&0xf0)!=0xf0)
  333.   x=1;
  334. else
  335.   x=0;
  336. return(x);
  337. }
  338.  
  339. readdat()
  340. { /* read the character data into the arrays */
  341. int i;
  342.  
  343. load_bmp("sledgrid.bmp");
  344. get(&sled[AHEAD],0,0,16,16);
  345. get(&sled[LEFTS],16,0,16,16);
  346. get(&sled[RIGHTS],32,0,16,16);
  347. get(&enemy[0],48,0,16,16);
  348. get(&enemy[270],64,0,16,16);
  349. get(&enemy[540],80,0,8,8);
  350. get(&enemy[606],88,0,8,8);
  351. get(&enemy[672],80,8,8,8);
  352. get(&enemy[SHOT],88,8,8,8);
  353. get(&enemy[810],96,0,8,16);
  354. get(&enemy[940],96,8,8,16);
  355.  
  356. for (i=0; i<4; i++)
  357.   get(&enemy[1080+(STEP*i)],112+(16*i),0,16,16);
  358.  
  359. for (i=0; i<9; i++)
  360. { get(&enemy[2160+(540*i)],176+(16*i),0,16,16);
  361.   get(&enemy[2430+(540*i)],176+(16*i),16,16,16);
  362. }
  363.  
  364. get(&enemy[7020],32,16,16,16);
  365. get(&enemy[7290],48,16,16,16);
  366.  
  367. get(&man[0],0,16,8,8);
  368. get(&man[66],8,16,8,8);
  369. get(&man[132],16,16,8,8);
  370. get(&man[198],24,16,8,8);
  371. get(&man[264],0,24,8,8);
  372. get(&man[330],8,24,8,8);
  373. get(&man[396],16,24,8,8);
  374. get(&man[462],24,24,8,8);
  375.  
  376. for (i=0; i<768; i++)
  377.   gp[i]=tp[i];        /* save palette */
  378. }
  379.  
  380. greet()
  381. { /* do the traditional greet screen */
  382. printf("\n\n\nHere we go again!\n");
  383. printf("Special greetings go out to:\n\n");
  384. printf("Aslan the Golden Lion: who has given me love and forgiveness,\n");
  385. printf("but is still far too busy. :/\n");
  386. printf("Orzel the Naughty Eagle: My #1 groupie, silly bird, confident, and friend.\n");
  387. printf("Peggy Hanks the Person: :) Who sent me my first fan-mail :) :)\n");
  388. printf("Mind Grind 'Cyber-Cafe': great little place in Kelowna, BC, who hath\n");
  389. printf("provided much stimulating chocolate mocha to me. :)\n");
  390. printf("Dolfin the Dolphin: for understanding.\n");
  391. printf("Anyone who has uploaded my stuff anywhere: Thanks! I need the exposure!\n\n");
  392. printf("Here are go... still working... finally got back to it. :)\n");
  393. printf("I need more inspiration. :) Well.. Super Sales Acer is, amazingly\n");
  394. printf("enough, due to be published on two shareware CDs... one being\n");
  395. printf("GameHead #7, the other I have no idea because they won't tell me!\n");
  396. printf("(But they figured they could send me a copy when it's released,\n");
  397. printf("so I guess that's cool.) Yeah... I'm asking for a donation or two\n");
  398. printf("now, but don't take it too seriously. When the games *deserve* money,\n");
  399. printf("I'll make sure you pay. >:) If not... pay if you want, don't if you\n");
  400. printf("don't, but keep the game either way. :)\n");
  401. printf("                                          Ta Ta!\n\n");
  402. exit(0);
  403. }
  404.  
  405. show(x,a) char *x,a;
  406. { /* used for the option menu, mostly :) */
  407. int y;
  408.  
  409. y=(80-strlen(x))/2;
  410. scr_rowcol(3,y);
  411. scr_aputs(x,a);
  412. scr_scdn();
  413. delay(speed);
  414. }
  415.  
  416. options()
  417. { /* do option screen! */
  418. int x;
  419. char c;
  420.  
  421. x=1;
  422. while (x)
  423. { set_txt();
  424.   scr_cursoff();
  425.   scr_rowcol(1,15);
  426.   scr_aputs("(another diversion brought to you by Mike Brent!)",9);
  427.   scr_rowcol(0,32);
  428.   scr_aputs("Super Sled Acer",7);
  429.  
  430.   while (joybut());
  431.  
  432.   show("(c)1991, 1996 by Mike Brent (originally on the TI-99/4A)",1);
  433.   show("---",8);
  434.   show("SPACE or FIRE to begin, ESC to quit",15);
  435.   show("---",8);
  436.   show("(R)ead instructions                                    ",11);
  437.   show("(C)alibrate joystick                                   ",11);
  438.   show("(D)ifficulty:                                          ",11);
  439.   show("(M)ode (used for keyboard control only):               ",11);
  440.   show("(Either SHIFT key to activate the brakes)",3);
  441.   show("(K)eys: (Turn Left: x   Go Straight: x   Turn Right: x)",11);   
  442.   show("---",8);
  443.   show("OPTIONS",2);
  444.   show("---",8);
  445.   show("Overuse may cause failure!! Good Luck, Super Sled Acer!",4);
  446.   show("positive braking system, only a simple aid to slow down!",4);
  447.   show("braking system. -WARNING- this is not designed to have a",4);
  448.   show("Your only aid will be your quick reflexes, and a simple",4);
  449.   show("down Doom Mountain, avoiding all obstacles in your path.",4);
  450.   show("Your Mission: Navigate your Super Sno-Speed Racer successfully",4);
  451.   show("---",8);
  452.   scr_rowcol(14,32);
  453.   scr_co(LKEY);
  454.   scr_rowcol(14,49);
  455.   if (SKEY==' ')
  456.     puts("SPC");
  457.   else
  458.     scr_co(SKEY);
  459.   scr_rowcol(14,65);
  460.   scr_co(RKEY);
  461.   scr_rowcol(16,53);
  462.   if (KEYMODE)
  463.     puts("Proportional");
  464.   else
  465.     puts("Direct");
  466.   scr_rowcol(17,26);
  467.   switch (diff)
  468.   { case 1: puts("Expert"); break;
  469.     case 2: puts("Normal"); break;
  470.     case 3: puts("Easier"); break;
  471.     default:puts("??????");
  472.   }
  473.   x=1;
  474.   while (x==1)
  475.   { c=scr_csts();
  476.     if (c==' ') x=0;
  477.     if (c==27) x=0;
  478.     if (joybut())
  479.     { x=0;
  480.       if (JOYCAL==0)
  481.         calibrate();
  482.     }
  483.     if ((c>='a')&&(c<='z')) c=c-32;
  484.     switch(c)
  485.     { case 'C': calibrate();
  486.                 x=2;
  487.                 break;
  488.       case 'R': readdoc();
  489.                 x=2;      /* exit this loop, but not the big one - redraw */
  490.                 break;
  491.       case 'M': if (KEYMODE)
  492.                   KEYMODE=0;
  493.                 else
  494.                   KEYMODE=1;
  495.                 scr_rowcol(16,53);
  496.                 if (KEYMODE)
  497.                   puts("Proportional");
  498.                 else
  499.                   puts("Direct      ");
  500.                 break;
  501.       case 'K': LKEY=blinkget(14,32);
  502.                 SKEY=blinkget(14,49);
  503.                 if (SKEY==' ')
  504.                 { scr_rowcol(14,49);
  505.                   puts("SPC");
  506.                 }
  507.                 else
  508.                 { scr_rowcol(14,50);
  509.                   puts("  ");
  510.                 }
  511.                 RKEY=blinkget(14,65);
  512.                 break;
  513.       case 'D': diff--;
  514.                 if (diff<1) diff=3;
  515.                 scr_rowcol(17,26);
  516.                 switch (diff)
  517.                 { case 1: puts("Expert"); break;
  518.                   case 2: puts("Normal"); break;
  519.                   case 3: puts("Easier"); break;
  520.                   default:puts("??????");
  521.                 }
  522.                 break;
  523.     } /* case */
  524.   } /* inner WHILE */
  525. } /* outer WHILE */
  526. if (c==27) GAMEON=0;
  527. }
  528.  
  529. int blinkget(r,c) int r,c;
  530. { /* flash a cursor and get 1 keypress */
  531. char x;
  532. int i;
  533.  
  534. x=0; i=0;
  535. while (x==0)
  536. { scr_rowcol(r,c);
  537.   if (i<30)
  538.     scr_co('*');
  539.   else
  540.     scr_co(' ');
  541.   i++;
  542.   if (i>59) i=0;
  543.   delay(speed);
  544.   x=scr_csts();
  545. }
  546. if ((x>='a')&&(x<='z'))
  547.   x=x-32;
  548. scr_rowcol(r,c);
  549. scr_co(x);
  550. return(x);
  551. }
  552.  
  553. readdoc()
  554. { /* display the SLEDACER.DOC file to the screen for the user */
  555. FILE *fp;
  556. int i,i2;
  557. char *fl,buf[81],c;
  558.  
  559. cls();
  560. fp=fopen("sledacer.doc","r");
  561. scr_rowcol(24,0);
  562. if (fp==NULL)
  563. { scr_aputs("* Unable to load SLEDACER.DOC *",14);
  564.   delay(speed*60);
  565. }
  566. else
  567. { i=-1;
  568.   fl=1;
  569.   buf[0]=0;
  570.   while (fl)
  571.   { scr_aputs(buf,7);
  572.     i++;
  573.     if (i==20)
  574.     { scr_aputs("\n-- More - Space or Fire to continue, <ESC> to abort --",8);
  575.       i2=1;
  576.       while (joybut());
  577.       while (i2)
  578.       { if (joybut()) i2=0;
  579.         c=scr_csts();
  580.         if (c==' ') i2=0;
  581.         if (c==27) { i2=0; fl=0; }
  582.       }
  583.     puts("\n\n");
  584.     i=0;
  585.     }
  586.     if (fl)
  587.       fl=fgets(buf,80,fp);
  588.   }
  589.   fclose(fp);
  590.   if (c!=27)
  591.   { scr_aputs("\n**Done** Press Space or Fire to continue",8);
  592.     i2=1;
  593.     while (joybut());
  594.     while (i2)
  595.     { if (joybut()) i2=0;
  596.       c=scr_csts();
  597.       if (c==' ') i2=0;
  598.     }
  599.   }
  600. }
  601. }
  602.  
  603. game()
  604. { /* play the game once */
  605. int i,i2;
  606. char xs[80];
  607.  
  608. if (CGA)
  609.   set_cga();
  610. else
  611.   set_vga();
  612.  
  613. for (i=0; i<768; i++)
  614.   tp[i]=gp[i];    /* load game palette */
  615.  
  616. fade_in(3);
  617.  
  618. level=1;
  619. lives=3;
  620. score=0;
  621.  
  622. while ((level>=1)&&(level<=9)&&(GAMEON))
  623. { /* main level loop: 0 = dead... 10 = win... */
  624.   cls();
  625.  
  626.   if (CGA)  /* gotta fill the screen with white */
  627.     for (i=0; i<200; i++)
  628.       for (i2=0; i2<scrn_lines; i2++)
  629.         _poke(0xff,line_table[i]+i2,scrn_base);
  630.  
  631.   get(blank,0,0,16,16);
  632.   
  633.   vprint(0,0,255,"Score:");
  634.   numprint(56,0,255,score);
  635.   vprint(0,8,255,"Level:");
  636.   numprint(56,8,255,level);
  637.   vprint(0,16,255,"Lives:");
  638.   numprint(56,16,255,lives);
  639.   vprint(0,24,255,"Brake:");
  640.   for (i=0; i<20; i++)
  641.     vprint(56+(i*8),24,255,"-");
  642.   vprint(200,0,255,"Distance:    %");
  643.   vprint(200,8,255,"Time:");
  644.  
  645.   Perfect=1;
  646.  
  647.   x=152; y=70;
  648.   put(&sled[AHEAD],x,y);
  649.  
  650.   strcpy(xs,"Mission x");
  651.   xs[8]=level+48;
  652.   vprint(120,120,255,xs);
  653.  
  654.   for (i=0; i<NUMEN; i++)
  655.     et[i]=-1;
  656.  
  657.   brake=0;
  658.   brakefail=0;
  659.   jump=0;
  660.  
  661.   while (scr_csts());  /* wait for clear keyboard/joystick */
  662.   while (joybut());
  663.  
  664.   strcpy(xs,"Watch for ");
  665.   switch (level)
  666.   { case 1: strcat(xs,"trees"); break;
  667.     case 2: strcat(xs,"rocks"); break;
  668.     case 3: strcat(xs,"skiers"); break;
  669.     case 4: strcat(xs,"snowmobiles"); break;
  670.     case 5: strcat(xs,"jumps"); break;
  671.     case 6: strcat(xs,"snowmen"); break;
  672.     case 7: strcat(xs,"avalanches"); break;
  673.     case 8: strcat(xs,"tanks"); break;
  674.     case 9: strcat(xs,"missiles"); break;
  675.   }
  676.   vprint(160-((strlen(xs)*8)/2),128,255,xs);
  677.  
  678.   waitkey();
  679.  
  680.   for (i=0; i<320; i=i+16)
  681.     put(blank,i,120);
  682.  
  683.   anim=0;
  684.   dist=0;
  685.   time=0;
  686.   perfecttime=241+((level-1)*50);
  687.   slspeed=0;
  688.  
  689.   while ((dist<1500+(level*400))&&(GAMEON))
  690.   { moveenemy();
  691.     sound_off();
  692.     if (jump)
  693.     { jump--;
  694.       if (jump==0) sound_on(1000);
  695.       score++;
  696.       put(blank,x,y);
  697.       if (jump%3==0)
  698.         if (jump>24)
  699.           y--; 
  700.         else
  701.           y++;
  702.       put(&sled[AHEAD],x,y);
  703.     }
  704.     else
  705.     { moveplayer();
  706.       check();
  707.     }
  708.     update();
  709.     delay(speed*diff);
  710.   }
  711.  
  712.   if (dist>=10000)
  713.     level=0;
  714.   else
  715.     if (GAMEON)
  716.     { finlevel();
  717.       level++;
  718.     }
  719. }
  720.  
  721. if (level==0)
  722.   gameover();
  723.  
  724. if (level==10)
  725.   gamewin();
  726. }
  727.  
  728. moveplayer()
  729. { /* move the player */
  730. int i,ox,oy,s,z;
  731. char failstr[21],qw[3];
  732.  
  733. strcpy(failstr,"******FAILURE!******");
  734.  
  735. input();
  736. ox=x; oy=y;
  737.  
  738. if ((FIRE==0)||(brakefail))
  739. { if (slspeed<8) slspeed++;
  740.   if ((brake>0)&&(anim%10==0))
  741.   { brake--;
  742.     vprint(56+brake*8,24,255|0x100,"-");
  743.   }
  744. }
  745. else
  746. { if (slspeed<3) slspeed++;
  747.   if (slspeed>3) slspeed--;
  748.   if ((brake<20)&&(anim%5==0))
  749.   { brake++;
  750.     vprint(48+brake*8,24,255|0x100,">");
  751.   }
  752.   if (brake==20)
  753.   { brake=0;
  754.     qw[1]=0;
  755.     for (i=0; i<20; i++)
  756.     { qw[0]=failstr[i];
  757.       vprint(56+i*8,24,255|0x100,qw);
  758.     }
  759.     brakefail=120;
  760.   }
  761. }
  762.  
  763. if (brakefail)
  764. { brakefail--;
  765.   if (brakefail<1)
  766.   { for (i=0; i<20; i++)
  767.       vprint(56+i*8,24,255|0x100,"-");
  768.   }
  769. }
  770.  
  771. s=AHEAD;
  772.  
  773. if (LEFT)
  774. { s=LEFTS;
  775.   z=(LEFT-(8-slspeed));
  776.   if (z>0)
  777.     x=x-z;
  778.   if (x<3) x=3;
  779. }
  780.  
  781. if (RIGHT)
  782. { s=RIGHTS;
  783.   z=(RIGHT-(8-slspeed));
  784.   if (z>0)
  785.     x=x+z;
  786.   if (x>300) x=300;
  787. }
  788.  
  789. put(blank,ox,oy);
  790. put(&sled[s],x,y);
  791. }
  792.  
  793. moveenemy()
  794. { /* move/start all enemies */
  795. int t,i,i2,z,ox,oy,s;
  796.  
  797. t=(rand()%13)+1; /* (1-10) */
  798. if (t<=level)
  799. { /* new enemy attempt */
  800.   z=-1;
  801.   for (i=0; i<NUMEN; i++)
  802.     if (et[i]==-1)
  803.       z=i;
  804.   if (z!=-1)
  805.   { switch (t)
  806.     { case 1: et[z]=0; ex[z]=rand()%304; ey[z]=199;
  807.               exd[z]=0; eyd[z]=0; break;
  808.       case 2: et[z]=1; ex[z]=rand()%304; ey[z]=199;
  809.               exd[z]=0; eyd[z]=0; break;
  810.       case 3: et[z]=2; ex[z]=0; ey[z]=rand()%100+70;
  811.               exd[z]=7; eyd[z]=4; break;
  812.       case 4: et[z]=3; ex[z]=304; ey[z]=rand()%100+70;
  813.               exd[z]=-(rand()%5+5); eyd[z]=0; break;
  814.       case 5: et[z]=4; ex[z]=rand()%304; ey[z]=199;
  815.               exd[z]=0; eyd[z]=0; break;
  816.       case 6: et[z]=5; ex[z]=rand()%304; ey[z]=199;
  817.               exd[z]=0; eyd[z]=0; break;
  818.       case 7: et[z]=26; ex[z]=rand()%304; ey[z]=10;
  819.               exd[z]=0; eyd[z]=rand()%4+9; break;
  820.       case 8: et[z]=8; ex[z]=rand()%304; ey[z]=199;
  821.               exd[z]=0; eyd[z]=-1; break;
  822.       case 9: et[z]=24; ex[z]=rand()%304; ey[z]=199;
  823.               exd[z]=0; eyd[z]=-7; break;
  824.     }
  825.   }
  826. }
  827.  
  828. /* move the enemies */
  829. for (i=0; i<NUMEN; i++)
  830. { if (et[i]!=-1)
  831.   { ox=ex[i]; oy=ey[i];
  832.     s=et[i]*STEP;
  833.     switch (et[i])
  834.     { case 2: if (exd[i]>7)
  835.                 exd[i]=7;
  836.               if (exd[i]==7)
  837.                 if (anim%55==0)
  838.                   exd[i]=5;
  839.               if (exd[i]<7)
  840.               { s=s+SMALL_STEP;
  841.                 if (exd[i]==6)
  842.                   s=s+SMALL_STEP;
  843.                 exd[i]++;
  844.               }
  845.               break;
  846.       case 3: if (anim%2)
  847.                 s=s+MID_STEP;
  848.               break;
  849.       case 5: if ((exd[i]>7)||(exd[i]<-7))
  850.                 exd[i]=0;
  851.               if ((exd[i]==0)&&(rand()%55==3))
  852.                 exd[i]=sgn(x-ex[i]);
  853.               if (exd[i])
  854.               { exd[i]=exd[i]+sgn(x-ex[i]);
  855.                 s=s+STEP;
  856.                 if (anim%2)
  857.                   s=s+STEP;
  858.               }
  859.               break;
  860.       case 26:
  861.       case 24: if (anim%2)
  862.                  s=s+STEP;
  863.                break;
  864.       case 8:
  865.       case 10:
  866.       case 12:
  867.       case 14:
  868.       case 16:
  869.       case 18:
  870.       case 20:
  871.       case 22: z=(et[i]-8)/2;
  872.                if ((tankx[z]!=sgn(x-ex[i]))||(tanky[z]!=sgn(y-ey[i])))
  873.                { /* need to re-aim tank */
  874.                  if (anim%4==0) /* slowly */
  875.                  { et[i]=et[i]+(2*sgn(x-ex[i]));
  876.                    if (et[i]<8) et[i]=22;
  877.                    if (et[i]>22) et[i]=8;
  878.                    s=et[i]*STEP;
  879.                  }
  880.                }
  881.                if (anim%2)
  882.                  s=s+STEP;
  883.                if (rand()%10==0)
  884.                { /* fire */
  885.                  z=-1;
  886.                  for (i2=0; i2<NUMEN; i2++)
  887.                    if ((et[i2]==-1)&&(z==-1))
  888.                      z=i2;
  889.                  if (z!=-1)
  890.                  { et[z]=28; ex[z]=ex[i]; ey[z]=ey[i];
  891.                    exd[z]=tankx[(et[i]-8)/2]*5;
  892.                    eyd[z]=tanky[(et[i]-8)/2]*5;
  893.                  }
  894.                }
  895.                break;
  896.       case 28: s=SHOT;
  897.                break;
  898.     } /* case */
  899.     ex[i]=ex[i]+exd[i];
  900.     ey[i]=ey[i]+eyd[i]-slspeed;
  901.     put(blank,ox,oy);
  902.     if (offscreen(ex[i],ey[i]))
  903.       et[i]=-1;
  904.     else
  905.     { put(&enemy[s],ex[i],ey[i]);
  906.       sizex[i]=(char)enemy[s+1];
  907.       sizey[i]=(char)enemy[s];
  908.     }
  909.   } /* if */
  910. } /* for */
  911. } /* function */
  912.  
  913. int abs(x) int x;
  914. { /* return absolute value of x */
  915. if (x<0) x=-x;
  916. return(x);
  917. }
  918.  
  919. check()
  920. { /* check for collision and deal with it. Level=0 if player game over */
  921. int i,c,x1,y1,x2,y2,r;
  922.  
  923. c=0;
  924. for (i=0; i<NUMEN; i++)
  925. { if (et[i]!=-1)
  926.   { x1=ex[i]+(sizex[i]>>1);
  927.     y1=ey[i]+(sizey[i]>>1);
  928.     x2=x+8;
  929.     y2=y+8;
  930.     r=(sizex[i]>>1);
  931.     if ((abs(x1-x2)<=r)&&(abs(y1-y2)<=r)&&(cheat==0))
  932.     { if (et[i]==4)
  933.       { jump=48;
  934.         sound_on(220);
  935.       }
  936.       else
  937.         c=1;
  938.     }
  939.   }
  940. }
  941. if (c)
  942. { crash();
  943.   lives--;
  944.   Perfect=0;
  945.   dist=dist/2;
  946.   numprint(56,16,255,lives);
  947.   if (lives)
  948.   { for (i=0; i<NUMEN; i++)
  949.       if (et[i]!=-1)
  950.       { put(blank,ex[i],ey[i]);
  951.         et[i]=-1;
  952.       }
  953.     put(blank,x,y);
  954.     x=152;
  955.     y=70;
  956.     put(&sled[AHEAD],x,y);
  957.     brake=0;
  958.     if (brakefail)
  959.       brakefail=1;  /* trick other routine into resetting display */
  960.   }
  961.   else
  962.     dist=10000;
  963. }
  964. }
  965.  
  966. crash()
  967. { /* animate the crash */
  968. int i,x2,y2,a,d;
  969.  
  970. x2=x+4;
  971. y2=y+14;
  972. a=0;
  973. d=1;
  974. for (i=0; i<16; i++)
  975. { put(blank,x2,y2);
  976.   y2++;
  977.   put(&man[a*SMALL_STEP],x2,y2);
  978.   a=a+d;
  979.   if (a==4) d=-1;
  980.   if (a==0) d=1;
  981.   delay(speed);
  982. }
  983. put(blank,x2,y2);
  984. y2++;
  985. put(&man[SMALL_STEP*5],x2,y2);
  986. delay(speed*4);
  987. for (i=0; i<10; i++)
  988. { put(&man[SMALL_STEP*6],x2,y2);
  989.   delay(speed*2);
  990.   put(&man[SMALL_STEP*7],x2,y2);
  991.   delay(speed*2);
  992. }
  993. delay(speed*4);
  994. put(blank,x2,y2);
  995. }
  996.  
  997. int offscreen(x,y) int x,y;
  998. { /* return true if x or y is offscreen */
  999. int z;
  1000.  
  1001. z=0;
  1002.  
  1003. if ((x<0)||(x>304))
  1004.   z=1;
  1005.  
  1006. if ((y<8)||(y>199))
  1007.   z=1;
  1008.  
  1009. return(z);
  1010. }
  1011.  
  1012. int sgn(x) int x;
  1013. { /* return sign of x */
  1014. int z;
  1015.  
  1016. z=0;
  1017.  
  1018. if (x<0) z=-1;
  1019. if (x>0) z=1;
  1020. return(z);
  1021. }
  1022.  
  1023. update()
  1024. { /* update displays */
  1025. unsigned z;
  1026.  
  1027. score=score+slspeed;
  1028. numprint(56,0,255,score);
  1029. time++;
  1030. numprint(248,8,255,time);
  1031. dist=dist+slspeed;
  1032. if (dist==0) dist=1;
  1033. z=dist/((1500+(level*400))/100);
  1034. numprint(280,0,255,z);
  1035. anim++;
  1036. }
  1037.  
  1038. finlevel()
  1039. { /* end of level stuff */
  1040. int z;
  1041. slspeed=0;
  1042. while (y<196)
  1043. { moveenemy();
  1044.   put(blank,x,y);
  1045.   y=y+8;
  1046.   put(&sled[AHEAD],x,y);
  1047.   delay(speed*diff);
  1048. }
  1049. put(blank,x,y);
  1050. vprint(80,80,255,"Time:");
  1051. delay(speed*20);
  1052. numprint(200,80,255,time);
  1053. delay(speed*20);
  1054. vprint(80,100,255,"Percentage:");
  1055. delay(speed*20);
  1056. z=((time-perfecttime)*100)/perfecttime;
  1057. z=100-z;
  1058. if ((Perfect)&&(z==100))
  1059. { vprint(200,100,255,"PERFECT!");
  1060.   z=1000;
  1061. }
  1062. else
  1063. { numprint(200,100,255,z);
  1064.   z=z*5;
  1065. }
  1066. delay(speed*20);
  1067. vprint(80,120,255,"Bonus:");
  1068. delay(speed*20);
  1069. numprint(200,120,255,z);
  1070. score=score+z;
  1071. numprint(56,0,255,score);
  1072. delay(speed*60);
  1073. delay(speed*60);
  1074. }
  1075.  
  1076. gameover()
  1077. { /* game over routine */
  1078. int y,x,ys;
  1079. int i1;
  1080. char buf[580];
  1081. char buf2[580];
  1082.  
  1083. y=33; x=124; ys=1;
  1084. get(buf2,x,y,8,72);
  1085. vprint(x,y,255|0x100,"GAME OVER");
  1086. get(buf,x,y,8,72);
  1087.  
  1088. while (y<190)
  1089. { put(buf2,x,y);
  1090.   y=y+ys;
  1091.   get(buf2,x,y,8,72);
  1092.   put(buf,x,y);
  1093.   ys++;
  1094.   delay(speed*2);
  1095. }
  1096.  
  1097. while (ys)
  1098. { put(buf2,x,y);
  1099.   y=y-ys;
  1100.   get(buf2,x,y,8,72);
  1101.   put(buf,x,y);
  1102.   ys=ys-2;
  1103.   if (ys<0) ys=0;
  1104.   delay(speed*2);
  1105. }
  1106.  
  1107. for (i1=0; i1<256; i1++)
  1108. { vprint(x,y,i1,"GAME OVER");
  1109.   delay(speed);
  1110. }
  1111. }
  1112.  
  1113. gamewin()
  1114. { /* game win routine */
  1115. int i,i1,i2;
  1116.  
  1117. fade_out(3);
  1118. load_bmp("sledwin.bmp");
  1119. fade_in(2);
  1120. for (i2=0; i2<100; i2=i2)
  1121. { for (i1=0; i1<255; i1++)
  1122.   { i=i1*3;
  1123.     if ((tp[i]==tp[i+1])&&(tp[i]==tp[i+2])&&(tp[i]!=63)&&(tp[i]>50))
  1124.     { tp[i]=tp[i]-1;
  1125.       if (tp[i]<51)
  1126.         tp[i]=62;
  1127.       tp[i+1]=tp[i];
  1128.       tp[i+2]=tp[i];
  1129.       colour(i1,tp[i],tp[i+1],tp[i+2]);
  1130.     }
  1131.   }
  1132.   delay(speed);
  1133.   if (scr_csts()) i2=1001;
  1134. }
  1135. set_txt();
  1136. scr_cursoff();
  1137. show("<press ESC to exit>",10);
  1138. show("---",8);
  1139. show("Great work, and thanks for playing!!",6);
  1140. show("---",8);
  1141. show("be invincible!",5);
  1142. show("if you hold down BOTH Shift keys you will",5);
  1143. show("Not many ways to cheat in this one, but",5);
  1144. show("---",8);
  1145. show("Next up is At the Races, then Super Speed Acer!",3);
  1146. show("2 months late. Oh well, it's all in fun. :)",3);
  1147. show("Finally finished and released on 13 March 1996, at least",3);
  1148. show("---",8);
  1149. show("of Doom Mountain! Congratulations!",9);
  1150. show("You have successfully navigated your way to the bottom",9);
  1151. show("---",8);
  1152. show("YOU MADE IT!",11);
  1153. while (scr_csts()!=27);
  1154. }
  1155.  
  1156.  
  1157.