Archive for 7月, 2008

普段使うのは MultiByteToWideChar とかな自分です。
変換関数は CのランタイムとWin32 API が用意されているけど、確か挙動が違うとどっかに書いてあったんだよね。
ぐぐったら出てきました -> 理ろぐ

自分で調べてなかったので、調べたくなりました。コードは 理ろぐ のを改造。
結論から言うと、locale 設定するだけでどちらでも正しい結果が出ます。

まぁ、ここまでが序章。
locale 設定しなくても Win32 API の方は正しく動いているように見えますので確認します。

C++:
  1. #include <iostream>
  2. #include <locale>
  3. #include <iomanip>
  4. #include <stdlib .h>
  5. #include <windows .h>
  6.  
  7. using namespace std;
  8. const int ARRAY_SIZE = 64;
  9.  
  10. std::ostream& couthex(const int n) {
  11.     return cout <<"Ox" <<setw(n) <<setfill('0') <<setbase(16);
  12. }
  13.  
  14.  
  15. void dump(unsigned char *data) {
  16.     for (int i=0; ; i++) {
  17.         if (i%16 == 0 && i != 0) cout <<endl;
  18.         couthex(2) <<static_cast<int>(*(data+i)) <<" " <<flush;
  19.  
  20.         if ((*(data+i) == 0) && (*(data+i+1) == 0)) break;
  21.     }
  22.  
  23.     cout <<endl <<endl;
  24. }
  25.  
  26.  
  27. bool charToWchar(const char* src, wchar_t* dst1, wchar_t* dst2) {
  28.     ::ZeroMemory(dst1, sizeof(wchar_t) * ARRAY_SIZE);
  29.     ::ZeroMemory(dst2, sizeof(wchar_t) * ARRAY_SIZE);
  30.  
  31.     bool retval = true;
  32.     if (::mbstowcs(dst1, src, sizeof(wchar_t) * ARRAY_SIZE) == -1) {
  33.         cout <<"mbstowcs : error" <<endl;
  34.         retval = false;
  35.     }
  36.  
  37.     if (::MultiByteToWideChar(CP_ACP, 0, src, -1, dst2, sizeof(wchar_t)* ARRAY_SIZE) == 0) {
  38.         cout <<"MultiByteToWideChar : error" <<endl;
  39.         retval = false;
  40.     }
  41.  
  42.     return true;
  43. }
  44.  
  45.  
  46. bool wcharToChar(const wchar_t* src, char* dst1, char* dst2) {
  47.     ::ZeroMemory(dst1, sizeof(char) * ARRAY_SIZE);
  48.     ::ZeroMemory(dst2, sizeof(char) * ARRAY_SIZE);
  49.  
  50.     bool retval = true;
  51.  
  52.     if (::wcstombs(dst1, src, sizeof(char) * ARRAY_SIZE) == -1) {
  53.         cout <<"wcstombs : error" <<endl;
  54.         retval = false;
  55.     }
  56.  
  57.  
  58.     if (::WideCharToMultiByte(CP_ACP, 0, src, -1, dst2, sizeof(char)* ARRAY_SIZE, 0, 0) == 0) {
  59.         cout <<"WideCharToMultiByte : error" <<endl;
  60.         retval = false;
  61.     }
  62.  
  63.     return true;
  64. }
  65.  
  66.  
  67. int main(int argc, char** argv)
  68. {
  69.     const char    csrc[]"Mrブギータンブリンマン";
  70.     const wchar_t wsrc[] = L"Mrブギータンブリンマン";
  71.     char    cdst1[ARRAY_SIZE] = "";
  72.     char    cdst2[ARRAY_SIZE] = "";
  73.     wchar_t wdst1[ARRAY_SIZE] = L"";
  74.     wchar_t wdst2[ARRAY_SIZE] = L"";
  75.  
  76.     // 1ループ目はロケール設定なし
  77.     // 2ループ目はロケール設定あり
  78.     for (int i=0; i&lt;2; i++) {
  79.         // マルチバイト文字 -> ワイド文字
  80.         {
  81.             charToWchar(csrc, wdst1, wdst2);
  82.             cout <<"mbstowcs : " <<endl;
  83.             dump(reinterpret_cast<unsigned char*>(wdst1));
  84.             cout <<"MultiByteToWideChar : " <<endl;
  85.             dump(reinterpret_cast<unsigned char*>(wdst2));
  86.         }
  87.         // ワイド文字 -> マルチバイト文字
  88.         {
  89.             wcharToChar(wsrc, cdst1, cdst2);
  90.             cout <<"wcstombs : " <<endl;
  91.             dump(reinterpret_cast<unsigned char*>(cdst1));
  92.             cout <<"WideCharToMultiByte : " <<endl;
  93.             dump(reinterpret_cast<unsigned char*>(cdst2));
  94.         }
  95.  
  96.         // locale 設定
  97.         cout <<"-- set locale --" <<endl;
  98.         locale::global(std::locale("japanese"));
  99.     }
  100.  
  101.     return 0;
  102. }

実行結果

mbstowcs :
Ox4d Ox00 Ox72 Ox00 Ox83 Ox00 Ox75 Ox00 Ox83 Ox00 Ox4d Ox00 Ox81 Ox00 Ox5b Ox00
Ox83 Ox00 Ox5e Ox00 Ox83 Ox00 Ox93 Ox00 Ox83 Ox00 Ox75 Ox00 Ox83 Ox00 Ox8a Ox00
Ox83 Ox00 Ox93 Ox00 Ox83 Ox00 Ox7d Ox00 Ox83 Ox00 Ox93 Ox00

MultiByteToWideChar :
Ox4d Ox00 Ox72 Ox00 Oxd6 Ox30 Oxae Ox30 Oxfc Ox30 Oxbf Ox30 Oxf3 Ox30 Oxd6 Ox30
Oxea Ox30 Oxf3 Ox30 Oxde Ox30 Oxf3 Ox30 Ox00

wcstombs : error
wcstombs :
Ox4d Ox72 Ox00

WideCharToMultiByte :
Ox4d Ox72 Ox83 Ox75 Ox83 Ox4d Ox81 Ox5b Ox83 Ox5e Ox83 Ox93 Ox83 Ox75 Ox83 Ox8a
Ox83 Ox93 Ox83 Ox7d Ox83 Ox93 Ox00

-- set locale --
mbstowcs :
Ox4d Ox00 Ox72 Ox00 Oxd6 Ox30 Oxae Ox30 Oxfc Ox30 Oxbf Ox30 Oxf3 Ox30 Oxd6 Ox30
Oxea Ox30 Oxf3 Ox30 Oxde Ox30 Oxf3 Ox30 Ox00

MultiByteToWideChar :
Ox4d Ox00 Ox72 Ox00 Oxd6 Ox30 Oxae Ox30 Oxfc Ox30 Oxbf Ox30 Oxf3 Ox30 Oxd6 Ox30
Oxea Ox30 Oxf3 Ox30 Oxde Ox30 Oxf3 Ox30 Ox00

wcstombs :
Ox4d Ox72 Ox83 Ox75 Ox83 Ox4d Ox81 Ox5b Ox83 Ox5e Ox83 Ox93 Ox83 Ox75 Ox83 Ox8a
Ox83 Ox93 Ox83 Ox7d Ox83 Ox93 Ox00

WideCharToMultiByte :
Ox4d Ox72 Ox83 Ox75 Ox83 Ox4d Ox81 Ox5b Ox83 Ox5e Ox83 Ox93 Ox83 Ox75 Ox83 Ox8a
Ox83 Ox93 Ox83 Ox7d Ox83 Ox93 Ox00

VS2008 st でコンパイルしました。
cl /EHsc /DWIN32 /MD /D_NODEBUG /D_CONSOLE convert.cpp

ちとソースが長いですが、結果を見ると locale 設定前でも Win32 API の方の変換は正しいことが確認できます。
ランタイムの方は locale を設定しないと、変換エラー出てますね。 (wcstombs)

windows で文字列の変換を行うときは Win32 API がよさそうですね。 Continue reading ‘VisualStudio でのマルチバイト文字とワイド文字の変換’ »

会社のマシンが新しくなって、環境移行していたのです。
んで、全データを移動して古いマシンはフォーマットされるために連れて行かれました。
ここまでが先日までの話。

で、今日は coLinux を入れるかと思って移動してきたデータを漁っていました。
おや、見つからないなぁー。オヤ、アレ、オカシイナァ・・・
データがナイィィー。察してくだしい。。

作業データは別に残っていたんだけど、coLinux の環境を再構築するようだ orz

最近はずっと utf-16 bom付き little endian でコードを書いていたんだけど。
ふと gcc でコンパイルしてみたらエラーが出た!ナンダッテー

utf-8 のbom 付きでも駄目みたい。 bom でこける。。

VS は bom 必須。gcc は bom 禁止。。どうすればいいんだ。。。

我が家のデスクトップPCの BIOS が壊れた!
昨日の夜、しばらく更新していないデスクトップPCの BIOS を更新しました。
更新後、再起動したら windows が起動しない。。。(ブラックアウト)
もちろん BIOS が原因だろう、ということで再起動して BIOS 画面を確認してみようとしました。

で、なんと BIOS メニュー画面に行けない!
BIOS メニュー画面に移動しようとするとフリーズするという狂った挙動をしてくれちゃってます。

MBの買いなおしかなぁ、と思っていましたが何とか直りました。
C-MOS をリセットしてやったら直ったわけです。。。BIOS メニューにも普通に移動可能!

やれやれ、これに半日悩んだと思うと疲れてきますね・・・ orz
BIOS の更新は慎重に。

使おうと思ったら壊れていた・・・ orz
新しいの買わないと。。
秋葉行けばめちゃめちゃ安く売っているけど、買うなら壊れにくいのがいいなー。

以前にいも古いバージョンが無償公開されていましたが、最新版が無償公開されました。
trueSpace 7.6

さっそくインストールしてライセンスを読んでみました。

THIS SOFTWARE IS FREE FOR PERSONAL USE OR FREEWARE APPLICATIONS.
IF YOU WISH TO THANK MY WORK, YOU MAY DONATE ANY SUM OF MONEY TO ME
FOR SUPPORT OF DEVELOPMENT OF THIS CLASS.
IF YOU USE THIS SOFTWARE IN COMMERCIAL OR SHAREWARE APPLICATIONS YOU
ARE GENTLY ASKED TO DONATE ANY SUM OF MONEY TO THE AUTHOR

個人的な利用やフリーウェアに利用する分にはどうぞご自由に。(寄付歓迎)
商用利用やシェアウェアであれば任意の金額を寄付してください。

本来 $595 のソフトウェアが任意の金額で商用利用可能なのはすごいですね。
少し使ってみましたが、直感的に弄りやすい感じがします。
細かいことをやるには慣れが必要そうですね。(何がどこにあるかわからない)

保存形式ですが、FBX は出力できるかなと思っていましたがデフォではついていませんね。XNA の人たちが使うなら FBX は標準でつけてほしいものですが。
対応フォーマットは少ない気がします。Xファイルはありますが。。
プラグインでいろいろ対応可能なのかな。

某所にコメント書いたので、ついでにエントリ書きます。

自分のマシンには October 2004 と 最新のSDK(June 2008) を入れています。
最新のSDKは遊び用で、開発には October 2004 を使うといった具合です。

SDK の選び方はいくらか方針があると思います。
下記に DirectX 9, 10 について選ぶポイントを軽くまとめてみました。

・ユーザに d3dx9_XX.dll を必要とさせたくない
December 2004 までが static-link 形式のライブラリになっています。
HLSL も Shader3.0 対応済みで、Windows 2000 の最終サポート版SDKである October 2004 がオススメです。

・HLSLコンパイラ を使いたい
April 2007 以降で修正版が入っています。
別途 D3DCompiler_XX.dll が必要となっていますが。

・なるべくバグのない SDK を使いたい
最新のSDK はバグフィクスも含んでいます。
素直に新しいSDKを利用するのがよいでしょう。

・DirectX 10.1 を使いたい
March 2008 以降を利用します。

- オマケ -
ただし、最近のSDKには古いライブラリが同梱されていません。
古いライブラリを利用する場合、August 2007 以前のSDKも一緒に導入しておく必要があります。

現在公開されている日本語リファレンスは October 2004 のものです。

金曜日
つぃったープログラマ飲み会に行ってきました。
参加者はこんな感じ @seasons @yuumizusawa @cpp_akira @yuji1982 @hajimehoshi @melt_slinc @finalJ2
やっぱプログラマで集まると熱い話があって面白い!(プログラム的な意味で)
濃い話からブラックな話まで飛び交うので楽しいのよね。またやりましょう!

土曜日
岐阜から友人と〜ふさんが襲来。酒飲んで、適当に寝る感じ。
積もる話をしつつ、だらだらと過ごす。

日曜日(東方のイベント当日)
イベント参加予定だったんだけど、朝起きるとテンション低め(低血圧)だったので、と〜ふさんだけでかけることに。
昼過ぎくらいにはと〜ふさん帰宅。早いな!!
で、夜は KAMBA, ちゅばくん の2人追加で酒飲んでだらだらと過ごす。

月曜日(桃狩り)
桃狩りで山梨まで遠出。6個ほど刈り取って1個はその場で食べた。ウマーー
残りはおみやげ。
ここでと〜ふさんとはお別れ。岐阜までファイトだ!!
で、晩御飯は残ったメンツで焼肉。

うーむ、金曜日から3連休はずっと遊んでしまった!!
明日から色々がんばろう。。

iPhone。本体は安いと言ってウリにしているけど、壊れると修理費用がすごく高いです。
「iPhone 3G」の修理費用、重度損傷で約6万円に
何か保険とかかけられないのか、これ。

あと気になることが書いてあるんだよね。

 またバッテリーの機能低下に対して、アップルでは「iPhoneバッテリー交換プログラム」を用意している。
価格は9800円で、バッテリー交換ではなく、本体交換となっており、内部のデータはユーザー自身が事前にバックアップして、移行することになる。

つまり、壊れたらバッテリー交換申請すれば新しい iPhone が届くってこと?
修理頼むより良いジャマイカ。。
iPhone ユーザはバックアップを小まめにすると幸せになれるかも?

# 自分は基本使用料がもっと安くなれば検討するんだけどなぁ。

Android SDK (android-sdk_m5-rc15_windows) に入っている OpenGL のサンプルコードがビルドできませんでした。
で、下記のような方法でとりあえずプリミティブ出せたのでコード残しておきます。

null

JAVA:
  1. import java.nio.FloatBuffer;
  2.  
  3. import javax.microedition.khronos.opengles.GL10;
  4.  
  5. import android.app.Activity;
  6. import android.os.Bundle;
  7. import android.util.Log;
  8. import android.view.SurfaceHolder;
  9. import android.view.SurfaceView;
  10. import android.graphics.OpenGLContext;
  11. import android.content.Context;
  12. import android.opengl.GLU;
  13.  
  14.  
  15. public class GlTest extends Activity {
  16.     @Override
  17.     public void onCreate(Bundle icicle) {
  18.         super.onCreate(icicle);
  19.         setContentView(new SurfaceTest(this));
  20.     }
  21. }
  22.  
  23. class SurfaceTest extends SurfaceView implements SurfaceHolder.Callback, Runnable {
  24.     final static private float SCREEN_WIDTH  = 320;
  25.     final static private float SCREEN_HEIGHT = 320;
  26.  
  27.     private OpenGLContext glContext_;
  28.     private GL10          glObject_;
  29.     private Thread        thread_;
  30.     private boolean       threadRunnable_;
  31.  
  32.     public SurfaceTest(Context c) {
  33.         super(c);
  34.         Log.i("userlog", "SurfaceTest.SurfaceTest()");
  35.  
  36.         getHolder().addCallback(this);
  37.     }
  38.  
  39.  
  40.     private boolean initialize() {
  41.         try {
  42.             glContext_ = new OpenGLContext(OpenGLContext.DEPTH_BUFFER);
  43.             glContext_.makeCurrent(getHolder());
  44.             glObject_  = (GL10)(glContext_.getGL());
  45.  
  46.             glObject_.glMatrixMode(GL10.GL_PROJECTION);
  47.             glObject_.glLoadIdentity();
  48.  
  49.             GLU.gluOrtho2D(glObject_, -1.0f, 1.0f, -1.0f, 1.0f);
  50.             glObject_.glViewport((int)(getWidth()-SCREEN_WIDTH)/2, (int)(getHeight() - SCREEN_HEIGHT)/2,
  51.                                  (int)SCREEN_WIDTH, (int)SCREEN_HEIGHT);
  52.         } catch (Exception e) {
  53.             Log.i("userlog", e.toString());
  54.             return false;
  55.         }
  56.         return true;
  57.     }
  58.  
  59.  
  60.     @Override
  61.     public void run() {
  62.         Log.i("userlog", "SurfaceTest.run()");
  63.  
  64.         if (initialize() == false) return;
  65.  
  66.         final float[] vertex = new float[] {
  67.             -0.0f,  0.6f, 0.0f,
  68.             -0.6f, -0.6f, 0.0f,
  69.              0.6f, -0.6f, 0.0f,
  70.         };
  71.  
  72.         final float[] color = new float[] {
  73.             1.0f, 0.0f, 0.0f,
  74.             0.0f, 1.0f, 0.0f,
  75.             0.0f, 0.0f, 1.0f,
  76.         };
  77.  
  78.         final FloatBuffer colors = FloatBuffer.wrap(color);
  79.         final FloatBuffer squareBuff = FloatBuffer.wrap(vertex);
  80.  
  81.         threadRunnable_ = true;
  82.  
  83.         while (threadRunnable_) {
  84.             glObject_.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
  85.             glObject_.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
  86.  
  87.             glObject_.glMatrixMode(GL10.GL_MODELVIEW);
  88.             glObject_.glLoadIdentity();
  89.             glObject_.glTranslatef(0.0f, 0.0f, -1.0f);
  90.  
  91.             glObject_.glVertexPointer(3, GL10.GL_FLOAT, 0, squareBuff);
  92.             glObject_.glEnableClientState(GL10.GL_VERTEX_ARRAY);
  93.             glObject_.glEnableClientState(GL10.GL_COLOR_ARRAY);
  94.             glObject_.glColorPointer(3, GL10.GL_FLOAT, 0, colors);
  95.             glObject_.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);
  96.  
  97.             glContext_.post();
  98.  
  99.             try {
  100.                 Thread.sleep(100);
  101.             } catch (InterruptedException e) {
  102.                 Log.i("userlog", e.toString());
  103.             }
  104.         }
  105.         glContext_.makeCurrent((SurfaceHolder)null);
  106.     }
  107.  
  108.  
  109.     @Override
  110.     public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
  111.         Log.i("userlog", "-- SurfaceTest.surfaceChanged");
  112.     }
  113.  
  114.  
  115.     @Override
  116.     public void surfaceCreated(SurfaceHolder holder) {
  117.         Log.i("userlog", "-- SurfaceTest.surfaceCreated");
  118.         thread_ = new Thread(this);
  119.         thread_.start();
  120.     }
  121.  
  122.  
  123.     @Override
  124.     public void surfaceDestroyed(SurfaceHolder holder) {
  125.         Log.i("userlog", "-- Surface.surfaceDestroyed");
  126.         threadRunnable_ = false;
  127.         try {
  128.             thread_.join();
  129.         }
  130.         catch (InterruptedException e) {
  131.             Log.i("userlog", e.toString());
  132.         }
  133.         thread_ = null;
  134.     }
  135. }

# いやぁ、Java は久しぶりです。