一番興味のあるところ、エディタおよびトラック部分のソースコードを読んでいる。
やっぱりこれくらいのアプリだとすごい込み入っている。
例えばイベントを1行表示するedit.cのtrk_dis()関数、下の絵の青で囲った部分を表示するだけなんだけれど、ソースコードは長い。
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の構文ぽい関数・マクロが随所に見られる。
マルチステートメントが多用されているところもなんとなくそれっぽい。
私はまともなエディタを作れないでいるのだけれど、相当コードを書いてあげないといけないなぁ。。というのが実感できる。
エディットモードや編集イベントの種類やフラグとか様々な状態を想定した処理を書かないといけないので混みいったコードになるのは仕方がない。
なんとなくこういう面倒くささが想像できるのでコードを書くのが億劫になってしまうんだよね。
これは私にとっての壁になっている。