公式Q&Aまとめ

Last-modified: 2012-09-12 (水) 01:41:20

前書き

このドキュメントは何か。

ttp://www2.alicesoft.com/club/index.html
ttp://www.alicesoft.com/cgi-bin/club/sdk/cbbs.cgi
System4 BBS にて登場した質問を、編者が時系列順に勝手にまとめたものである。下へ下へ読み進めるほど古い情報になっていく。

このドキュメントの読者はどんな人か。

System4SDK でゲームプログラミングする人々である。

元々の質問者がゲーム作りの初心者であったり、ある程度プログラミングの心得がある人であったりまちまちであるため難易度は一概には言えない。

このドキュメントに間違いを見つけた。

すばらしい。あなたが第一発見者だ。すぐに編集ボタンをクリックしよう。

FAQ

音楽が正常に動作しない(いくつかのリンク番号は鳴るが、ALDに入っているにもかかわらずいくつかのリンク番号は鳴らずにSYSTEM4.0が強制終了してしまう)

 bgi(ループ情報)との一致がされていない可能性がある。
 **.bgiファイルの名前が正しいか確かめ、またそれが古いALDへのものでないかどうか確認しよう。
 

セーブデータロード後の音楽系処理が不安定になります

 system.GlobalSaveよりも構造体のセーブ・ロードを使用した方がいいかもしれない。
 もしもsystem.ResumeSaveと併用して関数を作っているようなら、
SACT_RESUME_SAVEの方がいいだろう。

配列の参照はできますか?

 配列の個々の要素ごとは無理そうだが、配列そのものはできそうだ。
 pivot <- matrix;
 こんな感じでな。

!SACT.Sound_IsExist(2)エラーと表示されゲームが止まってしまいます。

 ふむ、リンクファイルをチェックしてみよう。
 ALDファイルの名前はainと一致しているか? きちんとリンクされているか?
 効果音データが存在しない場合に出る可能性があるぞ。
 

配列を初期化するとき、Cなどのようにできない

 SYSTEM4.0はCではない。だが、SYSTEM4.0なりの良さがあるはずだ。
 たとえばあなたの見ているこのサイトは、気づいたことを自由に書き込むことができる。

 任意の要素を埋めたいのなら、.Fill(int 開始位置,int 終了位置,要素);とすれば良いだろう。
 一つ一つ入れる方法としては文字列を配列に格納する(区切りは「,」)を参考にすると良い。これは文字列配列に入れる物で、有志たちの関数などの1027ヴァージョンの中にも似たようなものがある。
 これらは文字列配列だけだが、形違い用の関数は配列変数のもろもろにある「一括」の項を参考にすればできるはずだ。

インターフェイスから入力した文字列の取得をしたい

 最初からすべての機能が使えるのなら、世の中にあふれたMMOはどれだけ楽しいものになるだろうか?
 しかし案ずることはない、幸いにもアリスは追加用のDLLとして、Dialog.dll と InputString.dll のふたつを用意してくれた。
 そのどちらもあなたのsdkの、熟練者キットの中、HLLライブラリの中から見つけることができるだろう。

SystemService.SetMixerVolume(0,50)で音量が更新されません

困った! どうやらSYSTEM4は相当な面倒くさがり屋らしい!
彼を更新させるには、一度SYSTEM4.0.exeを再起動する必要があるのだ。
ゲーム起動時に設定し、一度再起動をかけるようにすることで、初期の音量は得られる。

もし手動で音量を得られるようにするのであれば、あとはMSC_PLAYの第3引数、
nVolumeによる音量調整しかないのかもしれない。

追記:
 厳密に言えば、systrem4.0を起動してから最初にそのチャンネルを使う時、
 そのチャンネルのボリュームが決定され、その後はSystemService.SetMixerVolumeを
使っても変更されないということらしい。つまり初期値として設定するくらいの用途しか
ないのかもしれないそうだ。

特定の変数だけをファイルとして保存することはできるのでしょうか?

 残念ながら、SYSTEM3と違い、ローカル変数(オブジェクト)を主とするSYSTEM4では、厳密な意味での
QEコマンドに当たる関数はない。ただ、グローバル変数を保存する関数があるので、それを利用することが
できるかもしれない。
 一般的にマップデータ等を制作する場合は、スクリプトソース上でまとめるか、外部のDLLを使うのを
推奨される。前者の場合、そのデータの保存には外部DLL「File.dll」を使うことが多いようだ。
後者は「ACXLoader.dll」or「Data.dll」を使うことになる。
 これらの外部DLLは熟練者キットの中のHLLライブラリの中にある。
 実装の方法は他の質問参照のこと。

 最後に、SYSTEM4.0で最初からあるグローバル変数保存の関数を記載しておく。

グローバルデータをセーブする関数です。

int system.GlobalSave(string szKeyName, string szFileName)

第1引数は、キーコードです。キーコードが違うデータをロードしようとするとエラーになります。一意な名前を付けて下さい。
第2引数はセーブするファイル名です。

IPはそのままでグローバルデータのみ保存されます。
セーブ直前に、全ての参照はNULLになります。

戻り値は、成功すれば1、失敗すれば0が返ります。

システムメニューを作ったが、通常画面に戻れない上メニューが固定されない

まず一つずつ解決していこう。
メニューからメニューを出す前の画面に戻れないのは、
老人の肉体が老人である限り、青春の頃に戻れないようなものだ。
そのため、もし老人が青春に戻るのであれば、身体を若返らせる必要がある。
老人であった時の経験を捨て去って。

 

これと同じように、メニューからメニュー前の画面に戻したいのであれば、
メニュー時に出したスプライトをすべて消し、関数をリターンさせる必要がある。
(たとえば
void system_menu関数を作り、その中で
セーブとロードのボタンをsp3とsp4に作ったのであれば、
system_menu関数からreturnする時にSP_DEL(sp3);SP_DEL(sp4);する)

 

メニューが固定されないのについては、
本スレQ&Aまとめの選択肢を固定したいの項を見て分かる通り、
forで囲めば良いだろう。

 

以下は大工氏のコードとなる。

 私は「bool コールバックB」と「void システムメニュー」の2つの関数で、
このように作ってみましたが、何らかの参考になるでしょうか?
(これはやや重い処理です)
void game_main(void)
{
msg1; //メッセージ枠を作ってください
REGISTER_MSG_KEY_WAIT_CALLBACK(&コールバックB); //コールバック設定
//シナリオです
'ある日'A;'私は熊に出会った。'A;'熊は云った。'A;'「銃をもって出直してこい。」'A;
'私はすぐさま家に戻り'A;'銃を片手に戻ってきた。'A;'すると、やつは私に襲いかかった。'A;
'私はやつを玄関のカーペットにしてやった。'A;
}
void システムメニュー(void)
{
int Sp_SysMenuB_1 = SP_GET_UNUSE_NUM;
int Sp_SysMenuB_2 = SP_GET_UNUSE_NUM;
SP_SET_POS(Sp_SysMenuB_1,570,215);
SP_SET_POS(Sp_SysMenuB_2,570,245);
int nX,nY;
int call;SACT_UPDATE();
while(!KEY_IS_DOWN(VK_RBUTTON))
{
MOUSE_GET_POS(nX,nY);
if (SP_IN_POINT(Sp_SysMenuB_1, nX, nY))
{SP_SET_CG(Sp_SysMenuB_1,9109);
if(KEY_IS_DOWN(VK_LBUTTON)){
system.ResumeSave("sl", "saveFile", call);
SP_DEL(Sp_SysMenuB_1);SP_DEL(Sp_SysMenuB_2);
return;}}
else {SP_SET_CG(Sp_SysMenuB_1,9110);
}
if (SP_IN_POINT(Sp_SysMenuB_2, nX, nY))
{SP_SET_CG(Sp_SysMenuB_2,9111);
if(KEY_IS_DOWN(VK_LBUTTON)){
system.ResumeLoad("sl", "saveFile");
}}
else {SP_SET_CG(Sp_SysMenuB_2,9112);
}
SACT_UPDATE();}
SP_DEL(Sp_SysMenuB_1);SP_DEL(Sp_SysMenuB_2);
}
bool コールバックB(void)
{
if(KEY_IS_DOWN(VK_RBUTTON))
{KEY_CLEAR;
int SysMenuMain = SP_GET_UNUSE_NUM;
SP_SET_CG(SysMenuMain,9102);
システムメニュー();
SP_DEL(SysMenuMain);SACT_UPDATE();
return false;}
return true;}

テキストエディタとして、TeraPadをDLしたのですが、これの適用方法がわかりません。

 君は圧縮されていた彼らを解凍し、出してあげただろうか?
 これは重要なクエストだ。必ずその中から「TeraPad.exe」を探し出そう。
 …………。

 よくやった!
 次に「Sys42IDE」、ピンクのあいつを起動しよう。**さあ、起きろ!**

 むにゃむにゃ。
 どうやら、少し長い読み込み時間の後、彼が起きたようだ。

 では、頭に並んでいるメニューのひとつ、「ファイル(F)」をクリック。さあ、
 ズラズラっと、黒かったり灰色だったりする文字が出てきたぞ。

 その中から君は見つけるだろう。大理石のように美しい黒で書かれた
 「環境設定(S)」の文字を! おお! 見つけた、することは一つ、合わせてクリック!!

すると

エディタ
 exeのパス             ...
 パラメーターの種類           ▼
 
マニュアル
 system4.0
 SACT2

こんな感じのダイアログが出てくるはず。なんとも複雑じゃないか。
これが最後の難関だ、気を引き締めていこう。

 さあ、exeのパスの右端にある「...」をクリックしたら、
参照を先ほど見つけ出したTeraPad.exeのところまで誘導してあげよう。
そうすれば別たれた二人は、君の手で巡り会うことになるだろう!!
おめでとう!
 
 

SP_GET_TEXT_CHAR_SPACEができないのですが……。

どうやらマニュアルは時折過去へいったり未来へ行ったりするようだ。
作りかけの関数が書いてあるなんて。

文字にアンチエイリアス&エッジ付きの文字を表示したりしたいのですが。

 アイチエイリアスはなんて素晴らしい友達だろう! 君が頼まなくても自動的についてきてくれる。
 それに比べて、エッジはsact_text_metrics_tでその色とドットを指定しなくてはならない。
気の利かないやつさ。

Sys40Reg.exeとは?

基本的にユーザーに不都合があるとき設定してもらうものだ。
もし君がマスターアップをすまし、それでちょっと不安が残るなら、
補助ツールとして同封することで、彼を頼るのもいいだろう。

UPDATEは時々の更新に呼ぶべきで、継続的に呼ぶべきではない?

君は、ジンにとりつかれてそんな風に思うのだろうか。
私はアラジンのこういう言葉を知っている。「your free」(君は自由だ)

リリース版にデバッグプラグインを同梱しないようにするにはどうすればいいか。

System40.exe と同じディレクトリにある DP サブディレクトリを削除する。

レジストリを削除をしなくていい場合とは。

System4 が共通で使用する部分は、削除してはならない。System4 設計者は、削除するのは好ましくないと述べている。
セットアップツールを用いてゲームをインストールする形式を取らなかった場合は、レジストリを全く使用しないので、削除する必要が生じない。

メニューバーに表示されるストリングを書き換えることはできるか。

公式にそれを達成する手段は、ない。一般的な Win32 アプリケーションとして考えた場合、いわゆる改造ツールのようなものを使ってそれをする事は可能。System4 の改造はほぼ公認のようだ。

ままにょにょに出てくるような、アイテム欄を実装する関数はあるか。

ない。が、実装するにあたってはSDKに同梱されているチュートリアルの「ドラッグ処理」の項が参考になると思われる。

関数への参照を、関数型配列に PushBack メソッドで直接格納できるか。

できない。だが焦ってはいけない。関数型の変数にまず格納し、その変数を配列オブジェクトに PushBack することはできる。

フルスクリーン時にマウスポインタを画面上端に持って行くとメニューバーが出てくるが、これを出さないようにする方法はあるか。

ない。
編者が思うに、Alt+F4 を知らないユーザーでもいつでもアプリケーションを終了させられるという事実は、アダルトゲームにとってとても大事なことではないだろうか。

グローバルな配列オブジェクトに、Alloc メソッドで領域を割り当てようとするとコンパイルエラーが発生する。

Alloc メソッドはどこかの関数ボディの中に入っているだろうか?もし入っていなければ大変だ!どんなに待っても、そんな所に CPU を使用する権利は回ってこない。そんなプログラムは、最初から書かれてないのと同じだ。

スプライトを選択肢として使うにはどうすればよいか。

親切な余市氏がソースを書いてくださった!

int GetOnSprite( array@int sp, int nX, int nY, int nShow = false ) {
  int i ;
  for (i = 0; i < sp.Numof(); i++) {
    if (SP_IN_POINT(sp[i], nX, nY)) {
      if (nShow || SP_GET_SHOW(sp[i])) {
        return sp[i] ;
      }
    }
  }
  return 0 ;
}

氏曰く、

spで渡されるスプライト上にマウスポインタ(nX、nY)があるか
判断する関数です。nShowにtrueを渡すと、
表示されていないスプライトについても判断します。
実際の利用方法はこんな感じでしょうか。
int nAct = MOUSE_GET_POS(nX, nY);
int nSPN = GetOnSprite(btn, nX, nY, true) ;
if (nAct && nSPN) {
  if (KEY_IS_DOWN(VK_LBUTTON)) {
    // 左ボタンがクリックされた場合
  } else if (KEY_IS_DOWN(VK_RBUTTON)) {
    // 右ボタンがクリックされた場合
  } else {
    // それ以外の場合
  }
}

もしこのコードが動かなくても文句を言ってはいけない。きちんと動くコードを書いて他人にプレゼントする権利にはあなたにもあるからね。

VOICE 関数に整数型変数を渡すとコンパイルエラーが発生する。

仕様だ。結論から言うと、VOICE 関数という名前は避ければよい。例えばこんなふうに。

void CallVoice(int nWaveNum)
{
  SACT_VOICE(nWaveNum);
}

ご存じの通り、VOICE 関数は SACT_VOICE 関数のラッパー関数である(ピンと来ない人は System4SDK ディレクトリをひっくり返して scenario_func.jaf というファイルを見てみよう)。SACT_VOICE 関数と VOICE 関数の違いは、本名とニックネームの違い程度にしか見えないに違いない。だが驚くべきことに VOICE 関数は台本出力と密接な関係にあり、コンパイラからは特別待遇を受けていたのだ。ゲーム実行時に初めて具体的な値が決定する変数の中身を、コンパイラがコンパイル時に知ろうったって、それは無茶な注文だろう?もしそんな台本が本当にあるなら、それは焚き付けに使ってしまうのが良い考えだ。

台本を出力するにはどうすればよいか。

System4 設計者は罪作りである。まだ作りかけの機能の名前だけを見せびらかすなんて。

CG を Y 軸に合わせて回転させたいが、 CG ナントカ系の関数はどんな引数を渡せばよいのか、丁寧にマニュアルを読んでも半分しか理解できない。

悪い知らせだ。もしかするとその半分も間違ってるかもしれない!

例えばこんな関数がある。

void CG_COPY_ROTATE_Y(int nWrite,
                      int nDest,
                      int nSrc,
                      int nSx,
                      int nSy,
                      int nWidth,
                      int nHeight,
                      float fRotate,
                      float fMag);

Source は入力元スプライトで Destination は出力先スプライトだと感じた人もいるだろう。編者もその一人だ。
実際のところどんな意味になるのか。
System4 設計者曰く

Y軸回転におけるnSrc,nDestは回転するポリゴンの表裏のスプライトを
意味し、nWriteはその結果を書き込むスプライトです。
一般的にはnSrc,nDestはSP_SET_SHOW()で非表示にして使うことになる
かと思います。

どのような色深度の画像に対応しているか。

あなたが描いたかわいい画像は、例外なく 24bit カラーで保存されている必要があります。
マスクの方は 8bit カラーで。

選択肢を表示している最中に、裏で色々と処理をしたい。

MENU_SELECT 関数は、選択肢をプレイヤーに提示し、プレイヤーが選んだ選択肢をプログラムに教える程度のことしかできない。REGISTER_MSG_KEY_WAIT_CALLBACK 関数を駆使しても徒労に終わりそうだ。
もしあなたが、裏側の処理とは非同期に・平行して動くことができる選択肢関数を自作できたら、目的を達成できるかもしれない。

rect_t構造体の子細がマニュアルに載ってないが、これはどんなものか。

struct rect_t
{
  int x,y,w,h;
}

クラスの継承ができないじゃないか!

代わりに合成を使おう。

オブジェクト指向の中で一番大事なもの(と今でも信じてる人が多いもの)が System4 から仲間はずれにされたのには浅からぬ訳がある。結論だけ述べておくと、クラスの継承は、既存のプログラムコードを流用する魔法として見ると全く力不足だったために見捨てられたのだ。詳しくは、オブジェクト指向を論じた最近の本やウェブサイトを参照していただきたい。

インターフェイスの継承については、System4 設計者は「将来的にはあり得るかもしれませんが、現状では使う人が少なさそうなので保留にしております。」と語っている。

C 関数や W 関数を使用するとルビがずれてしまう。または、RUBY_SET_PARAGRAPH_MODE 関数でルビを常に入れた場合も同様にずれてしまう。

SP_SET_TEXT_POS 関数を用いて本文をずらし、ルビによるズレを補正する対抗策が考えられる。しかしルビに合わせて一々関数をはさむのはあまり楽しい作業ではない。たぶんバグだ。いつか根本的に解決されるに違いない。きっと。

同梱の "シナリオ.jaf" ファイルを利用するような、System4 関連ツールを作っても問題ないか。

ない。

透過させる色を指定してスプライトをくりぬくことはできるか。

できない。くりぬきはマスク画像による。

マスク画像の形式を教えてほしい。

8bit・256色のビットマップ、インデックスカラー。
白と黒のグレースケールとする。白い部分は可視領域で、黒に近づいていくほど見えなくなる。
SDK 付属の CG 圧縮ツールを用いることで、通常のビットマップファイルとマスクファイルを結合した QNT 形式ファイルを出力することができる。ちなみに、この QNT 形式は汎用的なフォーマットはなくアリスソフト固有のものである。

サンプル「ポポリタン」で表示されるフォントのサイズを変えたい。

「ADVクラス」サブディレクトリ内の「CADVEngine.jaf」ファイル内を書き換えるとデフォルトのフォントサイズを変更することができる。

// メッセージ文字装飾設定
sact_text_metrics_t tm;
tm.nSize = 32;

もしくは、MES_SET_SIZE 関数を呼び出して変更する。おそらくこちらが簡単。

動画を再生したい。

まず幾つかのファイルが必要。熟練者向けセット/HLLライブラリ/PlayMovie ディレクトリ内にある4つのファイル全てを、それぞれ必要な場所にコピー/設定する必要がある。

  • PlayMovie.dll は、ゲーム本体があるディレクトリ内の DLL サブフォルダ内に置く。
    • Source/System/SACT/DLL ディレクトリ内にある「SACT_DLL.inc」の中に、「"PlayMovie.dll"」を追記する。(環境次第?)
  • PlayMovie.hll と PlayMovie.inc をプロジェクトディレクトリ内の HLL サブフォルダに置く。
  • System4IDE でプロジェクトファイルを開き、「HLLを追加」メニューから「PlayMovie.hll」を選ぶ。Hllエイリアス名はそのままにする。
  • ムービー再生.jaf をソースコードディレクトリに置く。
  • ソースコードディレクトリ内の game.inc(もしかしたら、あなたは違う名前に変更しているかもしれない)をエディタで開き、"ムービー再生.jaf" を追加する。

後は、ゲーム中のお好きな箇所でムービー再生関数を呼び出し、再生ファイル名を引数として渡せばよい。
もちろん、再生したい動画ファイルはゲーム本体と同じディレクトリに置いておく必要がある。

編者が考えるに、再生できる形式はおそらく WindowsMediaPlayer に準じているものと思われる。MPEG か WMV くらいを使っておくのが妥当だろう。ヘンなコーデックを使った AVI ファイルはもしかしたらユーザーのマシンでは再生できないかもしれないから。

乱数を作りたい。

RAND 関数を使う。C/C++ の rand 関数とは挙動が違うので、そっちの方面の出身の人は注意。また、乱数の種にまつわる関数は用意されていないので、リプレイ等の都合で同じ乱数を発生させたい人も注意。

CG 加工にまつわる関数の使い方がよく判らない。

System4 設計者は以下のようなサンプルを例示した。

int 反転CG取得(int nCG) {
  // 元になるスプライトを作成する
  int sp = SP_GET_UNUSE_NUM();
  SP_SET_CG(sp, nCG);
  // CG情報を取得する
  cg_metrics_t cgmet;
  CG_GET_METRICS(nCG, cgmet);
  // 反転結果を描画するスプライトを作成する
  int sp_result;
  if (cgmet.bExistPixel && cgmet.bExistAlpha) {
    sp_result = SP_GET_UNUSE_NUM();
    SP_CREATE(sp_result, cgmet.nWidth, cgmet.nHeight, 255, 255, 255, 255);
  }
  else if (cgmet.bExistPixel && !cgmet.bExistAlpha) {
    sp_result = SP_GET_UNUSE_NUM();
    SP_CREATE_PIXEL_ONLY(sp_result, cgmet.nWidth, cgmet.nHeight);
  }
  else {
    SP_DEL(sp);
    return -1;
  }
  // 元CGからサーフェスを反転コピーする
  if (cgmet.bExistPixel) {
    CG_COPY_REVERSE_LR(sp_result, 0, 0, sp, 0, 0, cgmet.nWidth, cgmet.nHeight);
  }
  if (cgmet.bExistAlpha) {
    CG_COPY_REVERSE_AMAP_LR(sp_result, 0, 0, sp, 0, 0, cgmet.nWidth, cgmet.nHeight);
  }
  // 元CGを削除する
  SP_DEL(sp);
  // 戻り値
  return sp_result;
}
// 用例
void CG反転(void)
{
  int sp = 反転CG取得(101);
  for (;;) {
    SACT_UPDATE();
  }
}

MOUSE_SET_POS 関数の挙動を System4 側のオプション設定で制御できるか。マウスポインタの瞬間移動は可能か。

できない。不可能である。

MOUSE_SET_POS 関数は、引数で指定されたポイントに瞬時にジャンプすることはできない。
マニュアルには「System4.xの設定により、アニメーション移動もしくは、瞬時に移動されます。」と記述されているが、これはマニュアル側が誤りである。必ずアニメーション移動となる。

「ポポリタン」にてメッセージウィンドウの表示位置を変えたい。

メッセージウィンドウ左 関数、メッセージウィンドウ右 関数、メッセージウィンドウノーマル 関数を用いる。

「ポポリタン」で背景画像を差し替えると、エラーは出ないが画像も出ない。

背景 CG のサイズがビューサイズ(System4 起動時のサイズ)と一致していないと、エラーも画像も出ないという状態になる。これは仕様らしい。CG のサイズとビューサイズを一致させればよい。ちなみにポポリタンの解像度は幅が 800 ピクセル、高さが 600 ピクセルである。ビューサイズは System40.exe と同じディレクトリの System40.ini にて指定される。

プレイヤーがとった行動の回数をカウントするにはどうすればよいか。

整数型変数を作り、その中にプレイヤーがとった行動の回数をカウントしておけばよい。
以下は、System4SDK 製作者が例示したサンプルである。

// グローバル変数
int g_n選択肢1が選ばれた回数 = 0;
MENU_ADD(1, "選択肢1");
MENU_ADD(2, "選択肢2");
MENU_ADD(3, "選択肢3");
int nSelect = MENU_SELECT();
if (nSelect == 1) {
  g_n選択肢1が選ばれた回数++;
  if (g_n選択肢1が選ばれた回数 >= 3) {
    // 選択肢1が3回以上選ばれたのでxxxイベントにジャンプ
    jump xxx;
  }
}
else if (nSelect == 2) {
  // 選択肢2が選ばれたとき
}
else {
}

IString::Set 関数が正常に動作しない。

同関数は終端がNull文字である文字列を引数に渡さないと正常に動作しない。

system40.exe のアイコンを書き換えた上で配布しても問題ないか。

ない。

MIDI サウンドを再生することはできるか。

できない。

メッセージとして表示されるフォントを変更できるか。

MES_SET_FACE 関数を用いることで、明朝・ゴシックのうちから選ぶことができる。
それ以上の変更は不可能。

配列オブジェクトの Realloc で二次元以上の割り当てができるか。

できない。
コンパイルエラーにはならないが実行時エラーが生じる。

クラスメソッドにデフォルト引き数値を与えようとするとコンパイルエラーが起きる。

メソッドの実装側ではなく、定義側にてデフォルト引数を与えるようにする。

これについて System4 設計者は、「クラス見ただけでデフォルト引数があるかないか判断できないというのは、間違いが起きやすいと判断したためです」と語っている。

System4 で使用できるフォントの数を増やす予定はあるか。

ない。

VisualStudio.Net で DLL を開発する場合のウィザードでの設定は。

Win32 の DLL として作成する。「空のプロジェクト」と「シンボルのエクスポート」のチェックは外しておいてよい。

文字列を返却する DLL を作りたい。

以下、System4 設計者によるサンプルを交える。

まず、DLL 内に IString インタフェースクラスを継承したクラスを作っておく。

class CString : public IString {
  private:
    std::string szText;
  public:
    virtual char** Get(void) {
      return (char*)szText.c_str();
    }
    virtual void Set(char* pszText) {
      szText = pszText;
    }
};

例では、内部的に std::string を使っているが、ここは std::vector<char> でも自前の文字列クラスでも何でも構わないとのこと。

System4側から呼ばれる HLL 関数は以下のように作る。

IString* getText(void) {
  static CString szText;
  szText.Set("xxx");
  return static_cast<IString*>(&szText);
}

途中、static 変数を用いているのは、getText 関数を一度抜けてすぐに変数が破棄されるのを防ぐためである。

IDE で編集を行った後、コンパイルが通らなくなることがある。

プロジェクトファイルをテキストエディタを使って直に編集する。

IDEを通してソースファイルの追加等を行った場合、IDE のバグによりプロジェクトファイル内からシステムソースの記述が消滅することがある。

CG_COPY_ROTATE 系の関数で思い通りの出力が得られない。

CG_COPY_ROTATE 系の関数は Write / Dest / Src 各サーフェスのサイズが全て同じであることを前提にしている点に留意すること。

16進数は記述できるか。

できる。
[+-]?0[xX][0-9a-fA-F]+ 。0x12AB や -0Xcd34 といった形式。

2進数は表現できるか。

できる。
[+-]?0[bB][01]+ 。 0b0000 や -0B11111 といった形式。

8進数は表記できるか。

できない。
これについて、設計者は「ほとんど使わないですし、「00100」と書いて10進数の「100」と解釈して欲しいという要望がSystem3.xの頃からあったので、8進数表記は見送りました」と述べている。

10のべき乗表現はできるか。

できない。

情報取得演算子の一つめのオペランドに memberindex 以外を指定できないか。

memberindex 以外には無い。

System4 から DirectDraw をきちんと動かすことができるか。

簡単ではない。
System4 設計者は「DLLを作成すれば可能だと思います。ただ、System4.0側でWM_PAINT発生時にBitBltしている処理があるのですが、それを無効化する手段を作らないと画面がちらつくことになるとは思いますが。」と述べている。

Syetem4 にネットワーク関係のライブラリは実装されているか。

実装されていない。

編者が考えるに、アリスソフトの夏休み企画として配布された D&D.NET は外部DLLを通して通信しているものと思われる。