www.pudn.com > ncdzsrc.rar > simbios.c
/*****************************************************************************************************
simbios.c
BIOSシミュレーション
※ 解析が進んでロード画面がエミュレーションで再現されるようになれば、これらは不要となります。
BIOSの実行は、エミュレーション中のBIOSのカーソル位置とボタンの押下情報、CD-ROMの状態チェックを
トリガにして各機能を実行しています。シミュレートの為、完全に実機と同じ動作をしているわけでは
ありませんが、ほぼ同様の動作をするように作ってあります。
BIOS実行中の判断は、M68000のアドレスレジスタ0が101480hかつ、VRAMの131(83h)番目のスプライトの情報
がBIOSのカーソル情報と一致するかどうかで行っています。
*****************************************************************************************************/
#include "neogeocd.h"
// CDDAの状態フラグ
#define BIOS_CDDA_READY -1
#define BIOS_CDDA_STOP 0
#define BIOS_CDDA_PLAY 1
#define BIOS_CDDA_PAUSE 2
// メッセージ番号
#define BIOS_MESSAGE_NONE -1
#define BIOS_MESSAGE_NOCD 0
#define BIOS_MESSAGE_WAIT 1
#define BIOS_MESSAGE_NODA 2
// フラグ
#define BIOS_FLAG_PUSHSTART (1 << 0)
#define BIOS_FLAG_PLUS10 (1 << 1)
#define BIOS_FLAG_LOOPPLAY (1 << 2)
#define BIOS_FLAG_PROGRUN (1 << 3)
#define BIOS_FLAG_PROGEDIT (1 << 4)
/***************************************************************************
プロトタイプ
***************************************************************************/
static int bios_check_cdrom(void);
static void bios_run_firsttime(void);
static void bios_run_game(void);
static void bios_run_cdplayer(void);
static void bios_exit_cdplayer(void);
static void bios_show_push_start_message(void);
static void bios_set_popup_message(int no, int sec);
static void bios_popup_message(void);
static void bios_draw_title(void);
static void bios_draw_cdstatus(void);
static void bios_cdplayer(void);
/***************************************************************************
グローバル変数
***************************************************************************/
int first_time_boot;
int boot_bios;
int next_game_index = -1;
int bios_ret_wait;
/***************************************************************************
ローカル変数
***************************************************************************/
// 状態、フラグ等
static int bios_status;
static int bios_message;
static int bios_flag;
static int bios_wait;
// カウンター
static UINT32 bios_frame_counter;
static UINT32 bios_popup_counter;
static UINT32 bios_program_counter;
// 再生トラック、次の再生トラック
static int current_play_track;
static int next_play_track;
// 総トラック数、時間
static int cdda_tracks;
static int cdda_minutes;
static int cdda_seconds;
// プログラム再生
static int program[100];
static int num_program;
static int program_pos;
static int program_sec;
// ボタン押下フラグ
static UINT8 cur_buttons[2][10];
static UINT8 prv_buttons[2][10];
// タイトル画像用メモリ
static UINT16 title_pal[0x5a0 >> 1];
/***************************************************************************
グローバル関数
***************************************************************************/
/*--------------------------------------------------------
BIOSシミュレート初期化
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_init(void)
{
int i;
// BIOS起動フラグ
if (game_index >= 0)
boot_bios = 0;
else
boot_bios = 1;
bios_status = BIOS_CDDA_READY;
bios_message = 0;
bios_flag = 0;
bios_wait = 0;
bios_ret_wait = 0;
// カウンター
bios_frame_counter = 0;
bios_popup_counter = 0;
bios_program_counter = 0;
// CDプレイヤー関係
current_play_track = 0;
next_play_track = 0;
// CD情報
if (options.region == 0)
cdda_tracks = 77; // なぞの数字77
else
cdda_tracks = 0;
cdda_minutes = 0;
cdda_seconds = 0;
// プログラム再生
program[0] = 0;
num_program = 0;
program_pos = 0;
// ボタン押下情報を初期化
for (i = 0; i < 10; i++)
{
cur_buttons[0][i] = 0;
cur_buttons[1][i] = 0;
prv_buttons[0][i] = 0;
prv_buttons[1][i] = 0;
}
}
/*--------------------------------------------------------
ゲームからBIOSシミュレートへの復帰
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_check_exit(void)
{
if (m68000_get_reg(M68K_A0) == 0x101480)
{
int cx, cy, tileno, tileatr;
// カーソル情報を取得し、BIOSのデータと一致した場合はBIOSに戻る
neogeo_bios_get_cursor_pos(&cx, &cy, &tileno, &tileatr);
if (tileno == 0x1dc && tileatr == 0x3000)
{
logerror("Return to bios.\n");
// CPUのリセットフラグを初期化
cpu_reset_flag = 0;
// NEOGEOのCDDA処理を終了
neogeo_cdda_exit();
// 次回起動ゲーム番号に起動していたゲーム番号を設定
next_game_index = game_index;
// ゲーム番号をオーディオCDにする
game_index = -2;
// CD-PLAYER初期化
bios_run_cdplayer();
// タイトル画面の読み込みと更新
bios_load_title();
// ウィンドウタイトル設定
neogeo_set_title();
// 操作の受付を停止
bios_wait = 2 * 60;
bios_ret_wait = 1 * 60;
clear_screen();
}
}
}
/*--------------------------------------------------------
BIOSシミュレートの実行
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_run(void)
{
int i, button;
static UINT32 reg;
static UINT32 prev_reg = 0;
if (bios_ret_wait)
{
bios_ret_wait--;
clear_screen();
return;
}
reg = m68000_get_reg(M68K_A0); // PCよりこちらのほうが判断しやすい
if (reg == 0x101480)
{
if (first_time_boot)
{
// 初回起動時のチェック
bios_run_firsttime();
return;
}
if ((bios_status == BIOS_CDDA_PLAY) && (bios_frame_counter % (5 * 60) == 0))
{
if (osd_drive_is_ready(cdrom_current_drive) == OSD_ERROR)
{
// CD-PLAYER終了
bios_exit_cdplayer();
// トレイがオープンされたのでメッセージ表示
bios_set_popup_message(BIOS_MESSAGE_NOCD, 2 * 60);
}
}
else if (bios_wait)
{
// 待ち時間中の時は何もしない
bios_wait--;
}
else if (bios_frame_counter % (5 * 60) == 0)
{
int status, min_drive, max_drive;
// 5秒毎にドライブのチェック
min_drive = 0;
max_drive = MAX_DRIVE;
// すでにドライブが設定されている場合はそのdライブのみチェック
if (cdrom_current_drive != -1)
{
min_drive = cdrom_current_drive;
max_drive = cdrom_current_drive + 1;
}
else if (options.drive != -1)
{
min_drive = options.drive;
max_drive = options.drive + 1;
}
for (i = min_drive; i < max_drive; i++)
{
int previous_status = cdrom_get_state(i);
if ((status = cdrom_check_state(i)) != 0)
{
if (status & CDROM_TRAYOPEN)
{
// CDが入っていた場合は無効に
if (cdrom_current_drive != -1)
{
// CD-PLAYER終了
bios_exit_cdplayer();
}
// トレイがオープンされたのでメッセージ表示
bios_set_popup_message(BIOS_MESSAGE_NOCD, 2 * 60);
}
else if (((status & CDROM_TRAYOPEN) && (~previous_status & CDROM_TRAYOPEN)) ||
((status & CDROM_READY) && (previous_status & CDROM_NOTREADY)))
{
if ((cdrom_current_drive = bios_check_cdrom()) != -1)
{
// ゲームCDかオーディオCDが挿入された
if (game_index >= 0)
{
// タイトル画面読み込み
bios_load_title();
// ゲームCDはゲーム番号のみ控えてとりあえずオーディオCDに設定
next_game_index = game_index;
game_index = -2;
}
// CD-PLAYER初期化
bios_run_cdplayer();
// しばらくお待ちくださいを表示
bios_set_popup_message(BIOS_MESSAGE_WAIT, 2 * 60);
}
}
}
}
}
if (game_index != -1)
{
if (next_game_index >= 0)
{
// PUSH START BUTTON 表示
if (bios_wait == 0)
bios_flag |= BIOS_FLAG_PUSHSTART;
if (cur_buttons[0][NEOGEO_INPUT_START] || cur_buttons[1][NEOGEO_INPUT_START])
{
// スタートボタンが押された
bios_run_game();
return;
}
}
if (game_index == -2 && bios_wait == 0)
{
// CDプレイヤー
bios_cdplayer();
}
}
// 画面更新
bios_draw_title();
bios_draw_cdstatus();
bios_popup_message();
// フレームカウンタ更新
bios_frame_counter++;
// 適当にスリープ
if (!bios_wait)
Sleep(4);
}
else
{
#if 1
int i;
for (i = 0; i < 10; i++)
{
if (cur_buttons[0][i] || cur_buttons[1][i])
{
if (options.region == 0)
cdda_tracks = 7; // なぞの数字7
break;
}
}
#else
// 実機と同じ動作にする場合はこちらを有効に
int i;
if (first_time_boot)
{
for (i = 0; i < 10; i++)
{
if (cur_buttons[0][i] || cur_buttons[1][i])
{
if (options.region == 0)
cdda_tracks = 7; // なぞの数字7
first_time_boot = 0;
// タイトル画面の読み込み
bios_load_title();
break;
}
}
}
#endif
if (prev_reg == 0x101480 && reg == 0x10ff1a)
{
// バックアップメモリユーティリティ
osd_cdda_exit();
game_index = -1;
next_game_index = -1;
cdrom_current_drive = -1;
bios_init();
first_time_boot = 1;
neogeo_set_title();
}
}
prev_reg = reg;
// ボタンの押下情報を更新
for (i = 0; i < 10; i++)
{
prv_buttons[0][i] = cur_buttons[0][i];
prv_buttons[1][i] = cur_buttons[1][i];
}
button = neogeo_controler1_16_r(0, 0);
for (i = 0; i < 8; i++)
{
cur_buttons[0][i] = ((~button) & (0x0100 << i)) != 0;
}
button = neogeo_controler2_16_r(0, 0);
for (i = 0; i < 8; i++)
{
cur_buttons[1][i] = ((~button) & (0x0100 << i)) != 0;
}
button = neogeo_controler3_16_r(0, 0);
for (i = 0; i < 2; i++)
{
cur_buttons[0][i + 8] = ((~button) & (0x0100 << i)) != 0;
cur_buttons[1][i + 8] = ((~button) & (0x0100 << (i + 2))) != 0;
}
}
/*--------------------------------------------------------
タイトル画像のロード
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_load_title(void)
{
int i;
UINT8 path[MAX_PATH];
UINT8 region_chr[3] = {'j','u','e'};
#if ENABLE_SYSTEM_CHECK
UINT8 *gfx = memory_region(REGION_GFX6);
#else
UINT8 *gfx = memory_region(REGION_GFX2);
#endif
FILE *fp = NULL;
if (next_game_index >= 0)
{
sprintf(path, "%c:/title_%c.sys", cdrom_current_drive + 'A', region_chr[options.region & 3]);
fp = fopen(path, "rb");
}
if (fp != NULL)
{
fread(title_pal, 0x5a0, 1, fp);
fread(gfx + 0x20000, 0x1680, 1, fp);
fclose(fp);
swab((UINT8 *)title_pal, (UINT8 *)title_pal, 0x5a0);
for (i = 0; i < 0x5a0 >> 1; i++)
title_pal[i] = video_color_lut[title_pal[i]];
}
else
{
int j;
UINT8 *mem = memory_region(REGION_USER1) + 0x60000;
UINT8 char_map[] = {
0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x0f,0x03,
0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x04,
0x18,0x19,0x1a,0x1b,0x1c,0x1d,0x1e,0x1f,0x05,
0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x06,
0x28,0x29,0x2a,0x2b,0x2c,0x2d,0x2e,0x2f,0x07
};
UINT8 pal_map[] = {
0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,0x2c,
0x2c,0x2c,0x2a,0x2a,0x2a,0x2a,0x2a,0x2c,0x2c,
0x2d,0x2d,0x2d,0x2b,0x2b,0x2b,0x2d,0x2d,0x2d,
0x2d,0x2d,0x2d,0x2b,0x2b,0x2b,0x2d,0x2d,0x2d,
0x2d,0x2d,0x2d,0x2b,0x2b,0x2b,0x2d,0x2d,0x2d
};
for (i = 0; i < 9 * 5; i++)
{
for (j = 0; j < 16; j++)
{
title_pal[i * 16 + j] = video_palette[pal_map[i] * 16 + j];
}
}
for (i = 0; i < 9 * 5; i++)
swab(mem + char_map[i] * 128, gfx + 0x20000 + i * 128, 128);
}
neogeo_decode_spr(gfx, 0x20000, 0x1680);
osd_unregister_palette(title_pal);
osd_register_palette(title_pal, 0x5a0 >> 1);
}
/***************************************************************************
ローカル関数
***************************************************************************/
/*--------------------------------------------------------
BIOSのFIXを描画
引 数: inr bank バンク
UINT16 charno キャラクタ番号
int x 横座標
int y 縦座標
int palno パレット番号
戻り値: なし
-------------------------------------------------------*/
void bios_draw_fix(int bank, UINT16 charno, int x, int y, int palno)
{
charno += bank * 0x100;
if (video_fix_usage[charno])
{
#if ENABLE_SYSTEM_CHECK
UINT8 *gfx = memory_region(REGION_GFX5);
#else
UINT8 *gfx = memory_region(REGION_GFX1);
#endif
neogeo_draw_fix(gfx, charno, x, y, &video_palette[palno * 16], video_fix_usage[charno] & 1);
}
}
/*--------------------------------------------------------
BIOSのSPRを描画
引 数: UINT16 tileno タイル番号
int x 横座標
int y 縦座標
int palno パレット番号
戻り値: なし
-------------------------------------------------------*/
void bios_draw_spr(UINT16 tileno, int x, int y, int palno)
{
if (video_spr_usage[tileno])
{
#if ENABLE_SYSTEM_CHECK
UINT8 *gfx = memory_region(REGION_GFX6);
#else
UINT8 *gfx = memory_region(REGION_GFX2);
#endif
neogeo_draw_gfx(gfx, tileno, x, y, &video_palette[palno * 16], video_spr_usage[tileno] & 1);
}
}
/*--------------------------------------------------------
CDの種別を判別し、ドライブを返す
引 数: なし
戻り値: ドライブ番号
※ game_indexの値も設定
-------------------------------------------------------*/
static int bios_check_cdrom(void)
{
int i, index;
if (options.drive != -1)
{
index = cdrom_verify_disc(options.drive);
if (index != -1)
{
game_index = index;
return options.drive;
}
}
else
{
for (i = 0; i < MAX_DRIVE; i++)
{
index = cdrom_verify_disc(i);
if (index != -1)
{
game_index = index;
return i;
}
}
}
return -1;
}
/*--------------------------------------------------------
CDプレイヤー画面初回起動時の動作
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_run_firsttime(void)
{
int i;
for (i = 0; i < 60; i++)
{
clear_screen();
sound_update();
osd_update_video(1);
}
// デフォルトタイトル画像読み込み
bios_load_title();
// ドライブの状態更新
for (i = 0; i < MAX_DRIVE; i++)
cdrom_check_state(i);
if ((cdrom_current_drive = bios_check_cdrom()) != -1)
{
if (game_index >= 0)
{
// 初回起動時はゲームをチェックして可能であれば即起動
bios_run_game();
}
else
{
// オーディオCDが見つかった場合は準備
game_index = -2;
// CD-PLAYER実行
bios_run_cdplayer();
// しばらくお待ちくださいを表示
bios_set_popup_message(BIOS_MESSAGE_WAIT, 2 * 60);
}
}
else
{
// CDを入れて下さい
bios_set_popup_message(BIOS_MESSAGE_NOCD, 2 * 60);
}
// 初回起動フラグをクリア
first_time_boot = 0;
}
/*--------------------------------------------------------
BIOSからゲームを起動
引 数: なし
戻り値: なし
-------------------------------------------------------*/
static void bios_run_game(void)
{
int i;
osd_cdda_exit();
for (i = 0; i < 60; i++)
{
clear_screen();
sound_update();
osd_update_video(1);
}
if (next_game_index != -1)
{
game_index = next_game_index;
next_game_index = -1;
}
bios_init();
cdda_tracks = 0;
osd_set_app_state(OSD_RESTART);
}
/*--------------------------------------------------------
BIOSからCDプレイヤーを起動
引 数: なし
戻り値: なし
-------------------------------------------------------*/
static void bios_run_cdplayer(void)
{
// BIOSシミュレーション初期化
bios_init();
// CDDAを再初期化
osd_cdda_init(cdrom_current_drive);
// トラック情報を取得
cdda_tracks = osd_cdda_get_num_tracks();
osd_cdda_get_totaltime(&cdda_minutes, &cdda_seconds);
// 画面を更新
bios_draw_cdstatus();
// ウィンドウタイトル設定
neogeo_set_title();
}
/*--------------------------------------------------------
BIOSのCDプレイヤーを終了
引 数: なし
戻り値: なし
-------------------------------------------------------*/
static void bios_exit_cdplayer(void)
{
cdrom_current_drive = -1;
game_index = -1;
next_game_index = -1;
bios_init();
osd_cdda_exit();
cdda_tracks = 0;
// タイトル画面読み込み
bios_load_title();
// ウィンドウタイトル設定
neogeo_set_title();
}
/*--------------------------------------------------------
ポップアップメッセージを設定
引 数: int no メッセージ番号
int sec 表示秒数
戻り値: なし
-------------------------------------------------------*/
void bios_set_popup_message(int no, int sec)
{
bios_message = no;
bios_popup_counter = sec;
bios_wait = sec;
}
/*--------------------------------------------------------
メッセージを表示
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_popup_message(void)
{
int x, y, sx, sy, pal, region;
int window[6 * 24] = {
0x0e8,0x0e9,0x0ea,0x0eb,0x0ec,0x0ed,0x0ee,0x0ef,0x0f0,0x0f1,0x0f2,0x0f3,0x0f4,0x0f5,0x0f6,0x0f7,0x0f8,0x0f9,0x0fa,0x0fb,0x0fc,0x0fd,0x0fe,0x120,
0x121,0x122,0x123,0x124,0x125,0x126,0x127,0x128,0x13e,0x13f,0x14f,0x150,0x151,0x152,0x153,0x154,0x155,0x156,0x157,0x158,0x159,0x15a,0x15b,0x15c,
0x15d,0x15e,0x15f,0x161,0x162,0x163,0x164,0x165,0x170,0x171,0x172,0x173,0x174,0x175,0x176,0x177,0x178,0x179,0x17a,0x17b,0x17c,0x17d,0x17e,0x17f,
0x181,0x182,0x183,0x184,0x185,0x190,0x191,0x192,0x193,0x194,0x195,0x196,0x197,0x198,0x199,0x19a,0x19b,0x19c,0x19d,0x19e,0x19f,0x1a0,0x1a1,0x1a2,
0x1a3,0x1a4,0x1a5,0x1a6,0x1a7,0x1a8,0x1a9,0x1aa,0x1ab,0x1ac,0x1ad,0x1ae,0x1af,0x1b0,0x1b1,0x1b2,0x1b3,0x1b4,0x1b5,0x1b6,0x1b7,0x1b8,0x1b9,0x1ba,
0x1bb,0x1bc,0x1bd,0x1be,0x1bf,0x1c0,0x1c1,0x1c2,0x1c3,0x1c4,0x1c5,0x1c6,0x1c7,0x1c8,0x1c9,0x1ca,0x1cb,0x1cc,0x1cd,0x1ce,0x1cf,0x1d0,0x1d1,0x1d2
};
int mes[3][2][4 * 22] = {
{
{
0x122,0x123,0x124,0x125,0x126,0x127,0x128,0x13e,0x13f,0x14f,0x150,0x151,0x152,0x153,0x154,0x155,0x156,0x157,0x158,0x159,0x15a,0x15b,
0x034,0x035,0x036,0x037,0x038,0x039,0x03a,0x03b,0x03c,0x03d,0x03e,0x03f,0x020,0x021,0x060,0x061,0x02e,0x02f,0x030,0x031,0x032,0x033,
0x054,0x055,0x056,0x057,0x058,0x059,0x05a,0x05b,0x05c,0x05d,0x05e,0x05f,0x040,0x041,0x080,0x081,0x04e,0x04f,0x050,0x051,0x052,0x053,
0x1a4,0x1a5,0x1a6,0x1a7,0x1a8,0x1a9,0x1aa,0x1ab,0x1ac,0x1ad,0x1ae,0x1af,0x1b0,0x1b1,0x1b2,0x1b3,0x1b4,0x1b5,0x1b6,0x1b7,0x1b8,0x1b9
},
{
0x122,0x123,0x124,0x125,0x126,0x127,0x128,0x13e,0x13f,0x14f,0x150,0x151,0x152,0x153,0x154,0x155,0x156,0x157,0x158,0x159,0x15a,0x15b,
0x15e,0x15f,0x161,0x162,0x163,0x164,0x165,0x0ac,0x0b4,0x0b5,0x0b3,0x0b1,0x0ad,0x0ae,0x0b6,0x0b7,0x179,0x17a,0x17b,0x17c,0x17d,0x17e,
0x182,0x183,0x184,0x185,0x190,0x191,0x192,0x0cc,0x0d4,0x0d5,0x0d3,0x0d1,0x0cd,0x0ce,0x0d6,0x0d7,0x19c,0x19d,0x19e,0x19f,0x1a0,0x1a1,
0x1a4,0x1a5,0x1a6,0x1a7,0x1a8,0x1a9,0x1aa,0x1ab,0x1ac,0x1ad,0x1ae,0x1af,0x1b0,0x1b1,0x1b2,0x1b3,0x1b4,0x1b5,0x1b6,0x1b7,0x1b8,0x1b9
},
},
{
{
0x122,0x123,0x124,0x125,0x126,0x127,0x128,0x13e,0x13f,0x14f,0x150,0x151,0x152,0x153,0x154,0x155,0x156,0x157,0x158,0x159,0x15a,0x15b,
0x15e,0x020,0x021,0x022,0x023,0x024,0x025,0x026,0x027,0x028,0x029,0x02a,0x02b,0x02c,0x02d,0x02e,0x02f,0x030,0x031,0x032,0x033,0x17e,
0x182,0x040,0x041,0x042,0x043,0x044,0x045,0x046,0x047,0x048,0x049,0x04a,0x04b,0x04c,0x04d,0x04e,0x04f,0x050,0x051,0x052,0x053,0x1a1,
0x1a4,0x1a5,0x1a6,0x1a7,0x1a8,0x1a9,0x1aa,0x1ab,0x1ac,0x1ad,0x1ae,0x1af,0x1b0,0x1b1,0x1b2,0x1b3,0x1b4,0x1b5,0x1b6,0x1b7,0x1b8,0x1b9
},
{
0x122,0x123,0x124,0x125,0x126,0x127,0x128,0x13e,0x13f,0x14f,0x150,0x151,0x152,0x153,0x154,0x155,0x156,0x157,0x158,0x159,0x15a,0x15b,
0x15e,0x15f,0x0aa,0x0ab,0x0ac,0x0ad,0x0ae,0x0af,0x0b0,0x0b1,0x0ae,0x0ab,0x0ae,0x0b2,0x0b0,0x0b2,0x0b3,0x0b4,0x0ad,0x17c,0x17d,0x17e,
0x182,0x183,0x0ca,0x0cb,0x0cc,0x0cd,0x0ce,0x0cf,0x0d0,0x0d1,0x0ce,0x0cb,0x0ce,0x0d2,0x0d0,0x0d2,0x0d3,0x0d4,0x0cd,0x19f,0x1a0,0x1a1,
0x1a4,0x1a5,0x1a6,0x1a7,0x1a8,0x1a9,0x1aa,0x1ab,0x1ac,0x1ad,0x1ae,0x1af,0x1b0,0x1b1,0x1b2,0x1b3,0x1b4,0x1b5,0x1b6,0x1b7,0x1b8,0x1b9
},
},
{
{
0x062,0x063,0x062,0x063,0x064,0x065,0x066,0x067,0x068,0x069,0x06a,0x06b,0x06c,0x06d,0x06e,0x06f,0x070,0x071,0x072,0x073,0x074,0x075,
0x082,0x083,0x082,0x083,0x084,0x085,0x086,0x087,0x088,0x089,0x08a,0x08b,0x08c,0x08d,0x08e,0x08f,0x090,0x091,0x092,0x093,0x094,0x095,
0x182,0x183,0x184,0x185,0x076,0x077,0x078,0x079,0x060,0x061,0x032,0x033,0x07a,0x07b,0x07c,0x07d,0x07e,0x07f,0x19e,0x19f,0x1a0,0x1a1,
0x1a4,0x1a5,0x1a6,0x1a7,0x096,0x097,0x098,0x099,0x080,0x081,0x052,0x053,0x09a,0x09b,0x09c,0x09d,0x09e,0x09f,0x1b6,0x1b7,0x1b8,0x1b9
},
{
0x122,0x123,0x124,0x125,0x0b8,0x0b1,0x0b0,0x0b9,0x0b1,0x0ab,0x0b2,0x0ae,0x0ab,0x0b1,0x0b3,0x0ab,0x0ae,0x0ba,0x158,0x159,0x15a,0x15b,
0x15e,0x15f,0x161,0x162,0x0d8,0x0d1,0x0d0,0x0d9,0x0d1,0x0cb,0x0d2,0x0ce,0x0cb,0x0d1,0x0d3,0x0cb,0x0ce,0x0da,0x17b,0x17c,0x17d,0x17e,
0x182,0x0b5,0x0b3,0x0bb,0x0b3,0x0b6,0x0ad,0x0ae,0x0bc,0x0ab,0x0bd,0x0b7,0x0ac,0x0b0,0x0ae,0x0ad,0x0b1,0x0ab,0x0b6,0x0be,0x0bc,0x1a1,
0x1a4,0x0d5,0x0d3,0x0db,0x0d3,0x0d6,0x0cd,0x0ce,0x0dc,0x0cb,0x0dd,0x0d7,0x0cc,0x0d0,0x0ce,0x0cd,0x0d1,0x0cb,0x0d6,0x0de,0x0dc,0x1b9
},
}
};
if (bios_flag & BIOS_FLAG_PUSHSTART)
{
if ((bios_frame_counter % 60) < 40)
{
const char *push_start = "PUSH START BUTTON";
// なぜかFIXなのに8ドットで割り切れる位置でない
for (x = 0; x < 17; x++)
bios_draw_fix(3, push_start[x], (18 + x) * 8, 27 * 8 + 4, 2);
}
}
if (bios_popup_counter == 0)
return;
// カウンタを減らす
bios_popup_counter--;
if (bios_popup_counter == 0)
{
if (bios_message == BIOS_MESSAGE_WAIT)
{
// しばらくお待ちください野表示が終わったら、タイトル画面更新
bios_load_title();
bios_draw_title();
}
bios_message = BIOS_MESSAGE_NONE;
return;
}
// パレット
if (bios_message == 2)
pal = 1;
else
pal = 0;
// 枠表示
sx = ((320/8) - 24) / 2;
sy = ((224/8) - 6) / 2 - 1;
for (y = 0; y < 6; y++)
{
for (x = 0; x < 24; x++)
{
bios_draw_fix(5, window[y * 24 + x], (sx + x) * 8, (sy + y) * 8, pal);
}
}
// メッセージ表示
sx++;
sy++;
region = (options.region != 0);
for (y = 0; y < 4; y++)
{
for (x = 0; x < 22; x++)
{
bios_draw_fix(5, mes[bios_message][region][y * 22 + x], (sx + x) * 8, (sy + y) * 8, pal);
}
}
}
/*--------------------------------------------------------
タイトル画像の表示
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_draw_title(void)
{
int x, y, r, g, b, tileno;
UINT16 backup[24][48];
#if ENABLE_SYSTEM_CHECK
UINT8 *gfx = memory_region(REGION_GFX6);
#else
UINT8 *gfx = memory_region(REGION_GFX2);
#endif
tileno = 0;
ui_get_pixel_color(183+8, 122+16, &r, &g, &b);
if (r == g && r == b)
{
for (y = 0; y < 24; y++)
for (x = 0; x < 48; x++)
backup[y][x] = scrbitmap.line[136 + y][136 + x];
}
for (y = 0; y < 5; y++)
{
for (x = 0; x < 9; x++)
{
neogeo_draw_gfx(gfx + 0x20000, tileno, 40 + x * 16, 80 + y * 16, &title_pal[tileno * 16], 1);
tileno++;
}
}
if (r == g && r == b)
{
for (y = 0; y < 24; y++)
for (x = 0; x < 48; x++)
scrbitmap.line[136 + y][136 + x] = backup[y][x];
}
}
/*--------------------------------------------------------
画面を指定された色で四角形に塗りつぶす
引 数: int sx 左上隅横座標
int sy 左上隅縦座標
int w 塗りつぶす幅
int w 塗りつぶす高さ
int r 塗りつぶす色の赤輝度
int g 塗りつぶす色の緑輝度
int v 塗りつぶす色の青輝度
戻り値: なし
-------------------------------------------------------*/
void bios_fill_box(int sx, int sy, int w, int h, int r, int g, int b)
{
UINT16 color = osd_make_pen(r, g, b);
int x, y;
for (y = 0; y < h; y++)
for (x = 0; x < w; x++)
scrbitmap.line[sy + y][sx + x] = color;
}
/*--------------------------------------------------------
CDプレイヤーの画面を更新
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_draw_cdstatus(void)
{
int cx, cy, tileno, tileatr, status;
int program_is_open, program_not_flash;
// トラックの情報を更新
if (bios_status == BIOS_CDDA_PLAY)
{
status = osd_cdda_get_status();
if (status == CDDA_PLAY || status == CDDA_PAUSE)
{
int current_track = osd_cdda_get_current_track();
if (current_track != current_play_track)
current_play_track = current_track;
}
else if (status == CDDA_STOP)
{
bios_status = BIOS_CDDA_STOP;
current_play_track = 0;
}
}
// 画面の色でナンバーキーの状態をチェック
program_not_flash = scrbitmap.line[139][212] == 0;
program_is_open = scrbitmap.line[138][191] == 0;
if (bios_flag & BIOS_FLAG_LOOPPLAY)
{
// 再生ボタンのループマーク
bios_draw_spr(0x0fb, 240, 72, 16);
bios_draw_spr(0x0fc, 256, 72, 16);
}
if (program_is_open)
{
// プログラムボタン点灯
if (bios_flag & BIOS_FLAG_PROGRUN)
{
bios_draw_spr(0x130, 140, 138, 0x39);
bios_draw_spr(0x131, 156, 138, 0x39);
bios_draw_spr(0x1d4, 172, 138, 0x39);
bios_draw_spr(0x1d5, 188, 138, 0x39);
}
}
if (program_not_flash)
{
// 表示されている数字を必要に応じて消す
if (bios_status != BIOS_CDDA_STOP || (bios_status == BIOS_CDDA_STOP && (bios_flag & BIOS_FLAG_PROGEDIT)))
{
if (bios_flag & BIOS_FLAG_PROGRUN)
{
// プログラム中/プログラム実行中
bios_fill_box(259, 171, 15, 2, 0, 0, 0);
}
bios_fill_box(218, 165, 19, 14, 0, 0, 0);
bios_fill_box(238, 197, 43, 14, 0, 0, 0);
}
if (bios_status == BIOS_CDDA_READY)
{
// 起動直後
// トラック数表示
bios_draw_spr(0x11f + cdda_tracks / 10, 218, 165, 25);
bios_draw_spr(0x11f + cdda_tracks % 10, 228, 165, 25);
// 総プレイ時間表示
bios_draw_spr(0x11f + cdda_minutes / 10, 238, 197, 25);
bios_draw_spr(0x11f + cdda_minutes % 10, 248, 197, 25);
bios_draw_spr(0x12a, 252, 197, 25);
bios_draw_spr(0x11f + cdda_seconds / 10, 262, 197, 25);
bios_draw_spr(0x11f + cdda_seconds % 10, 272, 197, 25);
}
else if (bios_status == BIOS_CDDA_STOP)
{
// 停止中
if (bios_flag & BIOS_FLAG_PROGEDIT)
{
int play_time_temp = program_sec;
// プログラム中
bios_fill_box(218, 165, 19, 14, 0, 0, 0);
bios_fill_box(238, 197, 43, 14, 0, 0, 0);
bios_fill_box(259, 171, 15, 2, 0, 0, 0);
if (bios_program_counter)
{
bios_draw_spr(0x11f + program[num_program + 1] / 10, 218, 165, 25);
bios_draw_spr(0x11f + program[num_program + 1] % 10, 228, 165, 25);
bios_draw_spr(0x11f + num_program / 10, 257, 165, 25);
bios_draw_spr(0x11f + num_program % 10, 267, 165, 25);
bios_program_counter--;
}
else if ((bios_frame_counter % 15) < 10)
{
if (~bios_flag & BIOS_FLAG_PLUS10)
{
// +10入力中以外
bios_draw_spr(0x11f + 0, 218, 165, 25);
bios_draw_spr(0x11f + 1, 228, 165, 25);
}
bios_draw_spr(0x11f + num_program / 10, 257, 165, 25);
bios_draw_spr(0x11f + num_program % 10, 267, 165, 25);
}
if (play_time_temp > 99 * 60 + 59)
play_time_temp = 99 * 60 + 59;
// 総プレイ時間表示
bios_draw_spr(0x11f + (play_time_temp / 60) / 10, 238, 197, 25);
bios_draw_spr(0x11f + (play_time_temp / 60) % 10, 248, 197, 25);
bios_draw_spr(0x11f + (play_time_temp % 60) / 10, 262, 197, 25);
bios_draw_spr(0x11f + (play_time_temp % 60) % 10, 272, 197, 25);
bios_draw_spr(0x12a, 252, 197, 25);
}
}
else
{
int m, s;
// 再生/ポーズ中
if (~bios_flag & BIOS_FLAG_PLUS10)
{
// +10入力中以外
bios_draw_spr(0x11f + current_play_track / 10, 218, 165, 25);
bios_draw_spr(0x11f + current_play_track % 10, 228, 165, 25);
}
if (bios_flag & BIOS_FLAG_PROGRUN)
{
int program_no = osd_cdda_get_current_program();
// プログラム番号
bios_draw_spr(0x11f + program_no / 10, 259, 165, 25);
bios_draw_spr(0x11f + program_no % 10, 269, 165, 25);
}
// プレイ時間表示
osd_cdda_get_play_time(&m, &s);
bios_draw_spr(0x11f + m / 10, 238, 197, 25);
bios_draw_spr(0x11f + m % 10, 248, 197, 25);
bios_draw_spr(0x11f + s / 10, 262, 197, 25);
bios_draw_spr(0x11f + s % 10, 272, 197, 25);
bios_draw_spr(0x12a, 252, 197, 25);
// 再生マーク
bios_draw_spr(0x12b, 220, 180, 1);
// ポーズマーク
if (bios_status == BIOS_CDDA_PAUSE)
bios_draw_spr(0x12c, 259, 180, 1);
// 各ボタンの点滅
if ((bios_frame_counter % 8) < 4)
{
if (bios_status == BIOS_CDDA_PLAY)
{
if (bios_flag & BIOS_FLAG_LOOPPLAY)
{
// 再生ボタンループマーク付き
bios_draw_spr(0x0fb, 240, 72, 53);
bios_draw_spr(0x0fc, 256, 72, 53);
}
else
{
// 再生ボタンループマークなし
bios_draw_spr(0x0f6, 240, 72, 53);
}
}
else if (bios_status == BIOS_CDDA_PAUSE)
{
// ポーズボタン
bios_draw_spr(0x102, 254, 88, 54);
bios_draw_spr(0x103, 270, 88, 54);
}
}
else if (program_is_open)
{
// プログラムボタン点灯消去
if (bios_flag & BIOS_FLAG_PROGRUN)
{
bios_draw_spr(0x130, 140, 138, 22);
bios_draw_spr(0x131, 156, 138, 22);
bios_draw_spr(0x1d4, 172, 138, 22);
bios_draw_spr(0x1d5, 188, 138, 22);
}
}
}
// ループマーク
if (bios_flag & BIOS_FLAG_LOOPPLAY)
bios_draw_spr(0x1db, 232, 180, 1);
if (bios_flag & BIOS_FLAG_PLUS10)
{
bios_fill_box(218, 165, 19, 14, 0, 0, 0);
if (bios_frame_counter % 15 < 10)
{
// 再生/停止/ポーズ中 1- 表示
bios_draw_spr(0x11f + next_play_track / 10, 218, 165, 25);
bios_draw_spr(0x129, 228, 165, 25);
}
}
}
// カーソル
neogeo_bios_get_cursor_pos(&cx, &cy, &tileno, &tileatr);
bios_draw_spr(0x1dc, cx, cy, 3);
}
/*--------------------------------------------------------
CDプレイヤーの実行
引 数: なし
戻り値: なし
-------------------------------------------------------*/
void bios_cdplayer(void)
{
int cx, cy, tileno, tileatr;
int play_start = 0;
int add_program = 0;
neogeo_bios_get_cursor_pos(&cx, &cy, &tileno, &tileatr);
if (cur_buttons[0][NEOGEO_INPUT_BUTTONA] || cur_buttons[1][NEOGEO_INPUT_BUTTONA])
{
if (bios_status == BIOS_CDDA_PLAY && (~bios_flag & BIOS_FLAG_PROGRUN))
{
if (bios_frame_counter % 10 == 0)
{
if (cx == 227 && cy == 132)
{
// 巻き戻し
osd_cdda_play_rewind(4);
}
else if (cx == 267 && cy == 132)
{
// 早送り
osd_cdda_play_foward(4);
}
}
}
}
if ((prv_buttons[0][NEOGEO_INPUT_BUTTONA] == 0 && cur_buttons[0][NEOGEO_INPUT_BUTTONA])
|| (prv_buttons[1][NEOGEO_INPUT_BUTTONA] == 0 && cur_buttons[1][NEOGEO_INPUT_BUTTONA]))
{
if (cx == 243 && cy == 84)
{
// 再生
if (bios_status == BIOS_CDDA_PLAY)
{
bios_flag ^= BIOS_FLAG_LOOPPLAY;
if (bios_flag & BIOS_FLAG_PROGRUN)
{
// オートループが有効なのはプログラム再生のみ
osd_cdda_set_autoloop((bios_flag & BIOS_FLAG_LOOPPLAY) != 0);
}
else
{
osd_cdda_set_autoloop(0);
}
}
else if (bios_status == BIOS_CDDA_STOP || bios_status == BIOS_CDDA_READY)
{
if (current_play_track == 0)
{
if (osd_cdda_get_track_type(1) == 1)
next_play_track = 1;
else
next_play_track = 2;
}
play_start = 2;
bios_flag &= ~BIOS_FLAG_PROGEDIT;
}
}
else if (cx == 227 && cy == 100)
{
// 停止
if (bios_status == BIOS_CDDA_PLAY || bios_status == BIOS_CDDA_PAUSE)
{
osd_cdda_stop();
bios_status = BIOS_CDDA_STOP;
current_play_track = 0;
}
}
else if (cx == 267 && cy == 100)
{
// 一時停止
if (bios_status == BIOS_CDDA_PLAY)
{
osd_cdda_pause();
bios_status = BIOS_CDDA_PAUSE;
}
else if (bios_status == BIOS_CDDA_PAUSE)
{
osd_cdda_resume();
bios_status = BIOS_CDDA_PLAY;
}
}
else if (cx == 227 && cy == 116)
{
// 前の曲
if (bios_status == BIOS_CDDA_PLAY)
osd_cdda_play_prev_track();
}
else if (cx == 267 && cy == 116)
{
// 次の曲
if (bios_status == BIOS_CDDA_PLAY)
osd_cdda_play_next_track();
}
else if (cx == 171 && cy == 150)
{
// プログラム
if (bios_status == BIOS_CDDA_READY)
bios_status = BIOS_CDDA_STOP;
if (bios_status == BIOS_CDDA_STOP)
{
if (~bios_flag & BIOS_FLAG_PROGRUN)
{
// プログラム編集開始
bios_flag |= BIOS_FLAG_PROGRUN;
bios_flag |= BIOS_FLAG_PROGEDIT;
program[1] = 0;
num_program = 0;
program_sec = 0;
}
else
{
// プログラム終了
bios_flag &= ~BIOS_FLAG_PROGRUN;
bios_flag &= ~BIOS_FLAG_PROGEDIT;
program[1] = 0;
num_program = 0;
}
}
else if (bios_status == BIOS_CDDA_PLAY)
{
if (bios_flag & BIOS_FLAG_PROGRUN)
{
// プログラムキャンセル
bios_flag &= ~BIOS_FLAG_PROGRUN;
bios_flag &= ~BIOS_FLAG_PROGEDIT;
program[1] = 0;
num_program = 0;
osd_cdda_chancel_program();
}
}
}
else if (((cx >= 149 && cx <= 197) && (cy >= 163 && cy <= 185)) || (cx == 149 && cy == 196))
{
int number = ((cx - 149) / 24) + ((cy - 163) / 11) * 3 + 1;
if (number == 10) number = 0;
// 0 - 9
if (next_play_track + number != 0)
{
if (bios_status == BIOS_CDDA_READY)
bios_status = BIOS_CDDA_STOP;
if ((~bios_flag & BIOS_FLAG_PROGRUN) || ((bios_flag & BIOS_FLAG_PROGRUN) && bios_status == BIOS_CDDA_STOP))
{
if (next_play_track + number <= osd_cdda_get_num_tracks())
{
if (osd_cdda_get_track_type(next_play_track + number) == 0)
{
// データトラックは無視する
next_play_track = 0;
bios_flag &= ~BIOS_FLAG_PLUS10;
bios_set_popup_message(BIOS_MESSAGE_NODA, 15);
}
else
{
// 普通に再生中か、プログラム中
next_play_track += number;
if (bios_flag & BIOS_FLAG_PROGRUN)
add_program = 1;
else
play_start = 1;
}
}
}
else
{
// プログラム再生中はプログラムナンバーの指定
if (next_play_track + number >= num_program)
next_play_track = num_program;
else
next_play_track += number;
play_start = 1;
}
}
}
else if (cx == 185 && cy == 196)
{
// +10
if ((~bios_flag & BIOS_FLAG_PROGRUN) || ((bios_flag & BIOS_FLAG_PROGRUN) && bios_status == BIOS_CDDA_STOP))
{
if (next_play_track + 10 <= osd_cdda_get_num_tracks())
{
next_play_track += 10;
bios_flag |= BIOS_FLAG_PLUS10;
if (bios_status == BIOS_CDDA_READY)
bios_status = BIOS_CDDA_STOP;
}
}
else
{
if (next_play_track + 10 <= num_program)
{
next_play_track += 10;
bios_flag |= BIOS_FLAG_PLUS10;
if (bios_status == BIOS_CDDA_READY)
bios_status = BIOS_CDDA_STOP;
}
}
}
else if (cx == 171 && cy == 209)
{
// キャンセル
next_play_track = 0;
bios_flag &= ~BIOS_FLAG_PLUS10;
if (bios_flag & BIOS_FLAG_PROGRUN)
add_program = 2;
else
play_start = 1;
}
else if (cx == 148 && cy == 74)
{
// スタート
if (next_game_index != -1)
{
// ゲーム起動
bios_run_game();
return;
}
}
if (add_program)
{
int i;
if (add_program == 1 && num_program < 98)
{
program[num_program + 1] = next_play_track;
num_program++;
}
else if (add_program == 2 && num_program > 0)
{
num_program--;
if (num_program == 0)
{
// 全てキャンセルしたらプログラム終了
bios_flag &= ~BIOS_FLAG_PROGRUN;
bios_flag &= ~BIOS_FLAG_PROGEDIT;
return;
}
}
else
return;
program_sec = 0;
for (i = 1; i <= num_program; i++)
{
program_sec += osd_cdda_get_track_sec(program[i]);
}
next_play_track = 0;
bios_flag &= ~BIOS_FLAG_PLUS10;
bios_program_counter = 30;
}
if (play_start)
{
int play_type;
if (bios_flag & BIOS_FLAG_PROGRUN)
{
if (play_start == 1)
{
// プログラムナンバー指定
current_play_track = program[next_play_track];
play_type = 2;
}
else if (num_program == 0)
{
// プログラムが指定されていなければ解除して普通に再生
bios_flag &= ~BIOS_FLAG_PROGRUN;
bios_flag &= ~BIOS_FLAG_PROGEDIT;
current_play_track = next_play_track;
play_type = 0;
}
else
{
// プログラムの最初から
program[num_program + 1] = 0;
current_play_track = program[1];
play_type = 1;
}
}
else
{
// プログラムの最初から普通に再生
current_play_track = next_play_track;
play_type = 0;
}
// 再生
switch (play_type)
{
case 0:
osd_cdda_play_tracks(current_play_track);
break;
case 1:
osd_cdda_play_program(program);
break;
case 2:
osd_cdda_play_program_no(current_play_track);
break;
}
bios_status = BIOS_CDDA_PLAY;
bios_flag &= ~BIOS_FLAG_PLUS10;
next_play_track = 0;
}
}
}