/*=========================================================[ PM.C ]=====*/ /* Play Music */ /* ver 1.30 by FJK H04/12/16 */ /*======================================================================*/ #include #include #include #include #include #include #include #include #include "tools.h" /*------------------- MACROS ----------------------*/ #define MDATMAX 1600 /* MMLデータの格納サイズ */ #define MDSPMAX 800 /* MMLデータの編集サイズ */ #define CLS() printf("\x1b[2J") /* 全画面の消去 */ #define CLS_E() printf("\x1b[0J") /* 現在位置から画面終わりまで消去 */ #define CLS_L() printf("\x1b[0K") /* 現在位置から行末まで消去 */ #define WHITE() printf("\x1b[0m") /* 文字の色を白色に */ #define RED() printf("\x1b[31m") /* 文字の色を赤色に */ #define GREEN() printf("\x1b[32m") /* 文字の色を緑色に */ #define YELLOW() printf("\x1b[33m") /* 文字の色を黄色に */ #define BLUE() printf("\x1b[34m") /* 文字の色を青色に */ #define MAZENTA() printf("\x1b[35m") /* 文字の色を紫色に */ #define CYAN() printf("\x1b[36m") /* 文字の色を水色に */ #define R_RED() printf("\x1b[41m") /* 文字の色を赤色に */ #define SHFT k[14]&0x01 /* キーコード */ #define CAPS k[14]&0x02 #define KANA k[14]&0x04 #define CTRL k[14]&0x10 #define SPACE k[ 6]&0x10 #define RLUP k[ 6]&0x40 #define RLDWN k[ 6]&0x80 #define CRTN k[ 3]&0x10 #define TAB k[ 1]&0x80 #define BS k[ 1]&0x40 #define ESC k[ 0]&0x10 #define SLASH k[ 8]&0x02 #define FUNC1 k[12]&0x04 #define FUNC2 k[12]&0x08 #define FUNC3 k[12]&0x10 #define FUNC4 k[12]&0x20 #define FUNC5 k[12]&0x40 #define FUNC6 k[12]&0x80 #define FUNC7 k[13]&0x01 #define FUNC8 k[13]&0x02 #define FUNC9 k[13]&0x04 #define FUNC10 k[13]&0x08 /*-------------- 共通変数 ----------------------*/ MC_MML mc; /* 演奏用構造体 */ MC_INQUIRE inq; /* サウンドIC情報構造体 */ char *mmd[6]; /* MMLデータ格納ポインタ */ char *fbf; /* ファイルアクセス用ワークポインタ */ int ch = 0; /* 編集選択チャンネル */ int lng = 4; /* デフォルト音長 */ int oct = 5; /* デフォルトオクターブ */ int snd = 5; /* 音色番号 */ int tmpo = 120; /* テンポ */ int loct = 5; /* 一つ前の音のオクターブ */ char sbf[80] = ""; /* 一時発声用MMLデータ */ char title[80] = ""; /* 曲名 */ char fnam[21] = ""; /* ファイル名 */ static char *kcd_grp[][8]={ /* 鍵盤データ */ NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL, "{" ,"}" ,"Q7","Q8","^" ,"R" ,NULL,NULL, "G#","A#",NULL,"C#","D#",NULL,"F#","G#", "A#",NULL,"C#","D#",NULL,"A" ,"B" ,"C", "D" ,"E" ,"F" ,"G" ,"A" ,"B" ,"C" ,"D", "E" ,NULL,NULL,NULL,NULL,NULL,NULL,NULL }; static int oct_grp[][8]={ /* オクターブデータ */ 0, 0, 0, 0, 0, 0, 0, 0, 98,99,98,98,99,99, 0, 0, -1,-1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0,-1,-1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, }; char tm[] = "@ABCDEFGKLMOPQRSTV!*<>{}# ^.0123456789"; /* MML有効キーデータ */ char *neiro[] = /* 80種類の音色(STEEL'S CRYは無し)*/ { "低域の金管楽器","高域の弦楽器 ","丸いEピアノ ","シンセサイザベース " ,"堅めEオルガン","低域パイプオルガン","フ ル ー ト  ","オ ー ボ エ " ,"クラリネット ","ビブラフォン ","ハープシコード","ベ  ル   " ,"アコースティックピアノ","虫の鳴き声  ","下降する効果音","UFO効果音 " ,"レーシングカー","SF効果音(1) ","SF効果音(2) ","正 弦 波  " ,"高域の金管楽器","低域の金管楽器","トランペット ","低域の弦楽器 " ,"高域の弦楽器 ","エレクトリックピアノ ","堅めEピアノ ","丸いEピアノ " ,"エレキギター ","シンセサイザベース ","ウッドベース ","堅めEオルガン" ,"丸いEオルガン","低域パイプオルガン","高域パイプオルガン","フ ル ー ト " ,"ピ ッ コ ロ ","オ ー ボ エ  ","クラリネット ","グロッケン " ,"ビブラフォン ","シロフォン  ","琴      ","チ タ ー  " ,"クラビネット ","ハープシコード","ベ ル   ","ハ ー プ  " ,"ベルと金管楽器","ハーモニカ  ","スチームドラム","ティンパニー " ,"汽 笛 の 音  ","救急車の音  ","小 鳥 の 声  ","雨だれの音  " ,"ホ ル ン  ","スネアドラム ","カ ウ ベ ル  ","バネが弾ける音" ,"グラスを弾く音","ウィンドチャイム ","オルゴール  ","チ ェ ロ  " ,"チ ュ ー バ  ","木管楽器asmbl,","アコーステックギター ","フルートとハープ  " ,"打 弦 楽 器  ","ファンキーベース ","メロディラインリード","金属効果音(1) " ,"金属効果音(2) ","氷の転がる音 ","人 の 声  ","ウッドベース " ,"チ ャ イ ム ","機械的な口笛 ","オーボエとクラリネット ","古いバイオリン" }; /*==================================================================*/ /*--------------- 指定されたキーグループの押し下げチェック ---------*/ chk_keyg(int g) { KEY_INFO key; key.cmmd=4; key.group_num=g; return( bios98key(&key) ); /* 押し下げ情報を返す */ } /*--------------- 全てのキーをチェックしk[]に格納 ------------------*/ get_keyg(int *k) { int i; for(i=0;i<15;i++,k++) *k = chk_keyg(i); } /*--------------- 1が立っているビット位置を返す ---------------------*/ chk_bit(int b) { if(b&0x01) return(0); if(b&0x02) return(1); if(b&0x04) return(2); if(b&0x08) return(3); if(b&0x10) return(4); if(b&0x20) return(5); if(b&0x40) return(6); if(b&0x80) return(7); return(-1); } /*-------------- 文字列中の下線を空白に置き換える --------------------*/ clr_uber(char *p) { while(*p!='\0'){ if(*p=='_') *p=' '; p++; } } /*-------------- 文字列中の空白を下線に置き換える --------------------*/ rps_uber(char *p) { while(*p!='\0'){ if(*p==' ') *p='_'; p++; } } /*-------------- 文字列の色指定付き画面出力 --------------------------*/ pc(char *str) { while(*str!=0){ if(iskanji(*str)){ putchar(*str); str++; putchar(*str); }else{ switch(*str){ case 'ミ': putchar(' '); GREEN(); break; case 'キ': putchar(' '); YELLOW(); break; case 'ホ': putchar(' '); WHITE(); break; case 'シ': putchar(' '); CYAN(); break; case 'レ': RED(); break; case 'マ': MAZENTA(); break; case 'ヲ': str++; printf(" \x1b[32m%c\x1b[0m",*str); break; case 'ワ': WHITE(); break; default: putchar(*str); break; } } str++; } WHITE(); } /*=============================================================*/ /*--------------- 鍵盤入力時の説明 ----------------------------*/ setumei() { CYAN(); printf(" 基本が4分音符なら"); pc("キSHIFTシは8分音符、キCTRLシは2分音符、キSHIFT+CTRLシは全音符\n"); pc("キスペースシは符点追加、キカナシは基本を16分音符に、キCAPSシは8分音符に\n"); pc("キBSシは一つ前を消去、キSHIFT+TABシはこのチャンネルのみ演奏\n"); pc("キf・1〜6シ各チャンネルにキf・7シロード キf・8シセーブ キf・9シMML編集 キf・10シで終わり。"); } /*--------------- 鍵盤の表示 -----------------------------------*/ kenban(int py) { gotoxy(1,py); pc("OCCCoCCCoCCCoCCCoCCCoCCCoCCCoCCCoCCCoCCCoCCCoCCCoCCCCCCS キROLLUP\n"); pc("Eソ#Eラ#E Eド#Eレ#E Eファ#Eソ#Eラ#E Eド#Eレ#E 小節 E シオクターブ上げホ\n"); pc("E ヲQE ヲWE E ヲRE ヲTE E ヲUE ヲIE ヲOE E ヲ@E ヲ[E 区切 E キROLLDOWN\n"); pc("WCoCwCoCwCoCwCoCwCoCwCoCwCoCwCoCwCoCwCoCwCoCwCoCwCS E シオクターブ下げ\n"); pc(" ホEラ Eシ Eド Eレ Eミ Eファ Eソ Eラ Eシ Eド Eレ Eミ E E キ\\シは休符\n"); pc(" ホE ヲAE ヲSE ヲDE ヲFE ヲGE ヲHE ヲJE ヲKE ヲLE ヲ;E ヲ:E ヲ]EミcrホE キ^シはタイ\n"); pc(" ホWCCCwCCCwCCCwCCCwCCCwCCCwCCCwCCCwCCCwCCCwCCCwCCCwCCCC[\n"); setumei(); } /*--------------- 音色データの入力 -----------------------------*/ sound_in() { WIN *wp; int sel; MENU nir = { 4,20,16,-2,-3 }; menu_blnk(2); wp = wm_open(&nir,neiro,1,3," 音色の選択 ",-7,-6,-4,1); w_msgout(wp,"CRで決定、中止はESC",-6); nir.last = snd-1; sel = wm_sel(wp,&nir,80); if(sel) snd = sel; w_close(wp); menu_blnk(0); while(chk_keyg(3)); /* キーが離れるまで待つ */ kb_flash(); return(sel); } /*-------------- 編集の説明 -------------------------------*/ ed_setumei() { pc("\n シ<MML編集モード>\n"); pc(" ミ←→↑↓ホキーで位置を合わせ、MMLデータをキーで挿入できます。\n"); pc("ミDELホを押すと消去、ミESCホを押すと音符入力に戻ります"); } /*--------------- 入力パラメータの表示 -------------------------*/ parameta() { int x,y; x = wherex(); y = wherey(); gotoxy(1,2); CYAN();printf(" チャンネル:"); WHITE();printf("%2d",ch+1); /* px=9 */ CYAN();printf(" テンポ:"); WHITE();printf("%3d",tmpo); /* px=18 */ CYAN();printf(" オクターブ:"); WHITE();printf("%2d",oct); /* px=30 */ CYAN();printf(" オンチョウ:"); WHITE();printf("%2d",lng); /* px=40 */ CYAN();printf(" 分音符 "); CYAN();printf(" ネイロ: "); WHITE();printf("%s",neiro[snd-1]);/* px=58 */ gotoxy(x,y); } /*-------------- パラメータの表示書換え ----------------------*/ dsp_para(int pn, int dt ) { int x,y; x = wherex(); y = wherey(); switch(pn){ case 1: gotoxy( 9,2); printf("%2d",dt); break; case 2: gotoxy(18,2); printf("%3d",dt); break; case 3: gotoxy(30,2); printf("%2d",dt); break; case 4: gotoxy(40,2); printf("%2d",dt); break; case 5: gotoxy(58,2); printf("%s",neiro[dt-1]); break; } gotoxy(x,y); } /*-------------- 曲名の表示 -------------------------------*/ dsp_name(char *str) { int x,y; x = wherex(); y = wherey(); gotoxy(1,1); CLS_L(); GREEN(); printf("曲 名: "); YELLOW(); printf("%s",str); WHITE(); gotoxy(x,y); } /*-------------- 音の追加および発声 -----------------------*/ add_play(char *mdata, char *sbf) { if(strlen(mdata)>MDSPMAX){ w_error("\n\t","これ以上データを追加できません"); }else{ printf("%s",sbf); /* 画面に表示 */ mc_play(&mc); /* その音を出す */ strcat(mdata,sbf); /* データに追加 */ } } /*============================================================*/ /*-------------- 1文字の挿入 -------------------------------*/ ins_ch(char *s, int c) { int a,b,x,y; x = wherex(); y = wherey(); a = c; do{ b = *s; *s = a; putchar(a); a = b; s++; }while(a!=0); *s = 0; gotoxy(x,y); putchar(c); } /*-------------- 1文字の削除 ---------------------------*/ del_ch(char *s) { int x,y; x = wherex(); y = wherey(); while(*s!=NULL){ *s = *(s+1); s++; putchar(*s); } putchar(' '); gotoxy(x,y); } /*----------- 現在チャンネルの初期化 -------------------*/ init_ch() { int i; mc_initialize(); for(i=0;i<6;i++) mc.mml[i] = NULL; sprintf(sbf,"T%03d@%02dL%dO%d",tmpo,snd,lng,oct); mc.mml[ch] = sbf; mc_play(&mc); } /*------------- 1チャンネルのみの演奏 ------------------*/ play_sgl(char *mmdat) { int kf,i,x,y,trs; char c,*sp,*ep,*me; CRS_OFF(); x = wherex(); y=wherey(); kb_flash(); init_ch(); mc_ground(2); /* バックグラウンドで演奏 */ sp = mmdat; ep = sp+80; me = sp + strlen(mmdat); trs = 1; CYAN(); do{ /* 80文字づつ演奏させます */ if((trs)&&(spstr+80){ putchar(c); s -= 80; } else{ while(s>str){ putchar(0x08); s--; } } break; case 0x09: /* TABキーでカーソル位置から演奏 */ p = s; while((*p!=NULL)&&(!isalpha(*p))) p++; play_sgl(p); YELLOW(); break; default: /* その他の文字はデータへ挿入 */ t = strchr(tm,toupper(c)); if(t!=NULL){ ins_ch(s,*t); s++; smx++; } } } }while(loop); while(s!=smx){ putchar(*s); s++; } } /*===============================================================*/ /*------------ 指定のチャンネルに切り替える -----------*/ char *set_chan(int n) { int i; ch = n; dsp_para(1,ch+1); strncpy(sbf,mmd[ch],7); gotoxy(1,15); CLS_E(); for(i=0;i<6;i++){ if(ch==i) mc.mml[i]=sbf; else mc.mml[i]=""; } mc_play(&mc); printf("%s",mmd[ch]); while(chk_keyg(12)); return(mmd[ch]); } /*------------ 必要なら音長表示を変更する --------------*/ ln_chg(int *ln,int n) { if(*ln!=n){ *ln=n; dsp_para(4,n); } } /*------------ 文字列の最後の文字の取得 ---------------*/ char str_last(char *s) { int e; char *p; e = strlen(s); p = s+e; if(e>0){ for(p--;e>0;e--,p--){ if(*p!=' ') break; } } return(*p); } /*------------ MMLデータ入力 -----------------------------------*/ mml_in(int md) { int c,i,kf,sc,kn,co,ln; int k[16]; char *mdata; /* 編集中のデータ */ char *ml,*mp,bf[20]; CLS(); /* 画面の初期化 */ dsp_name(title); parameta(); kenban(3); mdata = mmd[ch]; gotoxy(1,15); if(md==0){ /* 新規作成の場合 */ snd = 5; if(sound_in()==0) return(1); title[0]='\0'; dsp_name(title); dsp_para(5,snd); gotoxy(1,15); CLS_E(); sprintf(sbf,"T%03d@%02dL%dO%d",tmpo,snd,lng,oct); strcpy(mdata,sbf); }else{ /* 追加の場合 */ sprintf(sbf,"T%03d@%02dL%dO%d",tmpo,snd,lng,oct); } for(i=0;i<6;i++){ /* 現在のチャンネルのみ有効とする */ if(ch==i) mc.mml[i]=sbf; else mc.mml[i]=""; } mc_play(&mc); printf("%s",mdata); loct = oct; ln = 0; /*======= 主ループ ======*/ do{ get_keyg(k); /* キーチェック */ if(KANA){ /* カナロックのチェック */ if(lng!=16){ /* カナロックなら基本音長は16分音符 */ sprintf(sbf,"L16"); add_play(mdata,sbf); lng = 16; dsp_para(4,16); } } else if(CAPS){ /* CAPSロックのチェック */ if(lng!=8){ /* CAPSロックなら基本音長は8分符 */ sprintf(sbf,"L8"); add_play(mdata,sbf); lng = 8; dsp_para(4,8); } } else if(lng!=4){ /* ロックなしなら基本音長は4分音符 */ sprintf(sbf,"L4"); add_play(mdata,sbf); lng = 4; dsp_para(4,4); } /* SHIFT、CTRL チェック */ if(lng==16){ if((SHFT)&&(CTRL)){ ln_chg(&ln,64); } /* SHIF+CNTLなら基本の1/4 */ else if(SHFT){ ln_chg(&ln,32); } /* SHIFのみなら基本の1/2 */ else if(CTRL){ ln_chg(&ln, 8); } /* CNTLのみなら基本の2倍 */ else{ ln_chg(&ln,16); } /* SHIFもCNTLもないなら基本 */ }else if(lng==8){ if((SHFT)&&(CTRL)){ ln_chg(&ln, 2); } else if(SHFT){ ln_chg(&ln,16); } else if(CTRL){ ln_chg(&ln, 4); } else{ ln_chg(&ln, 8); } }else{ if((SHFT)&&(CTRL)){ ln_chg(&ln, 1); } else if(SHFT){ ln_chg(&ln, 8); } else if(CTRL){ ln_chg(&ln, 2); } else{ ln_chg(&ln, 4); } } /* 鍵盤キーのチェック */ kf = 0; for(sc=1;sc<6;sc++){ /* 鍵盤として有効なキーか調べる */ if(k[sc]){ kn = chk_bit(k[sc]); ml = kcd_grp[sc][kn]; /* 有効ならMMLコードを得る */ if(ml!=NULL){ kf=1; break; } } } if(kf){ /* 鍵盤キーが押された場合 */ sprintf(sbf,""); co = oct_grp[sc][kn]; if(co<90){ if( loct != oct+co ){ loct = oct+co; sprintf(sbf,"O%d",loct); } } if(*ml=='^'){ c = str_last(mdata); if(!(isdigit(c)||(c=='.')) ){ sprintf(bf,"%d",lng); strcat(sbf,bf); } } if(co==98){ strcat(sbf,ml); }else{ if(SPACE){ /* 符点がある */ sprintf(bf,"%s%d.",ml,ln); }else{ /* 符点が無い */ if( (ln!=lng)||(*ml=='^')||(*ml=='}') ){ sprintf(bf,"%s%d",ml,ln); }else sprintf(bf,"%s" ,ml); } strcat(sbf,bf); } add_play(mdata,sbf); while(chk_keyg(1)); /* キーが離れるまで待つ */ } else if(RLDWN || RLUP){ if((oct>1) && RLDWN){ oct--; dsp_para(3,oct); } if((oct<8) && RLUP){ oct++; dsp_para(3,oct); } while(chk_keyg(6)); /* キーが離れるまで待つ */ } else if((TAB)&&(SHFT)){ /* 1チャンネル演奏 */ play_sgl(mdata); mc.mml[ch]=sbf; sprintf(sbf,"O%dL%d",oct,lng); mc_play(&mc); while(chk_keyg(1)); /* キーが離れるまで待つ */ } else if(BS){ /*=== データ消去 ===*/ mp = mdata+strlen(mdata); while(mp>mdata+7){ if(isalpha(*mp)||(*mp=='^')||(*mp=='{')||(*mp=='}')) break; mp--; putchar('\b'); CLS_L(); } *mp = 0; while(chk_keyg(1)); /* キーが離れるまで待つ */ } else if(CRTN){ strcat(mdata," "); printf(" "); while(chk_keyg(3)); /* キーが離れるまで待つ */ } else if(SLASH){ if(sound_in()){ dsp_para(5,snd); sprintf(sbf,"@%02d",snd); if(mmd[ch][4]=='@'){ mmd[ch][5]=sbf[1]; mmd[ch][6]=sbf[2]; } mc_play(&mc); gotoxy(1,15); CLS_E(); printf("%s",mdata); } } else if(FUNC1){ mdata = set_chan(0); } /* チャンネル1に */ else if(FUNC2){ mdata = set_chan(1); } /* チャンネル2に */ else if(FUNC3){ mdata = set_chan(2); } /* チャンネル3に */ else if(FUNC4){ mdata = set_chan(3); } /* チャンネル4に */ else if(FUNC5){ mdata = set_chan(4); } /* チャンネル5に */ else if(FUNC6){ mdata = set_chan(5); } /* チャンネル6に */ else if(FUNC7){ /* ファイルロード */ gotoxy(1,15); CLS_E(); ld_file(ch,SHFT); /* SHFT付きなら追加 */ gotoxy(1,15); CLS_E(); WHITE(); printf("%s",mdata); } else if(FUNC8){ /* ファイルセーブ */ gotoxy(1,15); CLS_E(); sv_file(ch,SHFT); /* SHFT付きならアペンド */ gotoxy(1,15); CLS_E(); WHITE(); printf("%s",mdata); } else if(FUNC9){ gotoxy(1,10); CLS_E(); ed_setumei(); gotoxy(1,15); YELLOW(); printf("%s",mdata); str_edit(mdata); /* MML編集モードへ */ gotoxy(1,10); CLS_E(); setumei(); gotoxy(1,15); WHITE(); printf("%s",mdata); } rewind(stdin); kb_flash(); /* キーバッファーのクリア */ }while(!(FUNC10)); /* f10でメニューへ戻る */ } /*==================================================================*/ /*---------- ウィンドウによる文字列の取得 -------------*/ w_gets(char *msg,char *str,int n) { WIN *wp; int rt,x; wp = w_open(10,14,70,19,"",-7,-5,-4,1); cprintf(" %s",msg); x = 0; do{ gotoxy(6,3); rt = ledit(str,str,n,x); x = wherex()-1; trimr(str); }while(!((rt==13)||(rt==27))); w_close(wp); return(rt); } /*------------- ウィンドウによる確認 -------------------*/ w_ckms(char *msg1,char *msg2,int yn) { WIN *wp; int rt; wp = w_open(10,14,70,20,"",-7,-4,-4,1); cprintf(" %s%s(YorN)",msg1,msg2); rt = w_yesno(45,17,-7,-7,yn); w_close(wp); return(rt); } /*----------- ウィンドウによるエラーメッセージ -----------*/ w_error(char *msg1,char *msg2) { WIN *wp; wp = w_open(10,14,70,18,"ERROR",-6,-2,-3,1); cprintf(" %s %s\a",msg1,msg2); gotoxy(20,3);cprintf("何かキーを押して下さい"); getch(); w_close(wp); } /*---------------- ファイルのセーブ --------------------*/ sv_file(int n,int md) { FILE *fp; char ffnm[25],omd[2]; int i,rt; rt = w_gets("ファイル名は(中止はESC)? ",fnam,20); if(rt==27) return(0); sprintf(ffnm,"%s.mml",fnam); if((fp=fopen(ffnm,"r"))!=NULL){ fclose(fp); rt = w_ckms(ffnm,"は既にあります。\n\r\tオーバライトしますか?",1); if(rt!=1) return(0); } if(md==0) strcpy(omd,"w"); else strcpy(omd,"a"); if((fp=fopen(ffnm,omd))==NULL){ w_error(ffnm,"はセーブできません"); return(0); } if(strlen(title)!=0) strcpy(fbf,title); rps_uber(fbf); fprintf(fp,"$%s\n",fbf); if(n!=0){ strcpy(fbf,mmd[n]); rps_uber(fbf); fprintf(fp," %s\n",fbf); }else{ for(i=0;i<6;i++){ strcpy(fbf,mmd[i]); rps_uber(fbf); fprintf(fp," %s\n",fbf); } } fclose(fp); return(strlen(fbf)); } /*------------- ファイルのロード ---------------------------*/ ld_file(int n,int md) { FILE *fp; char ffnm[40],*p; int i; menu_blnk(0); i = wget_fnam(ffnm,3,12,5,8,"a:","","*.mml",0); if(i==0) return(0); if((fp=fopen(ffnm,"r"))==NULL){ w_error(ffnm,"はロードできません"); return(0); } fscanf(fp,"%s",fbf); if(fbf[0]=='$'){ clr_uber(fbf); sscanf(fbf+1,"%s",title); dsp_name(title); fscanf(fp,"%s",fbf); } clr_uber(fbf); if(sscanf(fbf,"T%3d",&i)==1){ tmpo = i; dsp_para(2,tmpo); } if(sscanf(fbf+4,"@%2d",&i)==1){ snd = i; dsp_para(5,snd); } if(n!=0){ if(md==0) { strcpy(mmd[ch],fbf); } else { strcat(mmd[ch],fbf); } fbf[79]=0; puts(fbf); }else{ for(i=0;i<6;i++){ if(md==0){ strcpy(mmd[i],fbf); } else { strcat(mmd[i],fbf); } fbf[79]=0; puts(fbf); if(!feof(fp)){ fscanf(fp,"%s",fbf); clr_uber(fbf); }else{ fbf[7]=0; } } } fclose(fp); } /*--------------- 全チャンネルの演奏 -------------------------*/ play_all() { int i,kf,ae; char c[6],*sp[6],*ep[6],*me[6]; mc_initialize(); mc_ground(2); CRS_OFF(); for(i=0;i<6;i++){ sp[i] = mmd[i]; ep[i] = sp[i] + 80; me[i] = sp[i] + strlen(mmd[i])+ 80; } mc_inquire(&inq); do{ ae = 0; for(i=0;i<6;i++){ if(inq.unsize[i]2) strcat(mmd[i],"V15"); mc.mml[i]=mmd[i]; } mc_play(&mc); CONSOLE(0); loop = 1; /* loop = 1 は初期モード */ do{ if(loop==1) main_menu(); gotoxy(1,10); CLS_L(); gotoxy(50,10); YELLOW(); printf("コマンド? "); WHITE(); c=getch(); gotoxy(1,10); CLS_E(); loop = 2; switch(toupper(c)){ case 'N': mml_in(0); loop = 1; break; case 'A': mml_in(1); loop = 1; break; case 'R': YELLOW(); for(i=0;i<6;i++){ printf("\n--- channel %d ---\n",i+1); } WHITE(); play_all(); break; case '/': if(sound_in()>0){ dsp_para(5,snd); sprintf(bf,"%2d",snd); for(i=0;i<6;i++){ if(mmd[i][4]=='@'){ mmd[i][5]=bf[0]; mmd[i][6]=bf[1]; } } } break; case 'S': printf("全チャンネルデータをセーブします。\n"); sv_file(0,0); break; case 'L': printf("全チャンネルデータをロードします。\n\n"); ld_file(0,0); break; case '+': printf("全チャンネルにデータを追加します。\n\n"); ld_file(0,1); break; case 'T': sprintf(bf,"%03d",tmpo); w_gets("\n テンポは(32〜255)? ",bf,3); sscanf(bf,"%d",&tmpo); if(tmpo<32) tmpo=32; else if(tmpo>255) tmpo=255; sprintf(bf,"%03d",tmpo); for(i=0;i<6;i++){ if(mmd[i][0]=='T'){ mmd[i][1]=bf[0]; mmd[i][2]=bf[1]; mmd[i][3]=bf[2]; } } dsp_para(2,tmpo); break; case '1': case '2': case '3': case '4': case '5': case '6': gotoxy(1,12); ch = c - '1'; dsp_para(1,ch+1); puts(mmd[ch]); break; case '@': w_gets("\n 曲名は(中止はESC)? ",title,79); dsp_name(title); break; case 'Q': if(w_ckms("\n","\t本当に終了してもいいですか",1)==1) loop = 0; break; default: loop = 2; break; } }while(loop); mc_stop(); for(i=0;i<6;i++) free(mmd[i]); free(fbf); } /*====================[ e n d ]============== PM.C ===============*/