スリム化
次回の作品更新に向けて準備。
まずはスリム化。
今回はAXサイズの余裕がありサイズ削減を突き詰める必要はないのですが、ある程度やらないとつまらないので。
>この処理に入る前に、mapgとmapcはオール0クリアしています。
フレーム毎にそれぞれクリア(memset)をやっていたのですが、AXサイズ的に無駄に感じていました。
これを、mapcを倍のサイズにして、パネル面積カウンタとグループマップを連結してしまうことで圧縮。
グループマップ要素には常にdupしてからアクセスしており、オフセットしても8バイト増で済むのでこちらを後半。
面積の方は加算処理でどうしても配列参照しなければならないため、オフセット不要な前半という扱いにしました。
これにより、memsetとdimを一組削除して28バイト減らせたので、差し引き20バイトの削減。
グループ判定&面積計算のロジックにも手を入れます。
sffq=eep ; キュー先頭に開始位置の値を登録 repeat if( cnt>eeq ){ break } ; キューの末尾まで到達済みなら調査終了 c0=sffq(cnt) if((mapf(c0)!=emapf)|mapg(c0)|mapd(c0)<grpchklim){}else{ mapg(c0)=sffq; 該当セルのmapgにグループ番号(開始位置)をマークして調査済にする mapc(sffq)+ ; グループのパネル数をカウントアップ repeat 4 ;上下左右のセルに範囲拡張する。※Size優先で無条件に拡張 eeq+:sffq(eeq)=c0+du(cnt) ; 対象とする位置を計算して登録 loop } loop
配列duに定義された上下左右を示す変化量を使っていますが、今回は縦横移動がなくdu利用はここだけでした。
duへの初期代入とrepeat 4などをやめることができれば、それなりにサイズが減るはずです。
また、ifの中でマップの配列参照は、他でも使っているdup後の変数が利用できればサイズが相当減ります。
というわけで以下のようになりました。
lpoke sffp ; キュー書き込み用ポインタ初期化 repeat ; グループ判別処理 if( cnt>sffp ){ break } ; キューの末尾まで到達済みなら調査終了 gosub *posclceg ; 検索位置がeepにあることを利用しマップ値dup(条件判定での配列参照を軽減) if(((mapf(eeq)=emapf)*(emapf>=0)*(emapd>=eeo))>emapg){ ; 検索位置の条件を判定 emapg=eeq ; 該当セルのmapgにグループ番号(開始位置)をマークして調査済にする mapc(eeq)+ ; グループのパネル数をカウントアップ sffq(sffp)=eep-1,eep+1,eep-MAPW,eep+MAPW;上下左右に範囲拡張。※Size優先で無条件に行う sffp+4 ; キュー書き込み用ポインタを進める。 } eep=sffq(cnt) ;次ループに備えてキューからeepへ探索先を代入 loop
この処理を呼ぶ際はパラメータ定義として、eeo=パネル状態閾値,開始位置,開始位置 を行っておきます。
eep,eeqはそれぞれeeo.1,eeo.2に相当します。
では頭から解説。
lpoke sffp ; キュー書き込み用ポインタ初期化
現在の検索位置をeep、開始位置をeeqとして使用するので、キュー書き込み用ポインタは専用の変数sffpで管理。
gosub *posclceg ; 検索位置がeepにあることを利用しマップ値dup(条件判定での配列参照を軽減)
各マップ要素をdupするサブルーチンを呼びます。posclcegは以下のようになっています。
*posclceg pos eex,eey dup emapg,mapc(eep+EMAPNUM) ; 現在位置のグループマップ dup emapf,mapf(eep) ; 現在位置のフロアマップ dup emapd,mapd(eep) ; 現在位置の状態マップ dup emapc,mapc(emapg) ; 現パネルが属するグループのパネル数(参照のみ) return
posなどグループ判定には不要なものありますが、別の処理の兼ね合いで必要な準備処理としてまとめています。
EMAPNUMはmapcの後半をグループマップとして使用するためのオフセット。
if(((mapf(eeq)=emapf)*(emapf>=0)*(emapd>=eeo))>emapg){ ; 検索位置の条件を判定
現在の検索場所が壁なら処理をしないように、emapf>=0をここに追加しています。
これによって、呼び出し側でやっていた開始位置が壁の場合を除外するためのifを廃止できました。
また、修正前にはelseで処理をしていましたが、emapgの評価方法を工夫したことで、真の場合の処理にしています。
emapg=eeq ; 該当セルのmapgにグループ番号(開始位置)をマークして調査済にする mapc(eeq)+ ; グループのパネル数をカウントアップ
初期位置はeeqで示されているので、そのまま使います。
sffq(sffp)=eep-1,eep+1,eep-MAPW,eep+MAPW;上下左右に範囲拡張。※Size優先で無条件に行う sffp+4 ; キュー書き込み用ポインタを進める。
上下左右の4箇所分を一度に登録してからポインタに4を加算。これによってduが廃止可能になりました。
eep=sffq(cnt) ;次ループに備えてキューからeepへ探索先を代入
eepはループ1回目は処理前に登録された開始位置、2回目以降はキューから取り出した位置情報を順次使います。
これらの対応を行うことで、50バイト近く削減できました。