www.pudn.com > ncdzsrc.rar > cdda.c


/*************************************************************************** 
 
	cdda.c 
 
	NEOGEO CD CDDA制御 
 
***************************************************************************/ 
 
#include "neogeocd.h" 
 
#define VERBOSE OUTPUT_CDDA_LOG 
#if VERBOSE 
#define LOG(x) logerror x 
#else 
#define LOG(x) 
#endif 
 
 
/**************************************************************************** 
	ローカル変数 
 ***************************************************************************/ 
 
static int cdda_ready; 
static int cdda_current_volume; 
static int cdda_autoloop; 
 
static int kof96ngc_comment_playing = 0; 
static int kof96ngc_prev_track = 0; 
 
int kof96ngc_track_list[] = { 
	4,	// 京コメント 
	6,	// テリー、キムコメント 
	8,	// リョウ、大門コメント 
	9,	// ユリコメント 
	11,	// レオナ、香澄、バイスコメント 
	13,	// アテナコメント 
	15,	// チョイ、ラルフ、紅丸コメント 
	19,	// 舞コメント 
	21,	// キングコメント 
	23,	// 庵コメント 
	25,	// クラウザーコメント 
	27,	// ギースコメント 
	29,	// Mr.BIG コメント 
	31,	// マチュアコメント 
	33,	// ちづるコメント 
	36,	// ゲーニッツ、クラークコメント 
	43,	// アンディコメント 
	44,	// ロバートコメント 
	45,	// ケンスウコメント 
	46,	// チンコメント 
	47,	// チャンコメント 
	48,	// ジョーNGコメント(舞) 
	49,	// ジョー紹介(舞) 
	50, // ジョーコメント(アンディ) 
	-1 
}; 
 
 
/*************************************************************************** 
	グローバル関数 
 ***************************************************************************/ 
 
/*------------------------------------------------------ 
 
	CDDAの初期化 
 
	引  数: なし 
	戻り値: 成功=1,エラー=0 
 
 -----------------------------------------------------*/ 
 
int neogeo_cdda_init(void) 
{ 
	// 変数初期化 
	cdda_ready = 0; 
	cdda_current_volume = -1; 
	cdda_autoloop = 0; 
 
	if (cdrom_current_drive == -1 || !options.enable_cdda) 
		return 1; 
 
	if (osd_cdda_init(cdrom_current_drive) == OSD_ERROR) 
	{ 
		logerror("CDDA: drive %c: could not initialize.\n", cdrom_current_drive + 'A'); 
		return 0; 
	} 
 
	// ミキサーボリュームの設定 
	if (options.cdda_volume != -1) 
	{ 
		cdda_set_volume(options.cdda_volume); 
	} 
 
	cdda_ready = 1; 
 
	kof96ngc_comment_playing = 0; 
	kof96ngc_prev_track = 0; 
 
	return 1; 
} 
 
 
/*------------------------------------------------------ 
 
	CDDAの終了 
 
	引  数: なし 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void neogeo_cdda_exit(void) 
{ 
	if (cdda_ready) 
	{ 
		osd_cdda_restore_volume(); 
		osd_cdda_stop(); 
		osd_cdda_exit(); 
		cdda_current_volume = -1; 
		cdda_autoloop = 0; 
 
		// CDDA関連のメモリをクリア 
		m68000_write_memory_32(0x10f6ea, 0); 
		m68000_write_memory_8(0x10f678, 0); 
		m68000_write_memory_8(0x10f64b, 0); 
		m68000_write_memory_8(0x10f6f8, 0); 
		m68000_write_memory_8(0x10f6f7, 0); 
		m68000_write_memory_8(0x10f6f6, 0); 
	} 
 
	cdda_ready = 0; 
} 
 
 
/*------------------------------------------------------ 
 
	CDDAのリセット 
 
	引  数: なし 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void neogeo_cdda_reset(void) 
{ 
	kof96ngc_comment_playing = 0; 
	kof96ngc_prev_track = 0; 
 
	if (cdda_ready) 
	{ 
		osd_cdda_set_autoloop(0); 
		osd_cdda_stop(); 
	} 
} 
 
 
/*------------------------------------------------------ 
 
	CDDAのコマンド発行チェック (MC68000) 
 
	引  数: なし 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void neogeo_cdda_control(void) 
{ 
	int command = (m68000_get_reg(M68K_D0) >> 8) & 0xff; 
	int track = m68000_get_reg(M68K_D0) & 0xff; 
	offs_t offset; 
 
	if ((command & 2) == 0) 
	{ 
		m68000_write_memory_8(0x108000 + 0x764b, track); 
		m68000_write_memory_8(0x108000 + 0x76f8, track); 
		m68000_write_memory_8(0x108000 + 0x76f7, command); 
	} 
	m68000_write_memory_8(0x108000 + 0x76f6, command); 
 
	if (command <= 7) 
	{ 
		if ((command || track) && cdda_ready) 
			neogeo_cdda_post_command(command, track); 
	} 
 
	offset = m68000_read_memory_32(0x108000 + 0x76ea); 
 
	if (offset) 
	{ 
		m68000_write_memory_8(0x108000 + 0x7678, 0x01); 
 
		if (command > 7) 
		{ 
			logerror("Z80 I/O ERROR ( ID = %02x, DATA = %02x )\n", 
						m68000_read_memory_8(0x108000 + 0x7678), command); 
		} 
		else 
		{ 
			UINT8  *mem = memory_region(REGION_CPU2); 
 
			offset  = (offset - 0xe00000) >> 1; 
			mem[offset + 0] = 0; 
			mem[offset + 1] = 0; 
		} 
	} 
} 
 
 
/*------------------------------------------------------ 
 
	CDDAのコマンド発行チェック (Z80) 
 
	引  数: なし 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void neogeo_cdda_check(void) 
{ 
	offs_t offset; 
 
	if (kof96ngc_comment_playing) 
	{ 
		if (osd_cdda_get_status() == CDDA_STOP) 
		{ 
			int D0 = m68000_get_reg(M68K_D0); 
 
			kof96ngc_comment_playing = 0; 
 
			m68000_set_reg(M68K_D0, kof96ngc_prev_track); 
			neogeo_cdda_control(); 
			m68000_set_reg(M68K_D0, D0); 
 
			m68000_write_memory_16(0x108000 + 0x2cb8, 0x0000);	// コントローラ入力受付再開 
			return; 
		} 
	} 
 
	offset = m68000_read_memory_32(0x108000 + 0x76ea); 
 
	if (offset) 
	{ 
		UINT8 *mem = memory_region(REGION_CPU2); 
		UINT8 command, track; 
 
		offset  = (offset - 0xe00000) >> 1; 
 
		command = mem[offset + 0]; 
		track   = mem[offset + 1]; 
 
		mem[offset + 0] = 0; 
		mem[offset + 1] = 0; 
 
		if (command > 7) 
		{ 
			logerror("Z80 I/O ERROR ( ID = %02x, DATA = %02x )\n", 
					m68000_read_memory_8(0x108000 + 0x7678), command); 
		} 
		else if ((command || track) && cdda_ready) 
		{ 
			neogeo_cdda_post_command(command, track); 
		} 
	} 
} 
 
 
/*------------------------------------------------------ 
 
	CDDAのコマンドを実行 
 
	引  数: int command  実行するコマンド番号 
	        int track    再生するトラック番号 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void neogeo_cdda_post_command(int command, int track) 
{ 
	int loop, _track; 
 
	_track = track; 
	track = ((track >> 4) * 10) + (track & 0x0f); 
	loop  = !(command & 1); 
 
	switch (command) 
	{ 
	case 0: 
	case 1: 
	case 4: 
	case 5: 
		if (track > 1 && track <= 99) 
		{ 
			if (GAME_NAME("kof96ngc")) 
			{ 
				extern int kof96ngc_cdda_play_comment_track(int track); 
				int i = 0; 
 
				while (kof96ngc_track_list[i] != -1) 
				{ 
					if (kof96ngc_track_list[i] == track) 
					{ 
						kof96ngc_comment_playing = 1; 
						kof96ngc_cdda_play_comment_track(track); 
						if (track == 49) kof96ngc_prev_track = 5; 
						osd_cdda_set_autoloop(0); 
						cdda_autoloop = 0; 
						return; 
					} 
					i++; 
				} 
 
				kof96ngc_comment_playing = 0; 
				kof96ngc_prev_track = _track; 
			} 
 
			/* play */ 
			LOG(("CDDA: command = %d track = %d / play (auto-loop:%s)\n", command, track, loop ? "on" : "off")); 
			if (osd_cdda_play_track(track) == OSD_ERROR) 
			{ 
				logerror("CDDA: play track %d failed.\n", track); 
			} 
			else 
			{ 
				osd_cdda_set_autoloop(loop); 
				cdda_autoloop = loop; 
			} 
		} 
		break; 
 
	case 2: 
	case 6: 
		if (osd_cdda_get_status() == CDDA_PLAY) 
		{ 
			LOG(("CDDA: command = %d track = %d / pause\n", command, track)); 
			osd_cdda_set_autoloop(0); 
			osd_cdda_pause(); 
		} 
		break; 
 
	case 3: 
	case 7: 
		if (osd_cdda_get_status() == CDDA_PAUSE) 
		{ 
			LOG(("CDDA: command = %d track = %d / resume\n", command, track)); 
			osd_cdda_set_autoloop(cdda_autoloop); 
			osd_cdda_resume(); 
		} 
		break; 
	} 
} 
 
 
/*------------------------------------------------------ 
 
	CDDA停止 
 
	引  数: なし 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void neogeo_cdda_stop(void) 
{ 
	osd_cdda_stop(); 
 
	kof96ngc_comment_playing = 0; 
	kof96ngc_prev_track = 0; 
} 
 
 
/*------------------------------------------------------ 
 
	CDDAの音量設定 
 
	引  数: 設定する音量(0-200) 
	戻り値: なし 
 
 -----------------------------------------------------*/ 
 
void cdda_set_volume(int volume) 
{ 
	if (cdda_ready) 
	{ 
		int new_volume = (int)(65535.0 * ((double)volume / 200.0)); 
 
		if (volume != cdda_current_volume) 
		{ 
			cdda_current_volume = volume; 
 
			if (volume == -1) 
			{ 
				osd_cdda_restore_volume(); 
			} 
			else 
			{ 
				if (cdda_current_volume == -1) 
					osd_cdda_init_volume(); 
 
				osd_cdda_set_volume(new_volume); 
 
				cdda_current_volume = volume; 
			} 
		} 
	} 
}