<head> <!-- ここにバナーが入るよん --> column 第1回 第1回 BMS読み込みDLLを設計してみる 2000/1/7


TIXさんのページでBMS(BME,BMX)読み込みDLLを作ろうという話が出ていたので、
なんとなくプロトタイプを作ってみました。
とりあえず演奏関連のみです。
あんまり美しくない実装なので、意見のある方はどんどんお寄せください。
足りない関数とかも多々あると思います。
かなり開発者向けなので、わからない方すみません。

とりあえず全体の流れから解説します。
まず、LoadBMS("hoge.bms")で、BMSを読み込みます。
そして演奏開始時にStart()を呼びます。
その後、1フレームに一度ProcessFrame()します。これにより現在のオブジェの位置が計算されます。
フレーム内の処理では、
・キーが押されたらJudge()で判定する
・GetOBJtoDraw()で描画するべきオブジェを取得して、描画
・バックコーラスとかはGetWAVtoPlay()で演奏する必要のあるWAV番号を取得して、演奏
・BMSAも同様にGetBMSAtoDraw()とGetBMSALayertoDraw()を使う
という具合です。


以下、関数リファレンスです。
BOOLを返すものは特記のない限り
TRUE = 成功, FALSE = 失敗を意味します。
具体的なエラー内容はGetErrorStr()で取得します。
BOOL LoadBMS(const char* szFile);

BOOL GetTitle(char* buf, int max);
BOOL GetArtist(char* buf, int max);
BOOL GetGenre(char* buf, int max);
int GetPlayLevel(void);
int GetRank(void);
BOOL GetBMPFileName(int bmpnum, char* buf, int max);
BOOL GetWAVFileName(int wavnum, char* buf, int max);

ここまでは文字通り。maxはbufのサイズ。文字数で。

BOOL Start(void);
この関数を呼び出した瞬間から内部タイマーが動き始める。

BOOL Stop(void);
BOOL Pause(void);
BOOL ReStart(void);
文字通り。

BOOL Seek(int pos);
絶対シーク。

BOOL SeekDist(int pos);
相対シーク。

BOOL ProcessFrame(void);
この関数を呼ぶことで、現在のオブジェの位置等が再計算される。
できるだけ頻繁に呼ばないと音抜け等が発生するので注意。

BOOL SetScale(int flag);
flag = SS_PIXEL, SS_MS
単位の指定。ピクセルかミリ秒。
SetDrawRange(),Seek(),SetJudgeRange()に渡した値がこの単位で解釈される。
GetOBJtoDraw()で返される値もこの単位になる。

BOOL SetDrawRange(int min, int max);
次のGetOBJtoDraw()で返してほしいオブジェの範囲を指定する。
現在位置がmin以上max以下なオブジェを返すようになる。
例えば画面の縦幅が480ならSetDrawRange(0,480)とすると画面内のオブジェのみを返す。

BOOL GetOBJtoDraw(OBJ* pObj);
描画する必要のあるオブジェの情報を返す。

typedef struct tagobj
{
	int ch; // チャンネル番号
	int pos; // 現在の位置
	int absPos; // 曲の開始からの絶対位置
	BOOL judged; // 判定されたかどうか
} OBJ;

TRUEが返ったらまだ描画するオブジェがあることを示す。
FALSEが返ったらもうオブジェはない。
つまり

OBJ obj;
while(GetOBJtoDraw(&obj))
{
	// 描画処理
}

とする。

int Judge(int chNum);
chNumで指定されるチャンネルを判定する。
戻り値はJUDGE_PERFECT, JUDGE_GREAT, JUDGE_GOOD, JUDGE_BAD, JUDGE_POORのいずれか。
JUDGE_POORは無駄押し。

int SetJudgeRange(int perfect, int great, int good, int bad);
Judge()の判定範囲を指定する。
badより外側は無駄押しPoorとされる。

BOOL SetIgnorePoor(BOOL bUse);
無駄押しPoorでPoorアニメを表示するかどうか設定する。
bUse = TRUEで無駄押しPoorを無視する。

int GetPoor(void);
前回呼び出してからの見逃しPoorの数を得る。

int GetTotalNote(void);
まんま。

int GetBMSAtoDraw(void);
int GetBMSALayertoDraw(void);
現在表示するべきBMSAと、LayerのBMP番号(#BMPxxのxx)が返る。

BOOL SetPoorAnimeUse(BOOL bUse);
bUse = TRUEで呼ぶと上の関数がPoorアニメも考慮してくれるようになる。

BOOL GetWAVtoPlay(int& wavnum);
演奏する必要のあるWAV番号(#WAVxxのxx)を返す。
GetOBJtoDraw()と同じ要領で複数回呼ぶ。

BOOL GetNearWAV(int ch, int& wavnum);
指定されたチャンネルの、現在の演奏位置から最も近いオブジェのWAV番号を返す。
不可視オブジェも考慮する。

BOOL SetAutoPlayCh(int ch, BOOL bAuto);
オートプレイにするチャンネルを指定。

char* GetErrorStr(void);
最後に起こったエラーの内容を示す文字列を返す。