2012年10月20日土曜日

レブリミット警告灯再び

~~~これまでのお話~~~
・LED でレブリミット警告灯を自作してた
・なつやすみのこうさく感が半端無かったので撤廃して Android でレブリミット警告を表示してみた
・画面が暗くて昼間は役に立たない←いまここ

はっきり言ってサーキットでは LED のスピード表示とかは見ないし,LED 1灯だけのレブリミット警告灯でも作りなおすかなぁ,とか思ったけど,よく考えたら Android のカメラのフラッシュライトが使えるんじゃね? と思ってやってみた.
フラッシュを光らせること自体は簡単に出来たが,フラッシュは画面の反対側についているので光を画面側に持ってこないといけない.というわけで,光沢のある金属板で反射鏡作ってみた.

直視するとヤバイくらいの光量なだけあって,実際に昼間に車で走ってみても点灯してるのがわかって良い感じヽ(´ー`)ノ


なつやすみのこうさく感が薄れたかどうかは定かではない.

2012年10月7日日曜日

なんかエラー出て動かへんバスター

パソコンに詳しくない人から help を求められた時によく言われる言葉「なんかエラー出て動かへん」.
受ける側としては情報量 0 でエスパーレスするのも不可能で,ウチの親からもこんなかんじで最近サポート工数が増えてきたので,なんかエラー出て動かへんバスタースクリプト作成.

動作としては,スクリーンショットを撮ってメールした後再起動するだけwww これをワンタッチアプリ起動ボタンに割り当てて,なんかあったらここを押せと教えておく.ほとんどの場合再起動すれば親にとっても既知のステートに戻るし,「なんかエラー」よりスクリーンショットのほうが情報エントロピーは無限大ヽ(´ー`)ノ 本当にまずい状態だったのならその後の対応も取りやすい.

というわけでその hta スクリプト置いときます
スクリーンショットを撮るのは WinShot を使っているので別途ダウンロードが必要.

2012年9月4日火曜日

久々に鈴鹿サーキット

って 2日ぶりやんけ!
アホやな俺も.

5月にあった鈴鹿サーキット先導車付き体験走行会の拡大版なるものがあって,軽く申し込んでみたらまた当たったw ので行ってきた.
今回は \1,500 で 9周くらい× 2セット.前も書いたけど先導車付きと言いつつスピードは結構出せて,あとコーナーによっちゃ減速~脱出加速と,マジ走りしようと思えばできる (ホントはダメなんだろうけど).

で,まず 1本目.天気が曇りでぎりぎり持つかな,と思ったら,走行開始直後に豪雨(;´д⊂)コースに川ができるくらいの雨で,ウォータースクリーンで 20m 前が見えねぇ.しかも自分の直後の車が某大型バンだったので,突っ込んでこないかそれだけが気になって全然楽しくねぇ orz
どんだけ酷いか車載動画上げたかったけど,「車載動画は YouTube とかに上げたらダメ!」って言われたので,車載静画を載せてみるテスト.直前にセーフティカーがいるんだけど,西ストレートとかフラッシュライトしか見えないw

2本目は,雨は上がってセミウェット.まあ今回のスピードレンジなら問題ない程度に乾いていたので,俄然楽しくなってきた!! と思ったら,まさかの赤旗.某ドイツ車がひっくり返ってた ((((;゚д゚))))ガクガクブルブル
幸いドライバーは無傷のようだったけど,ああ,事故処理でこの走行会もタイムアップかなぁ…,と思ったら,予定を後ろにずらして再開ヽ(´ー`)ノ 2本目の 8周くらいは楽しめた.

あと,SMSC に入ったらエリで本コース走れるかダメ元で係員に聞いてみたら,
・オープンカーはロールケージ必須だが,エリは数年前に,特例で年式によっては走れるようになったはず
・(自分の車見て) これはいけるんじゃないかなぁ? 多分
みたいなこと言ってた.ひょっとしてエキシージと混同されてるのかもしれないけど,マジで入れるんだったら真剣に検討してみよ.

2012年9月3日月曜日

やっぱ車はエンジン音が命

鈴鹿サーキット 50周年アニバーサリーデーに行ってきた.

往年のレースカーとか有名な元・現役レーサーとかいっぱい来てそれだけですごかったけど,なんといっても自分的一番の目玉は マツダ 787B.
4ローターのロータリーサウンドが聞けて,しかもそれがサーキットの全開走行時なんて,この先めったに無いと思う. (何かのイベントで狭いところでエンジンかける程度は,たまにやってるみたいだけど)

しょぼいスマフォの動画撮影でしか残せなかったことだけが心残りだけど,実際に聞いた 4ローターの音は期待通りのチョー素晴らしい高音だった.


あと,いろいろなイベントの合間にカート乗ってきたら,無事 A ライがとれた.

いろいろと満足ヽ(´ー`)ノ

2012年8月27日月曜日

Google sites に twitter ガジェットを貼り付ける

2013/6/30 追記:
twitter のなんかの仕様が変わったらしく,以下の方法はダメになったみたい.
こちらの方法でいけた.

------------
表題通りのことがしたくって,ググレカス先生に聞いてみたけど,先人たちが公開している方法は今現在使えなくなっているみたい.だけどいろいろもがいているうちにできたので,方法を公開しとく.

大筋のやり方は「Twitter の リストウィジェット を、Google サイト にガジェットとして貼り付ける」の通り.
で,ここの「3. Google Gadget Editor によるガジェットの作成」で Hello world をツイッター公式ガジェット作成ページで取得した JavaScript に置換する手順があるけど,ここで一手間加える.

twitter から取得した JavaScript が以下のものだとする.
<script charset="utf-8" src="http://widgets.twimg.com/j/2/widget.js"></script>
<script>
new TWTR.Widget({
   (...省略...)
}).render().setUser('hoge').start();
</script>
結論から言って,これの先頭に書いてある http://widgets.twimg.com/j/2/widget.js のインクルードがうまくいってないっぽいので,直接埋め込んでしまうw
まず http://widgets.twimg.com/j/2/widget.js をダウンロード.そして最初に取得した JavaScript の先頭行を消し,それの <script> の直後の行に,あとからダウンロードした widget.js の内容を全部埋め込んでしまう.
<script>
(... widget.js の内容...)
new TWTR.Widget({
   (...省略...)
}).render().setUser('hoge').start();
</script>
こうしてできた新しい JavaScript 全体を,Hello world と置き換える.
それ以外の手順は上で紹介したサイトのやり方通り.

実際になると,こんなかんじになる.

2012年8月14日火曜日

プログラマ ≠ デザイナ

VSD for GPS を更新しました.
配布ページはこちら

ぱっと見,デザイン的には大して変わっていように見えるけど,今回の目玉は「スキン機能」,つまり画面のデザインを変えられるようになった.

また,スキンの作り方は追々情報公開していく予定なので,好きなようにユーザーがデザインを作れるようになる.

←今までとガラっと雰囲気を変えてみた感じでは,こんなのも作れるようになる.
スキンの実態は JavaScript なので,暇な人は vsd_skins\*.js とか見てくれたら,だいたい雰囲気は掴んでもらえるはず.

で,TrackVision とかみたいに華やかなデザインいっぱい作って公開したかったけど,
俺にそんなデザインセンスは無かった(;´д⊂)
一番上のやつも,適当に光沢出してカーボン柄貼りつけただけだし.

というわけであとはユーザーの皆さんに期待w
デザイン作ってくれる人が現れたら,その情報を配布ページでまとめて公開とかできたらいいなぁ,とか考えてます.

-----
どうでもいいおまけ.
←最初に VSD を公開したときは 14本あったスライダバーが

今や 5本に…w
なぜかバージョンアップするたびに設定項目が削られていく謎.

2012年7月28日土曜日

冷やしデザイン,はじめました ~in 2012夏~

プロジェクト V8 の続き.

で,VSD for GPS に Google V8 を組み込んで結局何がしたかったのかというと,今 VSD の画面デザインはハードコーディングされていてユーザにはいじる余地がないので,画面描画を JavaScript で制御できるようにしておけば,ユーザが自由にデザインを作れて,要はスキン機能のようなものが実現できる.

で,あらかた動き始めたので,テストがてらめっちゃイケてるメーターつくってみたよ!!

シブい…我ながらシブ過ぎちゃうぜ.

ちなみにこの時の JavaScript はこんな感じ.
今までは円とか線とかプログラムで描いてメーター画像を生成してたけど,画像ファイルを読み込めるようにしておけば,かなりデザインの自由度が広がるはず.
var vsd = new Vsd;
var img = new Image( "d:\\dds\\vsd\\vsd_filter\\meter.png" );
var font = new Font( "Impact", 50 );

function Draw(){
    // メーター画像描画
    vsd.PutImage( vsd.Width - img.Width, vsd.Height - img.Height, img );
    
    // メーター針描画
    vsd.DrawNeedle( 981, 613, 130, 150, 30, vsd.Speed / 180, 0xFF0000, 3 );
    
    // 適当に文字列描画
    vsd.DrawString( 920, 650, ~~vsd.Speed, font, 0x00FF00 );
    vsd.DrawString( 200, 300, "hoge fuga piyo", font, 0x00FF00, 0x0000FF );
}

2012年7月22日日曜日

V8 エンジン搭載完了ヽ(´ー`)ノ

Google V8 の「初期化・コンパイル」と「スクリプト実行」の関数スコープを分離する,がうまくいった.ただし正しいやり方なのかどうかは不明(;´д⊂)

まず,クラスを新規に作成し,初期化・コンパイルルーチンである Load() とスクリプト実行ルーチンである Run() に分ける.
Load() で構築されかつ保持しておかなければならないオブジェクトは,メンバ変数に保存しておく.ただし,Script::New() したハンドルは ( Local<> なハンドルなので ) メンバ変数に保持しただけでは×なので,handle_scope.Close( script ) とすることで,現在のハンドルスコープを破棄しつつ script はその上位のハンドルスコープにコピーされる.
あと Run() で Context::Scope context_scope( ... ); でコンテキストに入っているけど,コンパイル時にも何らかのコンテキストに入っておかなければならないらしいので,ダミーで Context::Scope context_scope( ... ); やっている.
一番やばそうなのは,一番最初の v8::HandleScope を関数ローカル変数としてではなくメンバ変数で (すなわち new で) 生成していること.Google のドキュメント
Note: The handle stack is not part of the C++ call stack, but the handle scopes are embedded in the C++ stack. Handle scopes can only be stack-allocated, not allocated with new.
とあるように,HandleScope は new で作ってはいけないのだが,いわば First-new-Last-delete さえ守れば多分大丈夫と自分を信じることにする(笑)

以下はコードの断片.足りない関数とかは v8/samples/shell.cc とかから持ってきてくらさい.
class CScript {
  public:
    CScript( void );
    ~CScript( void );
    
    BOOL Load( char *szFileName );
    BOOL Run( void );
    
  private:
    v8::Persistent<v8::Context> m_context;
    v8::Handle<v8::Script> m_script;
    v8::HandleScope m_handle_scope;
};

/*** print ******************************************************************/

// 関数オブジェクト print の実体 
Handle<Value> Func_print(const Arguments& args) {
  String::AsciiValue str(args[0]);
  DebugMsgD("%s\n", *str);
  return Undefined();
}

/*** コンストラクタ *********************************************************/

CScript::CScript(){
    m_context.Clear();
    m_script.Clear();
}

/*** デストラクタ ***********************************************************/

CScript::~CScript(){
    m_context.Dispose();
}

/*** ロード・コンパイル *****************************************************/

#define SCRIPT_SIZE ( 64 * 1024 )

BOOL CScript::Load( char *szFileName ){
    // 準備
    HandleScope handle_scope;
    
    // グローバルオブジェクトの生成
    Handle<ObjectTemplate> global = ObjectTemplate::New();
    
    global->Set(
        String::New( print ),
        FunctionTemplate::New( Func_name )
    );
    
    // グローバルオブジェクトから環境を生成
    m_context = Context::New( NULL, global );
    
    TryCatch try_catch;
    
    // ダミーのスコープを生成  Script::New するときは
    // 何らかのコンテキストに Enter しておかなければならないらしい
    Context::Scope context_scope( m_context );
    
    char *szBuf = new char[ SCRIPT_SIZE ];
    
    // スクリプト ロード
    FILE *fp;
    if(( fp = fopen( szFileName, "r" )) == NULL ){
        // エラー処理
        return FALSE;
    }
    
    int iReadSize = fread( szBuf, 1, SCRIPT_SIZE, fp );
    fclose( fp );
    szBuf[ iReadSize ] = '\0';
    
    Handle<String> ScriptBody = String::New( szBuf );
    
    delete [] szBuf;
    
    Handle<Script> script = Script::New(
        ScriptBody, String::New( szFileName )
    );
    if( script.IsEmpty()){
        // Print errors that happened during compilation.
        ReportException( &try_catch );
        return false;
    }
    
    m_script = handle_scope.Close( script );
    return TRUE;
}

/*** Run ********************************************************************/

BOOL CScript::Run( void ){
    HandleScope handle_scope;
    TryCatch try_catch;
    
    // 環境からスコープを生成
    Context::Scope context_scope( m_context );
    
    Handle<Value> result = m_script->Run();
    
    if( result.IsEmpty()){
        assert( try_catch.HasCaught());
        // Print errors that happened during execution.
        ReportException( &try_catch );
        return FALSE;
    }else{
        assert( !try_catch.HasCaught());
        if( !result->IsUndefined()) {
            // If all went well and the result wasn't undefined then print
            // the returned value.
            String::Utf8Value str( result );
            const char* cstr = ToCString( str );
            DebugMsgD( "%s\n", cstr );
        }
        return TRUE;
    }
    
    return TRUE;
}

-----
以下自分用メモ
・v8 を shared library でコンパイルするには,gyp の実行時以下のコマンドラインで実行.
third_party\python_26\python build\gyp_v8 -Dcomponent=shared_library

・pdb 不要な形式で作成 (/Z7)
standalone.gypi の 'DebugInformationFormat': '3'→'1',

2012年7月21日土曜日

V8 エンジン搭載

# 以下,「できない」と書いてるのは「ぼくにはとてもできない」の意味

VSD for GPS に Google V8 を搭載することにした.
で,色々なサンプルをみてると,だいたい次のような流れになっている.
main(){
  V8初期化処理;
  スクリプトコンパイル;
  while( ... ){
    スクリプト実行;
  }
}
ここで注意しなければならないのは,V8 の作りとして,初期化・コンパイルで構築されたオブジェクトが生存していることが前提で,すなわち
init(){
  V8初期化処理;
  スクリプトコンパイル;
}

run(){
  スクリプト実行;
}

main(){
  init();
  while( ... ){
    run();
  }
}
みたいなことが単純にはできない.なぜなら,init() を抜けた時点で init() 内で構築されたオブジェクトが破棄されてしまうから.
ちょっと C に詳しい人なら (゚Д゚)ハァ? 何言ってんだコイツは,と思う人がいるかもしれない.でも俺が理解する限り V8 がそうなってるんです.特に HandleScope とかが独自のスタック構造になっていて,init() 内のオブジェクトを生かしたまま init() を抜けるとかができない.

で,ここで問題になってくるのが,VSD は AviUtl のプラグインだということ.大雑把に言ってプラグインとしてユーザが定義するのは 1フレーム分の画像を処理する関数で,1フレーム処理するごとにプラグイン関数を抜けて AviUtl に制御を返してやらなければならない.
ということは,プラグイン関数の中で毎回 初期化・スクリプトコンパイル・スクリプト実行 を行なってやらなければならない.数千フレームある動画をエンコすると数千回コンパイルが起こるわけでwww あほらしすぎる(;´д⊂)

んー,どうしたものか.

2012年7月1日日曜日

Win7 の avisynth DirectShowSource() でハマる

昔入れた WindowsServer2008R2,どうもマルチメディア系の動作が変で使いにくかったので,放置状態だった.で,ひょんなことから Win7 Ultimate を \4,600 で購入www 中国からの通販でもなんか平気になってきた自分…恐ろしい子!

んで,Win7 に本格的に乗り換えようといろいろ設定してたら,avisynth の DirectShowSource() で mp4 を読もうとすると,「Media Player Classic はグラフ中のピンのいくつかを再生できませんでした (云々かんぬん)」で怒られる.
avisynth は 1.5 倍再生とか VSD for GPS とかで多用しているので,これが動かないと痛すぎる.(;´Д⊂)
こういう時はたいてい必要なコーデックが足りてないと怒られるけど,ffdshow + MP4 splitter ちゃんと入れてるけどなぁ.

でいろいろもがいているうちに,なぜか avs 再生した時は ffdshow が使われてなさそうなことがわかった.
Win7 では OS 標準で mp4 デコーダとかを持ってるはずだけど,インストールされている DirectShowFilter のどれを使うかっていう優先度はどこで決めてるんだろ? と思ってたどり着いたのがここ
なるほど,メリット値ってので優先度が決まるのね.で DirectShow Filter Tool で ffdshow の優先度見てみたら,ほぼ最優先じゃん orz

んーと思って,さらにググって見つけたのがここ
ここをみると,Win7 からはメリット値を無視して (!!!) マイクロソフト謹製のデコーダしか使わず,ffdshow とかは使わないらしい.
そう聞くと,MPC で mp4 は問題なく再生できたこと (MPC はメリット値を無視しない) も,avisynth の DirectShowSource() で問題がでたことも,WinServer2008R2 ではこの問題が起こらなかったこと (2008R2 には MS 謹製コーデックは入ってない) も,全てに合点がいく.

で,Win7DSFilterTweaker というツールで Win7 でもデコーダの優先順位を設定できて,avisynth の DirectShowSource() でも無事 ffdshow が使用された.

てか,中途半端なウンコデコーダを強制的に使わせてエラー吐くとか,ヤメテクレ(;´Д⊂)