/*
 *	TSARC - 『チュートリアルサマー』体験版ARC展開ユーティリティ
 *
 *	『チュートリアルサマー』体験版（すたじおみりす・2005）
 *	“ARC”形式のアーカイブを展開するためのツールです。
 *
 *	Copyright (C) 2005 Naoyuki Sawa
 *
 *	* Mon Sep 10 19:10:00 JST 2004 Naoyuki Sawa
 *	- 作成開始。
 *	  ヘッダ書式が判らないので、Oggファイルの内容から判断して切り出しています。
 *	  “ARC”形式に限らず、一般的なOggアーカイブにも適用できるかも知れません。
 */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define VERSION		"20051010"

const char* APPNAME;
const char* ARCHIVE;

unsigned char* buffer/*[buffer_length]*/;	/* アーカイブ全体を読み込むバッファ */
int buffer_length;				/* アーアカイブサイズ */

#define MAX_FILES	100			/* Oggファイル数の上限 (調整可) */
int files[MAX_FILES];				/* Oggファイルの先頭オフセット */
int num_files;					/* Oggファイル数 */

void
usage()
{
	printf("TSARC - 『チュートリアルサマー』体験版ARC展開ユーティリティ (%s)\n", VERSION);
	printf("USAGE:\n");
	printf("\t%s <アーカイブファイル名>\n", APPNAME);
	printf("EXAMPLE:\n");
	printf("\t%s \"C:\\チュートリアルサマー体験版\\bgm.arc\"\n", APPNAME);
	exit(-1);
}

int
main(int argc, char* argv[])
{
	int retval;
	FILE* fp;
	int pos;
	int len;
	int i;
	char fname[32];

	/* アーカイブファイル名を取得します。 */
	APPNAME = argv[0];
	if(argc != 1 + 1) {
		usage();
	}
	ARCHIVE = argv[1];

	/*-------------------------------------------------------------------*/

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

	/* アーカイブサイズを取得します。 */
	retval = fseek(fp, 0, SEEK_END);
	if(retval != 0) {
		printf("+++ fseekが失敗しました。\n");
		exit(-1);
	}
	buffer_length = ftell(fp);
	if(buffer_length < 0) {
		printf("+++ ftellが失敗しました。\n");
		exit(-1);
	}
	rewind(fp);

	/* アーカイブ全体を読み込むバッファを確保します。 */
	buffer = malloc(buffer_length);
	if(!buffer) {
		printf("+++ メモリ不足です。\n");
		exit(-1);
	}

	/* アーカイブ全体を読み込みます。 */
	retval = fread(buffer, 1, buffer_length, fp);
	if(retval != buffer_length) {
		printf("+++ freadが失敗しました。\n");
		exit(-1);
	}

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

	/*-------------------------------------------------------------------*/

	/* Oggファイルの先頭アドレスを探します。 */
	for(pos = 0; pos < buffer_length - 8; pos++) {
		if(memcmp(&buffer[pos], "OggS\0\2\0\0", 8) == 0) {
			files[num_files] = pos;
			printf("found %02d: %08x\n", num_files + 1, pos);
			num_files++;
			if(num_files == MAX_FILES) {
				break;
			}
		}
	}

	/*-------------------------------------------------------------------*/

	/* Oggファイルを作成します。 */
	for(i = 0; i < num_files; i++) {
		pos = files[i];
		if(i < num_files - 1) {
			len = files[i + 1] - pos;
		} else {
			len = buffer_length - pos;
		}

		/* Oggファイル名を作成します。 */
		sprintf(fname, "%02d.ogg", i + 1);
		printf("write %s: %08x (%08x)\n", fname, pos, len);

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

		/* Oggデータを書き込みます。 */
		retval = fwrite(&buffer[pos], 1, len, fp);
		if(retval != len) {
			printf("+++ fwriteが失敗しました。\n");
			exit(-1);
		}

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

	/*-------------------------------------------------------------------*/

	/* アーカイブ全体を読み込んだバッファを解放します。 */
	free(buffer);

	printf("OK\n");

	return 0;
}
