Exemplo n.º 1
0
bool WaveFileWriter::Start(const std::string& filename, unsigned int HLESampleRate)
{
  // Check if the file is already open
  if (file)
  {
    PanicAlertT("The file %s was already open, the file header will not be written.",
                filename.c_str());
    return false;
  }

  file.Open(filename, "wb");
  if (!file)
  {
    PanicAlertT("The file %s could not be opened for writing. Please check if it's already opened "
                "by another program.",
                filename.c_str());
    return false;
  }

  audio_size = 0;

  if (basename.empty())
    SplitPath(filename, nullptr, &basename, nullptr);

  current_sample_rate = HLESampleRate;

  // -----------------
  // Write file header
  // -----------------
  Write4("RIFF");
  Write(100 * 1000 * 1000);  // write big value in case the file gets truncated
  Write4("WAVE");
  Write4("fmt ");

  Write(16);          // size of fmt block
  Write(0x00020001);  // two channels, uncompressed

  const u32 sample_rate = HLESampleRate;
  Write(sample_rate);
  Write(sample_rate * 2 * 2);  // two channels, 16bit

  Write(0x00100004);
  Write4("data");
  Write(100 * 1000 * 1000 - 32);

  // We are now at offset 44
  if (file.Tell() != 44)
    PanicAlert("Wrong offset: %lld", (long long)file.Tell());

  return true;
}
Exemplo n.º 2
0
static void WriteData(lcd * pLCD, const uint8_t Data) 
{
  SetMode(pLCD, modeWriteData);
  
  Write4(pLCD, Data>>4);
  Write4(pLCD, Data);
}
Exemplo n.º 3
0
static void WriteCommand(lcd * pLCD, const uint8_t Command) 
{
  SetMode(pLCD, modeWriteCommand);
  
  Write4(pLCD, Command>>4);
  Write4(pLCD, Command);
}
Exemplo n.º 4
0
/* fetchkey():
   This massages the key into a form that's easier to handle. When it
   returns, the key will be stored in keybuf if keysize <= 4; otherwise,
   it will be in memory.
*/
static void fetchkey(unsigned char *keybuf, glui32 key, glui32 keysize, 
  glui32 options)
{
  int ix;

  if (options & serop_KeyIndirect) {
    if (keysize <= 4) {
      for (ix=0; ix<keysize; ix++)
        keybuf[ix] = Mem1(key+ix);
    }
  }
  else {
    switch (keysize) {
    case 4:
      Write4(keybuf, key);
      break;
    case 2:
      Write2(keybuf, key);
      break;
    case 1:
      Write1(keybuf, key);
      break;
    default:
      fatal_error("Direct search key must hold one, two, or four bytes.");
    }
  }
}
Exemplo n.º 5
0
bool WaveFileWriter::Start(const char *filename, unsigned int HLESampleRate)
{
	if (!conv_buffer)
		conv_buffer = new short[BUF_SIZE];

	// Check if the file is already open
	if (file)
	{
		PanicAlertT("The file %s was already open, the file header will not be written.", filename);
		return false;
	}

	file.Open(filename, "wb");
	if (!file)
	{
		PanicAlertT("The file %s could not be opened for writing. Please check if it's already opened by another program.", filename);
		return false;
	}

	// -----------------
	// Write file header
	// -----------------
	Write4("RIFF");
	Write(100 * 1000 * 1000);  // write big value in case the file gets truncated
	Write4("WAVE");
	Write4("fmt ");

	Write(16);  // size of fmt block
	Write(0x00020001); //two channels, uncompressed

	const u32 sample_rate = HLESampleRate;
	Write(sample_rate);
	Write(sample_rate * 2 * 2); //two channels, 16bit

	Write(0x00100004);
	Write4("data");
	Write(100 * 1000 * 1000 - 32);

	// We are now at offset 44
	if (file.Tell() != 44)
		PanicAlert("wrong offset: %lld", (long long)file.Tell());

	return true;
}
Exemplo n.º 6
0
int main(int argc, char** argv) {
  if (argc != 4) {
    fprintf(stderr, "usage: %s <src-img> <tgt-img> <patch-file>\n", argv[0]);
    return 2;
  }

  int num_src_chunks;
  ImageChunk* src_chunks;
  if (ReadImage(argv[1], &num_src_chunks, &src_chunks) == NULL) {
    fprintf(stderr, "failed to break apart source image\n");
    return 1;
  }

  int num_tgt_chunks;
  ImageChunk* tgt_chunks;
  if (ReadImage(argv[2], &num_tgt_chunks, &tgt_chunks) == NULL) {
    fprintf(stderr, "failed to break apart target image\n");
    return 1;
  }

  // Verify that the source and target images have the same chunk
  // structure (ie, the same sequence of gzip and normal chunks).

  if (num_src_chunks != num_tgt_chunks) {
    fprintf(stderr, "source and target don't have same number of chunks!\n");
    return 1;
  }
  int i;
  for (i = 0; i < num_src_chunks; ++i) {
    if (src_chunks[i].type != tgt_chunks[i].type) {
      fprintf(stderr, "source and target don't have same chunk "
              "structure! (chunk %d)\n", i);
      return 1;
    }
  }

  // Confirm that given the uncompressed chunk data in the target, we
  // can recompress it and get exactly the same bits as are in the
  // input target image.  If this fails, treat the chunk as a normal
  // non-gzipped chunk.

  for (i = 0; i < num_tgt_chunks; ++i) {
    if (tgt_chunks[i].type == CHUNK_GZIP) {
      if (ReconstructGzipChunk(tgt_chunks+i) < 0) {
        printf("failed to reconstruct target gzip chunk %d; "
               "treating as normal chunk\n", i);
        ChangeGzipChunkToNormal(tgt_chunks+i);
        ChangeGzipChunkToNormal(src_chunks+i);
      } else {
        printf("reconstructed target gzip chunk %d\n", i);
      }
    }
  }

  // Compute bsdiff patches for each chunk's data (the uncompressed
  // data, in the case of gzip chunks).

  unsigned char** patch_data = malloc(num_src_chunks * sizeof(unsigned char*));
  size_t* patch_size = malloc(num_src_chunks * sizeof(size_t));
  for (i = 0; i < num_src_chunks; ++i) {
    patch_data[i] = MakePatch(src_chunks+i, tgt_chunks+i, patch_size+i);
    printf("patch %d is %d bytes (of %d)\n", i, patch_size[i],
           tgt_chunks[i].type == CHUNK_NORMAL ? tgt_chunks[i].len : tgt_chunks[i].gzip_len);

  }

  // Figure out how big the imgdiff file header is going to be, so
  // that we can correctly compute the offset of each bsdiff patch
  // within the file.

  size_t total_header_size = 12;
  for (i = 0; i < num_src_chunks; ++i) {
    total_header_size += 4 + 8*3;
    if (src_chunks[i].type == CHUNK_GZIP) {
      total_header_size += 8*2 + 4*6 + tgt_chunks[i].gzip_header_len + 8;
    }
  }

  size_t offset = total_header_size;

  FILE* f = fopen(argv[3], "wb");

  // Write out the headers.

  fwrite("IMGDIFF1", 1, 8, f);
  Write4(num_src_chunks, f);
  for (i = 0; i < num_tgt_chunks; ++i) {
    Write4(tgt_chunks[i].type, f);
    Write8(src_chunks[i].start, f);
    Write8(src_chunks[i].type == CHUNK_NORMAL ? src_chunks[i].len :
           (src_chunks[i].gzip_len + src_chunks[i].gzip_header_len + 8), f);
    Write8(offset, f);

    if (tgt_chunks[i].type == CHUNK_GZIP) {
      Write8(src_chunks[i].len, f);
      Write8(tgt_chunks[i].len, f);
      Write4(tgt_chunks[i].level, f);
      Write4(tgt_chunks[i].method, f);
      Write4(tgt_chunks[i].windowBits, f);
      Write4(tgt_chunks[i].memLevel, f);
      Write4(tgt_chunks[i].strategy, f);
      Write4(tgt_chunks[i].gzip_header_len, f);
      fwrite(tgt_chunks[i].gzip_header, 1, tgt_chunks[i].gzip_header_len, f);
      fwrite(tgt_chunks[i].gzip_footer, 1, GZIP_FOOTER_LEN, f);
    }

    offset += patch_size[i];
  }

  // Append each chunk's bsdiff patch, in order.

  for (i = 0; i < num_tgt_chunks; ++i) {
    fwrite(patch_data[i], 1, patch_size[i], f);
  }

  fclose(f);

  return 0;
}
Exemplo n.º 7
0
int main(int argc, char** argv) {
  int zip_mode = 0;

  if (argc >= 2 && strcmp(argv[1], "-z") == 0) {
    zip_mode = 1;
    --argc;
    ++argv;
  }

  size_t bonus_size = 0;
  unsigned char* bonus_data = NULL;
  if (argc >= 3 && strcmp(argv[1], "-b") == 0) {
    struct stat st;
    if (stat(argv[2], &st) != 0) {
      printf("failed to stat bonus file %s: %s\n", argv[2], strerror(errno));
      return 1;
    }
    bonus_size = st.st_size;
    bonus_data = malloc(bonus_size);
    FILE* f = fopen(argv[2], "rb");
    if (f == NULL) {
      printf("failed to open bonus file %s: %s\n", argv[2], strerror(errno));
      return 1;
    }
    if (fread(bonus_data, 1, bonus_size, f) != bonus_size) {
      printf("failed to read bonus file %s: %s\n", argv[2], strerror(errno));
      return 1;
    }
    fclose(f);

    argc -= 2;
    argv += 2;
  }

  if (argc != 4) {
    usage:
    printf("usage: %s [-z] [-b <bonus-file>] <src-img> <tgt-img> <patch-file>\n",
            argv[0]);
    return 2;
  }

  int num_src_chunks;
  ImageChunk* src_chunks;
  int num_tgt_chunks;
  ImageChunk* tgt_chunks;
  int i;

  if (zip_mode) {
    if (ReadZip(argv[1], &num_src_chunks, &src_chunks, 1) == NULL) {
      printf("failed to break apart source zip file\n");
      return 1;
    }
    if (ReadZip(argv[2], &num_tgt_chunks, &tgt_chunks, 0) == NULL) {
      printf("failed to break apart target zip file\n");
      return 1;
    }
  } else {
    if (ReadImage(argv[1], &num_src_chunks, &src_chunks) == NULL) {
      printf("failed to break apart source image\n");
      return 1;
    }
    if (ReadImage(argv[2], &num_tgt_chunks, &tgt_chunks) == NULL) {
      printf("failed to break apart target image\n");
      return 1;
    }

    // Verify that the source and target images have the same chunk
    // structure (ie, the same sequence of deflate and normal chunks).

    if (!zip_mode) {
        // Merge the gzip header and footer in with any adjacent
        // normal chunks.
        MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks);
        MergeAdjacentNormalChunks(src_chunks, &num_src_chunks);
    }

    if (num_src_chunks != num_tgt_chunks) {
      printf("source and target don't have same number of chunks!\n");
      printf("source chunks:\n");
      DumpChunks(src_chunks, num_src_chunks);
      printf("target chunks:\n");
      DumpChunks(tgt_chunks, num_tgt_chunks);
      return 1;
    }
    for (i = 0; i < num_src_chunks; ++i) {
      if (src_chunks[i].type != tgt_chunks[i].type) {
        printf("source and target don't have same chunk "
                "structure! (chunk %d)\n", i);
        printf("source chunks:\n");
        DumpChunks(src_chunks, num_src_chunks);
        printf("target chunks:\n");
        DumpChunks(tgt_chunks, num_tgt_chunks);
        return 1;
      }
    }
  }

  for (i = 0; i < num_tgt_chunks; ++i) {
    if (tgt_chunks[i].type == CHUNK_DEFLATE) {
      // Confirm that given the uncompressed chunk data in the target, we
      // can recompress it and get exactly the same bits as are in the
      // input target image.  If this fails, treat the chunk as a normal
      // non-deflated chunk.
      if (ReconstructDeflateChunk(tgt_chunks+i) < 0) {
        printf("failed to reconstruct target deflate chunk %d [%s]; "
               "treating as normal\n", i, tgt_chunks[i].filename);
        ChangeDeflateChunkToNormal(tgt_chunks+i);
        if (zip_mode) {
          ImageChunk* src = FindChunkByName(tgt_chunks[i].filename, src_chunks, num_src_chunks);
          if (src) {
            ChangeDeflateChunkToNormal(src);
          }
        } else {
          ChangeDeflateChunkToNormal(src_chunks+i);
        }
        continue;
      }

      // If two deflate chunks are identical (eg, the kernel has not
      // changed between two builds), treat them as normal chunks.
      // This makes applypatch much faster -- it can apply a trivial
      // patch to the compressed data, rather than uncompressing and
      // recompressing to apply the trivial patch to the uncompressed
      // data.
      ImageChunk* src;
      if (zip_mode) {
        src = FindChunkByName(tgt_chunks[i].filename, src_chunks, num_src_chunks);
      } else {
        src = src_chunks+i;
      }

      if (src == NULL || AreChunksEqual(tgt_chunks+i, src)) {
        ChangeDeflateChunkToNormal(tgt_chunks+i);
        if (src) {
          ChangeDeflateChunkToNormal(src);
        }
      }
    }
  }

  // Merging neighboring normal chunks.
  if (zip_mode) {
    // For zips, we only need to do this to the target:  deflated
    // chunks are matched via filename, and normal chunks are patched
    // using the entire source file as the source.
    MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks);
  } else {
    // For images, we need to maintain the parallel structure of the
    // chunk lists, so do the merging in both the source and target
    // lists.
    MergeAdjacentNormalChunks(tgt_chunks, &num_tgt_chunks);
    MergeAdjacentNormalChunks(src_chunks, &num_src_chunks);
    if (num_src_chunks != num_tgt_chunks) {
      // This shouldn't happen.
      printf("merging normal chunks went awry\n");
      return 1;
    }
  }

  // Compute bsdiff patches for each chunk's data (the uncompressed
  // data, in the case of deflate chunks).

  DumpChunks(src_chunks, num_src_chunks);

  printf("Construct patches for %d chunks...\n", num_tgt_chunks);
  unsigned char** patch_data = malloc(num_tgt_chunks * sizeof(unsigned char*));
  size_t* patch_size = malloc(num_tgt_chunks * sizeof(size_t));
  for (i = 0; i < num_tgt_chunks; ++i) {
    if (zip_mode) {
      ImageChunk* src;
      if (tgt_chunks[i].type == CHUNK_DEFLATE &&
          (src = FindChunkByName(tgt_chunks[i].filename, src_chunks,
                                 num_src_chunks))) {
        patch_data[i] = MakePatch(src, tgt_chunks+i, patch_size+i);
      } else {
        patch_data[i] = MakePatch(src_chunks, tgt_chunks+i, patch_size+i);
      }
    } else {
      if (i == 1 && bonus_data) {
        printf("  using %zu bytes of bonus data for chunk %d\n", bonus_size, i);
        src_chunks[i].data = realloc(src_chunks[i].data, src_chunks[i].len + bonus_size);
        memcpy(src_chunks[i].data+src_chunks[i].len, bonus_data, bonus_size);
        src_chunks[i].len += bonus_size;
     }

      patch_data[i] = MakePatch(src_chunks+i, tgt_chunks+i, patch_size+i);
    }
    printf("patch %3d is %zd bytes (of %zd)\n",
           i, patch_size[i], tgt_chunks[i].source_len);
  }

  // Figure out how big the imgdiff file header is going to be, so
  // that we can correctly compute the offset of each bsdiff patch
  // within the file.

  size_t total_header_size = 12;
  for (i = 0; i < num_tgt_chunks; ++i) {
    total_header_size += 4;
    switch (tgt_chunks[i].type) {
      case CHUNK_NORMAL:
        total_header_size += 8*4;
        break;
      case CHUNK_DEFLATE:
        total_header_size += 8*6 + 4*5;
        break;
      case CHUNK_RAW:
        total_header_size += 4 + patch_size[i];
        break;
    }
  }

  size_t offset = total_header_size;

  FILE* f = fopen(argv[3], "wb");

  // Write out the headers.

  fwrite("IMGDIFFX", 1, 8, f);
  Write4(num_tgt_chunks, f);
  for (i = 0; i < num_tgt_chunks; ++i) {
    Write4(tgt_chunks[i].type, f);

    switch (tgt_chunks[i].type) {
      case CHUNK_NORMAL:
        printf("chunk %3d: normal   (%10zd, %10zd)  %10zd\n", i,
               tgt_chunks[i].start, tgt_chunks[i].len, patch_size[i]);
        Write8(tgt_chunks[i].source_start, f);
        Write8(tgt_chunks[i].source_len, f);
        Write8(offset, f);
        Write8(patch_size[i], f);
        offset += patch_size[i];
        break;

      case CHUNK_DEFLATE:
        printf("chunk %3d: deflate  (%10zd, %10zd)  %10zd  %s\n", i,
               tgt_chunks[i].start, tgt_chunks[i].deflate_len, patch_size[i],
               tgt_chunks[i].filename);
        Write8(tgt_chunks[i].source_start, f);
        Write8(tgt_chunks[i].source_len, f);
        Write8(offset, f);
        Write8(patch_size[i], f);
        Write8(tgt_chunks[i].source_uncompressed_len, f);
        Write8(tgt_chunks[i].len, f);
        Write4(tgt_chunks[i].level, f);
        Write4(tgt_chunks[i].method, f);
        Write4(tgt_chunks[i].windowBits, f);
        Write4(tgt_chunks[i].memLevel, f);
        Write4(tgt_chunks[i].strategy, f);
        offset += patch_size[i];
        break;

      case CHUNK_RAW:
        printf("chunk %3d: raw      (%10zd, %10zd)\n", i,
               tgt_chunks[i].start, tgt_chunks[i].len);
        Write4(patch_size[i], f);
        fwrite(patch_data[i], 1, patch_size[i], f);
        break;
    }
  }

  // Append each chunk's bsdiff patch, in order.

  for (i = 0; i < num_tgt_chunks; ++i) {
    if (tgt_chunks[i].type != CHUNK_RAW) {
      fwrite(patch_data[i], 1, patch_size[i], f);
    }
  }

  fclose(f);

  return 0;
}
Exemplo n.º 8
0
static int write_long(dest_t *dest, glui32 val)
{
  unsigned char buf[4];
  Write4(buf, val);
  return write_buffer(dest, buf, 4);
}