home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
097.lha
/
Ic.Source
/
action.c
next >
Wrap
C/C++ Source or Header
|
1986-11-20
|
30KB
|
1,097 lines
/*
InvaderCraft von J.Hertel
(C) CW-Publikationen
"action.c"
Kompilieren mit Aztec C Version 3.20a.
Im Include-Directory muessen sich die Header-Files "invadercraft1.h" und
"invadercraft2.h" befinden!
Aufruf: cc action -a -e400
as action
Linken: siehe invadercraft.c
*/
#include <exec/types.h>
#include <graphics/gfx.h>
#include <graphics/rastport.h>
#include <graphics/view.h>
#include <hardware/custom.h>
#include <hardware/cia.h>
/* Vor Compiler-Aufruf unbedingt "invadercraft1.h" und "invadercraft2.h"
in include/ - Directory kopieren! */
#include <invadercraft1.h>
#include <invadercraft2.h>
extern struct GfxBase *GfxBase;
extern struct RastPort rp,rp2,rphi;
extern struct BitMap bmhi,bm,bm2,inb,schb,misb,expb,bunb,dummyb,mistreb,
mutb,bunkerbuff[2],ab1,titelbild,bssb,bsib;
extern struct ViewPort vp,vphi;
extern struct Custom *custom;
extern struct CIA *ciaa;
extern struct liste slots[MAXVERSIONS][SLOTS];
extern UWORD color[],color1[];
extern USHORT rnd;
extern int trainer,kick,INBEWVERZ[],EIZAEMAXNORM[],MUTZAEMAX[],SCHZAEMAX[],
MISANZ[],MISZAEMAX[],MISWK[],GEZIELTEWK[],ANZPANZER[];
extern long YA1[],YA[],MITTE[],EIXD[],MUTD[],SCHD[],MISD[];
UWORD *colorp;
long KO2[2]={15L,17L},INYD[]={13L,17L},mutoff,BPRS,BPRI,GAMEOVERY;
ULONG score[MAXVERSIONS][2],hiscore[MAXVERSIONS],frei[ANZFREIPANZER+1]={
/* ab dieser Punktzahl gibt es jeweils einen Freipanzer; ANZFREIPANZER
ist die Anzahl an moeglichen Freipanzern (im Headerfile zu aendern) */
4999,9999,19999,49999,99999,199999,499999
,0xffffffff};
/* Y-Koordinaten der sensitiven Punkte der Missiles */
long misyhs[MHSANZ]={3L,8L,MKO4-1L}; /* aufsteigende Reihenfolge */
/* Aufstellung der Invaders pro Level */
int levelmin[MAXLEVEL]={1,3,5,7,9,11,13,15,17,19,21,23,24,25,25,25};
int levelh[MAXLEVEL]={4,4,5,5,5,5,6,6,6,6,6,6,6,6,6,6};
int levelb[MAXLEVEL]={7,8,8,8,9,9,9,10,10,10,10,10,10,10,10,10};
int levela[2][MAXLEVEL]={{0,0,0,1,1,2,1,1,1,2,2,2,2,2,2,2},
{0,1,1,2,2,2,1,2,2,3,3,4,4,4,4,4}};
int freipanz[2],invor[KO5][KO6],invor1[KO5],invor2[KO5],invor3,invaderanz,
inligre,inregre,inobgre,inungre,strigzae,eizae,eizaemax,mutzae,miszae1,
miszae1max,schzae,miszae,player,abschuss,inbewsound,ship[2],anzplay,anzplay1,
version,level[2],demo,demolevel;
long mutphase,eiphase,mutxd,inxd,inx,inphase,inphased,iny,regre,ligre,ungre,
obgre,aligre,aregre,aungre,aobgre,mutx,schx,schy,by,eix,eiy,eiligre,eiregre,
inbewsoundzae,mutbewsoundzae,eibewsoundzae,playx[2]={90,470},time;
char *txt[2]={"Player1","Player2"};
#define LEN 7L /* Laenge der obigen Texte */
char *text[2]={" Ready ","Game over"};
#define LEN2 9L /* s.o. */
struct Vorddef {
int invor[KO5][KO6],invaderanz,inligre,inregre,inobgre,inungre;
long inxd,inx,inphase,inphased,iny,regre,ligre,ungre,obgre;
} vd[2];
struct schmis {
long x,y;
int phase;
BYTE flag;
} schuss,mis[MISANZMAX];
anfang()
/* einmalige Initialisierungen und Aufruf des Hauptmenues */
{
int i,j;
UBYTE *diskreg=0xBFD100;
*diskreg|=0x80; *diskreg|=0x08; *diskreg&=0xf7; /* Disk-Motor aus */
GAMEOVERY=MITTE[kick]+VY;
aligre=VX; aregre=XA1+VX; aobgre=MUTKO4+MUTY+4; aungre=YA1[kick]+VY;
eiregre=aregre-KO3+1; eiligre=aligre; eiy=aungre-KO4+1;
by=eiy-SAY-BKO4+1; miszae1max=MKO4/MISD[version];
BPRS=BSSWIDTH/8; BPRI=BSIWIDTH/8; BPRS+=BPRS%2; BPRI+=BPRI%2;
sternsetz();
for (i=0;i<3;i++)
hiscore[i]=slots[i][0].score;
hauptmenu();
}
spiel(plr)
BYTE plr;
/* Beginn des Spiels, plr ist Nummer des Spielers (fuer Two Player Game) */
{
int i;
BYTE status;
/* Befindet sich das Programm im Demo-Modus (siehe menues.c), so ist die
Variable 'demo' ungleich Null (siehe menues.c) */
if(demo==0) {
level[0]=level[1]=0; score[version][0]=0; ship[0]=ANZPANZER[version];
if(plr) {
score[version][1]=0;
ship[1]=ANZPANZER[version];
}
freipanz[0]=0; freipanz[1]=0;
}
else {
if(demolevel==2)
demolevel=7;
else
demolevel=2;
level[0]=demolevel;
}
anzplay=plr; anzplay1=anzplay+1; player=0;
setup();
if(demo==0) {
titrest();
textanz(0);
}
player=1;
bunker();
storeplayer();
setupnextplayer();
player=0;
storeplayer();
setupnextplayer();
einblenden(color,0);
do {
if(anzplay1==2) {
setupnextplayer();
}
time=0;
trainerlabel:
do {
/* Alles bewegen, bis kein Invader mehr da ist, der Panzer getroffen oder
mit der linken Maustaste unterbrochen wird */
status=inbew();
if(status==KEINE_IN_MEHR) {
for(i=0;i<PAUSE;i++) {
if(status=leer()) { /* einen Augenblick warten */
break;
}
status=KEINE_IN_MEHR;
}
if(status==KEINE_IN_MEHR) {
level[player]++; /* neue Aufstellung */
setup();
bunker();
}
}
} while(status==KEINE_IN_MEHR);
if(demo==0 && status!=QUIT && trainer!=0) {
if (status==UEBERROLLT) {
ueber();
ausblenden(0);
SetRast(&rp,0L);
SetRast(&rp2,0L);
einblenden(color,0);
level[player]++;
setup();
bunker();
}
goto trainerlabel;
}
if(status==ABGESCHOSSEN) {
if(ship[player]==0)
status=LETZTERPANZER;
}
if(status==UEBERROLLT)
ueber();
if(status==UEBERROLLT||status==LETZTERPANZER) {
anzplay1--;
ausblenden(0);
textanz(1);
if(anzplay1) {
player=(player+1)%2;
titrest();
textanz(0);
setupnextplayer();
}
if(anzplay1)
einblenden(color,0);
}
else if(status==ABGESCHOSSEN) {
if(anzplay1==2) {
storeplayer();
player=(player+1)%2;
ausblenden(0);
titrest();
textanz(0);
einblenden(color,0);
}
}
else if(status==QUIT||status==DEMO) {
anzplay1=0;
ausblenden(0);
}
else if(status==QUITDEMO) {
anzplay1=0;
ausblenden(0);
return(1);
}
} while(anzplay1!=0);
return(0);
}
storeplayer()
/* Zwischenspeichern der Daten eines Spielers (fuer Spiel zu zweit) */
{
int i,j;
vd[player].invaderanz=invaderanz; vd[player].inligre=inligre;
vd[player].inregre=inregre; vd[player].inobgre=inobgre;
vd[player].inungre=inungre; vd[player].ligre=ligre;
vd[player].regre=regre; vd[player].obgre=obgre;
vd[player].ungre=ungre; vd[player].inxd=inxd;
vd[player].inx=inx; vd[player].iny=iny;
vd[player].inphase=inphase; vd[player].inphased=inphased;
for(i=0;i<KO5;i++)
for(j=0;j<KO6;j++)
vd[player].invor[i][j]=invor[i][j];
/* Aussehen der Bunker merken */
BltBitMap(&bm,VX,by,&bunkerbuff[player],0L,0L,XA,BKO4,0xc0L,0xffL);
}
setupnextplayer()
/* Zwischengespeicherte Daten in aktuelle Variablen uebertragen */
{
int i,j;
for(i=0;i<MISANZ[version];i++)
mis[i].flag=0;
schuss.flag=0; mutxd=0; schx=0; eiphase=0; eix=eiligre; eizae=0;
eizaemax=EIZAEMAXNORM[version]; miszae=1%MISZAEMAX[version];
schzae=2%SCHZAEMAX[version]; mutzae=3%MUTZAEMAX[version];
strigzae=DAUERFEUERBREMSE; inbewsound=0;
invaderanz=vd[player].invaderanz; inligre=vd[player].inligre;
inregre=vd[player].inregre; inobgre=vd[player].inobgre;
inungre=vd[player].inungre; ligre=vd[player].ligre;
regre=vd[player].regre; obgre=vd[player].obgre;
ungre=vd[player].ungre; inxd=vd[player].inxd;
inx=vd[player].inx; iny=vd[player].iny;
inphase=vd[player].inphase; inphased=vd[player].inphased;
for(i=0;i<KO5;i++)
for(j=0;j<KO6;j++)
invor[i][j]=vd[player].invor[i][j];
/* Bunker auf urspruenglichen Zustand bringen */
BltBitMap(&bunkerbuff[player],0L,0L,&bm,VX,by,XA,BKO4,0xc0L,0xffL);
}
textanz(flag)
BYTE flag;
/* Get Ready (flag==0) oder Game Over (flag==1) Meldung auf Lautsprecher
und Schirm geben. */
{
int i,j;
SetRast(&rp2,0L); SetRast(&rp,0L);
SetAPen(&rp2,1L);
Move(&rp2,VX+155L-5*LEN,GAMEOVERY-7L); Text(&rp2,txt[player],LEN);
Move(&rp2,VX+110L,GAMEOVERY+13L); Text(&rp2,text[flag],LEN2);
SetAPen(&rp2,2L);
Move(&rp2,VX+155L-5*LEN+1L,GAMEOVERY-7L); Text(&rp2,txt[player],LEN);
Move(&rp2,VX+110L+1L,GAMEOVERY+13L); Text(&rp2,text[flag],LEN2);
sound(11+flag,0,2-player);
einblenden(color1,0);
for(i=0;i<50;i++) {
SetRGB4(&vp,10L,(long)(i%5+5),(long)((i+3)%5+5),(long)((i+6)%6+5));
sound(13+flag,(2*flag-1)*i*5,player+1); /* zus. Soundeffekt */
sync();
}
if(flag) {
ausblenden(0);
eintrag(score[version][player]);
ausblenden(0);
interaus();
}
else
ausblenden(0);
SetAPen(&rp2,0L); SetAPen(&rp,0L);
SetRast(&rp2,0L); SetRast(&rp,0L);
}
ueber()
/* Schirm flimmern lassen, wenn Invaders Panzer ueberrollen */
{
int i,j;
sound(3,0,3);
SetRast(&rp,0L); SetRast(&rp2,0L);
for(i=0;i<61;i++) {
SetRGB4(&vphi,0L,(long)(i%16),(long)((i+3)%5),(long)((i+6)%3));
SetRGB4(&vp,0L,(long)(i%16),(long)((i+3)%5),(long)((i+6)%3));
sync();
}
}
setup()
/* Invaders neu aufstellen, einige Variablen initialisieren */
{
int i,j;
invaderanz=0;
if(level[player]>=MAXLEVEL)
level[player]=MAXLEVEL-1;
for(i=0;i<KO5;i++)
for(j=0;j<KO6;j++)
invor[i][j]=0;
for(i=0;i<levelb[level[player]];i++)
for(j=0;j<levelh[level[player]];j++) {
invor[i][j]=levelmin[level[player]]+j;
invaderanz++;
}
inphase=0; inxd=1; inphased=1; inligre=0; inregre=KO5-1; inobgre=0;
inungre=KO6-1;
fingre();
obgre=aobgre-inobgre*KO2[kick]+(ungre-aobgre+inobgre*KO2[kick])%INYD[kick];
inx=ligre; iny=obgre+INYD[kick]*levela[kick][level[player]];
}
titrest()
/* Status-Balken am oberen Bildschirmrand restaurieren */
{
SetRast(&rphi,0L);
SetAPen(&rphi,1L);
titrest1(player);
if(anzplay) {
SetAPen(&rphi,2L);
titrest1((player+1)%2);
}
SetAPen(&rphi,3L);
if(anzplay) {
ausdruck(300L,hiscore[version]);
Move(&rphi,270L,8L);
}
else {
ausdruck(530L,hiscore[version]);
Move(&rphi,500L,8L);
}
Text(&rphi,"Hi",2L);
}
titrest1(plyr)
int plyr;
/* Punkte und Anzahl an Panzern (Ships) ausgeben*/
{
Move(&rphi,playx[plyr]-80L,8L); Text(&rphi,txt[plyr],LEN);
ausdruck(playx[plyr],score[version][plyr]);
Move(&rphi,playx[plyr]+70L,8L); Text(&rphi,"Ships",5L);
shipanz(playx[plyr],ship[plyr]);
}
bunker()
/* Bunker (neue) auf Schirm bringen */
{
long k;
for(k=0;k<BANZ;k++)
BltBitMap(&bunb,BOFF1,BOFF2,&bm,k*BKO1+BX,by,BKO3,BKO4,0xc0L,0xffL);
}
punktezaehlung()
/* Evtl. Freipanzer vergeben und Hiscore aktualisieren */
{
SetAPen(&rphi,1L);
ausdruck(playx[player],score[version][player]);
if(score[version][player]>frei[freipanz[player]]) {
freipanz[player]++; ship[player]++;
shipanz(playx[player],ship[player]);
}
if(score[version][player]>hiscore[version]) {
hiscore[version]=score[version][player];
SetAPen(&rphi,3L);
if(anzplay)
ausdruck(300L,hiscore[version]);
else
ausdruck(530L,hiscore[version]);
}
}
ausdruck(x,z)
long x,z;
/* Ausdruck der Punkte z auf Status-Balken (x-Koordinate=x) */
{
char str[6];
int i;
for(i=5;i>=0;i--) {
str[i]= z % 10 + 48;
z/=10;
}
Move(&rphi,x,8L); Text(&rphi,str,6L);
}
shipanz(x,s)
long x;
BYTE s;
/* Ausdruck der Anzahl an Panzern s auf Status-Balken (x-Koordinate=x) */
{
char str[2];
str[1]=s%10+48; s/=10; str[0]=s%10+48;
Move(&rphi,130L+x,8L); Text(&rphi,str,2L);
}
strig()
/* Feuerknopf-Abfrage und Verlangsamung bei dauerndem Druck auf Knopf */
{
if(ciaa->ciapra & 0x80 && demo==0) {
strigzae=0;
return(0);
}
else {
if(strigzae) {
strigzae--;
return(0);
}
else {
strigzae=DAUERFEUERBREMSE;
return(1);
}
}
}
eibew()
/* Panzer bewegen (Joystick oder, im Demo-Modus, zufaellig) */
{
BYTE flg=0;
static BYTE demorichtung=1;
if(eiphase<0) {
/* Panzer explodiert */
BltBitMap(&expb,OFF1,(-eiphase-1)*EXPHEIGHT+OFF2,&bm,eix,eiy,KO3,KO4,
0xc0L,0xffL);
--eiphase;
if(eiphase==-EXPPHASEN-1) {
abschuss=1; eiphase=0; eix=eiligre; eizaemax=EIZAEMAXNORM[version];
}
}
else {
if(demo==0) {
if(custom->joy1dat&0x200) { /* Joystick bewegt Panzer */
if(eix-EIXD[version]>=eiligre) {
eix-=EIXD[version]; eiphase=++eiphase%PHASEN; flg=1;
}
}
else if (custom->joy1dat & 2) {
if (eix+EIXD[version]<=eiregre) {
eix+=EIXD[version]; eiphase=(eiphase+PHASEN-1) % PHASEN;
flg=1;
}
}
}
else { /* Demo-Modus: Zufall bewegt Panzer */
rnd1();
if(rnd>61000L) {
rnd1();
if(rnd>55000L)
demorichtung=inxd;
else {
rnd1();
demorichtung=3L*rnd/0x10000L-1;
}
}
if(demorichtung==-1) {
if(eix-EIXD[version]>=eiligre) {
eix-=EIXD[version]; eiphase=++eiphase%PHASEN; flg=1;
}
else
demorichtung=-demorichtung;
}
else if (demorichtung==1) {
if (eix+EIXD[version]<=eiregre) {
eix+=EIXD[version]; eiphase=(eiphase+PHASEN-1) % PHASEN;
flg=1;
}
else
demorichtung=-demorichtung;
}
}
if(flg) /* Panzer bewegt: flg!=0 */
if(eiphase==0) {
if(eibewsoundzae==0) {
sound(2,0,3);
eibewsoundzae=EIBEWSOUNDZAEMAX;
}
eibewsoundzae--;
}
else
eibewsoundzae==0;
BltBitMap(&inb,INEX*(INA-1)+OFF1,eiphase*INEY+OFF2,&bm,eix,eiy,KO3,KO4,0xc0L,0xffL);
}
}
schbew()
/* Schuss bewegen und Abfrage auf Treffer */
{
int xz=0,yz=0;
short farbe;
long i;
if(schuss.flag) { /* immer nur ein Schuss unterwegs */
if(schuss.y<=VY-SKO4) { /* Schuss nicht mehr sichtbar */
schuss.flag=0;
/* Zeit-Dummys: */
farbe=ReadPixel(&rp,13L,13L);
BltBitMap(&schb,SOFF1,SOFF2,&dummyb,0L,0L,SKO3,SKO4,0xc0L,0xffL);
for(i=0;i<50;i++) ;
}
else {
BltBitMap(&schb,SOFF1,schuss.phase*SCHHEIGHT+SOFF2,&bm2,schuss.x,
schuss.y,SKO3,SKO4,0xc0L,0xffL);
if(schuss.y>=VY) {
if(farbe=ReadPixel(&rp,schuss.x+SHS,schuss.y)) {
/* Treffer */
xz=(schuss.x+SHS-inx)/KO1; yz=(schuss.y-iny)/KO2[kick];
if(farbe==7) { /* Bunker hat Farbe 7 */
sound(7,0,1); /* Bunkertreffer */
BltPattern(&rp,bssb.Planes[0],schuss.x+SHS-BSHS,
schuss.y-BSSHEIGHT+SCHD[version],
schuss.x+SHS-BSHS+BSSWIDTH-1L,schuss.y+SCHD[version]-1L,
BPRS); /* Bunker beschaedigen */
schuss.flag=0;
RectFill(&rp2,schuss.x,schuss.y,schuss.x+SKO3-1L,
schuss.y+SKO4-1L);
}
else if(schuss.y<MUTY+MUTKO4) {
if(mutphase>=0) { /* Mutterschiff-Treffer */
sound(9,0,3);
mutphase=-1;
RectFill(&rp2,schuss.x,schuss.y,schuss.x+SKO3-1L,
schuss.y+SKO4-1L);
schuss.flag=0;
if(demo==0) {
rnd1();
score[version][player]+=(mutoff/MUTWIDTH)*
(MUTPUNKTE+MUTPUNKTERND*(long)rnd/65536L);
punktezaehlung();
}
}
}
else if(invor[xz][yz]>0) {
sound(5,0,1); /* Invader getroffen */
if(demo==0) {
score[version][player]+=10*invor[xz][yz];
punktezaehlung();
}
invor[xz][yz]=-1;
schuss.flag=0;
rnd1();
RectFill(&rp2,schuss.x,schuss.y,schuss.x+SKO3-1L,
schuss.y+SKO4-1L);
}
}
}
else {
/* Zeit-Dummy: */
farbe=ReadPixel(&rp,0L,0L);
}
schuss.y-=SCHD[version];
schuss.phase=++schuss.phase%SCHPHASEN;
}
}
else { /* kein Schuss unterwegs */
if(strig() && eiphase>=0) {
schuss.y=eiy-SAY; /* Schuss abgefeuert */
schuss.x=eix+SAX;
schuss.phase=0;
schuss.flag=1;
sound(0,0,4);
}
/* Zeit-Dummys: */
farbe=ReadPixel(&rp,13L,13L);
BltBitMap(&schb,SOFF1,SOFF2,&dummyb,0L,0L,SKO3,SKO4,0xc0L,0xffL);
for(i=0;i<20;i++) ;
}
}
misbew()
/* Bewegen der Missiles */
{
int xz,yz,i,k,farbe1,farbe2,flg;
long zwx1,zwx2,yko;
miszae1 = ++miszae1 % miszae1max;
if(miszae1==0) {
/* Ein Invader darf nur dann schiessen, wenn ueber ihm keiner ist;
mit invor1 und invor2 werden die Indices, mit invor3 die Anzahl
der Kandidaten, die fuer den Start eines Misiles in Frage kommen,
gespeichert*/
invor3=0;
for(xz=inligre;xz<=inregre;xz++) {
for(yz=inungre;yz>=inobgre;yz--) {
if(invor[xz][yz]>0) {
break;
}
}
if(yz>=inobgre) {
invor1[xz]=yz; invor2[invor3]=xz; invor3++;
}
else {
invor1[xz]=-1;
}
}
}
for(i=0;i<MISANZ[version];i++) { /* MISANZ ist max. Missile-Anzahl */
if(mis[i].y>=YA[kick]+VY) {
mis[i].flag=0; /* Missile am Rand verschwunden */
}
if(mis[i].flag) { /* Missile unterwegs */
BltBitMap(&misb,MOFF1,MOFF2+mis[i].phase*MISHEIGHT,&bm2,mis[i].x,
mis[i].y,MKO3,MKO4,0xc0L,0xffL);
zwx1=mis[i].x+MHS-MHSDX; zwx2=mis[i].x+MHS+MHSDX; flg=0;
for(k=0;k<MHSANZ;k++) { /* Sensitive Punkte der Missiles
auf Kollision abfragen */
farbe1=ReadPixel(&rp,zwx1,mis[i].y+misyhs[k]);
farbe2=ReadPixel(&rp,zwx2,mis[i].y+misyhs[k]);
if(farbe1==7||farbe2==7) {
flg=7; yko=misyhs[k]; /* Bunkertreffer */
break; /* oberster Wert zaehlt */
}
else if(farbe1||farbe2) { /* Panzertreffer */
flg=1; yko=misyhs[k]; /* unterster Wert zaehlt*/
}
}
if(flg) { /* Treffer */
if(flg==7) { /* Bunker hat Prioritaet ueber
Panzertreffer */
sound(7,0,1);
mis[i].flag=0;
BltPattern(&rp,bsib.Planes[0],mis[i].x+MHS-BIHS,
mis[i].y-MISD[version]+1L+yko,mis[i].x+MHS-BIHS+BSIWIDTH-1L,
mis[i].y-MISD[version]+BSIHEIGHT+yko,BPRI);
RectFill(&rp2,mis[i].x,mis[i].y,mis[i].x+MKO3-1L,
mis[i].y+MKO4-1L);
}
/* Abfrage nur um auszuschliessen, dass ein Invader sich selbst
abschiesst (beim Herabsetzen des Invaderblocks am Rand) */
else if(mis[i].y+yko>=eiy && eiphase>=0) {
sound(1,0,4); /* Panzertreffer */
mis[i].flag=0;
RectFill(&rp2,mis[i].x,mis[i].y,mis[i].x+MKO3-1L,
mis[i].y+MKO4-1L);
if(demo==0 && trainer==0)
--ship[player];
SetAPen(&rphi,1L);
shipanz(playx[player],ship[player]);
eiphase=-1; eizaemax=STRAFE;
eibew();
}
}
mis[i].y+=MISD[version]; mis[i].phase=++mis[i].phase%MISPHASEN;
}
else {
rnd1(); /* zufaellig Missile starten */
if(rnd<=MISWK[version] && miszae1==0 && invor3!=0) {
rnd1(); /* Zufall entscheidet ueber
gezielten Angriff auf Panzer */
if(rnd<=GEZIELTEWK[version]) {
xz=(eix+SAX+SHS-inx)/KO1;
if(xz<inligre)
xz=inligre;
else if(xz>inregre)
xz=inregre;
}
else {
rnd1();
xz=invor2[(long)rnd*invor3/65536L]; /* kein gezielter
Schuss */
}
if((yz=invor1[xz])!=-1) { /* Missile nur ausloesen,
wenn Invader auch vorhanden */
sound(4,0,2);
mis[i].y=KO2[kick]*yz+iny+MAY; mis[i].x=KO1*xz+inx+MAX;
mis[i].phase=0; mis[i].flag=1;
}
}
/* Zeit-Dummy */
for(k=0;k<2*MISANZ[version];k++)
farbe1=ReadPixel(&rp,0L,0L);
BltBitMap(&misb,MOFF1,MOFF2,&dummyb,0L,0L,MKO3,MKO4,0xc0L,0xffL);
}
}
}
mistre()
/* Treffer von Schuss auf Missile, kurze Explosion einblenden */
{
int i,k=0;
long yko=0;
for(i=0;i<MISANZ[version];i++) {
if(mis[i].flag && yko<mis[i].y && mis[i].x+MHS-MHSDX<=schuss.x+SHS &&
schuss.x+SHS<=mis[i].x+MHS+MHSDX) {
if(schuss.flag && schuss.y+SCHD[version]<=mis[i].y-MISD[version]+
misyhs[MHSANZ-1]) {
yko=mis[i].y; k=i+1;
}
}
}
if(schx) {
RectFill(&rp2,schx,schy,MTKO3+schx,MTKO4+schy);
schx=0;
}
if(k) {
sound(8,0,2);
k--; mis[k].flag=0;
RectFill(&rp2,mis[k].x,mis[k].y,mis[k].x+MKO3-1L,mis[k].y+MKO4-1L);
RectFill(&rp2,schuss.x,schuss.y,schuss.x+SKO3-1L,schuss.y+SKO4-1L);
schuss.flag=0; schx=schuss.x+SHS-MTHSX; schy=schuss.y-MTHSY;
BltBitMap(&mistreb,MTOFF1,MTOFF2,&bm2,schx,schy,MTKO3,MTKO4,0xc0L,
0xffL);
}
}
mutbew()
/* Mutterschiff bewegen */
{
if(mutxd) {
if(mutphase<0)
/* Explosion des Mutterschiffs*/
BltBitMap(&mutb,MUTOFF1+mutoff,(-mutphase+MUTPHASEN-1)*MUTHEIGHT+
MUTOFF2,&bm,mutx,MUTY,MUTKO3,MUTKO4,0xc0L,0xffL);
else {
BltBitMap(&mutb,MUTOFF1+mutoff,mutphase*MUTHEIGHT+MUTOFF2,&bm,mutx,
MUTY,MUTKO3,MUTKO4,0xc0L,0xffL);
if(mutphase==0) {
if(mutbewsoundzae==0) {
sound(10,0,3);
mutbewsoundzae=MUTBEWSOUNDZAEMAX;
}
mutbewsoundzae--;
}
}
mutx+=mutxd;
if(mutxd<0) {
if(mutx<=VX-MUTKO3)
mutxd=0;
else {
if(mutphase<0)
if(mutphase==-MUTEXPPHASEN)
mutxd=0;
else
--mutphase;
else
mutphase=++mutphase%MUTPHASEN;
}
}
else {
if (mutx>=XA+VX)
mutxd=0; /* am Rand verschwunden */
else {
if(mutphase<0)
if(mutphase==-MUTEXPPHASEN)
mutxd=0;
else
--mutphase;
else
mutphase=(mutphase+MUTPHASEN-1) % MUTPHASEN;
}
}
}
else {
rnd1(); /* kein Mutterschiff unterwegs */
if(rnd<=MUTWK) { /* Zufall entscheidet ueber neues Schiff */
mutbewsoundzae=0;
if(rnd%2==0) {
mutxd=MUTD[version]; mutx=VX-MUTKO3;
}
else {
mutxd=-MUTD[version]; mutx=XA+VX;
}
mutphase=0;
rnd1();
mutoff=MUTWIDTH*(MUTANZ*rnd/0x10000L);
}
/* Dummy */
BltBitMap(&mutb,MUTOFF1+mutoff,mutphase*MUTHEIGHT+MUTOFF2,
&dummyb,0L,0L,MUTKO3,MUTKO4,0xc0L,0xffL);
}
}
fingre()
/* Findet die Grenzen des Invaderblocks, damit sich die Invaders stets bis
zum Rand bewegen, auch wenn mehrere bereits abgeschossen sind. */
{
int i;
for(i=inligre;i<inregre;i++)
if(fingre1(i))
break;
inligre=i;
for(i=inregre;i>inligre;i--)
if(fingre1(i))
break;
inregre=i;
for(i=inobgre;i<inungre;i++)
if(fingre2(i))
break;
inobgre=i;
for(i=inungre;i>inobgre;i--)
if(fingre2(i))
break;
inungre=i;
ligre=aligre-inligre*KO1; regre=aregre-inregre*KO1-KO3+1L;
ungre=by+BKO4-inungre*KO2[kick]-KO4;
}
fingre1(i)
int i;
{
int j;
for(j=inobgre;j<=inungre;j++)
if(invor[i][j])
return(1);
return(0);
}
fingre2(j)
int j;
{
int i;
for(i=inligre;i<=inregre;i++)
if(invor[i][j])
return(1);
return(0);
}
inbew()
/* Bewegung der Invaders und Steuerung des Gesamtablaufs */
{
int i,xv,yv,flag=0;
eibewsoundzae=0; abschuss=0;
if(invaderanz==0) /* Alle schon abgeschossen ? */
if(demo==0)
return(KEINE_IN_MEHR);
else
return(DEMO);
label:
for(yv=inobgre;yv<=inungre;yv++) { /* Alle Invaders bewegen */
for(xv=inligre;xv<=inregre;xv++) {
if(invor[xv][yv]) {
if(invor[xv][yv]>0) {
BltBitMap(&inb,INEX*(invor[xv][yv]-1)+OFF1,inphase*INEY+OFF2,
&bm,KO1*xv+inx,KO2[kick]*yv+iny,KO3,KO4,0xc0L,0xffL);
}
else {
/* explodierende Invader */
BltBitMap(&expb,OFF1,(-invor[xv][yv]-1)*EXPHEIGHT+OFF2,&bm,
KO1*xv+inx,KO2[kick]*yv+iny,KO3,KO4,0xc0L,0xffL);
if(invor[xv][yv]==-EXPPHASEN) {
invaderanz--; invor[xv][yv]=0;
if(invaderanz==0) {
if(demo==0)
flag=KEINE_IN_MEHR;
else
flag=DEMO;
break;
}
else
fingre();
}
else
--invor[xv][yv];
}
/* Da die Geschwindigkeit der Schuesse, Missiles, usw.
konstant sein sollen, wird nach jeder Bewegung eines
Invaders restbew() aufgerufen */
if(flag=restbew()) {
break; /* Panzer getroffen */
}
}
}
if(flag)
break;
}
if(flag)
return(flag);
flag=0;
for(i=0;i<INBEWVERZ[version];i++) {
/* damit der letzte Invader etwas gebremst wird */
if(flag=leer()) {
break;
}
}
if(inbewsoundzae==0) {
inbewsound=(inbewsound+1)%3;
sound(6,inbewsound*30,2);
inbewsoundzae=INBEWSOUNDZAEMAX;
}
inbewsoundzae--; inphase+=inphased;
if(inphase>0) {
if(inphase==PHASEN) {
inphase=0;
}
}
else {
if(inphase==-1) {
inphase=PHASEN-1;
}
}
inx+=inxd;
if ( (inx>regre) || (inx<ligre) ) {
inxd=-inxd; inx+=inxd; inphased=-inphased;
RectFill(&rp,inligre*KO1+inx,inobgre*KO2[kick]+iny,
inregre*KO1+inx+KO3-1L,inungre*KO2[kick]+iny+KO4-1L);
if(kick || iny+2*INYD[kick] <= ungre)
RectFill(&rp,VX,inungre*KO2[kick]+KO4+iny,VX+XA,
iny+INYD[kick]+inungre*KO2[kick]+KO4-1L);
else
RectFill(&rp,VX,inungre*KO2[kick]+KO4+iny,VX+XA,
iny+INYD[kick]+inungre*KO2[kick]+KO4+2L);
iny+=INYD[kick];
if (iny>ungre) /* Invaders schon zu tief ? */
if(demo==0)
return(UEBERROLLT);
else
return(DEMO);
}
if(flag)
return(flag);
goto label;
}
restbew()
/* Alles ausser Invaders bewegen, Abfrage der Maustaste (Pause)
Wenn Panzer abgeschossen oder Spiel unterbrochen wurde gibt restbew() einen
entsprechenden Wert zurueck */
{
int item=1;
if(demo) {
time++;
if(time==DEMOTIME)
return(DEMO);
if((ciaa->ciapra & 0x80)==0) {
while((ciaa->ciapra & 0x80)==0) ;
return(QUITDEMO);
}
}
if((ciaa->ciapra & 0x40)==0) { /* Mit linker Maustaste Pause */
while((ciaa->ciapra & 0x40)==0) ;
if(demo==0) {
SetRast(&rphi,3L);
SetAPen(&rphi,2L); SetBPen(&rphi,3L);
Move(&rphi,215L,8L); Text(&rphi,"Pause - use joystick !",22L);
pausanz(0);
SetAPen(&rphi,1L);
pausanz(1);
while(ciaa->ciapra&0x80) {
if(custom->joy1dat&0x200)
item=0;
else if(custom->joy1dat&2)
item=1;
SetAPen(&rphi,1L); pausanz(item);
SetAPen(&rphi,2L); pausanz((item+1)%2);
}
while((ciaa->ciapra&0x80)==0) ;
SetBPen(&rphi,0L);
titrest();
if(item==0)
return(QUIT);
}
else {
return(QUITDEMO);
}
}
/* Die Zaehler (Endung 'zae') sind fuer die Geschwindigkeiten
verantwortlich */
mutzae++;
if(mutzae==MUTZAEMAX[version]) {
mutzae=0;
mutbew();
}
eizae++;
if (eizae==eizaemax) {
eizae=0;
eibew();
}
schzae++;
if (schzae==SCHZAEMAX[version]) {
schzae=0;
schbew();
mistre();
}
miszae++;
if (miszae==MISZAEMAX[version]) {
miszae=0;
misbew();
}
if(abschuss) {
if(demo==0)
return(ABGESCHOSSEN);
else
return(DEMO);
}
else
return(0);
}
leer()
/* Zeitdummy */
{
/* Zeit-Dummy: */
BltBitMap(&inb,OFF1,OFF2,&dummyb,0L,0L,KO3,KO4,0xc0L,0xffL);
return(restbew());
}
pausanz(item)
BYTE item;
/* Pause im Status-Balken anzeigen */
{
if(item) {
Move(&rphi,510L,8L); Text(&rphi,"Back to game",12L);
}
else {
Move(&rphi,10L,8L); Text(&rphi,"Quit",4L);
}
}