blogSimutrans本体改造まわりのお話をつらつらと2018-09-12続・アドオンの減色について前回はアドオンの減色のしくみについて解説したので、今回はなぜ減色がされているのか、今後減色が解消される見込みはあるのかなどについて考えたいと思います。himeshi.hateblo.jpアドオン減色について語るには、まずSimutransの描画処理まわりをおさらいする必要があります。Simutransに限らず大半のGUIプログラムは、描画処理を何らかのライブラリに任せる形で行っています。言い換えると、描画ライブラリと呼ばれるプログラムに対して描画命令をすることで画面が描画されるということです。Simutransは描画ライブラリとしてallegro、GDI、OpenGL、SDL、SDL2をサポートしています。今回は描画ライブラリをSDL2として話を進めることにします。描画ライブラリの命令は描画ライブラリごとに異なるので、simsys.hが描画命令を共通化する役割を持っています。SDL2の場合の実装ファイルはsimsys_s2.ccです。描画手順は各ライブラリごとに若干異なりますが、概ね次の手順で行われます。Simutransは描画するピクセルデータを描画バッファと呼ばれる変数に格納します。描画バッファにピクセルデータを格納し終えたらライブラリの画面更新命令を呼びます。これで、描画バッファに格納されたピクセルデータが画面に反映されるのです。Simutransの描画処理は、地面を描き、線路を描き、車両を描き・・・と続いていきます。地面画像の上に線路画像や車両画像が塗り重ねられていき、最終的にすべて塗り重ねた結果を描画ライブラリに渡しています。よってピクセルを塗り重ねていく処理はSimutrans自身が行うことになります。塗り重ねの処理はdisplay/simgraph16.ccにかかれています。simgraph0.ccはGUIを起動しないサーバーモード用の処理であり、描画処理を行いません。simgraph16.ccの386行目で、描画バッファ変数は次のように宣言されています。NULL;PIXVAL型の実体はuint16です。この時点で、画像の塗り重ね処理自体が16bit整数で行われていることがわかります。減色されたアドオン画像を256階調RGBに復元しているわけではないのです。ちなみに画像のアルファ値はライブラリに渡されるのではなく、simutrans自身が重ね塗りをするときに吸収しています。描画処理自体が16bit(内訳はRGBそれぞれ5bitずつで本当は15bit)で行われていることがわかりましたが、32bitで扱うのとくらべてどのような違いがあるのでしょうか?大きな違いは主に2つです。描画処理のパフォーマンスに差が出るアドオンpakファイルサイズが2倍になる32bit化するとアドオンサイズが2倍になるのは良いと思います。1ピクセルにつき従来は16bitで表現されていたものが32bitで表現されますからね。描画処理のパフォーマンスに差が出るというのは、まずピクセル計算に必要なメモリが倍になります。それに伴ってメモリとCPUのデータやりとりも2倍になります。ひめしはあまりグラフィックに詳しくないのでこれがどのレベルまでパフォーマンスに影響を与えるかはよくわかりません。色を32bitで扱うようにするとストレージや処理系の負担になることは事実です。近年のコンピュターのパフォーマンスを考えればそろそろ32bit化をしても良い気はしてきます。実は32bit化の足かせになるのはここではありません。Simutransの描画系が16bitから32bitに移行するに当たって困難なのは次の二点です。実装量が膨大であることアドオンの互換性を担保しなければならないこと画像描画まわりのコードは膨大です。新しく32bitでの描画をサポートしようとすれば、最低限display/simgraph.hで宣言されている関数をすべて実装しなければなりません。simgraph.hは宣言ファイルですが、このファイルだけで381行あります。16bit色描画を実装したsimgraph16.ccは5336行あります。実装するのはsimgraphまわりだけではありません。makeobjでpng画像をコンパイルする過程もそうですし、なによりGDIやSDLといった各ライブラリとのインターフェースも32bit色表現に対応させる必要があります。すべての描画ライブラリできちんと動作することを担保せねばなりません。ちなみに現行Simutransがアルファ対応をするときに32bit化せず16bit空間でゴリ押したのは実装量低減とパフォーマンスの問題とされています。(ソース:https://forum.simutrans.com/index.php/topic,15314.0.html)アドオンの互換性も大きな課題です。Simutransにはプレイヤーカラーや発光色といった特殊色があります。16bit色環境ではこれらは特殊色として専用の値を割り当てていましたが、32bit色環境でも似た処理を採用するのが望ましいでしょう。するとARGB各成分それぞれフルに8bitを割り当てるわけには行きません。ALPHA成分は5bitにするといった策が現実的になると考えられます。32bit色環境は間違いなくパフォーマンス面で悪影響をもたらすので、オプションとして提供されるのが望ましいでしょう。すると、アドオンは16bit環境と32bit環境の双方をサポートする必要が出てきます。16bit色環境実行時のパフォーマンスが落ちては元も子もないので、32bit色でコンパイルされたアドオンを16bit色環境でスムーズに表示できるよう工夫が必要です。16bit画像をpakに含めてしまうのは一つの策ですが、明らかにファイルサイズが無駄に大きくなります。32bit色表現で、16bit色環境実行時にスムーズに読み出せるbit配置に工夫するのが良い作戦かと思います。書きましたが、要点はこんな感じです。減色ナシ化はパフォーマンスが悪化する。それを受け入れれば可能。(ただしアルファチャンネルは若干のビット落ちがあるかも)本体を減色ナシに対応させるのであれば、減色版本体も同時に提供する必要。19:29続・アドオンの減色についてTweet広告を非表示にするもっと読むコメントを書く2018-09-10アドオン画像の減色についてアドオン画像の減色メカニズムについて、コードを読みながら整理したいと思います。本来この話は現在執筆中の『Simutransの本体開発』に載せるつもりでしたが、本の構成上溢れそうなのでこちらで供養するといったものです。Simutransの仕様は数年もすれば様変わりしてしまいますが、いつ何時も原典であるコードの読み方といっしょに分析しておけば時代が下っても参考程度にはなるかなと考え書き残しておきます。減色処理はpngとdatからアドオンをコンパイルするときに行われるのでdescriptor/writer/image_writer.ccを見れば良いことになります。コードはこちらからオンラインで見れます。github.comきちんと流れを追うのはしんどいのでわかりやすいところからつまみ食いしていきましょう。62行目からはじまるpixrgb_to_pixval関数を呼んでいきます。名前の通り8bitなrgb値をSimutrans内部で使われているpixval値に変換する関数です。endian(pix);}前提として、一般的にピクセルの色はアルファ値を含めて32bitで表現されます。頭8bitが透明度、次の8bitがR、その次の8bitがG、一番最後の8bitがBを表します。0x00FFFFFFで分岐しているので、ざっくりALPHA値が含まれてるか否かで処理が分岐していることがわかると思います。ココでは数値はすべて16進数で表記されています(頭に0xがついていたら16進数)。ALPHA値が入っていない処理から見ていきましょう。以下はpixrgb_to_pixval関数の後半部分を抜粋したものです。endian(pix);与えられた色に対してプレイヤーカラーや発光色といった特別色に該当していないかまず検査します。特別色の場合は特別色番号に0x8000を加算した値をpixvalとして返します。pixval値は16bitなので最上位bitが1の場合は特別色であることを表すことがわかります(0x8000は2進数で表すと1000000000000000)。一般色に使えるbitは15bitしかありません。(ちなみに後で分かりますが、最上位bitが1のときは「透過ナシ一般色ではない」というのが真の意味です。)特別色でない場合は、色の32bit表現からr,g,bを取り出した上で、各成分8bit(256段階)から5bit(32段階)にダウンサイジングしています。ビット演算で表現されてるので少々わかりにくいですが、やってることは256階調の色の値を8で割ってあまりは切り捨てです。R成分が87であれば87÷8→10となります。最終的に返されるpixval値は16bitになります。元が32bitなのでデータサイズだけで見れば半分に圧縮されたことになります。つづいてアルファ値が入っている場合を見てみましょう。以下はpixrgb_to_pixval関数の前半部分を抜粋したものです。endian(pix);}やってることは概ね同じで、特別色を検査してから8bitのrgb値を圧縮しています。pixval値で一般色に使えるbit数は15bitなので、ALPHA値がない場合はRGB各成分5bit(32段階)で表現してましたが、今回はALPHA値の表現ですでに5bit(32段階)使っているのでRGBを10bitで表現せねばなりません。そのため、RとBは3bit(8段階)、Gは4bit(4段階)に圧縮されています。計算ルールは同じで、例えば元のRGB値でRが87であれば、87÷(256÷8)→2と計算されます。pixval値は16bitであり、その中で透過ナシ色や特別色と衝突しない表現をする必要があるので、最終的な値の計算式はやや複雑になります。グラデーションの表現が不自然になることですでに悪名高い減色処理ですが、png画像にALPHA値を含めるとさらに激しく減色されるので、必要ない限りはALPHA値を含めることは避けるべきです。いえ大サイズ3Dアドオンが普及するにつれて減色問題による弊害は深刻さを増しているので、次回は減色がなぜ行われているのか、減色問題を解決する手立てはあるのかについて分析する予定です。C95に応募しました表題のとおりです。冬コミに応募しました。サークル名は日本シムトラ学会名義です。私自身はsimutrans本体開発入門本を出します。他にも数名の方から私のブースで本やCDを出すというオファーをいただいているので、日本シムトラ学会として楽しいブースにできるかなと思います。私が執筆中のシムトラ入門本のメインターゲットは「プログラミングのお勉強はかじったことあるけどそこからSimutransの本体開発に繋がらない」という方です。C++の一部を自習していただければ十分ついていける内容になっています。ソフトウェアの開発経験をお持ちの方にとってもシムトラ開発特有の知識をたっぷり解説していますのでスムーズな導入になるでしょう。シムトラ本体開発はOSSの改造ということになるのでそれ相応の知識と技能が必要になってきます。本ではそこを中心にカバーして、本体開発を楽しむ人が一人でも増えれば嬉しいなと考えながら書いています。最初に書きなぐった段階の原稿なのでこれから修正を重ねていくことを考えると楽観的に見てもまだ4割ぐらいの進捗でしょう。思いのほかページ数が増えそう(といっても技術本として考えればそんなに多くはない)なので印刷原価が上がるのが心配ですが、頒布価格は3ケタ円には抑えようと考えています。初回頒布は冬コミ、ではなく、12月アタマに開催される予定の関西シムトラ学会(ありすさん主催)にする予定です。西日本にお住まいの方はシムトラ学会でお求めになるのがいいでしょう。その後冬コミで頒布して、終わり次第通販、は在庫次第です。11月のオフ会、12月のシムトラ学会、年末の冬コミと今年の冬は楽しいことになりそうです。C95に応募しましたTweet広告を非表示にするもっと読むコメントを書く2018-07-08std版OTRPの方針についてひめしです。v14_5をリリースしました。v14_5をリリースしました。2018OTRPはもともと本家standardへの統合を目指して開発していましたが、いろいろあって本家統合を放棄したのが昨年の11月末のことでした。extendedへの移植を行い、今年6月にextendedへの統合を果たしました。extendedへの統合を果たしたからといって全てが終わったわけではありません。OTRPには依然として不完全な箇所が多く存在しており、これからもそれが顕在化するごとに一つ一つ対処していくことになります。extendedに統合をしていただいたからこそ、私には保守を続ける責任があります。ところで、最近のOTRPは純粋な「二車線パッチ」の機能以外にも様々な機能を搭載するようになりました。height制限を64に拡張したり、交差点一時停止(結局コレは失敗作に終わりましたが)を実装してみたり、道路信号の方向制御を実装したりといった具合です。現在の(standard版)OTRPはこのように独自機能を拡大しています。するとOTRPは私、ひめしが運営する本家simutransの拡張版ということになるのですが、コレだけ聞くとjamespetts氏のsimutrans-extendedと同じことをやってるように聞こえます。本体改造にとって配布チャンネルはまとまっていればまとまっているほど良いので、私がやっているOTRPプロジェクトは全てextendedに一本化すれば良いという話になります。私はそうはせず、今後も独自に「simutransひめしエディション」の開発・配布を続けていくつもりです。いうのも、extendedはもはやstandardとは別ゲーであり、セーブデータの互換性もほぼなく、standardが好き・慣れている人々にとって到底受け入れられるものではないからです。そこで「simutransひめしエディション」では以下を開発の原則にしています。nightlyに追従する。standardの拡張版であり、本家でされた改良、バグ修正の恩恵をプレイヤーが確実に受け取れるようにする。アップデートで必ずnightlyに追従することで本家の変更をmergeすることが困難になるのを防ぐ。独自アドオンを要求する機能は搭載しない。standard用のアドオンがあればそれで完結する設計にする。extended用のpakとフィールドが分かれているsimutransのアドオン界隈において、OTRP独自の規格を設けてもうまくいくはずがないからである。セーブデータの互換性を確保する。いつ何時も、standardのセーブデータは必ずOTRPで読み込めるようにする。standardのセーブデータを読み込んだときは、OTRPで開いたときにはstandardと全く同じ挙動をするようにする。(つまりOTRPはただのstandardとしても使える。)OTRPのセーブデータもOTRP独自の機能まわりを犠牲にすればstandardで読み込む手段を提供する。(v14_5で実装済み)UIの互換性に配慮する。standardからOTRPに乗り換えてきた人にとって、OTRPの機能について何も知らなくてもstandardとして遊ぶ分には困らないようにする。プレイヤーはOTRPの機能について少しずつ探求することができる。(extendedは始める前にある程度extended独自のゲームシステムについての知識がないと不自由する傾向にある。standard」を目指すという話です。standardで遊ぶならOTRPで遊んだほうがよい、そう皆さまに思っていただけるようなプロジェクトにしたいと思っています。requestしていきます。extendedにはextendedの設計思想があるので、これに合致すると判断した機能のみextendedに持っていくことになります。(例えば交差点一時停止は今のアルゴリズムではダメ。number(v14_5の14の部分)を上げることにしています。numberが上がります。numberだけです。OTRPは常に皆さまのためのsimutransでありたいと思っています。タグをつけて投げていただければ可能な限り対応いたします。OTRPのコード自体の信頼性がどうしても本家standardより大きく劣るので皆さまにご迷惑をおかけすることも多いと思いますが、できる限りサポートさせていただいて信頼していただけるプロジェクトにしていく所存です。今年の夏はいろいろと忙しいので細々とやっていくことになりそうですが、今後ともよろしくおねがいします。23:36std版OTRPの方針についてTweet広告を非表示にするもっと読むコメントを書く2017-12-312017年をふりかえる年の瀬ということで2017年のシムトラ的活動を振り返ろうと思います。2016年12月〜2017年1月シムトラ本体いじりをいつから始めたかは定かではありませんが、2016年の年末には既にいじっていたのは覚えています。Patchの移植でもやろうかなと思いましたが難しそうなので「追い越し条件を緩和するだけでできそう!」という理由でOTRP(二車線パッチ)の開発をはじめました。その後大学の期末試験のおべんきょうをいくらか犠牲にしながら開発は進み、プロトタイプを公開するに至りました。大学の春休みになったのでOTRPの開発が一気に進みます。その後ハイペースで開発は進み、現在のおおよその骨格ができあがります。基本的には大学の講義やレポンヨヨに忙殺されていたのでOTRPの開発は停滞します。(が、なんだかんだいってちょくちょくはやっていました。)LCパッチを手直しして本家に投げたのはこの時期ですね。5月には横浜で第一回シムトラ学会が開催され、OTRPを始めとしたパッチ開発の普及を図りましたが、元はといえば私のこんなツイットがきっかけでした。2017年4月3日3月に大学の学科でLT(ライトニング・トーク。一人5分程度の持ち時間で次々とプレゼンをしていく。)合宿をしたのがきっかけで、それをシムトラ界隈に持ち込もうと思ったわけです。8月〜9月OTRPは増築を繰り返した影響でバグ(仕様上の欠陥?)が際限なく増えていったのでひたすらその対処をし続けていました。あいかわらずバグだらけのコードのおかげで本家フォーラムでの議論も陰りが見え始めます。この頃になると改造したいポイントが増え、一人ではどうしようもないレベルになってきました。そのうち私が手を付けることができたものについてはこのあいだのアドベントカレンダーに書きました。himeshi.hateblo.jpコードをいじれる人、そうでなくてもプログラミング的思考ができる日本勢が大幅に不足している現状を見て、少しでも状況を改善しようと実践パッチ開発ゼミを開催したのもこの頃ですね。9月のおわりには札幌シムトラ学会もありました。学期中はやっぱり大学に忙殺されるのでシムトラの活動は止まります。OTRPは9月の札幌学会の頃には実用上致命的な欠陥が取り除かれた状態になりました。してコードは整理されず、自分の開発リソースも限られているのでstandardでの開発を諦め(どういうかたちであれ)新しい進路をとることを決断しました。me.学科でアドベントカレンダーが開催されていたのに刺激されて、シムトラ界隈でもアドベントカレンダーを持ち込んでみました。最終的に全枠埋まり、非常に密度の濃い記事が多数投稿されたことは主催としてうれしいかぎりです。contributorへと立場が変わった年でした。participantといったほうがいいかもですね。間違いなく人生で最もシムトラ漬けな一年ではありましたが、最初一人で作っていたパッチから最終的にはこうして界隈のみなさんと共に歩んでいく方向に少しは行けたかなと思っています。一人でやれることはあまり多くありません。自分でやるより界隈のみなさんと一緒にやっていけたらなという思いからシムトラ学会を提唱し、パッチゼミを行い、アドベントカレンダーでより多くのみなさんと深いレベルの議論ができるように活動してきたつもりです。年末のシムトラ学会で今後の指針てきなものを打ち出したっきりそのままになってますので年明けから当面はその指針に沿って行けたらと思っています。2018年の抱負的なものは特に考えていませんが、しいて言えば指針の完遂ということになるでしょう。2018年は4月から研究室に配属され8月には院試もあるのでシムトラから離れるかもしれません。2018年もシムトラがよりすばらしい「なにか」になってくれればいいなと思っています。くれればいいなじゃないですね。これをお読みのみなさんが各々活動するんですね。