Moai SDK でゲームを作ろう(Android でサンプルを動作させる)

開発用の Linux 上でプログラムが動作したので、次は Android でプログラムを実行しようと思う。

で、調べながらやってみた結果、下記ページの説明通りにすることで、 Android でサンプルが動作した。
http://www.gamefromscratch.com/post/2012/08/28/Setting-up-a-Moai-Android-host-build-environment.aspx

Screenshot_2014-01-01-00-28-42

いい感じですな!
Android の実機で作ったプログラムが動作するのが確認できたので、簡単でよいのでゲームっぽいものを作ろうと思う。

Moai SDK でゲームを作ろう(Linux 上でサンプルを動作させる)

Moai SDK はホスト環境でも動くようなので、まずは Linux(Ubuntu) で動作させようと思う。

下記のリンクに手順が書いてあるけど、要は普通にビルドすれば良いらしい。
http://franciscotufro.com/2013/01/compiling-moai-on-linux/

私の場合、以下のコマンドでビルドできた。

apt-get install libxmu-dev
git clone git://github.com/moai/moai-dev.git
cd moai-dev/
git checkout linux
cd cmake
cmake .
make

そして、動作確認としてサンプルの anim-basic を動作させた。

cd moai-dev/samples/anim/anim-basic
../../../cmake/moai/moai main.lua

moai_2013_1231_anim-basic

サンプルの実行方法は、実行したいサンプルのディレクトリに移動して、moai の実行バイナリに main.lua を渡せばよい。

次は Android の実機でサンプルが動作するのを目指したい。

Moai SDK でゲームを作ろう (調査してみてわかったこと)

Android 向けのゲームを作るにあたり、いろいろ調べた結果 Moai SDK っていうのが良さそうに思った。

  • Android, iOS, Chrome 用の 2D ゲーム向けのフレームワーク
  • C++ でクラス作って Lua で操作するような作りになっている
  • オープンソース(ライセンスはゆるめの CPAL)

で、Kindle で Moai SDK の書籍(英語)も買って読んで「いいなー♪」とか思っていたが…、もう少し調べたいたところ大変なことがわかった。

「Moai SDK っていうプロジェクトは、もう息してない…」

下記のリンク先が詳しい内容だけど、要約するとメインの開発者が「もうええわ!」って感じで更新しない宣言をしたらしい。確かに github 上のソースも数ヶ月くらい更新ないし…。

http://getmoai.com/forums/thoughts-on-the-future-of-moai-sdk-t2012/

ただ、使うにあたっては起動ロゴに2秒以上 Moai SDK のロゴを表示するか、クレジットに表示するか、っていう要求のゆるさが気に入っているし、何より自分でフレームワークを作るよりは良いだろう、という判断のもとに Moai SDK を使ってゲームを作ってみようと思う。

次回は、実際に Moai SDK をセットアップして Linux 上や Android 上で画像でも表示するプログラムを作ってみたい。めげずに頑張る!

Blu-rayプレイヤーをHackする(その3)

さて、前回の記事??の続きです。

目当てを付けたシリアル通信がシリアルコンソールでなかったことに落胆を隠せず、そろそろ蓋を閉じてしまおうかともう一度基板を眺めていたところ…

あれ…

写真 2013-12-30 18 58 54

4ピンコネクタあんじゃん!
しかも堂々とコネクタ実装されてんじゃん!!!

OTL

シリアルコンソールはこっちだったか…
なんで気付かなかったし。

さて、気を取り直して改めてTeraTermに突っ込んでみます。

デターーーーーーーーーーーーーーーーーーーーー!!!!!

スクリーンショット 2013-12-30 19.00.41

なんか出ました。

ブートローダに工夫があるらしく、コンセントを入れた瞬間に少し起動して止まっています。
その後、電源を入れたあとにLinuxのローダが動いてるように見えます。

せっかくなので起動ログを全部貼ってみましょう。

0:00.000 preloader v5599
00:00.016
Apr 11 2011 15:48:04SSC (+-5/1000, 30kHz)
DDR3 1242 MHz.
B0:DQS( 4~38), 35, 21
B1:DQS( 5~41), 37, 23
0x7388=0x2e2e2e2e.
B0:Gw(13~107), 95, 62
B1:Gw( 7~100), 94, 54
0x7388=0x363e.
A 128MB, x16
B0:DQS( 7~41), 35, 24
B1:DQS( 7~40), 34, 23
0x7388=0x2e2e2e2e.
B0:Gw(13~105), 93, 61
B1:Gw( 6~97), 92, 53
0x7388=0x353d.
B 128MB, x16
00:00.139
00:00.171 u4_dramk_sa:[0x40000f60]
00:00.174 u4_loader_sa:[0x400030e4]
00:00.178 u4_loader_end:[0x40005970]
00:00.181 loader start
00:00.183 A00:00.184 B00:00.201 C00:00.202 D00:00.203 E00:00.235 aMTD Found at 0x300000
00:00.242 F00:00.243 G00:00.310 H00:00.311 K00:00.000 preloader v5599
00:00.016
Apr 11 2011 15:48:04SSC (+-5/1000, 30kHz)
DDR3 1242 MHz.
B0:DQS( 4~38), 35, 21
B1:DQS( 5~42), 38, 23
0x7388=0x2e2e2e2e.
B0:Gw(12~107), 96, 61
B1:Gw( 6~100), 95, 54
0x7388=0x363d.
A 128MB, x16
B0:DQS( 8~42), 35, 25
B1:DQS( 7~42), 36, 24
0x7388=0x2e2e2e2e.
B0:Gw(12~105), 94, 60
B1:Gw( 4~97), 94, 52
0x7388=0x343c.
B 128MB, x16
00:00.137
00:00.170 u4_dramk_sa:[0x40000f60]
00:00.173 u4_loader_sa:[0x400030e4]
00:00.176 u4_loader_end:[0x40005970]
00:00.180 loader start
00:00.182 A00:00.183 B00:00.200 C00:00.200 D00:00.202 E00:00.234 aMTD Found at 0x300000
00:00.241 FAVM 00:00:00.280 [AVM] DSP :v9200.03 DRV: v0.1
 AVM 00:00:00.284 [vMTD_main] NAND init
 AVM 00:00:00.288 [fgLoadNFBTable] MTD Init Start
 AVM 00:00:00.292 [fgLoadNFBTable] MTD Init Success
 AVM 00:00:00.360 [fgLoadNFBTable] MTD Init Success ##
 AVM 00:00:00.365 [mtd_part_tbl_init] MTD part table init start
 AVM 00:00:00.527 [mtd_part_tbl_init] MTD part table init DONE
 AVM 00:00:00.533 [vFLFlashRead] Get logo from flash
 AVM 00:00:00.538 [vLoad_binary] Get info name : ef09f7e
 AVM 00:00:00.719 [vLoad_binary] Load binary success
 AVM 00:00:00.724 [vLoad_binary] Get info name : ef0a09b
 AVM 00:00:00.732 [vLoad_binary] Load binary success
 AVM 00:00:00.737 [vMTD_main] Load FASTLOGO binaries ok
 AVM 00:00:00.967 [IDE_FB]FE firmware CheckSum OK !!
 AVM 00:00:00.972 [IDE_FB]read loader binary to buf:0xfe00000, version:5Q0300
 AVM 00:00:01.028 [IDE_FB]backup NAND flash info(0xff21c00, 64)
 AVM 00:00:01.033 [vMTD_main] Load IDE Binaries ok
 00:01.040 G00:01.107 H00:01.107 K00:01.397 J
U-Boot 2009.08 (Dec 13 2011 - 11:17:32)
I2C: ready
NXP B.V. - MT85XX SoC with ARM1176JZF-S
DRAM: 256 MB
NAND: 128 MiB
u-boot adaptive mtd mechanism applied.
[_i_find_part_tbl]Part tbl info passed from preloader
[_i_find_part_tbl] version is 1!!
[_i_get_upg_status_in_nand]upg status passed from preloader
Using default environment
In: serial
Out: serial
Err: serial
r_args_to_uboot:
 head sig : 0xa0b0ead1
 version : 1
 boot type : 0
 dram ch1 : 0x08000000
 dram ch2 : 0x08000000
 kern addr : 0x0d9fffc0
 initrd addr : 0x0e700000
 initrd size : 0x00021cc0
enable bim two way write.
boot type:[0]
Bootloader version 3847
l>)・ワkR・MD3I
Hit any key to stop autoboot: 0
## Booting kernel from Legacy Image at 0d9fffc0 ...
 Image Name:
 Image Type: ARM Linux Kernel Image (uncompressed)
 Data Size: 1558196 Bytes = 1.5 MB
 Load Address: 0da00000
 Entry Point: 0da00000
 Loading Kernel Image ... OK
OK
Starting kernel ...
Uncompressing Linux... done, booting the kernel.
@

CPUは「NXP B.V. – MT85XX SoC with ARM1176JZF-S」
予想通りマルチメディア用SocのARMですね。
http://www.arm.com/ja/products/processors/classic/arm11/arm1176.php

MT85xxで調べていたら、MT8520というBlu-ray用のチップにたどり着きました。
http://www.mediatek.com/_en/01_products/04_pro.php?sn=27

標準出力はすべてserialになっているようですが、booting the kernelのあと、@が表示されたあとのメッセージは表示されていないようです。
シェル無いのかなぁ…?

さて、こうなったら Hit any key to stop autoboot: 0 に本当に割り込めるのかどうか。
次回乞うご期待。

(続くかも)

Blu-rayプレイヤーをHackする(その2)

さて、前回の記事 ?の続きです。

電源周りは諦めたので、とりあえずCPU基板の方を眺めてみましょう。

写真 2013-12-29 23 11 37

水晶発振器は27MHz。基本的にNTSCでの信号生成を含むCPUの場合、これからPLLするのが多い気がします。
メインCPUはヒートシンクが接着されていて型番を読むことは出来ませんが、
右端にFlashROMがあります。
また、ケースにJavaのロゴが入っていました。
メディアプレイヤー向けのコア内蔵のLinuxが動くCPUであることはほぼ間違いないでしょう(経験上)右手前に赤外光受信機を実装するパターンが有りますが、ここには付いていません。
ボードのみで構成されるような小型の機器を作るため用のパターンでしょうか。
延長されてフロントのVFD基板に接続されています。
このパターンの周辺に5VのTPがあるので、電源ユニットからの5VSTBYで常時起きてて、
赤外線リモコンの割り込みでメインCPUが起きるようになっているのでしょう。

左下には放熱パッドの付いたICが。LOADと書かれていて、V,U,WなどのTPがあります。
トレイローディング用のモータドライバICかと思われます。

「ICE」と書かれたコネクタ。CPUのオンチップデバッグなどに使われるコネクタです。
8pinなので、JTAGの最小限の配線があるのでしょうか。

と、色々眺めていると「USB1」「USB2」のコネクタパターンの左にある謎の4ピンコネクタ。

写真 2013-12-29 23 16 51

そうです。シリアルコンソールに決まってます。
こういう機械に現れる未接続の4ピンコネクタは、VCC,TX,RX,GNDのシリアルコンソールに決まっているのです。
(っていうかRS232って書いてあったことにあとで気づくなど)

よっしゃキタコレーと思ってオシロスコープのプローブを当ててみます。

写真 2013-12-29 23 16 14

写真 2013-12-29 23 30 59

何か信号でたー!!!

パルス幅を測定してみます。

写真 2013-12-29 23 33 31

約115Hz。

もうこれは115.2kbpsのUART確定です。

小躍りしながらUSB-TTL UART変換ケーブルのRXに繋いでTeraTermを見てみます。

現れるのは

なんじゃこりゃー

バイナリ…
文字化けか?ボーレート変えてみるか?
いや、どれも一緒だ。アスキーらしきものは出ない…

おっかしーなー。
HEX確認可能な別のツール(XBee用のX-CTU)で見てみる。

スクリーンショット 2013-12-30 18.25.18
…バイナリだ。しかも4桁の数字や”NORM”と読める文字も出てるので、これはコンソールではなく、何か意味のある人間の読めない通信だ…

落胆

いやまて、信号反転かもしれん、ロジアナに繋いでみよう。
ついでに接触不良だと嫌だからハンダ付けしよう。
(良い子は真似してはいけません!)

写真 2013-12-29 23 24 12

ロジアナはZEROPLUSのLogic Cube LAP-C(16128)。
ストロベリーリナックスで4万円のお買い得品です。安くなったもんだ。
https://strawberry-linux.com/catalog/items?code=64002


スクリーンショット 2013-12-30 18.32.07

…あかん。信号反転するとUARTとしてエラーが多すぎる。
ロジックレベルも、ボーレートも、パリティも、ビット長も合っていて、正常に通信しているようだ。

落胆×2

小躍りしてからのこれなのでショックがでかい…
さすがにこれを解析する気力はないぞ…?

(つづく)

Blu-rayプレイヤーをHackする(その1)

こんにちは。hiromituです。

自家用車でBGVを再生するため、過去にiPodやAndroid動画プレイヤーを車載してきたのですが、自宅にスカパー+HDD/Blu-rayレコーダーを導入したため、処理しなければいけない動画の数が急増し、せめてBlu-rayディスクを再生する環境を早急に車載しなければいけない状態になりました。

しかし、車載Blu-rayプレイヤーは高い!
SONYのポータブルプレイヤーだと?http://pur.store.sony.jp/Qnavi/Product/BDP-Z1/?s_tc=st_ad_sony000_D_00_PL_pc?なんと五万円!
それ以外の3流メーカー製(あきばお?扱い)でも二万三千円するなど、ちょっと勢いで買うには高すぎます。

そこで、もっと安い家庭用のBlu-rayプレイヤーを買って車載することを思い立ち、
あきばお?で最安だった Blu-rayプレイヤー(8GB USBメモリ付き)を7,980円で買ってきたのでした。

外箱。
写真 2013-12-29 22 50 13

最近流行りの横長薄型とは違い、横方向は短いようです。
写真 2013-12-29 22 51 24

裏側。シンプル。HDMIとRCAがついてます。車載だと分配や小型モニタとの接続があるので
NTSC出力はありがたい。
写真 2013-12-29 22 51 35

電源を入れてみよう。
写真 2013-12-29 22 54 18

…なんだか解像度が低い…?

ディスクを入れてみよう。
再生。おお、なんだか一昔前の中華製プレイヤーのようなもっさり感は全然ない。
一応日本語看板がついてるぐらいのことはあるようだ。
写真 2013-12-29 22 57 00
せかいいち かわいいよ!!!

…が、なんか解像度低いぞ…?

いやまてさすがにBlu-rayでHDMIでこの画像だったらキレるわ。
説明書見ると、1080iまで対応と書いてある。

おもむろにセットアップメニュー。

写真 2013-12-29 22 57 37

写真 2013-12-29 22 57 48

出たー中華フォント!!!!

写真 2013-12-29 22 58 11

解像度が480です。そりゃぁ汚い。デフォルトで自動設定とかどうにかならんのか。

写真 2013-12-29 22 58 30

1080iにした。メニューもその場で切り替わってくっきり!
起動画面もくっきり!

写真 2013-12-29 22 58 43

動画もくっきり!(写真じゃわからんて)

写真 2013-12-29 22 59 16

せかいいちかわいいよ!

さて、ここからが本番です。
この機械は家庭用100Vで動作するため、電源をどうにかしなければなりません。

写真 2013-12-29 23 11 10
普通だと写真のようなDC/ACインバータを使用して100Vを出すのが素直なのですが、
所詮数十ボルトで動いてるような機器を12->100V->と変換するのは癪に障るものです。

銘版によると消費電力は15W。12V換算で1.5A。このぐらいの電流なら自力で電源周りを作ってやれないかと思ったわけです。

では。ご開帳。さよなら保証期間(4時間)
(良い子は真似してはいけません!!!!!!!!)

写真 2013-12-29 23 06 38

スッカスカです。最近の電化製品なんてこんなもんです。
左半分がBlu-rayドライブ、右下に電源ユニット、右上にCPUボードとI/Oがついています。
I/Oが偏っているのはCPUボードから直出しの都合なのですね。
生産コストをきっちり落とす優秀な設計です。

写真 2013-12-29 23 06 59

ドライブにはBDY-33と書いてあります。

さて、肝心の電源ユニット。

写真 2013-12-29 23 07 07
12Vからこれと同じ出力を作り出せればいいことになります。
出力は…

写真 2013-12-29 23 07 35
・5.1V 3.2A
・12V 0.2A
・5VSTBY 0.4A
・-24V 10mA
・3.3V AC 0.1A

…… む り か な !

あれ、こんな複雑な電圧が出てるとは思ってなかったぞ。
つーか-24VはVFDとして、3.3V ACとかなんにつかうんだこれ!

いや、ちょっと思ったとおりには行かなそうだ。
電源周りはとりあえずACインバータを使うことにしよう。

(つづく)

記録済みデータのフォーマットを Ruby で変更する

あるツールを使ってデータを記録したが、ツールに手を加えたためにデータの互換性がなくなってしまったのを「互換性がないなら、スクリプトで変更すればいいじゃない」という作業の流れを書きだしたものが、この記事です。

どういう仕組みで何を記録したのか

LMS511 という平面の距離を計測できるセンサがあるのですが、そのセンサとの通信内容を全て記録しました。通信データの記録は LMS11 から距離データを取得するために C++ で実装した Lms_driver というクラスで行なっています。

この Lms_driver クラスは Connection インターフェースを継承させていて、Connection インターフェースはセンサに対する open, read, write を提供します。そのため、Connection インターフェースの中身を差し替えることで、センサからのデータ取得、センサからデータを取得しつつログを記録、ログからデータを読み出して再生、ということが実現できます。

lms_driver_usage_2013_1228

ただ、この仕組みでデータの記録と再生を実現しようとすると Lms_driver でセンサとの通信に使っているコマンドの順番を変えると記録済みのデータが再生できなくなる、という欠点があります。今回は、いろいろ機能を追加すべく Lms_driver を変更した結果、過去に記録したデータが再生できなくなってしまいました。

行う必要があること

過去の実装から変更した点は、センサに発行するコマンドを追加した程度なので、そのセンサからの応答を過去のデータに追加してしまえば O.K. です。

実際に行ったこと

LMS511 との通信は STX, ETX が付加された以外は普通の ASCII 文字列で行われるため、Ruby スクリプトを用いて必要な箇所を置換していくことにします。

具体的に行う処理は

  • 追加したコマンドぶんの応答を追加
  • データ取得コマンドの変更による、データ先頭のコマンド文字列の置換

くらいかな。
改めて書きだしてみると、大したことはないですね。作成するスクリプトの方針としては、引数で与えたファイルの内容を読み込んで、置換でどうにかすることにします。

まず、引数で与えたファイル名を読み出すあたりまでの実装は、こんな感じでしょうか?

# -*- coding: utf-8 -*-
# LMS のログデータを変換するスクリプト

# 引数で渡されたファイルを順に処理する
ARGV.each { |log_file|
  original = File.open(log_file).read

  # コマンドの応答を追加する
  # !!!

  # 必要な置換を行う
  # !!!
}

次に、置換まわりのコードを追加します。(コードの一部の通信データを省略しています)

# -*- coding: utf-8 -*-
# LMS のログデータを変換するスクリプト

# 引数で渡されたファイルを順に処理する
ARGV.each { |log_file|
  converted = File.open(log_file).read

  # 最初のコマンド応答の部分を切り取る
  converted.sub!(/.+?/, "")

  # 必要な置換を行う
  converted.gsub!(/sRA/, "sSN")

  # 最初のコマンド応答を追加する
  converted = "sRA (省略) sEA LMDscandata 1" + converted

  # ファイル名を変更して出力する
  output_file = "converted_" + log_file
  File.open(output_file, "w").write(converted)
}

いつものことですが、実際に手を動かしてみると簡単です。
個人的には、面倒くさがらずに簡単ならもう少し早く取りかかれるようになりたいのですが「怠惰」はプログラマにとって美徳なので悩ましいところです。

まとめ

これからは怠惰な気持ちで楽することを考えつつも、実際には怠惰にならないようにする。

東北ずん子の痛 Suica を作ってみよう (完結編)

前回までのあらすじ

痛 Suica を作ろうとして会社のプリンタを買い直した。

というわけで、プリンターが届いたので作業を再開する。

new_printer_2013_1227

というか届いたプリンターを見て「最近のプリンターは安いのに色々と機能が付いててスゲー」と思ったり「こんなに安くて大丈夫か?」とか思ったりした。

で、セットアップを終えてから前回に作った痛 Suica のシートを印刷してみる。

suica_printed_2013_1227

いい感じです。
ちなみに同時刻の同僚はプリンターで回路パターンを印刷し、さっそく感光基板を作ってました…。うーん、ここでゲーテの表現を借りるなら

「感光基板を作る社員のとなりで 痛 Suica を作る社員がいてもいい。それが自由というものだ」

とか思ったりしました。
まぁ、作業を進めます。あとは、このシート(A-one 品番: 29281) を Suica に貼り付けてラミネートフィルムを貼り付けたらおしまいです。このあたりの手順は下記ページを参考に行いました。

痛Suicaの作り方
http://itaicard.com/%E7%97%9Bsuica%E3%81%AE%E4%BD%9C%E3%82%8A%E6%96%B9/

で、できたものがコレ。(実は微妙に気泡が入ってしまっています)

zunko_suica_2013_1227

前回からの作業も含めると色々と試行錯誤しましたが、それっぽく出来上がりました。今回の作業で得られた教訓としては

  • 簡単だと思っていることでも、実際に試しておいたほうが良い。
  • 新しいことをやると知識が増える。
  • フリー素材は人を動かしうる。

などでしょうか。
この知見は以降の業務でも生かしていきたいと思います。

東北ずん子の痛 Suica を作ってみよう (挫折編)

この記事では「せっかくだから 痛 Suica でも作ってみるか!」と思って作り始めた結果、色々と試行錯誤することになった様子を紹介できれば、と思います。

まず、テーマを探しました。せっかくなので「東北ずん子」で。
探すと、幾つかの候補が見つかります。

画像をダウンロードしたら、まずは印刷したときの大きさが Suica と一致するかを確認するために、印刷してみます。

suica_too_large_2013_1225

はい。大きすぎますね。
確認したところ「画像をフレームに合わせる」にチェックが入っていたのが原因でした。orz
気を取り直して、チェックを外して印刷してみます。

suica_too_small_2013_1225

うん。今度は小さすぎるかな!
何か原因があるように思うのですが、よくわかっていません。なので画像を拡大して対応しました。あと、Suica の絵を印刷する A4 のシートに1枚しか印刷しないのはもったいないので、いくつかの画像を配置して印刷してみます。

suica_gray_all_2013_1225

なんか、いい感じ。
(画像を複数ならべるのは Excel に画像を貼り付けることで実現しています)

ただ、プリントした画像を定規で測った結果、実物よりも少し小さかったので、印刷する画像を拡大して対処したりしました。プリンタの設定を変更してサイズ調整するのが良いのだと思いますが、 あきらめました。(設定方法がわからなかった!)

で、実際に Suica に貼るためのシートに印刷するために、カラーで印刷してみたところ、こんな感じに。

suica_color_2013_1225

ぱっと見よさそう。
と思ったものの、よく見ると…

suica_color_clip_12013_1225

単色のはずの緑の面が、かすれてる…。

この問題はプリンタ側の問題のようです。プリンタのヘッドクリーニングをしても改善されないので、同僚と相談した結果プリンタを新規に購入する方針になりました。印刷したパターンを感光させて回路基板を作るときにも困るしな。以下、プリンタを注文する前の社長から許可をもらったときの会話。(社員は全員で 10 人くらい、だっけ?)

私「あ、(社長) さん。プリンターなんですけどー、インクの出が悪くてエッチングで回路基板をつくるときとかに不都合があるんで、新しいの買ってもいいですか?」
社長「おう、いいよ。必要なら遠慮なく買って」

というわけで、社長に了承を取ったので遠慮なく注文した。
プリンターが届いたら作成の続きをしようと思う。

簡単だと思っていたことでも、実際にやってみると色々ある。ということが理解できただけでも有意義だった。

SDL で Android ゲームの開発 (画像が表示できた)

下記サイトを参考にした結果、Android タブレットに画像を表示させることができた。
http://www.dinomage.com/2013/01/howto-sdl-on-android/

このサイトと SDL リポジトリの SDL/README-android.txt に、ここまでの手順が書いてある。でプログラムを実行して Android タブレット(Nexus 7) で表示したところ、

Screenshot_2013-12-22-22-53-59

色が変だ…。
悩みつつ調べてみた結果、Gimp で png を bmp に変換するときに 24 bit を指定することで適切な色になった。

Screenshot_2013-12-23-01-48-20

gimp_bmp_setting_2013_1223

色についての詳しいことは、後でいいので調べて理解したい。

ここまでのソースコードは、下記プロジェクトで管理中。
https://bitbucket.org/satofumi/zunda_farm/src/67b09f285031/example/draw_image/?at=default