/* 2010-04-08
 * http://sed.free.fr
 * The revolution has begun.
 * But fuck, I'm late.
 *
 * This is a crack for Indiana Jones and the Last Crusade
 * (EGA/Atari ST/French version, may fail for others),
 * a game released, hum, a few years ago.
 *
 * After fucking up Indy4 (see http://sed.free.fr, somewhere), I needed
 * some more challenge.
 *
 * Here again it's damn useless. The game is playable in
 * ScummVM. And the codes are available everywhere. And even
 * without the codes, you can load and save in ScummVM.
 *
 * So... well...
 *
 * Wanna play the game? Get it at: http://atariste.free.fr/indiana.html
 * You will need a tool (if you don't have one) to shit the files
 * out of the MSA files. Get http://sed.free.fr/msa.c and read the
 * source, it's all explained in there.
 *
 * Then compile this crack and run it: ./a.out 92.LFL
 * May work with other versions too.
 *
 * Fuck me, I'm anonymous.
 */

#include <stdio.h>
#include <string.h>

unsigned char buf[4096+5];

int main(int n, char **v)
{
  /* we look for: Var[94 Bit 4] = 1 and replace by Var[94 Bit 4] = 0 */
  /* script 204 of room 92 is the guilty bastard. */
  unsigned char dig[] = { 0x1a, 0xe4, 0x85, 0x01, 0x00 };
  unsigned char rep[] = { 0x1a ^ 255, 0xe4 ^ 255, 0x85 ^ 255,
                          0x00 ^ 255, 0x00 ^ 255 };
  FILE *f;
  int pos;
  int i;
  long start_offset = -5;
  long offset;
  long old_pos;
  int found = 0;

  if (n != 2) {
    printf("gimme the 92.LFL file\n");
    return 1;
  }

  f = fopen(v[1], "r+b"); if (!f) { perror(v[1]); return 1; }

  while (1) {
    memcpy(buf, buf+4096, 5);
    memset(buf+5, 0, 4096);
    if (fread(buf+5, 4096, 1, f) == 0 && feof(f)) break;
    pos = 0;
    for (i = 0; i < 4096+5; i++) {
      if (dig[pos] == (buf[i] ^ 255)) pos++; else { i -= pos; pos = 0; }
      if (pos == 5) {
        printf("found at %ld\n", i+1-pos + start_offset);
        goto found;
back_from_found:
        pos = 0;
      }
    }
    start_offset += 4096;
  }

  if (found == 0)
    printf("Error. Pattern not found. Can't patch.\n");
  else
    printf("Pattern found %d times, patched %d times\n", found, found);
  fclose(f);
  return 0;

found:
  found++;
  offset = i+1-pos + start_offset;

  old_pos = ftell(f);
  fseek(f, offset, SEEK_SET);
  fwrite(rep, 5, 1, f);
  fseek(f, old_pos, SEEK_SET);
  goto back_from_found;
}
