Пример #1
0
long csavecompressed(char *finam, __block tobesaved, color pala[256], long exto)
{
  Stream *outpt;

  if (exto > 0) {
    outpt = ci_fopen(finam, Common::kFile_Create, Common::kFile_ReadWrite);
    outpt->Seek(Common::kSeekBegin, exto);
  } 
  else
    outpt = ci_fopen(finam, Common::kFile_CreateAlways, Common::kFile_Write);

  int widt, hit;
  long ofes;
  widt = *tobesaved++;
  widt += (*tobesaved++) * 256;
  hit = *tobesaved++;
  hit += (*tobesaved++) * 256;
  // Those were originally written as shorts, although they are ints
  outpt->WriteInt16(widt);
  outpt->WriteInt16(hit);

  unsigned char *ress = (unsigned char *)malloc(widt + 1);
  int ww;

  for (ww = 0; ww < hit; ww++) {
    for (int ss = 0; ss < widt; ss++)
      (*ress++) = (*tobesaved++);

    ress -= widt;
    cpackbitl(ress, widt, outpt);
  }

  for (ww = 0; ww < 256; ww++) {
    outpt->WriteInt8(pala[ww].r);
    outpt->WriteInt8(pala[ww].g);
    outpt->WriteInt8(pala[ww].b);
  }

  ofes = outpt->GetPosition();
  delete outpt;
  free(ress);
  return ofes;
}
Пример #2
0
void start_playback()
{
    Stream *in = Common::File::OpenFileRead(replayfile);
    if (in != NULL) {
        char buffer [100];
        in->Read(buffer, 12);
        buffer[12] = 0;
        if (strcmp (buffer, "AGSRecording") != 0) {
            Display("ERROR: Invalid recorded data file");
            play.playback = 0;
        }
        else {
            String version_string = String::FromStream(in, 12);
            AGS::Engine::Version requested_engine_version(version_string);
            if (requested_engine_version.Major != '2') 
                quit("!Replay file is from an old version of AGS");
            if (requested_engine_version < AGS::Engine::Version(2, 55, 553))
                quit("!Replay file was recorded with an older incompatible version");

            if (requested_engine_version != EngineVersion) {
                // Disable text as speech while displaying the warning message
                // This happens if the user's graphics card does BGR order 16-bit colour
                int oldalways = game.options[OPT_ALWAYSSPCH];
                game.options[OPT_ALWAYSSPCH] = 0;
                play.playback = 0;
                Display("Warning! replay is from a different version of AGS (%s) - it may not work properly.", buffer);
                play.playback = 1;
                srand (play.randseed);
                play.gamestep = 0;
                game.options[OPT_ALWAYSSPCH] = oldalways;
            }

            int replayver = in->ReadInt32();

            if ((replayver < 1) || (replayver > 3))
                quit("!Unsupported Replay file version");

            if (replayver >= 2) {
                fgetstring_limit (buffer, in, 99);
                int uid = in->ReadInt32 ();
                if ((strcmp (buffer, game.gamename) != 0) || (uid != game.uniqueid)) {
                    char msg[150];
                    sprintf (msg, "!This replay is meant for the game '%s' and will not work correctly with this game.", buffer);
                    delete in;
                    quit (msg);
                }
                // skip the total time
                in->ReadInt32 ();
                // replay description, maybe we'll use this later
                fgetstring_limit (buffer, in, 99);
            }

            play.randseed = in->ReadInt32();
            int flen = in->GetLength() - in->GetPosition ();
            if (replayver >= 3) {
                flen = in->ReadInt32() * sizeof(short);
            }
            recordbuffer = (short*)malloc (flen);
            in->Read(recordbuffer, flen);
            srand (play.randseed);
            recbuffersize = flen / sizeof(short);
            recsize = 0;
            disable_mgetgraphpos = 1;
            replay_time = 0;
            replay_last_second = loopcounter;
            if (replayver >= 3) {
                int issave = in->ReadInt32();
                if (issave) {
                    if (RestoreGameState(in, kSvgVersion_321) != kSvgErr_NoError)
                        quit("!Error running replay... could be incorrect game version");
                    replay_last_second = loopcounter;
                }
            }
            delete in;
        }
    }
    else // file not found
        play.playback = 0;
}
Пример #3
0
int SpriteCache::saveToFile(const char *filnam, int lastElement, bool compressOutput)
{
  Stream *output = Common::File::CreateFile(filnam);
  if (output == NULL)
    return -1;

  if (compressOutput) {
    // re-open the file so that it can be seeked
    delete output;
    output = File::OpenFile(filnam, Common::kFile_Open, Common::kFile_ReadWrite); // CHECKME why mode was "r+" here?
    if (output == NULL)
      return -1;
  }

  int spriteFileIDCheck = (int)time(NULL);

  // version 6
  output->WriteInt16(6);

  output->WriteArray(spriteFileSig, strlen(spriteFileSig), 1);

  output->WriteInt8(compressOutput ? 1 : 0);
  output->WriteInt32(spriteFileIDCheck);

  int i, lastslot = 0;
  if (elements < lastElement)
    lastElement = elements;

  for (i = 1; i < lastElement; i++) {
    // slot empty
    if ((images[i] != NULL) || ((offsets[i] != 0) && (offsets[i] != sprite0InitialOffset)))
      lastslot = i;
  }

  output->WriteInt16(lastslot);

  // allocate buffers to store the indexing info
  int numsprits = lastslot + 1;
  short *spritewidths = (short*)malloc(numsprits * sizeof(short));
  short *spriteheights = (short*)malloc(numsprits * sizeof(short));
  int32_t *spriteoffs = (int32_t*)malloc(numsprits * sizeof(int32_t));

  const int memBufferSize = 100000;
  char *memBuffer = (char*)malloc(memBufferSize);

  for (i = 0; i <= lastslot; i++) {

    spriteoffs[i] = output->GetPosition();

    // if compressing uncompressed sprites, load the sprite into memory
    if ((images[i] == NULL) && (this->spritesAreCompressed != compressOutput))
      (*this)[i];

    if (images[i] != NULL) {
      // image in memory -- write it out
      pre_save_sprite(i);
      int bpss = images[i]->GetColorDepth() / 8;
      spritewidths[i] = images[i]->GetWidth();
      spriteheights[i] = images[i]->GetHeight();
      output->WriteInt16(bpss);
      output->WriteInt16(spritewidths[i]);
      output->WriteInt16(spriteheights[i]);

      if (compressOutput) {
        size_t lenloc = output->GetPosition();
        // write some space for the length data
        output->WriteInt32(0);

        compressSprite(images[i], output);

        size_t fileSizeSoFar = output->GetPosition();
        // write the length of the compressed data
        output->Seek(Common::kSeekBegin, lenloc);
        output->WriteInt32((fileSizeSoFar - lenloc) - 4);
        output->Seek(Common::kSeekEnd, 0);
      }
      else
        output->WriteArray(images[i]->GetDataForWriting(), spritewidths[i] * bpss, spriteheights[i]);

      continue;
    }

    if ((offsets[i] == 0) || ((offsets[i] == sprite0InitialOffset) && (i > 0))) {
      // sprite doesn't exist
      output->WriteInt16(0);
      spritewidths[i] = 0;
      spriteheights[i] = 0;
      spriteoffs[i] = 0;
      continue;
    }

    // not in memory -- seek to it in the source file
    seekToSprite(i);
    lastLoad = i;

    short colDepth = cache_stream->ReadInt16();
    output->WriteInt16(colDepth);

    if (colDepth == 0) {
      continue;
    }

    if (this->spritesAreCompressed != compressOutput) {
      // shouldn't be able to get here
      free(memBuffer);
      delete output;
      return -2;
    }

    // and copy the data across
    int width = cache_stream->ReadInt16();
    int height = cache_stream->ReadInt16();

    spritewidths[i] = width;
    spriteheights[i] = height;

    output->WriteInt16(width);
    output->WriteInt16(height);

    int sizeToCopy;
    if (this->spritesAreCompressed) {
      sizeToCopy = cache_stream->ReadInt32();
      output->WriteInt32(sizeToCopy);
    }
    else {
      sizeToCopy = width * height * (int)colDepth;
    }

    while (sizeToCopy > memBufferSize) {
      cache_stream->ReadArray(memBuffer, memBufferSize, 1);
      output->WriteArray(memBuffer, memBufferSize, 1);
      sizeToCopy -= memBufferSize;
    }

    cache_stream->ReadArray(memBuffer, sizeToCopy, 1);
    output->WriteArray(memBuffer, sizeToCopy, 1);
  }

  free(memBuffer);

  delete output;

  // write the sprite index file
  Stream *spindex_out = File::CreateFile(spindexfilename);
  // write "SPRINDEX" id
  spindex_out->WriteArray(&spindexid[0], strlen(spindexid), 1);
  // write version (1)
  spindex_out->WriteInt32(2);
  spindex_out->WriteInt32(spriteFileIDCheck);
  // write last sprite number and num sprites, to verify that
  // it matches the spr file
  spindex_out->WriteInt32(lastslot);
  spindex_out->WriteInt32(numsprits);
  spindex_out->WriteArrayOfInt16(&spritewidths[0], numsprits);
  spindex_out->WriteArrayOfInt16(&spriteheights[0], numsprits);
  spindex_out->WriteArrayOfInt32(&spriteoffs[0], numsprits);
  delete spindex_out;

  free(spritewidths);
  free(spriteheights);
  free(spriteoffs);

  return 0;
}