Index: unk/MagicSoft/Mars/mgui/MineSweeper.cc
===================================================================
--- /trunk/MagicSoft/Mars/mgui/MineSweeper.cc	(revision 1434)
+++ 	(revision )
@@ -1,526 +1,0 @@
-/* ======================================================================== *\
-!
-! *
-! * This file is part of MARS, the MAGIC Analysis and Reconstruction
-! * Software. It is distributed to you in the hope that it can be a useful
-! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
-! * It is distributed WITHOUT ANY WARRANTY.
-! *
-! * Permission to use, copy, modify and distribute this software and its
-! * documentation for any purpose is hereby granted without fee,
-! * provided that the above copyright notice appear in all copies and
-! * that both that copyright notice and this permission notice appear
-! * in supporting documentation. It is provided "as is" without express
-! * or implied warranty.
-! *
-!
-!
-!   Author(s): Thomas Bretz 07/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
-!
-!   Copyright: MAGIC Software Development, 2000-2002
-!
-!
-\* ======================================================================== */
-
-/////////////////////////////////////////////////////////////////////////////
-//
-// MineSweeper
-// -----------
-//
-// Camera Display Games: Mine Sweeper
-//
-// Start the game by:
-//   MineSweeper mine;
-//
-// It is the well known Mine Sweeper.
-// Set a mark using a single mouse click.
-// Open a pixel using a double click.
-//
-// Try to open all pixels without bombs. If you open a pixel with no
-// bomb around all pixels around are opened.
-//
-// To restart the game use the context menu. It can only be accessed if
-// the game has been stopped (either because you win the game or because
-// you hit a bomb) With the context menu you can also toggle between
-// different camera layouts.
-//
-////////////////////////////////////////////////////////////////////////////
-#include "MineSweeper.h"
-
-#include <iostream.h>
-
-#include <TText.h>
-#include <TMarker.h>
-#include <TRandom.h>
-#include <TCanvas.h>
-#include <TClonesArray.h>
-#include <TInterpreter.h>
-
-#include "MHexagon.h"
-
-#include "MGeomPix.h"
-#include "MGeomCamCT1.h"
-#include "MGeomCamMagic.h"
-
-ClassImp(MineSweeper);
-
-const Int_t MineSweeper::fColorBombs[7] = {
-    22,
-    kYellow,
-    kGreen,
-    kBlue,
-    kCyan,
-    kMagenta,
-    kRed
-};
-
-void MineSweeper::Free()
-{
-    if (!fGeomCam)
-        return;
-
-    fPixels->Delete();
-    fText->Delete();
-    fFlags->Delete();
-
-    delete fText;
-    delete fFlags;
-    delete fPixels;
-
-    delete fGeomCam;
-}
-
-void MineSweeper::ChangeCamera()
-{
-    static Bool_t ct1=kFALSE;
-
-    cout << "Change to " << (ct1?"Magic":"CT1") << endl;
-
-    if (ct1)
-        SetNewCamera(new MGeomCamMagic);
-    else
-        SetNewCamera(new MGeomCamCT1);
-
-    ct1 = !ct1;
-
-    Reset();
-    DrawHexagons();
-}
-
-void MineSweeper::SetNewCamera(MGeomCam *geom)
-{
-    Free();
-
-    //
-    //  Reset the display geometry
-    //
-    fW=0;
-    fH=0;
-
-    //
-    //  Set new camera
-    //
-    fGeomCam = geom;
-
-    //
-    //  create the hexagons of the display
-    //
-    fNumPixels = fGeomCam->GetNumPixels();
-    fRange     = fGeomCam->GetMaxRadius();
-
-    //
-    // Construct all hexagons. Use new-operator with placement
-    //
-    fNumBombs = fNumPixels/5;
-
-    fText   = new TClonesArray("TText",    fNumPixels);
-    fFlags  = new TClonesArray("TMarker",  fNumPixels);
-    fPixels = new TClonesArray("MHexagon", fNumPixels);
-
-    for (UInt_t i=0; i<fNumPixels; i++)
-    {
-        MHexagon &h = *new ((*fPixels)[i]) MHexagon((*fGeomCam)[i]);
-#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
-        h.SetBit(kNoContextMenu|kCannotPick);
-#endif
-
-        TText &t = *new ((*fText)[i]) TText;
-        t.SetTextFont(122);
-        t.SetTextAlign(22);   // centered/centered
-        t.SetTextSize(0.3*h.GetD()/fRange);
-#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
-        t.SetBit(kNoContextMenu|kCannotPick);
-#endif
-
-        const MGeomPix &pix = (*fGeomCam)[i];
-
-        TMarker &m = *new ((*fFlags)[i]) TMarker(pix.GetX(), pix.GetY(), kOpenStar);
-#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
-        m.SetBit(kNoContextMenu|kCannotPick);
-#endif
-    }
-}
-
-// ------------------------------------------------------------------------
-//
-// Draw all pixels of the camera
-//  (means apend all pixelobjects to the current pad)
-//
-void MineSweeper::DrawHexagons()
-{
-    for (UInt_t i=0; i<fNumPixels; i++)
-        (*this)[i].Draw();
-}
-
-// ------------------------------------------------------------------------
-//
-//  default constructor
-//
-MineSweeper::MineSweeper()
-    : fGeomCam(NULL), fDone(NULL), fShow(NULL), fW(0), fH(0), fDrawingPad(NULL), fIsAllocated(kFALSE)
-{
-    SetNewCamera(new MGeomCamMagic);
-
-    //
-    // Make sure, that the object is destroyed when the canvas/pad is
-    // destroyed. Make also sure, that the interpreter doesn't try to
-    // delete it a second time.
-    //
-    SetBit(kCanDelete);
-    gInterpreter->DeleteGlobal(this);
-
-    Draw();
-}
-
-// ------------------------------------------------------------------------
-//
-// Destructor. Deletes TClonesArrays for hexagons and legend elements.
-//
-MineSweeper::~MineSweeper()
-{
-    Free();
-
-    delete fShow;
-
-    if (fDone)
-        delete fDone;
-
-    if (fDrawingPad->GetListOfPrimitives()->FindObject(this)==this)
-    {
-        fDrawingPad->RecursiveRemove(this);
-        delete fDrawingPad;
-    }
-}
-
-// ------------------------------------------------------------------------
-//
-// This is called at any time the canvas should get repainted.
-// Here we maintain an aspect ratio of 5/4=1.15. This makes sure,
-// that the camera image doesn't get distorted by resizing the canvas.
-//
-void MineSweeper::Paint(Option_t *opt)
-{
-    const UInt_t w = (UInt_t)(gPad->GetWw()*gPad->GetAbsWNDC());
-    const UInt_t h = (UInt_t)(gPad->GetWh()*gPad->GetAbsHNDC());
-
-    //
-    // Check for a change in width or height, and make sure, that the
-    // first call also sets the range
-    //
-    if (w*fH == h*fW && fW && fH)
-        return;
-
-    //
-    // Calculate aspect ratio (5/4=1.25 recommended)
-    //
-    const Double_t ratio = (Double_t)w/h;
-
-    Float_t x;
-    Float_t y;
-
-    if (ratio>1.0)
-    {
-        x = fRange*(ratio*2-1);
-        y = fRange;
-    }
-    else
-    {
-        x = fRange;
-        y = fRange/ratio;
-    }
-
-    fH = h;
-    fW = w;
-
-    //
-    // Set new range
-    //
-    fDrawingPad->Range(-fRange, -y, x, y);
-
-    //
-    // Adopt absolute sized of markers to relative range
-    //
-    for (UInt_t i=0; i<fNumPixels; i++)
-    {
-        Float_t r = (*this)[i].GetD()*gPad->XtoAbsPixel(1)/325;
-        GetFlag(i)->SetMarkerSize(20.0*r/fRange);
-    }
-}
-
-// ------------------------------------------------------------------------
-//
-// Call this function to draw the camera layout into your canvas.
-// Setup a drawing canvas. Add this object and all child objects
-// (hexagons, etc) to the current pad. If no pad exists a new one is
-// created.
-//
-void MineSweeper::Draw(Option_t *option)
-{
-    // root 3.02:
-    // gPad->SetFixedAspectRatio()
-
-    if (fDrawingPad)
-        return;
-
-    //
-    // if no canvas is yet existing to draw into, create a new one
-    //
-    if (!gPad)
-    {
-        /*TCanvas *c =*/ new TCanvas("MineSweeper", "Magic Mine Sweeper", 0, 0, 800, 800);
-        //c->ToggleEventStatus();
-        fIsAllocated = kTRUE;
-    }
-    else
-        fIsAllocated = kFALSE;
-
-    fDrawingPad = gPad;
-    fDrawingPad->SetBorderMode(0);
-
-    //
-    // Append this object, so that the aspect ratio is maintained
-    // (Paint-function is called)
-    //
-    AppendPad(option);
-
-    //
-    // Draw the title text
-    //
-    fShow = new TText;
-    fShow->SetTextAlign(23);   // centered/bottom
-#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
-    fShow->SetBit(kNoContextMenu|kCannotPick);
-#endif
-    fShow->Draw();
-    //
-    // Reset the game pad
-    //
-    Reset();
-    DrawHexagons();
-}
-
-void MineSweeper::Update(Int_t num)
-{
-    TString txt = "Pixels: ";
-    txt += fNumPixels;
-    txt += "  Bombs: ";
-    txt += num;
-
-    fShow->SetText(0, fRange, txt);
-}
-
-// ------------------------------------------------------------------------
-//
-// reset the all pixel colors to a default value
-//
-void MineSweeper::Reset()
-{
-    if (fDone)
-    {
-        delete fDone;
-        fDone = NULL;
-    }
-
-    for (UInt_t i=0; i<fNumPixels; i++)
-    {
-        Remove(GetText(i));
-        Remove(GetFlag(i));
-
-        (*this)[i].SetFillColor(kHidden);
-        (*fGeomCam)[i].ResetBit(kUserBits);
-
-        GetFlag(i)->SetMarkerColor(kBlack);
-    }
-    Update(fNumBombs);
-
-    TRandom rnd(0);
-    for (int i=0; i<fNumBombs; i++)
-    {
-        Int_t idx;
-
-        do idx = (Int_t)rnd.Uniform(fNumPixels);
-        while ((*fGeomCam)[idx].TestBit(kHasBomb));
-
-        (*fGeomCam)[idx].SetBit(kHasBomb);
-    }
-
-    fDrawingPad->SetFillColor(22);
-
-#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
-    fDrawingPad->SetBit(kNoContextMenu);
-    SetBit(kNoContextMenu);
-#endif
-}
-
-void MineSweeper::Done(TString txt, Int_t col)
-{
-    for (unsigned int j=0; j<fNumPixels; j++)
-        if ((*fGeomCam)[j].TestBit(kHasBomb))
-        {
-            (*this)[j].SetFillColor(kBlack);
-            GetFlag(j)->SetMarkerColor(kWhite);
-        }
-
-    fDone = new TText(0, 0, txt);
-    fDone->SetTextColor(kWhite);  // white
-    fDone->SetTextAlign(22);  // centered/centered
-    fDone->SetTextSize(0.05); // white
-#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
-    fDone->SetBit(kNoContextMenu|kCannotPick);
-#endif
-    fDone->Draw();
-
-    fDrawingPad->SetFillColor(col);
-
-#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
-    fDrawingPad->ResetBit(kNoContextMenu);
-    ResetBit(kNoContextMenu);
-#endif
-}
-
-// ------------------------------------------------------------------------
-//
-// Check whether a hexagon should be opened and which color/number should
-// be visible
-//
-void MineSweeper::OpenHexagon(Int_t idx)
-{
-    MGeomPix &pix=(*fGeomCam)[idx];
-
-    if (pix.TestBit(kIsVisible))
-        return;
-
-    if (pix.TestBit(kHasFlag))
-        Remove(GetFlag(idx));
-
-    pix.SetBit(kIsVisible);
-    pix.ResetBit(kHasFlag);
-
-    Int_t cnt=0;
-    for (int j=0; j<pix.GetNumNeighbors(); j++)
-        if ((*fGeomCam)[pix.GetNeighbor(j)].TestBit(kHasBomb))
-            cnt++;
-
-    (*this)[idx].SetFillColor(fColorBombs[cnt]);
-
-    if (cnt)
-    {
-        TText *txt = GetText(idx);
-        TString str;
-        str += cnt;
-        txt->SetText(pix.GetX(), pix.GetY(), str);
-        txt->Draw();
-        return;
-    }
-
-    for (int j=0; j<pix.GetNumNeighbors(); j++)
-        OpenHexagon(pix.GetNeighbor(j));
-}
-
-void MineSweeper::Remove(TObject *obj)
-{
-    fDrawingPad->RecursiveRemove(obj);
-}
-
-// ------------------------------------------------------------------------
-//
-// Execute a mouse event on the camera
-//
-void MineSweeper::ExecuteEvent(Int_t event, Int_t px, Int_t py)
-{
-    if (event==kMouseMotion   || event==kMouseEnter    || event==kMouseLeave    ||
-        event==kButton1Up     || event==kButton2Up     || event==kButton3Up     ||
-        event==kButton1Motion || event==kButton2Motion || event==kButton3Motion ||
-                                 event==kButton2Double || event==kButton3Double ||
-        fDone)
-        return;
-
-    /*
-    if (event==kKeyPress && py==0x1000)
-    {
-        Reset();
-        return;
-    }
-    */
-
-    UInt_t idx;
-    for (idx=0; idx<fNumPixels; idx++)
-        if ((*fPixels)[idx]->DistancetoPrimitive(px, py)==0)
-            break;
-
-    if (idx==fNumPixels)
-        return;
-
-    MGeomPix &pix=(*fGeomCam)[idx];
-
-    if (event==kButton1Double)
-    {
-        OpenHexagon(idx);
-
-        if (pix.TestBit(kHasBomb))
-            Done("Argh... you hit the Bomb!!!", kRed);
-    }
-
-    if (event==kButton1Down && !pix.TestBit(kIsVisible))
-    {
-        if (pix.TestBit(kHasFlag))
-            Remove(GetFlag(idx));
-        else
-            GetFlag(idx)->Draw();
-
-        pix.InvertBit(kHasFlag);
-    }
-
-    UInt_t vis=fNumBombs;
-    UInt_t flg=fNumBombs;
-    for (UInt_t i=0; i<fNumPixels; i++)
-    {
-        if ((*fGeomCam)[i].TestBit(kIsVisible))
-            vis++;
-        if ((*fGeomCam)[i].TestBit(kHasFlag))
-            flg--;
-    }
-
-    Update(flg);
-
-    if (vis==fNumPixels && !fDone)
-        Done("Great! Congratulations, you did it!", kGreen);
-
-    fDrawingPad->Modified();
-
-    /*
-     switch (event)
-     {
-     case kNoEvent:       cout << "No Event" << endl; break;
-     case kButton1Down:   cout << "Button 1 down" << endl; break;
-     case kButton2Down:   cout << "Button 2 down" << endl; break;
-     case kButton3Down:   cout << "Button 3 down" << endl; break;
-     case kKeyDown:       cout << "Key down" << endl; break;
-     case kKeyUp:         cout << "Key up" << endl; break;
-     case kKeyPress:      cout << "Key press" << endl; break;
-     case kButton1Locate: cout << "Button 1 locate" << endl; break;
-     case kButton2Locate: cout << "Button 2 locate" << endl; break;
-     case kButton3Locate: cout << "Button 3 locate" << endl; break;
-    }
-    */
-}
Index: unk/MagicSoft/Mars/mgui/MineSweeper.h
===================================================================
--- /trunk/MagicSoft/Mars/mgui/MineSweeper.h	(revision 1434)
+++ 	(revision )
@@ -1,78 +1,0 @@
-#ifndef MARS_MineSweeper
-#define MARS_MineSweeper
-
-#ifndef MARS_MAGIC
-#include "MAGIC.h"
-#endif
-#ifndef ROOT_TClonesArray
-#include <TClonesArray.h>
-#endif
-
-class TText;
-class TMarker;
-class TVirtualPad;
-
-class MGeomCam;
-class MHexagon;
-
-class MineSweeper : public TObject
-{
-private:
-    static const Int_t fColorBombs[7]; // colors for the hexagons
-
-    MGeomCam      *fGeomCam;       // pointer to camera geometry
-
-    UInt_t         fNumPixels;     // number of pixels in the present geometry
-    Int_t          fNumBombs;      // number of bombs in total
-    Float_t        fRange;         // the range in millimeters of the present geometry
-
-    TClonesArray  *fPixels;        // array of all hexagons
-    TClonesArray  *fText;          // array of all texts
-    TClonesArray  *fFlags;         // array of all texts
-
-    TText         *fDone;          // TText showing the 'Game over'
-    TText         *fShow;          // TText showing the numbers of pixels and bombs
-
-    UInt_t         fW;             // Width of canvas
-    UInt_t         fH;             // Height of canvas
-    TVirtualPad   *fDrawingPad;    // pad in which we are drawing
-    Bool_t         fIsAllocated;
-
-    enum
-    {
-        kHidden    = 50,
-        kIsVisible = BIT(15),
-        kHasBomb   = BIT(16),
-        kHasFlag   = BIT(17),
-        kUserBits  = 0x0000ff00 // 14-23 are allowed
-    };
-
-    MHexagon &operator[](int i) { return *((MHexagon*)fPixels->At(i)); }
-
-    TText   *GetText(Int_t i) { return (TText*)fText->At(i); }
-    TMarker *GetFlag(Int_t i) { return (TMarker*)fFlags->At(i); }
-
-    void  Remove(TObject *);
-    void  OpenHexagon(Int_t idx);
-    void  Done(TString, Int_t);
-    void  Update(Int_t);
-    void  SetNewCamera(MGeomCam *);
-    void  DrawHexagons();
-    void  Free();
-
-    void  Paint(Option_t *option="");
-    void  Draw(Option_t *option="");
-    void  ExecuteEvent(Int_t event, Int_t px, Int_t py);
-    Int_t DistancetoPrimitive(Int_t px, Int_t py) { return 0; }
-
-public:
-    MineSweeper();
-    ~MineSweeper();
-
-    void Reset();        //*MENU*
-    void ChangeCamera(); //*MENU*
-
-    ClassDef(MineSweeper, 0) // Magic Camera Games
-};
-
-#endif
Index: /trunk/MagicSoft/Mars/mtools/MagicCivilization.cc
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MagicCivilization.cc	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MagicCivilization.cc	(revision 1435)
@@ -0,0 +1,444 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 07/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MagicCivilization
+// ---------
+//
+// Tool to visualize Next Neighbours.
+//
+// Start the show by:
+//   MagicCivilization show;
+//
+// Use the following keys:
+// -----------------------
+//
+//   * Space:
+//     Toggle between auto increment and manual increment
+//
+//   * Right/Left:
+//     Increment/Decrement pixel number by 1
+//
+//   * Right/Left:
+//     Increment/Decrement pixel number by 1
+//
+//   * Up/Down:
+//     Increment/Decrement pixel number by 10
+//
+//   * PageUp/PageDown:
+//     Increment/Decrement pixel number by 100
+//
+//   * Home/End:
+//     Jump to first/last pixel
+//
+////////////////////////////////////////////////////////////////////////////
+#include "MagicCivilization.h"
+
+#include <iostream.h>
+
+#include <KeySymbols.h>
+
+#include <TCanvas.h>
+#include <TRandom.h>
+#include <TInterpreter.h>
+
+#include "MHexagon.h"
+
+#include "MGeomPix.h"
+#include "MGeomCamCT1.h"
+#include "MGeomCamMagic.h"
+
+ClassImp(MagicCivilization);
+
+void MagicCivilization::Free()
+{
+    if (!fGeomCam)
+        return;
+
+    fPixels->Delete();
+
+    delete fPixels;
+
+    delete fGeomCam;
+}
+
+// ------------------------------------------------------------------------
+//
+// Draw all pixels of the camera
+//  (means apend all pixelobjects to the current pad)
+//
+void MagicCivilization::DrawHexagons()
+{
+    for (UInt_t i=0; i<fNumPixels; i++)
+        (*this)[i].Draw();
+}
+
+void MagicCivilization::ChangeCamera()
+{
+    static Bool_t ct1=kFALSE;
+
+    cout << "Change to " << (ct1?"Magic":"CT1") << endl;
+
+    if (ct1)
+        SetNewCamera(new MGeomCamMagic);
+    else
+        SetNewCamera(new MGeomCamCT1);
+
+    ct1 = !ct1;
+
+    DrawHexagons();
+}
+
+void MagicCivilization::SetNewCamera(MGeomCam *geom)
+{
+    Free();
+
+    //
+    //  Reset the display geometry
+    //
+    fW=0;
+    fH=0;
+
+    //
+    //  Set new camera
+    //
+    fGeomCam = geom;
+
+    //
+    //  create the hexagons of the display
+    //
+    fNumPixels = fGeomCam->GetNumPixels();
+    fRange     = fGeomCam->GetMaxRadius();
+
+    //
+    // Construct all hexagons. Use new-operator with placement
+    //
+    fPixels = new TClonesArray("MHexagon", fNumPixels);
+
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        MHexagon &h = *new ((*fPixels)[i]) MHexagon((*fGeomCam)[i]);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        h.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+//  default constructor
+//
+MagicCivilization::MagicCivilization(Byte_t lim, UShort_t init)
+    : fTimer(this, 500, kTRUE), fGeomCam(NULL), fNumInit(init), fLimit(lim), fW(0), fH(0)
+{
+    SetNewCamera(new MGeomCamMagic);
+
+    //
+    // Make sure, that the object is destroyed when the canvas/pad is
+    // destroyed. Make also sure, that the interpreter doesn't try to
+    // delete it a second time.
+    //
+    SetBit(kCanDelete);
+    gInterpreter->DeleteGlobal(this);
+
+    Draw();
+
+    fTimer.TurnOn();
+}
+
+// ------------------------------------------------------------------------
+//
+// Destructor. Deletes TClonesArrays for hexagons and legend elements.
+//
+MagicCivilization::~MagicCivilization()
+{
+    fTimer.TurnOff();
+    Free();
+
+    if (fDrawingPad->GetListOfPrimitives()->FindObject(this)==this)
+    {
+        fDrawingPad->RecursiveRemove(this);
+        delete fDrawingPad;
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// This is called at any time the canvas should get repainted.
+// Here we maintain an aspect ratio of 5/4=1.15. This makes sure,
+// that the camera image doesn't get distorted by resizing the canvas.
+//
+void MagicCivilization::Paint(Option_t *opt)
+{
+    const UInt_t w = (UInt_t)(gPad->GetWw()*gPad->GetAbsWNDC());
+    const UInt_t h = (UInt_t)(gPad->GetWh()*gPad->GetAbsHNDC());
+
+    //
+    // Check for a change in width or height, and make sure, that the
+    // first call also sets the range
+    //
+    if (w*fH == h*fW && fW && fH)
+        return;
+
+    //
+    // Calculate aspect ratio (5/4=1.25 recommended)
+    //
+    const Double_t ratio = (Double_t)w/h;
+
+    Float_t x;
+    Float_t y;
+
+    if (ratio>1.0)
+    {
+        x = fRange*(ratio*2-1);
+        y = fRange;
+    }
+    else
+    {
+        x = fRange;
+        y = fRange/ratio;
+    }
+
+    fH = h;
+    fW = w;
+
+    //
+    // Set new range
+    //
+    fDrawingPad->Range(-fRange, -y, x, y);
+}
+
+void MagicCivilization::Reset()
+{
+    if (fNumInit>=fNumPixels)
+        fNumInit = fNumPixels-1;
+    if (fNumInit<0)
+        fNumInit = 0;
+
+    if (fLimit<0)
+        fLimit=6;
+    if (fLimit>6)
+        fLimit=0;
+
+
+    TRandom rnd(0);
+    for (int i=0; i<fNumPixels; i++)
+        (*fGeomCam)[i].ResetBit(kUserBits);
+
+    for (int i=0; i<fNumInit; i++)
+    {
+        Int_t idx;
+
+        do idx = (Int_t)rnd.Uniform(fNumPixels);
+        while ((*fGeomCam)[idx].TestBit(kHasFlag));
+
+        if (idx>=fNumPixels)
+            cout << "!!!!!!!!!!!!!!!!!!!!!!!!" << endl;
+
+        (*fGeomCam)[idx].SetBit(kHasFlag);
+    }
+
+    fAuto = kFALSE;
+    fStep = 0;
+
+    Update();
+
+    fDrawingPad->Modified();
+    fDrawingPad->Update();
+}
+
+// ------------------------------------------------------------------------
+//
+// Call this function to draw the camera layout into your canvas.
+// Setup a drawing canvas. Add this object and all child objects
+// (hexagons, etc) to the current pad. If no pad exists a new one is
+// created.
+//
+void MagicCivilization::Draw(Option_t *option)
+{
+    //
+    // if no canvas is yet existing to draw into, create a new one
+    //
+    /*TCanvas *c =*/ new TCanvas("MagicCivilization", "Magic Civilization", 0, 0, 800, 800);
+    //c->ToggleEventStatus();
+
+    fDrawingPad = gPad;
+    fDrawingPad->SetBorderMode(0);
+    fDrawingPad->SetFillColor(22);
+
+    //
+    // Append this object, so that the aspect ratio is maintained
+    // (Paint-function is called)
+    //
+    AppendPad(option);
+
+    //
+    // Reset the game pad
+    //
+    DrawHexagons();
+
+    fCivilization.SetTextAlign(23);   // centered/bottom
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fCivilization.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    fCivilization.Draw();
+
+    Reset();
+}
+
+void MagicCivilization::Update()
+{
+    TString txt = "Lim: ";
+    txt += (int)fLimit;
+    txt += "  Init: ";
+    txt += fNumInit;
+    txt += "  On: ";
+    txt += fNumCivilizations;
+    txt += "  Step: ";
+    txt += fStep;
+
+    if (!fAuto)
+        txt += "  (paused)";
+
+    fCivilization.SetText(0, fRange, txt);
+}
+
+
+
+// ------------------------------------------------------------------------
+//
+// Execute a mouse event on the camera
+//
+void MagicCivilization::ExecuteEvent(Int_t event, Int_t keycode, Int_t keysym)
+{
+    if (event!=kKeyPress)
+        return;
+
+    switch (keysym)
+    {
+    default:
+        return;
+
+    case kKey_Space:
+        if ((fNumCivilizations==0 || fNumCivilizations==fNumPixels) && !fAuto)
+            Reset();
+        fAuto = !fAuto;
+        Update();
+        fDrawingPad->Update();
+        return;
+
+    case kKey_Right:
+        fNumInit += 1;;
+        break;
+
+    case kKey_Left:
+        fNumInit -= 1;
+        break;
+
+    case kKey_Up:
+        fNumInit += 10;
+        break;
+
+    case kKey_Down:
+        fNumInit -= 10;
+        break;
+
+    case kKey_PageUp:
+        fNumInit += 100;
+        break;
+
+    case kKey_PageDown:
+        fNumInit -= 100;
+        break;
+
+    case kKey_Plus:
+        fLimit++;
+        break;
+
+    case kKey_Minus:
+        fLimit--;
+        break;
+    }
+
+    Reset();
+}
+
+Bool_t MagicCivilization::HandleTimer(TTimer *timer)
+{
+    if (!fAuto)
+        return kTRUE;
+
+    for (int i=0; i<fNumPixels; i++)
+    {
+        MGeomPix &pix = (*fGeomCam)[i];
+
+        Byte_t cnt=0;
+        for (int j=0; j<pix.GetNumNeighbors(); j++)
+            if ((*fGeomCam)[pix.GetNeighbor(j)].TestBit(kHasFlag))
+                cnt++;
+
+        cnt += (6-pix.GetNumNeighbors())*cnt/6;
+
+        if (cnt>fLimit)
+            pix.SetBit(kHasCreation);
+    }
+
+    fNumCivilizations = 0;
+    for (int i=0; i<fNumPixels; i++)
+    {
+        MGeomPix &pix = (*fGeomCam)[i];
+        MHexagon &hex = (*this)[i];
+
+        if (pix.TestBit(kHasCreation))
+        {
+            pix.SetBit(kHasFlag);
+            hex.SetFillColor(kBlack);
+            fNumCivilizations++;
+        }
+        else
+        {
+            pix.ResetBit(kHasFlag);
+            hex.SetFillColor(kBackground);
+        }
+        pix.ResetBit(kHasCreation);
+    }
+
+    if (fNumCivilizations==0 || fNumCivilizations==fNumPixels)
+        fAuto = kFALSE;
+
+    fStep++;
+
+    Update();
+
+    fDrawingPad->Update();
+
+    return kTRUE;
+}
+
+char       *MagicCivilization::GetObjectInfo(Int_t px, Int_t py) const
+{
+    cout << "GET " << px << " " << py << endl;
+    return 0;
+}
Index: /trunk/MagicSoft/Mars/mtools/MagicCivilization.h
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MagicCivilization.h	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MagicCivilization.h	(revision 1435)
@@ -0,0 +1,83 @@
+#ifndef MARS_MagicCivilization
+#define MARS_MagicCivilization
+
+#ifndef MARS_MAGIC
+#include "MAGIC.h"
+#endif
+
+#ifndef ROOT_TText
+#include <TText.h>
+#endif
+#ifndef ROOT_TTimer
+#include <TTimer.h>
+#endif
+#ifndef ROOT_TClonesArray
+#include <TClonesArray.h>
+#endif
+
+class TMarker;
+class TVirtualPad;
+
+class MGeomCam;
+class MHexagon;
+
+class MagicCivilization : public TObject
+{
+private:
+    enum
+    {
+        kBackground   = 50,
+        kHasFlag      = BIT(15),
+        kHasCreation  = BIT(16),
+        kUserBits     = 0x0000ff00, // 14-23 are allowed
+    };
+
+    TTimer    fTimer;           // timer rising the 500ms interrputs
+
+    MGeomCam *fGeomCam;         // pointer to camera geometry
+
+    UShort_t  fNumPixels;       // number of pixels in the present geometry
+    Short_t   fNumInit;         // number of bombs in the field
+    Float_t   fRange;           // the range in millimeters of the present geometry
+
+    Bool_t    fAuto;
+
+    Char_t    fLimit;
+
+    UShort_t  fNumCivilizations;
+    UInt_t    fStep;
+
+    TText     fCivilization;    // TText showing the numbers of pixels and bombs
+
+    UInt_t    fW;               // Width of canvas
+    UInt_t    fH;               // Height of canvas
+
+    TClonesArray *fPixels;      // array of all hexagons
+    TVirtualPad  *fDrawingPad;  // pad in which we are drawing
+
+    MHexagon &operator[](int i) { return *((MHexagon*)fPixels->At(i)); }
+
+    void   Update();
+    void   Free();
+    void   DrawHexagons();
+    void   SetNewCamera(MGeomCam *);
+
+    Bool_t HandleTimer(TTimer *timer);
+    void   Draw(Option_t *option="");
+    void   Paint(Option_t *option="");
+    void   ExecuteEvent(Int_t event, Int_t px, Int_t py);
+    Int_t  DistancetoPrimitive(Int_t px, Int_t py) { return 0; }
+
+public:
+    MagicCivilization(Byte_t lim=2, UShort_t init=200);
+    ~MagicCivilization();
+
+    void ChangeCamera(); //*MENU*
+    void Reset();        //*MENU*
+
+    char       *MagicCivilization::GetObjectInfo(Int_t px, Int_t py) const;
+
+    ClassDef(MagicCivilization, 0) // Tool to visualize next neighbours
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mtools/MagicDomino.cc
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MagicDomino.cc	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MagicDomino.cc	(revision 1435)
@@ -0,0 +1,722 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 07/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MagicDomino
+// -----------
+//
+// Magic Camera games.
+//
+// Start the show by:
+//   MagicDomino show;
+//
+// Use the following keys:
+// -----------------------
+//
+//   * Cursor up/down, left/right:
+//     Move tile
+//
+//   * Space:
+//     Rotate tile
+//
+//   * Enter:
+//     Set tile
+//
+//   * Esc:
+//     Skip tile
+//
+//  Rules:
+//  ------
+//
+//   Each hexagon in the tile must at least have one neighbor
+//   which has the same color. It is not allowed to put a tile onto
+//   another one. The game is over if you have skipped three tiles
+//   in a row.
+//
+////////////////////////////////////////////////////////////////////////////
+#include "MagicDomino.h"
+
+#include <iostream.h>
+
+#include <KeySymbols.h>
+
+#include <TCanvas.h>
+#include <TRandom.h>
+#include <TInterpreter.h>
+
+#include "MHexagon.h"
+
+#include "MGeomPix.h"
+#include "MGeomCamCT1.h"
+#include "MGeomCamMagic.h"
+
+ClassImp(MagicDomino);
+
+// ------------------------------------------------------------------------
+//
+// Free all onbects connected to a special camera geometry
+//
+void MagicDomino::Free()
+{
+    if (!fGeomCam)
+        return;
+
+    fPixels->Delete();
+
+    delete fPixels;
+
+    delete fGeomCam;
+}
+
+// ------------------------------------------------------------------------
+//
+// Draw all pixels of the camera
+//  (means apend all pixelobjects to the current pad)
+//
+void MagicDomino::DrawHexagons()
+{
+    for (UInt_t i=0; i<fNumPixels; i++)
+        (*this)[i].Draw();
+}
+
+// ------------------------------------------------------------------------
+//
+// Change camera from Magic to CT1 and back
+//
+void MagicDomino::ChangeCamera()
+{
+    static Bool_t ct1=kFALSE;
+
+    cout << "Change to " << (ct1?"Magic":"CT1") << endl;
+
+    if (ct1)
+        SetNewCamera(new MGeomCamMagic);
+    else
+        SetNewCamera(new MGeomCamCT1);
+
+    ct1 = !ct1;
+
+    Reset();
+    DrawHexagons();
+}
+
+// ------------------------------------------------------------------------
+//
+// Reset/set all veriables needed for a new camera geometry
+//
+void MagicDomino::SetNewCamera(MGeomCam *geom)
+{
+    Free();
+
+    //
+    //  Reset the display geometry
+    //
+    fW=0;
+    fH=0;
+
+    //
+    //  Set new camera
+    //
+    fGeomCam = geom;
+
+    //
+    //  create the hexagons of the display
+    //
+    fNumPixels = fGeomCam->GetNumPixels();
+    fRange     = fGeomCam->GetMaxRadius();
+
+    //
+    // Construct all hexagons. Use new-operator with placement
+    //
+    fPixels = new TClonesArray("MHexagon", fNumPixels);
+
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        MHexagon &h = *new ((*fPixels)[i]) MHexagon((*fGeomCam)[i]);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        h.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// remove the pixel numbers in the tile from the pad
+//
+void MagicDomino::RemoveNumbers()
+{
+    for (int i=0; i<6; i++)
+        if (fText[i])
+        {
+            delete fText[i];
+            fText[i] = NULL;
+        }
+}
+
+// ------------------------------------------------------------------------
+//
+// Reset/restart the game
+//
+void MagicDomino::Reset()
+{
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        MHexagon &h = (*this)[i];
+        h.SetFillColor(kBackground);
+        h.ResetBit(kUserBits);
+    }
+
+
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fDrawingPad->SetBit(kNoContextMenu);
+    SetBit(kNoContextMenu);
+#endif
+
+    if (fDone)
+    {
+        delete fDone;
+        fDone = NULL;
+    }
+
+
+    fDrawingPad->SetFillColor(22);
+
+    fNumPixel = -1;
+    fNumTile  =  0;
+    fPoints   =  0;
+
+    NewTile();
+}
+
+// ------------------------------------------------------------------------
+//
+//  default constructor
+//
+MagicDomino::MagicDomino()
+    : fGeomCam(NULL), fDir(kBottom), fDone(NULL)
+{
+    memset(fText, 0, sizeof(fText));
+
+    SetNewCamera(new MGeomCamMagic);
+
+    //
+    // Make sure, that the object is destroyed when the canvas/pad is
+    // destroyed. Make also sure, that the interpreter doesn't try to
+    // delete it a second time.
+    //
+    SetBit(kCanDelete);
+    gInterpreter->DeleteGlobal(this);
+
+    Draw();
+}
+
+// ------------------------------------------------------------------------
+//
+// Destructor. Deletes TClonesArrays for hexagons and legend elements.
+//
+MagicDomino::~MagicDomino()
+{
+    Free();
+
+    RemoveNumbers();
+
+    if (fDrawingPad->GetListOfPrimitives()->FindObject(this)==this)
+    {
+        fDrawingPad->RecursiveRemove(this);
+        delete fDrawingPad;
+    }
+
+}
+
+// ------------------------------------------------------------------------
+//
+// This is called at any time the canvas should get repainted.
+// Here we maintain an aspect ratio of 5/4=1.15. This makes sure,
+// that the camera image doesn't get distorted by resizing the canvas.
+//
+void MagicDomino::Paint(Option_t *opt)
+{
+    const UInt_t w = (UInt_t)(gPad->GetWw()*gPad->GetAbsWNDC());
+    const UInt_t h = (UInt_t)(gPad->GetWh()*gPad->GetAbsHNDC());
+
+    //
+    // Check for a change in width or height, and make sure, that the
+    // first call also sets the range
+    //
+    if (w*fH == h*fW && fW && fH)
+        return;
+
+    //
+    // Calculate aspect ratio (5/4=1.25 recommended)
+    //
+    const Double_t ratio = (Double_t)w/h;
+
+    Float_t x;
+    Float_t y;
+
+    if (ratio>1.0)
+    {
+        x = fRange*(ratio*2-1);
+        y = fRange;
+    }
+    else
+    {
+        x = fRange;
+        y = fRange/ratio;
+    }
+
+    fH = h;
+    fW = w;
+
+    //
+    // Set new range
+    //
+    fDrawingPad->Range(-fRange, -y, x, y);
+}
+
+// ------------------------------------------------------------------------
+//
+// Call this function to draw the camera layout into your canvas.
+// Setup a drawing canvas. Add this object and all child objects
+// (hexagons, etc) to the current pad. If no pad exists a new one is
+// created.
+//
+void MagicDomino::Draw(Option_t *option)
+{
+    //
+    // if no canvas is yet existing to draw into, create a new one
+    //
+    /*TCanvas *c =*/ new TCanvas("MagicDomino", "Magic Domino Next Neighbours", 0, 0, 800, 800);
+    //c->ToggleEventStatus();
+
+    fDrawingPad = gPad;
+    fDrawingPad->SetBorderMode(0);
+
+    //
+    // Append this object, so that the aspect ratio is maintained
+    // (Paint-function is called)
+    //
+    AppendPad(option);
+
+    //
+    // Reset the game pad
+    //
+    Reset();
+    DrawHexagons();
+
+    /*
+     TPave *p = new TPave(-0.66*fRange, 0.895*fRange, 0.66*fRange, 0.995*fRange, 4, "br");
+     p->ConvertNDCtoPad();
+     p->SetFillColor(12);
+     p->SetBit(kCanDelete);
+     p->Draw();
+     */
+
+    fDomino.SetTextAlign(23);   // centered/bottom
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fDomino.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    fDomino.Draw();
+}
+
+void MagicDomino::Update()
+{
+    TString txt = "Points: ";
+    txt += fPoints;
+    txt += "  Tile: ";
+    txt += fNumTile;
+
+    switch (fSkipped)
+    {
+    case 0:
+        fDomino.SetTextColor(8/*kGreen*/);
+        break;
+    case 1:
+        fDomino.SetTextColor(kYellow);
+        break;
+    case 2:
+        fDomino.SetTextColor(kRed);
+        break;
+    default:
+        fDomino.SetTextColor(kWhite);
+        break;
+    }
+    fDomino.SetText(0, fRange, txt);
+}
+
+// ------------------------------------------------------------------------
+//
+// Choose new colors for the tile
+//
+void MagicDomino::NewColors()
+{
+    TRandom rnd(0);
+    for (int i=0; i<3; i++)
+    {
+        Int_t color = (Int_t)rnd.Uniform(5)+2;
+        fNewColors[i*2]   = color;
+        fNewColors[i*2+1] = color;
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// Create a new tile
+//
+void MagicDomino::NewTile()
+{
+    if (fNumPixel>=0)
+    {
+        const MGeomPix &pix=(*fGeomCam)[fNumPixel];
+        (*this)[fNumPixel].ResetBit(kIsTile);
+        for (int i=0; i<pix.GetNumNeighbors(); i++)
+            (*this)[pix.GetNeighbor(i)].ResetBit(kIsTile);
+
+        fPoints += pix.GetNumNeighbors();
+    }
+
+    RemoveNumbers();
+
+    fNumPixel = -1;
+    fSkipped  =  0;
+    fNumTile++;
+
+    NewColors();
+    Update();
+
+    fDrawingPad->Update();
+}
+
+// ------------------------------------------------------------------------
+//
+//  Check for at least one correct color for each pixel in tile.
+//  Ignore the tile itself and all background pixels. Check whether
+//  background of tile is empty.
+//
+Bool_t MagicDomino::CheckTile()
+{
+    if (fNumPixel<0)
+        return kFALSE;
+
+    for (int i=0; i<7; i++)
+        if (fOldColors[i]!=kBackground)
+            return kFALSE;
+
+    Int_t cnt=0;
+    const MGeomPix &pix1=(*fGeomCam)[fNumPixel];
+    for (int i=0; i<pix1.GetNumNeighbors(); i++)
+    {
+        const Int_t idx1 = pix1.GetNeighbor(i);
+        const MGeomPix &pix2 = (*fGeomCam)[idx1];
+
+        Byte_t ignored = 0;
+        Byte_t found   = 0;
+        for (int j=0; j<pix2.GetNumNeighbors(); j++)
+        {
+            const Int_t    idx2 = pix2.GetNeighbor(j);
+            const MHexagon &hex = (*this)[idx2];
+
+            if (hex.TestBit(kIsTile) || hex.GetFillColor()==kBackground)
+            {
+                ignored++;
+                continue;
+            }
+
+            if (hex.GetFillColor()==(*this)[idx1].GetFillColor())
+                found++;
+        }
+        if (ignored==pix2.GetNumNeighbors() || found>0)
+            cnt++;
+    }
+
+    return cnt==pix1.GetNumNeighbors();
+}
+
+// ------------------------------------------------------------------------
+//
+// Game over!
+//
+void MagicDomino::Done()
+{
+    fDone = new TText(0, 0, "Game Over!");
+    fDone->SetTextColor(kWhite);  // white
+    fDone->SetTextAlign(22);  // centered/centered
+    fDone->SetTextSize(0.05); // white
+    fDone->Draw();
+
+    fDomino.SetTextColor(kBlue);
+
+    fDrawingPad->SetFillColor(kRed);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fDone->SetBit(kNoContextMenu|kCannotPick);
+    fDrawingPad->ResetBit(kNoContextMenu);
+    ResetBit(kNoContextMenu);
+#endif
+
+    fDrawingPad->Modified();
+    fDrawingPad->Update();
+}
+
+// ------------------------------------------------------------------------
+//
+// Execute a mouse event on the camera
+//
+void MagicDomino::ExecuteEvent(Int_t event, Int_t keycode, Int_t keysym)
+{
+    if (event!=kKeyPress || fDone)
+        return;
+
+    switch (keysym)
+    {
+    case kKey_Escape:
+        fPoints -= 6;
+        fSkipped++;
+        if (fSkipped==3)
+        {
+            Done();
+            return;
+        }
+        NewColors();
+        RotateTile(0);
+        return;
+
+    case kKey_Space:
+        RotateTile(-1);
+        return;
+
+    case kKey_Return:
+        if (CheckTile())
+            NewTile();
+        return;
+
+    case kKey_Right:
+        fDir = kRight;
+        Step(kRight);
+        return;
+
+    case kKey_Left:
+        fDir = kLeft;
+        Step(kLeft);
+        return;
+
+    case kKey_Up:
+        Step(kTop|fDir);
+        return;
+
+    case kKey_Down:
+        Step(kBottom|fDir);
+        return;
+
+    case kKey_Plus:
+        RotateTile(+1);
+        return;
+
+    case kKey_Minus:
+        RotateTile(-1);
+        return;
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// Rotate the colors in the tile
+//
+void MagicDomino::RotateTile(Int_t add)
+{
+    fPosition += add+6;  // Make result positive
+    fPosition %= 6;      // Align result between 0 and 5
+
+    HideTile();
+    ShowTile();
+
+    Update();
+
+    fDrawingPad->Modified();
+    fDrawingPad->Update();
+}
+
+// ------------------------------------------------------------------------
+//
+// Hide the tile from the pad
+//
+void MagicDomino::HideTile()
+{
+    if (fNumPixel<0)
+        return;
+
+    MagicDomino &This = *this;
+
+    RemoveNumbers();
+
+    const MGeomPix &pix1=(*fGeomCam)[fNumPixel];
+    This[fNumPixel].SetFillColor(fOldColors[6]);
+    This[fNumPixel].ResetBit(kIsTile);
+    for (int i=0; i<pix1.GetNumNeighbors(); i++)
+    {
+        Int_t idx = pix1.GetNeighbor(i);
+
+        This[idx].SetFillColor(fOldColors[i]);
+        This[idx].ResetBit(kIsTile);
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// Show the tile on the pad
+//
+void MagicDomino::ShowTile()
+{
+    if (fNumPixel<0)
+        return;
+
+    MagicDomino &This = *this;
+
+    Int_t indices[6];
+    GetSortedNeighbors(indices);
+
+    RemoveNumbers();
+
+    const MGeomPix &pix2=(*fGeomCam)[fNumPixel];
+    fOldColors[6] = This[fNumPixel].GetFillColor();
+    This[fNumPixel].SetFillColor(kBlack);
+    This[fNumPixel].SetBit(kIsTile);
+    for (int i=0; i<pix2.GetNumNeighbors(); i++)
+    {
+        Int_t idx = pix2.GetNeighbor(i);
+
+        fOldColors[i] = This[idx].GetFillColor();
+
+        int j=0;
+        while (indices[j]!=i)
+            j++;
+
+        This[idx].SetFillColor(fNewColors[(j+fPosition)%6]);
+        This[idx].SetBit(kIsTile);
+
+        TString num;
+        num += idx;
+
+        fText[i] = new TText(This[idx].GetX(), This[idx].GetY(), num);
+        fText[i]->SetTextSize(0.3*This[idx].GetD()/fGeomCam->GetMaxRadius());
+        fText[i]->SetTextFont(122);
+        fText[i]->SetTextAlign(22);   // centered/centered
+        fText[i]->Draw();
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// Hide the tile, change its position, show it again, update status text
+//
+void MagicDomino::ChangePixel(Int_t add)
+{
+    HideTile();
+
+    fNumPixel = add;
+
+    ShowTile();
+
+    Update();
+
+    fDrawingPad->Update();
+}
+
+// ------------------------------------------------------------------------
+//
+// Analyse the directions of the next neighbors
+//
+Short_t MagicDomino::AnalysePixel(Int_t dir)
+{
+    const MGeomPix &pix=(*fGeomCam)[fNumPixel<0?0:fNumPixel];
+
+    Double_t fAngle[6] = { -10, -10, -10, -10, -10, -10 };
+
+    for (int i=0; i<pix.GetNumNeighbors(); i++)
+    {
+        MGeomPix &next = (*fGeomCam)[pix.GetNeighbor(i)];
+        fAngle[i] = atan2(next.GetY()-pix.GetY(), next.GetX()-pix.GetX());
+    }
+
+    Int_t indices[6];
+    TMath::Sort(6, fAngle, indices); // left, top, right, bottom
+
+    for (int i=0; i<pix.GetNumNeighbors(); i++)
+    {
+        const Int_t    idx   = pix.GetNeighbor(indices[i]);
+        const Double_t angle = fAngle[indices[i]]*180/TMath::Pi();
+
+        if (angle<-149 && dir==kLeft)
+            return idx;
+        if (angle>-149 && angle<-90 && dir==kBottomLeft)
+            return idx;
+        //if (angle==-90 && dir==kBottom)
+        //    return idx;
+        if (angle>-90 && angle<-31 && dir==kBottomRight)
+            return idx;
+        if (angle>-31 && angle<31 && dir==kRight)
+            return idx;
+        if (angle>31 && angle<90 && dir==kTopRight)
+            return idx;
+        //if (angle==90 && dir==kTop)
+        //    return idx;
+        if (angle>90 && angle<149 && dir==kTopLeft)
+            return idx;
+        if (angle>149 && dir==kLeft)
+            return idx;
+    }
+    return -1;
+}
+
+// ------------------------------------------------------------------------
+//
+// Sort the next neighbort from the left, top, right, bottom
+//
+void MagicDomino::GetSortedNeighbors(Int_t indices[6])
+{
+    const MGeomPix &pix=(*fGeomCam)[fNumPixel<0?0:fNumPixel];
+
+    Double_t fAngle[6] = { -10, -10, -10, -10, -10, -10 };
+
+    for (int i=0; i<pix.GetNumNeighbors(); i++)
+    {
+        MGeomPix &next = (*fGeomCam)[pix.GetNeighbor(i)];
+        fAngle[i] = atan2(next.GetY()-pix.GetY(), next.GetX()-pix.GetX());
+    }
+
+    TMath::Sort(6, fAngle, indices); // left, top, right, bottom
+}
+
+// ------------------------------------------------------------------------
+//
+// Move tile one step in the given direction
+//
+void MagicDomino::Step(Int_t dir)
+{
+    Short_t newidx = AnalysePixel(dir);
+    if (newidx<0)
+        return;
+    ChangePixel(newidx);
+}
+
Index: /trunk/MagicSoft/Mars/mtools/MagicDomino.h
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MagicDomino.h	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MagicDomino.h	(revision 1435)
@@ -0,0 +1,101 @@
+#ifndef MARS_MagicDomino
+#define MARS_MagicDomino
+
+#ifndef MARS_MAGIC
+#include "MAGIC.h"
+#endif
+
+#ifndef ROOT_TText
+#include <TText.h>
+#endif
+#ifndef ROOT_TClonesArray
+#include <TClonesArray.h>
+#endif
+
+class TMarker;
+class TVirtualPad;
+
+class MGeomCam;
+class MHexagon;
+
+class MagicDomino : public TObject
+{
+private:
+    enum
+    {
+        kBackground  = 50,
+        kIsTile      = BIT(17),
+        kRight       = BIT(18),
+        kLeft        = BIT(19),
+        kTop         = BIT(20),
+        kBottom      = BIT(21),
+        kUserBits    = 0x0000ff00, // 14-23 are allowed
+
+        kBottomLeft  = kBottom|kLeft,
+        kBottomRight = kBottom|kRight,
+        kTopLeft     = kTop|kLeft,
+        kTopRight    = kTop|kRight
+
+    };
+
+    MGeomCam *fGeomCam;         // pointer to camera geometry
+
+    UShort_t  fNumPixels;       // number of pixels in the present geometry
+    Short_t   fNumPixel;        // number of actual pixel
+    Int_t     fNumTile;         // number of setteled tiles
+    Float_t   fRange;           // the range in millimeters of the present geometry
+
+    Int_t     fPoints;          // points you got
+
+    Int_t     fDir;             // direction you move the tile
+
+    Int_t     fOldColors[7];    // colors of hexagons which are under the tile
+    Int_t     fNewColors[6];    // colors of the tile itself
+    Byte_t    fPosition;        // rotation position of colors in tile
+    Byte_t    fSkipped;         // number of skipped tiles
+
+    TText     fDomino;          // TText showing status informations
+    TText    *fText[6];         // ttext showing the six numbers in the tile
+    TText    *fDone;            // game over text
+
+    UInt_t    fW;               // Width of canvas
+    UInt_t    fH;               // Height of canvas
+
+    TClonesArray *fPixels;      // array of all hexagons
+    TVirtualPad  *fDrawingPad;  // pad in which we are drawing
+
+    MHexagon &operator[](int i) { return *((MHexagon*)fPixels->At(i)); }
+
+    Bool_t  CheckTile();
+    void    NewTile();
+    void    NewColors();
+    void    HideTile();
+    void    ShowTile();
+    void    RotateTile(Int_t add);
+    void    Update();
+    void    Free();
+    void    Done();
+    void    RemoveNumbers();
+    void    DrawHexagons();
+    void    SetNewCamera(MGeomCam *);
+    void    ChangePixel(Int_t add);
+    void    Step(Int_t dir);
+    Short_t AnalysePixel(Int_t dir);
+    void    GetSortedNeighbors(Int_t indices[6]);
+
+    void  Draw(Option_t *option="");
+    void  Paint(Option_t *option="");
+    void  ExecuteEvent(Int_t event, Int_t px, Int_t py);
+    Int_t DistancetoPrimitive(Int_t px, Int_t py) { return 0; }
+
+public:
+    MagicDomino();
+    ~MagicDomino();
+
+    void Reset();        //*MENU*
+    void ChangeCamera(); //*MENU*
+
+    ClassDef(MagicDomino, 0) // Tool to visualize next neighbours
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mtools/MagicShow.cc
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MagicShow.cc	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MagicShow.cc	(revision 1435)
@@ -0,0 +1,421 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 07/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MagicShow
+// ---------
+//
+// Tool to visualize Next Neighbours.
+//
+// Start the show by:
+//   MagicShow show;
+//
+// Use the following keys:
+// -----------------------
+//
+//   * Space:
+//     Toggle between auto increment and manual increment
+//
+//   * Right/Left:
+//     Increment/Decrement pixel number by 1
+//
+//   * Right/Left:
+//     Increment/Decrement pixel number by 1
+//
+//   * Up/Down:
+//     Increment/Decrement pixel number by 10
+//
+//   * PageUp/PageDown:
+//     Increment/Decrement pixel number by 100
+//
+//   * Home/End:
+//     Jump to first/last pixel
+//
+////////////////////////////////////////////////////////////////////////////
+#include "MagicShow.h"
+
+#include <iostream.h>
+
+#include <KeySymbols.h>
+
+#include <TCanvas.h>
+#include <TInterpreter.h>
+
+#include "MHexagon.h"
+
+#include "MGeomPix.h"
+#include "MGeomCamCT1.h"
+#include "MGeomCamMagic.h"
+
+ClassImp(MagicShow);
+
+// ------------------------------------------------------------------------
+//
+// Free all onbects connected to a special camera geometry
+//
+void MagicShow::Free()
+{
+    if (!fGeomCam)
+        return;
+
+    fPixels->Delete();
+
+    delete fPixels;
+
+    delete fGeomCam;
+}
+
+// ------------------------------------------------------------------------
+//
+// Draw all pixels of the camera
+//  (means apend all pixelobjects to the current pad)
+//
+void MagicShow::DrawHexagons()
+{
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        MHexagon &h = (*this)[i];
+
+        h.SetFillColor(kBackground);
+        h.Draw();
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// Change camera from Magic to CT1 and back
+//
+void MagicShow::ChangeCamera()
+{
+    static Bool_t ct1=kFALSE;
+
+    cout << "Change to " << (ct1?"Magic":"CT1") << endl;
+
+    if (ct1)
+        SetNewCamera(new MGeomCamMagic);
+    else
+        SetNewCamera(new MGeomCamCT1);
+
+    ct1 = !ct1;
+
+    DrawHexagons();
+}
+
+// ------------------------------------------------------------------------
+//
+// Reset/set all veriables needed for a new camera geometry
+//
+void MagicShow::SetNewCamera(MGeomCam *geom)
+{
+    Free();
+
+    //
+    //  Reset the display geometry
+    //
+    fW=0;
+    fH=0;
+
+    //
+    //  Set new camera
+    //
+    fGeomCam = geom;
+
+    //
+    //  create the hexagons of the display
+    //
+    fNumPixels = fGeomCam->GetNumPixels();
+    fRange     = fGeomCam->GetMaxRadius();
+
+    fNumPixel  = fNumPixels-1;
+
+    //
+    // Construct all hexagons. Use new-operator with placement
+    //
+    fPixels = new TClonesArray("MHexagon", fNumPixels);
+
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        MHexagon &h = *new ((*fPixels)[i]) MHexagon((*fGeomCam)[i]);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        h.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+//  default constructor
+//
+MagicShow::MagicShow()
+    : fTimer(this, 250, kTRUE), fGeomCam(NULL), fNumPixel(-1), fAuto(kTRUE), fW(0), fH(0)
+{
+    SetNewCamera(new MGeomCamMagic);
+
+    memset(fText, 0, sizeof(fText));
+
+    //
+    // Make sure, that the object is destroyed when the canvas/pad is
+    // destroyed. Make also sure, that the interpreter doesn't try to
+    // delete it a second time.
+    //
+    SetBit(kCanDelete);
+    gInterpreter->DeleteGlobal(this);
+
+    Draw();
+
+    fTimer.TurnOn();
+}
+
+// ------------------------------------------------------------------------
+//
+// Destructor. Deletes TClonesArrays for hexagons and legend elements.
+//
+MagicShow::~MagicShow()
+{
+    Free();
+
+    for (int i=0; i<6; i++)
+        if (fText[i])
+            delete fText[i];
+
+    if (fDrawingPad->GetListOfPrimitives()->FindObject(this)==this)
+    {
+        fDrawingPad->RecursiveRemove(this);
+        delete fDrawingPad;
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// This is called at any time the canvas should get repainted.
+// Here we maintain an aspect ratio of 5/4=1.15. This makes sure,
+// that the camera image doesn't get distorted by resizing the canvas.
+//
+void MagicShow::Paint(Option_t *opt)
+{
+    const UInt_t w = (UInt_t)(gPad->GetWw()*gPad->GetAbsWNDC());
+    const UInt_t h = (UInt_t)(gPad->GetWh()*gPad->GetAbsHNDC());
+
+    //
+    // Check for a change in width or height, and make sure, that the
+    // first call also sets the range
+    //
+    if (w*fH == h*fW && fW && fH)
+        return;
+
+    //
+    // Calculate aspect ratio (5/4=1.25 recommended)
+    //
+    const Double_t ratio = (Double_t)w/h;
+
+    Float_t x;
+    Float_t y;
+
+    if (ratio>1.0)
+    {
+        x = fRange*(ratio*2-1);
+        y = fRange;
+    }
+    else
+    {
+        x = fRange;
+        y = fRange/ratio;
+    }
+
+    fH = h;
+    fW = w;
+
+    //
+    // Set new range
+    //
+    fDrawingPad->Range(-fRange, -y, x, y);
+}
+
+// ------------------------------------------------------------------------
+//
+// Call this function to draw the camera layout into your canvas.
+// Setup a drawing canvas. Add this object and all child objects
+// (hexagons, etc) to the current pad. If no pad exists a new one is
+// created.
+//
+void MagicShow::Draw(Option_t *option)
+{
+    //
+    // if no canvas is yet existing to draw into, create a new one
+    //
+    /*TCanvas *c =*/ new TCanvas("MagicShow", "Magic Show Next Neighbours", 0, 0, 800, 800);
+    //c->ToggleEventStatus();
+
+    fDrawingPad = gPad;
+    fDrawingPad->SetBorderMode(0);
+    fDrawingPad->SetFillColor(22);
+
+    //
+    // Append this object, so that the aspect ratio is maintained
+    // (Paint-function is called)
+    //
+    AppendPad(option);
+
+    //
+    // Reset the game pad
+    //
+    DrawHexagons();
+
+    fShow.SetTextAlign(23);   // centered/bottom
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fShow.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    fShow.Draw();
+}
+
+// ------------------------------------------------------------------------
+//
+// Update Status text
+//
+void MagicShow::Update()
+{
+    TString txt = "Pixels: ";
+    txt += fNumPixels;
+    txt += "  Pixel: ";
+    txt += fNumPixel;
+
+    if (fAuto)
+        txt += "  (auto)";
+
+    fShow.SetText(0, fRange, txt);
+}
+
+// ------------------------------------------------------------------------
+//
+// Execute a mouse event on the camera
+//
+void MagicShow::ExecuteEvent(Int_t event, Int_t keycode, Int_t keysym)
+{
+    if (event!=kKeyPress)
+        return;
+
+    switch (keysym)
+    {
+    case kKey_Space:
+        fAuto = !fAuto;
+        Update();
+        fDrawingPad->Update();
+        return;
+
+    case kKey_Right:
+        ChangePixel(+1);
+        return;
+
+    case kKey_Left:
+        ChangePixel(-1);
+        return;
+
+    case kKey_Up:
+        ChangePixel(+10);
+        return;
+
+    case kKey_Down:
+        ChangePixel(-10);
+        return;
+
+    case kKey_PageUp:
+        ChangePixel(+100);
+        return;
+
+    case kKey_PageDown:
+        ChangePixel(-100);
+        return;
+
+    case kKey_Home:
+        ChangePixel(-fNumPixel);
+        return;
+
+    case kKey_End:
+        ChangePixel(fNumPixels-fNumPixel-1);
+        return;
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// Change the shown pixel by add indices
+//
+void MagicShow::ChangePixel(Int_t add)
+{
+    MagicShow &This = *this;
+
+    const MGeomPix &pix1=(*fGeomCam)[fNumPixel];
+    This[fNumPixel].SetFillColor(kBackground);
+    for (int i=0; i<pix1.GetNumNeighbors(); i++)
+    {
+        This[pix1.GetNeighbor(i)].SetFillColor(kBackground);
+        if (!fText[i])
+            continue;
+
+        delete fText[i];
+        fText[i] = NULL;
+    }
+
+    fNumPixel += add;
+
+    if (fNumPixel>=fNumPixels)
+        fNumPixel = 0;
+    if (fNumPixel<0)
+        fNumPixel = fNumPixels-1;
+
+    const MGeomPix &pix2=(*fGeomCam)[fNumPixel];
+    This[fNumPixel].SetFillColor(kBlue);
+    for (int i=0; i<pix2.GetNumNeighbors(); i++)
+    {
+        Int_t idx = pix2.GetNeighbor(i);
+
+        This[idx].SetFillColor(kMagenta);
+
+        TString num;
+        num += idx;
+
+        fText[i] = new TText(This[idx].GetX(), This[idx].GetY(), num);
+        fText[i]->SetTextSize(0.3*This[idx].GetD()/fGeomCam->GetMaxRadius());
+        fText[i]->SetTextFont(122);
+        fText[i]->SetTextAlign(22);   // centered/centered
+        fText[i]->Draw();
+    }
+
+    Update();
+
+    fDrawingPad->Update();
+}
+
+// ------------------------------------------------------------------------
+//
+// If automatic is switched on step one pixel forward
+//
+Bool_t MagicShow::HandleTimer(TTimer *timer)
+{
+    if (fAuto)
+        ChangePixel(+1);
+
+    return kTRUE;
+}
Index: /trunk/MagicSoft/Mars/mtools/MagicShow.h
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MagicShow.h	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MagicShow.h	(revision 1435)
@@ -0,0 +1,76 @@
+#ifndef MARS_MagicShow
+#define MARS_MagicShow
+
+#ifndef MARS_MAGIC
+#include "MAGIC.h"
+#endif
+
+#ifndef ROOT_TText
+#include <TText.h>
+#endif
+#ifndef ROOT_TTimer
+#include <TTimer.h>
+#endif
+#ifndef ROOT_TClonesArray
+#include <TClonesArray.h>
+#endif
+
+class TMarker;
+class TVirtualPad;
+
+class MGeomCam;
+class MHexagon;
+
+class MagicShow : public TObject
+{
+private:
+    enum
+    {
+        kBackground = 50,
+        kUserBits   = 0x0000ff00, // 14-23 are allowed
+
+    };
+
+    TTimer    fTimer;           // timer rising the 500ms interrputs
+
+    MGeomCam *fGeomCam;         // pointer to camera geometry
+
+    UShort_t  fNumPixels;       // number of pixels in the present geometry
+    Short_t   fNumPixel;        // number of pixel actually shown
+    Float_t   fRange;           // the range in millimeters of the present geometry
+
+    Bool_t    fAuto;            // automatic stepping on/off
+
+    TText     fShow;            // TText showing the numbers of pixels and bombs
+    TText    *fText[6];         // ttext showing the pixel numbers of the neighbors
+
+    UInt_t    fW;               // Width of canvas
+    UInt_t    fH;               // Height of canvas
+
+    TClonesArray *fPixels;      // array of all hexagons
+    TVirtualPad  *fDrawingPad;  // pad in which we are drawing
+
+    MHexagon &operator[](int i) { return *((MHexagon*)fPixels->At(i)); }
+
+    void   Update();
+    void   Free();
+    void   DrawHexagons();
+    void   SetNewCamera(MGeomCam *);
+    void   ChangePixel(Int_t add);
+
+    Bool_t HandleTimer(TTimer *timer);
+    void   Draw(Option_t *option="");
+    void   Paint(Option_t *option="");
+    void   ExecuteEvent(Int_t event, Int_t px, Int_t py);
+    Int_t  DistancetoPrimitive(Int_t px, Int_t py) { return 0; }
+
+public:
+    MagicShow();
+    ~MagicShow();
+
+    void ChangeCamera(); //*MENU*
+
+    ClassDef(MagicShow, 0) // Tool to visualize next neighbours
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mtools/MagicSnake.cc
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MagicSnake.cc	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MagicSnake.cc	(revision 1435)
@@ -0,0 +1,628 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 07/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MagicSnake
+// ----------
+//
+// Camera Display Games: Snake
+//
+// Start the game by:
+//   MagicSnake snake;
+//
+// Controll the worm using right/left. Make sure, that the mouse pointer
+// is inside the canvas.
+//
+// Move the mouse pointer outside the canvas to pause the game.
+//
+// The pixel colors have the following meaning:
+// --------------------------------------------
+//  Green:   Food, collect all packages.
+//  Red:     Bombs, don't touch it!
+//  Yellow:  Transport, try it.
+//  Magenta: Home, touch it to win the game.
+//
+// To restart the game use the context menu. It can only be accessed if
+// the game has been stopped (either because you win the game or because
+// you hit a bomb) With the context menu you can also toggle between
+// different camera layouts.
+//
+////////////////////////////////////////////////////////////////////////////
+#include "MagicSnake.h"
+
+#include <iostream.h>
+
+#include <KeySymbols.h>
+
+#include <TColor.h>
+#include <TCanvas.h>
+#include <TMarker.h>
+#include <TRandom.h>
+#include <TInterpreter.h>
+
+#include "MHexagon.h"
+
+#include "MGeomPix.h"
+#include "MGeomCamCT1.h"
+#include "MGeomCamMagic.h"
+
+ClassImp(MagicSnake);
+
+void MagicSnake::Free()
+{
+    if (!fGeomCam)
+        return;
+
+    fPixels->Delete();
+
+    delete fPixels;
+
+    delete fGeomCam;
+
+    delete fArray;
+}
+
+// ------------------------------------------------------------------------
+//
+// Draw all pixels of the camera
+//  (means apend all pixelobjects to the current pad)
+//
+void MagicSnake::DrawHexagons()
+{
+    for (UInt_t i=0; i<fNumPixels; i++)
+        (*this)[i].Draw();
+}
+
+void MagicSnake::ChangeCamera()
+{
+    if (!fDone)
+        Done("Changing Camera...", 22);
+
+    static Bool_t ct1=kFALSE;
+
+    cout << "Change to " << (ct1?"Magic":"CT1") << endl;
+
+    if (ct1)
+        SetNewCamera(new MGeomCamMagic);
+    else
+        SetNewCamera(new MGeomCamCT1);
+
+    ct1 = !ct1;
+
+    Reset();
+    DrawHexagons();
+}
+
+void MagicSnake::SetNewCamera(MGeomCam *geom)
+{
+    Free();
+
+    //
+    //  Reset the display geometry
+    //
+    fW=0;
+    fH=0;
+
+    //
+    //  Set new camera
+    //
+    fGeomCam = geom;
+
+    //
+    //  create the hexagons of the display
+    //
+    fNumPixels = fGeomCam->GetNumPixels();
+    fRange     = fGeomCam->GetMaxRadius();
+
+    //
+    // Construct all hexagons. Use new-operator with placement
+    //
+    fPixels = new TClonesArray("MHexagon", fNumPixels);
+
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        MHexagon &h = *new ((*fPixels)[i]) MHexagon((*fGeomCam)[i]);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        h.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+//  default constructor
+//
+MagicSnake::MagicSnake()
+    : fTimer(this, 500, kTRUE), fGeomCam(NULL), fDone(NULL), fPaused(NULL), fW(0), fH(0)
+{
+    SetNewCamera(new MGeomCamMagic);
+
+    //
+    // Make sure, that the object is destroyed when the canvas/pad is
+    // destroyed. Make also sure, that the interpreter doesn't try to
+    // delete it a second time.
+    //
+    SetBit(kCanDelete);
+    gInterpreter->DeleteGlobal(this);
+
+    Draw();
+
+    Pause();
+
+    fTimer.TurnOn();
+}
+
+void MagicSnake::Pause(Bool_t yes=kTRUE)
+{
+    if (yes && !fPaused)
+    {
+        fPaused = new TText(0, 0, "Paused!");
+        fPaused->SetTextColor(kWhite);
+        fPaused->SetTextAlign(22);
+        fPaused->SetTextSize(0.05); // white
+        fPaused->Draw();
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        fPaused->SetBit(kNoContextMenu|kCannotPick);
+        fDrawingPad->ResetBit(kNoContextMenu);
+        ResetBit(kNoContextMenu);
+#endif
+        fDrawingPad->Update();
+    }
+
+    if (yes)
+        return;
+
+    if (!fDone)
+    {
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        fDrawingPad->SetBit(kNoContextMenu);
+        SetBit(kNoContextMenu);
+#endif
+    }
+    if (!fPaused)
+        return;
+
+    Remove(fPaused);
+
+    fDrawingPad->Update();
+
+    delete fPaused;
+    fPaused=NULL;
+}
+
+// ------------------------------------------------------------------------
+//
+// Destructor. Deletes TClonesArrays for hexagons and legend elements.
+//
+MagicSnake::~MagicSnake()
+{
+    Free();
+    Pause(kFALSE);
+
+    if (fDone)
+        delete fDone;
+
+    if (fDrawingPad->GetListOfPrimitives()->FindObject(this)==this)
+    {
+        fDrawingPad->RecursiveRemove(this);
+        delete fDrawingPad;
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// This is called at any time the canvas should get repainted.
+// Here we maintain an aspect ratio of 5/4=1.15. This makes sure,
+// that the camera image doesn't get distorted by resizing the canvas.
+//
+void MagicSnake::Paint(Option_t *opt)
+{
+    const UInt_t w = (UInt_t)(gPad->GetWw()*gPad->GetAbsWNDC());
+    const UInt_t h = (UInt_t)(gPad->GetWh()*gPad->GetAbsHNDC());
+
+    //
+    // Check for a change in width or height, and make sure, that the
+    // first call also sets the range
+    //
+    if (w*fH == h*fW && fW && fH)
+        return;
+
+    //
+    // Calculate aspect ratio (5/4=1.25 recommended)
+    //
+    const Double_t ratio = (Double_t)w/h;
+
+    Float_t x;
+    Float_t y;
+
+    if (ratio>1.0)
+    {
+        x = fRange*(ratio*2-1);
+        y = fRange;
+    }
+    else
+    {
+        x = fRange;
+        y = fRange/ratio;
+    }
+
+    fH = h;
+    fW = w;
+
+    //
+    // Set new range
+    //
+    fDrawingPad->Range(-fRange, -y, x, y);
+}
+
+// ------------------------------------------------------------------------
+//
+// Call this function to draw the camera layout into your canvas.
+// Setup a drawing canvas. Add this object and all child objects
+// (hexagons, etc) to the current pad. If no pad exists a new one is
+// created.
+//
+void MagicSnake::Draw(Option_t *option)
+{
+    //
+    // if no canvas is yet existing to draw into, create a new one
+    //
+    /*TCanvas *c =*/ new TCanvas("MagicSnake", "Magic Snake", 0, 0, 800, 800);
+    //c->ToggleEventStatus();
+
+    fDrawingPad = gPad;
+    fDrawingPad->SetBorderMode(0);
+
+    //
+    // Append this object, so that the aspect ratio is maintained
+    // (Paint-function is called)
+    //
+    AppendPad(option);
+
+    //
+    // Reset the game pad
+    //
+    Reset();
+    DrawHexagons();
+
+    fShow.SetTextAlign(23);   // centered/bottom
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fShow.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    fShow.Draw();
+}
+
+void MagicSnake::Update()
+{
+    TString txt = "Pixels: ";
+    txt += fNumPixels;
+    txt += "  Bombs: ";
+    txt += fNumBombs;
+    txt += "  Food: ";
+    txt += fNumFood;
+
+    fShow.SetText(0, fRange, txt);
+}
+
+// ------------------------------------------------------------------------
+//
+// reset the all pixel colors to a default value
+//
+void MagicSnake::Reset()
+{
+    fDirection = fGeomCam->InheritsFrom("MGeomCamCT1") ? kLeft : kRight;
+    fLength = 2;
+
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        (*this)[i].SetFillColor(kBackground);
+        (*fGeomCam)[i].ResetBit(kUserBits);
+    }
+
+    fNumBombs = fNumPixels/30;
+
+    TRandom rnd(0);
+    for (int i=0; i<fNumBombs; i++)
+    {
+        Int_t idx;
+
+        do idx = (Int_t)rnd.Uniform(fNumPixels);
+        while ((*fGeomCam)[idx].TestBits(kHasBomb|kHasWorm));
+
+        (*fGeomCam)[idx].SetBit(kHasBomb);
+        (*this)[idx].SetFillColor(kRed);
+    }
+
+    fNumFood = fNumPixels/6;
+
+    fArray = new Int_t[fNumFood+3];
+
+    fArray[0] = 0;
+    fArray[1] = 1;
+
+    for (int i=0; i<fNumFood+3; i++)
+    {
+        Float_t f = (float)i/(fNumFood+3);
+        gROOT->GetColor(51+i)->SetRGB(f, f, f);
+    }
+    for (int i=0; i<fNumFood; i++)
+    {
+        Int_t idx;
+
+        do idx = (Int_t)rnd.Uniform(fNumPixels);
+        while ((*fGeomCam)[idx].TestBits(kHasBomb|kHasFood|kHasWorm));
+
+        (*fGeomCam)[idx].SetBit(kHasFood);
+        (*this)[idx].SetFillColor(kGreen);
+    }
+
+    SetWormColor();
+
+    for (int i=0; i<2; i++)
+    {
+        Int_t idx;
+
+        do idx = (Int_t)rnd.Uniform(fNumPixels);
+        while ((*fGeomCam)[idx].TestBits(kHasBomb|kHasFood|kHasWorm|kHasTransport));
+
+        fTransport[i] = idx;
+        (*fGeomCam)[idx].SetBit(kHasTransport);
+        (*this)[idx].SetFillColor(kYellow);
+    }
+
+    fDrawingPad->SetFillColor(22);
+
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fDrawingPad->SetBit(kNoContextMenu);
+    SetBit(kNoContextMenu);
+#endif
+
+    if (!fDone)
+        return;
+
+    delete fDone;
+    fDone = NULL;
+}
+
+void MagicSnake::Done(TString txt, Int_t col)
+{
+    //(*this)[fArray[fLength-1]].SetFillColor(kBlue);
+
+    fDone = new TText(0, 0, txt);
+    fDone->SetTextColor(kWhite);  // white
+    fDone->SetTextAlign(22);  // centered/centered
+    fDone->SetTextSize(0.05); // white
+    fDone->Draw();
+    fDrawingPad->SetFillColor(col);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fDone->SetBit(kNoContextMenu|kCannotPick);
+    fDrawingPad->ResetBit(kNoContextMenu);
+    ResetBit(kNoContextMenu);
+#endif
+}
+
+void MagicSnake::Remove(TObject *obj)
+{
+    fDrawingPad->RecursiveRemove(obj);
+}
+
+// ------------------------------------------------------------------------
+//
+// Execute a mouse event on the camera
+//
+void MagicSnake::ExecuteEvent(Int_t event, Int_t keycode, Int_t keysym)
+{
+    if (event==kMouseEnter || event==kMouseMotion)
+    {
+        Pause(kFALSE);
+        return;
+    }
+
+    if (fDone)
+        return;
+
+    if (event==kMouseLeave)
+    {
+        Pause();
+        return;
+    }
+    if (event!=kKeyPress)
+        return;
+
+    switch (keysym)
+    {
+    case kKey_Left:
+        fDirection --;
+        break;
+
+    case kKey_Right:
+        fDirection ++;
+        break;
+
+    case kKey_Escape:
+        Done("Reset...", 22);
+        Reset();
+        return;
+
+    default:
+        cout << "Keysym=0x" << hex << keysym << endl;
+    }
+
+     if (fDirection < kRightTop)
+         fDirection = kLeftTop;
+     if (fDirection > kLeftTop)
+         fDirection = kRightTop;
+}
+
+void MagicSnake::Step(Int_t newpix)
+{
+    if ((*fGeomCam)[newpix].TestBit(kHasTransport))
+    {
+        (*this)[fArray[0]].SetFillColor(kBackground);
+        (*fGeomCam)[fArray[0]].ResetBit(kHasWorm);
+
+        for (int i=1; i<fLength; i++)
+            fArray[i-1] = fArray[i];
+
+        fArray[fLength-1] = newpix==fTransport[0]?fTransport[1]:fTransport[0];
+
+        return;
+    }
+
+    if (!(*fGeomCam)[newpix].TestBit(kHasFood))
+    {
+        MGeomPix &pix = (*fGeomCam)[fArray[0]];
+
+        if (!pix.TestBit(kHasTransport))
+            if (pix.TestBit(kHasDoor))
+                (*this)[fArray[0]].SetFillColor(kMagenta);
+            else
+                (*this)[fArray[0]].SetFillColor(kBackground);
+
+        pix.ResetBit(kHasWorm);
+
+        for (int i=1; i<fLength; i++)
+            fArray[i-1] = fArray[i];
+
+        fArray[fLength-1] = newpix;
+    }
+    else
+    {
+        fArray[fLength++] = newpix;
+        (*fGeomCam)[newpix].ResetBit(kHasFood);
+
+        fNumFood--;
+
+        if (fNumFood==0)
+            for (int i=1; i<7; i++)
+            {
+                (*this)[i].SetFillColor(kMagenta);
+                (*fGeomCam)[i].SetBit(kHasDoor);
+            }
+    }
+
+    SetWormColor();
+}
+
+void MagicSnake::SetWormColor()
+{
+    for (int i=0; i<fLength; i++)
+    {
+        const Int_t idx = fArray[i];
+
+        MGeomPix &pix = (*fGeomCam)[idx];
+
+        if (pix.TestBit(kHasTransport))
+            continue;
+
+        pix.SetBit(kHasWorm);
+
+        Int_t color = 51+fLength-i;
+        (*this)[idx].SetFillColor(color);
+    }
+}
+
+Int_t MagicSnake::ScanNeighbours()
+{
+    const Int_t first = fArray[fLength-1];
+
+    const MGeomPix &pix=(*fGeomCam)[first];
+
+    Double_t dx = pix.GetX();
+    Double_t dy = pix.GetY();
+
+    Int_t newpix = -1;
+    for (int i=0; i<pix.GetNumNeighbors(); i++)
+    {
+        const Int_t     idx  = pix.GetNeighbor(i);
+        const MGeomPix &next = (*fGeomCam)[idx];
+
+        const Double_t x = next.GetX();
+        const Double_t y = next.GetY();
+
+        switch (fDirection)
+        {
+        case kRightTop:    if (x>=dx && y>dy) { newpix=idx; dy=y; } continue;
+        case kRight:       if (x>dx)          { newpix=idx; dx=x; } continue;
+        case kRightBottom: if (x>=dx && y<dy) { newpix=idx; dy=y; } continue;
+        case kLeftTop:     if (x<=dx && y>dy) { newpix=idx; dy=y; } continue;
+        case kLeft:        if (x<dx)          { newpix=idx; dx=x; } continue;
+        case kLeftBottom:  if (x<=dx && y<dy) { newpix=idx; dy=y; } continue;
+        }
+    }
+
+    if (newpix<0)
+        return -1;
+
+    const MGeomPix &np = (*fGeomCam)[newpix];
+
+    if (fNumFood==0 && np.TestBit(kHasDoor))
+        return -4;
+
+    if (np.TestBit(kHasBomb))
+        return -2;
+
+    if (np.TestBit(kHasWorm))
+        return -3;
+
+    return newpix;
+}
+
+Bool_t MagicSnake::HandleTimer(TTimer *timer)
+{
+    if (fDone || fPaused)
+        return kTRUE;
+
+    const Int_t newpix = ScanNeighbours();
+
+    switch (newpix)
+    {
+    case -1:
+        Done("You crashed! Don't drink and drive!", kRed);
+        break;
+    case -2:
+        Done("Ouch, you found the bomb!", kRed);
+        break;
+    case -3:
+        Done("Argh... don't eat yourself!", kRed);
+        break;
+    case -4:
+        Done("Congratulations! You won the game!", kGreen);
+        break;
+    default:
+        Step(newpix);
+    }
+
+    Update();
+
+    cout << "Update " << flush;
+
+    fDrawingPad->Modified();
+    fDrawingPad->Update();
+
+    cout << "Done." << endl;
+
+    return kTRUE;
+}
Index: /trunk/MagicSoft/Mars/mtools/MagicSnake.h
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MagicSnake.h	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MagicSnake.h	(revision 1435)
@@ -0,0 +1,101 @@
+#ifndef MARS_MagicSnake
+#define MARS_MagicSnake
+
+#ifndef MARS_MAGIC
+#include "MAGIC.h"
+#endif
+
+#ifndef ROOT_TText
+#include <TText.h>
+#endif
+#ifndef ROOT_TTimer
+#include <TTimer.h>
+#endif
+#ifndef ROOT_TClonesArray
+#include <TClonesArray.h>
+#endif
+
+class TMarker;
+class TVirtualPad;
+
+class MGeomCam;
+class MHexagon;
+
+class MagicSnake : public TObject
+{
+private:
+    enum {
+        kRightTop,
+        kRight,
+        kRightBottom,
+        kLeftBottom,
+        kLeft,
+        kLeftTop
+    };
+
+    enum
+    {
+        kBackground   = 50,
+        kHasBomb      = BIT(15),
+        kHasFood      = BIT(16),
+        kHasWorm      = BIT(17),
+        kHasTransport = BIT(18),
+        kHasDoor      = BIT(19),
+        kUserBits     = 0x0000ff00, // 14-23 are allowed
+
+    };
+
+    Byte_t    fLength;          // actual length of worm
+    Int_t    *fArray;           // inices of pixels which are 'wormed'
+    Char_t    fDirection;       // actual direction of worm
+
+    TTimer    fTimer;           // timer rising the 500ms interrputs
+
+    MGeomCam *fGeomCam;         // pointer to camera geometry
+
+    UShort_t  fTransport[2];    // pixel ids with the yellow transpoters
+    UInt_t    fNumPixels;       // number of pixels in the present geometry
+    Byte_t    fNumBombs;        // number of bombs in the field
+    Byte_t    fNumFood;         // number of food packages
+    Float_t   fRange;           // the range in millimeters of the present geometry
+
+    TText    *fDone;            // TText showing the 'Game over'
+    TText    *fPaused;          // TText showing the 'Game over'
+    TText     fShow;            // TText showing the numbers of pixels and bombs
+
+    UInt_t    fW;               // Width of canvas
+    UInt_t    fH;               // Height of canvas
+
+    TClonesArray  *fPixels;     // array of all hexagons
+    TVirtualPad   *fDrawingPad; // pad in which we are drawing
+
+    MHexagon &operator[](int i) { return *((MHexagon*)fPixels->At(i)); }
+
+    void   Remove(TObject *);
+    void   Done(TString, Int_t col);
+    void   Step(Int_t newpix);
+    void   Update();
+    void   Free();
+    void   DrawHexagons();
+    Int_t  ScanNeighbours();
+    void   SetNewCamera(MGeomCam *);
+    void   SetWormColor();
+    void   Pause(Bool_t yes=kTRUE);
+
+    Bool_t HandleTimer(TTimer *timer);
+    void   Draw(Option_t *option="");
+    void   Paint(Option_t *option="");
+    void   ExecuteEvent(Int_t event, Int_t px, Int_t py);
+    Int_t  DistancetoPrimitive(Int_t px, Int_t py) { return 0; }
+
+public:
+    MagicSnake();
+    ~MagicSnake();
+
+    void Reset();        //*MENU*
+    void ChangeCamera(); //*MENU*
+
+    ClassDef(MagicSnake, 0) // Magic Camera Games
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mtools/Makefile
===================================================================
--- /trunk/MagicSoft/Mars/mtools/Makefile	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/Makefile	(revision 1435)
@@ -0,0 +1,51 @@
+##################################################################
+#
+#   makefile
+# 
+#   for the MARS software
+#
+##################################################################
+include ../Makefile.conf.$(OSTYPE)
+include ../Makefile.conf.general
+
+#
+# Handling name of the Root Dictionary Files
+#
+CINT  = Tools
+
+#
+# Library name to creatre
+#
+LIB   = mtools.a
+
+#
+#  connect the include files defined in the config.mk file
+#
+INCLUDES = -I. -I../mbase -I../mgui
+
+#------------------------------------------------------------------------------
+
+.SUFFIXES: .c .cc .cxx .h .hxx .o 
+
+SRCFILES = MagicSnake.cc \
+           MagicShow.cc \
+           MagicDomino.cc \
+           MagicCivilization.cc \
+           MineSweeper.cc
+
+SRCS    = $(SRCFILES)
+HEADERS = $(SRCFILES:.cc=.h)
+OBJS    = $(SRCFILES:.cc=.o) 
+
+############################################################
+
+all: $(LIB)
+
+include ../Makefile.rules
+
+clean:	rmcint rmobjs rmcore rmlib
+
+mrproper:	clean rmbak
+
+# @endcode
+
Index: /trunk/MagicSoft/Mars/mtools/MineSweeper.cc
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MineSweeper.cc	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MineSweeper.cc	(revision 1435)
@@ -0,0 +1,526 @@
+/* ======================================================================== *\
+!
+! *
+! * This file is part of MARS, the MAGIC Analysis and Reconstruction
+! * Software. It is distributed to you in the hope that it can be a useful
+! * and timesaving tool in analysing Data of imaging Cerenkov telescopes.
+! * It is distributed WITHOUT ANY WARRANTY.
+! *
+! * Permission to use, copy, modify and distribute this software and its
+! * documentation for any purpose is hereby granted without fee,
+! * provided that the above copyright notice appear in all copies and
+! * that both that copyright notice and this permission notice appear
+! * in supporting documentation. It is provided "as is" without express
+! * or implied warranty.
+! *
+!
+!
+!   Author(s): Thomas Bretz 07/2002 <mailto:tbretz@astro.uni-wuerzburg.de>
+!
+!   Copyright: MAGIC Software Development, 2000-2002
+!
+!
+\* ======================================================================== */
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// MineSweeper
+// -----------
+//
+// Camera Display Games: Mine Sweeper
+//
+// Start the game by:
+//   MineSweeper mine;
+//
+// It is the well known Mine Sweeper.
+// Set a mark using a single mouse click.
+// Open a pixel using a double click.
+//
+// Try to open all pixels without bombs. If you open a pixel with no
+// bomb around all pixels around are opened.
+//
+// To restart the game use the context menu. It can only be accessed if
+// the game has been stopped (either because you win the game or because
+// you hit a bomb) With the context menu you can also toggle between
+// different camera layouts.
+//
+////////////////////////////////////////////////////////////////////////////
+#include "MineSweeper.h"
+
+#include <iostream.h>
+
+#include <TText.h>
+#include <TMarker.h>
+#include <TRandom.h>
+#include <TCanvas.h>
+#include <TClonesArray.h>
+#include <TInterpreter.h>
+
+#include "MHexagon.h"
+
+#include "MGeomPix.h"
+#include "MGeomCamCT1.h"
+#include "MGeomCamMagic.h"
+
+ClassImp(MineSweeper);
+
+const Int_t MineSweeper::fColorBombs[7] = {
+    22,
+    kYellow,
+    kGreen,
+    kBlue,
+    kCyan,
+    kMagenta,
+    kRed
+};
+
+void MineSweeper::Free()
+{
+    if (!fGeomCam)
+        return;
+
+    fPixels->Delete();
+    fText->Delete();
+    fFlags->Delete();
+
+    delete fText;
+    delete fFlags;
+    delete fPixels;
+
+    delete fGeomCam;
+}
+
+void MineSweeper::ChangeCamera()
+{
+    static Bool_t ct1=kFALSE;
+
+    cout << "Change to " << (ct1?"Magic":"CT1") << endl;
+
+    if (ct1)
+        SetNewCamera(new MGeomCamMagic);
+    else
+        SetNewCamera(new MGeomCamCT1);
+
+    ct1 = !ct1;
+
+    Reset();
+    DrawHexagons();
+}
+
+void MineSweeper::SetNewCamera(MGeomCam *geom)
+{
+    Free();
+
+    //
+    //  Reset the display geometry
+    //
+    fW=0;
+    fH=0;
+
+    //
+    //  Set new camera
+    //
+    fGeomCam = geom;
+
+    //
+    //  create the hexagons of the display
+    //
+    fNumPixels = fGeomCam->GetNumPixels();
+    fRange     = fGeomCam->GetMaxRadius();
+
+    //
+    // Construct all hexagons. Use new-operator with placement
+    //
+    fNumBombs = fNumPixels/5;
+
+    fText   = new TClonesArray("TText",    fNumPixels);
+    fFlags  = new TClonesArray("TMarker",  fNumPixels);
+    fPixels = new TClonesArray("MHexagon", fNumPixels);
+
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        MHexagon &h = *new ((*fPixels)[i]) MHexagon((*fGeomCam)[i]);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        h.SetBit(kNoContextMenu|kCannotPick);
+#endif
+
+        TText &t = *new ((*fText)[i]) TText;
+        t.SetTextFont(122);
+        t.SetTextAlign(22);   // centered/centered
+        t.SetTextSize(0.3*h.GetD()/fRange);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        t.SetBit(kNoContextMenu|kCannotPick);
+#endif
+
+        const MGeomPix &pix = (*fGeomCam)[i];
+
+        TMarker &m = *new ((*fFlags)[i]) TMarker(pix.GetX(), pix.GetY(), kOpenStar);
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+        m.SetBit(kNoContextMenu|kCannotPick);
+#endif
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// Draw all pixels of the camera
+//  (means apend all pixelobjects to the current pad)
+//
+void MineSweeper::DrawHexagons()
+{
+    for (UInt_t i=0; i<fNumPixels; i++)
+        (*this)[i].Draw();
+}
+
+// ------------------------------------------------------------------------
+//
+//  default constructor
+//
+MineSweeper::MineSweeper()
+    : fGeomCam(NULL), fDone(NULL), fShow(NULL), fW(0), fH(0), fDrawingPad(NULL), fIsAllocated(kFALSE)
+{
+    SetNewCamera(new MGeomCamMagic);
+
+    //
+    // Make sure, that the object is destroyed when the canvas/pad is
+    // destroyed. Make also sure, that the interpreter doesn't try to
+    // delete it a second time.
+    //
+    SetBit(kCanDelete);
+    gInterpreter->DeleteGlobal(this);
+
+    Draw();
+}
+
+// ------------------------------------------------------------------------
+//
+// Destructor. Deletes TClonesArrays for hexagons and legend elements.
+//
+MineSweeper::~MineSweeper()
+{
+    Free();
+
+    delete fShow;
+
+    if (fDone)
+        delete fDone;
+
+    if (fDrawingPad->GetListOfPrimitives()->FindObject(this)==this)
+    {
+        fDrawingPad->RecursiveRemove(this);
+        delete fDrawingPad;
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// This is called at any time the canvas should get repainted.
+// Here we maintain an aspect ratio of 5/4=1.15. This makes sure,
+// that the camera image doesn't get distorted by resizing the canvas.
+//
+void MineSweeper::Paint(Option_t *opt)
+{
+    const UInt_t w = (UInt_t)(gPad->GetWw()*gPad->GetAbsWNDC());
+    const UInt_t h = (UInt_t)(gPad->GetWh()*gPad->GetAbsHNDC());
+
+    //
+    // Check for a change in width or height, and make sure, that the
+    // first call also sets the range
+    //
+    if (w*fH == h*fW && fW && fH)
+        return;
+
+    //
+    // Calculate aspect ratio (5/4=1.25 recommended)
+    //
+    const Double_t ratio = (Double_t)w/h;
+
+    Float_t x;
+    Float_t y;
+
+    if (ratio>1.0)
+    {
+        x = fRange*(ratio*2-1);
+        y = fRange;
+    }
+    else
+    {
+        x = fRange;
+        y = fRange/ratio;
+    }
+
+    fH = h;
+    fW = w;
+
+    //
+    // Set new range
+    //
+    fDrawingPad->Range(-fRange, -y, x, y);
+
+    //
+    // Adopt absolute sized of markers to relative range
+    //
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        Float_t r = (*this)[i].GetD()*gPad->XtoAbsPixel(1)/325;
+        GetFlag(i)->SetMarkerSize(20.0*r/fRange);
+    }
+}
+
+// ------------------------------------------------------------------------
+//
+// Call this function to draw the camera layout into your canvas.
+// Setup a drawing canvas. Add this object and all child objects
+// (hexagons, etc) to the current pad. If no pad exists a new one is
+// created.
+//
+void MineSweeper::Draw(Option_t *option)
+{
+    // root 3.02:
+    // gPad->SetFixedAspectRatio()
+
+    if (fDrawingPad)
+        return;
+
+    //
+    // if no canvas is yet existing to draw into, create a new one
+    //
+    if (!gPad)
+    {
+        /*TCanvas *c =*/ new TCanvas("MineSweeper", "Magic Mine Sweeper", 0, 0, 800, 800);
+        //c->ToggleEventStatus();
+        fIsAllocated = kTRUE;
+    }
+    else
+        fIsAllocated = kFALSE;
+
+    fDrawingPad = gPad;
+    fDrawingPad->SetBorderMode(0);
+
+    //
+    // Append this object, so that the aspect ratio is maintained
+    // (Paint-function is called)
+    //
+    AppendPad(option);
+
+    //
+    // Draw the title text
+    //
+    fShow = new TText;
+    fShow->SetTextAlign(23);   // centered/bottom
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fShow->SetBit(kNoContextMenu|kCannotPick);
+#endif
+    fShow->Draw();
+    //
+    // Reset the game pad
+    //
+    Reset();
+    DrawHexagons();
+}
+
+void MineSweeper::Update(Int_t num)
+{
+    TString txt = "Pixels: ";
+    txt += fNumPixels;
+    txt += "  Bombs: ";
+    txt += num;
+
+    fShow->SetText(0, fRange, txt);
+}
+
+// ------------------------------------------------------------------------
+//
+// reset the all pixel colors to a default value
+//
+void MineSweeper::Reset()
+{
+    if (fDone)
+    {
+        delete fDone;
+        fDone = NULL;
+    }
+
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        Remove(GetText(i));
+        Remove(GetFlag(i));
+
+        (*this)[i].SetFillColor(kHidden);
+        (*fGeomCam)[i].ResetBit(kUserBits);
+
+        GetFlag(i)->SetMarkerColor(kBlack);
+    }
+    Update(fNumBombs);
+
+    TRandom rnd(0);
+    for (int i=0; i<fNumBombs; i++)
+    {
+        Int_t idx;
+
+        do idx = (Int_t)rnd.Uniform(fNumPixels);
+        while ((*fGeomCam)[idx].TestBit(kHasBomb));
+
+        (*fGeomCam)[idx].SetBit(kHasBomb);
+    }
+
+    fDrawingPad->SetFillColor(22);
+
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fDrawingPad->SetBit(kNoContextMenu);
+    SetBit(kNoContextMenu);
+#endif
+}
+
+void MineSweeper::Done(TString txt, Int_t col)
+{
+    for (unsigned int j=0; j<fNumPixels; j++)
+        if ((*fGeomCam)[j].TestBit(kHasBomb))
+        {
+            (*this)[j].SetFillColor(kBlack);
+            GetFlag(j)->SetMarkerColor(kWhite);
+        }
+
+    fDone = new TText(0, 0, txt);
+    fDone->SetTextColor(kWhite);  // white
+    fDone->SetTextAlign(22);  // centered/centered
+    fDone->SetTextSize(0.05); // white
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fDone->SetBit(kNoContextMenu|kCannotPick);
+#endif
+    fDone->Draw();
+
+    fDrawingPad->SetFillColor(col);
+
+#if ROOT_VERSION_CODE > ROOT_VERSION(3,01,06)
+    fDrawingPad->ResetBit(kNoContextMenu);
+    ResetBit(kNoContextMenu);
+#endif
+}
+
+// ------------------------------------------------------------------------
+//
+// Check whether a hexagon should be opened and which color/number should
+// be visible
+//
+void MineSweeper::OpenHexagon(Int_t idx)
+{
+    MGeomPix &pix=(*fGeomCam)[idx];
+
+    if (pix.TestBit(kIsVisible))
+        return;
+
+    if (pix.TestBit(kHasFlag))
+        Remove(GetFlag(idx));
+
+    pix.SetBit(kIsVisible);
+    pix.ResetBit(kHasFlag);
+
+    Int_t cnt=0;
+    for (int j=0; j<pix.GetNumNeighbors(); j++)
+        if ((*fGeomCam)[pix.GetNeighbor(j)].TestBit(kHasBomb))
+            cnt++;
+
+    (*this)[idx].SetFillColor(fColorBombs[cnt]);
+
+    if (cnt)
+    {
+        TText *txt = GetText(idx);
+        TString str;
+        str += cnt;
+        txt->SetText(pix.GetX(), pix.GetY(), str);
+        txt->Draw();
+        return;
+    }
+
+    for (int j=0; j<pix.GetNumNeighbors(); j++)
+        OpenHexagon(pix.GetNeighbor(j));
+}
+
+void MineSweeper::Remove(TObject *obj)
+{
+    fDrawingPad->RecursiveRemove(obj);
+}
+
+// ------------------------------------------------------------------------
+//
+// Execute a mouse event on the camera
+//
+void MineSweeper::ExecuteEvent(Int_t event, Int_t px, Int_t py)
+{
+    if (event==kMouseMotion   || event==kMouseEnter    || event==kMouseLeave    ||
+        event==kButton1Up     || event==kButton2Up     || event==kButton3Up     ||
+        event==kButton1Motion || event==kButton2Motion || event==kButton3Motion ||
+                                 event==kButton2Double || event==kButton3Double ||
+        fDone)
+        return;
+
+    /*
+    if (event==kKeyPress && py==0x1000)
+    {
+        Reset();
+        return;
+    }
+    */
+
+    UInt_t idx;
+    for (idx=0; idx<fNumPixels; idx++)
+        if ((*fPixels)[idx]->DistancetoPrimitive(px, py)==0)
+            break;
+
+    if (idx==fNumPixels)
+        return;
+
+    MGeomPix &pix=(*fGeomCam)[idx];
+
+    if (event==kButton1Double)
+    {
+        OpenHexagon(idx);
+
+        if (pix.TestBit(kHasBomb))
+            Done("Argh... you hit the Bomb!!!", kRed);
+    }
+
+    if (event==kButton1Down && !pix.TestBit(kIsVisible))
+    {
+        if (pix.TestBit(kHasFlag))
+            Remove(GetFlag(idx));
+        else
+            GetFlag(idx)->Draw();
+
+        pix.InvertBit(kHasFlag);
+    }
+
+    UInt_t vis=fNumBombs;
+    UInt_t flg=fNumBombs;
+    for (UInt_t i=0; i<fNumPixels; i++)
+    {
+        if ((*fGeomCam)[i].TestBit(kIsVisible))
+            vis++;
+        if ((*fGeomCam)[i].TestBit(kHasFlag))
+            flg--;
+    }
+
+    Update(flg);
+
+    if (vis==fNumPixels && !fDone)
+        Done("Great! Congratulations, you did it!", kGreen);
+
+    fDrawingPad->Modified();
+
+    /*
+     switch (event)
+     {
+     case kNoEvent:       cout << "No Event" << endl; break;
+     case kButton1Down:   cout << "Button 1 down" << endl; break;
+     case kButton2Down:   cout << "Button 2 down" << endl; break;
+     case kButton3Down:   cout << "Button 3 down" << endl; break;
+     case kKeyDown:       cout << "Key down" << endl; break;
+     case kKeyUp:         cout << "Key up" << endl; break;
+     case kKeyPress:      cout << "Key press" << endl; break;
+     case kButton1Locate: cout << "Button 1 locate" << endl; break;
+     case kButton2Locate: cout << "Button 2 locate" << endl; break;
+     case kButton3Locate: cout << "Button 3 locate" << endl; break;
+    }
+    */
+}
Index: /trunk/MagicSoft/Mars/mtools/MineSweeper.h
===================================================================
--- /trunk/MagicSoft/Mars/mtools/MineSweeper.h	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/MineSweeper.h	(revision 1435)
@@ -0,0 +1,78 @@
+#ifndef MARS_MineSweeper
+#define MARS_MineSweeper
+
+#ifndef MARS_MAGIC
+#include "MAGIC.h"
+#endif
+#ifndef ROOT_TClonesArray
+#include <TClonesArray.h>
+#endif
+
+class TText;
+class TMarker;
+class TVirtualPad;
+
+class MGeomCam;
+class MHexagon;
+
+class MineSweeper : public TObject
+{
+private:
+    static const Int_t fColorBombs[7]; // colors for the hexagons
+
+    MGeomCam      *fGeomCam;       // pointer to camera geometry
+
+    UInt_t         fNumPixels;     // number of pixels in the present geometry
+    Int_t          fNumBombs;      // number of bombs in total
+    Float_t        fRange;         // the range in millimeters of the present geometry
+
+    TClonesArray  *fPixels;        // array of all hexagons
+    TClonesArray  *fText;          // array of all texts
+    TClonesArray  *fFlags;         // array of all texts
+
+    TText         *fDone;          // TText showing the 'Game over'
+    TText         *fShow;          // TText showing the numbers of pixels and bombs
+
+    UInt_t         fW;             // Width of canvas
+    UInt_t         fH;             // Height of canvas
+    TVirtualPad   *fDrawingPad;    // pad in which we are drawing
+    Bool_t         fIsAllocated;
+
+    enum
+    {
+        kHidden    = 50,
+        kIsVisible = BIT(15),
+        kHasBomb   = BIT(16),
+        kHasFlag   = BIT(17),
+        kUserBits  = 0x0000ff00 // 14-23 are allowed
+    };
+
+    MHexagon &operator[](int i) { return *((MHexagon*)fPixels->At(i)); }
+
+    TText   *GetText(Int_t i) { return (TText*)fText->At(i); }
+    TMarker *GetFlag(Int_t i) { return (TMarker*)fFlags->At(i); }
+
+    void  Remove(TObject *);
+    void  OpenHexagon(Int_t idx);
+    void  Done(TString, Int_t);
+    void  Update(Int_t);
+    void  SetNewCamera(MGeomCam *);
+    void  DrawHexagons();
+    void  Free();
+
+    void  Paint(Option_t *option="");
+    void  Draw(Option_t *option="");
+    void  ExecuteEvent(Int_t event, Int_t px, Int_t py);
+    Int_t DistancetoPrimitive(Int_t px, Int_t py) { return 0; }
+
+public:
+    MineSweeper();
+    ~MineSweeper();
+
+    void Reset();        //*MENU*
+    void ChangeCamera(); //*MENU*
+
+    ClassDef(MineSweeper, 0) // Magic Camera Games
+};
+
+#endif
Index: /trunk/MagicSoft/Mars/mtools/ToolsIncl.h
===================================================================
--- /trunk/MagicSoft/Mars/mtools/ToolsIncl.h	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/ToolsIncl.h	(revision 1435)
@@ -0,0 +1,3 @@
+#ifndef __CINT__
+
+#endif // __CINT__
Index: /trunk/MagicSoft/Mars/mtools/ToolsLinkDef.h
===================================================================
--- /trunk/MagicSoft/Mars/mtools/ToolsLinkDef.h	(revision 1435)
+++ /trunk/MagicSoft/Mars/mtools/ToolsLinkDef.h	(revision 1435)
@@ -0,0 +1,13 @@
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class MineSweeper+;
+#pragma link C++ class MagicSnake+;
+#pragma link C++ class MagicShow+;
+#pragma link C++ class MagicDomino+;
+#pragma link C++ class MagicCivilization+;
+
+#endif
