FPSを作ってみる@wiki
05)
最終更新:
slice
-
view
(2011/05/29)
Unicode対応完了
変換プログラムを作った後にふと「メインプログラムもunicode対応しておこうか」と思い立ってしまったのでそれをしていた.
こんなカスのようなプログラムでもそれなりコード量があって
想像だけでおなか一杯だが何時かはやらねばならんのだ.
というかShiftJIS版Luaを使わずに行くと決めた時点でunicode対応は必須事項.
こんなカスのようなプログラムでもそれなりコード量があって
想像だけでおなか一杯だが何時かはやらねばならんのだ.
というかShiftJIS版Luaを使わずに行くと決めた時点でunicode対応は必須事項.
最初unicode対応と聞いてプログラム中の文字列を全部wchar_t型に置き換えるのかと勝手に決めつけ
ソースコード中の文字列をひたすら_T()で括りstd::stringはtstring(※1)に,その他ルーチンを対応の物に置き換えていたのだが
実際そんな単純な話ではない.例えば
XMLパーサのxercesライブラリは元々内部表現としてunicodeを使用している為にANSIから変換するコードが不要になるし
HLSLのクラスであるD3DXEFFECTはメソッド引数にANSIしか受け付けない(※2).
Luaとやり取りする文字列に関してもシステム定数なんかの
「アルファベットと数字だけと分かっている」文字列はどちらにせよASCIIコードの範囲内だから
unicodeで定義する必要はない(というよりASCII文字だけの場合はUTF-8にしようがコードは同一であるからむしろcharのままが自然)
ソースコード中の文字列をひたすら_T()で括りstd::stringはtstring(※1)に,その他ルーチンを対応の物に置き換えていたのだが
実際そんな単純な話ではない.例えば
XMLパーサのxercesライブラリは元々内部表現としてunicodeを使用している為にANSIから変換するコードが不要になるし
HLSLのクラスであるD3DXEFFECTはメソッド引数にANSIしか受け付けない(※2).
Luaとやり取りする文字列に関してもシステム定数なんかの
「アルファベットと数字だけと分かっている」文字列はどちらにせよASCIIコードの範囲内だから
unicodeで定義する必要はない(というよりASCII文字だけの場合はUTF-8にしようがコードは同一であるからむしろcharのままが自然)
他にはBOM(Byte Order Mark)のスキップやら対応してないエンコードを弾くなどの処理も必要だがこんな所である.
ちなみにunicodeは仕様上最初の2バイトは必ずASCII文字であるので最初の4バイトを見ればUTFの何でエンコードされているか判別可能だ.
ちなみにunicodeは仕様上最初の2バイトは必ずASCII文字であるので最初の4バイトを見ればUTFの何でエンコードされているか判別可能だ.
そもそもなぜunicode対応(UTF-16)をするのかといえば
- WindowsAPIの内部表現がそうなっているから(ANSIだと都度変換がかかる)
- 日本語の扱いを簡単にする(全角も半角も同じ2バイトだから扱いが楽.ShiftJISのような2バイト目にバックスラッシュと同じコードが入って不具合を起こす事も無い)
だった.
しかしその後の調査で1番目はともかく2番目に関しては1文字につき基本2バイトだけど4バイトの文字(サロゲートペア)もある事がわかって利点が半分崩れる格好となった.
LuaからC++に渡した日本語の文字化け回避くらいしかこれといった利点が・・・(※3)
しかしその後の調査で1番目はともかく2番目に関しては1文字につき基本2バイトだけど4バイトの文字(サロゲートペア)もある事がわかって利点が半分崩れる格好となった.
LuaからC++に渡した日本語の文字化け回避くらいしかこれといった利点が・・・(※3)
※1 UNICODEがdefineしてあるかで分岐して std::string か std::wstring をtstringとしてtypedefした物.
※2 そもそもHLSLのコンパイラからしてunicodeに非対応,MSDNを見るに文字列型も仕様的にASCIIオンリーとしてある.
※3 しかし同じunicodeといってもExeで扱う形式はUTF-16,LuaはUTF-8なのでASCIIなら無変換で渡せるのに対しUTF-16では変換の手間があるという中途半端さ
~続く~
※2 そもそもHLSLのコンパイラからしてunicodeに非対応,MSDNを見るに文字列型も仕様的にASCIIオンリーとしてある.
※3 しかし同じunicodeといってもExeで扱う形式はUTF-16,LuaはUTF-8なのでASCIIなら無変換で渡せるのに対しUTF-16では変換の手間があるという中途半端さ
~続く~
(visual studioで「unicode文字セットを使う」を選ぶと何が変わるの?という疑問が浮かんだので
調べたらUNICODEがdefineされるか否かだけらしい.なんとまぁ・・)
調べたらUNICODEがdefineされるか否かだけらしい.なんとまぁ・・)
(2011/05/24)#2
サロゲートペア
前回でUTF-8ならばluaでunicodeを扱えそうだという事がわかり,
じゃあ早速UTF-8とUTF-16を相互に変換するルーチンをググって探して組み込めば良いだろう.
と思いきや,暫しググった後
ふと「そんな細いの探すのも面倒だし元々相互変換しやすく設計されたんだからちゃっちゃと表を見ながら作ればいいのでは?」
(unicodeの理解を深める為にも!)
そんな考えが浮かんだ.
実際やってみたら割とアッサリ出来た.
じゃあ早速UTF-8とUTF-16を相互に変換するルーチンをググって探して組み込めば良いだろう.
と思いきや,暫しググった後
ふと「そんな細いの探すのも面倒だし元々相互変換しやすく設計されたんだからちゃっちゃと表を見ながら作ればいいのでは?」
(unicodeの理解を深める為にも!)
そんな考えが浮かんだ.
実際やってみたら割とアッサリ出来た.
んで折角作るのだからとサロゲートペアにも対応してみた・・・が.BMPに含まれない文字は,少なくともwindowsXPにおいて
付属のメモ帳はともかくvisual studioでさえ「・」や「□」(適切なフォントが見当たらない時の表示)になってしまい少々調子が狂う.
これはファイルに保存する文字コードをUTF-8に設定しても変わらない.インターネットエクスプローラも駄目だ.
しかしFireFoxでは普通に入力可能.結局アプリケーションに依るところが大きい.
付属のメモ帳はともかくvisual studioでさえ「・」や「□」(適切なフォントが見当たらない時の表示)になってしまい少々調子が狂う.
これはファイルに保存する文字コードをUTF-8に設定しても変わらない.インターネットエクスプローラも駄目だ.
しかしFireFoxでは普通に入力可能.結局アプリケーションに依るところが大きい.
XPの内部表現がサロゲートペアに対応してないという事なんだろうか.
まだXPで頑張るつもりの自分としてはなんとも残念な話だがVista以降は大丈夫でしょうな?
まだXPで頑張るつもりの自分としてはなんとも残念な話だがVista以降は大丈夫でしょうな?
(2011/05/24)
LuaとUnicode
そういやluaってunicode対応してたっけなぁと思い,調べたり.
ソースコードをどの文字コードで書いたらOKなの?とか.
結論から言えばUTF-8でソースを書き動作させるのは可能である.
ソースコードをどの文字コードで書いたらOKなの?とか.
結論から言えばUTF-8でソースを書き動作させるのは可能である.
独自にShiftJIS対応したバージョンを開発して配布してる人も居るようだが
本家luaがバージョンアップした時にまたShiftJISバージョンまで待たされるのもアレだ(というか出る保証もないし).
そんな訳で本家バージョンを使いつつなんとかする方向で行く.
本家luaがバージョンアップした時にまたShiftJISバージョンまで待たされるのもアレだ(というか出る保証もないし).
そんな訳で本家バージョンを使いつつなんとかする方向で行く.
で,"lua unicode"などのキーワードでググって出てきたページでは
8bit目は問題なく処理するから対応してるどうのこうのとか小難しく言ってたが
平たく言えばluaは
8bit目は問題なく処理するから対応してるどうのこうのとか小難しく言ってたが
平たく言えばluaは
- マルチバイト文字には対応してない
- 文字列はそのままバイト列として扱うから(0x00で終わってさえいれば)中身は関係ない
そしてUTF-8の特徴は
- ASCIIコードと互換性がある
- 文字の2バイト目以降はASCIIコードが現れない
である.
この事からUTF-8でソースを書く事はコメントと文字列定数以外ASCIIで書くのと同義である.
文字列は先述した通りバイト列として扱われ,終端文字もASCII(=0x00)であるのでこれも問題ない.
コメント文についても閉じタグがASCIIなので(以下略)
この事からUTF-8でソースを書く事はコメントと文字列定数以外ASCIIで書くのと同義である.
文字列は先述した通りバイト列として扱われ,終端文字もASCII(=0x00)であるのでこれも問題ない.
コメント文についても閉じタグがASCIIなので(以下略)
luaのソースがUTF-8で書けるというのはそういう事のようだ.
基本的にソースコードをUTF-8で保存するだけでunicodeに対応できるが
当然luaから送られてくる文字列はUTF-8なので文字列表現にUTF-16を用いるユーザープログラム側で
変換をかまさなければならない.
こうなるとゲームでの処理負荷が気になる所だが所詮は文字列.何百回もループするわけでなし気にしない事にする.
基本的にソースコードをUTF-8で保存するだけでunicodeに対応できるが
当然luaから送られてくる文字列はUTF-8なので文字列表現にUTF-16を用いるユーザープログラム側で
変換をかまさなければならない.
こうなるとゲームでの処理負荷が気になる所だが所詮は文字列.何百回もループするわけでなし気にしない事にする.
(2011/05/16)
Unicode
ファイルパッキング自体は完了.ついでにUnicode対応もしてみた.
何故今までしてなかったかというと
VC++でUnicode文字セットを使う設定にすると文字列の型がchar(1バイト)からwchar_t(2バイト)となるのだが
ネットで調べるとUTF-8は1~4バイトだとか,UTF-16は2or4バイトだとか書いてあり
1文字2バイトにしたところでどうなんだと,合点がいかなかったからだ.
何故今までしてなかったかというと
VC++でUnicode文字セットを使う設定にすると文字列の型がchar(1バイト)からwchar_t(2バイト)となるのだが
ネットで調べるとUTF-8は1~4バイトだとか,UTF-16は2or4バイトだとか書いてあり
1文字2バイトにしたところでどうなんだと,合点がいかなかったからだ.
更にUTFはUTFでもUnicode Transformation Formatや, UCS Transformation Formatの略でもあるとかで
自分がUTF-8で調べて文字長が1~4なのと1~6なのとで混乱したのはこれの違いだった.
え?UnicodeとUCSは違うの?どうやら少し違うらしい.訳がわからん.貴様らDVD+Rと-Rか.
(コンピュータ関連各社が参加するユニコードコンソーシアムで制定されたのがUnicodeで
後にISOが国際規格として標準化したのがUCSのようだ.
当初は世界中の文字を1つの文字コードに統一する目的で別々に動いていたが途中で歩調を合わせるようになり云々・・)
自分がUTF-8で調べて文字長が1~4なのと1~6なのとで混乱したのはこれの違いだった.
え?UnicodeとUCSは違うの?どうやら少し違うらしい.訳がわからん.貴様らDVD+Rと-Rか.
(コンピュータ関連各社が参加するユニコードコンソーシアムで制定されたのがUnicodeで
後にISOが国際規格として標準化したのがUCSのようだ.
当初は世界中の文字を1つの文字コードに統一する目的で別々に動いていたが途中で歩調を合わせるようになり云々・・)
個人的な理解は
Unicodeで定義された文字全てを表すには21ビット必要でそれを満たしCPUにとって扱いやすいサイズは32ビット(4バイト)である.
4バイトを1文字とする形式はUTF-32と呼ばれる.
基本多言語面(BMP, Basic Multilingual Plane)は2バイト,それ以外は4バイトで表すのがUTF-16.
ASCII文字を主に使うケースにおいてアルファベット1つに2バイト使っていたのでは無駄が大きすぎるという事で生まれたのが(多分)
ASCIIコードの0x00~0x7fの範囲は互換性を持たせそれ以外の文字を1~4バイトの可変長で表すUTF-8.
UTF-16を7ビット単位でしかデータを扱えない環境(メール送信とか?)でUnicode文字を送受信する場合にBase64などで細工をかました形式がUTF-7.
またUTF-32とUTF-16にはそれぞれリトルエンディアンとビッグエンディアンの両方が存在しUTF-32LE,UTF-32BEと表記したりする.
とまぁそんなところである.
Unicodeで定義された文字全てを表すには21ビット必要でそれを満たしCPUにとって扱いやすいサイズは32ビット(4バイト)である.
4バイトを1文字とする形式はUTF-32と呼ばれる.
基本多言語面(BMP, Basic Multilingual Plane)は2バイト,それ以外は4バイトで表すのがUTF-16.
ASCII文字を主に使うケースにおいてアルファベット1つに2バイト使っていたのでは無駄が大きすぎるという事で生まれたのが(多分)
ASCIIコードの0x00~0x7fの範囲は互換性を持たせそれ以外の文字を1~4バイトの可変長で表すUTF-8.
UTF-16を7ビット単位でしかデータを扱えない環境(メール送信とか?)でUnicode文字を送受信する場合にBase64などで細工をかました形式がUTF-7.
またUTF-32とUTF-16にはそれぞれリトルエンディアンとビッグエンディアンの両方が存在しUTF-32LE,UTF-32BEと表記したりする.
とまぁそんなところである.
話が長くなったが
windowsXPで使われるUnicodeはUTF-16LE.単にUnicodeといえばUTF-16を指す事が多い.
UTF-16は2or4バイトなので結局文字列処理の複雑さがShiftJISとかと変わらん気もしたが通常
BMPは2バイトで表される為に,特にゲームでは無視しても大丈夫なのだろう.
でも「鮭(サケ)」は2バイトだけど「
windowsXPで使われるUnicodeはUTF-16LE.単にUnicodeといえばUTF-16を指す事が多い.
UTF-16は2or4バイトなので結局文字列処理の複雑さがShiftJISとかと変わらん気もしたが通常
BMPは2バイトで表される為に,特にゲームでは無視しても大丈夫なのだろう.
でも「鮭(サケ)」は2バイトだけど「
添付ファイル