Exemple #1
0
int
lynx_n (st_rominfo_t *rominfo, const char *name)
{
  st_lnx_header_t header;
  char dest_name[FILENAME_MAX];

  if (!rominfo->buheader_len)
    {
      fprintf (stderr, "ERROR: This is no LNX file\n\n");
      return -1;
    }

  ucon64_fread (&header, 0, sizeof (st_lnx_header_t), ucon64.rom);

  memset (header.cartname, 0, sizeof (header.cartname));
  strncpy (header.cartname, name, sizeof (header.cartname));

  strcpy (dest_name, ucon64.rom);
  ucon64_file_handler (dest_name, NULL, 0);
  fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
  ucon64_fwrite (&header, 0, sizeof (st_lnx_header_t), dest_name, "r+b");

  printf (ucon64_msg[WROTE], dest_name);
  return 0;
}
Exemple #2
0
int
pce_f (st_ucon64_nfo_t *rominfo)
/*
  Region protection codes are found in (American) TurboGrafx-16 games. It
  prevents those games from running on a PC-Engine. One search pattern seems
  sufficient to fix/crack all TG-16 games. In addition to that, the protection
  code appears to be always somewhere in the first 32 kB.
*/
{
  char src_name[FILENAME_MAX], dest_name[FILENAME_MAX], buffer[32 * 1024];
  int bytesread, n;

  puts ("Attempting to fix region protection code...");

  strcpy (src_name, ucon64.fname);
  strcpy (dest_name, ucon64.fname);
  ucon64_file_handler (dest_name, src_name, 0);
  fcopy (src_name, 0, ucon64.file_size, dest_name, "wb"); // no copy if one file

  if ((bytesread = ucon64_fread (buffer, rominfo->backup_header_len, 32 * 1024, src_name)) <= 0)
    return -1;

  // '!' == ASCII 33 (\x21), '*' == 42 (\x2a)
  if (rominfo->interleaved)
    n = change_mem (buffer, bytesread, "\x94\x02\x0f", 3, '*', '!', "\x01", 1, 0);
  else
    n = change_mem (buffer, bytesread, "\x29\x40\xf0", 3, '*', '!', "\x80", 1, 0);

  ucon64_fwrite (buffer, rominfo->backup_header_len, 32 * 1024, dest_name, "r+b");

  printf ("Found %d pattern%s\n", n, n != 1 ? "s" : "");
  printf (ucon64_msg[WROTE], dest_name);
  remove_temp_file ();
  return n;
}
Exemple #3
0
int
pce_swap (st_ucon64_nfo_t *rominfo)
{
  char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
  unsigned char *rom_buffer;
  int size = ucon64.file_size - rominfo->backup_header_len;

  if ((rom_buffer = (unsigned char *) malloc (size)) == NULL)
    {
      fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], size);
      return -1;
    }

  strcpy (src_name, ucon64.fname);
  strcpy (dest_name, ucon64.fname);
  ucon64_file_handler (dest_name, src_name, 0);

  if (rominfo->backup_header_len)                    // copy header (if present)
    fcopy (src_name, 0, rominfo->backup_header_len, dest_name, "wb");

  ucon64_fread (rom_buffer, rominfo->backup_header_len, size, src_name);
  swapbits (rom_buffer, size);
  ucon64_fwrite (rom_buffer, rominfo->backup_header_len, size, dest_name,
            rominfo->backup_header_len ? "ab" : "wb");
  free (rom_buffer);

  printf (ucon64_msg[WROTE], dest_name);
  remove_temp_file ();
  return 0;
}
Exemple #4
0
static int
lynx_b (st_rominfo_t *rominfo, int bank, const char *value)
{
  st_lnx_header_t header;
  short int *bankvar;
  char dest_name[FILENAME_MAX];

  if (!rominfo->buheader_len)
    {
      fprintf (stderr, "ERROR: This is no LNX file\n\n");
      return -1;
    }

  ucon64_fread (&header, 0, sizeof (st_lnx_header_t), ucon64.rom);

  bankvar = (bank == 0 ? &header.page_size_bank0 : &header.page_size_bank1);
  if ((atol (value) % 64) != 0 || (atol (value) > 512))
    *bankvar = 0;
  else
#ifdef  WORDS_BIGENDIAN
    *bankvar = bswap_16 (atol (value) * 4);
#else
    *bankvar = atol (value) * 4;
#endif

  strcpy (dest_name, ucon64.rom);
  ucon64_file_handler (dest_name, NULL, 0);
  fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
  ucon64_fwrite (&header, 0, sizeof (st_lnx_header_t), dest_name, "r+b");

  printf (ucon64_msg[WROTE], dest_name);
  return 0;
}
Exemple #5
0
int
dc_parse (const char *templ_file)
{
    char ip[0x8000], dest_name[FILENAME_MAX];

    if (access (templ_file, F_OK) == -1)
    {
        int i = 0;

        printf ("Creating empty template file: \"%s\"\n", templ_file);

        for (i = 0; templ[i].name; i++)
            set_property (templ_file, templ[i].name, templ[i].def, templ[i].comment);

        printf (ucon64_msg[WROTE], templ_file);
    }

    if (parse_templ (templ_file, ip) == -1)
        return -1;

    update_crc (ip);

    strcpy (dest_name, "ip.bin");
    ucon64_file_handler (dest_name, NULL, 0);

    ucon64_fwrite (ip, 0, 0x8000, dest_name, "wb");

    printf (ucon64_msg[WROTE], dest_name);
    return 0;
}
Exemple #6
0
int
ppf_set_fid (const char *ppf, const char *fidname)
{
    int fidsize, ppfsize, pos;
    char ppfname[FILENAME_MAX],
         fidbuf[MAX_ID_SIZE + 34 + 1] = "@BEGIN_FILE_ID.DIZ"; // +1 for string terminator

    strcpy (ppfname, ppf);
    ucon64_file_handler (ppfname, NULL, 0);
    fcopy (ppf, 0, fsizeof (ppf), ppfname, "wb"); // no copy if one file

    printf ("Adding FILE_ID.DIZ (%s)...\n", fidname);
    fidsize = ucon64_fread (fidbuf + 18, 0, MAX_ID_SIZE, fidname);
    memcpy (fidbuf + 18 + fidsize, "@END_FILE_ID.DIZ", 16);

    ppfsize = fsizeof (ppfname);
    pos = ucon64_find (ppfname, 0, ppfsize, "@BEGIN_FILE_ID.DIZ", 18,
                       MEMCMP2_CASE | UCON64_FIND_QUIET);
    if (pos == -1)
        pos = ppfsize;
    truncate (ppfname, pos);

    ucon64_fwrite (fidbuf, pos, fidsize + 18 + 16, ppfname, "r+b");
    pos += fidsize + 18 + 16;
#ifdef  WORDS_BIGENDIAN
    fidsize = bswap_32 (fidsize);                 // Write file size in little-endian format
#endif
    ucon64_fwrite (&fidsize, pos, 4, ppfname, "r+b");

    printf (ucon64_msg[WROTE], ppfname);
    return 0;
}
Exemple #7
0
int
mccl_read (const char *filename, unsigned int parport)
{
  unsigned char buffer[0x1760], inbyte;
  char dest_name[FILENAME_MAX];
  int count = 0;
  time_t starttime;

  parport_print_info ();
  puts ("Resetting device");
  do
    {
      outportb (CONTROL, 0x24);
      while ((inportb (STATUS) & 0x20) == 0)
        ;
    }
  while ((inportw (DATA) & 0xf) != 4);
  outportb (CONTROL, 0x22);
  while ((inportb (STATUS) & 0x20) != 0)
    ;
  outportb (CONTROL, 0x26);

  printf ("Receive: %d Bytes (%.4f Mb)\n\n", 0x1760, (float) 0x1760 / MBIT);
  starttime = time (NULL);
  do
    {
      outportb (CONTROL, 0x26);
      while ((inportb (STATUS) & 0x20) == 0)
        ;
      inbyte = (unsigned char) (inportw (DATA) & 0xf);
      outportb (CONTROL, 0x22);
      while ((inportb (STATUS) & 0x20) != 0)
        ;
      outportb (CONTROL, 0x26);
      while ((inportb (STATUS) & 0x20) == 0)
        ;
      inbyte |= (unsigned char) ((inportw (DATA) & 0xf) << 4);
      outportb (CONTROL, 0x22);
      while ((inportb (STATUS) & 0x20) != 0)
        ;
      buffer[count++] = inbyte;
      if ((count & 0x1f) == 0)
        ucon64_gauge (starttime, count, 0x1760);
    }
  while (count < 0x1760);

  strcpy (dest_name, filename);
  ucon64_file_handler (dest_name, NULL, 0);
  ucon64_fwrite (buffer, 0, count, dest_name, "wb");
  printf (ucon64_msg[WROTE], dest_name);
  return 0;
}
Exemple #8
0
int
dc_unscramble (void)
{
    char dest_name[FILENAME_MAX];

    strcpy (dest_name, ucon64.fname);
    ucon64_file_handler (dest_name, NULL, 0);

    if (!descramble (ucon64.fname, ucon64.file_size, dest_name))
        printf (ucon64_msg[WROTE], dest_name);
    else
        fprintf (stderr, ucon64_msg[WRITE_ERROR], dest_name);
    return 0;
}
Exemple #9
0
int
ppf_set_desc (const char *ppf, const char *description)
{
    char desc[50], ppfname[FILENAME_MAX];

    strcpy (ppfname, ppf);
    memset (desc, ' ', 50);
    strncpy (desc, description, strlen (description));
    ucon64_file_handler (ppfname, NULL, 0);
    fcopy (ppf, 0, fsizeof (ppf), ppfname, "wb"); // no copy if one file
    ucon64_fwrite (desc, 6, 50, ppfname, "r+b");

    printf (ucon64_msg[WROTE], ppfname);
    return 0;
}
Exemple #10
0
int
lynx_lnx (st_rominfo_t *rominfo)
{
  st_lnx_header_t header;
  char dest_name[FILENAME_MAX];
  int size = ucon64.file_size;

  if (rominfo->buheader_len != 0)
    {
      fprintf (stderr, "ERROR: This seems to already be an LNX file\n\n");
      return -1;
    }

  header.page_size_bank0 = size > 4 * MBIT ? 4 * MBIT / 256 : size / 256;
  header.page_size_bank1 = size > 4 * MBIT ? (size - (4 * MBIT)) / 256 : 0;
#ifdef  WORDS_BIGENDIAN
  header.page_size_bank0 = bswap_16 (header.page_size_bank0);
  header.page_size_bank1 = bswap_16 (header.page_size_bank1);
#endif

  memset (header.cartname, 0, sizeof (header.cartname));
  memset (header.manufname, 0, sizeof (header.manufname));
  memset (header.spare, 0, sizeof (header.spare));

#ifdef  WORDS_BIGENDIAN
  header.version = bswap_16 (1);
#else
  header.version = 1;
#endif

  memcpy (header.magic, "LYNX", 4);
  header.rotation = 0;
  strncpy (header.cartname, ucon64.rom, sizeof (header.cartname));
  strcpy (header.manufname, "Atari");

  strcpy (dest_name, ucon64.rom);
  set_suffix (dest_name, ".lnx");

  ucon64_file_handler (dest_name, NULL, 0);
  ucon64_fwrite (&header, 0, sizeof (st_lnx_header_t), dest_name, "wb");
  fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "ab");

  printf (ucon64_msg[WROTE], dest_name);
  return 0;
}
Exemple #11
0
// header format is specified in src/backup/ffe.h
int
pce_msg (st_ucon64_nfo_t *rominfo)
{
  char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
  unsigned char *rom_buffer = NULL;
  st_msg_header_t header;
  int size = ucon64.file_size - rominfo->backup_header_len;

  if (rominfo->interleaved)
    if ((rom_buffer = (unsigned char *) malloc (size)) == NULL)
      {
        fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], size);
        return -1;
      }

  memset (&header, 0, MSG_HEADER_LEN);
  header.size = (unsigned char) (size / 8192);
  header.emulation = size == 3 * MBIT ? 1 : 0;
  header.id1 = 0xaa;
  header.id2 = 0xbb;
  header.type = 2;

  strcpy (src_name, ucon64.fname);
  strcpy (dest_name, ucon64.fname);
  set_suffix (dest_name, ".msg");
  ucon64_file_handler (dest_name, src_name, 0);

  ucon64_fwrite (&header, 0, MSG_HEADER_LEN, dest_name, "wb");
  if (rominfo->interleaved)
    {
      // Magic Super Griffin files should not be "interleaved"
      ucon64_fread (rom_buffer, rominfo->backup_header_len, size, src_name);
      swapbits (rom_buffer, size);
      ucon64_fwrite (rom_buffer, MSG_HEADER_LEN, size, dest_name, "ab");
      free (rom_buffer);
    }
  else
    fcopy (src_name, rominfo->backup_header_len, size, dest_name, "ab");

  printf (ucon64_msg[WROTE], dest_name);
  remove_temp_file ();
  return 0;
}
Exemple #12
0
int
lynx_lyx (st_rominfo_t *rominfo)
{
  char dest_name[FILENAME_MAX];

  if (!rominfo->buheader_len)
    {
      fprintf (stderr, "ERROR: This is no LNX file\n\n");
      return -1;
    }

  strcpy (dest_name, ucon64.rom);
  set_suffix (dest_name, ".lyx");

  ucon64_file_handler (dest_name, NULL, 0);
  fcopy (ucon64.rom, rominfo->buheader_len, ucon64.file_size, dest_name, "wb");

  printf (ucon64_msg[WROTE], dest_name);
  return 0;
}
Exemple #13
0
// see src/backup/mgd.h for the file naming scheme
int
pce_mgd (st_ucon64_nfo_t *rominfo)
{
  char src_name[FILENAME_MAX], dest_name[FILENAME_MAX];
  unsigned char *rom_buffer = NULL;
  int size = ucon64.file_size - rominfo->backup_header_len;

  if (!rominfo->interleaved)
    if ((rom_buffer = (unsigned char *) malloc (size)) == NULL)
      {
        fprintf (stderr, ucon64_msg[ROM_BUFFER_ERROR], size);
        return -1;
      }

  strcpy (src_name, ucon64.fname);
  mgd_make_name (ucon64.fname, UCON64_PCE, size, dest_name);
  ucon64_file_handler (dest_name, src_name, OF_FORCE_BASENAME);

  // bit-swapping images for the MGD2 only makes sense for owners of a TG-16
  //  (American version of the PCE)
  if (!rominfo->interleaved)
    {
      ucon64_fread (rom_buffer, rominfo->backup_header_len, size, src_name);
      swapbits (rom_buffer, size);
      ucon64_fwrite (rom_buffer, 0, size, dest_name, "wb");
      free (rom_buffer);
    }
  else
    fcopy (src_name, rominfo->backup_header_len, size, dest_name, "wb");

  printf (ucon64_msg[WROTE], dest_name);
  remove_temp_file ();

  mgd_write_index_file ((char *) basename2 (dest_name), 1);
  return 0;
}
Exemple #14
0
static int
lynx_rot (st_rominfo_t *rominfo, int rotation)
{
  st_lnx_header_t header;
  char dest_name[FILENAME_MAX];

  if (!rominfo->buheader_len)
    {
      fprintf (stderr, "ERROR: This is no LNX file\n\n");
      return -1;
    }

  ucon64_fread (&header, 0, sizeof (st_lnx_header_t), ucon64.rom);

  header.rotation = rotation;                   // header.rotation is an 8-bit field

  strcpy (dest_name, ucon64.rom);
  ucon64_file_handler (dest_name, NULL, 0);
  fcopy (ucon64.rom, 0, ucon64.file_size, dest_name, "wb");
  ucon64_fwrite (&header, 0, sizeof (st_lnx_header_t), dest_name, "r+b");

  printf (ucon64_msg[WROTE], dest_name);
  return 0;
}
Exemple #15
0
// based on sourcecode of MakePPF v2.0 Linux/Unix by Icarus/Paradox
int
ppf_create (const char *orgname, const char *modname)
{
    FILE *orgfile, *modfile, *ppffile;
    char ppfname[FILENAME_MAX], buffer[MAX_ID_SIZE], obuf[512], mbuf[512];
#if 0
    char *fidname = "FILE_ID.DIZ";
#endif
    int x, osize, msize, blocksize, n_changes, total_changes = 0;
    unsigned int seekpos = 0, pos;

    osize = fsizeof (orgname);
    msize = fsizeof (modname);
#ifndef DIFF_FSIZE
    if (osize != msize)
    {
        fprintf (stderr, "ERROR: File sizes do not match\n");
        return -1;
    }
#endif

    if ((orgfile = fopen (orgname, "rb")) == NULL)
    {
        fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], orgname);
        exit (1);
    }
    if ((modfile = fopen (modname, "rb")) == NULL)
    {
        fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], modname);
        exit (1);
    }
    strcpy (ppfname, modname);
    set_suffix (ppfname, ".ppf");
    ucon64_file_handler (ppfname, NULL, 0);
    if ((ppffile = fopen (ppfname, "wb")) == NULL)
    {
        fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], ppfname);
        exit (1);
    }

    // creating PPF 2.0 header
    fwrite ("PPF20", 5, 1, ppffile);              // magic
    fputc (1, ppffile);                           // encoding method
    memset (buffer, ' ', 50);
    fwrite (buffer, 50, 1, ppffile);              // description line
#ifdef  WORDS_BIGENDIAN
    x = bswap_32 (osize);
    fwrite (&x, 4, 1, ppffile);
#else
    fwrite (&osize, 4, 1, ppffile);               // orgfile size
#endif
    fseek (orgfile, 0x9320, SEEK_SET);
    memset (buffer, 0, 1024);                     // one little hack that makes PPF
    fread (buffer, 1024, 1, orgfile);             //  suitable for files < 38688 bytes
    fwrite (buffer, 1024, 1, ppffile);            // 1024 byte block

    printf ("Writing patch data, please wait...\n");
    // finding changes
    fseek (orgfile, 0, SEEK_SET);
    fseek (modfile, 0, SEEK_SET);
    while ((blocksize = fread (obuf, 1, 255, orgfile)))
    {
        blocksize = fread (mbuf, 1, blocksize, modfile);
#ifdef  DIFF_FSIZE
        if (blocksize == 0)
            break;
#endif
        pos = seekpos;
        x = 0;
        while (x != blocksize)
        {
            if (obuf[x] != mbuf[x])
            {
                pos = seekpos + x;
                n_changes = 0;
                do
                {
                    buffer[n_changes] = mbuf[x];
                    n_changes++;
                    x++;
                }
                while (x != blocksize && obuf[x] != mbuf[x]);
                total_changes += n_changes;
#ifdef  WORDS_BIGENDIAN
                pos = bswap_32 (pos);
#endif
                fwrite (&pos, 4, 1, ppffile);
                fputc (n_changes, ppffile);
                fwrite (buffer, n_changes, 1, ppffile);
            }
            else
                x++;
        }
        seekpos += blocksize;
    }

#ifdef  DIFF_FSIZE
    if (msize > osize)
    {
        pos = seekpos;
        while ((blocksize = fread (buffer, 1, 255, modfile)))
        {
            total_changes += blocksize;
#ifdef  WORDS_BIGENDIAN
            x = bswap_32 (pos);
            fwrite (&x, 4, 1, ppffile);
#else
            fwrite (&pos, 4, 1, ppffile);
#endif
            fputc (blocksize, ppffile);
            fwrite (buffer, blocksize, 1, ppffile);
            pos += blocksize;
        }
    }
    else if (msize < osize)
        printf ("WARNING: %s is smaller than %s\n"
                "         PPF can't store information about that fact\n",
                modname, orgname);
#endif

    fclose (orgfile);
    fclose (modfile);

    if (total_changes == 0)
    {
        printf ("%s and %s are identical\n"
                "Removing: %s\n", orgname, modname, ppfname);
        fclose (ppffile);
        remove (ppfname);
        return -1;
    }

#if 0
    if (fidname)
    {
        int fsize = fsizeof (fidname);
        if (fsize > MAX_ID_SIZE)
            fsize = MAX_ID_SIZE;                    // File id only up to 3072 bytes!
        printf ("Adding FILE_ID.DIZ (%s)...\n", fidname);
        ucon64_fread (buffer, 0, fsize, fidname);
        fwrite ("@BEGIN_FILE_ID.DIZ", 18, 1, ppffile);
        fwrite (buffer, fsize, 1, ppffile);
        fwrite ("@END_FILE_ID.DIZ", 16, 1, ppffile);
#ifdef  WORDS_BIGENDIAN
        fsize = bswap_32 (fsize);                 // Write file size in little-endian format
#endif
        fwrite (&fsize, 4, 1, ppffile);
    }
#endif
    fclose (ppffile);

    printf (ucon64_msg[WROTE], ppfname);
    return 0;
}
Exemple #16
0
// based on source code of ApplyPPF v2.0 for Linux/Unix by Icarus/Paradox
int
ppf_apply (const char *mod, const char *ppfname)
{
    FILE *modfile, *ppffile;
    char desc[50 + 1], diz[MAX_ID_SIZE + 1], buffer[1024], ppfblock[1024],
         modname[FILENAME_MAX];
    int x, method, dizlen = 0, modlen, ppfsize, bytes_to_skip = 0, n_changes;
    unsigned int pos;

    strcpy (modname, mod);
    ucon64_file_handler (modname, NULL, 0);
    fcopy (mod, 0, fsizeof (mod), modname, "wb"); // no copy if one file

    if ((modfile = fopen (modname, "r+b")) == NULL)
    {
        fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], modname);
        exit (1);
    }
    if ((ppffile = fopen (ppfname, "rb")) == NULL)
    {
        fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], ppfname);
        exit (1);
    }

    // Is it a PPF File?
    fread (buffer, 3, 1, ppffile);
    if (strncmp ("PPF", buffer, 3))
    {
        fprintf (stderr, "ERROR: %s is not a valid PPF file\n", ppfname);
        exit (1);
    }

    // What encoding method? PPF 1.0 or PPF 2.0?
    fseek (ppffile, 5, SEEK_SET);
    method = fgetc (ppffile);
    if (method != 0 && method != 1)
    {
        fprintf (stderr, "ERROR: Unknown encoding method! Check for updates\n");
        exit (1);
    }

    ppfsize = fsizeof (ppfname);

    // Show PPF information
    fseek (ppffile, 6, SEEK_SET);                 // Read description line
    fread (desc, 50, 1, ppffile);
    desc[50] = 0;                                 // terminate string
    printf ("\n"                                  // print a newline between
            "Filename        : %s\n", ppfname);   //  backup message and PPF info
    printf ("Encoding method : %d (PPF %d.0)\n", method, method + 1);
    printf ("Description     : %s\n", desc);

    if (method == 0)                              // PPF 1.0
    {
        printf ("FILE_ID.DIZ     : No\n\n");
        x = 56;                                   // file pointer is at right position (56)
    }
    else // method == 1                           // PPF 2.0
    {
        fseek (ppffile, ppfsize - 8, SEEK_SET);
        fread (buffer, 4, 1, ppffile);

        // Is there a file id?
        if (strncmp (".DIZ", buffer, 4))
            printf ("FILE_ID.DIZ     : No\n\n");
        else
        {
            printf ("FILE_ID.DIZ     : Yes, showing...\n");
            fread (&dizlen, 4, 1, ppffile);
#ifdef  WORDS_BIGENDIAN
            dizlen = bswap_32 (dizlen);           // FILE_ID.DIZ size is in little-endian format
#endif
            fseek (ppffile, ppfsize - dizlen - (16 + 4), SEEK_SET);
            bytes_to_skip = dizlen + 18 + 16 + 4; // +4 for FILE_ID.DIZ size integer
            if (dizlen > MAX_ID_SIZE)
                dizlen = MAX_ID_SIZE;               // do this after setting bytes_to_skip!
            fread (diz, dizlen, 1, ppffile);
            diz[dizlen] = 0;                      // terminate string
            puts (diz);
        }

        // Do the file size check
        fseek (ppffile, 56, SEEK_SET);
        fread (&x, 4, 1, ppffile);
#ifdef  WORDS_BIGENDIAN
        x = bswap_32 (x);                         // file size is stored in little-endian format
#endif
        modlen = fsizeof (modname);
        if (x != modlen)
        {
            fprintf (stderr, "ERROR: The size of %s is not %d bytes\n", modname, x);
            exit (1);
        }

        // Do the binary block check
        fseek (ppffile, 60, SEEK_SET);
        fread (ppfblock, 1024, 1, ppffile);
        fseek (modfile, 0x9320, SEEK_SET);
        memset (buffer, 0, 1024);                 // one little hack that makes PPF
        fread (buffer, 1024, 1, modfile);         //  suitable for files < 38688 bytes
        if (memcmp (ppfblock, buffer, 1024))
        {
            fprintf (stderr, "ERROR: This patch does not belong to this image\n");
            exit (1);
        }

        fseek (ppffile, 1084, SEEK_SET);
        x = 1084;
    }

    // Patch the image
    printf ("Patching...\n");
    for (; x < ppfsize - bytes_to_skip; x += 4 + 1 + n_changes)
    {
        fread (&pos, 4, 1, ppffile);              // Get position for modfile
#ifdef  WORDS_BIGENDIAN
        pos = bswap_32 (pos);
#endif
        n_changes = fgetc (ppffile);              // How many bytes do we have to write?
        fread (buffer, n_changes, 1, ppffile);    // And this is what we have to write
        fseek (modfile, pos, SEEK_SET);           // Go to the right position in the modfile
        fwrite (buffer, n_changes, 1, modfile);   // Write n_changes bytes to that pos
    }

    printf ("Done\n");
    fclose (ppffile);
    fclose (modfile);

    printf (ucon64_msg[WROTE], modname);
    return 0;
}
Exemple #17
0
int
bsl_apply (const char *mod, const char *bslname)
{
  FILE *modfile, *bslfile;
  unsigned char byte;
  char buf[4096], modname[FILENAME_MAX];
  int data, nbytes, offset;

  strcpy (modname, mod);
  ucon64_file_handler (modname, NULL, 0);
  fcopy (mod, 0, fsizeof (mod), modname, "wb"); // no copy if one file

  if ((modfile = fopen (modname, "r+b")) == NULL)
    {
      fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], modname);
      return -1;
    }
  if ((bslfile = fopen (bslname, "rb")) == NULL)
    {
      fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], bslname);
      return -1;
    }

  printf ("Applying BSL/Baseline patch...\n");

  while (!feof (bslfile))                       // we could use 1, but feof() makes it fail-safe
    {
      fscanf (bslfile, "%d\n", &offset);
      fscanf (bslfile, "%d\n", &data);
      if ((offset == -1) && (data == -1))
        break;

      fseek (modfile, offset, SEEK_SET);
      fputc (data, modfile);
    }

  fscanf (bslfile, "%d\n", &offset);
  fscanf (bslfile, "%d\n", &nbytes);
  fseek (modfile, offset, SEEK_SET);
  if (nbytes > 0)
    {
      while (nbytes > 4096)
        {
          fread (buf, 4096, 1, bslfile);
          fwrite (buf, 4096, 1, modfile);
          nbytes -= 4096;
        }
      while (nbytes-- >= 0)                     // yes, one byte more than the
        {                                       //  _value_ read from the BSL file
          byte = (unsigned char) fgetc (bslfile);
          fputc (byte, modfile);
        }
    }

  printf ("Patching complete\n\n");
  printf (ucon64_msg[WROTE], modname);
  printf ("\n"
          "NOTE: Sometimes you have to add/strip a 512 bytes header when you patch a ROM\n"
          "      This means you must modify for example a SNES ROM with -swc or -stp or\n"
          "      the patch will not work\n");

  fclose (bslfile);
  fclose (modfile);

  return 0;
}
Exemple #18
0
int
pce_multi (int truncate_size, char *fname)
{
#define BUFSIZE (32 * 1024)
  int n, n_files, file_no, bytestowrite, byteswritten, done, truncated = 0,
      totalsize = 0, size, org_do_not_calc_crc = ucon64.do_not_calc_crc;
  struct stat fstate;
  FILE *srcfile, *destfile;
  char destname[FILENAME_MAX];
  unsigned char buffer[BUFSIZE];

  if (truncate_size == 0)
    {
      fprintf (stderr, "ERROR: Cannot make multi-game file of 0 bytes\n");
      return -1;
    }

  if (fname != NULL)
    {
      strcpy (destname, fname);
      n_files = ucon64.argc;
    }
  else
    {
      strcpy (destname, ucon64.argv[ucon64.argc - 1]);
      n_files = ucon64.argc - 1;
    }

  ucon64_file_handler (destname, NULL, OF_FORCE_BASENAME);
  if ((destfile = fopen (destname, "wb")) == NULL)
    {
      fprintf (stderr, ucon64_msg[OPEN_WRITE_ERROR], destname);
      return -1;
    }

  printf ("Creating multi-game file for PCE-PRO: %s\n", destname);

  file_no = 0;
  for (n = 1; n < n_files; n++)
    {
      if (access (ucon64.argv[n], F_OK))
        continue;                               // "file" does not exist (option)
      stat (ucon64.argv[n], &fstate);
      if (!S_ISREG (fstate.st_mode))
        continue;
      if (file_no == 32)                        // loader + 31 games
        {
          printf ("WARNING: A multi-game file can contain a maximum of 31 games. The other files\n"
                  "         are ignored.\n");
          break;
        }

      ucon64.console = UCON64_UNKNOWN;
      ucon64.fname = ucon64.argv[n];
      ucon64.file_size = fsizeof (ucon64.fname);
      // DON'T use fstate.st_size, because file could be compressed
      ucon64.do_not_calc_crc = 1;
      if (pce_init (ucon64.nfo) != 0)
        printf ("WARNING: %s does not appear to be a PC-Engine ROM\n", ucon64.fname);

      if ((srcfile = fopen (ucon64.fname, "rb")) == NULL)
        {
          fprintf (stderr, ucon64_msg[OPEN_READ_ERROR], ucon64.fname);
          continue;
        }
      if (ucon64.nfo->backup_header_len)
        fseek (srcfile, ucon64.nfo->backup_header_len, SEEK_SET);
      size = ucon64.file_size - ucon64.nfo->backup_header_len;

      if (file_no == 0)
        {
          printf ("Loader: %s\n", ucon64.fname);
          if (size != PCE_PRO_LOADER_SIZE)
            printf ("WARNING: Are you sure %s is a loader binary?\n", ucon64.fname);
        }
      else
        {
          printf ("ROM%d: %s\n", file_no, ucon64.fname);
          write_game_table_entry (destfile, file_no, totalsize, size);
        }
      file_no++;

      done = 0;
      byteswritten = 0;                         // # of bytes written per file
      while (!done)
        {
          bytestowrite = fread (buffer, 1, BUFSIZE, srcfile);
          if (totalsize + bytestowrite > truncate_size)
            {
              bytestowrite = truncate_size - totalsize;
              done = 1;
              truncated = 1;
              printf ("Output file needs %d Mbit on flash card, truncating %s, skipping %d bytes\n",
                      truncate_size / MBIT, ucon64.fname, size - (byteswritten + bytestowrite));
            }
          totalsize += bytestowrite;
          if (bytestowrite == 0)
            done = 1;
          fwrite (buffer, 1, bytestowrite, destfile);
          byteswritten += bytestowrite;
        }

      // Be sure the ROM size is a multiple of the buffer size used in
      //  pce_write_rom(), which is 0x4000 (16 kB, so using "buffer" is OK).
      bytestowrite = ((size + 0x3fff) & ~0x3fff) - size;
      if (bytestowrite)
        {
          memset (buffer, 0xff, bytestowrite);
          totalsize += bytestowrite;
          fwrite (buffer, 1, bytestowrite, destfile);
        }

      // pce_write_rom() handles alignment. Games have to be aligned to a Mbit
      //  boundary.
      totalsize = (totalsize + MBIT - 1) & ~(MBIT - 1);
      if (size == 3 * MBIT || size == 4 * MBIT)
        totalsize += 2 * MBIT;
      fclose (srcfile);
      if (truncated)
        break;
    }
  // fill the next game table entry
  fseek (destfile, 0xb000 + (file_no - 1) * 0x20, SEEK_SET);
  fputc (0, destfile);                          // indicate no next game

  // Make it possible for pce_write_rom() to detect that the file is a
  //  multi-game file.
  fseek (destfile, 0xb3f4, SEEK_SET);
  strncpy ((char *) buffer, "uCON64 " UCON64_VERSION_S, 12);
  buffer[12] = 0;
  fwrite (buffer, 1, strlen ((char *) buffer), destfile);

  fclose (destfile);
  ucon64.console = UCON64_PCE;
  ucon64.do_not_calc_crc = org_do_not_calc_crc;

  return 0;
}