#include <16F628.h>

#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //Internal RC Osc, no CLKOUT
#FUSES PUT                      //Power Up Timer
#FUSES NOPROTECT                //Code not protected from reading
#FUSES BROWNOUT                 //Reset when brownout detected
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                    //No EE protection

#use delay(clock=16000000)

#define R1LED PIN_A0
#define G1LED PIN_A1
#define B1LED PIN_A2

#define R2LED PIN_A3
#define G2LED PIN_A4
#define B2LED PIN_B7

#define R3LED PIN_B1
#define G3LED PIN_B2
#define B3LED PIN_B3

#define R4LED PIN_B4
#define G4LED PIN_B5
#define B4LED PIN_B6


#define BUTTON PIN_B0

int1 timeflag;         //vége a visszaszámlálásnak? 1 igen; 0 nem
int16 time;            //a visszaszámlálásban segít
int8 pnum;            //tárolja, hogy mely effekt menjen

void setscreen(int1 condition);         //kijelző írása

#INT_EXT
void ext_isr()
{
int8 p1;
int8 p2;

p1=input_a();            //kimenet mentése

cimke:
delay_ms(10);
p2=input_b();
if ((p2 && 1)==0) goto cimke;

++pnum;                     //új effekt
if (pnum==6) pnum=0;

setscreen(1);           // a kijelzőre írunk;

output_b(p2);
output_a(p1);

setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
set_timer1(0xffff);
enable_interrupts(INT_TIMER1);
time=100;                                 //elindítjuk a timer1-t





}

 #INT_TIMER1
 void clock_isr()
{
--time;               //csökkentjük a time-t

if (time==0) timeflag=1;            //ha elértük a nullát, a timert majd ki kell kapcsolni, ezt jelzi a flag
set_timer1(0xffff);

}




void kiir( int8 r1,int8 r2,int8 r3,int8 r4,
         int8 g1,int8 g2,int8 g3,int8 g4,
         int8 b1,int8 b2,int8 b3,int8 b4 )
{
       int8 i;                  //4 rgb ledet fogok külön irányítani, ez a pwm

   disable_interrupts(GLOBAL);

         output_a(0b00111111);
         output_b(0b11111111);            //minden led világít

      for(i=255; i!=0; --i)
          {

            delay_us(20);

            if (r1==0) output_low(R1LED);
            if (g1==0) output_low(G1LED);
            if (b1==0) output_low(B1LED);               //kikapcsoljuk az adott ledet, ha már eleget világított

            if (r2==0) output_low(R2LED);
            if (g2==0) output_low(G2LED);
            if (b2==0) output_low(B2LED);

            if (r3==0) output_low(R3LED);
            if (g3==0) output_low(G3LED);
            if (b3==0) output_low(B3LED);

            if (r4==0) output_low(R4LED);
            if (g4==0) output_low(G4LED);
            if (b4==0) output_low(B4LED);

            --r1;
            --r2;
            --r3;
            --r4;
            --g1;
            --g2;
            --g3;
            --g4;
            --b1;
            --b2;
            --b3;
            --b4;
            }

   enable_interrupts(GLOBAL);
}


int elso()
{               //6 effekt van

      int8 i,j;
      int8 r1=161;
      int8 g1=1;
      int8 b1=1;


      output_a(0);
      output_b(1);




   while(pnum==0)
      {


      for (i=110; i!=0; --i)
         {
        for (j=2;j!=0;--j)
        {
        kiir(r1,r1,r1,r1,g1,g1,g1,g1,b1,b1,b1,b1);
        }

      ++b1;


         }

      for (i=100; i!=0; --i)
         {
        for (j=2;j!=0;--j)
        {
        kiir(r1,r1,r1,r1,g1,g1,g1,g1,b1,b1,b1,b1);
        }

      ++g1;


}

      for (i=160; i!=0; --i)
         {
        for (j=2;j!=0;--j)
        {
        kiir(r1,r1,r1,r1,g1,g1,g1,g1,b1,b1,b1,b1);
        }

      --r1;

         }
         if (pnum!=0) return 0;
         if (timeflag==1) setscreen(0);            //ha előtte időzítés ment, és letelt, akkor kijelzőre írás(és időzítés kikapcsolása)

      for (i=110; i!=0; --i)
         {
         for (j=2;j!=0;--j)
        {
        kiir(r1,r1,r1,r1,g1,g1,g1,g1,b1,b1,b1,b1);
        }

      --b1;


}



     for (i=160; i!=0; --i){
   kiir(r1,r1,r1,r1,g1,g1,g1,g1,b1,b1,b1,b1);
      ++r1;


      }

    for (i=100; i!=0; --i)
         {
     for (j=2;j!=0;--j)
     {
     kiir(r1,r1,r1,r1,g1,g1,g1,g1,b1,b1,b1,b1);
     }

      --g1;

         }

         if (timeflag==1) setscreen(0);

     }

return 0;

}

int masodik()
{

      int8 i;
      int8 r1=181;
      int8 r2=1;


      int8 g1=1;
      int8 g2=101;


      int8 b1=1;
      int8 b2=111;

      output_a(0);
      output_b(1);


   while(pnum==1)
      {




      for (i=110; i!=0; --i)
         {
 kiir(r1,r2,r1,r2,g1,g2,g1,g2,b1,b2,b1,b2);

      ++b1;
      --b2;


         }

      for (i=100; i!=0; --i)
         {
 kiir(r1,r2,r1,r2,g1,g2,g1,g2,b1,b2,b1,b2);

      ++g1;
      --g2;


}

      for (i=180; i!=0; --i)
         {
  kiir(r1,r2,r1,r2,g1,g2,g1,g2,b1,b2,b1,b2);

      --r1;
      ++r2;
}
         if (pnum!=1) return 0;
         if (timeflag==1) setscreen(0);


      for (i=110; i!=0; --i)
         {
 kiir(r1,r2,r1,r2,g1,g2,g1,g2,b1,b2,b1,b2);

      --b1;
      ++b2;


}



     for (i=180; i!=0; --i){
  kiir(r1,r2,r1,r2,g1,g2,g1,g2,b1,b2,b1,b2);
      ++r1;
      --r2;


      }

    for (i=100; i!=0; --i)
         {
 kiir(r1,r2,r1,r2,g1,g2,g1,g2,b1,b2,b1,b2);
      --g1;
      ++g2;
         }

         if (timeflag==1) setscreen(0);

     }

return 0;

}

int harmadik(int16 i)
{

output_b(1);
output_a(1);


output_a(0b00000001);
output_b(0b01101001);
delay_ms(i);

output_a(0b00001011);
output_b(0b01000001);
delay_ms(i);

output_a(0b00011111);
output_b(0b00000011);
delay_ms(i);

if (!((pnum==2) || pnum==3)) return 0;
if (timeflag==1) setscreen(0);

output_a(0b00011110);
output_b(0b10010111);
delay_ms(i);

output_a(0b00010100);
output_b(0b10111111);
delay_ms(i);


output_a(0b00000000);
output_b(0b11111101);
delay_ms(i);


 return 0;
}

int negyedik ()
{
harmadik(100);
harmadik(100);
harmadik(100);
harmadik(200);
harmadik(200);
harmadik(200);
harmadik(400);
harmadik(400);
harmadik(800);
harmadik(800);
if (pnum!=3) return 0;
harmadik(1600);
if (pnum!=3) return 0;
harmadik(3200);
if (pnum!=3) return 0;
harmadik(1600);
harmadik(800);
harmadik(800);
harmadik(400);
harmadik(400);
harmadik(200);
harmadik(200);
harmadik(200);
return 0;
}

int otodik()
{

int8 i,j;
int8 r1=1;

int8 b1=1;

int8 g1=1;



output_a(0);
output_b(1);

while (pnum==4)
{

   for (i=200; i!=0; --i)
   {
   for (j=2; j!=0; --j)
   {   kiir(r1,1,1,r1,1,g1,1,g1,1,1,b1,b1);}
   ++r1;
   ++g1;
   ++b1;
   }

   for (i=200; i!=0; --i)
   {
   for (j=2; j!=0; --j)
   {   kiir(r1,1,1,r1,1,g1,1,g1,1,1,b1,b1);}
   --r1;
   --g1;
   --b1;
   }


   if (pnum!=4) return 0;
   if (timeflag==1) setscreen(0);


   for (i=200; i!=0; --i)
   {
   for (j=2; j!=0; --j)
   {   kiir(r1,r1,1,1,g1,1,g1,1,b1,1,1,b1);}
   ++r1;
   ++g1;
   ++b1;
   }

   for (i=200; i!=0; --i)
   {
   for (j=2; j!=0; --j)
   {   kiir(r1,r1,1,1,g1,1,g1,1,b1,1,1,b1);}
   --r1;
   --g1;
   --b1;
   }


   if (pnum!=4) return 0;
   if (timeflag==1) setscreen(0);


   for (i=200; i!=0; --i)
   {
   for (j=2; j!=0; --j)
   {   kiir(1,r1,r1,1,1,g1,1,g1,b1,b1,1,1);}
   ++r1;
   ++g1;
   ++b1;
   }

   if (pnum!=4) return 0;

   for (i=200; i!=0; --i)
   {
   for (j=2; j!=0; --j)
   {   kiir(1,r1,r1,1,1,g1,1,g1,b1,b1,1,1);}
   --r1;
   --g1;
   --b1;
   }


   if (pnum!=4) return 0;
   if (timeflag==1) setscreen(0);


   for (i=200; i!=0; --i)
   {
   for (j=2; j!=0; --j)
   {   kiir(1,1,r1,r1,g1,1,g1,1,1,b1,b1,1);}
   ++r1;
   ++g1;
   ++b1;
   }


   for (i=200; i!=0; --i)
   {
   for (j=2; j!=0; --j)
   {   kiir(1,1,r1,r1,g1,1,g1,1,1,b1,b1,1);}
   --r1;
   --g1;
   --b1;
   }



}


return 0;
}


int hatodik()
{

int8 i,j;
int8 r1=81;
int8 r2=1;
int8 r3=81;
int8 r4=81;

int8 g1=81;
int8 g2=81;
int8 g3=1;
int8 g4=1;

int8 b1=1;
int8 b2=81;
int8 b3=81;
int8 b4=1;



output_a(0);
output_b(1);

while (pnum==5)
{


   for (i=80; i!=0; --i)
   {
  for (j=3; j!=0; --j) {   kiir(r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4);}
   r1+=2;
   ++g2;
   ++b3;
   ++g4;
   --r3;
   }

      if (pnum!=5) return 0;
   if (timeflag==1) setscreen(0);


   for (i=80; i!=0; --i)
   {
 for (j=3; j!=0; --j) {   kiir(r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4);}
   ++r2;
   --r1;
   b2+=2;
   ++g3;
   ++g1;
   --g2;

   }


   for (i=80; i!=0; --i)
   {
 for (j=3; j!=0; --j) {   kiir(r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4);}
   --r1;
   --r4;
   ++r3;
   ++r2;
   g1-=2;
   b4+=2;
   b2-=2;
   --b3;
   ++b1;


   }

   for (i=80; i!=0; --i)
   {
 for (j=3; j!=0; --j) {   kiir(r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4);}
   ++g4;
   --g3;
   ++g2;
   ++r2;
   --r1;
   b1+=2;
   ++b4;
   --b3;
   }

   if (pnum!=5) return 0;
   if (timeflag==1) setscreen(0);



for (i=80; i!=0; --i)
   {
 for (j=3; j!=0; --j) {   kiir(r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4);}
   r4+=2;
   ++g1;
   --g2;
   --g4;
   --b1;
   --b2;
   ++r3;
   b3+=2;
   b4-=3;

   }


for (i=80; i!=0; --i)
   {
 for (j=3; j!=0; --j) {   kiir(r1,r2,r3,r4,g1,g2,g3,g4,b1,b2,b3,b4);}
   ++r1;
   r2-=3;
   --r3;
   --r4;
   --g4;
   b1-=2;
   ++b2;
   --b3;
   }
}



return 0;
}


void setscreen(int1 condition)
{

disable_interrupts(GLOBAL);
 set_tris_b(0);   //interrupt RB0-ból kimenetet csinálunk, és ezzel vezéreljüka D-flipflopot

 if (condition==0)         //ha kijelzőre már nem akarunk írni, csak 0-t
 {
 output_b(0);
 timeflag=0;
 set_timer1(0);
 disable_interrupts(INT_TIMER1);
 setup_timer_1(T1_DISABLED);         //és kikapcsoljuka  timer1-t ha be volt kapcsolva
 }

 else
 {                        //ha az interrupt indította a setscreent, kiírjuk a kijelzőre az effekt számát

   switch (pnum)
   {
   case 0: output_b(0b11111110);            //ezek még nem számok igazából, csak össze vissza valami
   case 1: output_b(0b11111100);
   case 2: output_b(0b11111000);
   case 3: output_b(0b11110000);
   case 4: output_b(0b11100000);
   case 5: output_b(0b11000000);
   }

 }

 delay_us(10);
 output_high(PIN_B0);            //kikapcsoljuk a lath enablet- tehát hogy a d-flipflop érékelje a változást
 delay_us(10);

set_tris_b(1);

enable_interrupts(GLOBAL);
}


void main()
{



      pnum=0;
      timeflag=0;

      ext_int_edge(H_TO_L);

      setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
      setup_timer_2(T2_DISABLED,0,1);
      setup_comparator(NC_NC_NC_NC);
      setup_vref(FALSE);
      set_timer0(0);


   set_tris_a(0b11100000);

   setscreen(0);  //(kijelzőre 0-t írunk))

   output_a(0);
   output_b(1);

   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);

while(1)
{

 switch (pnum)
   {                           //melyik effekt
   case 0: elso(); break;
   case 1: masodik(); break;
   case 2: harmadik(1000); break;
   case 3: negyedik(); break;
   case 4: otodik(); break;
   case 5: otodik(); break;
   }

 }


   }

