//_|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|
//___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|__
//_|___|___|_B r i c k   B r e a k e r   P r o t o t y p e |___|___|___|
//___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|__
//_|___|___|___|___|___|___|f o r   M S  X  2__|___|___|___|___|___|___|
//___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|__
//_|___|___|___|___|Part of the Fusion-c Coding Tutorial___|___|___|___|
//___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|__
//_|___|___|___|___|___|___|__               __|___|___|___|___|___|___|
//___|___|___|___|___|___|__Eric Boez (c) 2018___|___|___|___|___|___|__
//_|___|___|___|___|___|___|___|           _|___|___|___|___|___|___|___|
//___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|__
//_|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|
//___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|__
//_|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|
//___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|__
//_|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|
//___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|___|__
//                 M a d e   w i t h     F U S I O N - C                        
//

#include "fusion-c/header/msx_fusion.h"
#include "fusion-c/header/vdp_sprites.h"
#include "fusion-c/header/vdp_graph2.h"


// Sprites Definition Patterns
//
static const unsigned char board_pattern[]={
  0b11111111,
  0b11111111,
  0b11111111,
  0b11111111,
  0b11111111,
  0b00000000,
  0b00000000,
  0b00000000
};

static const unsigned char ball_pattern[]={
    0b00111100,
    0b01111110,
    0b11111111,
    0b11111111,
    0b11111111,
    0b11111111,
    0b01111110,
    0b00111100
};

unsigned char playfield[24][16];
int x;
int y;
int dir_x;
int dir_y;
int px;
int py;
int brx;
int bry;
char verif_flag;

void FT_wait(int cicles)
{
  int i;
  for(i=0;i<cicles;i++) 
    {
      Halt();
    }
}


// Show Sprites on screen, and do graphic job
//
void FT_Srpites(void)
{
         PutSprite(0,1,x,y,10);           // Ball Sprite
         PutSprite(1,0,px,py,10);         // The Paddle is composed of 3 sprites
         PutSprite(2,0,px+8,py,10);
         PutSprite(3,0,px+16,py,10);
          if (brx!=0 && bry!=0)            // If there is a brick to remove ? it does the job
         {
            Rect(brx*16,bry*8,(brx*16)+15,(bry*8)+7,0,FILL_ALL);   
            brx=0;
            bry=0;
         }
}   

// Verifiation if the ball hurting a brick
//
void FT_verif(int x, int y, int point)
{
  int fx,fy;
  fx=x/16;
  fy=y/8;
      
      if (playfield[fy][fx]==1)
        {
          verif_flag=1;
          playfield[fy][fx]=0;
          if (point==1 || point==3)
          {
            dir_y *= -1;
          }
          if (point==2 || point==4)
          {
            dir_x *= -1;
          }
          brx=fx;
          bry=fy;
     
          Beep();
        }
}

void FT_CalcPosition (void)
{
    // If the Ball is hurting left or right border of the screen
    if (x>247 || x<1)
    {
        dir_x *= -1;
    }
    
    // If the Ball is hurting up or bottom border of the screen
    if (y>187 || y<1)
    {
        dir_y *= -1;
    }

    // If the ball is entering the screen zone where Bricks are supposed to be (5 brick lines, with 8 pixels height : 5x8=40 )
    if (y<44)            
    {
        verif_flag=0;                   // This flag is at 1 if a brick is touched. It disable other testing in case of the ball touch a brick
       
        if (verif_flag==0)  
        {
            FT_verif(x+4, y,1);           // Testing Ball point 1
        }

        if (verif_flag==0)
        {
            FT_verif(x+7, y+4,2);         // testing Ball point 2
        }
       
        if (verif_flag==0)
        {
            FT_verif(x+4, y+7,3);         // Testing Ball point 3
        }
       
        if (verif_flag==0)
        {
            FT_verif(x-1, y+4, 4);        // testing Ball point 4
        }
    }
    verif_flag=0;

    x+=dir_x;
    y+=dir_y;
}

// Joystick control function
//
void FT_Joy()
{
  char joy;
  char trig;

  joy=JoystickRead(0);
  trig=TriggerRead(0);

  // FT_Srpites();

    if (trig!=0)
    {
      Screen(0);
      Exit(0);
    }

    switch (joy)
    {
        case 3:
        if (px<231)
        {
            px++;
        }
        break;

        case 7:
        if (px>0)
        {
          px--;
        }
        break;
    }
}

// Fill the main array with empty 
//
void FT_EmptyField(void)
{
  int j,i;

   for(j=0;j<24;j++)
   {
      for(i=0;i<16;i++)
      {
        playfield[j][i]=0;
      }
  }
}


// Put some Bricks inthe Array
//
void FT_PutBricks(void)
{
  int j,i;
  // Fill The main array with some bricks
  for(j=1;j<5;j++)
   {
      for(i=0;i<16;i++)
      {
        playfield[j][i]=1;
      }
  }
}

// Showing Bricks Wall on screen
//
void FT_ShowBricksWall(void)
{
  int j,i;

   for(j=0;j<24;j++)
   {
      for(i=0;i<16;i++)
      {
        if (playfield[j][i]==1)
        {
          Rect((i*16),(j*8),(i*16)+14,(j*8)+6,99+j*8,FILL_ALL);
          Rect((i*16),(j*8),(i*16)+14,(j*8)+6,255,0);
        }
      }
  }
}

void main(void)
{
    char BallColors[8]= {15,8,8,8,8,8,8,15};
    char BoardColors[8]={15,15,15,15,15,15,15,15};
    
    x=170;
    y=110;
    dir_x=1;
    dir_y=-1;
    px=170;
    py=185;


    // Preparing Screen
    SetColors(15,0,1);
    Screen(8);
    SetColors(255,0,100);
    Cls();
    KeySound(0);
    VDP60Hz();

    // Check MSX
    if(ReadMSXtype()==3)  // If MSX is Turbo-R Switch CPU to Z80 Mode
    {
        ChangeCPU(0);
    }

    // Creating Sprites
    SpriteReset();
    SpriteSmall();
    SetSpritePattern(0, board_pattern,8);
    SetSpritePattern(1, ball_pattern,8);

    SC8SpriteColors(0,BallColors);
    SC8SpriteColors(1,BoardColors);
    SC8SpriteColors(2,BoardColors);
    SC8SpriteColors(3,BoardColors);

    FT_EmptyField();
    FT_PutBricks();
    FT_ShowBricksWall();

  while (1)
  {  
      FT_Joy();

      FT_CalcPosition();

      FT_Srpites(); 

      FT_wait(1);
  }

}