home *** CD-ROM | disk | FTP | other *** search
/ PSION CD 2 / PsionCDVol2.iso / Programs / 266 / PYRAMID.SIS / PYRAMID.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1998-08-27  |  29.2 KB  |  997 lines

  1. // Here are the 'public domain' sources
  2. // of Pyramid v1.1
  3. // To get a correct indentation of these sources
  4. // use a Tab char of size 4 !
  5. // The .mmp project is made for the sources to be in
  6. // a \epoc32ex\pyramid directory but you can change that
  7.  
  8. // PYRAMID.CPP
  9. //
  10. // Written rapidly by Frederic Bouvry in 1997
  11. // Email: fb@mailandnews.com
  12.  
  13. // Note: to compile the cards.mbm file, use 'bmconv cards.txt'
  14. // in the cards\bmp subdir and then copy cards.mbm to the Pyramid app dir.
  15. // To compile the pyramid.aif, use 'bmconv pyr.txt' in the cards
  16. // directory then aiftool.
  17.  
  18. #include <e32keys.h>
  19. #include <e32base.h>
  20. #include <e32math.h>
  21. #include <e32svr.h>
  22. #include <e32math.h>
  23. #include <eikconso.h>
  24. #include <e32keys.h>
  25. #include <barsread.h>
  26. #include <coecntrl.h>
  27. #include <eikdef.h>
  28. #include <eikenv.h>
  29. #include <eikappui.h>
  30. #include <eikdialg.h>
  31. #include <eikdialg.hrh>
  32. #include <eikcapc.h>
  33. #include <eikcapca.h>
  34. #include <eikctrls.hrh>
  35. #include <eikcmds.hrh>
  36. #include <eikmfne.h>
  37. #include <eikmfne.hrh>
  38. #include <eikfpne.h>
  39. #include <eikedwin.hrh>
  40. #include <eikcmbut.h>
  41. #include <eiklabel.h>
  42. #include <eikseced.h>
  43. #include <eikrted.h>
  44. #include <txtrich.h>
  45. #include <eiktbar.h>
  46. #include <eikchred.h>
  47. #include <eikchmap.h>
  48. #include <eikrted.h>
  49. #include <eikopbut.h>
  50. #include <eikhopbt.h>
  51. #include <eikchkbx.h>
  52. #include <eikmenub.h>
  53. #include <eikmenup.h>
  54. #include <eikmenu.hrh>
  55. #include <eikfsel.h>
  56. #include <eikapp.h>
  57. #include <eikdoc.h>
  58. #include <basched.h>
  59. #include <coemain.h>
  60. #include <eikfnlab.h>
  61. #include <coeutils.h>
  62. #include <eikcfdlg.h>
  63. #include <eikdoc.h>
  64. #include <eikon.rsg>
  65. #include <eikfutil.h>
  66. #include <eikenv.h>
  67. #include <eikdef.h>
  68. #include <eikcmds.hrh>
  69. #include <eiklabel.h>
  70. #include <fontids.h>
  71. #include <s32file.h>
  72. #include "pyramid.rsg"
  73. #include "pyramid.hrh"
  74. #include "pyramid.h"
  75.  
  76. #pragma data_seg(".E32_UID")
  77. __WINS_UID(0,KAppUidValue,0x1000055D)
  78. #pragma data_seg()
  79.  
  80. //
  81. // TPyramidModel
  82. //
  83.  
  84. TPyramidModel::TPyramidModel()
  85.     {
  86.     iLibrary=_L("");
  87.     }
  88.  
  89. // Differs from what ? :-)
  90. TBool TPyramidModel::Differs(const TPyramidModel* aCompare) const
  91.     {
  92.     return((*(TInt32*)this)!=(*(TInt32*)aCompare));
  93.     }
  94.  
  95. void CPyramidControl::Random() // Init a new game and deal the cards
  96. {
  97.     TInt cards[52];
  98.     TInt i,offset, res;
  99.     for(i = 0; i<52; i++)
  100.       cards[i] = 0;
  101.     offset = 0;
  102.     Score = 0;
  103.     state = 0;
  104.     for(i = 0; i<28; i++)
  105.       {
  106.       Math::Rand(seed);
  107.       res = seed.Low() & 0x3F;
  108.       offset = (offset + res) % 52;
  109.       while(cards[offset] != 0)
  110.         offset = (offset + 1) % 52;
  111.       cards[offset] = Tapis[i] = offset+1;
  112.       }
  113.     for(i = 0; i<23; i++)
  114.       {
  115.       Math::Rand(seed);
  116.       res = seed.Low() & 0x3F;
  117.       offset = (offset + res) % 52;
  118.       while(cards[offset] != 0)
  119.         offset = (offset + 1) % 52;
  120.       cards[offset] = Stock[i] = offset+1;
  121.       }
  122.     while(cards[offset] != 0)
  123.       offset = (offset + 1) % 52;
  124.     Tallon = offset+1;
  125.     StockSize = 23;
  126.     WasteSize = 0;
  127.     for(i = 0; i < 28; i++)
  128.       {
  129.       if(i < 21)
  130.           TapisState[i] = 0;
  131.       else
  132.           TapisState[i] = 1;
  133.       }
  134.     DragCard = 0;
  135.     Redeals = 0;
  136. }
  137.  
  138. void CPyramidControl::ConstructL(RWindowTreeNode& parent, const TRect& aRect)
  139.     {
  140.     CWindowGc& gc=SystemGc(); // graphics context we draw to
  141.     int i;
  142.     TFontSpec MyFontSpec(_L("Arial"), 120);
  143.     TFontSpec MyFontSpec2(_L("Arial"), 180);
  144.     TFontStyle MyStyle(EPostureUpright,EStrokeWeightBold,EPrintPosNormal);
  145.     TTime home;
  146.     CreateBackedUpWindowL(parent, EGray4);
  147.     MyFontSpec.iFontStyle = MyStyle; // Font for 'Tallon:', ...
  148.     MyFontSpec2.iFontStyle = MyStyle; // Font for 'Score:'
  149.     iZoomFactor.SetGraphicsDeviceMap(iCoeEnv->ScreenDevice());
  150.     iZoomFactor.SetZoomFactor(TZoomFactor::EZoomOneToOne);
  151.     iDeviceMap = &iZoomFactor;
  152.     SetRectL(aRect);
  153.     iEikonEnv->InfoMsg(_L("Loading"));
  154.     TBufC<40> multiBitmapFile(_L("\\System\\Apps\\Pyramid\\cards.mbm"));
  155.     iCardsMsBmp = new (ELeave) CFbsBitmap();
  156.     LoadBitmapL(iCardsMsBmp, multiBitmapFile, 0); // Load the bitmap mask for all cards
  157.     iCardsNoBmp = new (ELeave) CFbsBitmap();
  158.     LoadBitmapL(iCardsNoBmp, multiBitmapFile, 1); // Load the empty slot bitmap
  159.     iCardsBkBmp = new (ELeave) CFbsBitmap();
  160.     LoadBitmapL(iCardsBkBmp, multiBitmapFile, 2); // Load the other side of the moon (back of the card)
  161.     for(i = 0; i< 52; i++) // Load the 52 cards
  162.       {
  163.       iCards52Bmp[i] = new (ELeave) CFbsBitmap();
  164.       LoadBitmapL(iCards52Bmp[i], multiBitmapFile, i+3);
  165.       }
  166.     for(i = 0; i< 28; i++) // create the bitmaps that will keep the background of a Tapis' card
  167.       {
  168.       iUnderTapis[i] =  new(ELeave) CFbsBitmap;
  169.       iUnderTapis[i]->Create(TSize(73,97), EGray4);
  170.       }
  171.  
  172.     home.HomeTime(); // Base the random numbers generator seed on the current time
  173.     seed = home.DateTime().Second() + home.DateTime().MicroSecond();
  174.     iDeviceMap->GetNearestFontInTwips(MyFont,MyFontSpec);
  175.     iDeviceMap->GetNearestFontInTwips(MyFont2,MyFontSpec2);
  176.     SetObserver(this); // I use an observer for this control but this is not really necessary
  177.     Random(); // Start a new game
  178.     ActivateL();
  179.     UpdateModelL();
  180.     // go for it
  181.     }
  182.  
  183. CPyramidControl::~CPyramidControl()
  184.     {
  185.     int i;
  186.     delete iCardsMsBmp;
  187.     delete iCardsBkBmp;
  188.     delete iCardsNoBmp;
  189.     for(i = 0; i< 52; i++)
  190.       delete iCards52Bmp[i];
  191.     for(i = 0; i< 28; i++)
  192.       delete iUnderTapis[i];
  193.     CloseWindow();
  194.     }
  195.  
  196. void CPyramidControl::UpdateModelL()
  197.     {
  198.     }
  199.  
  200. const TInt TapisRow[28]= {0,1,1,2,2,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6};
  201. const TInt TapisCol[28]= {0,-1,1,-2,0,2,-3,-1,1,3,-4,-2,0,2,4,-5,-3,-1,1,3,5,-6,-4,-2,0,2,4,6};
  202. const TInt TapisDownTree[28] = {2,4,5,7,8,9,11,12,13,14,16,17,18,19,20,22,23,24,25,26,27,0,0,0,0,0,0,0};
  203. const TInt TapisUpTree[56] = {0,0,0,1,1,0,0,2,2,3,3,0,0,4,4,5,5,6,6,0,0,7,7,8,8,9,9,10,10,0,0,11,11,12,12,13,
  204.                               13,14,14,15,15,0,0,16,16,17,17,18,18,19,19,20,20,21,21,0};
  205. const TInt WasteCol = 483;
  206. const TInt WasteRow = 14;
  207. const TInt TallonCol = 563;
  208. const TInt TallonRow = 14;
  209. const TInt StockCol = 563;
  210. const TInt StockRow = 128;
  211.  
  212. void CPyramidControl::DrawTapis(CWindowGc& gc) const
  213. {
  214. // if wanting to use sprites, take a look at \eikon\zoom\zoom.cpp
  215.     TInt i;
  216.     TInt posx,posy;
  217.     TRect bmpPieceRect;
  218.     TSize bmpSizeInPixels(73,97);
  219.     bmpPieceRect.SetRect(TPoint(0,0),bmpSizeInPixels); // full size
  220.     for(i = 0; i < 28; i++)
  221.       {
  222.       if(Tapis[i])
  223.         {
  224.         posx = 280 + TapisCol[i] * 40 - 37;
  225.         posy = TapisRow[i] * 23 + 3;
  226.         iEikonEnv->ScreenDevice()->CopyScreenToBitmap(iUnderTapis[i],TRect(posx,posy,posx+73,posy+97));
  227.         gc.BitBltMasked(TPoint(posx,posy), iCards52Bmp[Tapis[i]-1], bmpPieceRect, iCardsMsBmp, ETrue);
  228.         //to restore: gc.BitBlt(TPoint(posx,posy), iUnderTapis[i], TRect(0,0,73,97));
  229.         }
  230.       }
  231. }
  232. void CPyramidControl::DrawWaste(CWindowGc& gc) const
  233. {
  234.     TRect bmpPieceRect;
  235.     TSize bmpSizeInPixels(73,97);
  236.     bmpPieceRect.SetRect(TPoint(0,0),bmpSizeInPixels); // full size
  237.     if(WasteSize > 0)
  238.       gc.BitBltMasked(TPoint(WasteCol,WasteRow), iCards52Bmp[Waste[WasteSize-1]-1], bmpPieceRect, iCardsMsBmp, ETrue);
  239.     else
  240.       gc.BitBltMasked(TPoint(WasteCol,WasteRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  241. }
  242.  
  243. void CPyramidControl::DrawLabels(CWindowGc& gc) const
  244. {
  245.     TBuf<20> txt;
  246.     TInt textHeight(MyFont->HeightInPixels());
  247.     TInt textHeight2(MyFont2->HeightInPixels());
  248.     TRect box(16,20,120,44);
  249.     TInt offset,margin=0;
  250.     offset=(textHeight2+box.Height())/2 - 2; // 1/2 font ht below halfway down box
  251.     gc.UseFont(MyFont2);
  252.     gc.SetBrushStyle(gc.ESolidBrush);
  253.     gc.SetBrushColor(KRgbBlack);
  254.     gc.SetPenColor(KRgbWhite);
  255.     gc.SetPenStyle(gc.ESolidPen);
  256.     txt.Format(_L(" Score: %d"), Score);
  257.     gc.DrawText(txt,box,offset,CGraphicsContext::ELeft,margin);
  258.     gc.UseFont(MyFont);
  259.     box = TRect(WasteCol+6,WasteRow-12,WasteCol+68,WasteRow-1);
  260.     offset=(textHeight+box.Height())/2; // 1/2 font ht below halfway down box
  261.     txt.Format(_L(" Waste: %d"), WasteSize);
  262.     gc.DrawText(txt,box,offset,CGraphicsContext::ELeft,margin);
  263.     box = TRect(TallonCol+6,TallonRow-12,TallonCol+68,TallonRow-1);
  264.     txt.Format(_L(" Tallon: %d"), (Tallon ? 1 : 0) );
  265.     gc.DrawText(txt,box,offset,CGraphicsContext::ELeft,margin);
  266.     box = TRect(StockCol+6,StockRow-12,StockCol+68,StockRow-1);
  267.     txt.Format(_L(" Stock: %d"), StockSize);
  268.     gc.DrawText(txt,box,offset,CGraphicsContext::ELeft,margin);
  269. }
  270.  
  271.  
  272. void CPyramidControl::DrawStock(CWindowGc& gc) const
  273. {
  274.     TRect bmpPieceRect;
  275.     TSize bmpSizeInPixels(73,97);
  276.     bmpPieceRect.SetRect(TPoint(0,0),bmpSizeInPixels); // full size
  277.     if(StockSize > 0)
  278.       gc.BitBltMasked(TPoint(StockCol,StockRow), iCardsBkBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  279.     else
  280.       gc.BitBltMasked(TPoint(StockCol,StockRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  281. }
  282. void CPyramidControl::DrawTallon(CWindowGc& gc) const
  283. {
  284.     TRect bmpPieceRect;
  285.     TSize bmpSizeInPixels(73,97);
  286.     bmpPieceRect.SetRect(TPoint(0,0),bmpSizeInPixels); // full size
  287.     if(Tallon)
  288.       gc.BitBltMasked(TPoint(TallonCol,TallonRow), iCards52Bmp[Tallon-1], bmpPieceRect, iCardsMsBmp, ETrue);
  289.     else
  290.       gc.BitBltMasked(TPoint(TallonCol,TallonRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  291. }
  292.  
  293. void CPyramidControl::Draw(const TRect&/*aRect*/) const
  294.     {
  295.     CWindowGc& gc=SystemGc(); // graphics context we draw to
  296.     gc.SetPenStyle(gc.ESolidPen);
  297.     gc.SetBrushStyle(gc.EDiamondCrossHatchBrush);
  298.     gc.SetBrushColor(KRgbWhite);
  299.     gc.DrawRect(Rect()); // clear the area to be drawn to
  300.     DrawTapis(gc);
  301.     DrawStock(gc);
  302.     DrawTallon(gc);
  303.     DrawWaste(gc);
  304.     DrawLabels(gc);
  305.     gc.SetBrushStyle(gc.ESolidBrush);
  306.        }
  307.  
  308. void CPyramidControl::LoadBitmapL(CFbsBitmap* aBitMap,TDesC& aPathAndFile,TInt aId)
  309.     {
  310.     TParse    mbfn;
  311.     TBufC<2>  c_drive(_L("C:"));
  312.     TBufC<2>  z_drive(_L("D:"));
  313.  
  314.     mbfn.Set(aPathAndFile,&c_drive,NULL);
  315.     if (!aBitMap->Load(mbfn.FullName(),aId,ETrue))
  316.         return;
  317.  
  318.     mbfn.Set(aPathAndFile,&z_drive,NULL);
  319.     User::LeaveIfError(aBitMap->Load(mbfn.FullName(),aId,ETrue));
  320.     return;
  321.     }
  322.  
  323. void CPyramidControl::HandlePointerEventL(const TPointerEvent& aPointerEvent)
  324.     {
  325.     TInt card = 0;
  326.     if (aPointerEvent.iType==TPointerEvent::EButton1Down)
  327.       {
  328.       TInt posx,posy,i;
  329.       if(Score == 52)
  330.         return;
  331.         if(Tallon > 0 &&
  332.            aPointerEvent.iPosition.iX >= TallonCol &&
  333.            aPointerEvent.iPosition.iX < (TallonCol+73) &&
  334.            aPointerEvent.iPosition.iY >= TallonRow &&
  335.            aPointerEvent.iPosition.iY < (TallonRow+97) )
  336.         card = 29;
  337.       else
  338.         if(  aPointerEvent.iPosition.iX >= StockCol &&
  339.            aPointerEvent.iPosition.iX < (StockCol+73) &&
  340.            aPointerEvent.iPosition.iY >= StockRow &&
  341.            aPointerEvent.iPosition.iY < (StockRow+97) )
  342.         card = 30;
  343.       else
  344.         if(WasteSize > 0 &&
  345.            aPointerEvent.iPosition.iX >= WasteCol &&
  346.            aPointerEvent.iPosition.iX < (WasteCol+73) &&
  347.            aPointerEvent.iPosition.iY >= WasteRow &&
  348.            aPointerEvent.iPosition.iY < (WasteRow+97) )
  349.         card = 31;
  350.       else
  351.       for(i = 0; i < 28; i++)
  352.              {
  353.           if(Tapis[i] && TapisState[i])
  354.             {
  355.             posx = 280 + TapisCol[i] * 40 - 37;
  356.             posy = TapisRow[i] * 23 + 3;
  357.             if(aPointerEvent.iPosition.iX >= posx &&
  358.                aPointerEvent.iPosition.iX < (posx+73) &&
  359.                aPointerEvent.iPosition.iY >= posy &&
  360.                aPointerEvent.iPosition.iY < (posy+97) )
  361.                 {
  362.                 card = i+1;
  363.                 break;
  364.                 }
  365.             }
  366.           }
  367.       if(card != 0)
  368.           {
  369.           if(DragCard == 0)
  370.             {
  371.                DragCardHit = card;
  372.             switch(card)
  373.               {
  374.               case 29:{ // Tallon
  375.                       DragCardValue = (Tallon-1)%13 + 1;
  376.                       break;
  377.                       }
  378.               case 30:break; // Stock
  379.               case 31:{ // Waste
  380.                       DragCardValue = (Waste[WasteSize-1]-1)%13 + 1;
  381.                       break;
  382.                       }
  383.               default:{
  384.                       DragCardValue = (Tapis[card-1]-1)%13 + 1;
  385.                       break;
  386.                       }
  387.                  }
  388.             if((card != 30) && (DragCardValue == 13)) // a king
  389.                 {
  390.                 Score++;
  391.                 DropCardHit = 0;
  392.                 state = 3;
  393.                 }
  394.             else
  395.                 {
  396.                 state = 1;
  397.                 if(card != 30)
  398.                   DragCard = card;
  399.                 }
  400.             }
  401.           else
  402.               {
  403.               if(card == DragCard)
  404.                 {
  405.                 state = 2; // cancel drag card
  406.                 DragCardHit = card;
  407.                 DragCard = 0;
  408.                 }
  409.               else
  410.                 {
  411.                 TInt Bingo = 0;
  412.                 switch(card)
  413.                   {
  414.                   case 29:{ // Tallon
  415.                           if((Tallon-1)%13 + DragCardValue == 12)
  416.                               Bingo = 1;
  417.                             break;
  418.                           }
  419.                   case 30:break; // Stock
  420.                   case 31:{ // Waste
  421.                           if((Waste[WasteSize-1]-1)%13 + DragCardValue == 12)
  422.                               Bingo = 1;
  423.                             break;
  424.                           }
  425.                   default:{ // Tapis
  426.                           if((Tapis[card-1]-1)%13 + DragCardValue == 12)
  427.                               Bingo = 1;
  428.                             break;
  429.                           }
  430.                   }
  431.                 if(Bingo)
  432.                      {
  433.                      Score += 2;
  434.                      DragCardHit = DragCard;
  435.                      DropCardHit = card;
  436.                      DragCard = 0;
  437.                      state = 3;
  438.                      }
  439.                 }
  440.               }
  441.           if(state)
  442.             ReportEventL(EEventStateChanged);
  443.           }
  444.       }
  445.     }
  446.  
  447. void CPyramidControl::Restart()
  448. {
  449.     Random();
  450.     ActivateGc();
  451.     Draw(TRect(0,0,640,240));
  452.     DeactivateGc();
  453. }
  454.  
  455. void CPyramidControl::HandleControlEventL(CCoeControl* aControl,TCoeEvent aEventType)
  456. {
  457.     int px, py, crd;
  458.     if(aEventType != EEventStateChanged)
  459.       return;
  460.     int oldstate = state;
  461.     state = 0;
  462.     ActivateGc();
  463.     CWindowGc& gc=SystemGc(); // graphics context we draw to
  464.     TRect bmpPieceRect;
  465.     TSize bmpSizeInPixels(73,97);
  466.     bmpPieceRect.SetRect(TPoint(0,0),bmpSizeInPixels); // full size
  467.     gc.SetPenSize(TSize(4,4));
  468.     gc.SetPenColor(KRgbDarkGray);
  469.     switch(oldstate)
  470.       {
  471.       case 1:{
  472.              switch(DragCardHit)
  473.                {
  474.                case 29:{
  475.                        gc.DrawEllipse(TRect(TallonCol+6,TallonRow+6,TallonCol+67,TallonRow+91));
  476.                        break;
  477.                        }
  478.                case 30:{
  479.                        if(StockSize == 0)
  480.                          {
  481.                            if(Redeals >= MaxRedeals)
  482.                            {
  483.                            iEikonEnv->InfoMsg(_L("No more redeals allowed !"));
  484.                            break;
  485.                            }
  486.                          Redeals++;
  487.                          if(Tallon != 0)
  488.                            Stock[StockSize++] = Tallon;
  489.                          while(WasteSize > 0)
  490.                            Stock[StockSize++] = Waste[--WasteSize];
  491.                          if(StockSize > 0)
  492.                              {
  493.                              Tallon = Stock[--StockSize];
  494.                              gc.BitBltMasked(TPoint(StockCol,StockRow), iCardsBkBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  495.                              }
  496.                          else
  497.                              gc.BitBltMasked(TPoint(StockCol,StockRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  498.                          gc.BitBltMasked(TPoint(WasteCol,WasteRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  499.                          if(Tallon > 0)
  500.                              gc.BitBltMasked(TPoint(TallonCol,TallonRow), iCards52Bmp[Tallon-1], bmpPieceRect, iCardsMsBmp, ETrue);
  501.                          else
  502.                              gc.BitBltMasked(TPoint(TallonCol,TallonRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  503.                          DrawLabels(gc);
  504.                          break;
  505.                          }
  506.                        if(Tallon > 0)
  507.                          {
  508.                          Waste[WasteSize++] = Tallon;
  509.                          gc.BitBltMasked(TPoint(WasteCol,WasteRow), iCards52Bmp[Waste[WasteSize-1]-1], bmpPieceRect, iCardsMsBmp, ETrue);
  510.                          }
  511.                        if(StockSize > 0)
  512.                          {
  513.                          Tallon = Stock[--StockSize];
  514.                          gc.BitBltMasked(TPoint(TallonCol,TallonRow), iCards52Bmp[Tallon-1], bmpPieceRect, iCardsMsBmp, ETrue);
  515.                          }
  516.                        else
  517.                          gc.BitBltMasked(TPoint(StockCol,StockRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  518.                        DrawLabels(gc);
  519.                        break;
  520.                        }
  521.                case 31:{
  522.                        gc.DrawEllipse(TRect(WasteCol+6,WasteRow+6,WasteCol+67,WasteRow+91));
  523.                        break;
  524.                        }
  525.                default:{
  526.                        TInt posx,posy;
  527.                        posx = 280 + TapisCol[DragCardHit-1] * 40 - 37;
  528.                        posy = TapisRow[DragCardHit-1] * 23 + 3;
  529.                        gc.DrawEllipse(TRect(posx+6,posy+6,posx+67,posy+91));
  530.                        break;
  531.                        }
  532.                }
  533.              break;
  534.              }
  535.       case 2:{
  536.              switch(DragCardHit)
  537.                {
  538.                case 29:{
  539.                        gc.BitBltMasked(TPoint(TallonCol,TallonRow), iCards52Bmp[Tallon-1], bmpPieceRect, iCardsMsBmp, ETrue);
  540.                        break;
  541.                        }
  542.                case 31:{
  543.                        gc.BitBltMasked(TPoint(WasteCol,WasteRow), iCards52Bmp[Waste[WasteSize-1]-1], bmpPieceRect, iCardsMsBmp, ETrue);
  544.                        break;;
  545.                        }
  546.                default:{
  547.                        TInt posx,posy;
  548.                        posx = 280 + TapisCol[DragCardHit-1] * 40 - 37;
  549.                        posy = TapisRow[DragCardHit-1] * 23 + 3;
  550.                        gc.BitBltMasked(TPoint(posx,posy), iCards52Bmp[Tapis[DragCardHit-1]-1], bmpPieceRect, iCardsMsBmp, ETrue);
  551.                        break;
  552.                        }
  553.                }
  554.              break;
  555.              }
  556.       case 3:{
  557.              TInt card;
  558.              int i;
  559.              for(i = 0; i < 2; i++)
  560.              {
  561.              if(i == 0)
  562.                card = DragCardHit;
  563.              else
  564.                card = DropCardHit;
  565.              if(card == 0)
  566.                continue;
  567.              switch(card)
  568.                {
  569.                case 29:{
  570.                        Tallon = 0;
  571.                        gc.BitBltMasked(TPoint(TallonCol,TallonRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  572.                        break;
  573.                        }
  574.                case 31:{
  575.                        --WasteSize;
  576.                        if(WasteSize > 0)
  577.                          gc.BitBltMasked(TPoint(WasteCol,WasteRow), iCards52Bmp[Waste[WasteSize-1]-1], bmpPieceRect, iCardsMsBmp, ETrue);
  578.                        else
  579.                          gc.BitBltMasked(TPoint(WasteCol,WasteRow), iCardsNoBmp, bmpPieceRect, iCardsMsBmp, ETrue);
  580.                        break;;
  581.                        }
  582.                default:{
  583.                        TInt posx,posy,cardup,carddown;
  584.                        Tapis[card-1] = TapisState[card-1] = 0;
  585.                        cardup = TapisUpTree[(card-1)*2];
  586.                        if(cardup)
  587.                            {
  588.                            carddown = TapisDownTree[cardup-1];
  589.                            if((Tapis[carddown-1] == 0) && (Tapis[carddown] == 0))
  590.                              TapisState[cardup-1] = 1;
  591.                            }
  592.                        cardup = TapisUpTree[(card-1)*2 + 1];
  593.                        if(cardup)
  594.                            {
  595.                            carddown = TapisDownTree[cardup-1];
  596.                            if((Tapis[carddown-1] == 0) && (Tapis[carddown] == 0))
  597.                              TapisState[cardup-1] = 1;
  598.                            }
  599.                        posx = 280 + TapisCol[card-1] * 40 - 37;
  600.                        posy = TapisRow[card-1] * 23 + 3;
  601.                        gc.BitBlt(TPoint(posx,posy), iUnderTapis[card-1], TRect(0,0,73,97));
  602.                        break;
  603.                        }
  604.                }
  605.                }
  606.              DrawLabels(gc);
  607.              break;
  608.              }
  609.       }
  610.     if(Score == 52) // He won !
  611.       {
  612.       gc.SetPenStyle(gc.ESolidPen);
  613.       gc.SetBrushStyle(gc.ESolidBrush);
  614.       gc.SetBrushColor(KRgbWhite);
  615.       gc.DrawRect(Rect()); // clear the area to be drawn to
  616.       crd = 0;
  617.       for(py = 0; py < 2 ; py++)
  618.       for(px = 0; px < 8 ; px++)
  619.         {
  620.         gc.BitBltMasked(TPoint(px*78+8,py*120+10), iCards52Bmp[crd], bmpPieceRect, iCardsMsBmp, ETrue);
  621.         crd = (crd + 13) % 52;
  622.         }
  623.       }
  624.     DeactivateGc();
  625.     if(Score == 52)
  626.       {
  627.       CEikDialog* dialog = new (ELeave) CExampleAboutDialog();
  628.       GamesPlayed[Redeals]++;
  629.       GamesWon[Redeals]++;
  630.       MaxScore[Redeals] = 52;
  631.       TotalScore[Redeals] += 52;
  632.       dialog->ExecuteLD(R_EXAMPLE_WIN_DIALOG);
  633.       Random();
  634.       ActivateGc();
  635.       Draw(TRect(0,0,640,240));
  636.       DeactivateGc();
  637.       }
  638. }
  639.  
  640. TKeyResponse CPyramidControl::OfferKeyEventL(
  641.             const TKeyEvent& aKeyEvent,TEventCode aType
  642.             )
  643.     {
  644.     return EKeyWasNotConsumed;
  645.     }
  646.  
  647. //
  648. // class CPyramidContainer
  649. //
  650.  
  651. void CPyramidContainer::ConstructL(const TRect& aRect, TPyramidModel* aModel)
  652.     {
  653.     iModel=aModel;
  654.     CreateWindowL();
  655.     iContext=this;
  656.        iBrushStyle=CGraphicsContext::ESolidBrush;
  657.     iBrushColor=KRgbWhite;
  658.     SetRectL(aRect);
  659.     iPyramidControl = new(ELeave)CPyramidControl;
  660.     iPyramidControl->ConstructL(Window(), TRect(0,0,640,240));
  661.     ActivateL();
  662.     iPyramidControl->MyActivateGc(); // little hack for saving correctly the background
  663.     iPyramidControl->Draw(TRect(0,0,640,240)); // of the cards while using a BackedUpWindow
  664.     iPyramidControl->MyDeactivateGc();
  665.     }
  666.  
  667. CPyramidContainer::~CPyramidContainer()
  668.     {
  669.     delete iPyramidControl;
  670.     }
  671.     
  672. TInt CPyramidContainer::CountComponentControls() const
  673.     {
  674.     return 1;
  675.     }
  676.  
  677. CCoeControl* CPyramidContainer::ComponentControl(TInt aIndex) const
  678.     {
  679.     switch (aIndex)
  680.       {
  681.       case 0: return iPyramidControl;
  682.       default: return 0;
  683.       };
  684.     }
  685.  
  686.  
  687. TKeyResponse CPyramidContainer::OfferKeyEventL(const TKeyEvent& aKeyEvent,TEventCode aType)
  688.     {
  689.     if    (iPyramidControl)
  690.            return iPyramidControl->OfferKeyEventL(aKeyEvent,aType);
  691.     else
  692.         return EKeyWasNotConsumed;
  693.     }
  694.  
  695. void CPyramidContainer::Draw(const TRect& /*aRect*/) const
  696.     {
  697.     CWindowGc& gc = SystemGc();
  698.     gc.SetPenStyle(CGraphicsContext::ENullPen);
  699.     gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
  700.     gc.DrawRect(Rect());
  701.     }
  702.  
  703. //
  704. // CPyramidAppUi
  705. //
  706.  
  707. void CPyramidAppUi::ConstructL()
  708.     {
  709.     BaseConstructL();
  710.     iModel=((CPyramidDocument*)iDocument)->Model();
  711.     iContainer=new(ELeave) CPyramidContainer;
  712.     iContainer->ConstructL(ClientRect(),iModel);
  713.     ReadProfile();
  714.     // add container to stack; enables key event handling.
  715.     AddToStackL(iContainer);
  716.     }
  717.  
  718. void CPyramidAppUi::HandleCommandL(TInt aCommand)
  719.     {
  720.     switch (aCommand)
  721.         {
  722.  
  723.     case EEikCmdEditCut:            // <---Pre-defined command id
  724.     case EEikCmdEditCopy:           // <---Pre-defined command id
  725.     case EEikCmdEditPaste:          // <---Pre-defined command id
  726.     case EEikCmdEditSelectAll:      // <---Pre-defined command id
  727.         iEikonEnv->InfoMsg(_L("Not used by Pyramid"));
  728.         return;
  729.         // Infrared command
  730.     case EEikCmdIrdaSend:
  731.         iEikonEnv->InfoMsg(_L("Sending cards to Jupiter"));
  732.         break;
  733.     case EEikCmdIrdaReceive:
  734.         iEikonEnv->InfoMsg(_L("Receiving cards from Pluton"));
  735.         break;
  736.  
  737.     case EEikCmdPreferences:
  738.         {
  739.         CEikDialog* dialog = new (ELeave) CPrefDialog(&(iContainer->iPyramidControl->MaxRedeals));
  740.         dialog->ExecuteLD(R_EXAMPLE_PREFERENCES_DIALOG);
  741.         break;
  742.         }
  743.  
  744.     case EEikCmdExit:
  745.         {
  746.         if((iContainer->iPyramidControl->Score > 0) && (iContainer->iPyramidControl->Score < 52))
  747.           {
  748.           CEikDialog* dialog = new (ELeave) CExampleAboutDialog();
  749.           if(dialog->ExecuteLD(R_EXAMPLE_ADDTOSTATISTICS_DIALOG))
  750.             {
  751.             iContainer->iPyramidControl->GamesPlayed[iContainer->iPyramidControl->Redeals]++;
  752.             iContainer->iPyramidControl->TotalScore[iContainer->iPyramidControl->Redeals] += iContainer->iPyramidControl->Score;
  753.             if(iContainer->iPyramidControl->Score > iContainer->iPyramidControl->MaxScore[iContainer->iPyramidControl->Redeals])
  754.               iContainer->iPyramidControl->MaxScore[iContainer->iPyramidControl->Redeals] = iContainer->iPyramidControl->Score;
  755.             }
  756.           }
  757.         UpdateProfile();
  758.         CBaActiveScheduler::Exit();
  759.         }
  760.     case EEikCmdAbout:
  761.         {
  762.         CEikDialog* dialog = new (ELeave) CExampleAboutDialog();
  763.         dialog->ExecuteLD(R_EXAMPLE_ABOUT_DIALOG);
  764.         break;
  765.         }
  766.     case EEikCmdNewGame:
  767.         {
  768.         if((iContainer->iPyramidControl->Score > 0) && (iContainer->iPyramidControl->Score < 52))
  769.           {
  770.           CEikDialog* dialog = new (ELeave) CExampleAboutDialog();
  771.           if(dialog->ExecuteLD(R_EXAMPLE_ADDTOSTATISTICS_DIALOG))
  772.             {
  773.             iContainer->iPyramidControl->GamesPlayed[iContainer->iPyramidControl->Redeals]++;
  774.             iContainer->iPyramidControl->TotalScore[iContainer->iPyramidControl->Redeals] += iContainer->iPyramidControl->Score;
  775.             if(iContainer->iPyramidControl->Score > iContainer->iPyramidControl->MaxScore[iContainer->iPyramidControl->Redeals])
  776.               iContainer->iPyramidControl->MaxScore[iContainer->iPyramidControl->Redeals] = iContainer->iPyramidControl->Score;
  777.             }
  778.           }
  779.         iContainer->iPyramidControl->Restart();
  780.         break;
  781.         }
  782.     case EEikCmdStatistics:
  783.         {
  784.         CEikDialog* dialog = new (ELeave) CStatDialog(&iContainer->iPyramidControl->GamesPlayed[0],
  785.         &iContainer->iPyramidControl->GamesWon[0], &iContainer->iPyramidControl->MaxScore[0],
  786.         &iContainer->iPyramidControl->TotalScore[0]);
  787.         dialog->ExecuteLD(R_EXAMPLE_STATISTICS_DIALOG);
  788.         break;
  789.         }
  790.  
  791.     case EEikCmdCStatistics:
  792.         {
  793.         CEikDialog* dialog = new (ELeave) CExampleAboutDialog();
  794.         if(dialog->ExecuteLD(R_EXAMPLE_CSTATISTICS_DIALOG))
  795.           {
  796.           int i;
  797.           for(i = 0; i < 4; i++)
  798.             {
  799.             iContainer->iPyramidControl->GamesPlayed[i] = 0;
  800.             iContainer->iPyramidControl->GamesWon[i] = 0;
  801.             iContainer->iPyramidControl->MaxScore[i] = 0;
  802.             iContainer->iPyramidControl->TotalScore[i] = 0;
  803.              }
  804.           }
  805.         break;
  806.         }
  807.  
  808.         }
  809.     }
  810.  
  811. CPyramidAppUi::~CPyramidAppUi()
  812.     {
  813.     delete iContainer;
  814.     }
  815.  
  816. //
  817. // CPyramidDocument
  818. //
  819.  
  820. CEikAppUi* CPyramidDocument::CreateAppUiL()
  821.     {
  822.     return(new(ELeave) CPyramidAppUi);
  823.     }
  824.  
  825. //
  826. // CPyramidApplication
  827. //
  828.  
  829. TUid CPyramidApplication::AppDllUid() const
  830.     {
  831.     return KUidPyramidApp;
  832.     }
  833.  
  834. CApaDocument* CPyramidApplication::CreateDocumentL()
  835.     {
  836.     return new(ELeave) CPyramidDocument(*this);
  837.     }
  838.  
  839. //
  840. // EXPORTed functions
  841. //
  842.  
  843. EXPORT_C CApaApplication* NewApplication()
  844.     {
  845.     return new CPyramidApplication;
  846.     }
  847.  
  848. GLDEF_C TInt E32Dll(TDllReason)
  849.     {
  850.     return KErrNone;
  851.     }
  852.  
  853. void CPrefDialog::PreLayoutDynInitL()
  854. {
  855.     TInt dlgid;
  856.     switch(*dlgpref)
  857.       {
  858.       case 1:dlgid = EExampleControlIdHorOptButton2; break;
  859.       case 2:dlgid = EExampleControlIdHorOptButton3; break;
  860.       case 3:dlgid = EExampleControlIdHorOptButton4; break;
  861.       default: dlgid = EExampleControlIdHorOptButton1; break;
  862.       }
  863.     SetHorOptionButListCurrentSet(EExampleControlIdHorOptButtonList,dlgid);
  864. }
  865.  
  866. TBool CPrefDialog::OkToExitL(TInt)
  867.     {
  868.     switch(HorOptionButListCurrentSet(EExampleControlIdHorOptButtonList))
  869.       {
  870.       case EExampleControlIdHorOptButton2: *dlgpref = 1; break;
  871.       case EExampleControlIdHorOptButton3: *dlgpref = 2; break;
  872.       case EExampleControlIdHorOptButton4: *dlgpref = 3; break;
  873.       default: *dlgpref = 0; break;
  874.       }
  875.     return ETrue;
  876.     }
  877.  
  878. void CStatDialog::PreLayoutDynInitL()
  879. {
  880. TBuf<60> txt;
  881. TReal r;
  882. TRealFormat rf(6,2);
  883. int i;
  884. txt.Format(_L("Games Played: %d / %d / %d / %d"), gamesp[0], gamesp[1], gamesp[2], gamesp[3]);
  885. SetLabelL(EExampleControlIdStat2, txt);
  886. txt.Format(_L("Games Won:    %d / %d / %d / %d"), gamesw[0], gamesw[1], gamesw[2], gamesw[3]);
  887. SetLabelL(EExampleControlIdStat3, txt);
  888. txt = _L("Win Percent: ");
  889. for(i = 0;; i++)
  890.   {
  891.   if(gamesp[i] == 0)
  892.     r = 0;
  893.   else
  894.     r = ((TReal)gamesw[i]/(TReal)gamesp[i]) * 100;
  895.   txt.AppendNum(r, rf);
  896.   txt.Append('%');
  897.   if(i == 3)
  898.     break;
  899.   txt.Append(_L(" / "));
  900.   }
  901. SetLabelL(EExampleControlIdStat4, txt);
  902. txt = _L("Ave Score: ");
  903. for(i = 0;; i++)
  904.   {
  905.   if(gamesp[i] == 0)
  906.     r = 0;
  907.   else
  908.     r = (TReal)tscore[i]/(TReal)gamesp[i];
  909.   txt.AppendNum(r, rf);
  910.   if(i == 3)
  911.     break;
  912.   txt.Append(_L(" / "));
  913.   }
  914. SetLabelL(EExampleControlIdStat5, txt);
  915. txt.Format(_L("Best Score: %d / %d / %d / %d"), mscore[0], mscore[1], mscore[2], mscore[3]);
  916. SetLabelL(EExampleControlIdStat6, txt);
  917. }
  918.  
  919. const TUid PROFILE_UID={0x1000055E};
  920.  
  921. void CPyramidAppUi::UpdateProfile()
  922.     {
  923.     int i;
  924.       // Open the "ini" file. Application architecture creates the "ini" file
  925.       // if it does not exist
  926.     CDictionaryStore* iniFile = Application()->OpenIniFileLC(iCoeEnv->FsSession());
  927.  
  928.       // The stream containing the background preference will be associated
  929.       // with a Uid. AssignL() creates the stream if it does not exist
  930.     RDictionaryWriteStream writeStream;
  931.     writeStream.AssignLC(*iniFile,PROFILE_UID);
  932.     writeStream.WriteInt32L(iContainer->iPyramidControl->MaxRedeals);
  933.     for(i = 0; i < 4; i++)
  934.         {
  935.         writeStream.WriteInt32L(iContainer->iPyramidControl->GamesPlayed[i]);
  936.         writeStream.WriteInt32L(iContainer->iPyramidControl->GamesWon[i]);
  937.         writeStream.WriteInt32L(iContainer->iPyramidControl->MaxScore[i]);
  938.         writeStream.WriteInt32L(iContainer->iPyramidControl->TotalScore[i]);
  939.         }
  940.     writeStream.CommitL();
  941.     CleanupStack::PopAndDestroy();
  942.      
  943.     // Commit changes to the store
  944.     if (iniFile->Commit()!=KErrNone)
  945.         iniFile->RevertL(); 
  946.     // Destroys the "ini" file store object and closes
  947.     // the "ini" file
  948.     CleanupStack::PopAndDestroy(); // iniFile
  949.     }
  950.  
  951. void CPyramidAppUi::ReadProfile()
  952.     {
  953.     TInt v, i;
  954.       // Open the "ini" file. Application architecture creates the "ini" file
  955.       // if it does not exist
  956.     CDictionaryStore* iniFile = Application()->OpenIniFileLC(iCoeEnv->FsSession());
  957.     
  958.       // The stream containing the background preference will be associated
  959.       // with a Uid.
  960.       // Open the stream associted with the Uid; it will be created
  961.       // if it does not exist.
  962.     RDictionaryReadStream readStream;
  963.     readStream.OpenL(*iniFile,PROFILE_UID);
  964.  
  965.     iContainer->iPyramidControl->MaxRedeals = 2;
  966.     for(i = 0; i < 4; i++)
  967.       {
  968.       iContainer->iPyramidControl->GamesPlayed[i] = 0;
  969.       iContainer->iPyramidControl->GamesWon[i] = 0;
  970.       iContainer->iPyramidControl->MaxScore[i] = 0;
  971.       iContainer->iPyramidControl->TotalScore[i] = 0;
  972.       }
  973.       // If the stream has just been created (because the "ini" file has just
  974.       // been created), it will be "empty" and attempting to read from 
  975.       // the stream will leave with a KErrEof.
  976.     TRAPD(err, v = readStream.ReadInt32L());
  977.     if (!err)
  978.         {
  979.         iContainer->iPyramidControl->MaxRedeals = v;
  980.         for(i = 0; i < 4; i++)
  981.           {
  982.           v = readStream.ReadInt32L();
  983.           iContainer->iPyramidControl->GamesPlayed[i] = v;
  984.           v = readStream.ReadInt32L();
  985.           iContainer->iPyramidControl->GamesWon[i] = v;
  986.           v = readStream.ReadInt32L();
  987.           iContainer->iPyramidControl->MaxScore[i] = v;
  988.           v = readStream.ReadInt32L();
  989.           iContainer->iPyramidControl->TotalScore[i] = v;
  990.           }
  991.         }
  992.     readStream.Close();
  993.  
  994.     CleanupStack::PopAndDestroy();
  995.  
  996.     }
  997.