fslashtのサアラたん日記

ドール写真アルバム
トリップ:WMfSLASHTY
主なカテゴリ:
[お人形(あるいは法廷)]:[sahra]サアラたん/[lycee]リセたん/[maya]マヤっち/[mokochan]もこちゃん
[メイド喫茶(あるいはパテント)]/[maid]
[プログラミング]:[lua]/[proce55ing]  マイコン:[USBSPYDER08]/[MXSDVK]

slashdot.jpでの日記はこちらです。サイトはこちらです。(簡易投稿フォーム,転記処理)
1000 | 01 |
2001 | 01 | 06 |
2003 | 11 | 12 |
2004 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2007 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2009 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2011 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 |
2012 | 02 | 03 | 04 | 05 | 06 | 12 |
2013 | 01 | 04 | 05 |
2014 | 03 | 04 | 05 |
2015 | 11 |
2018 | 02 |

2004-05-09

[][][][] SDLオフ会のネタ作成中 02:39

STATUS: 故障

 SDLオフ会のネタ作成中。
 今日の12:00集合だから、あと9時間くらいしかないよ〜
 で、いま必要なライブラリが揃ったという感じ、ゲームはこれから作るのだ。きっと開発効率が最強に強まったライブラリ群をバリバリ使ってあっという間に完成ですよ(妄想)

 Lua操作クラスでコルーチンを簡単に利用できるようにしました。
 ライブラリ群はゲームが完成したら、いっしょに公開します。

● 利用例
        FTEzLua lua( "test1.lua" , FTEzLua::LIB_BASE , this );
        FTEzLua luaCo = lua.NewThread("co_func");

        lua.SetGlobalVar("g",(FTEzLuaValue)0 );
        int n = 1;
        while (luaCo.Resume( FTEzLuaValue(n) ) == 0) {
                FTEzLuaValue lv = luaCo.GetResumeResult();
                lv.Dump();
                n*=2;
        }
        TRACE("g=%d\n", (int)lua.GetGlobalVar("g") );

● luaスクリプト (test1.lua)
function co_func()
        n=999;
        for i=0,10 do
                n = coroutine.yield(i,n)
                g=g+n
        end
end

● 実行結果
0:999 1:0
0:2 1:1
0:4 1:2
0:8 1:3
0:16 1:4
0:32 1:5
0:64 1:6
0:128 1:7
0:256 1:8
0:512 1:9
0:1024 1:10
0:(none)
g=4094

コメント
【転記元】fslasht の slashdot.jp日記「[SDL

2004-05-06

fslasht2004-05-06

[][][] Lua操作クラスが出来てきた 23:56

STATUS: 故障

● FTEzLua利用サンプルイメージ
/*
 開発中の Lua 操作クラス「FTEzLua」の使用例
 けっこうMFCべったり
*/

#include "stdafx.h"
#include "FTEzLua.h"

class MyClass {
public:
    // テスト関数
    void Start() {
        FTEzLua    lua;    // Luaクラスインスタンス

        lua.Open();        // Open (lua_open();と同等)
        ASSERT( lua.IsValid() );
        lua.LoadScriptFile("test.lua");        // スクリプトファイルをロード
        lua.LibOpen( FTEzLuaValue::LIB_BASE | FTEzLuaValue::LIB_MATH );    // 使用ライブラリを指定してOpen
        lua.SetThis( this );    // thisポインタをセット (コールバック関数で取得するため)

        lua.RegistFunc( "MyFunc" , MyFunc );    // コールバック関数登録

        // スクリプト中の関数(LuaFuncを呼び出し。戻り値は FTEzLuaValue(複数値保持可能)に)
        FTEzLuaValue lv = lua.CallFunc( "LuaFunc",2,2, FTEzLuaValue(123),FTEzLuaValue("ABC") );
        TRACE("Result1=%d / Reault2=%s\n",(int)lv[0],(LPCSTR)lv[1] ):

        // 新しいスレッドを生成( co_func関数を開始する )
        FTEzLua lua2 = lua.NewThread("co_func");

        FTEzLuaValue lv2;
        while ( (lv2=lua2.Resume(1, FTEzLuaValue(123))).IsValid() ) {    // スレッドを実行
            // 実行結果が有効だった場合はスレッド継続
            TRACE("Result1=%dx\n",(int)lv2 ):
        }

        lua2.Close();  // クローズ
        lua1.Close();
    }

    // コールバック関数
    static void MyFunc( lua_State *L ) {
        FTEzLua lua( L );    // Attach
        MyClass* p = lua.GetThis();        // Thisポインタを取得
        int x = lua.GetParam(1);        // 関数パラメータ1取得 (lua_tonumber( L, 1 );と同等)
        int y = lua.GetParam(2);        // 関数パラメータ2取得 (lua_tonumber( L, 2 );と同等)

        int r = p->Calc(x,y);            // thisポインタを利用して非staticメンバ関数をコール

        lua.AddParam( FTEzLuaValue(r) );                // 戻り値を設定 ( lua_pushnumber( L , r );と同等 )
    }

    // 非staticメンバ関数
    int Calc( int x,int y) {           
        return x * y;
    }
}

● FTEzLuaValue利用サンプルイメージ
/*
 「FTEzLua」で使用する値管理クラス「FTEzLuaValue」の使用例
 関数の戻り値が複数になることに対応するため、Array的な使い方ができる。
*/

    FTEzLuaValue lv(128);
    FTEzLuaValue lv2("ABC");
    FTEzLuaValue lv3(lv2);

    double d = lv;
    CString str = lv2;
    int n = lv2;
    TRACE("d=%f n=%d str=%s\n",d,n,str); // 出力:d=128.000000 n=0 str=ABC

    TRACE("lv3=%d\n",(int)lv3);    // 出力:lv3=0
    TRACE("lv3=%s\n",(LPCSTR)lv3); // 出力:lv3=ABC
   
    lv3.Add(  FTEzLuaValue("ADDED") );
    lv3.Add(  FTEzLuaValue(9876)  );
    lv3.Add(  FTEzLuaValue("LAST")  );
    lv3.Dump();  // 出力:0:ABC 1:ADDED 2:9876.000000 3:LAST

    lv3[2]=4567;
    lv3.Dump();  // 出力:0:ABC 1:ADDED 2:4567.000000 3:LAST

    TRACE("lv3[2]=%d lv3.count=%d\n",(int)lv3[2] , lv3.Count() ); // 出力:lv3[2]=4567 lv3.count=4

    FTEzLuaValue lv4;
    lv4=lv3;
    lv4.Dump(); // 出力:0:ABC 1:ADDED 2:4567.000000 3:LAST

    FTEzLuaValue lv5 = FTEzLuaValue( "dsfdvs",0,  123,"ZZZ",1.01,999,lv4,"END");    // 複数の値で初期化 引数(フォーマット,ダミー, 値1,値2 ... )、フォーマット(d=int f=double s=LPCSTR v=FTEzLuaValue)
    lv5.Dump(); // 出力:1:123.000000 2:ZZZ 3:1.010000 4:999.000000 5:ABC 6:ADDED 7:4567.000000 8:LAST 9:END

コメント
【転記元】fslasht の slashdot.jp日記「[lua

2004-05-04

fslasht2004-05-04

[][][] LuaのVC用libファイルはCaLuaからGET? 17:55

STATUS: 故障中 / 0.884 [fslasht kg]

(この日記の結論:VC6ではこのままでは駄目、VC7では多分大丈夫そう)

 LuaのVisualC++用のlibファイル公式サイトに置いてないので、以前の日記に書いたように「VisualCから使う方法 」 (みはえる氏のwiki)のページからダウンロードしたファイルをいじって使ってました。
 ところが、今日CaLuaライブラリアーカイブをみたらまるごとLuaのlibファイルが入ってました。
 これそのまま使えたらいいな〜

 VisualC++6.0のプロジェクトのフォルダの中に「lua」フォルダを作ってその中に、CaLua内の「lib」「include」フォルダをコピーしました。
 自分のプログラムのヘッダに以下のコードを追加。

extern "C" {
#include "Lua/include/lua.h"
#include "Lua/include/lualib.h"
#include "Lua/include/lauxlib.h"
};

 プロジェクトの設定で、「リンク」タブの「オブジェクト/ライブラリ モジュール」欄の以下のライブラリを追加

lua/lib/lua50.lib lua/lib/lualib.lib

 とりあえず、ソースにLuaのコードを追加。

lua_State *m_pLua;
m_pLua = lua_open();

 それではビルド!

リンク中...
LINK : warning LNK4098: defaultlib "MSVCRT" は他のライブラリの使用と競合しています; /NODEFAULTLIB:library を使用してください
lua50.lib(llex.obj) : error LNK2001: 外部シンボル "___security_cookie" は未解決です
lua50.lib(ldo.obj) : error LNK2001: 外部シンボル "___security_cookie" は未解決です
lua50.lib(ldebug.obj) : error LNK2001: 外部シンボル "___security_cookie" は未解決です
lua50.lib(lvm.obj) : error LNK2001: 外部シンボル "___security_cookie" は未解決です
lua50.lib(llex.obj) : error LNK2001: 外部シンボル "@__security_check_cookie@4" は未解決です
lua50.lib(ldo.obj) : error LNK2001: 外部シンボル "@__security_check_cookie@4" は未解決です
lua50.lib(ldebug.obj) : error LNK2001: 外部シンボル "@__security_check_cookie@4" は未解決です
lua50.lib(lvm.obj) : error LNK2001: 外部シンボル "@__security_check_cookie@4" は未解決です
lua50.lib(ltable.obj) : error LNK2001: 外部シンボル "__ftol2" は未解決です
lua50.lib(lundump.obj) : error LNK2001: 外部シンボル "__ftol2" は未解決です
lua50.lib(lcode.obj) : error LNK2001: 外部シンボル "__ftol2" は未解決です
Debug/testFTEzLuaClass.exe : fatal error LNK1120: 外部参照 3 が未解決です。
link.exe の実行エラー

 コンパイルは通りましたが、リンクに失敗してしました。
 「___security_cookie」って何〜? あと、「__ftol2」?

 ___security_cookieと__ftol2でぐぐったら、これについて書いてあるページ「ObjectARX Programming Tips (Main)」を見つけました。

 それによると…

● ___security_cookie

 VC7(=VC.net)から搭載された新機能で、バッファーオーバーランとかを防ぐための機能らしい。
 VC6でもリンクできるライブラリを作るときは、プロジェクトの設定の「C/C++->Code Generation. Change the setting for 'Buffer Security Check'」を'No'にする必要があるとのこと。
 …ということは、いまここにある lib ファイルはそのままでは使えないのか。ガーン
 CaLua自体のプロジェクト自体、VC7でビルドしているっぽい(プロジェクトファイルが、.slnだ)ので、いまどきVC6あたりで開発しているのが悪いのかなあ。

● __ftol2

 VC6のC libには含まれていない関数
 VC7のプロジェクトではこんな感じに書いておけばよいとのこと

#if (_MSC_VER >= 1300) && (WINVER < 0x0500)
//VC7 or later, building with pre-VC7 runtime libraries
extern "C" long _ftol( double ); //defined by VC6 C libs
extern "C" long _ftol2( double dblSource ) { return _ftol( dblSource ); }
#endif

 VC6で使うときも、
extern "C" long _ftol( double ); //defined by VC6 C libs
extern "C" long _ftol2( double dblSource ) { return _ftol( dblSource ); }
だけ書いておけばいいのかなあ。どうせ、luaのなかではこの関数使ってないだろうし。

【結論】
 そういうわけで、Luaのlibファイルをそのまま持ってきて使っちゃおう作戦は失敗でした(VC6では)。
 VC7で使う場合は、そのまま使えると思うので、これ(CaLua同梱のLib)使えばいいんじゃないでしょうか。

コメント
【転記元】fslasht の slashdot.jp日記「[lua

[][][] LuaのVC用libファイルはCaLuaからGET? (2)もうひと手間かけろよ編 18:38

STATUS: 故障

 CaLuaライブラリのアーカイブに含まれている Lua フォルダ内のプロジェクトをVC6でビルドしたらそのまま使えました。なんだ〜

 Luaフォルダ内の、lua50.dsp と lualib.dsp をVC6の DeveloperStudio にドロップして、それぞれビルドすると、VC6でも使えるlibファイルが ../lib/ フォルダ内に出来ています。何も設定変更する必要無し、簡単。

 ところで、Luaを組み込んだプログラムでは著作権表示とかどうすればいいのかな。
 ライセンスについてのページによると、MITライセンスらしい。
 で、結局どうすればいいのかな。
 バイナリ配布の場合は、ライセンスのページにある文章を「Lua 5.0 license.txt」とかテキストファイルとして一緒にアーカイブに入れておけばいいのかなあ。

コメント
【転記元】fslasht の slashdot.jp日記「[lua

2004-05-02 ミアカフェに行ってきました

m.i.a. cafeに行ってきました

[][][] C++メンバ関数をコールバック関数とする場合の妄想的改善案 09:58

STATUS: 故障

 C++クラスのメンバ関数をコールバック関数とする場合、そのメンバ関数をstatic関数にして、コールバック時にthisポインタを渡してもらいます。

【参考URL】
コールバック関数をクラスのメンバとするには?
MFC でコールバック関数を使う

 さて、lua言語を組み込んで独自機能を追加する場合、関数ポインタを設定してコールバック的に呼び出してもらうわけですが、この場合もthisポインタを返してもらう必要があります。
 でもluaスクリプト内で、thisポインタを扱わせるのは危なっかしいです。値を間違ったり省略したら即落ちますし、スクリプト中でいちいちthisポインタ渡すのがめんどくさい。
 コールバック関数内で、thisポインタの有効性をチェックしたり、ポインタの変わりにIDか何かを使ってもいいのですが、パフォーマンスが心配です。

● 改善案

 thisポインタをセットしてからコールバック関数を呼び出す(マシン語)コードを生成して、そのコードへのポインタをコールバック関数として設定すれば、よいのではないかと考えました。
 以下の、CallbackHelperクラスでは、上記の処理を実装したものです(ただし、C++もどきなテケトーコードです)。
 使用例では、lua_register関数の第3引数として、メンバ関数MyFuncをコールバック関数として登録しています。
 コールバック関数が呼ばれる際は、thisポインタもちゃんと渡されるため、static関数にする必要はありません。便利〜。
 登録するコールバック関数の数だけCallbackHelperのインスタンスが必要になりますが、1個10byteそこらなので問題ないでしょう。

【コールバックヘルパクラス】(概念的なソース)

class CallbackHelper {
        BYTE byteCode[10];
        void* Create( void *pThis , void* pfCallback ) {
                // コールバック関数にthisポインタを渡すコードを生成する

                // thisポインタを設定(ecxレジスタと仮定 コンパイラ依存)
                byteCode[0] = 0xb9; // mov ecx,pThis
                byteCode[1 .. 4] = pThis;

                // 本来のコールバック関数ジャンプ
                byteCode[5] = 0x0f; // jp pfCallback
                byteCode[6 .. 9] = pfCallback;

                return byteCode;
        }
};

【使用例】

class MyClass {
        CallbackHelper ch;
        lua_Statech *m_pLua;

        MyClass() {
                m_pLua = lua_open();
                lua_baselibopen(m_pLua);
                lua_register( m_pLua, "MyFunc",ch.Create(this,MyFunc) ); // ココでコールバック関数を登録
                // 以下略
        }

        int MyFunc( lua_State *L ); // コールバック関数
};

● 改善案の問題点

・データ領域でコードを実行するので、WinXPの新しいSPでは動かないかも
・ヘルパクラスで生成するコードがコンパイラ依存
・そもそもこれ動くのか?
・luaの場合は、適当な(luaスクリプト内の)グローバル変数にでもthisポインタを突っ込んでおいてコールバック関数(static)内で勝手取得して使えば良いということに気づいてしまった…
・lua_State自体にthisポインタを指定できたら便利だな(実は出来たりして)

コメント
【転記元】fslasht の slashdot.jp日記「[lua

2004-03-22

赤く塗れにLuaを組み込んだ

[][][] 「赤く塗れ」にlua言語を組み込んでみました 10:39

STATUS: 故障

 luaだいぶわかってきましたよ。
 以前作ったゲーム赤く塗れにlua言語を組み込んでみました。

 lua test with Akakunure (Windows用)

 プログラムを起動すると、同じディレクトリにある luaスクリプトファイルtest.lua」を読み込んで実行します。
 赤い線を引いたりしているのは、このスクリプトからゲーム本体のルーチンを呼び出して実現しています。
 また、コルーチンを使って協調型マルチスレッドみたいな感じで動いてます。
 スクリプト中の yieldで時々ゲーム本体側に処理を戻しています。そのため、画面を徐々に暗くする処理やマウスで線を書くという本体側の機能も平行して実行されています。
 yield命令さえいれとけばいいので、ほとんど逐次処理でかけるので無茶苦茶楽です。

 test.luaを書き換えると処理の内容を変更できますので試してみてください。
 LineByLua関数が独自に追加したもので、次のような仕様です。

書式:LineByLua( x1 , y1 , x2 , y2 )
説明:座標(x1,y1)から(x2,y2)まで赤い線をひきます。
   (画面のサイズは、400x400dotです)

 また、coroutine.yield() で処理を戻すときに、文字列をパラメータで渡すと、その内容が画面に表示されます。

サンプル


function co_draw()
        for i=0,400,5 do
                LineByLua(i,0,400-i,400);
                coroutine.yield("loop:" .. i )
        end
end


 うーん簡単簡単。
 corewarsとかカルネージハートみたいなプログラム同士を戦わせるゲームとかも結構簡単に作れるんじゃないかな。(FM-7にタンクバトルなやつがあったけど、なんてゲームがったかな)
 yieldで返ってくるのを期待していると不正しまくりなので、コードの実行ステップごとにhookいれるようにすればよさそう。
 昔スタック型言語でっちあげて作ろうとしたなあ>プログラムバトルなゲーム
 lua使ってなんか作ってみようか。

コメント
【転記元】fslasht の slashdot.jp日記「[lua

2004-03-20

[][][] VisualC++から使ってみよう 05:08

STATUS: 故障

 とりあえずサンプルぐらいは自前でコンパイルしないと、ということでVisaulC++(6.0)用に環境を作ってみました。
 これは自分の間抜けさもあって、さんざんはまって泣きそうでしたが、わかってしまえば簡単なことでした。
( extern "C" を書き忘れてリンクできなかった。それに気づかず、いろんなところからlibとか持ってきたり、ビルドしなおしてみたりおおハマリ。ライブラリのヘッダに extern "C" くらい書いておいてよ〜 )

【環境とか】
コンパイラ: VisualC++6.0
OS: Windows2000
lua: version 5.0

● Luaのlibファイルをそろえる

 環境作成にあたり参考にしたサイトは、VisualCから使う方法 (みはえる氏のwiki) です。
 このページの「Lua5_miha2.lzh」をダウンロードしてきて展開してください。

 Lua5/Debug/Lua5.lib …(1)
 このファイルはそのまま使えます。(ReleaseBuildではうまくいかなかったので、DebugBuildだそうです)
 あと、「LibLua.lib」と「LibLuaLib.lib」が足りないので、VCを起動してビルドします。
 Lua5/Lua.dsw をDeveloperStudioで開いてください。
 ClassViewに「LibLua+CRT.libクラス」と「LibLuaLib+CRT.libクラス」がありますので、それぞれビルドしてください。
 ビルド(Debug)すると次のファイルが生成されます。
 Lua5/dbin/LibLua+CRT.lib …(2)
 Lua5/dbin/LibLuaLib+CRT.lib …(3)

 その他必要なヘッダファイルは次の3つです。
 Lua5/include/lua.h …(4)
 Lua5/include/LibLua.h …(5)
 Lua5/include/LibLuaLib.h …(6)

 以上で、必要なファイルがそろいました。
(公式サイトに各コンパイラ用にコンパイル済みの libファイル置いておいてくれたらいいのに…)

● サンプルプログラムを入力

 DeveloperStudioのAppWizardでプロジェクトを作ります。
 とりあえずコンソールアプリ(Win32 Console Application)にします。
 プロジェクト名は「testLua1」とします。
 アプリケーションの種類は「"Hello, World!"アプリケーション(W)」とします。
 これでプロジェクトが出来ました。

 プロジェクトのフォルダに、「lua」というフォルダを掘って、その中にlibファイルとして準備した(1)〜(6)のファイルをコピーします。
 (1)〜(6)のファイルをプロジェクトに追加します。

 testLua1.cpp に、みはえる氏のサイトの「最小限のテスト」のサンプルコードを入力(コピー)します。
 このままでは以下の理由で動きません。
ライブラリ、ヘッドのフォルダ位置が違う
・みはえる氏のサンプルは、C言語用だが、いまの手順で作っているのはC++(拡張子がCPPなので)用なので、extern "C"宣言が必要。

「int _tmain(int argc, _TCHAR* argv[])」の行までは以下のように変更してください。

#include "stdafx.h"

extern "C" {
#include "Lua/lua.h"
#include "Lua/lualib.h"
#include "Lua/lauxlib.h"
};

int main(int argc, char* argv[])

※ このあとは元のソースのまま

 あと、みはえる氏のページにあるようにファイルtest.lua」をプロジェクトのフォルダに作ります。
 このファイルがこれから実行するluaスクリプトです。
(このファイルがないと、lua_call関数を呼び出した時点でいきなりプログラムが終了してしまいます。)

 これで準備完了です。
 あとは、F5キー(実行)で実行されます。
 画面には luaスクリプトの実行結果である「35.0000」が表示されるはずです。

 ふぅやっと動いた。

# この蛇足気味の解説はいったい誰に向かって描いているんだろう…

コメント
【転記元】fslasht の slashdot.jp日記「[lua

[][][] memo 10:16

STATUS: 故障

 マニュアル読みながら luaいじってました。
 以下メモ。

        lua_pushstring(L, "foobar");
        lua_gettable(L, LUA_GLOBALSINDEX);

        lua_getglobal(L,"foobar");
は等価。lua_getglobalは、マクロ。

 lua_getglobalの処理は、スタックトップにある文字列を(関数や変数の)シンボル名とみなして(関数や変数を保持している?)グローバルテーブルからポインタを持ってきてスタックに積むという動作なのかな?

APIの一覧はLua - APIが便利。

 各サイトのサンプルでは、luaの関数をcallした戻り値を取得するために lua_tonumber(L, 1) としている。
 スタックの絶対位置「1」を指定しているが、lua_tonumber(L, -1)としてスタックトップからの相対位置で値を取ったほうが安全なのでは?

 lua_tonumber関数ではスタックの指定位置の値を読むだけでpopはされない。

 スタック操作の関数名に混乱。forth見たいな関数名だったらよかったのに。popすらマクロ。

 挙動を調べる
 printf("statck top:%d\n" , lua_gettop(L) );
をあちこちに埋め込んで、スタックの数(スタックトップのインデックス)を調べる。

スタックの内容を表示するテスト関数
void printstack( lua_State *L ) {
        for ( int i=1; i<=lua_gettop(L); i++ ) printf("%d ",(int)lua_tonumber(L,i));
        printf("*\n");
}

値の型表示付
void printstack( lua_State *L ) {
        for ( int i=1; i<=lua_gettop(L); i++ )
                printf("%s:%d ", lua_typename( L , lua_type(L,i)) ,(int)lua_tonumber(L,i));
        printf("*\n");
}

 ハンガリアン記法信者としては、サンプル中の L は、pL とかにしたい。

 スレッドの作り方は読んだ。
 lua_yield関数の使いどころがよくわからない。
 luaスクリプト内で yeieldされて戻ってきたときに、lua_resume しないでlua_yieldするとスレッドが終了するのかな?

コメント
【転記元】fslasht の slashdot.jp日記「[lua

青い鴉青い鴉 2006/10/08 12:48 テスト関数使わせてもらいました。thx!

2004-03-19

[][][] 組み込み用スクリプト言語「lua」を使ってみよう 23:52

STATUS: 故障

 年初に参加してSDLのオフ会(新年会)で、shinichiro.h氏がシューティングゲームで敵の移動などは、スクリプト言語で記述しているという話をされていました。
 敵の動きや弾幕の生成をいちいちアプリ本体内にプログラムで書いていたのでは生産性が悪いということですね。
 白い弾幕くんでは、スクリプトとして lua、弾幕生成には BulletML(ABA氏の弾幕記述言語)を使用しているとのことでした。
 オフ会でみせてもらったシューティングゲームでは、スクリプト言語として lua ではなくて、ioという言語を使っているそうです。
 なんか知らない言語がいっぱい出てきた(アプリ本体はD言語だし)のも印象的でしたが、スクリプト言語によってアルゴリズムを外部に追い出すとことによる生産性に魅力を感じました。なにより組み込みスクリプトというのがなんだかカッコイイじゃないですか。

 その後、オフ会では ruby の話になり、そのなかで関数(メソッド?)へのパラメータとしてプログラムコード(ブロック)自体を渡すことができ、呼び出された関数内でそのコードを実行できるという話を聞きました。
 呼び出しもとで渡すコードを自由に指定できるので、関数がとてつもなく柔軟に使えそうです。すげー。
 でも Cとかでも、luaみたいな組み込みスクリプト言語を利用すれば似たようなことが出来そうです。

● luaを手軽に体験してみよう

 というようなことで、組み込みスクリプトの活用を妄想して萌えてましたが、いまいちとっかかりがつかめず、全然取りかかれませんでした。
 が、いいサイト見つけました。

Luaでスクリプトを埋め込んでみよう (2004/1/29) (RYOKO日記)

 先日USBメモリの件で書いた、RYOKO日記での記事でとても分かりやすいサンプルがありました。
 とりあえずサンプルプログラムをダウンロードして実行してみましょう。
 サンプルプログラムは、luaスクリプト実行環境が埋め込まれていて、テキストボックスに入力したluaのスクリプトを実行できます。(実行結果の変数内容を見ることができる)
 また、luaスクリプトからサンプルプログラム内の一部機能(グラフィック描画機能)にアクセスできるので、luaで絵を描くようなスクリプトを書くと結果が視覚的でわかりやすいです。
 とにかくサンプル動かしてみよう。

 luaの言語仕様は「Lua言語の手引き」を最初に読むといいと思います。
 CのようなPascalのような。テーブル型が柔軟で強力です。あと関数が複数の値を返せます。メモリ管理はGCです。

 サンプルのなかでは、luaから呼び出しもとのプログラムの機能を呼び出しています。
 これはどうやっているのかというと、luaスクリプトを実行する前に、luaインタプリタにユーザーの関数を登録しているのです。
 (以下「RYOKO日記」のコードを引用)
 RYOKO日記の例では

lua_register( L, "pixelput", pixelput );

とあり、これは呼び出し元のプログラム(c言語)中の、「pixelput」という関数をlua側で「pixelput」という関数として使えるよう登録しています。
(pixelputは、指定座標に指定色の点を描く関数)
 lua側からはこのように呼び出します。

for i = 10,89 do
    for j = 10,89 do
        pixelput( i,j, 255 )
    end
end

 こんな感じで、簡単にスクリプトの機能を拡張できます。
 ゲームで使うときは、たとえば敵の出現関数とかをluaから呼び出せるようにしておけば、敵出現パターンをlauスクリプトで制御できますね。

 luaスクリプトは、通常は呼び出すと処理が完了するまで戻ってきませんが、スクリプト中にyield関数を入れておくと、その場所で一旦呼び出しもとに処理を戻しますので、必要なところにyieldいれておけば、逐次処理するようにとても素直なコード書けます。素晴らしい。はぁはぁ

● luaリンク

 とりあえず日本語で書かれているページをかたっぱしから読みました。

公式サイト (英文)

(解説/翻訳)
プログラミング言語Luaの紹介
Lua言語の手引き
プログラミング言語 Lua 5.0 リファレンスマニュアル
FAQ
(RYOKO日記) 解説、lua動作させるサンプル
ioと比較 (shinichiro.h氏)
D言語からlua (やねうらお氏)
VisualCから使う方法 (みはえる氏のwiki)
日本語パッチ

Programming in Lua の pdf (英文)

(2chのスレ)
プログラミング言語 Lua
 ※ 513 の弾幕シューティングが凄い
プログラミング言語 Lua  その2

(CaLua) luaの呼び出しを簡単にするラッパーのプロジェクト
sourceforgeでのCaLuaプロジェクト
日本語での紹介

コメント
【転記元】fslasht の slashdot.jp日記「[lua

junchanjunchan 2004/03/20 00:39 やぁこれは凄まじく萌える話題ですね。巨大なボスキャラもこれで作れまつか?

fslashtfslasht 2004/03/20 01:10 もうluaに夢中っすよ。ボスキャラの攻撃パターンもluaで書けます。というか書くべきだ。あと、lua むちゃくちゃ速い。上の例のpixelput呼び出し10000回ループで15msしかかからなかった(@Pen4 3.06GHz)。

junchanjunchan 2004/03/20 01:43 うーん、なかなかいいですね。2chのスレとかとりあえず全部じゃないけどいくつかサイトを見てきました。効率良くゲームを開発するには組み込み言語という選択もありなのか。うーむ。 何気にPHPの拡張言語としてほげほげとか(ぉぃ

shinichiro_hshinichiro_h 2004/03/20 02:07 I-Saint氏がほどよい長さの素晴しいチュートリアルを書かれてますのでご紹介。http://i-saint.abz.jp/2004.html#2004/2/19 あ、あとボスに関してはむしろザコとかで単純な動きをするものなんかはスクリプトよりもデータドリブン的なものの方が良いかと思います。同じく I-Saint氏がそういったことも書かれています。 http://i-saint.abz.jp/2004.html#2004/1/27

fslashtfslasht 2004/03/20 05:17 shinichiro_h様コメントありがとうございます(SDL新年会のときはいろいろ教えてもらいありがとうございました)。 I-Saint氏のサイトとてもわかりやすいです。なんで見落としていたんだろう。extern ”C” についても言及もある…

キミのこと忘れない。
counter: (since:2004/07/16) , profile
リング: