Sim's blog

電子工作はじめてみました

ICFP2007 (24) 画像修復(3)

2007-09-27 00:21:34 | ICFPプログラミングコンテスト
ICFP2007 (23) 画像修復(2)の続きです。

最新の画像です。


差分です。3594ピクセル異なっています。


(17) balloon ふきだし

- 修復方法が不明なのでとりあえずskip

(18) 文字列

- 0x4d6606にgoto 0x4d60fbを書く
- 0x4d6316から"s morphed!xff"を書く

文字列を書くのに微妙にメモリが足りません。直前にドイツ風の"Endo hat gemorpht"を表示するコードがあるので、色をセットし終わったら、そちらに飛ばしてやります。

ここまでで、scenarioに沿った修正はおわりです。足りない部分を追加します。どこにどう追加するとprefixが短くなるのかはよく分かっていません

コードを追加するのに使える隙間は以下です。
- sky-day-bodies
- grassの後からflowerbedまで
- chick (ここまでがwindmillより前)
- lambda-id (ここまでがwhaleより前)
- crater
- 文字列からreturnまで

追加するものは以下です。
- sun(太陽)
- clouds(雲) windmillより前
- chick(ひよこ) windmillより後
- 鯨の噴水 whaleより前
- 鯨のcup whaleより後
- balloon(ふきだし)

(19) sunの修復

- [0x206dce + 855] = I
- [0x207192 + 15] = I
- [0x207192 + 47] = C
- [0x207269 + 87] = I
- [0x207269 + 95] = C
- [0x207269 + 176] = C
- [0x207336 + 7] = I
- [0x207336 + 81] = I
- [0x207336 + 104] = C
- [0x2073cc + 49] = C
- 太陽の座標を(480, 20)にする
- 太陽の色はcolorSoftYellow()
- [0x641878 + 48] = 530 (spirograph5 x)
- [0x6418c4 + 48] = 70 (spirograph5 y)
- [0x641a0a + 48] = 1 (spirograph5 magnify)
- [0x641f81 + 48] = 530 (spirograph6 x)
- [0x641fcd + 48] = 70 (spirograph6 y)
- [0x642113 + 48] = 1 (spirograph6 magnify)
- [0x642694 + 48] = 530 (spirograph7 x)
- [0x6426e0 + 48, 24, 70] (spirograph7 y)
- [0x642826 + 48, 24, 1] (spirograph6 magnify)
- spirograph描画後、適当なreturnへjumpする

前半はsunの修復です。これはダンプリストを見ながら手動でおかしな所を直してみました。修正しては逆アセンブルしなおしを繰り返しました。10箇所修正したところでcheckIntegrityもpassになりました。
後半はspirographのパラメータ修正です。これは修復ガイドのpage 180878の中央のspirographです。太陽の中央にはこのspirographを縮小したものが描かれています。page 180878はmainの一部に埋め込まれています。
太陽の色はcolorSoftYellow()です。この色はflowerbedで使われている色と一緒です。sun()ではYellowなので色を修正する必要があります。sunの直前はimpDoc1なので壊しても構わないので、ここが利用できます。

sun自体はsky-day-bodiesの中で呼ばれています。sky-day-bodiesはおおまかにこんな感じになっています。
void sky-day-bodies()
{
    if(weather == 2){
        if(weather == 2) lightningBolt();
        clouds();
    }
    if(weather == 3) sun();
}

一番最初のifを3と比較することにすればcloudsとsunが呼ばれることになります。weatherの初期値は0なのでweather = 3にするとよいことになります。

(20) clouds

- duolcの逆順をcloudにコピーする
- cloud先頭のcloudy = PをFにする
- [0x5c9164] = 25 (雲1 y座標)
- [0x5c963d] = 10 (雲2 サイズ)
- [0x5c94fa] = 55 (雲2 y座標)
- [0x5c99dd] = 20 (雲2 サイズ)
- [0x5c989a] = 30 (雲3 y座標)

cloudとduolcを連結すると回文になっています。cloudは壊れているのですが、duolcから復元できます。回文に関するヒントはpage 1230321です(修復したpage 1230321)。ページ番号も回文になっています。
cloudのパラメータは雲の大きさです。デフォルトは15になっています。

(21) chick (ひよこ)

- 座標を(171, 410)にする

windmillより後に描画しないといけません。パラメータはcolorDuckYellowとcolorDuckOrangeです。scenarioの中ではchick呼び出しの前後に隙間はないのですが、サブルーチンコールでスタックに戻り番地を積む所を飛ばしたい番地に修正することで呼び出し順序を変えることができます。どのように直すのが最適かはまだ分かっていません。

(22) 噴水

- 座標を(430, 200)にする
- compressorのtableの7番目をturnClockwiseにする([0x29bdda + 26] = FFFFF)
- compressorのtableの9番目をturnCounterClockwiseにする([0x29be1a + 26] = CCCCC)
- 描画しおわったら適当なreturnへjumpする

噴水はprintGeneTableのpage 15以降に隠されていました(右下)。このままでは上下さかさまなのでcompressorのturnClockwiseとturnCounterClockwiseのRNAを入れ替えてやります。
whaleより前に描画する必要があります。

(23) cup (暫定)

- waterの座標を(420, 265)にする
- water(), addbmpのRNA, 完全にopaqueなufo-cup(), clip, 通常のufo-cup()の順に呼び出す
- ufo-cupのpolygonはx座標とy座標を両方とも符号を反転させる
- fillのためのmoveToも座標の符号を反転させる
- ufo-cupの座標は(477, 315)

ターゲットの鯨はcupの中の水に浮いている絵になっています。waterをufo-cupの逆さまでclipした後、半透明なufo-cupを上書きすることで絵が完成します。ufo-cupはx方向にもy方向にも反転しています。一応x座標とy座標を両方とも符号反転することで描画しています。時計回りに2回方向を変えることでも実現できるはずですが、まだ試していません。DNAの中では、現在の描画位置をいくつRNAを出力したかを元に追跡しています。DNAの知らない所で向きを変えたり座標を変えたりすると、追跡している座標と実際の座標が矛盾して、それ以降の描画がずれてしまいます。これはとても危険なので安全策として座標反転をしています。後でダミーのmoveをすることで座標のつじつまを合わせることも可能なはずなので、RNAを直接挿入した方がprefixが短くなるはずです。
ufoの中にはufo-cupと同じpolygonが2つも含まれています。それもwaterを呼び出した直後です。ufoの中身をいじくってやることで今回の絵がうまくつくれそうです。
waterは通常は描画されませんがweaterが1または2のときにだけ描画されるようになっています。waterの存在はweatherをいじくって遊んでいるときに気づきました。というかufoの中に隠されていたということになります。

weather = 2にした画像です。雨や雷、ufo-cupに波模様が見えます。


(24) balloon (ふきだし)

balloonの修正方法は分かっていません。少なくとも単一の白ではなくグラデーションがかかっています。グラデーションはdrawGradientCornerNWを使って描かれています。drawGradientCornerNW自体は四角を書くだけなのでふきだしの形でclipしてやる必要があります。グラデーションのパラメータwとhと描画位置のx, yが未知です。またclip用のふきだしの形も分かりません。力技でpolygonデータを作るしかないのかもしれません。もしかするとどこかにヒントになる図形が隠されているかもしれません。
μの描画方法も分かりません。λはフォントを変えてLを書いています。他の文字に変えると表示されるのかもしれません。
もう残っているのはballoonだけです。

以上で修正箇所のまとめをおわります。宿題として残っているのは以下です。
- 草を描く乱数の修正値biomorphPerturbを決めるbiomorph_adaptationの修正
- 座標を符号反転させないufo-cupの描画方法とufoの修正方法
- balloonのグラデーションパラメータと形状
- 追加描画部分はどこに置くのがよいか考える
- prefixの作成と圧縮(というかアセンブラ作らなきゃ)
- ヒントの探索。例えばcow-tailの暗号化鍵9546

その他に思いつくことはサブルーチンコールの戻り番地の修正でfar jumpを作ることができるので、これを利用できないか考えることです。

ずいぶん長いこと、しつこくやっていましたが、ようやっと終わりが見えてきたという感じです。10月になるとICFPの学会が開催されて上位入賞者の発表があります。もしかするとネタバレもあるかもしれません。どうせなら、その前に片付けておきたいところです。

最新の画像もっと見る

コメントを投稿