//*****************************************************************************
// copyright (c) 1998-2003 TLK Games all rights reserved
//-----------------------------------------------------------------------------
// file         : "score.cpp"
// created      : 1998-06-29
// updates      : 2003-07-20
//-----------------------------------------------------------------------------
// descriptions : manage scores / about / credits
//-----------------------------------------------------------------------------
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 of the License, or (at your option) any later
// version.
// 
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program; if not, write to the Free Software Foundation, Inc., 59 Temple
// Place - Suite 330, Boston, MA  02111-1307, USA.
//
//*****************************************************************************
#include "powermanga.hpp"
#include "score.hpp"
#ifndef SDL_TLK
#include <X11/keysym.h>
#include <X11/keysymdef.h>
#endif
#include <errno.h>
//..............................................................................
extern const char      *nomfichierscore[] ;
extern int              gameLevel;                             // Game difficulty (Laurent Duperval)
//..............................................................................
// Scores
char _score::cScoresNoms[iNOMBRE_SCORES][4] =
{ {'T', 'L', 'K', 0},
  {'J', 'M', 'M', 0},
  {'E', 'T', 'B', 0},
  {'D', 'A', 'V', 0},
  {'F', 'L', 'O', 0}
};
//..............................................................................
int                     _score::iScores[iNOMBRE_SCORES] = { 10, 90, 80, 7, 5 };
_chaine                *_score::pScoresObj = (_chaine *) 0x0;
_chaine                *_score::pChaineJoueur = (_chaine *) 0x0;        // objet de type '_chaine' reservee a l'entree du nom du joueur
_chaine                *_score::pGame = (_chaine *) 0x0;                // objet de type '_chaine'
_chaine                *_score::pOver = (_chaine *) 0x0;                // objet de type '_chaine'
int                     _score::iAction = 0;
int                     _score::iActionExecution = 0;
unsigned int            _score::iTempo = 0;                             // tempo durant lequel le score reste affiche
int                     _score::iLettreAnime = 0;                       // numero de la lettre anime    
_caractere             *_score::pLettreActuelle = (_caractere *) 0x0;
_caractere             *_score::pTexteAbout = (_caractere *) 0x0;
unsigned int            _score::iAnimIndex = 0;                         // Numero du caractere a anime
unsigned int            _score::iAboutNombreCaracteres = 0;
unsigned int            _score::iIndexAboutTable = 0;
unsigned int            _score::iAnimIndexTempo = 0;
_caractere             *_score::pTableau[iTOTALCARACTERES];
_chaine                *_score::pTxtChaines = 0x0;
int                     _score::iTxtPosX = 0;
unsigned int            _score::iTxtPosY = 0;
char                   *_score::pTxtTableau = 0x0;
unsigned short         *_score::pTableCommande = 0x0;
unsigned int            _score::iTableIndex = 0;                        // index sur le tableau pointee par 'pTableCommande'
int                     _score::iTableTempo = 0;                        // temporisation
//..............................................................................
char _score::pScoreTempo[32] =
{ 0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0,
  0, 0, 0, 0, 0, 0, 0, 0
};
char _score::pGameTexte[] = { "GAME" };
char _score::pOverTexte[] = { "OVER" }; 
//..............................................................................
char                   *_score::pTableAbout[] =
{ "0MAIN",       "0PROGRAMMING", "1JEAN MICHEL", "1MARTIN", "@",
  "0LINUX",      "0VERSION",     "1BRUNO",       "1ETHVIGNOT", "@",
  "0LINUX",      "0VERSION",     "1ANDRE",       "1MAJOREL", "@",
  "0GRAPHIC",    "0DESIGN",      "1DAVID",       "1IGREJA", "@",
  "0ADDITIONAL", "0PROGRAMMING", "1ETIENNE",     "1SOBOLE", "@",
  "0ADDITIONAL", "0GRAPHICS",    "1JEAN MICHEL", "1MARTIN", "@",
  "0ADDITIONAL", "0PROGRAMMING", "1BRUNO",       "1ETHVIGNOT", "@",
  "0ADDITIONAL", "0PROGRAMMING", "1EMMANUEL",    "1FOUNAUD", "@",
  "0ADDITIONAL", "0PROGRAMMING", "1GUILLAUME",   "1COTTENCEAU", "@",
  "0ADDITIONAL", "0PROGRAMMING", "1LAURENT",     "1DUPERVAL", "@",
  "0ADDITIONAL", "0PROGRAMMING", "1SAMUEL",      "1HOCEVAR", "@",
  "0MUSICS BY",  "1MICHEL",      "1DOGNIAUX",    "@",
  "0(c) 2003",   "1TLK",         "1GAMES",       "@",
  "#"
};
// Variables declaree dans le fichier "powermanga.cpp"
extern int              player_score;                         // score du joueur
extern int              pos_y_menu;                           // position Y d'affichage du menu.
extern unsigned int     iCodeTouche;                          // code touche pressee
extern int              etat_menu;                            // indique l'etat du menu, on, off, apparition, disparition.
extern _etbfonte1      *pEtbfonte1;                           // objet '_etbfonte1' gestion affichage de caractere 8x8
extern unsigned int     iVerbeux;                             // 1=affiche les arguments / verbose mode
extern bool             aff_game_over;                        // 1=display "GAME OVER"

//******************************************************************************
// Retourne le type d'action en cours
//******************************************************************************
int _score::getActionExecution()
{
  return iActionExecution;
}

//******************************************************************************
// Routine d'execution principale / main loop
// input => _iFlag      : 0 main menu's disable (etat_menu==MENU_OFF)
//                      : 1 main menu's enable 
//******************************************************************************
void _score::execution(int _iFlag)
{
  switch (iActionExecution)
  { 
    // "Game Over" : le joueur a perdu son dernier vaisseau
    case 1:
      executeGameOver(_iFlag);
      break;
    
    // affiche la table des scores : le joueur presse ESC dans le menu
    case 2:
      executeTableScore(_iFlag);
      break;
    
    // affiche les 'abouts' : qui fait quoi
    case 3:
      executeAbout(_iFlag);
      break;
    
    // affiche le 'order' : comment commander
    case 4:
      executeOrder(_iFlag);
      break;

  }
}

//******************************************************************************
// Initialize 
// input => _iCodeAction : 1 = GAME OVER
//                         2 = SCORES 
//                         3 = ABOUT 
//                         4 = ORDER
//******************************************************************************
int _score::setAction(int _iCodeAction)
{
  switch (_iCodeAction)
  {
    case 0:
    {
      iActionExecution = 0;
      iAction = 0;
      break;
    }
      // initialize the 'GAME OVER' ----------
    case 1:
    {
      chargeScores();
      int _iPosition = trieScores();                           // _iPosition=position du joueur dans la table des scores
      if(_iPosition == -1) iTempo = iTEMPOTABLE;               // si pas de classement la table apparait un instant
      else                 iTempo = 0;                         // sinon pas de tempo, car le joueur entre son nom
      creeScores();
      initialiseGameOver(_iPosition);
      iActionExecution = 1;
      iAction = 1;
    }
      break;

    // initialize the 'SCORE TABLE' --------
    case 2:
      chargeScores();
      creeScores();
      iActionExecution = 2;
      iAction = 0;
      break;

    // initialize the 'ABOUT' --------------
    case 3:
      creeAbout();
      iActionExecution = 3;
      iAction = 0;
      break;

    // initialize the 'ORDER' --------------
    case 4:
      if(!creeOrder()) return 0;
      iActionExecution = 4;
      break;
  }
  return 1;
}

//=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
// GAME OVER : initialize / initialise
//  - trie des scores
//  - affiche table des scores 
//  - affiche "Game Over"
//=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
int _score::initialiseGameOver(int _iPosition)
{
  // Cree deux objets chaine pour les textes 'GAME' et 'OVER'
  if(pGame == (_chaine *) 0x0) pGame = new _chaine();
  if(pOver == (_chaine *) 0x0) pOver = new _chaine();
  pGame->initialise(pGameTexte, 4, 182, POS_Y_GAME, 38, 1);
  pOver->initialise(pOverTexte, 4, 182, POS_Y_OVER, 38, 1);
  pGame->initRotation(64, 0, 0, 120);
  pOver->initRotation(0, 0, 0, 120);

  // Trie des scores
  pChaineJoueur = (_chaine *) 0x0;                             // pointeur sur la chaine a rentrer

  // Initialise l'arrivee rotative des noms et des scores
  int _iIndexScore = 0;
  int _iAngle = 0;
  int _iAngleInc = 1;
  int _iRayonX = 200;
  int _iRayonY = 160;
  unsigned int _iIndex1 = 0;

  // initialise les noms
  for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES; _iIndex1++)
  { _chaine                *_pChaine = &pScoresObj[_iIndexScore++];
    _pChaine->initRotation(_iAngle, _iAngleInc, _iRayonX, _iRayonY);
    if(_iPosition == (int)(_iIndex1)) pChaineJoueur = _pChaine;
    _iAngle = (_iAngle + 1) & iANGLEMAXI;
    _iAngleInc = -_iAngleInc;
  }
  
  // initialise les scores
  for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES; _iIndex1++)
  { _chaine                *_pChaine = &pScoresObj[_iIndexScore++];
    _pChaine->initRotation(_iAngle, _iAngleInc, _iRayonX, _iRayonY);
    _iAngle = (_iAngle + 1) & iANGLEMAXI;
    _iAngleInc = -_iAngleInc;
  }
  return 1;
}

// ------------------------------------------------------------------------------
// cree les chaines de caractere des scores -------------------------------------
// ------------------------------------------------------------------------------
int _score::creeScores()
{
  int _iIndexScore = 0;
  if(pScoresObj == 0x0)
    pScoresObj = new _chaine[iNOMBRE_SCORES * 2];              // Cree les objets '_chaine'
  int _iPositionY = iTABLEY;
  unsigned int _iIndex1;
  int _iIndexTableau = 0;
  int _iIndex3;

  // Convertit les noms en sprites
  for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES; _iIndex1++)
  { _chaine                *_pChaine = &pScoresObj[_iIndexScore++];
    char                   *_pNom = &cScoresNoms[_iIndex1][0];
    _pChaine->initialise(_pNom, iLONGEURNOM, iTABLEX1, _iPositionY, 16, 0);
    _iPositionY += iTABLEOFFSET;

    // Recopie les pointeurs sur les objets caracteres dans un tableau
    int _iNombre = _pChaine->getNombreCaracteres();
    _caractere             *_pCaracteres = _pChaine->getCaracteres();
    for(_iIndex3 = 0; _iIndex3 < _iNombre; _iIndex3++)
      pTableau[_iIndexTableau++] = &_pCaracteres[_iIndex3];

  }
  // Convertit les scores en sprites
  _iPositionY = iTABLEY;
  for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES; _iIndex1++)
  {
    _chaine                *_pChaine = &pScoresObj[_iIndexScore++];
    int _iScore = iScores[_iIndex1];

    for(_iIndex3 = 0; _iIndex3 <= 7; _iIndex3++)
      pScoreTempo[_iIndex3] = '0';
    entierEnASCII(_iScore, pScoreTempo);
    _pChaine->initialise(pScoreTempo, iTABLEX2, _iPositionY, LARG_FONTE_GAME,
                         0);
    _iPositionY += iTABLEOFFSET;
    // Recopie les pointeurs sur les objets caracteres dans un tableau
    int _iNombre = _pChaine->getNombreCaracteres();
    _caractere             *_pCaracteres = _pChaine->getCaracteres();

    for(_iIndex3 = 0; _iIndex3 < _iNombre; _iIndex3++)
      pTableau[_iIndexTableau++] = &_pCaracteres[_iIndex3];
  }
  return 1;
}

// ------------------------------------------------------------------------------
// affiche les chaines de caractere des scores
// <=   _iRetour : 1=touche entree pressee
// ------------------------------------------------------------------------------
int _score::affScores()
{
  int _iRetour = 0;
  int _iRotation = 1;
  unsigned int _iIndex1 = 0;
  for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES * 2; _iIndex1++)
  { _chaine *_pChaine = &pScoresObj[_iIndex1];
    if(_pChaine->rotation1(2, 2, 0) == 0)
      _iRotation = 0; // _iRotation=1 alors rotation terminee
  }
  // Gestion entree des caracteres + clignotement du curseur
  if(pChaineJoueur != 0 && _iRotation == 1)
  { _iRetour = pChaineJoueur->entreeClavier();
    //   RETURN pressed ? (ASCII=13) 
#ifdef SDL_TLK
    if(_iRetour == SDLK_RETURN) 
#else
    if(_iRetour == XK_Return)
#endif
    { pChaineJoueur = (_chaine *) 0x0;
      sauveScores();
      _iRetour = 1;
    }
    else
    { _iRetour = 0;
    }
  }
  afficheScores();
  return _iRetour;
}

// ------------------------------------------------------------------------------
// Affichage de la table des scores
// ------------------------------------------------------------------------------
void _score::afficheScores()
{
  unsigned int _iIndex1;
  for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES * 2; _iIndex1++)
  {  _chaine *_pChaine = &pScoresObj[_iIndex1];
    _pChaine->affiche2();
  }
}


// Trie des scores  -----------------------------------------------------------
// Sortie <=    position dans la table des scores, de 0 a 4 ou -1 si non classe
int _score::trieScores()
{
  int _iPosition = -1;

  for(unsigned int _iIndex = 0; _iIndex < iNOMBRE_SCORES; _iIndex++)
  {
    if(player_score > iScores[_iIndex])
    {
      for(unsigned int _iIndex2 = iNOMBRE_SCORES - 1; _iIndex2 > _iIndex;
          _iIndex2--)
      {
        iScores[_iIndex2] = iScores[_iIndex2 - 1];
        cScoresNoms[_iIndex2][0] = cScoresNoms[_iIndex2 - 1][0];
        cScoresNoms[_iIndex2][1] = cScoresNoms[_iIndex2 - 1][1];
        cScoresNoms[_iIndex2][2] = cScoresNoms[_iIndex2 - 1][2];
      }
      iScores[_iIndex] = player_score;
      cScoresNoms[_iIndex][0] = ' ';
      cScoresNoms[_iIndex][1] = ' ';
      cScoresNoms[_iIndex][2] = ' ';
      _iPosition = _iIndex;
      break;
    }
  }
  return _iPosition;
}

// Routine permettant de remplir une structure image à partir d'un fichier---
int _score::chargeScores()
{
  unsigned int _iIndex;
  unsigned int _iIndex2;
  int _iHandle;
  struct stat sDescriptionFichier;
  char                   *_pMemoire = 0;
  _iHandle = open(nomfichierscore[gameLevel], O_RDONLY, 0);		 //ouvre le fichier
  if(_iHandle == -1)
  { printf("%s: %s\n", nomfichierscore[gameLevel], strerror(errno)) ;
  }
  else
  { if(fstat(_iHandle, &sDescriptionFichier))
    { printf("%s: %s\n", nomfichierscore[gameLevel], strerror(errno)) ;
    }
    else
    { _pMemoire = reserveMemoire(sDescriptionFichier.st_size); //reserve la place en memoire pour lire le fichier
      if(!_pMemoire)
      { afficheErreur("out of memory", "_score::chargeScores()");
      }
      else
      {
        if(read(_iHandle, _pMemoire, sDescriptionFichier.st_size) != sDescriptionFichier.st_size)
        { libereMemoire(_pMemoire);
          _pMemoire = 0;
          printf("%s: %s\n", nomfichierscore[gameLevel], strerror(errno)) ;
        }
        else
        {
#ifdef _VERBEUX_
          if(iVerbeux == 1)
            afficheMessage("_score::chargeScores() file \"powermanga.hi\" was loaded in memory");
#endif
        }
      }
    }
    close(_iHandle);
  }
  if(_pMemoire)
  {
    char                   *_pBufferC = _pMemoire;
    int                    *_pBufferL;

    //recopie les noms
    for(_iIndex = 0; _iIndex < iNOMBRE_SCORES; _iIndex++)
    {
      for(_iIndex2 = 0; _iIndex2 < iLONGEURNOM; _iIndex2++)
        cScoresNoms[_iIndex][_iIndex2] = *(_pBufferC++);
    }
    //recopie les scores
    _pBufferL = (int *)_pBufferC;
    for(_iIndex = 0; _iIndex < iNOMBRE_SCORES; _iIndex++)
    {
      iScores[_iIndex] = *(_pBufferL++);
    }
    int _iSomme2 = *_pBufferL;                                 // somme d'auto-controle du fichier
    int _iSomme = calculSomme((int *)_pMemoire, (iTAILLEBUFFER / 4) - 1);

    //le fichier charge n'est pas bon (on cree une nouvelle table des scores)
    if(_iSomme2 != _iSomme)
    {
      creeNouvelleTable();
    }
    libereMemoire(_pMemoire);
  }
  else
  {
    creeNouvelleTable();                                       //la tables des scores n'a pu etre chargee
  }
  return 1;
}

// Creation d'une nouvelle table des scores  ----------------------------------
void _score::creeNouvelleTable()
{
  unsigned int _iIndex;
  unsigned int _iIndex2;
  char _pNom[iLONGEURNOM] = { 'T', 'L', 'K' };

  // Cree les noms
  for(_iIndex = 0; _iIndex < iNOMBRE_SCORES; _iIndex++)
  {
    for(_iIndex2 = 0; _iIndex2 < iLONGEURNOM; _iIndex2++)
      cScoresNoms[_iIndex][_iIndex2] = _pNom[_iIndex2];
  }
  // Cree les scores

  int _iScore = 10000;

  for(_iIndex = 0; _iIndex < iNOMBRE_SCORES; _iIndex++)
  {
    iScores[_iIndex] = _iScore;
    _iScore = _iScore / 2;
  }
}

// Sauvegarde des scores  -----------------------------------------------------
void _score::sauveScores()
{                                                              //printf("%d %d \n", getgid(), getegid() ) ;
  char                   *_pBuffer = new char[iTAILLEBUFFER];
  char                   *_pBufferC = _pBuffer;
  int                    *_pBufferL;
  unsigned int _iIndex;
  unsigned int _iIndex2;
  for(_iIndex = 0; _iIndex < iNOMBRE_SCORES; _iIndex++)
  { for(_iIndex2 = 0; _iIndex2 < iLONGEURNOM; _iIndex2++)
      *(_pBufferC++) = cScoresNoms[_iIndex][_iIndex2];
  }
  _pBufferL = (int *)_pBufferC;
  for(_iIndex = 0; _iIndex < iNOMBRE_SCORES; _iIndex++)
  { *(_pBufferL++) = iScores[_iIndex];
  }
  int _iSomme = calculSomme((int *)_pBuffer, (iTAILLEBUFFER / 4) - 1);
  *_pBufferL = _iSomme;
  int _iHandle;
  umask(0002);                                                                         // set umask so that files are group-writable
  _iHandle = open(nomfichierscore[gameLevel] , O_WRONLY | O_CREAT, 00666);             //ouvre le fichier
  if(_iHandle == -1)
  { printf("%s: %s\n", nomfichierscore[gameLevel], strerror(errno)) ;
  }
  else
  { write(_iHandle, _pBuffer, iTAILLEBUFFER);
    if(close(_iHandle) != 0)
    { printf("%s: %s\n", nomfichierscore[gameLevel], strerror(errno)) ;
    }
  }
  delete _pBuffer;
}

// Calcul la somme d'auto-controle des scores ---------------------------------
// entree => _pBuffer   : pointeur sur le buffer
//                              => _iTaille     : nombre de mots de 32 bits
// sortie <= _iValeur   :       somme d'auto-controle 
int _score::calculSomme(int *_pBuffer, int _iTaille)
{
  int _iValeur = 0;

  for(int _iIndex = 0; _iIndex < _iTaille; _iIndex++)
    _iValeur |= *(_pBuffer++);
  return _iValeur;
}

//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--
// GAME OVER : apparition table des scores, entre le nom, affiche "GAME OVER"
// input => _iFlag      : 0 main menu's disable (etat_menu==MENU_OFF)
//                                                                      : 1 main menu's enable 
//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--
void _score::executeGameOver(int _iFlag)
{
  switch (iAction)
  {                                                            // Apparition des scores
    case 1:
    {
      int _iCode = affScores();                                // 1=le joueur a presse la touche RETURN

      if(iTempo == 0)                                          // si iTempo==0 alors le joueur entre son nom
      {
        if(_iCode == 1)                                        // touche RETURN pressee ?
        {
          iAction = 2;                                         // oui, les scores vont disparaitres
        }
      }
      else
      {
        iTempo--;                                              // iTempo>0 : le joueur n'est pas dans les scores
        if(iTempo == 0 || (iCodeTouche != 0 && iTempo < iTEMPOTABLE - 10))
          iAction = 2;                                         // on affiche un court moment la table des scores
      }

    }
      break;

      // Disparition des scores
    case 2:
    {
      unsigned int _iIndex1;
      int _iRotation = 1;

      for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES * 2; _iIndex1++)
      {
        _chaine                *_pChaine = &pScoresObj[_iIndex1];

        if(_pChaine->rotation2(2, 2, 250, 210) == 0)
          _iRotation = 0;                                      // _iRotation=1 alors rotation terminee
      }
      if(_iRotation == 1)
        iAction = 3;
      afficheScores();
    }
      break;

      // Le "GAME OVER" apparait les lettres tournent toutes
    case 3:
    {
      int _iRotation = 1;

      afficheScores();
      if(pGame->rotation1(2, 2, 0) == 0)
        _iRotation = 0;                                        // _iRotation=1 alors rotation terminee
      if(pOver->rotation1(2, 2, 0) == 0)
        _iRotation = 0;                                        // _iRotation=1 alors rotation terminee
      pGame->affiche2();
      pOver->affiche2();
      pGame->animationTous();
      pOver->animationTous();
      if(_iRotation == 1)
        iAction = 4;
    }
      break;

      // Le "GAME OVER" est fixe les lettres tournent toutes encore une fois
    case 4:
    {
      int _iFin = 0;

      pGame->affiche2();
      pOver->affiche2();
      if(pGame->animation2Tous() != 0)
        _iFin = 1;
      if(pOver->animation2Tous() != 0)
        _iFin = 1;
      if(_iFin == 0)
        iAction = 5;
      iLettreAnime = 7;
      _caractere             *_pListe = pOver->getCaracteres();

      pLettreActuelle = &_pListe[3];
      iTempo = 0;
    }
      break;


      // Le "GAME OVER" est fixe
    case 5:
    {
      {
        if(pLettreActuelle->animation2() == 0)                 // L'animation de la lettre est terminee ?
        {
          if(iTempo == 0)
          {
            iLettreAnime++;                                    // oui, passe a la lettre suivante
            if(iLettreAnime >= 8)
            {
              iLettreAnime = 0;
            }
            if(iLettreAnime == 7)
              iTempo = 200;
            if(iLettreAnime < 4)
            {
              _caractere             *_pListe = pGame->getCaracteres();

              pLettreActuelle = &_pListe[iLettreAnime];
            }
            else
            {
              _caractere             *_pListe = pOver->getCaracteres();

              pLettreActuelle = &_pListe[iLettreAnime - 4];
            }
            pLettreActuelle->debuteAnimation();
          }
          else
            iTempo--;
        }
      }
      pGame->affiche();
      pOver->affiche();
      if(etat_menu == MENU_ON)
      {
        iActionExecution = 0;
        //aff_game_over=0 ; 
      }
      if(_iFlag == 1)
      {
        pGame->changePositionY(POS_Y_GAME + pos_y_menu -
                               (BANDE_DE_CLIP + HAUT_ECR_RAM));
        pOver->changePositionY(POS_Y_OVER + pos_y_menu -
                               (BANDE_DE_CLIP + HAUT_ECR_RAM));
      }
      testApparitionMenu();
    }
      break;
  }
}

//------------------------------------------------------------------------------
// Animations de tous les caracteres du scores
//------------------------------------------------------------------------------
void _score::animationScore()
{
  if(iAnimIndexTempo == 0)
  {
    _caractere             *_oCaractere = pTableau[iAnimIndex++];

    _oCaractere->debuteAnimation();
    if(iAnimIndex >= iTOTALCARACTERES)
      iAnimIndex = 0;
    iAnimIndexTempo = 25;
  }
  else
    iAnimIndexTempo--;

  for(unsigned int _iIndex = 0; _iIndex < iTOTALCARACTERES; _iIndex++)
  {
    _caractere             *_oCaractere = pTableau[_iIndex];

    _oCaractere->animation2();
  }

}

//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--
// TABLE SCORE : apparition table des scores lorsque le joueur presse ESC
// input => _iFlag      : 0 main menu's disable (etat_menu==MENU_OFF)
//                                                                      : 1 main menu's enable 
//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--
void _score::executeTableScore(int _iFlag)
{
  unsigned int _iIndexScore = 0;
  unsigned int _iIndex1;

  switch (iAction)
  {                                                            // Initialise l'apparition
    case 0:
    {
      iAction = 1;
      iAnimIndexTempo = 0;
      iAnimIndex = 0;
    }
      break;

      // Les caracteres descendent ou montent
    case 1:
    {                                                          //animationScore() ;
      int _iPositionY = iTABLEY;

      for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES; _iIndex1++)
      {
        _chaine                *_pChaine = &pScoresObj[_iIndexScore++];

        _pChaine->changePositionY(_iPositionY + pos_y_menu -
                                  (BANDE_DE_CLIP + HAUT_ECR_RAM));
        _pChaine->affiche();
        _pChaine->animationTous();
        _iPositionY += iTABLEOFFSET;
      }
      _iPositionY = iTABLEY;
      for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES; _iIndex1++)
      {
        _chaine                *_pChaine = &pScoresObj[_iIndexScore++];

        _pChaine->changePositionY(_iPositionY + pos_y_menu -
                                  (BANDE_DE_CLIP + HAUT_ECR_RAM));
        _pChaine->affiche();
        _pChaine->animationTous();
        _iPositionY += iTABLEOFFSET;
      }
      if(pos_y_menu >= BANDE_DE_CLIP + HAUT_ECR_RAM)
        iAction = 2;                                           // (menu totalement disparu ?)
      testApparitionMenu();
      if(etat_menu == MENU_ON)
        iActionExecution = 0;
    }
      break;

      // Les caracteres sont fixes et s'arretent de tourner
    case 2:
    {
      int _iFin = 0;

      for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES; _iIndex1++)
      {
        _chaine                *_pChaine = &pScoresObj[_iIndexScore++];

        if(_pChaine->animation2Tous() != 0)
          _iFin = 1;
        _pChaine->affiche();
      }
      for(_iIndex1 = 0; _iIndex1 < iNOMBRE_SCORES; _iIndex1++)
      {
        _chaine                *_pChaine = &pScoresObj[_iIndexScore++];

        if(_pChaine->animation2Tous() != 0)
          _iFin = 1;
        _pChaine->affiche();
      }
      if(_iFin == 0)
        iAction = 3;
      testApparitionMenu();
    }
      break;

      // Les caracters sont fixes et s'animent les uns apres les autres
    case 3:
    {
      animationScore();
      afficheScores();
      if(pos_y_menu < BANDE_DE_CLIP + HAUT_ECR_RAM)
        iAction = 1;                                           // (tout tourne en motant)
      testApparitionMenu();
    }
      break;
  }
}

//=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
// ABOUT : initialize credits / initialise credit 
//=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
int _score::creeAbout()
{
  if(pTexteAbout == 0x0)
    pTexteAbout = new _caractere[iMAXICARACTERES];
  iAboutNombreCaracteres = 0;
  iIndexAboutTable = 0;
  return 1;
}

//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--
// ABOUT : credit du jeu (qui fait quoi ?) execution
// input => _iFlag      : 0 main menu's disable (etat_menu==MENU_OFF)
//                                                                      : 1 main menu's enable 
//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--
void _score::executeAbout(int _iFlag)
{
  unsigned int _iIndex;
  int _iPosY;
  int _iPosX;
  int _iType;
  char _cAscii;
  int _iFin;
  _caractere             *_oCaractere;
  char                   *_pLigne;
  int _iAngleInc;

  switch (iAction)
  {
    case 0:
    {
      _iPosY = 158;
      _iAngleInc = 1;
      iAboutNombreCaracteres = 0;
      _pLigne = pTableAbout[iIndexAboutTable++];
      if(*(_pLigne) == '#')
      {
        _pLigne = pTableAbout[0];
        iIndexAboutTable = 1;
      }

      while (*(_pLigne) != '@')
      {
        _iPosX = 160;
        if(iAboutNombreCaracteres >= iMAXICARACTERES)
          break;
        _cAscii = *(_pLigne++);
        if(_cAscii == '0')
          _iType = 0;                                          // premier caractere determine la police utilisee
        else
          _iType = 1;

        if(_iType == 0)
          _iPosX = 128 + (256 - ((strlen(_pLigne)) * 16)) / 2 - 8;
        else
          _iPosX = 128 + (256 - ((strlen(_pLigne)) * 22)) / 2 - 11;

        _cAscii = *(_pLigne++);
        while (_cAscii != 0)
        {
          if(iAboutNombreCaracteres >= iMAXICARACTERES)
            break;
          _oCaractere = &pTexteAbout[iAboutNombreCaracteres++];
          _oCaractere->initialise_caractere(_cAscii, _iPosX, _iPosY, _iType);
          _oCaractere->initRotation(0, _iAngleInc, 200, 200);
          if(_iAngleInc > 0)
          {
            _iAngleInc = -_iAngleInc;
          }
          else
          {
            _iAngleInc = -_iAngleInc;
            _iAngleInc++;
            if(_iAngleInc > 2)
              _iAngleInc = 1;
          }
          _cAscii = *(_pLigne++);
          if(_iType == 0)
            _iPosX += 16;
          else
            _iPosX += 22;
        }
        _iPosY += 30;
        _pLigne = pTableAbout[iIndexAboutTable++];
      }
      iAction = 1;
      testApparitionMenu();
    }
      break;

      // Les lettres apparaissent (rotation)
    case 1:
    {
      _iFin = 1;
      for(_iIndex = 0; _iIndex < iAboutNombreCaracteres; _iIndex++)
      {
        _oCaractere = &pTexteAbout[_iIndex];
        if(_oCaractere->rotation1(1, 1, 0) == 0)
          _iFin = 0;
        _oCaractere->animation();
        _oCaractere->affiche();
      }
      if(_iFin == 1)
        iAction = 2;
      testApparitionMenu();
    }
      break;

      // Les caracteres sont arrives (termine l'animation)
    case 2:
    {
      _iFin = 0;
      for(_iIndex = 0; _iIndex < iAboutNombreCaracteres; _iIndex++)
      {
        _oCaractere = &pTexteAbout[_iIndex];
        if(_oCaractere->animation2() != 0)
          _iFin = 1;
        _oCaractere->affiche();
      }
      if(_iFin == 0)
      {
        iAction = 3;
        iAnimIndex = 0;
        iAnimIndexTempo = 0;
        iTempo = 300;
      }
      testApparitionMenu();
    }
      break;

      // Les caracteres sont statiques
    case 3:
    {
      if(iAnimIndexTempo == 0)
      {
        _oCaractere = &pTexteAbout[iAnimIndex++];
        _oCaractere->debuteAnimation();
        if(iAnimIndex >= iAboutNombreCaracteres)
          iAnimIndex = 0;
        iAnimIndexTempo = 25;
      }
      else
      {
        iAnimIndexTempo--;
      }
      for(_iIndex = 0; _iIndex < iAboutNombreCaracteres; _iIndex++)
      {
        _oCaractere = &pTexteAbout[_iIndex];
        _oCaractere->animation2();
        _oCaractere->affiche();
      }
      if(--iTempo <= 0)
        iAction = 4;
      if(etat_menu == MENU_ON || pos_y_menu < BANDE_DE_CLIP + HAUT_ECR_RAM)
        iAction = 4;
      testApparitionMenu();
    }
      break;

    case 4:
    {
      _iFin = 0;
      for(_iIndex = 0; _iIndex < iAboutNombreCaracteres; _iIndex++)
      {
        _oCaractere = &pTexteAbout[_iIndex];
        if(_oCaractere->animation2() != 0)
          _iFin = 1;
        _oCaractere->affiche();
      }
      if(_iFin == 0)
        iAction = 5;
      testApparitionMenu();
    }
      break;

      // Les lettres disparaissent (rotation)
    case 5:
    {
      _iFin = 1;
      for(_iIndex = 0; _iIndex < iAboutNombreCaracteres; _iIndex++)
      {
        _oCaractere = &pTexteAbout[_iIndex];
        if(_oCaractere->rotation2(3, 3, 300, 300) == 0)
          _iFin = 0;
        _oCaractere->animation();
        _oCaractere->affiche();
      }
      if(_iFin == 1)
      {
        iAction = 0;
        if(etat_menu == MENU_ON || pos_y_menu < BANDE_DE_CLIP + HAUT_ECR_RAM)
          iActionExecution = 0;
      }
      testApparitionMenu();
    }
      break;
  }
}

//=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
// ORDER : initialize / initialise
//=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=!=
int _score::creeOrder()
{
  char                   *_pTxt;
  unsigned int _iIndex;

  if(pTxtChaines == 0x0)
    pTxtChaines = new _chaine[iTXT_NBRELIGNES];
  // Reserve le tableau de caractere
  if(pTxtTableau == 0x0)
  {
    pTxtTableau = new char[iTXT_NBRELIGNES * iTXT_NBRECOL];

    _pTxt = pTxtTableau;
    for(_iIndex = 0; _iIndex < iTXT_NBRELIGNES * iTXT_NBRECOL; _iIndex++)
    {
      _pTxt[_iIndex] = ' ';
    }

  }
  int _iPosY = 128 + 7;

  _pTxt = pTxtTableau;
  for(_iIndex = 0; _iIndex < iTXT_NBRELIGNES; _iIndex++)
  {
    _chaine                *_oChaine = &pTxtChaines[_iIndex];

    _oChaine->initialise(_pTxt, iTXT_NBRECOL, 128, _iPosY, 16, 0);
    _iPosY += 16;
    _pTxt += iTXT_NBRECOL;
  }
  iTxtPosX = 0;
  iTxtPosY = 0;
  if(!chargeTable())
  {
    afficheErreur("_score::ChargeTable()", "score.cpp/creeOrder()");
    return 0;
  }
  iTableIndex = 2;                                             // premier element de la table est le 2 (avant c'est la somme de controle)
  iTableTempo = 0;
  effaceCaracteres();
  return 1;
}

//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--
// ORDER : Affiche le texte a la Commodore 64 / display text
// iTXT_PAUSE : attente de la valeur suivante (1 a 32767)
// iTXT_FIN : fin du fichier
// sinon code clavier 
// input => _iFlag      : 0 main menu's disable (etat_menu==MENU_OFF)
//                                                                      : 1 main menu's enable 
//--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--**--
void _score::executeOrder(int _iFlag)
{
  unsigned int           _iIndex;
  _chaine                *_oChaine;
  int _iCodeTouchePressee = 0;
  int _iCurseurAction = 0;

  // Donne l'ordonnee de toutes les chaines       
  unsigned int _iPosY = pos_y_menu - HAUT_ECR_RAM + 7;

  for(_iIndex = 0; _iIndex < iTXT_NBRELIGNES; _iIndex++)
  {
    _oChaine = &pTxtChaines[_iIndex];
    _oChaine->changePositionY(_iPosY);
    _iPosY += 16;
  }
  _oChaine = &pTxtChaines[iTxtPosY];                           // objet '_chaine' ou est le curseur

  switch (iAction)
  {
      // ORDER = entre le texte
    case 0:
    {
      _iCodeTouchePressee = _oChaine->entreeClavier();         //0=pas de code touche
      iTxtPosX = _oChaine->getCurseurPosition();
      _iCurseurAction = _oChaine->getCurseurAction();          //1=depassement a gauche / 2=depassement a droite
      if(_iCodeTouchePressee == 0)
      {
        iTableTempo++;
        if(iTableTempo >= 32767)
        {
          entreTableValeur(iTXT_PAUSE);                        // code attente
          entreTableValeur(iTableTempo);                       // delai attente
          iTableTempo = 0;
        }
      }
      else
      {
        if(iTableTempo > 0)
        {
          entreTableValeur(iTXT_PAUSE);                        // code attente
          entreTableValeur(iTableTempo);                       // delai attente
          iTableTempo = 0;
        }
        entreTableValeur(_iCodeTouchePressee);
      }
      if(etat_menu == MENU_ON || etat_menu == APPARITION_MENU)
      {
        iActionExecution = 0;
        entreTableValeur(iTXT_FIN);                            // fin du fichier
        sauveTable();
      }
    }
      break;
      // ORDER : affiche le texte a partir du fichier charge
    case 1:
    {
      _iCodeTouchePressee = 0;
      if(--iTableTempo <= 0)
      {
        unsigned short _valeur = sortTableValeur();

        if(_valeur == iTXT_PAUSE)
        {
          iTableTempo = sortTableValeur();
          iTableTempo = iTableTempo / 3;
        }
        else
        {
          _iCodeTouchePressee = _valeur;                       //force unsigned
#ifdef SDL_TLK
         
/*       printf("XK_BackSpace=%x, XK_Delete=%x, XK_Right=%x, XK_Left=%x, XK_Up=%x, XK_Down=%x, XK_Return=%x, XK_F3=%x, XK_F4=%x, XK_F5=%x, XK_Shift_L=%x, XK_Shift_R=%x\n",
         XK_BackSpace, XK_Delete, XK_Right, XK_Left, XK_Up, XK_Down, XK_Return, XK_F3, XK_F4, XK_F5, XK_Shift_L, XK_Shift_R);                   
*/
        switch(_iCodeTouchePressee)
        { case 0xff08 : //XK_BackSpace
            _iCodeTouchePressee = SDLK_BACKSPACE;
            break;
          case 0xffff: //XK_Delete
            _iCodeTouchePressee = SDLK_DELETE;
            break;
          case 0xff53: //XK_Right
            _iCodeTouchePressee = SDLK_RIGHT;
            break;
          case 0xff51: //XK_Left
            _iCodeTouchePressee = SDLK_LEFT;
            break;
          case 0xff52: //XK_Up
            _iCodeTouchePressee = SDLK_UP;
            break;
          case 0xff54: //XK_Down
            _iCodeTouchePressee = SDLK_DOWN;
            break;
          case 0xff0d: //XK_Return
            _iCodeTouchePressee = SDLK_RETURN;
            break;
          case 0xffc0: //XK_F3
            _iCodeTouchePressee = SDLK_F3;
            break;
          case 0xffc1: //XK_F4
            _iCodeTouchePressee = SDLK_F4;
            break;
          case 0xffc2: //XK_F5
            _iCodeTouchePressee = SDLK_F5;
            break;
          case 0xffe1: //XK_Shift_L
            _iCodeTouchePressee = SDLK_LSHIFT;
            break;
          case 0xffe2: //XK_Shift_R
            _iCodeTouchePressee = SDLK_RSHIFT;
            break;
        }
#endif
            
        }
      }
      _oChaine->entreeClavier(_iCodeTouchePressee);
      iTxtPosX = _oChaine->getCurseurPosition();
      _iCurseurAction = _oChaine->getCurseurAction();          //1=depassement a gauche / 2=depassement a droite
      if(etat_menu == MENU_ON || etat_menu == APPARITION_MENU)
      {
        iAction = 2;
      }
      testApparitionMenu();
    }
      break;

      // le menu monte
    case 2:
    {
      _iCodeTouchePressee = 0;
      _iCurseurAction = 0;
      if(etat_menu == MENU_ON)
      {
        iActionExecution = 0;
      }
    }
      break;
  }

  // test les touches speciales
  switch (_iCodeTouchePressee)
  {
#ifdef SDL_TLK
    case SDLK_DOWN:
#else      
    case XK_Down:
#endif
      if(++iTxtPosY >= iTXT_NBRELIGNES)
      {
        iTxtPosY = iTXT_NBRELIGNES - 1;
        supprimeLigne(0);
      }
      break;
#ifdef SDL_TLK
    case SDLK_UP:
#else      
    case XK_Up:
#endif
    if(iTxtPosY == 0)
      {
        insertLigne(iTxtPosY);
      }
      else
      {
        iTxtPosY--;
      }
      break;
#ifdef SDL_TLK
    case SDLK_INSERT:
#else      
    case XK_Insert:                                           // touche INSERT pressee
#endif
      insertLigne(iTxtPosY);
      break;
#ifdef SDL_TLK
    case SDLK_RETURN:
#else      
    case XK_Return:                                           // touche RETURN pressed ? (ASCII=13)
#endif
    if(++iTxtPosY >= iTXT_NBRELIGNES)
      {
        iTxtPosY = iTXT_NBRELIGNES - 1;
        supprimeLigne(0);
      }
      iTxtPosX = 0;
      break;
#ifdef SDL_TLK
    case SDLK_F3:
#else      
    case XK_F3:                                               // curseur en haut a gauche
#endif
      iTxtPosX = 0;
      iTxtPosY = 0;
      break;
#ifdef SDL_TLK
    case SDLK_F4:
#else      
    case XK_F4:                                               // curseur en haut a gauche & efface l'ecran
#endif
      effaceCaracteres();
      break;
#ifdef SDL_TLK 
    case SDLK_F5:
#else      
    case XK_F5:                                               // supprime la ligne en cours
#endif
      supprimeLigne(iTxtPosY);
      break;
  }                                                            // fin test des touches speciales

  // test les depassements horizontaux du curseur
  switch (_iCurseurAction)
  {
    case 1:                                                   // Curseur depassement gauche
      if(iTxtPosY == 0)
      {
        insertLigne(iTxtPosY);
      }
      else
      {
        iTxtPosY--;
      }
      iTxtPosX = iTXT_NBRECOL - 1;
      break;
    case 2:                                                   // curseur depassement a droite
      if(++iTxtPosY >= iTXT_NBRELIGNES)
      {
        iTxtPosY = iTXT_NBRELIGNES - 1;
        supprimeLigne(0);
        iTxtPosX = 0;
      }
      else
        iTxtPosX = 0;
      break;
  }
  // donne la nouvelle position du cuseur
  _oChaine = &pTxtChaines[iTxtPosY];
  _oChaine->setCurseurPosition(iTxtPosX);
  // affiche toutes les chaines
  for(_iIndex = 0; _iIndex < iTXT_NBRELIGNES; _iIndex++)
  {
    _oChaine = &pTxtChaines[_iIndex];
    _oChaine->affiche();
    _oChaine->animation2Tous();
  }
}

// ------------------------------------------------------------------------------
// order :
// ------------------------------------------------------------------------------
void _score::effaceCaracteres()
{
  char                   *_pDestination;
  unsigned int _iIndex;

  iTxtPosX = 0;
  iTxtPosY = 0;
  _pDestination = pTxtTableau;
  for(_iIndex = 0; _iIndex < iTXT_NBRELIGNES * iTXT_NBRECOL; _iIndex++)
    *(_pDestination++) = ' ';
  for(_iIndex = 0; _iIndex < iTXT_NBRELIGNES; _iIndex++)
  {
    _chaine                *_oChaine = &pTxtChaines[_iIndex];

    _oChaine->initialiseSprite();
  }
}

// ------------------------------------------------------------------------------
// order : insert text line
// ------------------------------------------------------------------------------
// entree => _iLigne de 0 a 11
void _score::insertLigne(int _iLigne)
{
  char                   *_pDestination =
    pTxtTableau + (iTXT_NBRECOL * iTXT_NBRELIGNES) - 1;
  char                   *_pSource = _pDestination - iTXT_NBRECOL;
  unsigned int _iIndex;

  for(_iIndex = 0; _iIndex < (iTXT_NBRELIGNES - 1 - _iLigne) * iTXT_NBRECOL;
      _iIndex++)
  {
    *(_pDestination--) = *(_pSource--);
  }
  _pSource++;
  for(_iIndex = 0; _iIndex < iTXT_NBRECOL; _iIndex++)
  {
    *(_pSource++) = ' ';
  }
  for(_iIndex = 0; _iIndex < iTXT_NBRELIGNES; _iIndex++)
  {
    _chaine                *_oChaine = &pTxtChaines[_iIndex];

    _oChaine->initialiseSprite();
  }
}

// ------------------------------------------------------------------------------
// order :
// ------------------------------------------------------------------------------
// entree => _iLigne de 0 a 10
void _score::supprimeLigne(int _iLigne)
{
  char                   *_pDestination =
    pTxtTableau + (_iLigne * iTXT_NBRECOL);
  char                   *_pSource = _pDestination + iTXT_NBRECOL;
  unsigned int _iIndex;

  for(_iIndex = 0; _iIndex < (iTXT_NBRELIGNES - 1 - _iLigne) * iTXT_NBRECOL;
      _iIndex++)
  {
    *(_pDestination++) = *(_pSource++);
  }
  for(_iIndex = 0; _iIndex < iTXT_NBRECOL; _iIndex++)
  {
    *(--_pSource) = ' ';
  }
  for(_iIndex = 0; _iIndex < iTXT_NBRELIGNES; _iIndex++)
  {
    _chaine                *_oChaine = &pTxtChaines[_iIndex];

    _oChaine->initialiseSprite();
  }
}

// ------------------------------------------------------------------------------
// order :
// ------------------------------------------------------------------------------
// Charge la table de commande  -----------------------------------------------
int _score::chargeTable()
{
  if(pTableCommande == 0)
  {
    pTableCommande = (unsigned short *)reserveMemoire(iTXT_FICHIERTAILLE);
    if(!pTableCommande)
      return 0;
  }
  if(chargeFichier("graphics/pmorder.xxx", (char *)pTableCommande))
  {
    int _iSomme2 = *pTableCommande;                            // somme d'auto-controle du fichier
    int _iSomme =
      calculSomme((int *)pTableCommande, (iTXT_FICHIERTAILLE / 4) - 1);
    if(_iSomme2 != _iSomme)
      iAction = 0;
    iAction = 1;                                               // on se contente d'afficher le texte
  }
  //le fichier n'existe pas / file not found
  else
  {
    for(unsigned int _iIndex = 0; _iIndex < iTXT_FICHIERTAILLE / 2; _iIndex++)
    { pTableCommande[_iIndex] = 0;
    }
    iAction = 0;                                               // on rentre un nouveau texte
  }
  return 1;
}

// Sauvegarde la table de commande  -------------------------------------------
void _score::sauveTable()
{
  int _iSomme =calculSomme((int *)pTableCommande, (iTXT_FICHIERTAILLE / 4) - 1);
  *pTableCommande = _iSomme;
  int _iHandle = open("graphics/pmorder.xxx", O_WRONLY | O_CREAT, 0666);        //ouvre le fichier
  if(_iHandle == -1)
  { printf("_score::sauveTable() : can't open file : \"pmorder.xxx\"\n\n");
  }
  else
  {
    write(_iHandle, pTableCommande, iTXT_FICHIERTAILLE);
    close(_iHandle);
  }
}

// Entre une valeur dans la table de commande  --------------------------------
void _score::entreTableValeur(unsigned short _sValeur)
{
  if(iTableIndex < iTXT_FICHIERTAILLE - 1)
  { pTableCommande[iTableIndex++] = _sValeur;                  // sauve code 
    //printf("entreTableValeur : %i", _sValeur) ;
    //if(_sValeur>32 && _sValeur <= 'z') printf(" ==> %c", (char)(_sValeur)) ;
    //printf("\n") ;
  }
}

// Sort une valeur dans la table de commande  ---------------------------------
unsigned short _score::sortTableValeur()
{
  unsigned short _sValeur = (unsigned short) litMot16bits(
    (short*) &pTableCommande[iTableIndex++]
  );
  unsigned short _sValeur2 = (unsigned short) litMot16bits(
    (short*) &pTableCommande[iTableIndex]
  );
  
  if(iTableIndex >= iTXT_FICHIERTAILLE
     || _sValeur2 == iTXT_FIN)
  { effaceCaracteres();
    iTableIndex = 2;
    afficheMessage("Fin du fichier pmorder.xxx");
  }
  //printf("sortTableValeur : %i", _sValeur) ;
  //if(_sValeur>32 && _sValeur <= 'z') printf(" ==> %c", (char)(_sValeur)) ;
  //printf("\n") ;
  return _sValeur;
}

// Test si quitte le menu -----------------------------------------------------
void _score::testApparitionMenu()
{
  if(iCodeTouche != 0 && etat_menu == MENU_OFF)
  { etat_menu = APPARITION_MENU;                               //met le flag apparition du menu a 1
    Init_Scroll_Present();                                     //initialise le defilement du texte en bas
  }
}
// F3: // curseur en haut a gauche
// F4: // curseur en haut a gauche & efface l'ecran
// F5: // supprime la ligne en cours
/*
.THIS..PROGRAM..
IS FREE SOFTWARE
....YOU..CAN.... 
..REDISTRIBUTE..
...IT..AND/OR...
...MODIFY..IT...
...UNDER..THE...
TERMS OF THE GNU
.GENERAL PUBLIC.
...LICENSE AS...
..PUBLISHED.BY..
....THE FREE....
....SOFTWARE....
...FOUNDATION...
EITHER VERSION 2
.OF.THE LICENSE.
.......OR.......
(AT.YOUR.OPTION)
...ANY..LATER...
....VERSION.....
................
................
SEE THE GNU.....
GENERAL PUBLIC..
LICENSE FOR MORE
DETAILS.........
................
....(c) 2002....
...TLK..GAMES...
................
.LINUX..VERSION.
.......BY.......
BRUNO..ETHVIGNOT
......AND.......
.ANDRE..MAJOREL.
................
................
..Greetings.to..

.Alex...Senesse.
.Andre..Majorel.
Aurelien.Anselme
.David..Alardet.
..David.Igreja..
Delph..Ethvignot
Didier..Florentz
Emeric.Pourcelot
.Etienne.Sobole.
.Gaelle.Richard.
.Gautier.Portet.
..Hafida.Bouih..
J-Michel..Martin
J-Francois.Kabak
Karine.Philippon
Laurent.Guibelin
.Laurent..Tenza.
.M-J.Robertella.
.Nicolas.Arnaud.
Olivier..Simonin
Pascal.Ethvignot
..Pascal.Lauly..
Philip..Bouveret
Philip.Jacquemet
.Roderic.Moitie.
Sandrine..Berger
.Sophie.Bibanov.
..Sylvain.Cote..
..Yoan.Daubeze..
.Valerie.Arnaud.

*/
