File: colecobullet.c - Tab length: 1 2 4 8 - Lines: on off - No wrap: on off

/*
Voici un code source ColecoVision qui fait je pense ce que tu cherches.
Ca utilise un algo de bresenham modifi�. En gros, il y � un vaisseau au milieu de l'�cran et
 toi du tourne autour, et lui tire vers toi quelquesoit ta position dans l'�cran. J'esp�re que �a peut t'aider ...
*/


#include <string.h>
#include <coleco.h>
#include <getput1.h>

#define MAXBULLET 8
struct Bullet {
    byte flags;
    byte sprite;
    byte dx,dy;
    int err;
} bullet[MAXBULLET];
#define BUL_ACTIVE 0x80
#define BUL_UP 0x1
#define BUL_LEFT 0x2

void updatebullet(int id)
{
   byte s=bullet[id].sprite;
   byte dx=bullet[id].dx;
   byte dy=bullet[id].dy;
   int e2;

   if((bullet[id].flags&BUL_ACTIVE)==0) return; // not active.
   
   if(sprites[s].x==255 || sprites[s].x==0 || sprites[s].y==0 || sprites[s].y==191) {
      bullet[id].flags=0; // sprite inactive.
      sprites[s].y=192; // off screen.
   }
   e2=bullet[id].err<<1;
   if( e2 > -dy) {
      bullet[id].err-=dy;
      sprites[s].x+=(bullet[id].flags&BUL_LEFT)?-1:1;
   }
   if( e2 < dx ) {
      bullet[id].err+=dx;
      sprites[s].y+=(bullet[id].flags&BUL_UP)?-1:1;
   }
}

int newsprite(int id,int x0,int y0)
{
   const int reserved=2;
   sprites[id+reserved].x=x0;   // reserve first two sprites for player and enemy.
   sprites[id+reserved].y=y0;
   sprites[id+reserved].pattern=8;  // Our bullet pattern
   sprites[id+reserved].colour=15;   // VDP_WHITE
   return id+reserved;
}

int newbullet(int x0,int y0,int x1,int y1)
{
   int i;
   for(i=0;i<MAXBULLET;i++) {
      if(bullet[i].flags&BUL_ACTIVE) continue;
      /* found an unused bullet, so let's set it up.*/
      bullet[i].sprite=newsprite(i,x0,y0);
      bullet[i].flags=BUL_ACTIVE;
      bullet[i].flags|=(x0<x1)?0:BUL_LEFT;
      bullet[i].flags|=(y0<y1)?0:BUL_UP;
      bullet[i].dx=(x0<x1)?x1-x0:x0-x1;
      bullet[i].dy=(y0<y1)?y1-y0:y0-y1;
      bullet[i].err=bullet[i].dx-bullet[i].dy;
      return i;
   }
   return 0;   // all bullets still active.
}

const byte shipsPat[]={
   0x0f,0x1f,0x3f,0xff,0xff,0x3f,0x1f,0x0f,
   0x0f,0x1f,0x3f,0xff,0xff,0x3f,0x1f,0x0f,
   0xf0,0xf8,0xfc,0xff,0xff,0xfc,0xf8,0xf0,
   0xf0,0xf8,0xfc,0xff,0xff,0xfc,0xf8,0xf0,

   0x10,0x30,0xc3,0xcf,0xcf,0x3c,0x30,0x10,
   0x10,0x30,0xc3,0xcf,0xcf,0x3c,0x30,0x10,
   0x08,0x0c,0xc3,0xf3,0xf3,0x3c,0x0c,0x08,
   0x08,0x0c,0xc3,0xf3,0xf3,0x3c,0x0c,0x08,

   0x60,0xd0,0xf0,0x60,0,0,0,0,
   0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,
   0,0,0,0,0,0,0,0,
};

void main()
{
   int i;
   int frame=0;

   screen_mode_1_text();
   sprites_16x16();
   change_spattern(0,shipsPat,3*4);
   sprites[0].x=128;
   sprites[0].y=96;
   sprites[0].pattern=0;
   sprites[0].colour=11;
   sprites[1].x=192;
   sprites[1].y=64;
   sprites[1].pattern=4;
   sprites[1].colour=13;
   for(i=2;i<32;i++) sprites[i].y=0xd0;
   updatesprites(0,12);
   fill_color(0,0x61,255);
   load_ascii();
   cls();
   screen_on();
   print_at(2,0,"Stop, or I'll say stop again!");

   for(;;) {
     
      delay(1);
      for(i=0;i<MAXBULLET;i++) {
         updatebullet(i);
         updatebullet(i);   // 2 pixels per 60th.
      }
      if((frame&15)==0) newbullet(sprites[0].x+8,sprites[0].y+8,sprites[1].x+8,sprites[1].y+8);
      frame++;
      // user to dodge the bullets.
      disable_nmi();
      if(joypad_1&LEFT) sprites[1].x--;
      if(joypad_1&RIGHT) sprites[1].x++;
      if(joypad_1&UP) sprites[1].y--;
      if(joypad_1&DOWN) sprites[1].y++;
      enable_nmi();
     


      // draw the effects.
      updatesprites(0,12);
   }
}

void nmi()
{
   ;
}