アドベンチャーSDK概要



0.0■ SDKの概要
1.0■ APLの概要
1.1■ APL SDKの概要
1.2■ APL言語の特徴
2.0■ APLコンパイラー
2.1■ APLコンパイラー、コマンド行の構文
2.2■ コンパイラーエラーメッセージ
3.0■ .advのファイル構造
3.1■ .advファイルのヘダー
4.0■ APLバイナリーフォーマット
4.1■ APLバイナリーフォーマット
4.2■ コマンドオプコードとオペランド
4.3■ 式とGetVarコード
5.0■ APL言語リファレンス
5.1■ 命令語の構文と意味
5.1.1■ Key値の仕様
5.1.2■ 説明を要する特別のサブルーチン
5.1.3■ イベント起動プログラミング
5.1.4■ 説明を要する天候に関するコマンド


0.0■ SDKの概要

フライトシュミレータSDKにようこそ。このSDKはFS98を変更したり、拡張しようとし
ている開発経験者を助ける為に作られました。このSDKを使用する方はC++での開発経
験があることを前提としています。
SDKについては、その情報に対し高いニーズがあるのでマイクロソフト社のフライトシ
ミュレータのWEBページで可能な限り早く配布されます。

SDKは完成時点では以下のセクションが含まれる予定です。
・パネル
・機体コンテイナー
・アドベンチャー開発言語
・シナリー
・マルチプレーヤー

SDKは更新、配布、使用上の利便性を考え、MS Windows HELPファイルの形式で配布され
ます。SDKが完成した時点で、RTFファイルによるバージョンのリリースされる見込みです。
重要事項:SDKはマイクロソフト社の製品サポートサービスの対象ではありません。



1.1■ APL SDKの概要

Adventure Programming Language (APL) SDKは開発者にFS用のアドベンチャーを開発、編集
できるプログラム開発言語としてAPLを理解するのを助けることを目的に作成されました。

APL SDKは以下のセクションからできています。
・APL言語の機能仕様
・APLコンパイラー(Aplc.exe)
・アドベンチャー(.adv)ファイル構造
・APLバイナリーフォーマット
・APLとFSの相互関係
・完全なAPL言語のレファレンス
  (このレファレンスにはAPLの文法、命令、形式、機能、APLで使用可能なフライトシミュ
  レータ変数が説明されています。)
・特別のサブルーチンとイベント起動プログラミング

簡単に言えば、APL SDKはFS用アドベンチャーを作成する為に必要となるプログラミング
ツールについての説明であると言えます。
また、APL SDK.ZIPにはコンパイル可能なサンプルAPLアドベンチャーが含まれています。
重要事項:APL SDKに含まれる情報はプログラマーに対する参考資料となることを目的として
います。プログラマーはC及びBASIC言語を良くしっていることを前提としています。
SDKに含まれる情報はマイクロソフト社の製品サポートサービスの対象ではありません。



1.2■ APL言語の特徴

Adventure Programming Language(APL)は、殆どの言語機能をBASIC及びC言語を借りてきて
います。また一部は行単位(1行1コマンド)のプログラミングであるMASM
(Microsoft Macro Assembler)からも取り込んでいます。

ホワイトスペース
APLでは、それが意味をなすならどこでもブランクやタブによるホワイトスペースを使う事
ができます。例えば、数式の前後やコンマの後に段落(インデント)を付ける場合などです。
文法でスペースが必要な場合は、スペースはいくつつけても構いません。
ホワイトスペースは二つの演算子を分けるという効果を持ちます。
ホワイトスペースが有効でないのは引用符内の文字列に対する場合のみで、この場合は引用
符の中はスペースがあっても一つの文字列として扱われます。

大文字/小文字
APLでは、全てのコマンドや変数は大文字、小文字を区別しません。

コード内のコメント(リマークス)
APLは二つのコメント記述をサポートしています。セミコロン(;)とアポストロフィ(')がそれ
です。この二文字で始まる行、及び、行の途中でこの文字があった場合はそれ以降の文字は
コメント文として扱われます。
コメントが有効でないのは引用符内の文字列に対する場合のみで、この場合は引用符の中は
コメント文字があっても一つの文字列として扱われます。

またコメントを表すのにRemコマンドも使用できます。

16進定数(Hex Constants)
APLでは、通常、数字は10進数として扱われます。しかし、整数の独立変数が期待できる場所
ではどこでも16進数を使用することができます。この場合はC言語と同様に"0x"をプリフィッ
クスとして使用します。例えば"0xFF00"は文字の上位ビットマスクを特定します。実数を表す
場合は16進数に小数点を付けます。例えば"0x000F.F000"は15.9375を表します。(15と16分の15)

引用符
特定文字列にはダブルクォーテーションマークを使用します。開始のダブルクォーテションマ
ーク以降の文字列は終了のダブルクォーテションマークがでてくるまで特定文字列の一部とし
て扱われます。引用符の中では行末文字を使用することができません。引用符内の二つのダブ
ルクォーテーションマークは引用符内文字列の中の一つのダブルクォーテーションマークとし
て扱われます。また、引用符内の大文字/小文字は変更されません。

度、分、秒
しばしば、APLのプログラム内で緯度、経度の座標を示す必要があります。通常、この座標は
度、分、秒であらわされます。そしてこれを小数点付きの度に変換することは面倒なものです。
APLではコロン(:)を度、分、秒を区別するのに使用することができます。例えば12:34:56.7は
12度34分56.7秒(12°34′56.7″)を表します。

ブール定数
True は1、Falseは0と予め定数定義されています。


2.1■ APLコンパイラー、コマンド行の構文

Aplc.exeは単独で動くWindowsベースの32ビットコンソールプログラムです。Windows95または
WindowsNT上のMS-DOSプロンプトから走らせることができますが、純粋なMS-DOS上やOEM
版のMS-DOSマシン上では走らせることができません。

Aplc.exeはAPLソースコードをアドベンチャーバイナリー(.advファイル)に変換します。
コンパイラーは入力としてASCIIテキストを使用し、バイナリーの出力ファイルを作成します。

構文
APLC   []

options
-eをoptionsに使用した場合は、コンパイルエラーが発生した場合は、標準エラーとは異なり、
ファイルに書き出されます。エラーが発生した時に書き出されるファイルは出力ファイル
(.adv)が書き出されるパスネームで拡張子が.errになります。エラーがなかった場合は、既存の
エラーファイルは削除されます。その為、Aplc.exeを走らせた時、エラーファイルの有無をコ
ンパイルが成功したかどうかの目安とする事ができます。

-pを使用する場合は、インプットファイルがプリプロセスされていることを示します。Cプリ
プロセスはマイクロソフトC++コンパイラーで/Eオプションを付けることで行うことができま
す。プリプロセスされた出力ファイルはC_Prepro.aplというファイルにリダイレクトされます。
コンパイルが成功すると、APLCコンパイラーが終了する前にこのファイルは削除されます。標
準のCプリプロセッサーが使用される為、APLの構文上意味を持つプリプロセッサーの命令語(#include,#define,#if,#ifdef等)が使用可能です。

-qを使用した場合はcopyrightのバナーが出力されません。

name1
入力テキストファイルの名前を指定します。拡張子が指定されていない場合は.txtであるもの
として扱われます。name1にはマイナスサイン(-)が使用できます。この時はtextファイルの
替わりにname2で指定された標準入力が使用されます。

name2
オプションです。出力ファイルの名前を指定します。name2が指定されなかった場合はname1
の名前が使用され拡張子は.advに変更されます。
(アドベンチャーファイルは必ず.advの拡張子となります。)

コンパイルが成功した場合は(DOSエラーレベルの)exit statusは0となります。コンパイル中に
エラーが発生した場合は該当のエラーメッセージが標準エラー又はファイルに書き出され出力
ファイル(.adv)は削除され、exit statusは1となります。



2.2■ コンパイラーエラーメッセージ

以下の表にはAPLコンパイラー(Aplc.exe)が出す構文エラーメッセージを示します。必要な部分
ではエラーメッセージの説明があります。

Division by 0.		ゼロ除算

Duplicate label "%s".	ラベル名が重複している。重複したラベル名は%sの部分に実際に
			使用された名前で表示される。

Duplicate variable name "%s".	重複した変数が使用されている。重複した変数名は%sの
			部分に実際に使用された名前で表示される。

ELSE with no IF.		IFのないELSEが使用された。 

ELSEIF found after ELSE.	ELSEの後にELSEIFが見つかった。

ELSEIF without matching IF.	IFに対応しないELSEIFがある。

ENDIF with no IF.		IFに対応しないENDIFがある。

ENDWHILE with no WHILE. 	WHILEがないENDWHILEがある。

Extra characters on line.	有効な命令語の後にコンパイラーが処理できない文字(列)がコン
			パイル後に残ってしまった。これは最初の部分のエラーがコンパ
			イラーには誤ったコマンドとして認識された可能性のある込み入
			ったエラーかもしれない。

FOR at line %d has no NEXT %s.	
			NEXTのないFORがある。
			%dはForコマンドが見つかった行番号を示す。%sはFORコマンド
			の制御変数を示す。

GOSUB expected.		OnCrash, OnStall, OnKeyコマンド等Gosubが期待しているコマンド
			が見つからない。

IF at line %d has no ENDIF.		ENDIFのないIF文がある。%dはIFコマンドの行数を表す。

Illegal character "%c".	%cで示される使用できない文字が使われている。

Illegal character.		ASCIIコードにない文字が使われている。

Invalid coverage for this	Cloudコマンドで示されたタイプの雲にはcoverageキーワードは有
			効でない。詳細はCloudコマンドを参照の事。

Invalid number.		その行にコンパイラーが評価できない数値がある。例えば、小数
			点が2つ以上ある数値の場合はこのエラーとなる。

KEYPRESS expected.	WaitコマンドにKeypressパラメータがない。このエラーはコンパイ
			ラーが時間数値とコンマを見つけ、その行にkeypressパラメター
			以外が指定されていた場合やパラメターのスペルが違っていた場
			合にも発生する。

Key specification expected.		KV()関数が変数を理解できない。Key値の仕様を参照して
			下さい。

Keyword expected.	コンパイラーがキーワードを期待している時に、それ以外を見つけ
			た。このエラーは句読点の付け間違いにより発生していることがある。

Label name expected.	コンパイラーがラベル名を期待している時にラベル名以外の語が見
			つかった。このエラーは句読点の付け間違い、または、ラベル名の
			誤りにより発生していることがある。ラベル名はアルファベットで
			始まり、アルファベット、数字、アンダースコアのみ使用できます。

Line too long.		一行が255文字超の長さになることは許容されていません。(また行
			中にCRやLF記号が含まれることも禁止されています。)

Missing ")".		この行には開始括弧の数が終了括弧の数より多くあります。括弧が
			閉じられていません。

Missing label "%s" referenced at line %d.
			%d行にあるGoTo, GoSub, OnCrash, OnStall, OnKeyコマンドが参照
			している%sで示されるラベル名が見つかりません。 ラベル名の誤
			り及びラベル名の付け間違いをチェックして下さい。 

NEXT variable does not match FOR.
			Forコマンドによって指定された変数はNextコマンドに指定された
			変数と対になっている必要があります。このエラーはNextコマン
			ドがないか、スペルミスによっても発生します。

NEXT without matching FOR.		FORコマンドがないNEXTコマンドがあります。

Only one TITLE per adventure.	TITLEが複数あります。

Operand expected.	コンパイラーは期待しているオペランド(変数や値、括弧内の式等)
			を見つけられません。このエラーは句読点の付け間違い、2つの
			演算子並んでいる時、または演算子で行が終了している場合に起
			こります。

Quoted string expected.	このコマンドは引用符付き文字列を期待しています。このエラー
			は引用符を閉じていないケースでも起こります。

String expected.		Declare <変数> = ステートメントは引用符付きでない文字列を使
			用します。

String in KV must be 1 character long.	
			KV()の変数が引用符付きの場合は一文字である必要があります。
			Key値の値の項目を参照して下さい。

Syntax error.		構文エラー。句読点の間違いによっても発生します。

System variable name "%s" reused.	
			%sという名前の変数はフライトシミュレータでの規定変数である
			か関数である為、使用できません。

THEN expected.		IF文でTHENがありません。

TITLE too long (limit is %d characters).
			TITLE名が長すぎます。TITLE名は63文字以内にして下さい。

TO expected.		TOコマンドがありません。

Two ELSEs with same IF.	一つのIFに二つのELSEがあります。

Unbalanced quotation marks.	引用符が閉じられていません。

Unknown key name "%s".		KV( )関数は%sで示される値をKey名として認識できませ
				ん。 

Unrecognized command "%s".	%sで示されている文字をコマンド名として認識できませ
				ん。スペルをチェックして下さい。

Unrecognized keyword "%s".	%sで示される文字をKeywordとして認識できません。ス
				ペルをチェックして下さい。

Undeclared variable "%s".	
			%sで示される変数は規定変数でも宣言された変数でもありません。
			変数は使用する前に宣言されないといけません。
			変数のスペルをチェックして下さい。

Variable name expected.	コンパイラーは変数名を見つけられませんでした。このエラーは
			句読点の誤りか変数名の誤りによっても発生します。変数名はア
			ルファベットで始まり、アルファベット、数字、アンダースコア
			のみ使用できます。

WHILE at line %d has no ENDWHILE.	
			%d行にあるWHILEコマンドにはENDWHILEがありません。

"(" expected.		"("がありません。

")" expected.		")"がありません。

"," expected.		","がありません。

"=" expected.		"="がありません。

TRUE or FALSE are reserved keywords.	
			TRUEとFALSEは規定文字列で、変数として宣言することはできま
			せん。



3.1■ .advファイルのヘダー

アドベンチャー用のバイナリーファイルのヘダーはフライトシミュレータによって選択され
アドベンチャーファイルとして証明される為の情報を含んでいなければなりません。
この.advのヘダーに含まれる情報はプログラムとは区別されたものです。
.advのヘダー部512バイトの部分で、このファイルの内部構造は以下のサンプル(C言語で表現
されています)に示されています。

typedef struct

{

char adv_id[16];	//.adv file signature.
char title[64];	//File title string.
char description[256];	//File description string.
long version;	//APLC internal version number.
long custom_version;	//Custom APLC version number.
unsigned long CRC;	//CRC of code section.

unsigned long string_table_length;	//Number of APL string variables.

unsigned long string_table_offset;	//Offset to the string table.

unsigned long code_size;	//Number of bytes of APL code.

char reserved[152];	//Reserved for future use.
} ADV_FILE_HEADER;	//File header structure.


各フィールドの説明は以下の通りです。
adv_id			アドベンチャーファイルであることを示すマーカーです。このマ
			ーカーはテキスト文字列で結果としてDOSユーティリティで容易
			に判別することができます。 この値は"S6X Adventure^Z"で^Zは
			Ctrl+Z (end of file)記号です。
 
title			TITLEコマンドによってアドベンチャーソースに記載されたアドベ
			ンチャーファイルのタイトルです。

description		Descriptionコマンドによってアドベンチャーソースに記載された
			アドベンチャーファイルの説明です。ファイル説明文は一つの
			ASCIIZ文字列です。行替えはフライトシミュレータが自動的に行
			います。

long version		APLCによってヘダーに付けられた番号で、フライトシミュレータ
			がバージョンアップした際、.advファイルが最新のバージョン用
			か、以前のバージョン用かを区別し適切な対応をとるのに使用し
			ます。これは内部的なバージョンナンバーで.advファイルの形式
			が変更され、新しいバージョンのドライバーで以前のフォーマッ
			トが使用できなくなった時にバージョンアップが行われます。
			このバージョンナンバーはユーザーには見えません。

long custom_version	前項を参照して下さい。

CRC			データの整合性を保証するためのCRCチェックサムです。

string_table_length		ヘダー内のAPL文字列変数の数を指定します。

string_table_offset		文字列テーブルのオフセットを指定します。

code_size		APLコードのコードサイズを指定しています。

reserved			予備スペースです。ゼロで埋められます。将来の定義用に確保さ
			れています。



4.1■ APLバイナリーフォーマット

APL(Adventure Programming Language)のバイナリーフォーマットは1バイトのオプコードに
基づき、スペースを節約できる可変長のオペランドからできています。ソースコードのコメ
ント行以外の行はコマンドレベルのオプコードに一行毎に対応しています。コマンドレベル
オペコードの殆どのオペランドは明示的な数字、変数、式によって示された数字です。オペ
ランド、オプコード、GetVarコードについてのより詳細な説明はCommand Opcodes and 
OperandsとExpressions and GetVar Codesを参照して下さい。



4.2■ コマンドオプコードとオペランド

省略



4.3■ 式とGetVarコード

省略



5.1.1■ Key値の仕様

Key値(Onkey命令の変数やKey変数の値として仕様される)は各キーの内部的な値で整数で与え
られます。ここではAPLでこの値がどの様に使われるかを説明します。
APLでは、KV()関数をKeyの値を示すのに使用します。KV()関数は他の関数と異なり、通常の
数値ではなく特別のキーワードを組み合わせて使用します。また引用符も使用できます。
KV()の引数には以下の表に含まれるキーワードを使用できます。

Keyword		説明

ALT		ALT key pressed.
CTRL		CTRL key pressed.
SHIFT		SHIFT key pressed.

実際のキーは引用符付きのASCII文字または名前で示されるASCII以外のキーで特定できます。
SHIFTとASCII文字が引用符付きで使用された場合はそのキーがSHIFT付きであることを示します。

KV()関数が認識するキーの名前は次の表に示されています。
キーの名前		キーの場所

KeyPad0-KeyPad9		Numeric keypad keys.
KeyPadPeriod		Numeric keypad period (.), or DEL, key.
F1-12			Function keys.

例えば、KV(CTRL KeyPad9)はCTRL+PgUpを、KV(SHIFT"Q" )はSHIFT+QをKV(CTRL ALT F1)は
ALT+CTRL+F1を示します。

Note: 内部テスト以外では、アドベンチャーの内部キー値を明示的に使用するのは避けるべ
きです。



5.1.2■ 説明を要する特別のサブルーチン

OnCrash、OnStall、OnKeyコマンド等(イベント起動コマンド)を使用する場合は、特定のイベ
ントが起動された時に、コールされる特別のサブルーチンの為のポインターをセットする必
要があります。 これら特別のサブルーチンはフライトシミュレータが起動されたらいつでも
使用される可能性があります。しかし、この特別のサブルーチンは一度には一つしか起動で
きません。例えば、OnKeyルーチン実行中にストールが発生した場合は、OnStallルーチンは
コールされません。(OnKeyルーチンの終了後、なお、ストールしていればOnStallルーチンは
コールされます。)特別のサブルーチンがコールされた時には、そのリターンアドレスは
GoSubコマンドが実行された時と同様にスタックにストアされます。そして、リターンコマ
ンドによってリターンアドレスが戻されるまでの間、特別のサブルーチンが動き続けます。
もし、特別のサブルーチンが更にサブルーチンをコールしている場合、このコールされたサ
ブルーチンは特別のサブルーチンの一部であると解釈されます。APLインタープリターは特別
のサブルーチンが終了するまでコントロールをフライトシミュレータに戻しません。

特別のサブルーチンがコールされた場合:
・	フライトシミュレータが命令を通常通りに実行している間、特別のサブルーチンが
	コールされていない時はリターンアドレスは実行されるべき次のコマンドを示します。
・	Waitコマンド実行中だった時は、特別のサブルーチンが終了後、それがコールされた
	時点のWAITコマンドが戻されます。従って、待機時間は最初のWAITコマンドが発行
	されてからの通算になります。 Wait Keypressの場合は特定キーが押されるのを待つ
	ことになります。

特別のサブルーチンはフライトシミュレータに制御を戻すことなく実行される為、フライト
シミュレータが起動して10000命令がすぎた段階でアドベンチャーは終了させられます。



5.1.3■ イベント起動プログラミング

イベント起動プログラムとはAPLによる明示的なサブルーチンコールがなく、あるイベント
が発生するとそれを引き金にしてサブルーチンがコールされることを意味します。この引き
金になるイベントが発生した時に実行されるサブルーチンをイベントハンドラーと呼びます。

イベント起動プログラミングの一番の有利さは、開発者が繰り返し特定条件を判別し、サブ
ルーチンをコールするループを記述する必要が無く、システムが条件をチェックし、イベン
トが発生すれば、自動的にサブルーチンがコールされるという点にあります。いくつかの条
件が同時にチェックされなければならない場合(例えば、飛行機が正しい針路、高度、位置に
あるかの判別のチェックのようなケースです。)、通常のコードでは管理しきれなくなりま
す。APLでは、イベント起動プログラミングにより通常のプログラミングに比べより管理しや
すくなります。なぜなら、イベントの発生判断がフライトシミュレータの内部状態とシンク
ロしており、かつイベントハンドラーが特別のサブルーチンであるからです。

Onexp_True、Onexp_Bool_Change、Onexp_Change三つのAPLコマンドがイベントハンドラー
と共にイベント起動条件に連動しています。これらのコマンドが起動される条件や定義につ
いては各々のコマンド項目を参照して下さい。 これらのコマンドの一つが見つかった時には、
イベントリストにイベント情報が追加されます。 フライトシミュレータがAPLインタープリ
ターをコールする時は、インタープリターが停止していなければ、いつでも、イベントリス
トは参照され、イベント起動条件がチェックされます。もし、イベントが起動されれば、適
切なイベントハンドラーが特別のサブルーチンとしてコールされます。

必要がなくなればエベントリストからOnexp_Clearコマンドでイベントを外す事もできます。



5.1.4■ 説明を要する天候に関するコマンド

天候に関するコマンド(Weather, Weather_Char, Clouds, Winds, Temperature, Baro_Pressure, 
Visibility)はこれを合わせて使用することにより、アドベンチャーでローカル天候地域を作成
することができます。この項目では、天候に関するコマンドの概説し、天候に関するコマン
ドをどの様に組み合わせて使い天候エリア内で複雑な内容を実現するかを説明します。

アドベンチャー内では一度に一つの天候エリアを作り出すことができます。Weatherコマンド
は現状のアドベンチャー内の天候エリアを制御し定義することができます。Weatherコマンド
が実行される都度、既存の天候エリアはアドベンチャーが作ったものにせよ、既にあったも
のであっても、削除され、新しい天候エリアが作られます。 この動作はアドベンチャーの天
候エリアの名前がWeatherコマンドのパラメータで与えられた名前と一致するかどうかには依
存しません。

Clouds, Winds, Temperatureコマンドは高度によって区分された特定の場所に対して有効です。
例えば、雲は3層まで定義でき、各々のCloudsコマンドはそのおのおのの層に対して設定する
ことができます。三つのCloudsコマンドが現在の天候エリアに対して実行されると、全ての雲
層が定義される為、以降のCloudsコマンドは無効になります。たとえ後から発行されたClouds
コマンドが同一の高度領域を指していたとしても前の命令を置き換えることにはなりません。
雲のレイヤーはレイヤー番号によって特定します。レイヤー番号はフライトシミュレータによ
って表示される物理的な順番を示しているだけです。この番号は後続のコマンドに対し単に参
照番号をしめしているだけです。しかしながら、もし、後続のCloudsコマンドが同一レイヤー
番号を指定している場合は、後続のレイヤーが前のレイヤーを置き換えます。またCloudコマ
ンドが削除形式であれば、そのレイヤーを削除します。このレイヤーの考え方はWindsコマン
ドやTemperatureコマンドに対しても同様に働きます。 

これに対し、Weather_Char、Baro_Pressure、Visibilityコマンドは天候エリア全体に対する指定
になります。これらのコマンドはレイヤーで特定することができません。後続のコマンドは前
のコマンドを置き換えます。



Last Update 1999/1/6