// Includes #include // Include for PA_Lib #include #include typedef struct{ float x, y; } POINT; typedef struct{ int NumPoints; POINT Point[20]; } SHAPE; typedef struct{ POINT Loc; // Location on the screen int ViewAngle; // Angle at which the object is facing POINT Direction; // Direction which the object is moving, in pixels SHAPE Shape; // The shape of the object SHAPE Screen; // Actual points it occupies on the screen } OBJECT; struct{ OBJECT Ship; // The players spaceship } g; typedef struct { POINT Loc; int ViewAngle; POINT Direction; SHAPE Shape; SHAPE Screen; int Frames; } PARTICLE; struct { PARTICLE Fire[10]; } fire; //Exhaust particles void Cleanup( void ){ PA_Clear8bitBg(0); } void TranslatePoint( POINT *Dest, POINT *Src, int Angle ){ double Radians; Radians = Angle * 0.01745; Dest->x = Src->x * cos( Radians ) - Src->y * sin( Radians ); Dest->y = Src->x * sin( Radians ) + Src->y * cos( Radians ); } void TranslateParticle( PARTICLE *Particle ){ int i; for( i = 0; i < Particle->Shape.NumPoints; i++ ) { TranslatePoint(&Particle->Screen.Point[i],&Particle->Shape.Point[i],Particle->ViewAngle); Particle->Screen.Point[i].x += Particle->Loc.x; Particle->Screen.Point[i].y += Particle->Loc.y; } } void TranslateObject( OBJECT *Object ){ int i; for( i = 0; i < Object->Shape.NumPoints; i++ ){ TranslatePoint( &Object->Screen.Point[ i ], &Object->Shape.Point[ i ], Object->ViewAngle ); Object->Screen.Point[ i ].x += Object->Loc.x; Object->Screen.Point[ i ].y += Object->Loc.y; } } void DrawParticle(PARTICLE *Particle){ if(Particle->Frames>0){ int i; for( i = 1; i < Particle->Shape.NumPoints; i++ ) PA_Draw8bitLineEx(0, Particle->Screen.Point[i-1].x,Particle->Screen.Point[i-1].y,Particle->Screen.Point[i].x, Particle->Screen.Point[i].y,5,1); } } void MoveParticle(PARTICLE *Particle){ if(Particle->Frames<15 && Particle->Frames>0){ if(Particle->Frames==1){ Particle->Shape.NumPoints = 2; Particle->Shape.Point[1].x = 0; Particle->Shape.Point[1].y = 5; Particle->Shape.Point[2].x = 0; Particle->Shape.Point[2].y = 20; Particle->Loc.x = g.Ship.Loc.x; Particle->Loc.y = g.Ship.Loc.y; } Particle->Loc.x += Particle->Direction.x; Particle->Loc.y += Particle->Direction.y; Particle->Frames++; } else Particle->Frames=0; } void DrawObject( OBJECT *Object ){ int i; for( i = 1; i < Object->Shape.NumPoints; i++ ){ PA_Draw8bitLineEx(0, Object->Screen.Point[ i - 1 ].x,Object->Screen.Point[ i - 1 ].y,Object->Screen.Point[ i ].x, Object->Screen.Point[ i ].y,1,2); } PA_Draw8bitLineEx(0, Object->Screen.Point[ i - 1 ].x,Object->Screen.Point[ i - 1 ].y,Object->Screen.Point[ 0 ].x, Object->Screen.Point[ 0 ].y,1,2); } void MoveObject( OBJECT *Object ){ Object->Loc.x += Object->Direction.x; Object->Loc.y += Object->Direction.y; if( Object->Loc.x < 0 ) Object->Loc.x = Object->Loc.x + 255; if( Object->Loc.x > 255 ) Object->Loc.x = Object->Loc.x - 255; if( Object->Loc.y < 0 ) Object->Loc.y = Object->Loc.y + 191; if( Object->Loc.y > 191 ) Object->Loc.y = Object->Loc.y - 191; } void SyncToVerticalRetrace( void ){ PA_WaitForVBL(); Cleanup(); } #define N 10 #define ROTATE_STEP 3 // Number of degrees to rotate #define SPEED 0.08 // Speed control #define FRICTION 0.996 // Speed reduction per frame void Supervisor( void ){ // unsigned short KeyboardStatus; int i = 0; int randm=0; while(1){ for(i=0;i<=10;i++){ TranslateParticle(&fire.Fire[i]); DrawParticle(&fire.Fire[i]); MoveParticle(&fire.Fire[i]); } TranslateObject( &g.Ship ); DrawObject( &g.Ship ); // Draw the ship MoveObject( &g.Ship ); g.Ship.Direction.x *= FRICTION; g.Ship.Direction.y *= FRICTION; if(Pad.Held.Left) // left shift, rotate left { g.Ship.ViewAngle -= ROTATE_STEP; if( g.Ship.ViewAngle < 0 ) g.Ship.ViewAngle = 360 - ROTATE_STEP; } if(Pad.Held.Right) // right shift, rotate right { g.Ship.ViewAngle += ROTATE_STEP; if( g.Ship.ViewAngle > 359 ) g.Ship.ViewAngle = 0 + ROTATE_STEP; } if(Pad.Held.B) // shift-lock, fire { // Not supported yet. } if(Pad.Held.A) // alt, thrust { double Radians,Radp; if (randm==11)randm=0; Radians = g.Ship.ViewAngle * 0.01745; Radp = g.Ship.ViewAngle+(randm*2)* 0.01745; fire.Fire[randm].ViewAngle=g.Ship.ViewAngle+randm*2; fire.Fire[randm].Frames=1; fire.Fire[randm].Direction.x-=sin(Radp)*0.1; fire.Fire[randm].Direction.y+=cos(Radp)*0.1; g.Ship.Direction.x += sin( Radians ) * SPEED; g.Ship.Direction.y -= cos( Radians ) * SPEED; randm++; } SyncToVerticalRetrace(); // Pause until vertical retrace } } // Initialization code. void Init( void ){ PA_Init(); // Initializes PA_Lib PA_InitVBL(); // Initializes a standard VBL PA_Init8bitBg(0,0); PA_SetBgPalCol(0, 1, PA_RGB(31, 31, 31)); PA_SetBgPalCol(0, 2, PA_RGB(31, 0, 0)); PA_SetBgPalCol(0, 3, PA_RGB(0, 0, 31)); PA_SetBgPalCol(0, 4, PA_RGB(0, 31, 0)); PA_SetBgPalCol(0, 5, PA_RGB(31, 28, 7)); PA_SetBgPalCol(1, 1, PA_RGB(31, 31, 31)); PA_SetBgPalCol(1, 2, PA_RGB(31, 0, 0)); PA_SetBgPalCol(1, 3, PA_RGB(0, 0, 31)); PA_SetBgPalCol(1, 4, PA_RGB(0, 31, 0)); g.Ship.Shape.NumPoints = 16; g.Ship.Shape.Point[ 0 ].x = 0; g.Ship.Shape.Point[ 0 ].y = -5; g.Ship.Shape.Point[ 1 ].x = 4; g.Ship.Shape.Point[ 1 ].y = -3; g.Ship.Shape.Point[ 2 ].x = 3; g.Ship.Shape.Point[ 2 ].y = -1; g.Ship.Shape.Point[ 3 ].x = 3; g.Ship.Shape.Point[ 3 ].y = 0; g.Ship.Shape.Point[ 4 ].x = 4; g.Ship.Shape.Point[ 4 ].y = 4; g.Ship.Shape.Point[ 5 ].x = 0; g.Ship.Shape.Point[ 5 ].y = 3; g.Ship.Shape.Point[ 6 ].x = -4; g.Ship.Shape.Point[ 6 ].y = 4; g.Ship.Shape.Point[ 7 ].x = -3; g.Ship.Shape.Point[ 7 ].y = 0; g.Ship.Shape.Point[ 8 ].x = -3; g.Ship.Shape.Point[ 8 ].y = -1; g.Ship.Shape.Point[ 9 ].x = 0; g.Ship.Shape.Point[ 9 ].y = -2; g.Ship.Shape.Point[ 10 ].x = 3; g.Ship.Shape.Point[ 10 ].y = -1; g.Ship.Shape.Point[ 11 ].x = 3; g.Ship.Shape.Point[ 11 ].y = 0; g.Ship.Shape.Point[ 12 ].x = 0; g.Ship.Shape.Point[ 12 ].y = -1; g.Ship.Shape.Point[ 13 ].x = -3; g.Ship.Shape.Point[ 13 ].y = 0; g.Ship.Shape.Point[ 14 ].x = -3; g.Ship.Shape.Point[ 14 ].y = -1; g.Ship.Shape.Point[ 15 ].x = -4; g.Ship.Shape.Point[ 15 ].y = -3; g.Ship.ViewAngle = 0; g.Ship.Loc.x = 56; g.Ship.Loc.y = 45; g.Ship.Direction.x = 0; g.Ship.Direction.y = 0; } int main( int Argc, char *Argv[] ){ Init(); Supervisor(); return 0; }