S.F. Page

Programming,Music,etc...

STed2 いじり edit.cを読む。

一番興味のあるところ、エディタおよびトラック部分のソースコードを読んでいる。

やっぱりこれくらいのアプリだとすごい込み入っている。

例えばイベントを1行表示するedit.cのtrk_dis()関数、下の絵の青で囲った部分を表示するだけなんだけれど、ソースコードは長い。

20101223.PNG

static char tmp0[64],tmp1[64];
int i,po,cc=0,x,a,b,c,d,capi,skey;
int meas=0,meas2=0,step=0,sta;
unsigned char   *bp=trk[track];
sta=SUPER(0);
x=edit_scr*56+1;po=ad;
skey=scale_no(ad);
if(line==1){
if(po==0 || bp[po-4]>=0xfc || bp[po]==0xfc){goto clpo;}
if(!(bp[po]<0xf0 &&(po==0||bp[po-4+1]!=0||bp[po-4]>=0xf0))){goto trpo;}
}
clpo:
if(y>=0){
while(po>0){
unsigned char   e;
po=po-4;e=bp[po];
if(meas2==0){
if(e<0xf0 &&(po==0||bp[po-4+1]!=0||bp[po-4]>=0xf0)){
if(bp[po-4]==0xf7){
while(bp[po-4]==0xf7){po-=4;}
if(bp[po-4]==0x98 && bp[po-4+1]==0){goto next1;}
}
step++;
}
}
next1:
if( e==0xfd ){
meas=bp[po+2]*256+bp[po+3];break;
}else{
if( e>=0xfc || bp[po+4]==0xfc){meas2++;}
}
}
meas+=meas2;step++;meas++;po=ad;
}
trpo:
cons_md(0);
while(line!=0){
cc=0;
redis:
if( po>=tr_len[track] ){tmp0[0]=0;tmp1[0]=0;goto brank;}
a=bp[po];b=bp[po+1];c=bp[po+2];d=bp[po+3];
if(a==0xf7){po+=4;goto redis;}
if( a!=0xfe ){
if(po==0 || bp[po-4]>=0xfc || bp[po]==0xfc){
strcpy(tmp1,fstr(meas,5));
}else{
strcpy(tmp1,"     ");
}
if(a<0xf0 &&(po==0||bp[po-4+1]!=0||bp[po-4]>=0xf0)){
if(bp[po-4]==0xf7){
int pp=po-4;
while(bp[pp]==0xf7){pp-=4;}
if(bp[pp]==0x98 && bp[pp+1]==0){goto next2;}
}
strcat(tmp1,fstr(step,5));strcat(tmp1,":");step++;
}else{
next2:
strcat(tmp1,"     :");
}
}else{
strcpy(tmp1,"            ");
}
if( a<128 ){
if(c!=0 && d!=0){
if(y<=0){
strcpy(tmp0,keystr(a));
}else{
strcpy(tmp0,keystr1(a,skey));
}
}else{
strcpy(tmp0,"   ");
}
strcat(tmp0,fstr(a,4));strcat(tmp0,fstr(b,6));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));
if(b>0 && c>b){tmp0[19]='*';}
if(b==0 && c>0){
int i0=po;
while(i0<tr_len[track]-8){
i0=i0+4;
if(bp[i0]<0xf7){
int e=bp[i0+1];
if(e>0){
if(c>e){tmp0[19]='*';}
break;
}
}
}
}
if(b==0){cc=2;}
}else{
switch( a){
case  0x90:
case  0x91:
case  0x92:
case  0x93:
case  0x94:
case  0x95:
case  0x96:
case  0x97:
strcpy(tmp0,"UserExc ");tmp0[7]=a-0x90+'0';
strcat(tmp0,fstr(b,5));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));
break;
case  0x98:
strcpy(tmp0,"Tr.Exclu");
strcat(tmp0,fstr(b,5));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));
while(bp[po+4]==0xf7){po+=4;}
break;
case  0xdd:
strcpy(tmp0,"Rol.Base");
/*strcat(tmp0,fstr(b,5));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));*/
break;
case  0xde:
strcpy(tmp0,"Rol.Para");
/*strcat(tmp0,fstr(b,5));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));*/
break;
case  0xdf:
strcpy(tmp0,"Rol.Dev#");
/*strcat(tmp0,fstr(b,5));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));*/
break;
case  0xe6:
strcpy(tmp0,"MIDI CH.");strcat(tmp0,fstr(b,5));
strcat(tmp0,"   ");strcat(tmp0,chstr(c));
break;
case  0xe7:
strcpy(tmp0,"TEMPO");strcat(tmp0,fstr(b,8));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));
break;
case  0xea:
strcpy(tmp0,"AFTER C.");strcat(tmp0,fstr(b,5));
strcat(tmp0,fstr(c,6));
break;
case  0xeb:
strcpy(tmp0,ctrl_type(c));
strcat(tmp0,fstr(b,5));strcat(tmp0,fstr(c&127,6));
strcat(tmp0,fstr(d,6));
break;
case  0xe2:
capi=channele_no(po);
strcpy(tmp0,"BankProg");
/*                  d|=(bank_no(po)&0xff00);
1997-10-10      trk.edでのbankprgの表示がbank lsbに対応して
なかったのを修正した
*/
if(b==0){
strcat(tmp0,prog_name(capi,d,c,3));b=1;
}else{
strcat(tmp0,fstr(b,5));
strcat(tmp0,prog_name(capi,d,c,2));
}
break;
case  0xec:
capi=bank_no(po);
strcpy(tmp0,"PROGRAM ");
if(b==0){
strcat(tmp0,prog_name(d,capi,c,1));b=1;
}else{
strcat(tmp0,fstr(b,5));
strcat(tmp0,prog_name(d,capi,c,0));
}
break;
case  0xed:
strcpy(tmp0,"AFTER K.");strcat(tmp0,fstr(b,5));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));
break;
case  0xee:
strcpy(tmp0,"PITCH");strcat(tmp0,fstr(b,8));
strcat(tmp0,fstr((c+d*128)-8192,12));
break;
case  0xc0:strcpy(tmp0,"DX7FUNC");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xc1:strcpy(tmp0,"DX.PARA");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xc2:strcpy(tmp0,"DX.PREF");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xc3:strcpy(tmp0,"TX.FUNC");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xc5:strcpy(tmp0,"FB-01 P");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xc6:strcpy(tmp0,"FB-01 S");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xc7:strcpy(tmp0,"TX81Z V");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xc8:strcpy(tmp0,"TX81Z A");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xc9:strcpy(tmp0,"TX81Z P");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xca:strcpy(tmp0,"TX81Z S");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xcb:strcpy(tmp0,"TX81Z E");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xcc:strcpy(tmp0,"DX7-2 R");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xcd:strcpy(tmp0,"DX7-2 A");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xce:strcpy(tmp0,"DX7-2 P");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xcf:strcpy(tmp0,"TX802 P");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xdc:strcpy(tmp0,"MKS-7  ");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));break;
case  0xe5:strcpy(tmp0,"KeyScan");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));break;
/*              case  0xef:strcpy(tmp0,"CMU-800");strcat(tmp0,fstr(b,6));strcat(tmp0,fstr(c,6));break;*/
case  0xf5:strcpy(tmp0,"Music Key ");strcat(tmp0,scale_str(b));skey=b;b=1;break;
case  0xf6:
strcpy(tmp0," [                      ]");
i=3;
while(i<25){
unsigned char a;
a=bp[po+2];if(a==0){a=32;}tmp0[i++]=a;
a=bp[po+3];if(a==0){a=32;}tmp0[i++]=a;
if(bp[po+4]!=0xf7){break;}
po+=4;
}
/*strncpy(tmp0,(const char *)eucconv(tmp0),26); /* code converted! */
strncpy(tmp0,tmp0,26);
b=1;break;
case  0xf8:
strcpy(tmp0,"      ]");if(b==0){b=256;}
strcat(tmp0,fstr(b,6));break;
case  0xf9:strcpy(tmp0,"Repeat[");break;
case  0xfc:
strcpy(tmp0,"=========");
strcat(tmp0,fstr(((c&3)*256+b)+1,4));
strcat(tmp0," ===========");
b=1;break;
case  0xfd:
strcpy(tmp0,"--------");
strcat(tmp0,fstr(step_cluc(po),5));
strcat(tmp0," -----------");
b=1;break;
case  0xfe:
strcpy(tmp0,"      [End of Track]");
break;
default:
strcpy(tmp0,fstr(a,7));strcat(tmp0,fstr(b,6));
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));
break;
/* UNKNOWN SEQUENCE */
}
if(a>=0xdd && a<=0xdf){
strcat(tmp0,fstr(b,5));
if((cmdflag & 0x100)!=0){
strcat(tmp0,"   ");strcat(tmp0,hex_s(c,2));
strcat(tmp0,"H   ");strcat(tmp0,hex_s(d,2));
strcat(tmp0,"H");
}else{
strcat(tmp0,fstr(c,6));strcat(tmp0,fstr(d,6));
}
}
if( a<253 && a!=0xf6 ){cc=1;}
}
if(a>=0xfc || bp[po+4]==0xfc){meas++;step=1;}
if( a<252 && b==0 ){tmp0[10]=32;tmp0[11]=32;tmp0[12]=32;}
brank:
if(y<=0){break;}
B_LOCATE(x,y);
/*
if(cc==0){strcat(tmp1,tmp0);H_PRINT(tmp1,"","");
}else{if(cc==1){H_PRINT(tmp1,"",tmp0);}else{H_PRINT(tmp1,tmp0,"");}}
*/
if(cc==0){strcat(tmp1,tmp0);H_PRINT(eucconv(tmp1),"","");
}else{if(cc==1){H_PRINT(tmp1,"",tmp0);}else{H_PRINT(tmp1,tmp0,"");}}
/* code converted! Sep.12.1998 Daisuke Nagano */
if( line<0 ||(cplen<0 && cpadd==po) ){
if( line<0 ){line=-line;}
tcur(1,y,11,0);tcur(12,y,26,cc);
}
po=po+4;line--;y++;
}
cons_md(1);
if(y<=0){strcat(tmp1,tmp0);}
SUPER(sta);
return(tmp1);
}

STed2の本体のソースコードは、なんとなくBASICっぽい香りがしないでもない。B_LOCATEとかB_PRINTとかBASICの構文ぽい関数・マクロが随所に見られる。
マルチステートメントが多用されているところもなんとなくそれっぽい。

私はまともなエディタを作れないでいるのだけれど、相当コードを書いてあげないといけないなぁ。。というのが実感できる。 エディットモードや編集イベントの種類やフラグとか様々な状態を想定した処理を書かないといけないので混みいったコードになるのは仕方がない。
なんとなくこういう面倒くささが想像できるのでコードを書くのが億劫になってしまうんだよね。
これは私にとっての壁になっている。