Репозиторий Sisyphus
Последнее обновление: 1 октября 2023 | Пакетов: 18631 | Посещений: 37530533
en ru br
Репозитории ALT

Группа :: Игры/Прочее
Пакет: clonekeen

 Главная   Изменения   Спек   Патчи   Исходники   Загрузить   Gear   Bugs and FR  Repocop 

/*  Utility to extract the embedded sounds from Commander Keen
Episode 2 (keen2.exe) and Episode 3 (keen3.exe)

Copyright (C) 2007 Hans de Goede <j.w.r.degoede@hhs.nl>

Many thanks to Mitugu(Kou) Kurizono for the decompression algorithm.

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

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

int bit_count;
FILE *fin;

int get_bit(void)
{
static unsigned short bits;
int bit;

bit = bits & 1;
bit_count--;

if (bit_count <= 0)
{
bits = getc(fin) | getc(fin) << 8;

if (bit_count == -1) /* special case for first bit word */
{
bit = bits & 1;
bits >>= 1;
}

bit_count += 16;
}
else
bits >>= 1;

return bit;
}

int main(int argc, char *argv[])
{
unsigned char buf[131072];
short offset;
const char *output_filename;
int pos, repeat, sounds_start, sounds_end, ret = 0;
FILE *fout;

pos = 0;
bit_count = 0;

if (argc != 2)
{
fprintf(stderr, "%s: Usage: %s keen?.exe\n", argv[0], argv[0]);
return 1;
}

if (!strcmp(argv[1], "keen2.exe"))
{
output_filename = "sounds.ck2";
sounds_start = 0x12730;
sounds_end = 0x14BDA;
}
else if (!strcmp(argv[1], "keen3.exe"))
{
output_filename = "sounds.ck3";
sounds_start = 0x13A70;
sounds_end = 0x164D4;
}
else
{
fprintf(stderr, "%s: Error: Unknown keen executable name: %s\n",
argv[0], argv[1]);
return 1;
}

fin = fopen(argv[1], "r");
if (!fin)
{
fprintf(stderr, "%s: Error opening input file %s: ", argv[0], argv[1]);
perror(NULL);
}

fout = fopen(output_filename, "w");
if (!fout)
{
fprintf(stderr, "%s: Error opening output file %s: ", argv[0],
output_filename);
perror(NULL);
fclose(fin);
return 1;
}

/* skip header */
fseek(fin, 32, SEEK_SET);

while (1)
{
if (ferror(fin))
{
fprintf(stderr, "%s: Error reading from input file %s: ", argv[0],
argv[1]);
perror(NULL);
fclose(fin);
fclose(fout);
return 1;
}

if (get_bit())
{
buf[pos++] = getc(fin);
}
else
{
if (get_bit())
{
unsigned char tmp[2];
fread(tmp, 1, 2, fin);
repeat = (tmp[1] & 0x07);
offset = ((tmp[1] & ~0x07) << 5) | tmp[0] | 0xE000;

if (repeat == 0)
{
repeat = getc (fin);

if (repeat == 0)
break;
else if (repeat == 1)
continue;
else
repeat++;
}
else
repeat += 2;
}
else
{
repeat = ((get_bit() << 1) | get_bit()) + 2;
offset = getc(fin) | 0xFF00;
}

while (repeat > 0)
{
buf[pos] = buf[pos + offset];
pos++;
repeat--;
}
}
}

printf("%s: Decompression (unlzexe) of %s done\n", argv[0], argv[1]);

if (strcmp(&buf[sounds_start], "SND"))
{
fprintf(stderr, "%s: Error: Beginning of sound data not found at expected offset\n",
argv[0]);
ret = 1;
}
else if (fwrite(&buf[sounds_start], 1, sounds_end - sounds_start, fout) !=
(sounds_end - sounds_start))
{
fprintf(stderr, "%s: error writing to output file %s: ", argv[0],
output_filename);
perror(NULL);
ret = 1;
}
printf("%s: %s has been successfully written\n", argv[0], output_filename);

fclose(fin);
fclose(fout);

return ret;
}
 
дизайн и разработка: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
текущий майнтейнер: Michael Shigorin