今日も気づいたら夜

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

Civ:BE ModBuddy導入

steamでCiv:BE SDKをインストールをしたがうまくいかなかったのでその時の修正方法のメモ。

※下記を実行して不利益が発生しても筆者は一切責任を取りません。


0. MOD/MODの作り方 - Civ5 Wikiを見ながら導入。


1. Civ:BE SDKをインストール
「ライブラリ」→「ツール」から「Sid Meier's Civilization: Beyond Earth SDK」を右クリックし、インストール。


2.Civ:BE SDKからModBuddyを起動
途中でVS2010Shellをインストール。そして起動。

f:id:fallinsky:20141105205715p:plain

エラーが出て先に進めない。
仕方がないので「ModBuddy\StartPage」にあるStartPage.xamlの該当箇所をコメントアウト


3.ModBuddyを再び起動、そしてビルド
今度はうまくいった。
しかしサンプルを開いてビルドしようとすると「(インストールディスク):\Program Files (x86)\MSBuild\Firaxis\Modbuddy\CivBEMod.targets」が見つかりませんと言われる。

「ModBuddy\Build」にあるCivBEMod.targetsを指示のあった場所にコピー。念のため同じフォルダにある他のファイルもコピー。


4.ModBuddyをビルド、ビルド、ビルド
サンプルを開いて再びビルド。
今度は「CivBEPath」を設定してくださいと言われる。
いろいろ調べて、「ツール」→「オプション」からオプションを開き、「Civilization Beyond Earth」を選択して、上にゲームへのパスを、下にマイドキュメントにあるゲームデータへのパスを指定する。

f:id:fallinsky:20141105212025p:plain

「OK」を押して設定終了。あとはビルド。今度はうまくいってマイドキュメントの方に追加されている。
ゲームを起動して、「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に対応していないので、そのあたりはほかの方のブログを参照。

emacsのsquirrel-modeを作ってみた

squirrelを書こうとしているがどうやらemacssquirrel-modeはないみたいだったので自作した。

とは言ってもc++-modeの派生モードとして作っただけ。一応キーワードを色づけしたが正直言って微妙なレベル。しかし自動インデントが使えるのはうれしい。


init.elもしくは.emacsに以下の内容を記述。

;; my-sq-mode.elの遅延読み込み
(autoload 'squirrel-mode "squirrel-mode" nil t)
;; .nutファイルが読み込まれたときはmy-sq-modeにする
(add-to-list 'auto-mode-alist '("\\.nut$" . squirrel-mode))


以下の内容をsquirrel-mode.elとして保存。

;;squirrel-modeに関する設定
(defvar squirrel-font-lock-defaults
  (list
    'squirrel-font-lock-keywords
    nil
    nil
    ))

;;ハイライトするキーワードの定義
(defconst squirrel-font-lock-keywords
  '(
    ("\\<\\(local\\)[ \t]+\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>" (1 font-lock-keyword-face) (2 font-lock-variable-name-face))
    ("\\<\\(const\\|static\\)[ \t]+\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>" (1 font-lock-keyword-face) (2 font-lock-constant-face))
    ("\\<\\(enum\\)[ \t]+\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>" (1 font-lock-keyword-face) (2 font-lock-constant-face))
    ("\\<\\(function\\|class\\)\\>" (1 font-lock-keyword-face))
    ("\\<function[ \t]+\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>" (1 font-lock-function-name-face))
    ("\\<class[ \t]+\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>" (1 font-lock-type-face))
    ("\\<\\(constructor\\)\\>" (0 font-lock-function-name-face))
    ("\\<\\(parent\\)\\>" (0 font-lock-function-name-face))
    ("\\<\\(extends\\|instanceof\\)[ \t]++\\([a-zA-Z_][a-zA-Z_0-9]*\\)\\>" (1 font-lock-keyword-face) (2 font-lock-type-face))

    ("\\<\\(try\\|catch\\|throw\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(if\\|else\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(for\\|foreach\\|while\\|do\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(break\\|continue\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(switch\\|case\\|default\\)\\>" (0 font-lock-keyword-face))

    ("\\<\\(delegate\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(clone\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(delete\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(yield\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(resume\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(return\\)\\>" (0 font-lock-keyword-face))
    ("\\<\\(in\\|typeof\\)\\>" (0 font-lock-keyword-face))

    ("\"[^\"]*\"" (0 font-lock-string-face))
    ("\'[^\']*\'" (0 font-lock-string-face))
    ("\\<\\(this\\)\\>"(0 font-lock-constant-face))
    ("\\<\\(null\\)\\>"(0 font-lock-constant-face))
    ("\\<\\(true\\|false\\)\\>" (0 font-lock-constant-face))
    )
  "keyword to highlight in squirrel-mode.")


(add-hook 'squirrel-mode-hook
	  (function (lambda ()
		      (setq tab-width c-basic-offset)
		      (setq indent-tabs-mode t))))

;;派生モード squirrel-modeを定義
(define-derived-mode squirrel-mode c++-mode "Squirrel" "edit for squirrel."
  (setq font-lock-defaults squirrel-font-lock-defaults)
)

(provide 'squirrel-mode)

実現できなかった、enum A{AA,AB}と書いた時にAAとABに色を付けるにはどうすればいいんだろう。


参考ページ
GNU Emacs Lispリファレンスマニュアル Derived Modes
http://dl.dropbox.com/u/9975638/kuin/emacs/elisp/20121001/kuin-mode.el
kuin-mode.el (Kuin用 Emacs設定ファイル)

GLFWの導入

プログラムでグラフィックスを利用するときによく利用されるのがOpenGL + GLUTであるが、GLUTはイベント駆動型であり、ウィンドウのアクティブ/非アクティブ化を検知できないというちょっと困ったものであるので、ゲームのようなプログラムを書きたいときにちょっと苦労する。

 

そこでGLFWを導入してみた。

GLFWについては「GLUTによる「手抜き」OpenGL入門」で有名な床井先生の「床井研究室 - (1) GLFW で OpenGL を使う」で解説されています。

環境はWindows 7 + Visual Studio 2012(32-bit)。

 

1.ダウンロード
GLFWDownloadから「Binary archive for 32-bit Windows」のzipファイルを選択してダウンロードしファイルを展開。

 

2.パスを通す
Visual Stadio 2012を起動し、プロジェクト(C++の「Win32プロジェクト」)を作成しプロジェクトに一つ以上のC++ファイルを作成。
プロジェクトを右クリックし、リストから「プロパティ」を選択。
プロパティページの左上、、「構成」の「すべての構成」を選択。
左から「構成プロパティ」→「C/C++」→「全般」を選び、右の「追加のインクルード ディレクトリ」に先ほど展開したフォルダの中にある「include」フォルダを追加する。
続いて「リンカー」→「全般」を選び、右の「追加のライブラリ ディレクトリ」に先ほど展開したフォルダの中にある「lib-msvc110」フォルダを追加する。
そして「リンカー」→「入力」を選び、右の「追加の依存ファイル」に「opengl32.lib;glfw.lib;」を追加する。
右下の「適用」→「OK」で設定終了。

 

3. GLFWを利用する
ソースファイルに「#include "GL\glfw.h"」と書けばGLFWが利用できるようになる。