今日も気づいたら夜

技術メモとか。Civ:BEのMOD作成についてとか。

Sqratとの連携

少し前にSquirrelのラッパであるSqratのバージョンが0.8.92になり、Unicode対応になった。
しかし、どうしたことか、私の環境ではうまく動かなかった。
今回、いろいろ弄ってみて何とかうまくいった。
今後のメモのため、Sqrat導入時のサンプルコードを載せておく。なお、Squirrelは最新3.0.6を利用した。

#include <iostream>
#include <cstdarg>
#include <tchar.h>

#include <sqrat.h>

using namespace Sqrat;

#ifdef UNICODE

#define tvprintf vwprintf_s
#define tvsprintf _vsnwprintf_s
#define tprintf wprintf_s
#else
#define tvprintf vprintf_s
#define tvsprintf vsnprintf_s
#define tprintf printf_s
#endif

void SQ_PrintFunc(HSQUIRRELVM sqvm, const SQChar* str, ...)
{
	//可変長引数を受け取る変数
	va_list args;

	//可変長引数を受け取る
	va_start(args, str);

	//スクリプト内に"\n"を含める必要がないパターン。その代わり出力する文字数に制限がある
	/*
	SQChar buf[512];
	tvsprintf(buf, 512, str, args);
	tprintf(_T("%s\n"), buf);
	*/

	//スクリプト内に"\n"を含める必要があるパターン。その代わり出力する文字数に制限はない
	tvprintf(str, args);

	//可変長引数の使用後処理
	va_end(args);
}


int main() {
	//マルチバイト環境下、UNICODE環境下で正しく文字を表示する
	_tsetlocale(LC_ALL, _T("Japanese_Japan.932"));

	//仮想マシンの作成
	SQVM* sqvm = sq_open(1024);

	//標準エラーハンドラをセット
	sqstd_seterrorhandlers(sqvm);

	//print出力用関数をセット
	sq_setprintfunc(sqvm, SQ_PrintFunc, SQ_PrintFunc);

	//Sqratライブラリのクラスが破棄されるとき、vmを利用しているため、sq_closeする前にSqratライブラリのクラスを破棄する必要がある
	{
		DefaultVM().Set(sqvm);

		Script script;
#ifndef UNICODE
		//SJIS形式のソースコード
		script.CompileFile(_T("test_s.nut"));
#else
		//UNICODE形式のソースコード
		script.CompileFile(_T("test_u.nut"));
#endif

		script.Run();
	}

	sq_close(sqvm);
}

注意点としては、コンソールにUNICODEを出力するためにはsetlocaleしなくてはいけないこと、Sqratライブラリのクラスを利用した場合はsq_closeする前に破棄することである。
なお、配布されているSquirrelはそのままだとSJISに対応していないので、そのあたりはほかの方のブログを参照。