/* /-------------------------------------------/ タイトル BMSA鑑賞  バージョン 1.1 公開日 2004/01/29 制作 HAL Homepage http://www.harukitchen.com/ /-------------------------------------------/ ★バージョンアップ履歴 ver1.1 2004/01/28 ダイエット。クラスをやめる。ファイル名長くてもOK。ロード画面表示。 レイヤー機能BMS無視。曲終了後、10秒待つ。 ver1.0 2004/01/28 公開。 */ #define DIRECTMUSIC #define DIRECTINPUT #include "el.h" #include "harulib.h" #define MAIN_SCREEN 1 void MainScreen(void); //定数 #define LINENUM 9 //ライン数 #define FX 10 //左上座標 #define FY 16 //左上座標 #define MAXOBJ 65535 //最大オブジェ数 #define WAVNUM 256 //最大WAV数 #define BOTTOM 200 //底座標 //変数 int MaxSyousetu; //最大小節数 char Cdir[64]; //カレントディレクトリ int mfsp; //スタックポインタ int MaxSelectNum; //最大曲数 int SelectedNo; //現在選択中の曲NO char MusicFiles[256][MAX_PATH];//曲データファイル float PassTime; //経過時間 short TempoChangeCount;//テンポ変更カウント //カウンタ float FirstWait; //ロード待ちカウンタ float WaitTime; //待ち時間 //曲リスト構造体 struct _list{ char MusicTitle[MAX_PATH]; //曲タイトル char CopyRight[MAX_PATH]; //著作者 char Genre[128]; //ジャンル }Lists[256]; //オブジェクト構造体 typedef struct _obj{ float y; //Y座標 unsigned char wav; //音データ char key; //鍵盤の場所 BOOL done; //キーを押してGREATかGOODを出したか、ライン外に出てBADを出したフラグ。役割終了。 BOOL lineflag; //ラインを通り過ぎたかフラグ(doneフラグはまだ立たない) BOOL tempoflag; //テンポ変更フラグ short tempo; //テンポ変更時のテンポ unsigned short syousetu;//小節 } OBJ; OBJ obj[MAXOBJ]; int head; //開始ポインタ int LastID; //最後のインデックス short Tempo;//テンポ //画像構造体 typedef struct _image{ float y; //座標 unsigned char bmp;//画像データ } IMAGE; IMAGE images[MAXOBJ]; int ihead; //開始 int LastImageID;//最後のインデックス //Wav DSOBJ Wavs[WAVNUM]; //wavデータ DSOBJ SeWavs[1]; //効果音 char WavFiles[WAVNUM][MAX_PATH];//wavファイル名 int key[LINENUM]; //キーを押すと格納されているWavNoのWavが鳴る(key[0]<-Z,key[1]<-X,...) //BMP typedef struct _bmp{ DDOBJ Obj; //データ char File[MAX_PATH]; //ファイル名 unsigned short width,height;//横幅、高さ }BMP; BMP Bmps[WAVNUM]; //フラグ BOOL DebugMode; //デバッグモード BOOL StartFlag; //開始 BOOL MusicEndFlag; //曲終了 BOOL ExitFlag; //終了か BOOL EndFlag; //オブジェが全て降ったか BOOL PushKeyFlags[LINENUM];//キーを押しているか BOOL BmpEndFlag; //画像が終了か BOOL WavEndFlag; //音声が終了か BOOL LoadFlag; //ロード開始フラグ /********************************************************************************/ /* */ /* 関数プロトタイプ */ /* */ /********************************************************************************/ void Init();//初期化 void Load();//ロード void KeyAction();//キー入力 void Action();//処理 void Disp();//描画 void Reset();//リセット void LoadScript(int id);//スクリプト読み込み void Sort();//ソート void PushCheck(int);//判定 int SearchBmsFile(char*,int);//BMSファイル検索 void LoadScriptFirst(char *file);//タイトルとアーティストだけロード /********************************************************************************/ /* */ /* 初期化 */ /* */ /********************************************************************************/ void Init(){ int i; mfsp=0; LoadFlag=DebugMode=StartFlag=FALSE; SelectedNo=0; for(i=0;i29)){obj[count].key=-1;} else{ switch(place){ case 11:case 12:case 13:case 14:case 15:case 16:case 17://BMS obj[count].key=place-11;break; case 18:case 19://BME obj[count].key=place-13;break; case 22:case 23:case 24:case 25://POPN obj[count].key=place-17;break; } } } obj[count].syousetu=syousetu; obj[count].wav=data; obj[count].y=syousetu + rhythm*k;//配置 //BGMではなくて、もし同じライン上にオブジェが重なっていた場合,BGMにする for(j=0;j= obj[j].y-F(0.0001) && obj[count].y <= obj[j].y+F(0.0001)){ obj[count].key=-1; break; } } count++; k++; } LastID=count-1; } } fclose(fin); Sort();//ソート } /********************************************************************************/ /* */ /* ソート */ /* */ /********************************************************************************/ void Sort(){ int i,j; OBJ temp; //yが小さいものから順に並べる for(i=0;i obj[j].y){ temp = obj[i]; obj[i] = obj[j]; obj[j] = temp; } } } } /********************************************************************************/ /* */ /* ロード */ /* */ /********************************************************************************/ void Load(){ int i; char file[MAX_PATH]; for(i=0;i=1){ if(Bmps[images[ihead-1].bmp].File[0]!='\0'){ //鑑賞モードの場合、中央に表示 elDraw::DirectLayer(0,0,Bmps[images[ihead-1].bmp].Obj,0,0, Bmps[images[ihead-1].bmp].width, Bmps[images[ihead-1].bmp].height); } } if(DebugMode){ sprintf(temp,"Time:%3d Left:%3d/%3d",(int)PassTime,obj[head].syousetu,MaxSyousetu); SHOW(0,0,temp); sprintf(temp,"wav(%3d/%3d) bmp(%3d/%3d) ",head,LastID,ihead-1,LastImageID); SHOW(0,20,temp); if(MusicEndFlag){ SHOW(FX+100,BOTTOM-70,"END"); } } } /********************************************************************************/ /* */ /* 処理 */ /* */ /********************************************************************************/ void Action(){ int i; BOOL flags[9]; int start; //ロード開始 if(LoadFlag){ Reset(); LoadScript(SelectedNo); Load(); StartFlag=TRUE; FirstWait=F(2); LoadFlag = FALSE; } for(i=0;i<9;i++){PushKeyFlags[i]=FALSE;} //少し待つ if(FirstWait >= F(0)){ FirstWait-=FrameTime; return; } if(!StartFlag || EndFlag)return; PassTime+=FrameTime;//時間経過 //オブジェ移動(wav) for(i=0;i<=LastID;i++){ obj[i].y-=FrameTime/F(240.0/Tempo); } //オブジェ移動(bmp) for(i=0;i<=LastImageID;i++){ images[i].y-=FrameTime/F(240.0/Tempo); } //終了後、10秒待つ if(MusicEndFlag){ WaitTime+=FrameTime; if(WaitTime >= F(10)){ MusicEndFlag=FALSE; Reset(); StartFlag=FALSE; EndFlag=TRUE; return; } } //次の音を用意 start=head-9; if(start<0)start=0; for(i=0;i<9;i++)flags[i]=FALSE; for(i=start;i<=LastID;i++){ if(obj[i].y > F(0.5))break; if(obj[i].key!=-1 && !obj[i].done){ if(flags[obj[i].key]==FALSE){ flags[obj[i].key]=TRUE; key[obj[i].key]=obj[i].wav; } } } //ライン上に来た場合(wav) while(!WavEndFlag && !obj[head].lineflag && obj[head].y<=F(0)){ //その音を鳴らす if(!obj[head].tempoflag){ if(obj[head].key>=0){//オートプレイ PushKeyFlags[obj[head].key]=TRUE; PushCheck(obj[head].key); }else if(strcmp(WavFiles[obj[head].wav-1],"")!=0){//BGMの場合 elSound::Play(Wavs[obj[head].wav-1]); } }//テンポ変更 else if(obj[head].tempoflag){ Tempo=obj[head].tempo; } obj[head].lineflag=TRUE; head++; //最後の音 if(head==LastID+1){ head--; WavEndFlag=TRUE; break; } } //ライン上に来た場合(bmp) while(!BmpEndFlag && images[ihead].y<=F(0)){ ihead++; if(ihead==LastImageID+1){ BmpEndFlag=TRUE; break; } } //終了判定 if(WavEndFlag && BmpEndFlag){ MusicEndFlag=TRUE; } //終了時 if(MusicEndFlag){ WaitTime+=FrameTime; } } /********************************************************************************/ /* */ /* 判定 */ /* */ /********************************************************************************/ void PushCheck(int KeyNo){ int i,id=-1; float most; if(!StartFlag)return; PushKeyFlags[KeyNo]=TRUE; //音を鳴らす if(key[KeyNo]-1>=0 && strcmp(WavFiles[key[KeyNo]-1],"")!=0){ elSound::Play(Wavs[key[KeyNo]-1]); } if(EndFlag)return; //ライン周りにオブジェがあるかチェック for(i=0;i<=LastID;i++){ if(obj[i].key == KeyNo && !obj[i].done){ if(obj[i].y>=F(-0.05) && obj[i].y=F(0.02)){ obj[id].done=TRUE; } //GREAT else if(most>=F(-0.02)){ obj[id].done=TRUE; } //GOOD else{ obj[id].done=TRUE; } } /********************************************************************************/ /* */ /* キー入力 */ /* */ /********************************************************************************/ void KeyAction(){ while(elSystem::InputLoop()){ switch(elSystem::Get.Code){ case VC_ESC: if(elSystem::Get.Status){ //リセット if(StartFlag){Reset();StartFlag=FALSE;} else{ ExitFlag = TRUE; return; } } break; case VC_RIGHT:case VC_DOWN: if(elSystem::Get.Status && !StartFlag){ elSound::Play(SeWavs[0]); if(++SelectedNo > MaxSelectNum)SelectedNo=0; } break; case VC_LEFT:case VC_UP: if(elSystem::Get.Status){ if(!StartFlag){ elSound::Play(SeWavs[0]); if(--SelectedNo < 0){SelectedNo=MaxSelectNum;} } } break; case VC_ENTER: if(elSystem::Get.Status){ if(!StartFlag){ LoadFlag = TRUE;//ロード開始フラグ } } break; case VC_TAB://デバッグモード if(elSystem::Get.Status){ DebugMode=!DebugMode; } break; case VC_F4://テンポを二倍 if(elSystem::Get.Status){ Tempo*=2; if(++TempoChangeCount >= 5){ Tempo/=32; TempoChangeCount=0; } } break; } } } /********************************************************************************/ /* */ /* メイン関数 */ /* */ /********************************************************************************/ int elMain("BMSA鑑賞"); { elWindow(256,256,FALSE); elLoop(){ elSetScreen(MAIN_SCREEN,MainScreen()); } elExitMain(); } /********************************************************************************/ /* */ /* ウィンドウ生成関数 */ /* */ /********************************************************************************/ void elCreate(void) { elDraw::Screen(640,480); elCallScreen(MAIN_SCREEN); } /********************************************************************************/ /* */ /* キーボード関数 */ /* */ /********************************************************************************/ void elKeyboard(void) { elExitKeyboard(); } /********************************************************************************/ /* */ /* イベント関数 */ /* */ /********************************************************************************/ long elEvent(void) { elExitEvent(); } /********************************************************************************/ /* */ /* メイン画面 */ /* */ /********************************************************************************/ void MainScreen(void) { //画面が切り替わった時 if(elChangeScreen()){ Init();//初期化 } elDraw::Clear(); Disp();//描画 elDraw::Refresh(); Action();//処理 KeyAction();//キー入力 //終了 if(ExitFlag){ elDraw::Exit(); } }