Mensch ärgere dich nicht

Dependencies:   Led-libary TextLCD mbed

Fork of Laufled by Projekte_werkstatt

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "WS2812B.h"
00003 #include "TextLCD.h"
00004 
00005 I2C i2c(P0_5,P0_4);
00006 Serial port(P0_19,P0_18);
00007 BusOut myled(P1_8,P1_9,P1_10,P1_11,P1_0,P1_1,P1_3,P1_4,P1_6,P1_7,P1_12,P1_13);
00008 AnalogIn ldr(P0_12);
00009 AnalogIn poti(P0_11);
00010 //BusOut rgb(P0_9,P1_15,P0_21);
00011 
00012 RGBOut rgb(P0_21,P0_9,P1_15);
00013 
00014 InterruptIn Button0(P0_1);
00015 InterruptIn Button1(P1_16);
00016 InterruptIn Button2(P0_23);
00017 InterruptIn Button3(P0_10);
00018 InterruptIn Button4(P0_15);
00019 BusIn btn(P1_16,P0_23,P0_10,P0_15,P0_1);
00020 
00021 LedOut Feld (p6);//P6
00022 LedOut Home (p7);//P7
00023 LedOut Dice (p8);//P8
00024 //-> Würfel (ersten 3 LED in Binär-4. LED für 7. Zustand), Spieler, Referenz(auch RGB am board)
00025 
00026 TextLCD lcd(p21, p22, p23, p24, p25, p26,TextLCD::LCD20x4);
00027 
00028 InterruptIn DD_A(p29);//P29
00029 InterruptIn DD_B(p30);//P30
00030 InterruptIn DD_C(p35);//P35
00031 DigitalIn DD_D(p35);
00032 BusIn DD(p29,p30);//P29,P30
00033 
00034 //Dice
00035 Timer Random;
00036 Timer RandomDice;
00037 
00038 Ticker DiceAnim;
00039 void DiceRun();
00040 void setDice(char number);
00041 void DicePrint();
00042 void DiceCal(); //umrechning des 7.Zustands in eine Zahl zwischen 1 & 6
00043 char dicePos = 0;
00044 char diceEn = 0;
00045 char diceTick = 0;
00046 char diceNum = 0;
00047 int16_t diceDecode [7]= {0x1,0x88,0x89,0xAA,0xAB,0x1BA,0x154};
00048 //Game
00049 #define Feldgrose 10
00050 #define Spieler 4
00051 #define Steine 4
00052 
00053 char PlayPos[Spieler*Steine];   //Zahl zwischen 0 & 47 ((0xC0 -> Spieler)>>2 / 0x03 -> Stein)
00054 char Start[Spieler*Steine];           //Enthält den Index für PlayPos (nur das 'normale' Spielfend)
00055 char Ziel[Spieler*Steine];            //Enthält den Index für PlayPos (nur das 'normale' Spielfend)
00056 char Drann;                    //Spieler, der drann ist
00057 char count;                    //Für 6er & mehrfaches Würfeln beim Ansetzen
00058 char last[Spieler];            //zuletzt benutzte Spielstein, der zuletzt benutzt wurde
00059 char moglich[Steine];
00060 char selected;                 //der aktuell ausgewählte Zug
00061 char Field[Spieler*Feldgrose]; //Enthält den Index für PlayPos (nur das 'normale' Spielfend)
00062 void FieldPrint();             //Ausgabe auf Com-Port
00063 void FieldGenerate();          //Berechnung von PlayPos auf Start, Ziel, Field
00064 void FeldPrint();              //Ausgabe von Field auf den Led-Streifen (Feld) der Farben
00065 void GameCal();
00066 Ticker MoveAnim;
00067 void MoveRun();
00068 char MoveShow;
00069 void ColorPrint(uint32_t color);
00070 //Animations
00071 char AnimField[Spieler*Feldgrose];
00072 char AnimStart[Spieler*Steine];           
00073 char AnimZiel[Spieler*Steine];
00074 char AnimPos[Spieler*Steine];
00075 char AnimDo; //Feld_Animieren,Start Animieren, Ziel Animierenw
00076 void AnimCal();
00077 //Core Interactions
00078 void reset();
00079 void MoveDo();
00080 void moveNext();
00081 void moveLast();
00082 void DiceStart();
00083 void DiceStop();
00084 //Button entprellung (funktioniert nicht...)
00085 void btn0();
00086 void btn1();
00087 void btn2();
00088 void btn3();
00089 void btn4();
00090 char btnLast;
00091 //Farben
00092 uint32_t Farben[Spieler];      //Berechnete Hellichkeiten der Speiler fertig zur Ausgabe...
00093 uint32_t Background = 0;       //Hintergrund (Leerfeld)
00094 uint32_t DiseC = 0x00FF00;     //Würfelfarbe
00095 void ColorPrint(uint32_t color); //vorher den Header senden (manuell...)
00096 
00097 char DD_last;
00098 char DD_d;
00099 
00100 void dreh();
00101 void druck();
00102 
00103 void up();
00104 void down();
00105 void accept();
00106 void exit();
00107 void print_menu();
00108 void print_pos();
00109 void print_default();
00110 void posUpdate();
00111 char ausfuehren(uint32_t postion);
00112 
00113 //string test ("");
00114 //                                "1234567890123456789","1234567890123456789","1234567890123456789","1234567890123456789",  ,"1234567890123456789","1234567890123456789","1234567890123456789",
00115 const char * const  text_ln0[] = {"MENU:              ","Spiel-Menu:        ","Anzeige-Menu:      ","Speicher-Menu:     ","","7.Zustand-Menu:    ","Farben-Menu:       ","Spiel-Menu:        ","","Spielregeln-Menu:  ","Hell./Sp.Led-Menu: ","Config-Menu:       ","","Autplay-Menu:      ","Wurfel-Menu:       ","Ofline/Com-Menu:   "};
00116 const char * const  text_ln1[] = {"Spiel              ","7.Zustand          ","Farben             ","Spiel              ","","Disable            ","                   ","Laden              ","","Smeiszwang <I/0>   ","Wert: <wert>       ","Laden              ","","Zeit               ","Farbverhalten      ","New                "};
00117 const char * const  text_ln2[] = {"Anzeige            ","Spielregeln        ","Hellichkeit/Sp.Led ","Config.            ","","kleinstmoglich     ","SP: 1   2   3   4  ","Speichern          ","","Go Home first <I/0>","Sp.Led-Verhalten   ","Speichern          ","","Agro/Taktik        ","Farb def           ","Reset              "};
00118 const char * const  text_ln3[] = {"Speicher           ","Autoplay           ","Wurfel             ","Ofline/Com         ","","grostmoglich       ","                   ","Reset              ","","Ausfahrzwang <I/0> ","Andert: <wert>     ","Reset              ","","Enable/Manuell     ","Hellichkeit        ","Com                "};
00119 char textPos[]                 = {0x0                  ,0x1                  ,0x2                  ,0x3                  ,0x4,0x5                 ,0x6                  ,0x7                  ,0x8,0x9                 ,0xA                  ,0xB                  ,0xC,0xD                 ,0xE                  ,0xF                  ,0x10,0x11};
00120 
00121 char VHS = 0;
00122 char mSelected[256];
00123 char depth = 0;
00124 uint32_t postion = 0;//Dafür brauche ich die Methode
00125 char mDiceEn = 5;
00126 
00127 
00128 void btn0()
00129 {
00130     if((btnLast&0x10)==(btn&0x10))
00131         return;
00132     else  
00133     {
00134         if((btn&0x10)>0)
00135             reset();
00136         else
00137             /*DoNothing*/;
00138     }
00139     btnLast=(btnLast&(0x1F-0x10))|(btn&0x10);
00140 }
00141 
00142 void btn1()
00143 {
00144     if((btnLast&0x01)==(btn&0x01))
00145         return;
00146     else  
00147     {
00148         if((btn&0x01)>0)
00149             DiceStart();
00150         else
00151             DiceStop();
00152     }
00153     btnLast=(btnLast&(0x1F-0x01))|(btn&0x01);
00154 }
00155 
00156 void btn2()
00157 {
00158     if((btnLast&0x02)==(btn&0x02))
00159         return;
00160     else  
00161     {
00162         if((btn&0x02)>0)
00163             moveNext();
00164         else
00165             /*DoNothing*/;
00166     }
00167     btnLast=(btnLast&(0x1F-0x02))|(btn&0x02);
00168 }
00169 
00170 void btn3()
00171 {
00172     if((btnLast&0x04)==(btn&0x04))
00173         return;
00174     else  
00175     {
00176         if((btn&0x04)>0)
00177             moveLast();
00178         else
00179             /*DoNothing*/;
00180     }
00181     btnLast=(btnLast&(0x1F-0x04))|(btn&0x04);
00182 }
00183 
00184 void btn4()
00185 {
00186     if((btnLast&0x08)==(btn&0x08))
00187         return;
00188     else  
00189     {
00190         if((btn&0x08)>0)
00191             MoveDo();
00192         else
00193             /*DoNothing*/;
00194     }
00195     btnLast=(btnLast&(0x1F-0x08))|(btn&0x08);
00196 }
00197 
00198 void reset()
00199 {
00200     MoveAnim.detach();
00201     DiceAnim.detach();
00202     for(char i = 0;i<Spieler*Steine;i++)
00203         PlayPos[i]=i%4;
00204     for (char i = 0; i < Spieler; i++)
00205         last[i]=0; 
00206     Drann=0;
00207     diceEn=0; 
00208     myled = myled&0xF0F;
00209     DicePrint();
00210     rgb.set_RGB(0);
00211     FieldGenerate();
00212     FieldPrint();
00213     FeldPrint();
00214 }
00215 
00216 void Control()
00217 {
00218     while(port.readable ())
00219     {
00220         char message = port.getc();
00221         switch(message)
00222         {
00223             case '1':
00224             setDice(1);
00225             break;
00226             case '2':
00227             setDice(2);
00228             break;
00229             case '3':
00230             setDice(3);
00231             break;
00232             case '4':
00233             setDice(4);
00234             break;
00235             case '5':
00236             setDice(5);
00237             break;
00238             case '6':
00239             setDice(6);
00240             break;
00241             case '7':
00242             setDice(7);
00243             break;
00244             case 'A':
00245             DiceStart();
00246             break;
00247             case 'a':
00248             DiceStop();
00249             break;
00250             case 'B':
00251             moveNext();
00252             break;
00253             case 'C':
00254             moveLast();
00255             break;
00256             case 'D':
00257             MoveDo();
00258             break;
00259             case 'E':
00260                 exit();
00261             break;
00262             case 'F':
00263                 up();
00264             break;
00265             case 'G':
00266                 down();
00267             break;
00268             case 'H':
00269                 accept();
00270             break;
00271             case 'I':
00272                 depth=0;
00273                 mSelected[0]=0;
00274                 print_default();
00275                 mDiceEn=5;
00276                 reset();
00277             break;
00278         }
00279     }
00280 }
00281 
00282 int main() 
00283 {
00284     Random.start();
00285     //Random.stop();
00286     //Random.read_us();
00287     
00288     //Ticker:
00289     //.attach(&main,[sek]);
00290     //.attach_us(&main,[micro-sec]);
00291     //.detach();
00292     Button0.mode(PullDown);
00293     Button1.mode(PullDown);
00294     Button2.mode(PullDown);
00295     Button3.mode(PullDown);
00296     Button4.mode(PullDown);
00297     
00298     DD_A.mode(PullDown);
00299     DD_B.mode(PullDown);
00300     DD_C.mode(PullDown);
00301     
00302     wait(0.01);
00303     
00304     DD_A.rise(&dreh);
00305     DD_A.fall(&dreh);
00306     DD_B.rise(&dreh);
00307     DD_B.fall(&dreh);
00308     DD_C.rise(&druck);
00309     DD_C.fall(&druck);
00310     DD_last = DD;
00311     DD_d=DD_D;
00312 
00313     Button0.rise(&reset);
00314     Button1.rise(&btn1);
00315     Button1.fall(&btn1);
00316     Button2.rise(&btn2);
00317     Button2.fall(&btn2);
00318     Button3.rise(&btn3);
00319     Button3.fall(&btn3);
00320     Button4.rise(&btn4);
00321     Button4.fall(&btn4);
00322 
00323     //myled = 0xFFF;
00324     port.baud(76800);
00325     port.format(8,Serial::None, 1); 
00326     port.attach(&Control);
00327     /*
00328     Farben[0]=0x00FF00;//Rot
00329     Farben[1]=0xFF0000;//Blau
00330     Farben[2]=0x0000FF;//Grun
00331     Farben[3]=0x00FFFF;//Gelb
00332     Background = 0;    //Schwarz
00333     DiseC = 0x00FF00;  //Rot
00334     */
00335     Farben[0]=0x000800;//Rot
00336     Farben[1]=0x080000;//Blau
00337     Farben[2]=0x000008;//Grun
00338     Farben[3]=0x000808;//Gelb
00339     Background = 0;    //Schwarz
00340     DiseC = 0x000800;  //Rot
00341     /*
00342     Farben[0]=0xFFFFFF;//Weiß
00343     Farben[1]=0xFFFFFF;//Weiß
00344     Farben[2]=0xFFFFFF;//Weiß
00345     Farben[3]=0xFFFFFF;//Weiß
00346     Background = 0xFFFFFF;//Weiß
00347     DiseC = 0xFFFFFF;  //Weiß
00348     */
00349 
00350     __disable_irq();
00351     for(char i = 0;i<Spieler;i++)
00352     {
00353         Feld.WriteLed(Farben[i]);
00354         for(char j = 0;j<Feldgrose-1;j++)
00355             if((j==(Feldgrose-2))&(i==(Spieler-1)))
00356                 Feld.WriteLed(0xFFFFFF);
00357             else
00358                 Feld.WriteLed(Background);
00359     }
00360     __enable_irq();
00361     //reset();
00362     print_default();
00363     while(1) ;        
00364 }
00365 
00366 void DiceStart()
00367 {
00368     if(diceEn==0)
00369     {
00370     RandomDice.start();
00371     DiceAnim.attach(&DiceRun,0.1);
00372     diceEn = 1;
00373     diceTick = 1;
00374     DicePrint();
00375     }
00376 }
00377 
00378 void DiceStop()
00379 {
00380     if(diceEn==1)
00381     {
00382         if(RandomDice.read_us()> 200)
00383         {
00384             DiceAnim.detach();
00385             diceEn = 2;
00386             diceTick = 0;
00387             diceNum = Random.read_us()%7;
00388             diceNum = (RandomDice.read_us()+diceNum)%7+1;
00389             RandomDice.stop();
00390             RandomDice.reset();
00391             if(diceNum>=7)
00392                 DiceCal();
00393             //port.printf("LDiceNum:%d\n",diceNum);
00394             DicePrint();
00395             GameCal();
00396         }
00397     }
00398 }
00399 
00400 void DiceCal()
00401 {
00402     if((diceEn==2)||(diceEn==3))
00403     {
00404         if(diceNum>7)
00405             diceNum=7;
00406         if(diceNum==7)
00407         {
00408             diceEn=3;
00409             for(char i = 0;i<Steine;i++)
00410                 if((PlayPos[(Drann<<2)|i]>3)&&(PlayPos[(Drann<<2)|i] < 44))
00411                     for(char j = 1;j<=6;j++)
00412                     {
00413                         char temp = Field[(PlayPos[(Drann<<2)|i]- Steine + Feldgrose * Drann+j) % (Feldgrose*Steine)];
00414                         if(temp>0)
00415                         {
00416                             temp--; //(Spieler<<2)|Stein
00417                             temp = (temp&0xC)>>2;//Spieler
00418                             if(temp!=Drann)
00419                                 if(j<diceNum)
00420                                     diceNum=j;
00421                         }
00422                     }
00423             //PlayPos[(Drann<<2)|i] im Feld suchen, weiter setzen, wenn treffer, der kleiner als diceNum ->setzen von diceNum
00424         }//DiceNum == 7
00425         if(diceNum==7)
00426             diceNum=6;
00427         //port.printf("LdiceNum:%d\n",diceNum);
00428     }
00429 }
00430 
00431 void setDice(char number)
00432 {
00433     if(diceEn==4)
00434     {
00435         port.printf("LWarning: diceEn:%d -> Game over\n",diceEn);
00436     }
00437     else if(diceEn<4)
00438     {
00439         port.printf("LdiceEn:%d\n",diceEn);
00440         if(diceEn==1)
00441         {
00442             DiceAnim.detach();
00443             diceTick = 0;
00444             RandomDice.stop();
00445             RandomDice.reset();
00446         }
00447         diceEn = 2;
00448         diceNum = number;
00449         if(diceNum>=7)
00450             DiceCal();
00451         //port.printf("LForceDice:%d\n",diceNum);
00452         DicePrint();
00453         GameCal();
00454     }
00455 }
00456 
00457 void DiceRun()
00458 {
00459     if(diceTick)
00460     {
00461         diceTick=0;
00462         if(dicePos<7)
00463             dicePos++;
00464         else
00465             dicePos=0;
00466         }
00467     else
00468         diceTick=1;
00469     DicePrint();
00470 }
00471 
00472 void DicePrint()
00473 {
00474     switch(diceEn)
00475     {
00476         case 0: //Schwarz & Drann überschreiben...
00477         myled=(myled&0xFF0);
00478         myled=(myled&0x0FF)|(0x100<<Drann);
00479         port.printf("W%c%c\n",27,27);
00480         break;
00481         case 1: //Animation
00482         char dice_help = 0xFF-(1<<dicePos);
00483         myled=(myled&0xFF0)|(5)|(diceTick<<1);
00484         //myled = (myled&0xF)|(dice_help<<4);
00485         
00486         port.printf("W%c%c\n" , 27 + diceTick+((dice_help&0x1F)<<1),27 + ((dice_help& 0xE0)>>5));
00487         break;
00488         case 2://Case 3 = Case 2 ->Anzeigen
00489         myled=(myled&0xFF0)|(diceNum);
00490         //myled=myled|0xFF0;
00491         
00492         port.printf("W%c%c\n" , 27 +(diceDecode[diceNum-1]&0x3F),27 + ((diceDecode[diceNum-1]&0x1C0)>>6));
00493         break;
00494         case 3:
00495         myled=(myled&0xFF0)|(diceNum)|8;
00496         //myled=myled|0xFF0;
00497         
00498         port.printf("W%c%c\n" , 27 +(diceDecode[diceNum-1]&0x3F),27 + ((diceDecode[diceNum-1]&0x1C0)>>6));
00499         break;
00500         case 4://Spiel beendet! Animation?
00501         myled=(myled&0xFF0);
00502         port.printf("W%c%c\n",27,27);
00503         break;
00504         case 5://Menu
00505         break;
00506     }
00507 }
00508 
00509 void FieldGenerate()
00510 {
00511     for(char i = 0; i<Spieler*Feldgrose;i++)
00512         Field[i]=0; //Feld zurücksetzen
00513     for (char i = 0; i < Spieler*Steine; i++)
00514     {
00515         Ziel[i]=0;
00516         Start[i]=0;
00517     }
00518         
00519     for(char i = 0; i<Spieler;i++)
00520         for(char j = 0; j<Steine;j++)
00521         {
00522             if (PlayPos[(i<<2)|j] >= Steine)
00523             {
00524                 if (PlayPos[(i<<2)|j] >= (Spieler * Feldgrose + Steine))
00525                 {
00526                     //if (PlayPos[(i<<2)|j] < Steine * Feldgrose+Steine*2)
00527                         Ziel[(PlayPos[(i<<2)|j] - (Spieler * Feldgrose + Steine))|(i<<2)] = ((i<<2)|j) + 1;
00528                         //Ziel PlayPos[(i<<2)|j] - 44
00529                 }
00530                 else
00531                     Field[(PlayPos[(i<<2)|j]- Steine + Feldgrose * i) % (Steine * Feldgrose)] = ((i<<2)|j) + 1;
00532                     //Feld (PlayPos[(i<<2)|j]- 4 + 10 * i) % 40
00533             }
00534             else
00535                 Start[PlayPos[(i<<2)|j]|(i<<2)] = ((i<<2)|j)+1;
00536                 //start PlayPos[(i<<2)|j]
00537         }
00538 }
00539 
00540 void FieldPrint()
00541 {
00542     port.printf("F");
00543     for(char i = 0;i<Spieler*Steine;i++)
00544     {
00545         port.printf("%c",27+PlayPos[i]);
00546     }
00547     port.printf("\n");
00548 }
00549 
00550 void FeldPrint()
00551 {
00552     __disable_irq();
00553     for(char i = 0;i<Spieler*Feldgrose;i++)
00554         if(Field[i]>0)
00555             Feld.WriteLed(Farben[((Field[i]- 1)&0x0C)>>2]);
00556         else
00557             Feld.WriteLed(Background);
00558     //char Start[Spieler];
00559     //char Ziel[Spieler];
00560     char i = 0;
00561     char j = 0;
00562     while(i < Steine*Spieler)
00563     {
00564         if(Start[i]>0)
00565             Home.WriteLed(Farben[((Start[i]- 1)&0x0C)>>2]);
00566         else
00567             Home.WriteLed(Background);
00568         i++;
00569     }
00570     do
00571     {
00572         if(Ziel[j]>0)
00573             Home.WriteLed(Farben[((Ziel[j]- 1)&0x0C)>>2]);
00574         else
00575             Home.WriteLed(Background);
00576         j++;
00577     }while(j < Steine*Spieler);
00578     __enable_irq();
00579 }
00580 
00581 void AnimCal()
00582 {
00583     for(char i = 0; i<Spieler*Feldgrose;i++)
00584         AnimField[i]=0; //Feld zurücksetzen
00585     for (char i = 0; i < Spieler*Steine; i++)
00586     {
00587         AnimZiel[i]=0;
00588         AnimStart[i]=0;
00589     }
00590     AnimDo=0;//Feld_Animieren,Start Animieren, Ziel Animieren
00591 
00592     //char AnimDo; //Feld_Animieren,Start Animieren, Ziel Animierenw
00593 
00594     for (char i = 0; i < Spieler*Steine; i++) //Hauptschleife
00595         if(i==((Drann<<2)|selected))
00596         {
00597             if(moglich[selected]==1)
00598             {
00599                 if(PlayPos[i]<Steine) //nicht Draußsen
00600                 {
00601                     AnimDo = AnimDo|3;//Feld&Start
00602                     AnimPos[i] = Steine; //Ausfahren
00603                     char temp = Field[Drann*Feldgrose]; //Ansetzfeld wird analysiert
00604                     if(temp>0)
00605                     {
00606                         //myled = myled|temp<<8;
00607                         temp--; //(Spieler<<2)|Stein
00608                         AnimPos[temp] = (temp & 0x03); //rücksetzung des Feldes...
00609                     }
00610                 }
00611                 else //Draußen
00612                 {
00613                     AnimDo = AnimDo|1; //Feld
00614                     AnimPos[i] = PlayPos[i]+diceNum;; //Weitersetzen
00615                     //PlayPos[(Drann<<2)|selected]
00616                     if(AnimPos[i]<Steine+Spieler*Feldgrose) //noch nicht drinnen
00617                     {
00618                         //Field>0
00619                         char temp = Field[ (AnimPos[i]-Steine+Feldgrose*Drann) % (Feldgrose*Steine) ];
00620                         if(temp>0)
00621                         {
00622                             AnimDo = AnimDo|3;//Feld&Start
00623                             //myled = myled|temp<<8;
00624                             temp--; //(Spieler<<2)|Stein
00625                             AnimPos[temp] = (temp & 0x03); //rücksetzung des Feldes...
00626                         }
00627                     }
00628                     else
00629                         AnimDo=AnimDo|7;//Feld&Ziel (Start auch wegen Hardware)
00630                 }
00631             }
00632             else
00633                 AnimPos[i] = PlayPos[i]; //Spieler-pos Kopieren, weil es nicht möglich ist...
00634         }
00635         else
00636             AnimPos[i] = PlayPos[i]; //Spieler-pos Kopieren
00637     //FieldGenerate -> Anim...
00638     for(char i = 0; i<Spieler;i++)
00639         for(char j = 0; j<Steine;j++)
00640         {
00641             if (AnimPos[(i<<2)|j] >= Steine)
00642             {
00643                 if (AnimPos[(i<<2)|j] >= (Spieler * Feldgrose + Steine))
00644                 {
00645                     //if (AnimPos[(i<<2)|j] < Steine * Feldgrose+Steine*2)
00646                         AnimZiel[(AnimPos[(i<<2)|j] - (Spieler * Feldgrose + Steine))|(i<<2)] = ((i<<2)|j) + 1;
00647                         //AnimZiel AnimPos[(i<<2)|j] - 44
00648                 }
00649                 else
00650                     AnimField[(AnimPos[(i<<2)|j]- Steine + Feldgrose * i) % (Steine * Feldgrose)] = ((i<<2)|j) + 1;
00651                     //Feld (AnimPos[(i<<2)|j]- 4 + 10 * i) % 40
00652             }
00653             else
00654                 AnimStart[AnimPos[(i<<2)|j]|(i<<2)] = ((i<<2)|j)+1;
00655                 //start AnimPos[(i<<2)|j]
00656         }
00657 }
00658 
00659 void MoveRun() //Animation (zyklisch)
00660 {
00661     if(MoveShow)
00662         MoveShow = 0;
00663     else
00664         MoveShow = 1;
00665 
00666     if(MoveShow>0)
00667     {
00668         port.printf("F");
00669         for(char i = 0;i<Spieler*Steine;i++)
00670         {
00671             port.printf("%c",27+AnimPos[i]);
00672         }
00673         port.printf("\n");
00674         
00675         __disable_irq();
00676         if((AnimDo&1)>0)
00677         {
00678             for(char i = 0;i<Spieler*Feldgrose;i++)
00679                 if(AnimField[i]>0)
00680                     Feld.WriteLed(Farben[((AnimField[i]- 1)&0x0C)>>2]);
00681                 else
00682                     Feld.WriteLed(Background);
00683         }
00684         //char Start[Spieler];
00685         //char Ziel[Spieler];
00686         char i = 0;
00687         char j = 0;
00688         if((AnimDo&2)>0)
00689         {
00690             while(i < Steine*Spieler)
00691             {
00692                 if(AnimStart[i]>0)
00693                     Home.WriteLed(Farben[((AnimStart[i]- 1)&0x0C)>>2]);
00694                 else
00695                     Home.WriteLed(Background);
00696                 i++;
00697             }
00698         }
00699         if((AnimDo&4)>0)
00700         {
00701             do
00702             {
00703                 if(AnimZiel[j]>0)
00704                     Home.WriteLed(Farben[((AnimZiel[j]- 1)&0x0C)>>2]);
00705                 else
00706                     Home.WriteLed(Background);
00707                 j++;
00708             }while(j < Steine*Spieler);
00709         }
00710         __enable_irq();
00711     }
00712     else
00713     {
00714         FieldPrint();
00715         __disable_irq();
00716         if((AnimDo&1)>0)
00717         {
00718             for(char i = 0;i<Spieler*Feldgrose;i++)
00719                 if(Field[i]>0)
00720                     Feld.WriteLed(Farben[((Field[i]- 1)&0x0C)>>2]);
00721                 else
00722                     Feld.WriteLed(Background);
00723         }
00724         //char Start[Spieler];
00725         //char Ziel[Spieler];
00726         char i = 0;
00727         char j = 0;
00728         if((AnimDo&2)>0)
00729         {
00730             while(i < Steine*Spieler)
00731             {
00732                 if(Start[i]>0)
00733                     Home.WriteLed(Farben[((Start[i]- 1)&0x0C)>>2]);
00734                 else
00735                     Home.WriteLed(Background);
00736                 i++;
00737             }
00738         }
00739         if((AnimDo&4)>0)
00740         {
00741             do
00742             {
00743                 if(Ziel[j]>0)
00744                     Home.WriteLed(Farben[((Ziel[j]- 1)&0x0C)>>2]);
00745                 else
00746                     Home.WriteLed(Background);
00747                 j++;
00748             }while(j < Steine*Spieler);
00749         }
00750         __enable_irq();
00751     }
00752 }
00753 
00754 void moveNext()
00755 {
00756     selected = (selected+1)%Steine;
00757     for(char i = 0;i<Steine;i++)
00758         if(moglich[selected]>0)
00759             break;
00760         else
00761             selected = (selected+1)%Steine;
00762     AnimCal();
00763 }
00764 
00765 void moveLast()
00766 {
00767     selected = (selected+3)%Steine;
00768     for(char i = 0;i<Steine;i++)
00769         if(moglich[selected]>0)
00770             break;
00771         else
00772             selected = (selected+3)%Steine;
00773     AnimCal();
00774 }
00775 
00776 void GameCal()
00777 {
00778     char drausen = 0; //Ziel
00779     char feld = 0;
00780     char drinnen = 0; //start
00781     char moglichAny = 1;
00782     for(char i = 0;i<Steine;i++)
00783     {
00784         if(PlayPos[(Drann<<2)|i]>=Steine)
00785         {
00786             if(PlayPos[(Drann<<2)|i] >= (Steine+Spieler*Feldgrose))
00787                 drausen++;
00788             else
00789                 feld++;
00790         }
00791         else
00792             drinnen++;
00793         moglich[i]=0;
00794     }
00795     //Berechnung
00796     //Ausfahren:
00797     //drinnen >0 (Noch Spieler drinnen?)
00798     //Startfeld ist von Spieler belegt
00799     //Ziel ist frei
00800     if((drinnen>0)&&(moglichAny))
00801     {
00802         //port.printf("LDrinnen\n");
00803         if(((((Field[Feldgrose*Drann]-1) &0x0C) >>2)==Drann)&&(Field[Feldgrose*Drann]>0))
00804         {
00805             //port.printf("LAusfahrt Belegt\n");
00806             if(((((Field[(Feldgrose*Drann+diceNum)%(Feldgrose*Spieler)]-1) &0x0C) >>2)!=Drann)||(Field[(Feldgrose*Drann+diceNum)%(Feldgrose*Spieler)]==0))
00807             {
00808                 //port.printf("LZiel frei (Done)\n");
00809                 moglich[(Field[Feldgrose*Drann]-1) &0x03] = 1;
00810                 moglichAny=0;
00811             }
00812         }
00813     }
00814     
00815     //Ansetzen
00816     // 6 gewürfelt
00817     //drinnen>0
00818     //Start-feld ist nicht von Spieler belegt
00819     if((drinnen>0)&&(moglichAny)&&(diceNum==6))
00820     {
00821         //port.printf("LDrinnen & 6 \n");
00822         if(((((Field[Feldgrose*Drann]-1) &0x0C) >>2)!=Drann)||(Field[Feldgrose*Drann]==0))
00823         {
00824             //port.printf("LAusfahrt frei (Done...Schleife)\n");
00825             moglichAny=0;
00826             for(char i = 0;i<Steine;i++)
00827                 if(PlayPos[(Drann<<2)|i]<Steine)
00828                     moglich[i]=1;
00829         }
00830     }
00831     
00832     //Fahren
00833     if(moglichAny)
00834     {
00835         //port.printf("LNormal...\n");
00836         for(char i = 0;i<Steine;i++)
00837         {
00838             if(PlayPos[(Drann<<2)|i]>=Spieler) //Drausen
00839             {
00840                 if((PlayPos[(Drann<<2)|i]+diceNum) < (Steine+Feldgrose*Spieler))//Zeil noch am Feld
00841                 {
00842                     char temp = Field[(PlayPos[(Drann<<2)|i]- Steine + Feldgrose * Drann+diceNum) % (Feldgrose*Steine)]; //zielfeld
00843                     if(temp>0)
00844                     {
00845                         //myled = myled|temp<<8;
00846                         temp--; //(Spieler<<2)|Stein
00847                         temp = (temp&0xC)>>2;//Spieler
00848                         if(temp!=Drann)     //zielfeld ist nicht ich
00849                             moglich[i]=1;
00850                     }
00851                     else//Feld ist leer
00852                         moglich[i]=1;
00853                 }
00854                 else
00855                 {//Kollisionsberechnung ins Ziel...
00856                     if((PlayPos[(Drann<<2)|i]+diceNum)<(Steine*2+ Feldgrose*Spieler))//Schiest nicht über das Ziel hinaus...
00857                         if(Ziel[(PlayPos[(Drann<<2)|i]-(Steine+Feldgrose*Spieler)+diceNum)|(Drann<<2)]==0)//Zielfeld ist leer (enthält ja nur mich)
00858                             moglich[i]=1;
00859                 }
00860             }
00861         }
00862     }
00863         
00864 
00865     //Anzeigen der Möglichkeiten & überhaupt möglich?
00866     moglichAny=0;
00867     myled = myled&0xF0F;
00868     for(char i = 0;i<Steine;i++)
00869     {
00870         myled = myled|(moglich[i]<<i+4);
00871         moglichAny = moglichAny | moglich[i];
00872     }
00873 
00874     if(moglichAny) //Fahren möglich
00875     {
00876         selected = (last[Drann]+Steine-1)%Steine;
00877         moveNext();
00878         MoveAnim.attach(&MoveRun,0.3);
00879     }
00880     else //Fahren nicht möglich
00881     {
00882         if(feld<=0) //keine am Feld
00883         {
00884             if(count<2)
00885             {
00886                 diceEn=0;
00887                 count++;
00888                 port.printf("LCount: %d\n",count);
00889             }
00890         }
00891         else //Fahren nicht möglich,spieler am Feld & 6 gewürfelt
00892         {
00893             if(diceNum==6)
00894                 diceEn=0;
00895         }
00896     }
00897 }
00898 
00899 void MoveDo()
00900 {
00901     if((diceEn>1)&&(diceEn<4))
00902     {
00903         if(moglich[selected]==1)
00904         {
00905             if(PlayPos[(Drann<<2)|selected]<Steine) //nicht Draußsen
00906             {
00907                 PlayPos[(Drann<<2)|selected] = Steine; //Ausfahren
00908                 char temp = Field[Drann*Feldgrose]; //Ansetzfeld wird analysiert
00909                 if(temp>0)
00910                 {
00911                     //myled = myled|temp<<8;
00912                     temp--; //(Spieler<<2)|Stein
00913                     PlayPos[temp] = (temp & 0x03); //rücksetzung des Feldes...
00914                 }
00915             }
00916             else //Draußen
00917             {
00918                 PlayPos[(Drann<<2)|selected] += diceNum; //Weitersetzen
00919                 //PlayPos[(Drann<<2)|selected]
00920                 if(PlayPos[(Drann<<2)|selected]<Steine+Spieler*Feldgrose) //noch nicht drinnen
00921                 {
00922                     //Field>0
00923                     char temp = Field[ ( PlayPos[(Drann<<2)|selected] - Steine + (Feldgrose * Drann) ) % (Feldgrose*Steine) ];
00924                     if(temp>0)
00925                     {
00926                         //myled = myled|temp<<8;
00927                         temp--; //(Spieler<<2)|Stein
00928                         PlayPos[temp] = (temp & 0x03); //rücksetzung des Feldes...
00929                     }
00930                 }
00931             }
00932             //else //nicht möglich
00933             
00934         }
00935         MoveAnim.detach();
00936         last[Drann]=selected;
00937         myled = myled&0xF0F;
00938         count = 0;
00939         FieldGenerate();
00940         //Check for Win!
00941         char temp = 0;
00942         char j = 0;
00943         char running = 1;
00944         do
00945         {
00946             temp = 0;
00947             for (char i = 0; i < Steine; i++)
00948                 if (Ziel[(Drann<<2)|i]>0)
00949                     temp++;
00950             if((temp>=4)&&(diceEn>1))
00951                 port.printf("LSpieler %d hat das Spiel beendet!\n",Drann);
00952             if(temp==4)
00953                 Drann = (Drann+1)%Spieler;
00954             else
00955             {
00956                 if(j==0)
00957                 {
00958                     if(diceNum<6)
00959                         Drann = (Drann+1)%Spieler;
00960                     else
00961                         running = 0;
00962                 }
00963                 else
00964                     running = 0;
00965                 
00966             }
00967             diceEn = 0;
00968             j++;
00969         }while((j<=Spieler)&(running>0));
00970         if(running==1)
00971         {
00972             port.printf("LSpiel beendet!\n");
00973             diceEn = 4;
00974         }
00975         DicePrint();
00976         FieldPrint();
00977         FeldPrint();
00978         port.printf("LDrann:%d\n",Drann);
00979     }
00980 }
00981 
00982 void ColorPrint(uint32_t color)
00983 {
00984     port.printf("%c%c%c%c\n",27+((color&0xFC0000)>>18),27+((color&0x03f000)>>12),27+((color&0x000FC0)>>6),27+(color&0x00003F));
00985 }
00986 
00987 //http://www.repairfaq.org/REPAIR/F_SNES.html
00988 
00989 void dreh()
00990 {
00991     char temp = DD;
00992     if(DD_last == 3)
00993     { 
00994         if(temp == 0)
00995             DD_last = 0;
00996     }
00997     else
00998     {
00999         if(temp == 3)
01000         {
01001             if(DD_last == 1)
01002                 up();
01003             if(DD_last == 2)
01004                 down();
01005         }
01006         DD_last = temp;
01007     }
01008 }
01009 
01010 void druck()
01011 {
01012     if(DD_D==DD_d)
01013         return;
01014     else  if(DD_D)
01015         accept();
01016     DD_d=DD_D;
01017 }
01018 
01019 char ausfuehren(uint32_t postion)
01020 {
01021     char out = 1;//0 ende der postion
01022     VHS = 0;
01023     switch (postion)
01024     {
01025         case 0x15:
01026             out = 0;
01027             //zustand 7 aendern
01028             break;
01029         case 0x25:
01030             out = 0;
01031             //zustand kleinstmöglicher zustand
01032             break;
01033         case 0x35:
01034             out = 0;
01035             //zustand groestmoeglich
01036             break;
01037         case 0x19:
01038             out = 0;
01039             //schmeisszwang
01040             break;
01041         case 0x29:
01042             out = 0;
01043             //go home first
01044             break;
01045         case 0x39:
01046             out = 0;
01047             //ausfahrzwang
01048             break;
01049         case 0x17:
01050             out = 0;
01051             //Spiel-Menü:laden
01052             break;
01053         case 0x27:
01054             out = 0;
01055             //Spiel-Menü:speichern
01056             break;
01057         case 0x37:
01058             out = 0;
01059             //Spiel-Menü:reset
01060             break;
01061         case 0x1b:
01062             out = 0;
01063             //Config:laden
01064             break;
01065         case 0x2b:
01066             out = 0;
01067             //Config:speichern
01068             break;
01069         case 0x3b:
01070             out = 0;
01071             //Config:reset
01072             break;
01073         case 0x1f:
01074             out = 0;
01075             //Offline:new
01076             break;
01077         case 0x2f:
01078             out = 0;
01079             //Offline:reset
01080             break;
01081         case 0x3f:
01082             out = 0;
01083             //Offline:com
01084             break;
01085         case 0x6:
01086             VHS = 1;
01087             break;
01088         
01089     default:
01090         break;
01091     }
01092     return out;
01093 }
01094 
01095 void posUpdate()
01096 {
01097     postion = 0;
01098     for(char i = 0;i<depth-1;i++)
01099         postion = postion|(mSelected[i]<<(i*2));
01100 }
01101 
01102 void up()
01103 {
01104     if(depth>0)
01105     {
01106         if(mSelected[depth-1]<1)
01107         {
01108             if(VHS==0)
01109                 mSelected[depth-1]=3;
01110             else if(VHS==1)
01111                 mSelected[depth-1]=4;
01112             else
01113                 mSelected[depth-1]=VHS;
01114         }
01115         else
01116             mSelected[depth-1]--;
01117         print_pos();
01118     }
01119 }
01120 
01121 void down()
01122 {
01123     if(depth>0)
01124     {
01125         char temp=3;
01126         if(VHS==0)
01127             temp=3;
01128         else if(VHS==1)
01129             temp=4;
01130         else
01131             temp=VHS;
01132         if(mSelected[depth-1]>(temp-1))
01133             mSelected[depth-1]=0;
01134         else
01135             mSelected[depth-1]++;
01136         print_pos();
01137     }
01138 }
01139 
01140 void accept()
01141 {
01142     if(depth>0)
01143     {
01144         postion = 0;
01145         for(char i = 0;i<depth;i++)
01146             postion = postion|(mSelected[i]<<(i*2));
01147         char temp = ausfuehren(postion);
01148         if(temp>0)
01149         {
01150             if(mSelected[depth-1]==0)
01151             {
01152                 exit();
01153                 return;
01154             }
01155             else
01156             {
01157                 mSelected[depth]=1;
01158                 depth++;
01159             }
01160         }
01161     }
01162     else
01163     {
01164         depth=1;
01165         mDiceEn = diceEn;
01166         if(mDiceEn==1)
01167         {
01168             DiceAnim.detach();
01169             diceTick = 0;
01170             RandomDice.stop();
01171             mDiceEn=0;
01172         }
01173         if((mDiceEn==2)||(mDiceEn==3))
01174         {
01175             MoveAnim.detach();
01176             MoveShow = 1;
01177             MoveRun();
01178         }
01179         diceEn=5;
01180         DicePrint();
01181         //StartMenu-Anim
01182     }
01183     posUpdate();
01184     port.printf("Lpostion:0x%x\n",postion);
01185     if(depth>0)
01186     {
01187         print_menu();
01188         print_pos();
01189     }
01190     else
01191         print_default();
01192 }
01193 
01194 void exit()
01195 {
01196     if(depth>0)
01197     {
01198         depth--;
01199         mSelected[depth]=0;
01200     }
01201     if(depth==0)
01202     {
01203         if(mDiceEn<5)
01204         {
01205             diceEn=mDiceEn;
01206             if((mDiceEn==2)||(mDiceEn==3))
01207                 MoveAnim.attach(&MoveRun,0.3);
01208             mDiceEn=5;
01209         }
01210     }
01211     posUpdate();
01212     ausfuehren(postion);
01213     if(depth>0)
01214     {
01215         print_menu();
01216         print_pos();
01217     }
01218     else
01219         print_default();
01220 }
01221 
01222 void print_menu()
01223 {
01224     port.printf("DR\n");
01225     lcd.cls();
01226     lcd.locate(1,0);
01227     lcd.printf(text_ln0[textPos[postion]]);
01228     port.printf("D%c%c%s\n",28,27,text_ln0[textPos[postion]]);
01229     lcd.locate(1,1);
01230     lcd.printf(text_ln1[textPos[postion]]);
01231     port.printf("D%c%c%s\n",28,28,text_ln1[textPos[postion]]);
01232     lcd.locate(1,2);
01233     lcd.printf(text_ln2[textPos[postion]]);
01234     port.printf("D%c%c%s\n",28,29,text_ln2[textPos[postion]]);
01235     lcd.locate(1,3);
01236     lcd.printf(text_ln3[textPos[postion]]);
01237     port.printf("D%c%c%s\n",28,30,text_ln3[textPos[postion]]);
01238 }
01239 
01240 void print_pos()
01241 {
01242     if (VHS==1)
01243     {
01244         lcd.locate(0,3);
01245         //         "--------------------"
01246         lcd.printf("                    ");
01247         port.printf("D%c%c                    \n",27,27+3);
01248 
01249         lcd.locate(0,0);
01250         if(mSelected[depth-1]==0)
01251         {
01252             port.printf("D%c%c<\n",27,27);
01253             lcd.putc('<');
01254         }
01255         else
01256         {
01257             port.printf("D%c%c \n",27,27);
01258             lcd.putc(' ');
01259 
01260             lcd.locate(4*mSelected[depth-1],3);
01261             lcd.putc('^');
01262             port.printf("D%c%c^\n",27+4*mSelected[depth-1],27+3);
01263         }
01264     }
01265     else
01266     {
01267         for(char i=0;i<4;i++)
01268         {
01269             lcd.locate(0,i);
01270             if((mSelected[depth-1]+0)==i)
01271             {
01272                 if(i==0)
01273                 {
01274                     port.printf("D%c%c<\n",27,i+27);
01275                     lcd.putc('<');
01276                 }
01277                 else
01278                 {
01279                     port.printf("D%c%c>\n",27,i+27);
01280                     lcd.putc('>');
01281                 }
01282             }
01283             else
01284             {
01285                 port.printf("D%c%c \n",27,i+27);
01286                 lcd.putc(' ');
01287             }
01288         }
01289     }
01290 }
01291 
01292 void print_default()
01293 {
01294     lcd.cls();
01295         lcd.printf(" Spiel lauft...");
01296         lcd.locate(0,3);
01297         lcd.printf("12345678901234567890");
01298         port.printf("D%c%c Spiel lauft...     \n",27,27);
01299         port.printf("D%c%c                    \n",27,28);
01300         port.printf("D%c%c                    \n",27,29);
01301         port.printf("D%c%c12345678901234567890\n",27,30);
01302 }