Logo Search packages:      
Sourcecode: hex-a-hop version File versions  Download package

savestate.h

/*
    Copyright (C) 2005-2007 Tom Beaumont

    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
*/


struct HexPuzzle;

00022 class LevelSave
{
      friend struct HexPuzzle;

      char * bestSolution;
      int bestSolutionLength;
      int bestScore;
      #define NUM_LAST_SCORES 19
      int lastScores[NUM_LAST_SCORES];
      int unlocked;
public:
      LevelSave()
      {
            Clear();
      }
      void Clear()
      {
            unlocked = 0;
            bestSolution = 0;
            bestScore = 0;
            bestSolutionLength = 0;
            memset(lastScores, 0, sizeof(lastScores));      
      }
      void LoadSave(FILE* f, bool save)
      {
            typedef unsigned int _fn(void*, unsigned int, unsigned int, FILE*);
            _fn * fn = save ? (_fn*)fwrite : (_fn*)fread;

            fn(&bestSolutionLength, sizeof(bestSolutionLength), 1, f);
            fn(&bestScore, sizeof(bestScore), 1, f);
            fn(&lastScores, sizeof(lastScores), 1, f);
            fn(&unlocked, sizeof(unlocked), 1, f);          
            
            if (bestSolutionLength)
            {
                  if (!save) SetSolution(bestSolutionLength);
                  fn(bestSolution, sizeof(bestSolution[0]), bestSolutionLength, f);
            }
      }

      void Dump()
      {
            for (int j=1; j<NUM_LAST_SCORES; j++)
                  if (lastScores[j]==lastScores[0])
                        lastScores[j] = 0;

/*          for (int i=0; i<NUM_LAST_SCORES && lastScores[i]; i++)
                  if (lastScores[i] != bestScore)
                        printf("\t% 8d\n", lastScores[i]);*/
      }
      bool Completed()
      {
            return bestScore != 0;
      }
      bool IsNewCompletionBetter(int score)
      {
            for (int i=0; i<NUM_LAST_SCORES; i++)
            {
                  if (lastScores[i]==0)
                        lastScores[i] = score;
                  if (lastScores[i]==score)
                        break;
            }

            if (!Completed())
                  return true;

            return score <= bestScore;
      }
      bool PassesPar(int par)
      {
            if (!Completed())
                  return false;
            return bestScore <= par;
      }
      int GetScore()
      {
            return bestScore;
      }
      void SetScore(int s)
      {
            bestScore = s;
      }
      void SetSolution(int l) { 
            delete [] bestSolution;
            bestSolutionLength = l;
            bestSolution = new char [ l ];
      }
      void SetSolutionStep(int pos, int val)
      {
            bestSolution[pos] = val;
      }
};

00116 class SaveState
{
00118       struct X : public LevelSave
      {
            X* next;
            char* name;

            X(const char* n, X* nx=0) : next(nx)
            {
                  name = new char[strlen(n)+1];
                  strcpy(name, n);
            }
            ~X()
            {
                  delete [] name;
            }
      };

00134       struct General {
            int scoringOn;
            int hintFlags;
            int completionPercentage;
            int endSequence;
            int masteredPercentage;
            int pad[6];
      };

      X* first;

      void ClearRaw()
      {
            memset(&general, 0, sizeof(general));
            general.hintFlags = 1<<31 | 1<<30;

            X* x=first;
            while (x)
            {
                  X* nx = x->next;
                  delete x;
                  x = nx;
            }
            first = 0;

      }

public:
      
      General general;


      SaveState() : first(0)
      {
            Clear();
      }

      ~SaveState()
      {
            ClearRaw();
      }

      void Clear()
      {
            ClearRaw();
            ApplyStuff();
      }

      void GetStuff();
      void ApplyStuff();

      void LoadSave(FILE* f, bool save)
      {
            if (save)
            {
                  GetStuff();

                  //printf("----\n");

                  fputc('2', f);
                  fwrite(&general, sizeof(general), 1, f);
                  for(X* x=first; x; x=x->next)
                  {
                        short len = strlen(x->name);
                        fwrite(&len, sizeof(len), 1, f);
                        fwrite(x->name, len, 1, f);

                        x->LoadSave(f,save);

                        if (x->Completed())
                        {
                              //printf("% 8d %s\n", x->GetScore(), x->name);
                              x->Dump();
                        }
                  }
            }
            else
            {
                  ClearRaw();
                  int v = fgetc(f);
                  if (v=='2')
                  {
                        fread(&general, sizeof(general), 1, f);
                        v = '1';
                  }
                  if (v=='1')
                  {
                        while(!feof(f))
                        {
                              char temp[1000];
                              short len;
                              fread(&len, sizeof(len), 1, f);
                              if (feof(f)) break;
                              fread(temp, len, 1, f);
                              temp[len] = 0;
                              first = new X(temp, first);

                              first->LoadSave(f,save);
                        }
                  }

                  ApplyStuff();
            }
      }

      LevelSave* GetLevel(const char * name, bool create)
      {
            char * l = strstr(name, "Levels");
            if (l)
                  name = l;

            X* x = first;
            if (x && strcmp(name, x->name)==0) return x;
            while (x && x->next)
            {
                  if (strcmp(name, x->next->name)==0) return x->next;
                  x = x->next;
            }
            if (create)
            {
                  X* n = new X(name);
                  if (x)
                        x->next = n;
                  else
                        first = n;
                  return n;
            }
            else
            {
                  return 0;
            }
      }
};

Generated by  Doxygen 1.6.0   Back to index