squirrelはじめました

irrlichtのシーン構築をC++の外部に出す方法を模索中。ノードの位置を変える度に再コンパイルが発生するなど、開発効率が大変よろしくない。はじめはluaでシーン記述をやるつもりだったのだが整数と浮動少数の区別が無いことなどいろいろ気になりだした。そこで、以前から噂に聞いていたsquirrelをやってみることにした。


手始めにirrlichtのExample001 HelloWorldをsquirrelから実行できるようにしてみよう。
まず、
http://irrlicht.sourceforge.net/docu/example001.html
を適当にsquirrelの文法に直した。

と->を.に変更することと、変数型とテンプレート引数の削除以外はそんなに弄ってない。
// 01.HelloWorld.nut

device = irr.createDevice(irr.video.EDT_SOFTWARE,
    irr.dimension2d(640, 480), 16, false, false, false, 0);
if (!device){
  return 1;
}

device.setWindowCaption("Hello World! - Irrlicht Engine Demo");

driver = device.getVideoDriver();
smgr = device.getSceneManager();
guienv = device.getGUIEnvironment();

guienv.addStaticText("Hello World! This is the Irrlicht Software renderer!",
    irr.rect(10,10,260,22), true);

mesh = smgr.getMesh("../../media/sydney.md2");
if(!mesh)
{
  device.drop();
  return 1;
}
node=smgr.addAnimatedMeshSceneNode(mesh);

if (node)
{
  node.setMaterialFlag(irr.video.EMF_LIGHTING, false);
  node.setMD2Animation(irr.scene.EMAT_STAND);
  node.setMaterialTexture( 0, driver.getTexture("../../media/sydney.bmp") );
}                                                                               
smgr.addCameraSceneNode(0,                                                          irr.vector3df(0,30,-40), irr.vector3df(0,5,0));
                                                                                while(device.run())
{
  driver.beginScene(true, true, irr.video.SColor(255,100,101,140));
  smgr.drawAll();
  guienv.drawAll();
  driver.endScene();
}

device.drop();

return 0;

次に上のスクリプトを呼び出すcppアプリを作る。

/// sqirr.exe
#include <stdarg.h>
#include <stdio.h>

#include <squirrel.h>
#include <sqstdio.h>
#include <sqstdaux.h>

#ifdef SQUNICODE
#define scvprintf vwprintf
#else
#define scvprintf vprintf
#endif

void printfunc(HSQUIRRELVM v, const SQChar *s, ...)
{
  va_list arglist;
  va_start(arglist, s);
  scvprintf(s, arglist);
  va_end(arglist);
}

int main(int argc, char* argv[])
{
  if(argc<2){
    printf("usage: %s {script.nut}\n", argv[0]);
    return 1;
  }

  HSQUIRRELVM v = sq_open(1024); // creates a VM with initial stack size 1024

  sqstd_seterrorhandlers(v);

  sq_setprintfunc(v, printfunc); //sets the print function                      
  sq_pushroottable(v); //push the root table(were the globals of the script will be stored)
  if(!SQ_SUCCEEDED(sqstd_dofile(v, _SC(argv[1]), 0, 1))) // also prints syntax errors if any
  {
    // error
  }

  sq_pop(v,1); //pops the root table
  sq_close(v);

  return 0;
}

基本的にはこれ。
http://wiki.squirrel-lang.org/default.aspx/SquirrelWiki/EmbeddingGettingStarted.html
第1引数を実行するように変えた。
とりあえずコンパイルして実行してみる。

> debug\sqirr.exe 01.HelloWorld.nut

AN ERROR HAS OCCURED [the index 'irr' does not exist]

CALLSTACK
*FUNCTION [main()] 01.HelloWorld.nut line [5]

LOCALS
[this] TABLE

順調にエラー発生。これからirrlichtの要素をエクスポートする作業に入る。