/*
 *	KIF - KIF展開ユーティリティ
 *
 *	"KIF"形式(拡張子int)のアーカイブを展開するためのツールです。
 *	『はぴねす！体験版』(Windmill・2005)のBGMを取り出すために作りました。
 *
 *	Copyright (C) 2005 Naoyuki Sawa
 *
 *	* Thu Aug 18 03:26:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define VERSION		"20050818"

const char* APPNAME;
const char* ARCHIVE;

typedef struct _HEADER {
	char signature[4];	/* + 0, 4: "KIF\0" */
	int count;		/* + 4, 4: ファイル数 */
} HEADER;			/* = 8 */

typedef struct _FILEINFO {
	char fname[32];		/* + 0,32: ファイル名 */
	int offset;		/* +32, 4: データ位置 (ファイル先頭からの絶対位置) */
	int length;		/* +36, 4: データ長 */
} FILEINFO;			/* =40 */

void
usage()
{
	printf("KIF - KIF展開ユーティリティ (%s)\n", VERSION);
	printf("USAGE:\n");
	printf("\t%s <アーカイブファイル名>\n", APPNAME);
	printf("EXAMPLE:\n");
	printf("\t%s \"C:\\はぴねす！体験版\\bgm.int\"\n", APPNAME);
	exit(-1);
}

int
main(int argc, char* argv[])
{
	int retval;
	int i;
	int pos;
	FILE* fp_in;
	FILE* fp_out;
	HEADER header;
	FILEINFO fileinfo;
	unsigned char* buffer;

	APPNAME = argv[0];
	if(argc != 1 + 1) {
		usage();
	}
	ARCHIVE = argv[1];

	/* アーカイブを開きます。 */
	fp_in = fopen(ARCHIVE, "rb");
	if(!fp_in) {
		printf("+++ %sが開けません。\n", ARCHIVE);
		exit(-1);
	}

	/* ヘッダを読みます。 */
	retval = fread(&header, sizeof(HEADER), 1, fp_in);
	if(retval != 1) {
		printf("+++ HEADERが読めません。\n");
		exit(-1);
	}

	/* 各ファイルについて... */
	for(i = 0; i < header.count; i++) {

		/* ファイル情報を読みます。 */
		retval = fread(&fileinfo, sizeof(FILEINFO), 1, fp_in);
		if(retval != 1) {
			printf("+++ FILEINFOが読めません。\n");
			exit(-1);
		}

		printf("%d: %s\n", i, fileinfo.fname);

		/* バッファを確保します。 */
		buffer = malloc(fileinfo.length);
		if(!buffer) {
			printf("+++ メモリ不足です。\n");
			exit(-1);
		}

		/* データを読みます。 */
		pos = ftell(fp_in);
		fseek(fp_in, fileinfo.offset, SEEK_SET);
		retval = fread(buffer, 1, fileinfo.length, fp_in);
		if(retval != fileinfo.length) {
			printf("+++ データが読めません。\n");
			exit(-1);
		}
		fseek(fp_in, pos, SEEK_SET);

		/* ファイルを作成します。 */
		fp_out = fopen(fileinfo.fname, "wb");
		if(!fp_out) {
			printf("+++ %sが作成できません。\n", fileinfo.fname);
			exit(-1);
		}

		/* データを書きます。 */
		retval = fwrite(buffer, 1, fileinfo.length, fp_out);
		if(retval != fileinfo.length) {
			printf("+++ データが書き込めません。\n");
			exit(-1);
		}

		/* ファイルを閉じます。 */
		fclose(fp_out);

		free(buffer);
	}

	/* アーカイブを閉じます。 */
	fclose(fp_in);

	printf("OK\n");

	return 0;
}
