SFML の小ネタかもしれない話。
SFML 関連でわからないことがあったので、
この私がわからないということは、よい子のみなさんもきっと同じ疑問を抱いて苦悩していることでしょう、
ならば、疑問が解け次第、手順をまとめたページを作ってアップせねばならぬ、と思っていたネタが2つほどあります。
一つは、CMake で Code::Blocks(MinGW) 用のプロジェクトファイルを生成する方法。
もう一つは、テキストファイルを読み込んで文字を表示する方法。
とりあえず私の中ではどちらも一応解決したのですが、
なんだか、あんまり一般的な解法じゃないような気がして、気がして、背中がカユイなー、と思っているところです。誰かカイて。
> 一つは、CMake で Code::Blocks(MinGW) 用のプロジェクトファイルを生成する方法。
最初、チュートリアルに書いてある通りに作業したのですが、何度やってもエラーになる。
CMake が「あれがない、これがない」って次々とエラーメッセージを出してきて、
すべての注文に応じて、やっとこさ Code::Blocks のプロジェクトファイルが生成されたものの、
いざビルドしようとすると _Win32 が未定義だなんて言われる始末。いかにも根源的な風情の漂う不具合。
この私の原文読解が間違っているはずがないし、これは一体どうしたことか?
Visual Studio では何の問題もなく処理が通るので、
さては あのチュートリアルは Visual Studio での作業しか想定していないんだな、この帝国主義者めっ! 謎を解明してネタにしてやる!
と、藁人形を片手に打ち震えていたのですが、なんか、Cygwin をインストールしている環境だと、ダメっぽいのですね。
ためしに Cygwin をインストールしてあるフォルダを一時的にリネームすると、何の問題もなく CMake が成功するではありませんか。
コマンドがいろいろと衝突するらしい? すいません、よくわかりません。
少なくとも、チュートリアルに書いてある内容自体には間違いはなかったようです。疑ってごめんなさい。
一般論としての「SFML のソースを CMake して Code::Blocks + MinGW のプロジェクトファイルを生成するときの問題」という話ではなさそう?
あくまでも私のマシンの環境問題ということでしょうか? CO2 が多すぎるんでしょうか。
とりあえず「チュートリアルに書いてあることを鵜呑みにするのは幼虫に要注意だぜ? へっへっへ」などと、
得意顔で記事を作成できるような事象ではなさそうな気がします。
そもそも、Cygwin があると、なぜダメなのか、が、よくわからない。
さらにもう一つそもそも、SFML のソースを Code::Blocks + MinGW でビルドしたいという需要はあるんでしょうか?
Visual Studio だったら、例のマルチスレッド(/MT) の件があるので、是非ともビルドしたいところなのですけどね。
とりあえず、SFML のソースを Code::Block + MinGW 用に CMake したいけど、なんか妙なエラーが出て大変!
というお友達は、Cygwin をインストールしてないかどうかをチェックしようぜ! というだけのことでしょうか。あんまり面白くないですね。
エラーメッセージをここに書いておいたら、検索エンジン経由でこのページが誰かのお役に立つこともあるかな? あるといいな。
↓
sh.exe was found in your PATH, here:
C:/cygwin/bin/sh.exe
For MinGW make to work correctly sh.exe must NOT be in your path.
で、今ちょっと改めて検索してみたのですが、
これは Cygwin 云々というよりも CMake と sh.exe の相性の問題ということなのですか?
CMake の Wiki が出てまいりました。
http://www.cmake.org/Wiki/CMake_MinGW_Compiler_Issues
(引用)
> If make finds sh.exe in your path, it will use it, and then "MinGW Makefiles" will not work.
> If sh.exe is in your PATH, then you must use "MSYS Makefiles" or "Unix Makefiles".
(拙訳)
昔々あるところにおじいさんとおばあさんが住んでいて、
CMake で "MinGW Makefiles" を指定したところ、sh.exe がパスに含まれていたので鬼に食べられてキャー!
怖いですね、怖いですね。怖いですねー。
> そもそも、Cygwin があると、なぜダメなのか、が、よくわからない。
強いて言うなら、Cygwin の中に sh.exe が入っていて、CMake さんがそっちに惹かれてしまうから、ということでしょうか。
なんだか楽しそうな三角関係があるようですね。
環境変数の PATH から Cygwin関係のものを削除しても該当のエラーがなくならない。よほど CMake さんは sh.exe 氏のことが忘れられないのですね。断ち切れない想いがある。
もっと CMake さんの気持ちを理解できるようになりたいです。
> もう一つは、テキストファイルを読み込んで文字を表示する方法。
チュートリアルではソースファイルにリテラルを書いて表示する方法が紹介されてましたが、
実際の場面では、設定ファイルから読み込んで表示したいですよね?
それでお約束ながら、適当にやると文字化けするというわけです。
SFML にファイルIO の機能があればいいのになと思うところですが、
なにしろアルファベット26文字の世界の豪傑ですから、マルチバイト文字などに媚びるような軟弱な真似はしないといったところでしょうか。
結論だけ言うと、この手順でイケます:
1、ファイルを UTF-8N で作成する
2、C++ の std::string に読み込む
3、SFML の文字列型 sf::String に変換
4、sf::Text にセットする
3のところで sf::String::fromUtf8() を使うのがミソです。
なのですが、この手順でうまくいくというのは、一種の手抜きなような気がするのです。
UTF-8 で作成したテキストファイルを std::string に読み込んでいるところが C++ 的に手抜きくさい。
本当はこれ、ワイド文字がどうのこうの、っていう、なんか、そういうことしないとイケないんじゃなかったでしたっけ? どうでしたっけ?
うん、だからね、
> 3のところで sf::String::fromUtf8() を使うのがミソです。
なんて得意げに言いましたけど、同じような名前の関数として sf::String::fromUtf16() っていうのもあるのですが、
じゃあ、ファイルを UTF-16 で作成して、後は同じように std::string に読み込んで、sf::String::fromUtf16() を使えばうまくいくのかと言えば、
うまくいかないのですよね。
Unicode系の文字コードのテキストを 無造作に std::string に入れているというのが、根本的に間違っているような気がします。
UTF-8 ならば、たまたまうまくいっているように見える、それはなぜかと言うと、えーっと、なぜなのでしょう?
std::string の実体は char の配列で、UTF-8 はコードが 1バイトずつ並んでいるから、気持ちよく収まってくれる。
という理解でいいのでしょうか? 誰かに怒られそうで怖いです。ぶるぶる。
つまり、上で書いた手順は、マルチバイト文字を考慮していない実装、ということになる。
UTF-8 が おりこうさんだから、たまたまうまくいっているのであって、実装としてはお行儀がよくない。そんな気がします。
自分で書くアプリでこっそり使うだけならまだしも、人様にご教授できる方法ではなさそうです。
じゃあ、どうするのが正解なのかな、ということで少し調べていたのですけれども、
ちょっと、これ、ジャングルですね。
文字コードの問題は、深入りすると、遭難します。
非常に普遍的な問題であるはずなのですが、
そのわりに、検索しても「これが正解!」というズバリな方法が見つからない。
文字コードに関する薀蓄はたくさん出てくる。掲示板で困りごとを相談しているお友達も大勢いる。得意顔でつっこみを入れているお友達もたくさんいる。
それでいて「これが正解! 黙ってコピペしとけ!」という方法が出てこない。
きっと誰も正解を知らないんだ。
だってさ、たかがテキストファイルを読み込むだけのことですよ?
それが、どうして、こんなにもジャングルなのでしょう。
文字コードがコンピューター界隈における根深い問題だというのはよくわかりました。
だから、やっぱり、本当のところ、どうすればいいのか、というのは、誰も知らないのだと思います。
そういうことってよくありますよね。我々にはお馴染みのはず。
それともあまりにも簡単すぎて、誰も話題にもしないということだったりするのでしょうか?
私の kiが来るっているのでしょうか?
リンゴが木から落ちるなんてアタリマエじゃないかー。Hahaha!
ちなみにこの話は C++ での話です。
他の言語では、ファイルを読み込むときに文字コードを指定して読み込むような機能が普通にあったりしますよね。
内部でどんな処理をしてるんでしょう。
そういえば、たまに思い出したように重力や光についての本を読むんですが、理解できたことが一度もありません。
この世には私には一生理解できないエソテリックな奥義があるようです。
> 1、ファイルを UTF-8N で作成する
> 2、C++ の std::string で読み込む
> 3、SFML の文字列型 sf::String に変換
> 4、sf::Text にセットする
>
> 3のところで sf::String::fromUtf8() を使うのがミソです。
ジャングルに深入りして遭難するぐらいなら、あくまで手軽で大体うまくいく方法として割り切りつつ、これでいいんじゃないかな、とは思います。
目的はあくまでもゲームプログラミングですからね。それで文字化けするならそれもまた一興。
泣けるシーンでヒロインが「アレアサオ廠、ア邀莖ノアΤ!」とか言い出すこともあるでしょうけれど、魂で読解せよ。
ただ、sf::String::fromUtf16() って関数もあるのに、それの使い方がわからないというのが気になります。
おまけに FAQ には UTF-16 に対応してるって書いてあるじゃないですか。
それを聞いちゃあ、ますます fromUtf16() を使わないわけにはいかないような強迫観念が生じるってもんです。玄関の鍵閉めてない気がするってもんです。
手順をまとめたページを作るなら、せめてこの関数での読み込み処理に成功してからにしたいと思います。
というかこれ、SFML云々じゃなくて C++ の話ですよね。背中がカユイ!
|