圧縮ネタ(既出あり)

AXサイズを削減するためのスクリプト記法や、考え方など。

・配列変数へのアクセス時のdup
 同じ配列要素が複数回アクセスされる場合は、できるだけdupしてから行う。(パフォーマンス的にも有利)
 とくにcntを使ったアクセスは、一度まとめてdupして使う。
 キャラクター情報の初期化や座標計算などで、連続代入によって代入処理を減らすことができる。
・連続代入
 配列変数への代入には、x=…,…,… のような記述ができるかを検討する。
 x=y*z,x\10 のように、同じ代入文で計算したばかりのx.0を、以降の要素で即利用可能。
 dimしなくても連続代入すると1次元配列変数になる→場合によりdimの削減ができるかもしれない。
 また、dupと組み合わせると元が取りやすい。
・2次元マップを1次元配列にすることで計算量や引数指定を減らせるか考える。
・if 式=0 {処理} という構文があるなら、if 式 {}else{処理} としてみる。
・フラグ立ては、flag=1の様な記述の代わりに、flag++ や flag-- を使えるか検討する。
 (クリアが適切に行われていることも重要な条件)
・整数型変数クリアやフラグ下げに lpoke flag を使う。
・命令のパラメータが省略できるか検討。
  celput ,n デフォルトでBuffer1を見る。これは常套手段。
  pos ,y  pos x,y後のmesにより改行した場合、pos ,y で同位置指定
  pos x  pos x,y後のcelputの場合、pos x をすると同位置指定
  boxf   画面全体塗りつぶし。基本形。
  boxf x1  (x1,画面上端)-画面右下
  boxf x1,y1  (x1,y1)-画面右下
  boxf x1,y1,x2  (x1,y1)-(x2,画面下端)
  boxf ,y1 (画面左端,y1)-画面右下
  boxf ,y1,x2 (画面左端,y1)-(x2,画面下端)
  boxf ,y1,x2,y2 (画面左端,y1)-(x2,y2)
  color #000000
  color r #000000-$FF0000 g,b:00固定 
  color r,g #000000-$FFFF00 b:00固定  
  color ,g #000000-$00FF00 r,b:00固定 
  color ,g,b #000000-$00FFFF r:00固定  
  hsvcolor ,,n グレイスケール
・単純な色指定としてpalcolorを検討する。
  0〜6,12: RGB二値000〜110,111に相当し、RGB輝度$80
  7: #C0C0C0 Silver/銀色
  8: #C0DCC0 MoneyGreen/薄緑色
  9: #A6CAF0 SkyBlue/薄青色
  10: #FFFBF0 Cream/肌色
  11: #A0A0A4 MedGray/薄灰色
  13〜19:RGB二値001〜111に相当し、RGB輝度$FF
・条件ジャンプに on 〜 gotoを検討
  lp--:if(lp){}else{ goto *stage_clear }
    ↓
  lp--:on lp goto *stage_clear
・論理圧縮
  例1 Aが0かつBが40以上の場合…を処理 Aは0以上の正の整数とする。
     通常 if (A=0)&(B>=40) { … }
     圧縮 if (A<(B>=40)) { … } 8Bytes削減
  例2 点x1,y1が、x2,y2を中心とする矩形(高さh2*2、幅w2*2)の内側にあれば…を処理
     通常 if (x1>(x2-w2))&(x1<(x2+w2))&(y1>(y2-h2))&(y1<(y2+h2)) { … }
     圧縮 if ((x1-x2)/w2)|((y1-y2)/h2) {}else{ … } 42Bytes削減
・カウンタが絡む処理、31回分までならビットマスクと右シフトで計算してみる。
  たとえば、普段は黒表示の●を、15フレーム間で3フレーム周期の赤黒点滅をさせるケース。
  変数fにフレーム数の代入(f=15)が行われているとして普通に圧縮書きすると
  フレーム毎の処理は color ((f/3)&1)*255:mes "●":f-=(f>0) のようになるが、
  f=%111000111000111 のように代入すると color (f&1)*255:mes "●":f>>1 と書ける。
・値域を負値とした方が良いか検討する
  flag1とflag2が両方とも0なら処理する、という判定を以下の構文にしているケース。
   if(flag1|flag2){}else{処理}
  これは、flag1の値域を0以下、flag2の値域を0以上に調整できるなら、
   if(flag=flag2){処理}
  のように書ける。
・条件判断による代入のコスト削減
  flagが0なら変数xをクリア、0以外なら変更なしという処理、普通に書くと
  if(flag){}else{lpoke x}
  これは、flagが0〜3、xが0〜255に収まるなら poke x,flag と書ける。
・効力が残る命令は実行箇所をまとめやすいので、なるべく共通化などを検討する。
  font,color,hsvcolor,palcolor,gsel,gmode,pget,posなど
  たとえば、敵と自機の座標制御ルーチンを共通化し、座標計算時にposもやってしまう。


読みやすさの反対をひた走るので、コーディングスタイルとしてはお勧めできません。
Debugがとても面倒。
でも、うまく噛み合うとかなりのサイズが削れます。