home *** CD-ROM | disk | FTP | other *** search
/ Club Amiga de Montreal - CAM / CAM_CD_1.iso / files / 097.lha / Ic.Source / action.c next >
C/C++ Source or Header  |  1986-11-20  |  30KB  |  1,097 lines

  1. /*
  2.  
  3. InvaderCraft von J.Hertel
  4. (C) CW-Publikationen
  5.  
  6.   "action.c"
  7.  
  8.  
  9. Kompilieren mit Aztec C Version 3.20a.
  10.  
  11. Im Include-Directory muessen sich die Header-Files "invadercraft1.h" und
  12. "invadercraft2.h" befinden!
  13.  
  14. Aufruf:  cc action -a -e400
  15.          as action
  16.  
  17. Linken:  siehe invadercraft.c
  18.  
  19. */
  20.  
  21. #include <exec/types.h>
  22. #include <graphics/gfx.h>
  23. #include <graphics/rastport.h>
  24. #include <graphics/view.h>
  25. #include <hardware/custom.h>
  26. #include <hardware/cia.h>
  27.  
  28. /* Vor Compiler-Aufruf unbedingt "invadercraft1.h" und "invadercraft2.h"
  29. in include/ - Directory kopieren! */
  30.  
  31. #include <invadercraft1.h>
  32. #include <invadercraft2.h>
  33.  
  34. extern struct GfxBase *GfxBase;
  35. extern struct RastPort rp,rp2,rphi;
  36. extern struct BitMap bmhi,bm,bm2,inb,schb,misb,expb,bunb,dummyb,mistreb,
  37. mutb,bunkerbuff[2],ab1,titelbild,bssb,bsib;
  38. extern struct ViewPort vp,vphi;
  39. extern struct Custom *custom;
  40. extern struct CIA *ciaa;
  41.  
  42. extern struct liste slots[MAXVERSIONS][SLOTS];
  43. extern UWORD color[],color1[];
  44. extern USHORT rnd;
  45. extern int trainer,kick,INBEWVERZ[],EIZAEMAXNORM[],MUTZAEMAX[],SCHZAEMAX[],
  46. MISANZ[],MISZAEMAX[],MISWK[],GEZIELTEWK[],ANZPANZER[];
  47. extern long YA1[],YA[],MITTE[],EIXD[],MUTD[],SCHD[],MISD[];
  48.  
  49. UWORD *colorp;
  50. long KO2[2]={15L,17L},INYD[]={13L,17L},mutoff,BPRS,BPRI,GAMEOVERY;
  51.  
  52. ULONG score[MAXVERSIONS][2],hiscore[MAXVERSIONS],frei[ANZFREIPANZER+1]={
  53.  
  54. /* ab dieser Punktzahl gibt es jeweils einen Freipanzer; ANZFREIPANZER
  55. ist die Anzahl an moeglichen Freipanzern (im Headerfile zu aendern) */
  56.  
  57. 4999,9999,19999,49999,99999,199999,499999
  58. ,0xffffffff};
  59.  
  60. /* Y-Koordinaten der sensitiven Punkte der Missiles */
  61. long misyhs[MHSANZ]={3L,8L,MKO4-1L};   /* aufsteigende Reihenfolge */
  62.  
  63. /* Aufstellung der Invaders pro Level */
  64. int levelmin[MAXLEVEL]={1,3,5,7,9,11,13,15,17,19,21,23,24,25,25,25};
  65. int levelh[MAXLEVEL]={4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6};
  66. int levelb[MAXLEVEL]={7,8,8,8,9,9,9,10,10,10,10,10,10,10,10,10};
  67. int levela[2][MAXLEVEL]={{0,0,0,1,1,2,1,1,1,2,2,2,2,2,2,2},
  68.                          {0,1,1,2,2,2,1,2,2,3,3,4,4,4,4,4}};
  69.  
  70. int freipanz[2],invor[KO5][KO6],invor1[KO5],invor2[KO5],invor3,invaderanz,
  71. inligre,inregre,inobgre,inungre,strigzae,eizae,eizaemax,mutzae,miszae1,
  72. miszae1max,schzae,miszae,player,abschuss,inbewsound,ship[2],anzplay,anzplay1,
  73. version,level[2],demo,demolevel;
  74. long mutphase,eiphase,mutxd,inxd,inx,inphase,inphased,iny,regre,ligre,ungre,
  75. obgre,aligre,aregre,aungre,aobgre,mutx,schx,schy,by,eix,eiy,eiligre,eiregre,
  76. inbewsoundzae,mutbewsoundzae,eibewsoundzae,playx[2]={90,470},time;
  77.  
  78. char *txt[2]={"Player1","Player2"};
  79. #define LEN 7L  /* Laenge der obigen Texte */
  80.  
  81. char *text[2]={"  Ready  ","Game over"};
  82. #define LEN2 9L  /* s.o. */
  83.  
  84. struct Vorddef {
  85.    int invor[KO5][KO6],invaderanz,inligre,inregre,inobgre,inungre;
  86.    long inxd,inx,inphase,inphased,iny,regre,ligre,ungre,obgre;
  87.    } vd[2];
  88.  
  89. struct schmis {
  90.    long x,y;
  91.    int phase;
  92.    BYTE flag;
  93.    } schuss,mis[MISANZMAX];
  94.  
  95. anfang()
  96. /* einmalige Initialisierungen und Aufruf des Hauptmenues */
  97. {
  98.    int i,j;
  99.    UBYTE *diskreg=0xBFD100;
  100.  
  101.    *diskreg|=0x80;   *diskreg|=0x08;   *diskreg&=0xf7; /* Disk-Motor aus */
  102.  
  103.    GAMEOVERY=MITTE[kick]+VY;
  104.    aligre=VX; aregre=XA1+VX; aobgre=MUTKO4+MUTY+4; aungre=YA1[kick]+VY;
  105.    eiregre=aregre-KO3+1; eiligre=aligre; eiy=aungre-KO4+1;
  106.    by=eiy-SAY-BKO4+1; miszae1max=MKO4/MISD[version];
  107.    BPRS=BSSWIDTH/8; BPRI=BSIWIDTH/8; BPRS+=BPRS%2; BPRI+=BPRI%2;
  108.  
  109.    sternsetz();
  110.    for (i=0;i<3;i++)
  111.       hiscore[i]=slots[i][0].score;
  112.    hauptmenu();
  113. }
  114.  
  115. spiel(plr)
  116. BYTE plr;
  117. /* Beginn des Spiels, plr ist Nummer des Spielers (fuer Two Player Game) */
  118. {
  119.    int i;
  120.    BYTE status;
  121.  
  122. /* Befindet sich das Programm im Demo-Modus (siehe menues.c), so ist die
  123. Variable 'demo' ungleich Null (siehe menues.c) */
  124.    if(demo==0) {
  125.       level[0]=level[1]=0; score[version][0]=0; ship[0]=ANZPANZER[version];
  126.       if(plr) {
  127.           score[version][1]=0;
  128.           ship[1]=ANZPANZER[version];
  129.       }
  130.       freipanz[0]=0; freipanz[1]=0;
  131.    }
  132.    else {
  133.       if(demolevel==2)
  134.          demolevel=7;
  135.       else
  136.          demolevel=2;
  137.       level[0]=demolevel;
  138.    }
  139.    anzplay=plr; anzplay1=anzplay+1; player=0;
  140.    setup();
  141.    if(demo==0) {
  142.       titrest();
  143.       textanz(0);
  144.    }
  145.    player=1;
  146.    bunker();
  147.    storeplayer();
  148.    setupnextplayer();
  149.    player=0;
  150.    storeplayer();
  151.    setupnextplayer();
  152.    einblenden(color,0);
  153.  
  154.    do {
  155.       if(anzplay1==2) {
  156.          setupnextplayer();
  157.       }
  158.       time=0;
  159.   trainerlabel:
  160.       do {
  161. /* Alles bewegen, bis kein Invader mehr da ist, der Panzer getroffen oder
  162. mit der linken Maustaste unterbrochen wird */
  163.          status=inbew();
  164.          if(status==KEINE_IN_MEHR) {
  165.             for(i=0;i<PAUSE;i++) {
  166.                if(status=leer()) {   /* einen Augenblick warten */
  167.                   break;
  168.                }
  169.                status=KEINE_IN_MEHR;
  170.             }
  171.             if(status==KEINE_IN_MEHR) {
  172.                level[player]++;        /* neue Aufstellung */
  173.                setup();
  174.                bunker();
  175.             }
  176.          }
  177.       } while(status==KEINE_IN_MEHR);
  178.       if(demo==0 && status!=QUIT && trainer!=0) {
  179.          if (status==UEBERROLLT) {
  180.             ueber();
  181.             ausblenden(0);
  182.             SetRast(&rp,0L);
  183.             SetRast(&rp2,0L);
  184.             einblenden(color,0);
  185.             level[player]++;
  186.             setup();
  187.             bunker();
  188.          }
  189.          goto trainerlabel;
  190.       }
  191.       if(status==ABGESCHOSSEN) {
  192.          if(ship[player]==0)
  193.             status=LETZTERPANZER;
  194.       }
  195.       if(status==UEBERROLLT)
  196.          ueber();
  197.       if(status==UEBERROLLT||status==LETZTERPANZER) {
  198.          anzplay1--;
  199.          ausblenden(0);
  200.          textanz(1);
  201.          if(anzplay1) {
  202.             player=(player+1)%2;
  203.             titrest();
  204.             textanz(0);
  205.             setupnextplayer();
  206.          }
  207.          if(anzplay1)
  208.             einblenden(color,0);
  209.       }
  210.       else if(status==ABGESCHOSSEN) {
  211.          if(anzplay1==2) {
  212.             storeplayer();
  213.             player=(player+1)%2;
  214.             ausblenden(0);
  215.             titrest();
  216.             textanz(0);
  217.             einblenden(color,0);
  218.          }
  219.       }
  220.       else if(status==QUIT||status==DEMO) {
  221.          anzplay1=0;
  222.          ausblenden(0);
  223.       }
  224.       else if(status==QUITDEMO) {
  225.          anzplay1=0;
  226.          ausblenden(0);
  227.          return(1);
  228.       }
  229.    } while(anzplay1!=0);
  230.    return(0);
  231. }
  232.  
  233. storeplayer()
  234.  
  235. /* Zwischenspeichern der Daten eines Spielers (fuer Spiel zu zweit) */
  236.  
  237. {
  238.    int i,j;
  239.  
  240.    vd[player].invaderanz=invaderanz; vd[player].inligre=inligre;
  241.    vd[player].inregre=inregre;       vd[player].inobgre=inobgre;
  242.    vd[player].inungre=inungre;       vd[player].ligre=ligre;
  243.    vd[player].regre=regre;           vd[player].obgre=obgre;
  244.    vd[player].ungre=ungre;           vd[player].inxd=inxd;
  245.    vd[player].inx=inx;               vd[player].iny=iny;
  246.    vd[player].inphase=inphase;       vd[player].inphased=inphased;
  247.    for(i=0;i<KO5;i++)
  248.       for(j=0;j<KO6;j++)
  249.          vd[player].invor[i][j]=invor[i][j];
  250.  
  251.    /* Aussehen der Bunker merken */
  252.    BltBitMap(&bm,VX,by,&bunkerbuff[player],0L,0L,XA,BKO4,0xc0L,0xffL);
  253. }
  254.  
  255. setupnextplayer()
  256.  
  257. /* Zwischengespeicherte Daten in aktuelle Variablen uebertragen */
  258.  
  259. {
  260.    int i,j;
  261.    for(i=0;i<MISANZ[version];i++)
  262.       mis[i].flag=0;
  263.    schuss.flag=0; mutxd=0; schx=0; eiphase=0; eix=eiligre; eizae=0;
  264.    eizaemax=EIZAEMAXNORM[version];   miszae=1%MISZAEMAX[version];
  265.    schzae=2%SCHZAEMAX[version];      mutzae=3%MUTZAEMAX[version];
  266.    strigzae=DAUERFEUERBREMSE;        inbewsound=0;
  267.  
  268.    invaderanz=vd[player].invaderanz; inligre=vd[player].inligre;
  269.    inregre=vd[player].inregre;       inobgre=vd[player].inobgre;
  270.    inungre=vd[player].inungre;       ligre=vd[player].ligre;
  271.    regre=vd[player].regre;           obgre=vd[player].obgre;
  272.    ungre=vd[player].ungre;           inxd=vd[player].inxd;
  273.    inx=vd[player].inx;               iny=vd[player].iny;
  274.    inphase=vd[player].inphase;       inphased=vd[player].inphased;
  275.  
  276.    for(i=0;i<KO5;i++)
  277.       for(j=0;j<KO6;j++)
  278.          invor[i][j]=vd[player].invor[i][j];
  279.    /* Bunker auf urspruenglichen Zustand bringen */
  280.    BltBitMap(&bunkerbuff[player],0L,0L,&bm,VX,by,XA,BKO4,0xc0L,0xffL);
  281. }
  282.  
  283. textanz(flag)
  284. BYTE flag;
  285.  
  286. /* Get Ready (flag==0) oder Game Over (flag==1) Meldung auf Lautsprecher
  287. und Schirm geben. */
  288.  
  289. {
  290.    int i,j;
  291.  
  292.    SetRast(&rp2,0L); SetRast(&rp,0L);
  293.    SetAPen(&rp2,1L);
  294.    Move(&rp2,VX+155L-5*LEN,GAMEOVERY-7L);    Text(&rp2,txt[player],LEN);
  295.    Move(&rp2,VX+110L,GAMEOVERY+13L);         Text(&rp2,text[flag],LEN2);
  296.    SetAPen(&rp2,2L);
  297.    Move(&rp2,VX+155L-5*LEN+1L,GAMEOVERY-7L); Text(&rp2,txt[player],LEN);
  298.    Move(&rp2,VX+110L+1L,GAMEOVERY+13L);      Text(&rp2,text[flag],LEN2);
  299.    sound(11+flag,0,2-player);
  300.    einblenden(color1,0);
  301.    for(i=0;i<50;i++) {
  302.       SetRGB4(&vp,10L,(long)(i%5+5),(long)((i+3)%5+5),(long)((i+6)%6+5));
  303.       sound(13+flag,(2*flag-1)*i*5,player+1); /* zus. Soundeffekt */
  304.       sync();
  305.    }
  306.    if(flag) {
  307.       ausblenden(0);
  308.       eintrag(score[version][player]);
  309.       ausblenden(0);
  310.       interaus();
  311.    }
  312.    else
  313.       ausblenden(0);
  314.    SetAPen(&rp2,0L); SetAPen(&rp,0L);
  315.    SetRast(&rp2,0L); SetRast(&rp,0L);
  316. }
  317.  
  318. ueber()
  319.  
  320. /* Schirm flimmern lassen, wenn Invaders Panzer ueberrollen */
  321.  
  322. {
  323.    int i,j;
  324.  
  325.    sound(3,0,3);
  326.    SetRast(&rp,0L); SetRast(&rp2,0L);
  327.    for(i=0;i<61;i++) {
  328.       SetRGB4(&vphi,0L,(long)(i%16),(long)((i+3)%5),(long)((i+6)%3));
  329.       SetRGB4(&vp,0L,(long)(i%16),(long)((i+3)%5),(long)((i+6)%3));
  330.       sync();
  331.    }
  332. }
  333.  
  334. setup()
  335.  
  336. /* Invaders neu aufstellen, einige Variablen initialisieren */
  337.  
  338. {
  339.    int i,j;
  340.    invaderanz=0;
  341.  
  342.    if(level[player]>=MAXLEVEL)
  343.       level[player]=MAXLEVEL-1;
  344.    for(i=0;i<KO5;i++)
  345.       for(j=0;j<KO6;j++)
  346.          invor[i][j]=0;
  347.    for(i=0;i<levelb[level[player]];i++)
  348.       for(j=0;j<levelh[level[player]];j++) {
  349.          invor[i][j]=levelmin[level[player]]+j;
  350.          invaderanz++;
  351.       }
  352.    inphase=0; inxd=1; inphased=1; inligre=0; inregre=KO5-1; inobgre=0;
  353.    inungre=KO6-1;
  354.    fingre();
  355.    obgre=aobgre-inobgre*KO2[kick]+(ungre-aobgre+inobgre*KO2[kick])%INYD[kick];
  356.    inx=ligre; iny=obgre+INYD[kick]*levela[kick][level[player]];
  357. }
  358.  
  359. titrest()
  360.  
  361. /* Status-Balken am oberen Bildschirmrand restaurieren */
  362.  
  363. {
  364.    SetRast(&rphi,0L);
  365.    SetAPen(&rphi,1L);
  366.    titrest1(player);
  367.    if(anzplay) {
  368.       SetAPen(&rphi,2L);
  369.       titrest1((player+1)%2);
  370.    }
  371.    SetAPen(&rphi,3L);
  372.    if(anzplay) {
  373.       ausdruck(300L,hiscore[version]);
  374.       Move(&rphi,270L,8L);
  375.    }
  376.    else  {
  377.       ausdruck(530L,hiscore[version]);
  378.       Move(&rphi,500L,8L);
  379.    }
  380.    Text(&rphi,"Hi",2L);
  381. }
  382.  
  383. titrest1(plyr)
  384. int plyr;
  385.  
  386. /* Punkte und Anzahl an Panzern (Ships) ausgeben*/
  387.  
  388. {
  389.    Move(&rphi,playx[plyr]-80L,8L);   Text(&rphi,txt[plyr],LEN);
  390.    ausdruck(playx[plyr],score[version][plyr]);
  391.    Move(&rphi,playx[plyr]+70L,8L);   Text(&rphi,"Ships",5L);
  392.    shipanz(playx[plyr],ship[plyr]);
  393. }
  394.  
  395. bunker()
  396.  
  397. /* Bunker (neue) auf Schirm bringen */
  398.  
  399. {
  400.    long k;
  401.    for(k=0;k<BANZ;k++)
  402.       BltBitMap(&bunb,BOFF1,BOFF2,&bm,k*BKO1+BX,by,BKO3,BKO4,0xc0L,0xffL);
  403. }
  404.  
  405. punktezaehlung()
  406.  
  407. /* Evtl. Freipanzer vergeben und Hiscore aktualisieren */
  408.  
  409. {
  410.    SetAPen(&rphi,1L);
  411.    ausdruck(playx[player],score[version][player]);
  412.    if(score[version][player]>frei[freipanz[player]]) {
  413.       freipanz[player]++; ship[player]++;
  414.       shipanz(playx[player],ship[player]);
  415.    }
  416.    if(score[version][player]>hiscore[version]) {
  417.       hiscore[version]=score[version][player];
  418.       SetAPen(&rphi,3L);
  419.       if(anzplay)
  420.          ausdruck(300L,hiscore[version]);
  421.       else
  422.          ausdruck(530L,hiscore[version]);
  423.    }
  424. }
  425.  
  426. ausdruck(x,z)
  427. long x,z;
  428.  
  429. /* Ausdruck der Punkte z auf Status-Balken (x-Koordinate=x) */
  430.  
  431. {
  432.    char str[6];
  433.    int i;
  434.    for(i=5;i>=0;i--) {
  435.       str[i]= z % 10 + 48;
  436.       z/=10;
  437.    }
  438.    Move(&rphi,x,8L); Text(&rphi,str,6L);
  439. }
  440.  
  441. shipanz(x,s)
  442. long x;
  443. BYTE s;
  444.  
  445. /* Ausdruck der Anzahl an Panzern s auf Status-Balken (x-Koordinate=x) */
  446.  
  447. {
  448.    char str[2];
  449.  
  450.    str[1]=s%10+48; s/=10; str[0]=s%10+48;
  451.    Move(&rphi,130L+x,8L); Text(&rphi,str,2L);
  452. }
  453.  
  454. strig()
  455.  
  456. /* Feuerknopf-Abfrage und Verlangsamung bei dauerndem Druck auf Knopf */
  457.  
  458. {
  459.  
  460.    if(ciaa->ciapra & 0x80 && demo==0) {
  461.       strigzae=0;
  462.       return(0);
  463.    }
  464.    else {
  465.       if(strigzae) {
  466.          strigzae--;
  467.          return(0);
  468.       }
  469.       else {
  470.          strigzae=DAUERFEUERBREMSE;
  471.          return(1);
  472.       }
  473.    }
  474.  
  475. }
  476.  
  477. eibew()
  478.  
  479. /* Panzer bewegen (Joystick oder, im Demo-Modus, zufaellig) */
  480.  
  481. {
  482.    BYTE flg=0;
  483.    static BYTE demorichtung=1;
  484.  
  485.    if(eiphase<0) {
  486.       /* Panzer explodiert */
  487.       BltBitMap(&expb,OFF1,(-eiphase-1)*EXPHEIGHT+OFF2,&bm,eix,eiy,KO3,KO4,
  488.        0xc0L,0xffL);
  489.       --eiphase;
  490.       if(eiphase==-EXPPHASEN-1) {
  491.          abschuss=1; eiphase=0; eix=eiligre; eizaemax=EIZAEMAXNORM[version];
  492.       }
  493.    }
  494.    else {
  495.       if(demo==0) {
  496.          if(custom->joy1dat&0x200) {         /* Joystick bewegt Panzer */
  497.             if(eix-EIXD[version]>=eiligre) {
  498.                eix-=EIXD[version]; eiphase=++eiphase%PHASEN; flg=1;
  499.             }
  500.          }
  501.          else if (custom->joy1dat & 2) {
  502.             if (eix+EIXD[version]<=eiregre) {
  503.                eix+=EIXD[version]; eiphase=(eiphase+PHASEN-1) % PHASEN;
  504.                flg=1;
  505.             }
  506.          }
  507.       }
  508.       else {                      /*  Demo-Modus: Zufall bewegt Panzer */
  509.          rnd1();
  510.          if(rnd>61000L) {
  511.             rnd1();
  512.             if(rnd>55000L)
  513.                demorichtung=inxd;
  514.             else {
  515.                rnd1();
  516.                demorichtung=3L*rnd/0x10000L-1;
  517.             }
  518.          }
  519.          if(demorichtung==-1) {
  520.             if(eix-EIXD[version]>=eiligre) {
  521.                eix-=EIXD[version]; eiphase=++eiphase%PHASEN; flg=1;
  522.             }
  523.             else
  524.                demorichtung=-demorichtung;
  525.          }
  526.          else if (demorichtung==1) {
  527.             if (eix+EIXD[version]<=eiregre) {
  528.                eix+=EIXD[version]; eiphase=(eiphase+PHASEN-1) % PHASEN;
  529.                flg=1;
  530.             }
  531.             else
  532.                demorichtung=-demorichtung;
  533.          }
  534.       }
  535.       if(flg)                    /* Panzer bewegt: flg!=0 */
  536.          if(eiphase==0) {
  537.             if(eibewsoundzae==0) {
  538.                sound(2,0,3);
  539.                eibewsoundzae=EIBEWSOUNDZAEMAX;
  540.             }
  541.             eibewsoundzae--;
  542.          }
  543.       else
  544.          eibewsoundzae==0;
  545.       BltBitMap(&inb,INEX*(INA-1)+OFF1,eiphase*INEY+OFF2,&bm,eix,eiy,KO3,KO4,0xc0L,0xffL);
  546.    }
  547. }
  548.  
  549. schbew()
  550.  
  551. /* Schuss bewegen und Abfrage auf Treffer */
  552.  
  553. {
  554.    int xz=0,yz=0;
  555.    short farbe;
  556.    long i;
  557.  
  558.    if(schuss.flag) {          /* immer nur ein Schuss unterwegs */
  559.       if(schuss.y<=VY-SKO4) { /* Schuss nicht mehr sichtbar */
  560.          schuss.flag=0;
  561.          /* Zeit-Dummys: */
  562.          farbe=ReadPixel(&rp,13L,13L);
  563.          BltBitMap(&schb,SOFF1,SOFF2,&dummyb,0L,0L,SKO3,SKO4,0xc0L,0xffL);
  564.          for(i=0;i<50;i++) ;
  565.       }
  566.       else {
  567.          BltBitMap(&schb,SOFF1,schuss.phase*SCHHEIGHT+SOFF2,&bm2,schuss.x,
  568.           schuss.y,SKO3,SKO4,0xc0L,0xffL);
  569.          if(schuss.y>=VY) {
  570.             if(farbe=ReadPixel(&rp,schuss.x+SHS,schuss.y)) {
  571.                /* Treffer */
  572.                xz=(schuss.x+SHS-inx)/KO1; yz=(schuss.y-iny)/KO2[kick];
  573.                if(farbe==7) {             /* Bunker hat Farbe 7 */
  574.                   sound(7,0,1);           /* Bunkertreffer */
  575.                   BltPattern(&rp,bssb.Planes[0],schuss.x+SHS-BSHS,
  576.                    schuss.y-BSSHEIGHT+SCHD[version],
  577.                    schuss.x+SHS-BSHS+BSSWIDTH-1L,schuss.y+SCHD[version]-1L,
  578.                    BPRS);                 /* Bunker beschaedigen */
  579.                   schuss.flag=0;
  580.                   RectFill(&rp2,schuss.x,schuss.y,schuss.x+SKO3-1L,
  581.                    schuss.y+SKO4-1L);
  582.                }
  583.                else if(schuss.y<MUTY+MUTKO4) {
  584.                   if(mutphase>=0) {       /* Mutterschiff-Treffer */
  585.                      sound(9,0,3);
  586.                      mutphase=-1;
  587.                      RectFill(&rp2,schuss.x,schuss.y,schuss.x+SKO3-1L,
  588.                       schuss.y+SKO4-1L);
  589.                      schuss.flag=0;
  590.                      if(demo==0) {
  591.                         rnd1();
  592.                         score[version][player]+=(mutoff/MUTWIDTH)*
  593.                          (MUTPUNKTE+MUTPUNKTERND*(long)rnd/65536L);
  594.                         punktezaehlung();
  595.                      }
  596.                   }
  597.                }
  598.                else if(invor[xz][yz]>0) {
  599.                   sound(5,0,1);           /* Invader getroffen */
  600.                   if(demo==0) {
  601.                      score[version][player]+=10*invor[xz][yz];
  602.                      punktezaehlung();
  603.                   }
  604.                   invor[xz][yz]=-1;
  605.                   schuss.flag=0;
  606.                   rnd1();
  607.                   RectFill(&rp2,schuss.x,schuss.y,schuss.x+SKO3-1L,
  608.                    schuss.y+SKO4-1L);
  609.                }
  610.             }
  611.          }
  612.          else {
  613.             /* Zeit-Dummy: */
  614.             farbe=ReadPixel(&rp,0L,0L);
  615.          }
  616.          schuss.y-=SCHD[version];
  617.          schuss.phase=++schuss.phase%SCHPHASEN;
  618.       }
  619.    }
  620.    else {                              /* kein Schuss unterwegs */
  621.       if(strig() && eiphase>=0) {
  622.          schuss.y=eiy-SAY;             /* Schuss abgefeuert */
  623.          schuss.x=eix+SAX;
  624.          schuss.phase=0;
  625.          schuss.flag=1;
  626.          sound(0,0,4);
  627.       }
  628.  
  629.       /* Zeit-Dummys: */
  630.       farbe=ReadPixel(&rp,13L,13L);
  631.       BltBitMap(&schb,SOFF1,SOFF2,&dummyb,0L,0L,SKO3,SKO4,0xc0L,0xffL);
  632.       for(i=0;i<20;i++) ;
  633.    }
  634. }
  635.  
  636. misbew()
  637.  
  638. /* Bewegen der Missiles */
  639.  
  640. {
  641.    int xz,yz,i,k,farbe1,farbe2,flg;
  642.    long zwx1,zwx2,yko;
  643.  
  644.    miszae1 = ++miszae1 % miszae1max;
  645.    if(miszae1==0) {
  646.       /* Ein Invader darf nur dann schiessen, wenn ueber ihm keiner ist;
  647.       mit invor1 und invor2 werden die Indices, mit invor3 die Anzahl
  648.       der Kandidaten, die fuer den Start eines Misiles in Frage kommen,
  649.       gespeichert*/
  650.       invor3=0;
  651.       for(xz=inligre;xz<=inregre;xz++) {
  652.          for(yz=inungre;yz>=inobgre;yz--) {
  653.             if(invor[xz][yz]>0) {
  654.                break;
  655.             }
  656.          }
  657.          if(yz>=inobgre) {
  658.             invor1[xz]=yz; invor2[invor3]=xz; invor3++;
  659.          }
  660.          else {
  661.             invor1[xz]=-1;
  662.          }
  663.       }
  664.    }
  665.    for(i=0;i<MISANZ[version];i++) {    /* MISANZ ist max. Missile-Anzahl */
  666.       if(mis[i].y>=YA[kick]+VY) {
  667.          mis[i].flag=0;                /* Missile am Rand verschwunden */
  668.       }
  669.       if(mis[i].flag) {                /* Missile unterwegs */
  670.          BltBitMap(&misb,MOFF1,MOFF2+mis[i].phase*MISHEIGHT,&bm2,mis[i].x,
  671.           mis[i].y,MKO3,MKO4,0xc0L,0xffL);
  672.          zwx1=mis[i].x+MHS-MHSDX; zwx2=mis[i].x+MHS+MHSDX; flg=0;
  673.          for(k=0;k<MHSANZ;k++) {       /* Sensitive Punkte der Missiles
  674.                                           auf Kollision abfragen */
  675.             farbe1=ReadPixel(&rp,zwx1,mis[i].y+misyhs[k]);
  676.             farbe2=ReadPixel(&rp,zwx2,mis[i].y+misyhs[k]);
  677.             if(farbe1==7||farbe2==7) {
  678.                flg=7; yko=misyhs[k];   /* Bunkertreffer */
  679.                break;                  /* oberster Wert zaehlt */
  680.             }
  681.             else if(farbe1||farbe2) {  /* Panzertreffer */
  682.                flg=1; yko=misyhs[k];   /* unterster Wert zaehlt*/
  683.             }
  684.          }
  685.          if(flg) {                     /* Treffer  */
  686.             if(flg==7) {               /* Bunker hat Prioritaet ueber
  687.                                           Panzertreffer */
  688.                sound(7,0,1);
  689.                mis[i].flag=0;
  690.                BltPattern(&rp,bsib.Planes[0],mis[i].x+MHS-BIHS,
  691.                 mis[i].y-MISD[version]+1L+yko,mis[i].x+MHS-BIHS+BSIWIDTH-1L,
  692.                 mis[i].y-MISD[version]+BSIHEIGHT+yko,BPRI);
  693.                RectFill(&rp2,mis[i].x,mis[i].y,mis[i].x+MKO3-1L,
  694.                 mis[i].y+MKO4-1L);
  695.             }
  696.             /* Abfrage nur um auszuschliessen, dass ein Invader sich selbst
  697.                abschiesst (beim Herabsetzen des Invaderblocks am Rand) */
  698.             else if(mis[i].y+yko>=eiy && eiphase>=0) {
  699.                sound(1,0,4);           /* Panzertreffer */
  700.                mis[i].flag=0;
  701.                RectFill(&rp2,mis[i].x,mis[i].y,mis[i].x+MKO3-1L,
  702.                 mis[i].y+MKO4-1L);
  703.                if(demo==0 && trainer==0)
  704.                   --ship[player];
  705.                SetAPen(&rphi,1L);
  706.                shipanz(playx[player],ship[player]);
  707.                eiphase=-1; eizaemax=STRAFE;
  708.                eibew();
  709.             }
  710.          }
  711.          mis[i].y+=MISD[version]; mis[i].phase=++mis[i].phase%MISPHASEN;
  712.       }
  713.       else {
  714.          rnd1();                        /* zufaellig Missile starten */
  715.          if(rnd<=MISWK[version] && miszae1==0 && invor3!=0) {
  716.             rnd1();                     /* Zufall entscheidet ueber
  717.                                            gezielten Angriff auf Panzer */
  718.             if(rnd<=GEZIELTEWK[version]) {
  719.                xz=(eix+SAX+SHS-inx)/KO1;
  720.                if(xz<inligre)
  721.                   xz=inligre;
  722.                else if(xz>inregre)
  723.                   xz=inregre;
  724.             }
  725.             else {
  726.                rnd1();
  727.                xz=invor2[(long)rnd*invor3/65536L]; /* kein gezielter
  728.                                                       Schuss */
  729.             }
  730.             if((yz=invor1[xz])!=-1) {   /* Missile nur ausloesen,
  731.                                            wenn Invader auch vorhanden */
  732.                sound(4,0,2);
  733.                mis[i].y=KO2[kick]*yz+iny+MAY; mis[i].x=KO1*xz+inx+MAX;
  734.                mis[i].phase=0;                mis[i].flag=1;
  735.             }
  736.          }
  737.          /* Zeit-Dummy */
  738.          for(k=0;k<2*MISANZ[version];k++)
  739.             farbe1=ReadPixel(&rp,0L,0L);
  740.          BltBitMap(&misb,MOFF1,MOFF2,&dummyb,0L,0L,MKO3,MKO4,0xc0L,0xffL);
  741.       }
  742.    }
  743. }    
  744.  
  745. mistre()
  746.  
  747. /* Treffer von Schuss auf Missile, kurze Explosion einblenden */
  748.  
  749. {
  750.    int i,k=0;
  751.    long yko=0;
  752.  
  753.    for(i=0;i<MISANZ[version];i++) {
  754.       if(mis[i].flag && yko<mis[i].y && mis[i].x+MHS-MHSDX<=schuss.x+SHS &&
  755.        schuss.x+SHS<=mis[i].x+MHS+MHSDX) {
  756.          if(schuss.flag && schuss.y+SCHD[version]<=mis[i].y-MISD[version]+
  757.           misyhs[MHSANZ-1]) {
  758.             yko=mis[i].y; k=i+1;
  759.          }
  760.       }
  761.    }
  762.    if(schx) {
  763.       RectFill(&rp2,schx,schy,MTKO3+schx,MTKO4+schy);
  764.       schx=0;
  765.    }
  766.    if(k) {
  767.       sound(8,0,2);
  768.       k--; mis[k].flag=0;
  769.       RectFill(&rp2,mis[k].x,mis[k].y,mis[k].x+MKO3-1L,mis[k].y+MKO4-1L);
  770.       RectFill(&rp2,schuss.x,schuss.y,schuss.x+SKO3-1L,schuss.y+SKO4-1L);
  771.       schuss.flag=0; schx=schuss.x+SHS-MTHSX; schy=schuss.y-MTHSY;
  772.       BltBitMap(&mistreb,MTOFF1,MTOFF2,&bm2,schx,schy,MTKO3,MTKO4,0xc0L,
  773.        0xffL);
  774.    }
  775. }
  776.  
  777. mutbew()
  778.  
  779. /* Mutterschiff bewegen */
  780.  
  781. {
  782.    if(mutxd) {
  783.       if(mutphase<0)
  784.          /* Explosion des Mutterschiffs*/
  785.          BltBitMap(&mutb,MUTOFF1+mutoff,(-mutphase+MUTPHASEN-1)*MUTHEIGHT+
  786.           MUTOFF2,&bm,mutx,MUTY,MUTKO3,MUTKO4,0xc0L,0xffL);
  787.       else {
  788.          BltBitMap(&mutb,MUTOFF1+mutoff,mutphase*MUTHEIGHT+MUTOFF2,&bm,mutx,
  789.           MUTY,MUTKO3,MUTKO4,0xc0L,0xffL);
  790.          if(mutphase==0) {
  791.             if(mutbewsoundzae==0) {
  792.                sound(10,0,3);
  793.                mutbewsoundzae=MUTBEWSOUNDZAEMAX;
  794.             }
  795.             mutbewsoundzae--;
  796.          }
  797.       }
  798.       mutx+=mutxd;
  799.       if(mutxd<0) {
  800.          if(mutx<=VX-MUTKO3)
  801.             mutxd=0;
  802.          else {
  803.             if(mutphase<0)
  804.                if(mutphase==-MUTEXPPHASEN)
  805.                   mutxd=0;
  806.                else
  807.                   --mutphase;
  808.             else
  809.                mutphase=++mutphase%MUTPHASEN;
  810.          }
  811.       }
  812.       else {
  813.          if (mutx>=XA+VX)
  814.             mutxd=0;          /* am Rand verschwunden */
  815.          else {
  816.             if(mutphase<0)
  817.                if(mutphase==-MUTEXPPHASEN)
  818.                   mutxd=0;
  819.                else
  820.                   --mutphase;
  821.             else
  822.                mutphase=(mutphase+MUTPHASEN-1) % MUTPHASEN;
  823.          }
  824.       }
  825.    }
  826.    else {
  827.       rnd1();                 /* kein Mutterschiff unterwegs */
  828.       if(rnd<=MUTWK) {        /* Zufall entscheidet ueber neues Schiff */
  829.          mutbewsoundzae=0;
  830.          if(rnd%2==0) {
  831.             mutxd=MUTD[version]; mutx=VX-MUTKO3;
  832.          }
  833.          else {
  834.             mutxd=-MUTD[version]; mutx=XA+VX;
  835.          }
  836.          mutphase=0;
  837.          rnd1();
  838.          mutoff=MUTWIDTH*(MUTANZ*rnd/0x10000L);
  839.       }
  840.       /* Dummy */
  841.       BltBitMap(&mutb,MUTOFF1+mutoff,mutphase*MUTHEIGHT+MUTOFF2,
  842.        &dummyb,0L,0L,MUTKO3,MUTKO4,0xc0L,0xffL);
  843.    }
  844. }
  845.  
  846. fingre()
  847.  
  848. /* Findet die Grenzen des Invaderblocks, damit sich die Invaders stets bis
  849. zum Rand bewegen, auch wenn mehrere bereits abgeschossen sind. */
  850.  
  851. {
  852.    int i;
  853.  
  854.    for(i=inligre;i<inregre;i++)
  855.       if(fingre1(i))
  856.          break;
  857.    inligre=i;
  858.    for(i=inregre;i>inligre;i--)
  859.       if(fingre1(i))
  860.          break;
  861.    inregre=i;
  862.    for(i=inobgre;i<inungre;i++)
  863.       if(fingre2(i))
  864.          break;
  865.    inobgre=i;
  866.    for(i=inungre;i>inobgre;i--)
  867.       if(fingre2(i))
  868.          break;
  869.    inungre=i;
  870.    ligre=aligre-inligre*KO1; regre=aregre-inregre*KO1-KO3+1L;
  871.    ungre=by+BKO4-inungre*KO2[kick]-KO4;
  872. }
  873.  
  874. fingre1(i)
  875. int i;
  876. {
  877.    int j;
  878.  
  879.    for(j=inobgre;j<=inungre;j++)
  880.       if(invor[i][j])
  881.          return(1);
  882.    return(0);
  883. }
  884.  
  885. fingre2(j)
  886. int j;
  887. {
  888.    int i;
  889.  
  890.    for(i=inligre;i<=inregre;i++)
  891.       if(invor[i][j])
  892.          return(1);
  893.    return(0);
  894. }
  895.  
  896. inbew()
  897.  
  898. /* Bewegung der Invaders und Steuerung des Gesamtablaufs */
  899.  
  900. {
  901.    int i,xv,yv,flag=0;
  902.  
  903.    eibewsoundzae=0; abschuss=0;
  904.    if(invaderanz==0)      /* Alle schon abgeschossen ? */
  905.       if(demo==0)
  906.          return(KEINE_IN_MEHR);
  907.       else
  908.          return(DEMO);
  909. label:
  910.    for(yv=inobgre;yv<=inungre;yv++) {      /* Alle Invaders bewegen */
  911.       for(xv=inligre;xv<=inregre;xv++) {
  912.          if(invor[xv][yv]) {
  913.             if(invor[xv][yv]>0) {
  914.                BltBitMap(&inb,INEX*(invor[xv][yv]-1)+OFF1,inphase*INEY+OFF2,
  915.                 &bm,KO1*xv+inx,KO2[kick]*yv+iny,KO3,KO4,0xc0L,0xffL);
  916.             }
  917.             else {
  918.                /* explodierende Invader */
  919.                BltBitMap(&expb,OFF1,(-invor[xv][yv]-1)*EXPHEIGHT+OFF2,&bm,
  920.                 KO1*xv+inx,KO2[kick]*yv+iny,KO3,KO4,0xc0L,0xffL);
  921.                if(invor[xv][yv]==-EXPPHASEN) {
  922.                   invaderanz--; invor[xv][yv]=0;
  923.                   if(invaderanz==0) {
  924.                      if(demo==0)
  925.                         flag=KEINE_IN_MEHR;
  926.                      else
  927.                         flag=DEMO;
  928.                      break;
  929.                   }
  930.                   else
  931.                      fingre();
  932.                }
  933.                else
  934.                   --invor[xv][yv];
  935.             }
  936.             /* Da die Geschwindigkeit der Schuesse, Missiles, usw.
  937.                konstant sein sollen, wird nach jeder Bewegung eines
  938.                Invaders restbew() aufgerufen */
  939.             if(flag=restbew()) {
  940.                break;            /* Panzer getroffen */
  941.             }
  942.          }
  943.       }
  944.       if(flag)
  945.          break;
  946.    }
  947.    if(flag)
  948.       return(flag);
  949.    flag=0;
  950.    for(i=0;i<INBEWVERZ[version];i++) {
  951.    /* damit der letzte Invader etwas gebremst wird */
  952.       if(flag=leer()) {
  953.          break;
  954.       }
  955.    }
  956.    if(inbewsoundzae==0) {
  957.       inbewsound=(inbewsound+1)%3;
  958.       sound(6,inbewsound*30,2);
  959.       inbewsoundzae=INBEWSOUNDZAEMAX;
  960.    }
  961.    inbewsoundzae--; inphase+=inphased;
  962.    if(inphase>0) {
  963.       if(inphase==PHASEN) {
  964.          inphase=0;
  965.       }
  966.    }
  967.    else {
  968.       if(inphase==-1) {
  969.          inphase=PHASEN-1;
  970.       }
  971.    }
  972.    inx+=inxd;
  973.    if ( (inx>regre) || (inx<ligre) ) {
  974.       inxd=-inxd; inx+=inxd; inphased=-inphased;
  975.       RectFill(&rp,inligre*KO1+inx,inobgre*KO2[kick]+iny,
  976.        inregre*KO1+inx+KO3-1L,inungre*KO2[kick]+iny+KO4-1L);
  977.       if(kick || iny+2*INYD[kick] <= ungre)
  978.          RectFill(&rp,VX,inungre*KO2[kick]+KO4+iny,VX+XA,
  979.           iny+INYD[kick]+inungre*KO2[kick]+KO4-1L);
  980.       else
  981.          RectFill(&rp,VX,inungre*KO2[kick]+KO4+iny,VX+XA,
  982.           iny+INYD[kick]+inungre*KO2[kick]+KO4+2L);
  983.       iny+=INYD[kick];
  984.       if (iny>ungre)      /* Invaders schon zu tief ? */
  985.          if(demo==0)
  986.             return(UEBERROLLT);
  987.          else
  988.             return(DEMO);
  989.    }
  990.    if(flag)
  991.       return(flag);
  992.    goto label;
  993. }
  994.  
  995. restbew()
  996.  
  997. /* Alles ausser Invaders bewegen, Abfrage der Maustaste (Pause)
  998. Wenn Panzer abgeschossen oder Spiel unterbrochen wurde gibt restbew() einen
  999. entsprechenden Wert zurueck */
  1000.  
  1001. {
  1002.    int item=1;
  1003.  
  1004.    if(demo) {
  1005.       time++;
  1006.       if(time==DEMOTIME)
  1007.          return(DEMO);
  1008.       if((ciaa->ciapra & 0x80)==0) {
  1009.          while((ciaa->ciapra & 0x80)==0) ;
  1010.          return(QUITDEMO);
  1011.       }
  1012.    }
  1013.    if((ciaa->ciapra & 0x40)==0) {      /* Mit linker Maustaste Pause */
  1014.       while((ciaa->ciapra & 0x40)==0) ;
  1015.       if(demo==0) {
  1016.          SetRast(&rphi,3L);
  1017.          SetAPen(&rphi,2L); SetBPen(&rphi,3L);
  1018.          Move(&rphi,215L,8L); Text(&rphi,"Pause - use joystick !",22L);
  1019.          pausanz(0);
  1020.          SetAPen(&rphi,1L);
  1021.          pausanz(1);
  1022.          while(ciaa->ciapra&0x80) {
  1023.             if(custom->joy1dat&0x200)
  1024.                item=0;
  1025.             else if(custom->joy1dat&2)
  1026.                item=1;
  1027.             SetAPen(&rphi,1L); pausanz(item);
  1028.             SetAPen(&rphi,2L); pausanz((item+1)%2);
  1029.          }
  1030.          while((ciaa->ciapra&0x80)==0) ;
  1031.          SetBPen(&rphi,0L);
  1032.          titrest();
  1033.          if(item==0)
  1034.             return(QUIT);
  1035.       }
  1036.       else {
  1037.          return(QUITDEMO);
  1038.       }
  1039.    }
  1040.   /* Die Zaehler (Endung 'zae') sind fuer die Geschwindigkeiten
  1041.      verantwortlich */
  1042.    mutzae++;
  1043.    if(mutzae==MUTZAEMAX[version]) {
  1044.       mutzae=0;
  1045.       mutbew();
  1046.    }
  1047.    eizae++;
  1048.    if (eizae==eizaemax) {
  1049.       eizae=0;
  1050.       eibew();
  1051.    }
  1052.    schzae++;
  1053.    if (schzae==SCHZAEMAX[version]) {
  1054.       schzae=0;
  1055.       schbew();
  1056.       mistre();
  1057.    }
  1058.    miszae++;
  1059.    if (miszae==MISZAEMAX[version]) {
  1060.       miszae=0;
  1061.       misbew();
  1062.    }
  1063.    if(abschuss) {
  1064.       if(demo==0)
  1065.          return(ABGESCHOSSEN);
  1066.       else
  1067.          return(DEMO);
  1068.    }
  1069.    else
  1070.       return(0);
  1071. }
  1072.  
  1073. leer()
  1074.  
  1075. /* Zeitdummy */
  1076.  
  1077. {
  1078.    /* Zeit-Dummy: */
  1079.    BltBitMap(&inb,OFF1,OFF2,&dummyb,0L,0L,KO3,KO4,0xc0L,0xffL);
  1080.  
  1081.    return(restbew());
  1082. }
  1083.  
  1084. pausanz(item)
  1085. BYTE item;
  1086.  
  1087. /* Pause im Status-Balken anzeigen */
  1088.  
  1089. {
  1090.    if(item) {
  1091.       Move(&rphi,510L,8L); Text(&rphi,"Back to game",12L);
  1092.    }
  1093.    else {
  1094.       Move(&rphi,10L,8L); Text(&rphi,"Quit",4L);
  1095.    }
  1096. }
  1097.