プログラミング・マニュアル
0.クイックスタート
このマニュアルは、HSPによるプログラミング方法と言語仕様全般を解説したものになっています。
もし初めてプログラミングに挑戦するという人は、最初に「初心者のためのHSP入門」を読むことをお勧めします。
もし、ある程度プログラミングの経験があり、HSPが初めてという方はこのクイックスタートをお読みいただいて実際に使ってみることをお勧めします。
使っている過程でわからないことが出てきたら、このマニュアルで検索をして調べてみてください。
-
HSPで実行されるプログラムリストを「スクリプト」と呼んでいます。これを編集するエディタが、HSPスクリプトエディタ(hsed3.exe)です。これを起動して、スクリプトを記述したら[F5]キーを押して実行させることができます。付属のサンプルプログラムなどを実行して試してみてください。
-
HSPでは、「pos a,10」のように「命令」+「パラメータ(「,」で区切って複数指定することもできます)」という形式で
スクリプトを書いていきます。命令は1行目から順番に実行されていきます。
HSPスクリプトエディタでキーワード(命令)にカーソルを合わせて[F1]を押すと手軽にリファレンスを参照することができます。
-
命令の基本はBASICに近いものになっています。「変数=数値」で変数代入をしたり、「screen 0,x*64,y」のように数値、変数を混ぜた式をパラメータとして指定することができます。
-
変数には数値と文字どちらでも代入が可能です。変数や型のの宣言は必要ありません。
文字列は「a="string"」のように「"」で囲んだ形で記述します。
文字列の演算は結合(「+」)のみ可能です。
-
変数の配列は、「変数(要素)」の形でカッコを使って指定します。配列を使用するためには、あらかじめdim、sdim命令で宣言を行ないます。
-
プログラムの流れを制御するためのgoto、gosub命令が用意されています。そこで指定するラベルは、行の先頭に「*ラベル名」の形で定義します。繰り返しの記述は通常、repeat〜loop命令で行ないます。これは、C言語のfor、while、doを簡略化したものと捉えることができます。
この他にも、while〜wend、do〜until、for〜next、switch〜caseなどC言語ライクなマクロ命令が用意されています。
詳しくは、「標準マクロについて」を参照してください。
-
命令の定義や、関数を定義することもできるほか、名前空間を分けてソースを再利用するための仕組みが予定されています。
詳しくは、「モジュール」の項を参照してください。
-
作成したスクリプトは[ctrl]+[F9]で実行ファイルに変換することができます。
詳しくは、「EXE,SCRファイルの作成方法」を参照してください。
1.プログラミングガイド
- スクリプトの形式
HSPはプログラム(命令と実行の順序を記したもの)によって動作します。
そのもとになるのがスクリプト(ソースファイル)です。これはテキスト
ファイルの形式で、拡張子は .hsp または、.as になります。
(拡張子 .hsp は、HSP3.0から追加されたものです。)
スクリプトはHSPに付属しているHSPスクリプトエディタ(HSED3.EXE)や、
テキストエディタなどのアプリケーションで作成することができます。
- スクリプトの編集と実行
HSPスクリプトエディタ(HSED3.EXE)を使用すると、簡単にHSPのスクリプトを作成、編集、実行することが可能です。HSPスクリプトエディタを使用した場合は、
1.テキストのスクリプトを書く |
↓ |
2.「コンパイル+実行」のメニューを選ぶか、
ファンクションキーのF5を押して、スクリプトを実行させる |
という手順だけで、簡単にHSPのスクリプトを実行して動作を確かめることができます。
HSPスクリプトエディタ(HSED3.EXE)は、HSPのスクリプト編集用のエデ
ィタです。コンパイルや実行なども自動的に行なうことができます。
HSPスクリプトエディタを使用する場合には、HSED3.EXEと同じディレクトリに
以下のファイルが存在している必要があります。
HSED3.EXE | : HSPスクリプトエディタ本体 |
HSP3.EXE | : HSP実行ファイル本体 |
HSP3DEBUG.DLL | : HSPデバッグモジュールDLL |
HSPRT | : HSPランタイムモジュール |
HSPCMP.DLL | : HSPコードコンパイラDLL |
HSPスクリプトエディタは、本体(HSED3.EXE)とHSP実行ファイル(HSP3.EXE)
が必ず同じディレクトリに存在していなければなりません。
また、実行ファイル(EXEファイル)を作成するためには、ランタイム
ファイル(HSPRT)も、同じディレクトリに必要です。
HSPスクリプトエディタを起動すると、新規のテキスト編集ウィンドウ
が表示されます。あとは普通のテキストエディタと同じように、ファイルをロードしたり、
セーブしたりしながらHSPのスクリプトを記述していきます。
基本的な操作は、Windowsに付属している「メモ帳」とほぼ同じです。
文字列のカット&ペースト、検索などもメニューから選ぶことができます。
編集しているHSPスクリプトを実行させてみるには、メニューから
「コンパイル+実行」を選ぶか、またはファンクションキーのF5を押します。
「実行」またはCTRL+F5を押すと、最後にコンパイルされたスクリプトを実行します。
コンパイル中にエラーが発生した場合は、コンパイル後にエラーの内容と
エラーの出た行番号を知らせるダイアログが表示されます。
例: test.hsp(2) : error 7 : ラベル名はすでに使われています (2行目)
上の例では、「ラベルが重複している」エラーが行番号2で発生したと
いうことを示しています。エラーが発生した場合は、「 カ ー ソ ル」メニューの
「指定行に移動」(またはCTRL+J)を選んで、エラーが発生した行へ移動して
その内容をチェックしてみてください。
一般的な使い方としては、HSPスクリプトエディタで編集、
実行を繰り返しながらスクリプトを作成して、完成したらメニューから
「実行ファイル自動作成」([Ctrl]+[F9])を使って完成したスクリプトを
EXEファイルやSCRファイル(スクリーンセーバー)に変換して1本のソフトができあがります。
HSPのスクリプトエディタでは、以下のファイルを実行時に作成します。
これらのファイルは、コンパイル時にのみ必要なファイルなのでスクリ
プトができあがった時には削除してかまいません。
HSPTMP | : ソーススクリプトのテンポラリファイル |
HSPTMP.I
|
: ソーススクリプトのテンポラリファイル(通常は生成されません)
|
OBJ | : 実行オブジェクトのテンポラリファイル |
ソーススクリプトのアイコンを、HSED3.EXEのアイコン上かまたは、ウィンドウ内にドロップするだけで編集をすることができるようになっています。また、インストーラーからHSPをインストールした場合は、ソーススクリプトのアイコン(「.hsp」の拡張子を持つファイル)をダブルクリックするだけで、ソースを開くことができます。
ソーススクリプトが編集状態になった後は、そのソースファイルが格納されているディレクトリがカレントディレクトリとなります。
-
外部エディタの使用
外部のテキストエディタでHSPのソースファイルを編集したものを手軽に
コンパイル+実行させるために、スクリプトエディタでは「外部ファイル実行」の
ボタンがツールバーの一番右端に用意されています。
これにより、使い慣れた他のテキストエディタを使いHSPのスクリプトを記述
することが比較的容易になります。主な作業手順は以下のようになります。
-
HSPスクリプトエディタを開き、実行させたいソーススクリプトのファイルを開きます(たとえば「test.hsp」など)。一度開いたら、そのソースがあるディレクトリがカレントディレクトリとなるので、あとはタブ上の「閉じる」メニューを選んでスクリプトを閉じてください。
-
別のエディタ(秀丸など)で、さきほどスクリプトエディタで開いたものと同じファイルを開きます。あとは、これを自由に編集してかまいません。さきほどのスクリプトエディタは、そのままにしておきます。
-
編集したスクリプトを実行したくなった場合には、マウスカーソルを移動させてスクリプトエディタの「外部ファイル実行」ボタンを押します。そして、実行させるファイル名を入力するダイアログが出ますので、そこに外部で編集しているソースファイルの名前を入力します。たとえば、「test.hsp」ならば「test」のように拡張の「.hsp」は省略して入力します。
-
「OK」のボタンを押すと、外部で編集されたファイルがコンパイル+実行されます。外部で編集しているソースファイル名の入力は一度しておけば、次からは前の名前を覚えているので再び入力する必要はなくなります。
このような手順で、外部のエディタでスクリプトを編集することができます。この場合、HSPスクリプトエディタは、コンパイル+実行をするためのランチャーのような状態だと考えるといいでしょう。ウィンドウのサイズを小さくして、編集部分をなくしてしまえば画面上にコンパクトに配置することが可能です。
-
ラベル一覧
スクリプトエディタの「カーソル」メニューにある「ラベル一覧」([F11])
を選択すると、現在編集中のスクリプトに含まれるラベルの一覧がリストボックス
に表示され、任意のラベルを選ぶことでダイレクトに該当する行にジャンプすることができます。
スクリプトが大きくなって移動が不便な場合や、どのあたりにラベルを振ったか
忘れてしまった時などに便利です。
-
ワンキーヘルプ
スクリプトエディタで編集している文字列から、HSP命令のヘルプをボタン1つで呼び出す機能が
「ワンキーヘルプ機能」です。
使用方法は、調べたいキーワードにキャレット(エディタ内のカーソル位置)を合わせて、
[F1]キーを押すだけです。
該当する命令の説明、パラメータの意味などが表示されます。
もしキーワードに該当するヘルプがなかった場合は、アルファベット順のキーワード検索ヘルプが表示されます。
サンプルスクリプトが何をしているのかを調べる時、命令の詳細が思い出せない時などに便利な機能です。
ワンキーヘルプは、いくつかの表示方法を選ぶことができます。
標準では、HSPヘルプマネージャによるヘルプ閲覧に設定されています。
HSPスクリプトエディタでは、この他にもhtmlによる表示、Windows HLP形式による表示や、HSPヘルプマネージャによる表示など、4つの形式をサポートしています。
(HSPヘルプマネージャ形式以外は、対応するヘルプデータを別途用意して頂く必要があります)
1. HTML形式 (オプション)
ver2.5までの標準であるHTML形式ヘルプ表示を行ないます。
指定されたディレクトリに拡張子htmのヘルプファイルが必要になります。
2. Windows HELP形式 (オプション)
Windows標準のWinHelpによるヘルプ表示を行ないます。
HSP標準ではサポートされていませんが、ユーザーなどによって作られた
ヘルプデータの表示が可能です。キーワードによる検索に対応しています。
指定されたディレクトリにHSP.HLPというファイルが必要になります。
3. HSPヘルプマネージャ形式 (標準)
ヘルプマネージャを呼び出してヘルプの表示を行ないます。
指定されたディレクトリにHELPMAN.EXEというファイルと、インデックス
データ(idxファイル)およびヘルプデータ(hsファイル)が必要です。
ヘルプマネージャの詳しい説明は、「helpman.txt」のドキュメントをお読みください。
4. Windows HTML HELP形式 (オプション)
Windows98標準のHtmlHelpによるヘルプ表示を行ないます。
HSP標準ではサポートされていませんが、ユーザーなどによって作られた
ヘルプデータの表示が可能です。キーワードによる検索に対応しています。
指定されたディレクトリにHSP.CHMというファイルが必要になります。
これらは、HSPスクリプトエディタの「オプション」ダイアログにある「動作」メニューを選択して、設定することが可能です。
ヘルプのデータは、通常はスクリプトエディタ(HSED3.EXE)の下にある、hsphelpという
ディレクトリに格納されています。もし、他のディレクトリに移したい場合や、
ヘルプ表示をしようとした際にエラーが出る場合は、「オプション」ダイアログにある「ディレクトリ」メニューを選択して、
ヘルプデータのディレクトリを再設定してください。(たとえば、「c:\hsp30\hsphelp」など)
入力が空白の場合は、HSED3.EXEの下にあるHSPHELPというディレクトリを参照します。
ヘルプの標準ビューアーとしてS.Programsさん作成の「HSP HELP Browser II」が同梱されています。
全文検索、グループ別、プラグイン別検索など多機能なヘルプ閲覧が可能になっています。
また、ヘルプファイル(.hsファイル)を追加した場合にも自動的にヘルプキーワードが更新されるようになっています。
「HSP HELP Browser II」およびヘルプファイル、サポートツールについての詳細は、「hhx.txt」「HS_BIBLE.txt」を参照してください。
-
起動ディレクトリ
スクリプトエディタの「オプション」ダイアログにある「ディレクトリ」を選択すると、設定ダイアログが表示され起動時のディレクトリに関するオプションを変更することができます。設定は、以下の中から選択することができます。
1. マイドキュメント (標準)
スクリプトエディタ起動時のカレントディレクトリをマイドキュメントに設定します。
(ただし、Windows95(初期状態)では、マイドキュメントが存在しないため無効になります。)
2. ユーザーが指定したディレクトリ (オプション)
スクリプトエディタ起動時のカレントディレクトリを、ユーザー指定ディレクトリに書かれた場所に設定します。
「参照」ボタンを押すことで、ユーザー指定ディレクトリをブラウズすることが可能です。
3. 指定なし (オプション)
スクリプトエディタ起動時のカレントディレクトリは、システム標準の場所になります。以前のスクリプトエディタ(ver2.6まで)と同様の動作になります。
(Windows2000以降では、以前のディレクトリ位置を記憶します。)
起動ディレクトリの設定は、次回スクリプトエディタを起動した時から有効になります。
-
HSPのしくみ
HSPは、以下のような流れでスクリプトを実行しています。
1.コンパイル
ソーススクリプト(テキストファイル)を解析し、HSP用のオブジェクトファイル(AXファイル)
を作成します。(ここまでの作業はスクリプトエディタ(HSED3.EXE)とコードジェネレーター(HSPCMP.DLL)が行なっています)
2.実行
オブジェクトファイル(AXファイル)を読み込み、それを実行します。
(この部分は、HSP本体(HSP3.EXE)が行なっています)
ソーススクリプトのコンパイルは、瞬時に行なわれオブジェクトファイルを作成します。
オブジェクトファイルは、ソーススクリプトの余計な部分、コメントなどを排除して
コンパクトに、そして高速に実行できる形式になっています。
HSP本体は指定された オブジェクトファイルを読み込み実行するための核となる部分です。
これはHSP3.EXEですべて行われますので、それ以外に余計なDLLやモジュールは必要としません。
もし、あなたがHSPで作ったソフトを配布したいと思ったら、単体で実行できるEXE(実行)
ファイルを作成することができます。EXEファイルを作成すると、
そのファイルをダブルクリックするだけでスクリプトが動作するようになります。
オンラインソフトや同人ソフトとして配布する際には便利な機能です。
詳細は、「実行ファイルの作成方法」を参照してください。
バッチファイルやコマンドプロンプトから直接HSP3.EXEをファイル名指定
付きで実行させることもできます。
hsp3 demo.ax
のように入力すると、"demo.ax"というオブジェクトファイルが実行されます。
HSPでは、HSP3.EXE以外にもいくつかの実行用ファイルが存在します。
これらは、「ランタイム」と呼ばれており、用途によりいくつかの種類が存在します。
詳しくは、「拡張ランタイム」の項目を参照してください。
-
実行ファイルの作成方法
HSPでは、ユーザーが作成したスクリプトや、そこで使用されるデータ
ファイルなどを、ひとまとめにしてEXEファイルを作成することができる
ようになっています。また、EXEファイルの一種であるSCRファイル(スクリーンセーバーモジュール)も同じ手順で作成できます。
スクリプトエディタから現在編集中のファイルをEXEファイルに変換する場合には、メニューから「HSP」→「実行ファイル自動作成」を選択するか、
「CTRL」+「F9」を押すだけでカレントディレクトリに実行ファイルが作成されます。
通常は、「hsptmp.exe」という実行ファイルが生成されますが、ソーススクリプト内のオプション指定により、
ファイル名を始めとして、様々な設定を行なうことができます。
#pack "ファイル名" [PACKFILE追加ファイル指定]
#epack "ファイル名" [PACKFILE追加ファイル指定]
上の例では、packfileに追加されるファイルを指定しています。
指定されたファイルは、実行ファイル作成時にリソースとして一緒にパックされます。
#packは、通常の形式でパックします。#epackは、暗号化してパックされます。
重複したファイルを追加しようとした場合には、無視されます。
「start.ax」は、実行ファイル自動作成の際に自動的に追加されるため特に追加ファイルとして指定する必要はありません。
#pack、#epackで指定されたファイルは、スクリプトからは使用できますが、外部からは見えなくなります。これには次のような効果があります。
・ゲームで使用する画像ファイルなどを取り出せないように保護する |
・各ファイルの無駄なクラスタをなくしディスク容量を軽減する |
・大量のデータファイルがディレクトリにちらばるのを防ぐ |
例:
#pack "a.txt"
#epack "a.bmp"
上の例では、「a.txt」「a.bmp」というファイルを
実行ファイルと一緒にパックし、"a.bmp"は暗号化します。
#packopt キーワード名 パラメーター [自動作成オプション指定]
実行ファイル自動作成の動作を指定します。
キーワード名、の後スペース又はTABを入れてパラメーター
(文字列の場合は「"strings"」のように指定)を記述して下さい。
#packoptで指定できるキーワードは以下の通りです。
キーワード |
内容 |
初期値
|
name |
実行ファイル名 |
"hsptmp"
|
runtime |
使用するランタイム |
"hsprt"
|
type |
実行ファイルのタイプ |
0
|
|
(0=EXEファイル) |
|
|
(1=フルスクリーンEXE) |
|
|
(2=スクリーンセーバー) |
|
xsize |
初期ウィンドウXサイズ |
640
|
ysize |
初期ウィンドウYサイズ |
480
|
hide |
初期ウィンドウ非表示SW |
0
|
orgpath |
起動時ディレクトリ移動無効化SW |
0
|
例:
#packopt type 2
#packopt name "test"
#packopt runtime "hsp3c.hrt"
上の例では、「test.scr」というスクリーンセーバーを「hsp3c.hrt」というランタイムを使用して作成します。
今まで通りに、「packfile編集」からパックされるファイルを選択して
実行ファイルを作成することも可能です。
「実行ファイル自動作成」を行なうと、packfileが自動的に作成されるため、
それまで保存されていたpackfileの情報は上書きされるので注意して下さい。
尚、「start.ax」はデフォルトで暗号化されたものがpackfileに追加されます。
また、「#packopt runtime "ランタイムファイル名"」で指定された
ランタイムファイル(拡張子がhrtのもの)は、hspcmp.dllと同じディレクトリか、
または、runtimeディレクトリに置かれているものが使用されます。
「初期ウィンドウ非表示SW」のオプションで1を指定した場合には、「初期ウィンドウ非表示SW」がONになります。
(詳しくは、「メインウィンドウ非表示EXEファイル」を参照してください。)
「起動時ディレクトリ移動無効化SW」のオプションで1を指定した場合には、「起動時ディレクトリ移動無効化SW」がONになります。
(詳しくは、「ディレクトリ移動の無効化について」を参照してください。)
なお、ver2.55まで行なっていた手動による実行ファイル作成も可能です。こちらの方法は、以下の通りです。
マニュアルでEXEファイルを作成するための手順。(Ver2.55互換の方法)
1. | スクリプトのオブジェクトファイルを作成しておくこと。
この時、最初に実行されるオブジェクトファイル名は、
必ず「start.ax」にしておくこと。これがないと、スクリプトが起動されません。 |
2. |
「PACKFILE編集...」のダイアログで、EXEファイルに含めるための
ファイル一覧(PACKFILE)を作成します。ここでは、start.axなど
EXEファイルに埋め込むためのファイル名をすべて選択しておく
必要があります。 |
3. | スクリプトエディタのツールメニューから「EXEファイル作成」を選択します。
スクリーンセーバーの場合は、「スクリーンセーバー作成」を選択します。
これで、EXEまたはSCRファイルがカレントディレクトリにできあがります。 |
EXEファイルやSCRファイルを作成するには、必ずPACKFILEが必要に
なります。PACKFILEとは、複数のファイルをひとまとめにして、EXE,
SCRファイルの中に埋め込むための定義ファイルです。
この機能を使えば、EXEの中に埋め込まれた画像ファイルやデータファ
イルなどを使うことができ、1ファイルだけの画像や音声を使った
ソフトを作ることができます。(ただしMIDIファイルやDLLなど一部のデータ
ファイルは埋め込むことができません。また、埋め込んだファイルの
内容を変更して上からセーブすることはできません)
もちろん、スクリプトで使用されているすべてのデータファイルを
EXEの中に埋め込む必要はありません。必要だと思ったものだけを、
埋め込み、それ以外は通常の外部ファイルとして置いておいても問題
ありません。ただし、最初に実行されるスクリプト「start.ax」だけは
必ず埋め込んでおく必要がありますので注意してください。
「start.ax」というオブジェクトファイルは、スクリプトエディタのツールメニューで
「START.AXファイル作成」のメニューで作成することができます。
PACKFILEは、スクリプトエディタの「PACKFILE編集...」で簡単にファイルを
選択して編集することができます。ただし、ここで指定するファイル名は
スペースを含まない半角で11文字以内のMS-DOSファイルネームでなければなりません。
HSPでは、次のような順序でファイルのロードを行なっています。
1. |
EXEに埋め込まれたファイルがある場合には、その中からまずロードするファイルを探す。 |
2. |
なかった場合には、カレントディレクトリから探す。 |
3. |
それでもなかった場合には、pathで指定されているディレクトリから探す。Windows、Systemディレトクリなど。 |
4. |
それも見つからない場合は、エラーになります。 |
EXEファイルを作成し終わったら、まず必要最低限と思われるファイル
だけを、新しく作ったディレクトリに移して実行できるかどうかを
確認しておくといいでしょう。通常作業を行なっているディレクトリ
には、EXEに埋め込む前のファイルがカレントディレクトリに置かれて
いるので、PACKFILEで指定を忘れてファイルが埋め込まれていない
場合でも、正常に動作してしまうためです。
「外部ファイル実行」を使用している場合は、「オブジェクトファイルのみ作成」の
チェックボックスをONにしてから、外部ファイル実行をすることで、
オブジェクトファイルの作成が可能です。
-
PACKFILEの編集について
「PACKFILE一覧」ダイアログでは、EXEファイルやSCRファイルを作成する際に必要な
データファイル群を選択、管理することができます。ここで選択されたファイルの
データは、PACKFILEというファイル名でカレントディレクトリに保存されます。
HSP3.0以降では、「PACKFILE一覧」ダイアログを使用せずにスクリプトの記述だけで、
実行ファイル作成のオプションを設定することができるようになっているため、
通常は、このダイアログを使用する必要はありません。
詳しくは、「実行ファイルの作成方法」の項を参照してください。
「PACKFILE一覧」のダイアログは、おおまかに次のように分かれています。
右側の大きなウィンドウが、PACKFILEに含まれるファイル名の一覧になります。
|
左側にはファイル選択ウィンドウがあります。上下2つに分けられていて、上がカレントディレクトリのファイル名一覧。下がディレクトリの一覧になります。
|
中央には、各種機能を持つボタンと、ワイルドカード指定をするためのファイルマスク指定ウィンドウがあります。
|
ファイル選択ウィンドウには、中央のファイルマスクウィンドウ(通常は"*.*")で指定
されたファイルだけが表示されます。たとえば、ファイルマスクを"*.AX"とすると、
拡張子が"AX"のファイルだけが表示されるようになります。
表示されるディレクトリを変更したい場合は、左下のディレクトリ選択ウィンドウを
ダブルクリックしてください。[..]は、ディレクトリを1つ戻ることを、[-a-]や[-c-]
は、ドライブを意味しています。
PACKFILE一覧に、ファイルを追加するには次のように操作します。
1. |
左側のファイル選択ウィンドウで、追加したいファイルをクリックして選びます。 ([CTRL]キーを押しながらクリックすることで複数を選択することも可能です) |
2. |
「追加>>」ボタンを押します。 |
3. |
選択したファイルが、右側のPACKFILE一覧に追加されます。 |
PACKFILEから指定したファイルを除外するには次のように操作します。
1. |
右側のPACKFILE一覧ウィンドウで、除外したいファイルをクリックして選択します。(複数選択はできません) |
2. |
「削除->」ボタンを押します。 |
3. |
選択したファイルが、右側のPACKFILE一覧から除外されます。 |
「全追加>>」ボタンは、ファイル選択ウィンドウに表示されているすべてのファイル
をPACKFILE一覧に追加します。
「全削除->」ボタンは、PACKFILE一覧のファイルをすべてクリアします。
PACKFILEの編集が終了したら、「閉じる」ボタンを押してください。選択された
情報ファイルとして、PACKFILEというファイルがセーブされます。
PACKFILE編集によって、実際のファイルが削除されたりコピーされることはありません。
「キャンセル」ボタンを押すと、ウィンドウが閉じ、いままでの選択はすべて
無効になります。
現在のバージョンでは、PACKFILEは、スペースを含むディレクトリをサポートして
いません。「Program Files」などのスペースを含むディレクトリ下にあるファイルを
指定すると、うまく動作しないことがありますので注意してください。
実行ファイルに含まれるデータに暗号化を施し、外部からの解析や抜き出しに対処できるようになっています。
暗号化を行なう場合には、スクリプトエディタの「PACKFILE編集」ダイアログ
において、PACKFILEに含めるファイルを追加する際に「暗号化」のチェック
をONにしておいてください。PACKFILEに含めるファイル一覧の中で先頭に「+」
がつけられファイルは暗号化の対象になります。
ファイルの暗号化は、「start.ax」などのオブジェクトファイルを始めとして
画像ファイルや、テキストファイルなどHSPから読み込まれるファイルすべてに
適用することができます。PACKFILEに含めることのできないファイル、MIDIや
動画ファイルなどは対象にはなりません。
暗号化されたファイルは、bloadなどの命令で読み込んだ場合には、正常な
内容に復号されます。これをbsaveで保存した場合には暗号化されません。
-
スクリーンセーバーの作成
HSPでは、Windowsのコントロールパネルから選択可能なスクリーンセーバーモジュールの作成が可能です。
これは、特殊な命令を使いフルスクリーン画面を作成し、そこに描画された内容がそのままセーバーとなるというもので、
通常のスクリプトを少し手直しするだけで作成できます。
スクリーンセーバーの詳細については、サンプルファイルのあるディレクトリ
「ssaver」にある、「arusave.hsp」ファイルを開いてみてください。
スクリプトの書き方と実際の作成手順、そしてサンプルスクリプト本体が
書かれていますので参考にしてみてください。
標準の機能では、パスワード保護のないシンプルなスクリーンセーバーが作成可能です。
スクリーンセーバーモジュール(SCRファイル)の作成は、色々な約束事があります。
サンプルのスクリプトなどを参考にしながら、覚えていってください。
スクリーンセーバーの設定画面(ID0)のウィンドウサイズは、通常のHSP実行時とは異なり、
スクリーンセーバー作成時に設定されたウィンドウサイズに固定されます。
-
起動オプションのパース
HSPでは、起動オプションを取り込みスクリプトでそれに応じた
処理をすることができます。これにより、色々な機能を持たせた
EXEをバッチファイルから呼び出したり、EXEファイルのアイコン上
にファイルをドロップするような処理することが可能になります。
この機能をスクリプトエディタ上から試すために、HSPメニューに
「起動オプション...」があります。これを選択すると、スクリプト
エディタ上から起動した時にも、擬似的に起動オプションをつける
ことができます。
実際にスクリプトで起動オプションの内容を調べる場合には、
dir_cmdlineというシステム変数を使用します。詳しくは、システム変数一覧を参照してください。
-
実行ファイルのアイコン書き換え
配布用の実行ファイルは自由にアイコンを書き換えていただいて構いません。
通常、EXEファイルやSCRファイルを作成すると、Windowsから見たアイコンはHSP3.EXEと同じものになっています。
現在のHSPには、アイコンの編集機能はありませんがアイコンを直接書き換えるソフトを使用していただくことができます。
詳しくは、HSPオフィシャルサイト(HSPTV!)にあるHSP関連ツールの項目を参照してください。)
アイコンの色数やサイズ等を変更する場合は、リソースセクションの書き換えに対応したソフトが必要です。
Resource Hacker等のツールをご利用下さい。
-
HSPスクリプトサンプル
HSP3デモのタイトルから「サンプルスクリプトを見る」を選択するか、
HSPがインストールされたディレクトリ(C:\Program Files\hsp31\など)にある、
「sampview.exe」を実行することで、HSPスクリプトサンプルを閲覧、実行
することのできる、サンプルビューアーが起動します。
HSPには、スクリプトエディタからも実行可能なサンプルが多数収録されています。
使用する用途に合わせて、参考になるサンプルを探してみると良いでしょう。
HSPに同梱されているサンプルスクリプトは、すべて自由に改変、再利用しても構いません。
-
メインウィンドウ非表示EXEファイル
EXEファイル作成時に、メインウィンドウを非表示にして起動させることが可能です。
#packopt命令により設定されるオプションで、「#packopt hide 1」と指定して
実行ファイルを作成([ctrl]+[F9])すると、その実行ファイルは起動時にメインウィンドウ(ウィンドウID0)が最初に表示されなくなります。
これは、起動時にウィンドウサイズを変更したり、表示位置を変更しても一瞬だけウィンドウがデフォルトの位置に見えてしまうのを防ぎたいという人のためのオプションです。
このオプションをONにした場合は、「gsel 0,1」などの命令でウィンドウをアクティブ
にしない限りメインウィンドウは表示されません。
メインウィンドウの位置やサイズをちらつきなく変更したい場合や、メインウィンドウ
を表示する必要のないアプリケーションを作りたい時に活用してみてください。
また、メインウィンドウが非表示になっている場合でも、ウィンドウは存在しているので、
メインウィンドウに対して行なった描画やオブジェクト配置は正常に実行され保存されています。
-
ディレクトリ移動の無効化
#packopt命令により設定されるオプションで、「#packopt orgpath 1」と指定して
実行ファイルを作成すると、その実行ファイルは起動時にカレントディレクリ
(作業ディレクトリ)を自分自身のあるディレクトリに移動しなくなります。
このオプションは、通常ONにする必要はありません。
通常の実行ファイル起動時の動作は、起動されたEXEファイルのあるディレクトリに
カレントディレクリ(作業ディレクトリ)が合わせられます。つまり、システム変数
dir_curとdir_exeは同一の場所になっています。
ショートカット起動で指定された作業フォルダを反映したいなどの特殊な事情で、
起動時のカレントディレクリを変更したくない場合にのみ、このスイッチをONにして下さい。
ディレクトリ移動を無効にした状態では、起動時のシステム変数dir_curとdir_exeが
同一でなくなることを前提にスクリプトを作成しておく必要がありますのでご注意下さい。
-
HSP拡張プラグイン・モジュール
HSPでは、拡張プラグイン及びモジュールという形で機能を追加していくことが可能です。
これにより、HSP本体だけでは実現できない処理が可能になります。
HSP拡張プラグインは、標準でDLLまたはHPIの拡張子を持つファイルとなっています。
このファイルは、必ずHSP本体(HSP3.EXE)と同じディレクトリに存在していなければ
なりません。
また、EXEファイル作成の際にPACKFILEに入れて、1つのEXEファイルにすることは
できません。拡張プラグインを使用するEXEファイルを作成した場合は、EXEファイルと
同じディレクトリに拡張プラグインを置いてください。
モジュールは、拡張プラグインと同様に機能を追加するためのファイルですが、
ソーススクリプトに追加する形で使用します。
HSP拡張プラグインと違い、モジュールの場合は、EXEファイルと同じディレクトリに
ファイルを置く必要はありません。
拡張プラグインは、標準で以下のものが同梱されています。
それぞれのプラグインについての使い方詳細は、別途テキストを参照してください。
拡張プラグイン |
HSPEXT.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
標準の機能以外を幅広くサポートする、機能拡張プラグインです。
この拡張DLLを使用することにより、40種類以上の新規命令が追加され、
レジストリ操作、簡易数学関数、シリアル通信、拡張画像操作、
拡張ファイルアクセスなど多くの機能がHSPからコントロールできるようになります。
さらにアプリケーションキャプチャー命令の搭載により、HSP以外のアプリケーションを
コントロールすることが可能になります。
これらの命令は、HSP単体では実現できないようなツール、ユーティリティの
作成に役立つものが多く、さらに高度なアプリケーション開発が可能になります。
詳しくは、別途ドキュメント「hspext.txt」を参照してください。
|
拡張プラグイン |
HSPINET.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
インターネットアクセスのためのプラグインです。
http、ftpサーバーへ手軽にアクセスすることが可能になります。
指定したページにあるデータの取得はもちろん、プロキシサーバーを介してのアクセスや、
更新日時の取得など豊富なオプションが用意されています。
ftp接続時は、ディレクトリ一覧からftpコマンド送信まで細かい操作を行なうことができます。
また、他にもファイルのCRC32、MD5値を取得する命令などが装備されています。
詳しくは、別途ドキュメント「hspinet.txt」を参照してください。
|
拡張プラグイン |
HGIMG3.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
高機能2D・3D画像処理プラグインです。
2D・3Dグラフィック表示をサポートしたDirectX専用のプラグインになります。
スプライトを使用した2Dゲームから、3Dモデルを使った本格的なソフトまで幅広く
利用することができます。
HGIMG3.DLLで追加される主な機能は以下の通りです。
- DirectX、フルカラーモードを対象とした高度な描画システム
- 2Dスプライト、3Dポリゴンなどを共通の命令で設定可能な描画エンジン
- 2Dスプライトの回転拡大縮小、α合成、透明色抜き処理、タイリング(BG表示)
- 3D座標上の2Dスプライトと3Dポリゴンを混在可能なワールド管理
- 3Dの階層構造を持ったポリゴンモデルの管理が可能
- ボーンを用いた3Dワンスキンモデルのアニメーション表示が可能
- アニメ風のレンダリング(トゥーンシェーディング)表示が可能
- BMP、JPG、GIF、PNG、DDS、TGA、TIFF形式のテクスチャサポート
- アンチエイリアスを含めた日本語フォントのテクスチャレンダリング機能
- アルファチャンネルを含むテクスチャ画像のサポート
- スプライトの表示、移動の管理および衝突判定機能
- HSP3に対応した浮動小数によるジオメトリ演算
- イベントリスト登録機能により自由度の高い自律処理を実現可能
- 使いやすい直接描画命令を装備
- ストリーム再生を含むサウンド機能を装備
詳しくは、別途ドキュメント「hgimg3.txt」を参照してください。
|
拡張プラグイン |
Easy3D for HSP3 |
Ver3.0.2.0 |
作者:おちゃっこ |
作者のページ |
DirectXで3Dゲームを作るためのプラグインです。
高度なアニメーション表示や、レンダリング表示を始め、接触判定など
ゲームで必要となる処理をすべて内包した高機能描画プラグインです。
同時に開発されているツール、RokDeBone2と組み合わせることで、
手軽に3Dゲームを開発する環境が整います。
このプラグインは、おちゃっこ氏が製作したものをHSP本体に同梱しています。
プラグインについてのご意見や感想などは、 onion softwareではなく、おちゃっこ氏にフィードバックされるようお願いします。
詳しくは、別途ドキュメント「docs/easy3d/index.htm」を参照してください。
|
拡張モジュール |
d3module |
Ver1.66 |
作者:S.Programs |
作者のページ |
HSPの標準ランタイムで簡易3D表示を行なうためのモジュールです。
DirectX や 3D アクセラレータに依存しないため、多くの環境で同じ実行結果を得ることができるため、
手軽に3D的な表示を利用したい時などに威力を発揮します。
また、d3module と HSPLetを使用すれば、HSP の知識だけで、
ブラウザ上で動作する3Dアプレットを作成できるのもメリットの1つです。
このモジュールは、S.Programs氏が製作したものをHSP本体に同梱しています。
モジュールについてのご意見や感想などは、 onion softwareではなく、S.Programs氏にフィードバックされるようお願いします。
詳しくは、別途ドキュメント「d3module.txt」を参照してください。
|
拡張プラグイン |
HSPCV.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
OpenCV(Intel Open Source Computer Vision Library)が持つ機能を手軽に利用することができるプラグインです。
HSPCVを使用することにより、高度な画像処理やアルゴリズムを扱うことが
できます。他にも、各種フォーマット(PNG、JPEG、TIFF等)の読み書き及び、
ムービー(avi)ファイル操作やUSBカメラ等のキャプチャデバイス読み込みなど
映像に関する多くの機能を提供しています。
HSPCV.DLLで追加される主な機能は以下の通りです。
- 任意サイズの画像イメージ操作(コピー、加算、減算、乗算ほか)
- 画像イメージの高品質なリサイズ、スムージング、回転
- 画像イメージからの閾値による抽出、反転、色変換
- 各種フォーマットに対応した画像ファイルの読み込み、保存
- USBカメラ等のキャプチャデバイス経由の画像取得
- avi動画ファイルの読み込み、保存
- 顔抽出等の画像認識
- 任意の画像に近い領域を抽出するテンプレートマッチング
詳しくは、別途ドキュメント「hspcv.txt」を参照してください。
|
拡張プラグイン |
HSPDB.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
データベースアクセスのためのプラグインです。
ODBCを経由して各種データベースへアクセスすることが可能になります。
対応するODBCドライバがあれば、Oracle、MS-SQL Server、dBase、Paradoxなどの
データベースにアクセスして、SQLによるコントロール、データの受け渡しを行なうことができます。
HSPDBを使用するためには、WindowsにODBCおよび対応ドライバがインストールされている必要があります。
詳しくは、別途ドキュメント「hspdb.txt」を参照してください。
|
拡張プラグイン |
HSPDA.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
各種データアクセスのためのプラグインです。
大量の文字列や数値をまとめてデータ管理する場合に威力を発揮します。
特に数値や文字列のソート機能は、大量のデータでも短時間で並び替えが可能です。
また、ソーススクリプトで使用している変数データの一部またはすべてをファイルに書き出し、
読み込みを行なう機能を持っています。
その他にも、CSV形式のファイルを配列に変換したり検索する機能、実数の乱数発生などが用意されています。
詳しくは、別途ドキュメント「hspda.txt」を参照してください。
|
拡張プラグイン |
HSPDX.DLL |
Ver3.1 |
作者:おにたま/Shinagawa |
作者のページ |
DirectX対応の2D描画プラグインです。
豊富なスプライト制御命令を持っているので、面倒な角度ごとの移動、自由落下、衝突判定などを1つの命令で実行できます。
これにより、2Dキャラクタを使ったゲーム、デモなどの作成を手軽に行なうことができます。
このプラグインは、Shinagawa氏が改変、更新したものをHSP本体に同梱しています。
プラグインについてのご意見や感想などは、 onion softwareではなく、Sinagawa氏にフィードバックされるようお願いします。
詳しくは、別途ドキュメント「hspdx.txt」を参照してください。
|
拡張プラグイン |
HSPCMP.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
HSPシステム機能を持つプラグインです。
スクリプトエディタが持つHSP関連機能(コンパイル、実行、オブジェクト作成、実行ファイル作成)
をコントロール可能です。HSPのシステム機能を、HSPのスクリプトから制御することで、
それぞれのユーザーに合った独自のカスタマイズやバッチ処理が可能になります。
HSP3.1の新機能である、AHT(拡張テンプレート)のためのサポート機能も持っています。
詳しくは、別途ドキュメント「hspcmp.txt」を参照してください。
|
拡張プラグイン |
HSP3IMP.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
HSPランタイム機能を持つプラグインです。
HSP3IMP.DLLの動作画面は、指定されたウィンドウの子ウィンドウとして機能するので、
パーツを貼り付ける要領で、HSP3の画面を利用することが可能です。
また、HSPだけでなく、C/C++といった一般的な言語で作成されたアプリケーションに
HSPの機能を付加することができます。
詳しくは、別途ドキュメント「hsp3imp.txt」を参照してください。
|
拡張プラグイン |
HSPOGG.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
DirectSoundに対応したサウンド再生のためのプラグインです。
HGIMG3で使用することができるサウンド機能命令(dmm〜)と同等の機能を持っています。
3D機能などは使用しないが、サウンド機能のみ利用したい時や、
他の描画系プラグインと組み合わせたい時などに使用することができます。
詳しくは、別途ドキュメント「hspogg.txt」を参照してください。
|
拡張プラグイン |
HSPSOCK.DLL |
Ver3.1 |
作者:おにたま |
作者のページ |
TCP/IPソケット通信用プラグインです。
この拡張DLLを使用することにより、LANやインターネットを通じてデータの送受信を行なうことが可能になり、
簡単なクライアント・サーバーソフトを作成することもできます。
他のマシンとのコミュニケーションに、インターネットのクライアントに、ネット対応のゲームなど多くの場面で活用することができるでしょう。
詳しくは、別途ドキュメント「hspsock.txt」を参照してください。
|
拡張プラグイン |
HGIMG.DLL/HGIMGX.DLL |
Ver2.61 |
作者:おにたま |
作者のページ |
HGIMG3よりも古い形式の画像処理プラグインです。
このプラグインは、HSP2.61でサポートされていたもので、互換性の問題などで、
HGIMG3が使用できない場合に利用することを想定しています。
通常は、HGIMG3が上位互換で作成されているので、そちらをご使用下さい。
簡単なものであれば、HGIMG.DLL用のソースは、そのままHGIMG3に移行することができます。
HGIMG.DLLはフルカラー、パレットモードでの2D・3Dグラフィック表示をサポートします。
スプライトを使用した2Dゲームから、3Dモデルを使った本格的なソフトまで幅広く
利用することができます。HGIMG.DLLで追加される主な機能は以下の通りです。
- フルカラー、パレットモード、DirectXの有無などを切り替え可能なアーキテクチャ
- 2Dスプライト、3Dポリゴンなどを共通の命令で設定可能な描画エンジン
- 回転拡大縮小、α合成、透明色抜き処理、タイリング(BG表示)などの特殊効果サポート
- 3D座標上の2Dスプライトと3Dポリゴンを混在可能なワールド管理
- 3Dの階層構造を持ったポリゴンモデル表示、およびアニメーション管理
- 文字フォントテクスチャをもとにメッセージを合成表示
- スプライトの表示、移動の管理および衝突判定機能
- await命令より細かい単位でのウェイトと処理の負荷検出機能
- CPU処理や描画の負荷が変わってもアニメーションの速度を一定に保つ(フォールオフレンダリング)
- 32bit float精度によるジオメトリ演算
- MX形式、DXF形式による3Dモデル表示、MA形式によるアニメーションデータの読み込み
詳しくは、別途ドキュメント「hgimg.txt」を参照してください。
|
HSP拡張プラグインは、仕様が公開されていて、ユーザーの方たちが制作した
多くのプラグインが存在します。
HSPの可能性を大きく広げるプラグインが、HSPオフィシャルホームページでも多数紹介されています。
HSP拡張プラグインを作成するための詳細な仕様については、HSP開発キット(HSPSDK)を別途ダウンロードして
マニュアルを参照してください。
-
拡張ランタイム
「HSP拡張ランタイム」は、「HSP拡張プラグイン」の機能をDLLファイルなしで実行できるようにするためのシステムです。
簡単に言えば、拡張プラグインを使用したプログラムであっても、
EXEファイルと一緒にDLLファイルを同梱する必要がなくなります。
ただし、どんなDLLでも可能なわけではありません。仕様にもとづいて作られた
「HSP拡張ランタイムモジュール(HRTファイル)」がサポートするDLLのみ、
実現が可能です。
「HSP拡張ランタイム」により、HSPで作られたプログラムを
実行ファイルに変換する際の選択に、幅が広がります。
たとえば、COM機能を使用していないプログラムで実行ファイルを
作成する場合、「コンパクト版HSPランタイム」を使ってEXEファイルを作成すれば、
通常よりもサイズが小さく抑えられます。
公開するEXEファイルのサイズが少しでも小さい方がいい人にもお勧めします。
HSPフルセットには以下の拡張ランタイムが同梱されています。
使用する際の参考にしてください。
[hsp3c.hrt]
コンパクト版HSPランタイムです。
標準のHSP3から、COM関連機能、及びgrect、grotate、gsquare命令が削除されています。
これらの機能が必要がない場合に実行ファイルをコンパクトにすることができます。
[hsp3cl.hrt]
コンソール版HSP(HSPCL)ランタイムです。
コンソールアプリケーション専用の実行ファイルを作成する際に使用します。
[hsp3hg.hrt]
HGIMG3の機能を内包したランタイムです。
HGIMG3プラグインで作成したアプリケーションの実行ファイルを作成する際に使用します。
-
デバッグウィンドウ
スクリプト実行中にHSPの状態や変数の内容をチェックするためのデバッグウィンドウが搭載されています。
これは、スクリプトエディタの「HSP」メニューの「Debugウィンドウ表示」のスイッチを入れることで、実行時に常に表示させておくことが可能です。また、このスイッチが入っていない場合でも、HSPでエラーが起こった場合には自動的にポップアップ表示されます。
デバッグウィンドウの左上のウィンドウで表示カテゴリーを選択します。
選択された情報が、下のウィンドウに表示されます。
情報は、カテゴリーの選択をした時点でのものになります。内容は、
自動的には更新されないので、別な時点での情報を知りたい時には、再び
カテゴリーのウィンドウをクリックしてください。
[全般]
現在実行されている行、HSPの状態(実行モード)などが表示されます。
また、gosubやloopのネストレベル(深さ)を始めとするシステム変数も表示されます。
[ログ]
logmes命令によって送られたメッセージを表示します。
デバッグのためのメッセージなどを確認することができます。
[変数]
定義されている変数の内容を表示します。
「配列変数を表示」のチェックボックスを入れると、配列の内容を
一覧で表示します。また、「変数のダンプ」のチェックボックスを
入れることで、変数バッファの内容を16進数で表示します。
変数のダンプや配列の表示は、あまりにも大きなサイズが確保されて
いる変数の場合は、すべてが表示されない場合があります。
文字列型の変数に、バッファの容量を越えた文字列が代入されている
場合は、警告メッセージが表示されます。その場合は、sdim命令
などで確保するバッファのサイズを大きくしてください。
「モジュール変数を表示」にチェックがついている場合は、
モジュール内部で使用されている変数の内容も表示します。
また、「表示項目をソート」にチェックがついている場合は、
変数名リストがアルファベット順にソートされ検索がしやすくなります。
[実行]ボタン
assert命令や[停止]ボタンによって一時的に停止されたスクリプトの実行を再開します。
[次行]ボタン
assert命令や[停止]ボタンによって一時的に停止された状態から、
1行だけスクリプトの実行を再開します。
これにより、1行単位で実行内容を確認するステップ動作を行なうことができます。
[停止]ボタン
実行中のスクリプトを一時的に停止します。
awaitやwait命令などの時間待ち部分でのみ停止させることができます。
-
HSP拡張マクロ
HSP拡張マクロは、標準的にサポートされているマクロの定義セットで、
commonフォルダ内の「hspdef.as」ファイルが設定を行なっています。
スクリプトエディタのHSPメニューで、「HSP拡張マクロを使用する」がチェックされている時に有効となります。
HSP拡張マクロは、特別な理由がない限りはチェックを入れた状態にしておいて下さい。
-
HSP3支援モジュール
commonフォルダ内には、多くの「HSP3支援モジュール」が置かれています。
これは、ソースの先頭で#include命令により読み込むことで、便利な機能を追加したり、
マクロ定義を行なうためのモジュールになっています。
HSP3支援モジュールとして、標準で以下のファイルを利用可能です。
hsp3util.as
HSP3で使用するための便利な命令が定義されています。
文字列を1文字づつ表示したり、修飾を行なうtext命令、emes命令や、
日付や時刻を文字列で取得するgettimestr、getdatestr命令、
BMPファイルのパレットを取り出すbmppalette命令が追加されます。
また、配列と複数行文字列を相互変換するための命令も装備されています。
詳細については、「hsp3util.as」ファイル内を参照してください。
hsp261cmp.as
HSP2.61互換の命令セットを定義します。
あくまでも、HSP2.61に近い記述が可能になるだけで、一部の命令や動作は
完全な互換にはならないので、ご注意下さい。
form_decode.as
cgiで送信されたURLエンコードを元の文字列に戻すためのform_decode命令が追加されます。
HSPCLを使用してcgiを作成する時に便利なモジュールです。
詳細については、「form_decode.as」ファイル内を参照してください。
mod_getenv.as
環境変数の値を変数に取得するためのgetenv命令が追加されます。
cgiなどで実行時の環境変数を参照したい時に利用することができます。
詳細については、「mod_getenv.as」ファイル内を参照してください。
hspmath.as
高度な数学計算を行なうための定数やマクロが定義されています。
πなどの定数や、ラジアン・度の相互変換などの関数が追加されます。
詳細については、「hspmath.as」ファイル内を参照してください。
mod_joystick.as
接続されているジョイスティックから各種情報、ボタンの状態などを取得するための
joyGetPosEx命令が追加されます。
詳細については、「mod_joystick.as」ファイル内を参照してください。
obj.as
HSP2.61同梱のllmod.asでサポートしていた、
配置オブジェクトに関する命令
(objgray、p_scrwnd、getobjsize、resizeobj)を追加します。
詳細については、「obj.as」ファイル内を参照してください。
advapi32.as
comctl32.as
comdlg32.as
gdi32.as
kernel32.as
shell32.as
user32.as
winmm.as
同名のWindows DLLがエクスポートしているAPIを定義したファイルです。
引数はすべてsptrになっているので、API仕様に従って適切な値をユーザー側で渡す必要があります。
WIN32APIについての知識や資料が別途必要になります。
- スクリプトの色分けとタブ
HSPスクリプトエディタ(HSED3.EXE)では、キーワードの色分けと、タブ切り替えによる複数ファイルの編集に対応しています。
初期状態でキーワードは、以下の条件で色分けされます。
キーワード種類 色
---------------------------------------------------
コメント 緑色
命令/関数/システム変数 水色
プリプロセッサ命令 うすい水色
文字列 黄色
ラベル定義 紫色
その他 白色
キーワードや背景の色は、オプション設定のダイアログでユーザーが変更することができます。
また、複数ファイルを読み込み、タブで切り替えながら編集することが可能です。
タブを直接クリックするか、「ウィンドウ」メニューで編集しているファイルを切り替えることができます。
- HSPLetの利用について
HSP3.1では、山田 雄己(Yuki)さん製作によるHSPLetを標準で同梱しています。
HSPLetは、HSPの実行をJavaランタイム上で行なうためのシステムで、
これによりWebブラウザでの実行及び、Windows以外のシステムで動作させることが
可能になります。(いくつかの制約と互換性についての注意点があります)
HSPLetについての詳細は、HSPLetマニュアルを参照してください。
HSPスクリプトエディタから、直接HSPLetを使って実行させることが可能です。
スクリプトの先頭に、
#runtime "hsplet3"
を記述することで、HSPLetによる動作に切り替わります。
HSPLetによる実行時は、htmlブラウザが起動し、その中に実行結果が表示されます。
また、その際にHSPLetの簡易サーバーウィンドウが同時に表示されます。
これは、html表示を行なうために動作しているモジュールです。HSPLet実行時以外には必要ありませんので、テスト実行が終わったら閉じてしまって問題ありません。
HSPLetについてのご意見及び、報告については開発されている山田 雄己(Yuki)さんの
方に直接お送りいただくようお願いします。
Group Finity (HSPLet配布元)
http://group-finity.com/
- かんたん入力
HSP3.1から、スクリプトエディタの右クリックメニューに「かんたん入力」項目が
追加されています。これは、利用したい機能の内容を選ぶだけで、パラメーターや
オプションの選択を別ダイアログのユーザーインターフェースによって行なう
ことのできる初心者向けのアシスト機能です。
たとえば、「色を指定」という機能を選択した場合には、指定する色をR,G,Bまたは16進数により入力するためのボックスや、
色見本の中から指定することのできるダイアログが現われます。
ユーザーが指定したい色をダイアログに入力して「OK」ボタンを押すことで、
スクリプトエディタのカーソル位置にスクリプトが自動的に生成されます。
「かんたん入力」は、自分が利用したい機能のキーワードが不明な時や、
フォント名、カラーコードなど直感的でないパラメーターを入力する補助となります。
「かんたん入力」機能は、HSP3.1に搭載されているHSPテンプレートツール(AHT)をベースに
作られています。「かんたん入力」で表示されるダイアログや生成されるソースの
内容は、すべて「ezinput」フォルダ内にあるAHTファイル(拡張子が「.aht」ファイル)
によって定義されています。このファイルをユーザーが作成することで、
「かんたん入力」で利用できる項目も自由にカスタマイズすることが可能です。
AHTファイルについての詳細は、docsフォルダにある「aht.txt」を参照してください。
また、「かんたん入力」及び「AHTマネージャー」を構築するベースとなる
モジュール「mod_aht.as」が同梱されています。
「mod_aht.as」を使用することにより、AHTファイルの内容を手軽に編集、参照
することができるようになります。
AHTについての詳細は、別途ドキュメントaht.txtを参照してください。
- Peasエディタ
HSP3.1では、スクリプトエディタに替わるもう1つのスクリプト作成環境
「Peasエディタ」が同梱されています。
これは、メニューから「Peasエディタ」を選択するか、または直接
「ahtman.exe」から起動させて使用します。
「Peasエディタ」は、メイン画面の「追加」ボタンからパーツを選択し、
「編集」ボタンによりパーツの内容を編集することができます。
これは、ahtフォルダに含まれているAHTテンプレートファイルを1つの
アイコン(パーツ)と見なして、マウス操作と簡単なパラメーター調整だけで、
視覚的にスクリプト作成を行なう支援をするものです。
「Peasエディタ」は、HSPテンプレートツール(AHT)の技術をベースに
作成されており、モジュール「mod_aht.as」とともにすべてHSPで作成
されています。
「Peasエディタ」は、ソースコードが公開されており、誰でも自由に機能の
改編、拡張、再配布を行なうことが可能です。
「Peasエディタ」の詳細は、別途ドキュメントpeas.htmlを参照してください。
2.基本文法
-
HSP言語の規定
HSPでは、文法を大きく2つのカテゴリに分けています。
・基本文法
プログラム作成のために必要な最低限の文法。
初心者の方や、小さなプログラムを作成する場合には、基本文法のみを
使用しておいて問題ありません。
・拡張文法
HSPの機能を拡張するための仕組みを含む文法。
他のユーザーに向けて機能を提供する場合や、大規模なプログラムを
作成する場合に必要となります。
初心者の方は、拡張文法を特に覚えなくても支障ありません。
中上級者の方は、ステップアップのために拡張文法をマスターして
いくことをお勧めします。
このドキュメントでは、基本文法、拡張文法ともに詳しい仕様を
解説しています。
-
命令の書式
スクリプトはどのような順番で、どのような処理をするかをまとめた
テキストファイルです。その中の、どのような処理をするかを指示する
ものを命令(ステートメント)と呼びます。
BASICやCと同じように、命令はファイルの先頭行から下に向かって順に
実行されていきます。
命令(ステートメント)は、プログラムの流れを制御したり、画面や
ファイルなどの入出力を行ないます。
プログラム制御命令、入出力制御命令など多くの命令が存在します。
スクリプトはアルファベットの大文字・小文字を区別しません。
どちらで記述してもかまいません。
例:
randomize
上の例では、randomizeという命令を実行します。
命令には、多くの場合実行内容を細かく指定するためのパラメーターが付加
されることになります。
-
パラメータ
HSPでは、命令の後にパラメータを付加する書式が基本になっています。
命令に付加するパラメータと、命令の間はスペースで空けておく必要があり
ます。またパラメータが複数ある場合は、「,(カンマ)」で区切ります。
たとえば、
width 640,480
というスクリプトは、「width」が命令(ステートメント)にあたり、
640と480という数値がパラメータになります。この組み合わせで、
「ウィンドウサイズを640x480にする」という意味になります。
例 : ドキュメントファイルの「命令のリファレンス」の説明で、
statement p1,p2
p1=0〜3(1)
p2=0〜65535(0)
とあった場合は、この命令にはp1,p2の2つのパラメータが指定でき、
p1のとれる値が0〜3まで、省略した場合の値が1。p2のとれる値が、0〜
65535まで、省略した場合の値が0であることを示しています。
パラメータの省略をすることもできます。上の例では、p2の値を省略して
statement 3
と書くこともできます。その場合は、省略した時の値が自動的に設定
されて、
statement 3,0
と書いたのと同じことになります。
パラメータの途中だけを省略する場合は、
statement ,100
のように省略したパラメータを飛び越えて別のパラメータを指定すること
ができます。この場合は、
statement 1,100
と書いたのと同じことになります。
省略時の値は、命令ごとに異なります。
statement
とだけ書いてパラメータを指定しなかった場合でも、自動的に「1,0」と
いう値が設定されます。基本的にパラメーターは重要な順番に並んでいる
ので、すべてを省略することはあまりありません。また、文字列を指定す
るパラメータや、変数名でなければならないパラメータなどは省略ができ
ないことがあります。
-
マルチステートメント
命令と命令の間を:( コ ロ ン)で区切って1行に複数の命令を記述することも
可能です。これをマルチステートメントと呼びます。たとえば、
例:
mes "こんにちは" : mes "さようなら"
は、
mes "こんにちは"
mes "さようなら"
のように書くのと同じことです。
このように複数の命令を1行にまとめて書くことができます。
1行の長さに制限はありませんが、テキストエディタで見やすい程度に納めるようにした方がいいでしょう。
-
コメント
1行の中で;( セ ミ コ ロ ン)以降はコメント(注釈)とみなし無視されます。
例:
pos 320,100 : print "(^_^)" ; 顔マーク表示
CやJavaと同様のコメント記述が可能です。
1行の中で//(ダブルスラッシュ)以降はコメントとみなし無視されます。
「/*」から「*/」までの間は、コメントとみなし無視されます。
例:
pos 320,100 : print "(^_^;)" // 顔マーク表示
/* ここはコメントです */ goto *start
スペース、タブは見やすくするために自由に入れることができます。
-
式
命令のパラメータを指定する場所では、以下のような演算子を含む式を
書くことができます。
-2147483648〜2147483647 10進整数(32ビット)
-???.???〜???.??? 10進実数(64ビット倍精度)
$0〜$FFFFFFFF 16進整数
0x0〜0xffffffff 16進整数
%0〜%111111... 2進整数
0b0〜0b111111... 2進整数
'A' 文字コード(8ビット整数値)
"文字列" 文字列
変数 値を保持するキーワード
関数 値を変換するキーワード
+,-,*,/ 加算,減算,乗算,除算
&,|,^ 論理演算(and,or,xor)
\ 割り算の余り
=,<,>,! 条件式(同じ,小さい,大きい,同じでない)
==,<=,>=,!= 条件式2(同じ,以下,以上,同じでない)
<<,>> 左、右方向にビットシフト
たとえば、
statement 1+2+3+4
は、
statement 10
と書いたのと同じになります。これを数式といいます。
数式の評価は優先順位の高い順に行なわれます。
たとえば、
2+7*2
は、16になります。
式の評価では、以下の演算子の中で優先順位が高いものを優先します。
*,/ 4 高い
+,- 3
<<,>> 2
比較演算子 1
&,|,^ 0 低い
計算の順番を変更したい場合はカッコを使って、
(2+7)*2
のように書けば、カッコ内の2+7が先に計算されて結果は18になります。
条件式や論理演算は、後に説明する条件判断の際に使われます。
カッコは、いくつでも多重に使うことが可能です。もし、カッコの使い方が
間違っている場合は、エラー(priority error)が表示されます。
また、入力した値を加工するための関数を式の中で使うことができます。
整数値、実数値、文字列、関数を混在した式を書くことも可能です。
その場合は、計算する最初の項に合わせて、後の項が型変換されます。
たとえば、「8 + 4.5」のような計算は、最初の8(整数)に合わせて4.5は、4(整数)として扱われます。
逆に、「4.5 + 8」の場合は4.5(実数)に合わせられて12.5という計算結果になります。
数値が整数か、実数かは小数点があるかないかで区別されます。
実数型での演算を行なう場合には、明示的に「8.0 + 4.5」のように小数点を
入れるようにする必要があります。
また、「1.0e+10」のように「e」に続けて指数部を指定することで大きな桁を持つ実数を表現することも可能です。
ただし、実数値の扱いは整数値に比べてメモリ効率や速度のコストが高くなりますので注意してください。
「'」で囲まれた文字は、文字コードを示す整数値として解釈されます。
長い文字列や全角文字を指定した場合でも、最初の1バイトのみがコードとして解釈されます。
「'A'」の場合は、「A」を示す文字コード(65)となります。
その際に、文字列と同様の「\」記号による特殊コード(「\n」等)を記述することができます。
「'」そのものの文字コードを示す場合は、「'\''」を指定します。
また、「\」の文字コードを示す場合は、「'\\'」を指定してください。
-
文字列
命令のパラメータに文字列を指定する場所では、文字列を"( タ ゙ フ ゙ ル ク ォ ー テ ー シ ョ ン)
で囲むことで文字列を記述することができます。
例:
mes "This is test message..."
「+」を使って文字列同士、または変数との結合をすることができます。
たとえば、
"ABCD"+"EFGH" は、 "ABCDEFGH" と同じになります。
"VALUE="+val は、 "VALUE=5"(変数valが5の場合)になります。
「\」は特殊な意味を持つキャラクタとして解釈されます。
「\n」 は、改行して次の行にするという意味になります。
「\t」 は、TABコードを表わします。
「\r」 は、リターンコード(0x0d)を表わします。
「\"」 は、ダブルクォート(")を表わします。
「\\」 は、ただの「\」になります。
ですから、ディレクトリを示すための文字列、たとえば、
"C:\WINDOWS\SYSTEM" などの文字列は、
"C:\\WINDOWS\\SYSTEM" と記述しないと認識されません。
また、1行に収まりきらない長い文字列をまとめて記述することも可能です。
mes {"
ここには、1行まるまる直接メッセージを
書いてもいいです。
"}
このように、「{"」から「"}」までの間はすべて文字列として解釈されます。
複数行に渡っている時は、1行の最後に改行コードが挿入されます。
-
変数
任意の名前をつけた変数を扱うことができます。変数とは、代入により内容
を変化させることのできる容れ物のようなものです。
変数は、アルファベットまたは日本語で始まる59文字(半角)以下の文字列で
識別されます。変数は代入により数値や文字列などさまざまな情報を格納することができます。また、1つの変数の中にインデックスをつけて複数の情報を格納するための、配列変数を利用することができます。
数値として記憶できる範囲は、数式で指定できる値と同じ-2147483648から2147483647までの32ビット整数値または、実数値(64ビット倍精度)です。
変数にラベルと同じ名前や、命令と同じ名前は使用できません。変数は、代入命令や、数式の中で使うことができます。
代入命令は次のようなものです。
例:
x=100 ; 変数xに100という数値を代入
y=200 ; 変数yに200という数値を代入
命令の数値指定として使うと、
例:
x=100:y=200:pos x,y ; (100,200)に移動
のようになります。
変数に値を代入すると、以前まで記憶されていたものは消され、新しい
値が保持されることになります。
変数に文字列を代入する場合にも同じように、
例:
x="strings" ; 変数xに「strings」という文字列を代入
print x ; 変数xの内容を画面に表示
代入は"="の先にあるものが数値ならば数値を、文字列ならば文字列として
記憶します。変数には、記憶しているものが文字列だった場合の文字列型や、
数値だった場合の数値型、実数(小数)だった場合の実数型などいくつかの状態があります。
パラメーターが数値を必要としている命令に文字列型の変数を指定したり、
パラメーターが文字列を必要としている命令に数値型の変数を指定すると、「Type mismatch」エラーが出てしまうので注意してください。
いくつかの特殊な代入命令があります。「変数」+「演算子」+「=」+「パラメーター」でもとの変数に対して指定された演算子とパラメーターの計算を行ないます。
例:
a=10 ; 変数aに10を代入
a+=2 ; 変数aに2を加算(a=a+2と同じ)
上の例では、変数aは12という値になります。
このように、「+=」を使用すると「+=」以降が変数a自身に対して加算されます。
同じように「-=」や「*=」などすべての演算子を使用することができます。
(また、「=」を省略して「変数」+「演算子」+「パラメーター」の形式でも同様の動作になります。ただし、この書式はC言語やJavaなどとの互換性がないため推奨はされません。)
単純な加算と減算は、以下の書式で行なうことも可能です。
例:
a+ ; 変数aに1を加算
a- ; 変数aから1を減算
「変数」に「+」または「-」を付加することで+1と−1を実行します。
(C言語やJavaと互換のある書式、a++やa--でも同じ結果になります。ただし、式の中で使用することはできません)
変数の型を特定するために、変数の型を強制的に変更することができます。そのための関数がintとstrです。
例:
a=int(a) ; 変数aを数値型にする
b=str(b) ; 変数bを文字列型にする
c=double(c) ; 変数cを実数型にする
変数の型を変更しても、できる限りその内容を保持しようとします。
"123"という文字列を含んだ変数を数値型に変更すると、123という数値になりますし、逆に123という数値型の変数を文字列型に変更すると"123"という文字列に変換されます。
-
配列変数
配列変数を使うと、変数に記憶させるものに対して番号をつけて大量に管理することができるようになります。
通常は、変数aには1つの数値、または文字列しか記憶させることができません。
しかし配列変数を使えば、これに複数の数値、または文字列を記憶させることができます。配列変数は以下のようにして使われます。
例:
a(0)=10 ; 変数aの要素0に10を代入
a(1)=20 ; 変数aの要素1に20を代入
a(2)=30 ; 変数aの要素2に30を代入
変数の後にカッコをつけ、その後に数値による番号を指定します。
この番号を「配列の要素」といい変数の中のどこに記憶されているかを特定します。要素は通常0から始まる整数値を指定します。
配列変数の要素は、代入された時点で自動的に確保されます。
たとえば、「a(2)=5」のように書いた場合は、a(2)が自動的に確保され
5という値が代入されます。ただし、「a(1000)=0」と書いた場合には、
a(0)〜a(1000)までの要素すべてがメモリに確保されてしまうので要素の
数値は、0から順番に使用するように注意してください。
また、配列要素の確保が行なわれるのは代入時のみですので、
a=b(10)と書いた場合に、配列変数bに要素10が確保されていない場合は、
エラーになるので注意してください。
なお、配列要素の自動確保で次元を拡張することはできません。
配列要素をあらかじめ確保しておきたい場合には、dim命令を使用します。
例:
dim a,20 ; 変数aの要素は0〜19まで使えるようになります
また、dim命令を使って多次元配列を作成することも可能です。
例:
dim a,10,5 ; 変数aは2次元配列が使用できます
a(0,0)=1 ; 要素(0,0)に1を代入
a(1,0)=2 ; 要素(1,0)に2を代入
a(0,1)=3 ; 要素(0,1)に3を代入
この場合は、「変数名(1つめの要素 , 2つめの要素)」のように","(カンマ)を2つ使って要素を指定してください。同様にdim命令を使って4次元までの配列を作成することができます。
変数の型が連想配列をサポートしている場合には、要素として整数値以外を指定することができます。
例:
a("test")=10 ; 変数aの要素"test"に10を代入
a(5.5)=20 ; 変数aの要素5.5に20を代入
要素が変わっても同じ変数なので、要素ごとに変数の型を混在させることはできません。変数aが文字列型ならば、すべての要素も文字列型となります。数値型も同様です。
例:
a(0)=0
a(10)="string" ; エラーになります
配列変数を示す別な書式もあります。
例:
a.5=123 ; 変数aの要素5に123を代入
この書式は、HSP ver2までの書式と互換性があります。「a.5」は、「a(5)」と同じ意味になります。多次元配列の場合は、「a.1.0」のように"."(ピリオド)で区切ります。
この書式では、"."(ピリオド)の後に続く1項目だけを要素として認識します。
要素に式を使いたい場合は、「a.(a+5)=10」のようにカッコでくくる必要があります。
文字列型の変数に配列を使う場合にはsdim命令を使います。
sdim命令では、まず扱う文字列の初期文字数を指定してから、要素の数を
指定します。たとえば、
例:
sdim a,32,5 ; 変数aは32文字までの文字列を5つの要素で扱えます
a(0)="test"
a(1)="message"
のように変数名の次に2つのパラメータを指定します。
また、sdim命令により文字列の初期文字数を確保することもできます。
例:
sdim a,200 ; 変数aは200文字までの文字列を扱えます
これは配列変数ではなく、通常の変数になります。
文字列型の変数に代入されるデータが、初期文字数をオーバーした場合には
自動的に再確保が行なわれますので、初期文字数を気にする必要はほとんどの
場合ありません。
代入するパラメータに「,」をつけることで、配列変数への代入を連続して
行なうこともできます。
例:
tmp=1,5,10 ; 配列に連続して代入をする
上の例では、「tmp(0)=1:tmp(1)=5:tmp(2)=10」と同じことになります。
配列の途中から代入を開始するには、
例:
tmp.2=10,20,50 ; 要素2から連続して代入をする
この例では、「tmp(2)=10:tmp(3)=20:tmp(4)=50」と同じことになります。
「tmp="ABC","DEF","GHI"」のように文字列を連続して代入することもできます。
-
関数
関数は、パラメーター式の中である値をもとに変換された値を得るために使用します。
関数を示す名前に続いてカッコ内にパラメーターを指定することで、結果を返します。
例:
x=sin(3.141592)
上の例では、3.141592のサイン(正弦)値を求めて変数xに代入します。
関数には、三角関数などの算術関数から、文字列を扱うものなど様々な種類があります。
関数は、必ず式の中で使う必要があります。命令(ステートメント)として使用することはできません。
標準で以下のような関数が用意されています。
関数名 返値 内容
--------------------------------------------------------------
int 整数 パラメーターを整数に変換する
rnd 整数 0〜(パラメーター-1)の乱数を発生する
strlen 整数 文字列の長さを返す
length 整数 変数の持つ配列要素数を返す(1次元)
length2 整数 変数の持つ配列要素数を返す(2次元)
length3 整数 変数の持つ配列要素数を返す(3次元)
length4 整数 変数の持つ配列要素数を返す(4次元)
vartype 整数 変数の型を返す
varptr 整数 変数のデータを示すアドレスを返す
varuse 整数 変数の使用状況を返す
gettime 整数 日付・時間を返す
str 文字列 パラメーターを文字列に変換する
dirinfo 文字列 特定のディレクトリ情報を返す
peek 整数 バッファから値を取り出す
wpeek 整数 バッファから値を取り出す
lpeek 整数 バッファから値を取り出す
double 実数 パラメーターを実数に変換する
sin 実数 サイン値を返す(パラメーター単位はラジアン)
cos 実数 コサイン値を返す(パラメーター単位はラジアン)
tan 実数 タンジェント値を返す(パラメーター単位はラジアン)
atan 実数 アークタンジェント値を返す
sqrt 実数 ルート(平方根)値を返す
logf 実数 対数値を返す
expf 実数 指数値を返す
abs 整数 整数の絶対値を返す
absf 実数 実数の絶対値を返す
limit 整数 整数値を範囲内に収める
limitf 実数 実数値を範囲内に収める
sysinfo 整数 システム情報を取得します
ginfo 整数 ウィンドウに関する情報を取得します
objinfo 整数 ウィンドウオブジェクトに関する情報を取得します
-
ラベル
プログラム上の位置を示すためにラベルとして名前をつけることができます。
ラベルは*(アスタリスク)の後に続く59文字(半角)以下の文字列で示します。
例:
*label
mes "Wait.":wait 100
goto *label ; 無限ループを生成
ラベルは主に、goto命令、gosub命令またはbutton命令の飛び先を指定するのに使用されます。
ラベル名は、1つのソーススクリプトで重複することはできません。
また、変数名と重複することもできません。
変数にラベルの位置を代入することも可能です。
例:
a=*test
この場合は、変数aに「*test」という位置を代入します。
以降は、変数aはラベル型の変数として扱われ、パラメーターにラベル指定を行なう場所に、
ラベル型の変数を指定することができるようになります。
以下は、ラベル型を使用したサンプルスクリプトの例です。
; ラベル型変数のテスト
;
a=*test
a(1)=*test2
mes "TYPE="+vartype(a)
mes "USE="+varuse(a)
gosub a
gosub a(1)
mes "OK"
stop
*test
mes "JUMP OK"
return
*test2
mes "JUMP OK2"
return
ラベル型変数は、vartype関数によりタイプ値「1」が取得されます。
また、varuse関数により有効なラベルが代入されているかどうかを判別することが可能です。
ラベル型変数の配列は、「dimtype a,vartype("label"),20」と指定して確保することができます。
ラベル型変数は、スクリプトの飛び先が見えにくくなり、全体の把握が難しくなります。
その反面、on〜gotoなどで処理しきれない大量の飛び先を効率よく管理できます。
HSPではローカルラベル機能をサポートしています。
これは、特殊な名前のラベルを何度でも使うことのできる機能で、
何でもない部分や、名前をつけるのが面倒な時などに便利です。
例:
mes "GO!"
*@
mes "A="+a
a+
if a<5 : goto *@back ; 前のローカルラベルに戻る
stop
ローカルラベルは、「*@」という名前で定義します。これは、他の
ラベルと違い1つのソーススクリプト内で何度でも置くことができます。
このローカルラベルを、goto命令などで参照する時には、
「*@back」と「*@forward」を使います。
「*@back」は、その場所より上にあり一番近いローカルラベルを指します。
「*@forward」は、その場所より下にあり一番近いローカルラベルを指す
ものになります。
「*@back」は、「*@b」と省略することが可能です。
「*@forward」は、「*@f」と省略することが可能です。
ローカルラベルは、多用するとかえって見にくいスクリプトになって
しまう可能性もあるので、後の見やすさを考えてから使ってみてください。
-
条件判断
条件判断を行う場合には、if命令を使用します。if命令は、パラメータで
示された条件が満たされた場合は、それ以降の命令を実行し、そうでなければ
次の行から実行を続けます。
例:
a=10
if a=10 : mes "aは10です。"
上の例では、「a=10」の部分が条件式になります。条件式には主に、
a=b | aとbは等しい |
a!b | aとbは等しくない |
a<b | aはbよりも小さい |
a>b | aはbよりも大きい |
a<=b | aはbよりも小さいか等しい |
a>=b | aはbよりも大きいか等しい |
を使います。if+条件式の後は:(コロン)で区切り、それに続いて
条件が満たされた場合に実行される部分を書きます。
(C言語やJavaと同じように「=」「!」を「==」「!=」のように記述することも可能です)
複合的な条件判断をするために、論理演算式を使うこともできます。
a&b aとbがともに正しい (and)
a|b aとbのどちらかが正しい (or)
これによって複数の条件を一度に記述することができます。
例:
a=10:b=20
if a=10|b=10 : mes "aかbのどちらかが10です。"
上の例では、「a=10」と「b=10」という条件式を|(or)でつないで、
どちらかが正しい場合には、正しいという結果が出るようにしています。
論理演算は、「|」「&」といった記号の他に「or」「and」という文字列でも記述することができます。
例:
if (a=10)or(b=10) : mes "aかbのどちらかが10です。"
上のように書いても、結果は同じになります。
HSPでは、論理演算はビットごとの演算として扱われているため、
C言語やJavaなどで用いられる「&&」「||」などの論理演算子とは等価ではありませんのでご注意下さい。
もし、条件によってプログラムの流れを変えたい場合には、
例:
a=10
if a>10 : goto *over10
mes "aは10以下です。"
stop
*over10
mes "aは10より大きいです。"
stop
上のように、goto命令で別なラベルに飛ばすことも可能です。
else命令を使って条件が満たされなかった場合の処理を書くことも可能です。
例:
a=10
mes "aは、"
if a=10 : mes "10です。" : else : mes "10ではありません。"
stop
この場合は、else命令のある部分までは、条件を満たした場合に実行され、
else命令以降は、条件を満たされなかった場合に実行されます。
次の行以降は、条件に関わらず通常通りに実行されます。
条件判断の実行を、複数行で行なうこともできます。
if命令の条件が正しい時に実行されるスクリプトを複数行に渡って記述する場合は、
例:
a=10
if a>5 {
mes "TRUE"
mes "(MULTILINE IF)"
}
のように「{」で始めて「}」で終わる部分までを指定します。
(上の例では、見やすくするためにC言語風に行の最初にTABを入れてありますが、特に必要なものではありません。ユーザーの見やすいように記述してください)
else命令でも複数行の指定ができます。
例:
a=10
if a>5 {
mes "TRUE"
mes "(MULTILINE IF)"
} else {
mes " FALSE"
mes " (MULTILINE IF)"
}
return
ただし、elseの後に「{」を記述しなければ複数行にはならないので注意してください。
例:
if a>5 {
mes "TRUE"
}
else ; <- 間違い
{
mes "FALSE"
}
上の例は間違いです。エラーになります。
else命令もまたif命令と同じように、「{」がない限りは、その1行のみが有効範囲になります。
また、if命令を多重に実行させることも可能です。
例:
a=10
b=10
c=10
if a>5 {
if b>5 {
if c>5 { mes "--3" } else { mes "--2" }
} else {
mes "--1"
}
}
上の例では、変数aが10より大きい場合は「--1」を、変数a,bが10より大きい場合は「--2」を、変数a,b,cが10より大きい場合は「--3」を表示します。
if命令の多重化は、スクリプトがだんだんと複雑になっていくので、注意して使ってください。HSPでは、128重までの多重化が可能です。
-
繰り返し命令
repeat〜loop命令は、HSPで繰り返しの動作をさせる場合に欠かすことのできない重要な命令です。
repeat 5
mes "繰り返し["+cnt+"]"
loop
のように、repeat命令の後に回数を指定すると、loop命令までを指定回数だけ繰り返します。繰り返し中は、システム変数cntが0、1、2、3…と自動的にカウントアップされていきます。
繰り返し回数に0が指定された場合には、repeat〜loopの範囲は実行されずに通過します。
また、繰り返し回数指定を省略するかまたはマイナス値を指定すると無限ループになります。
repeat〜loop命令と、break、continue命令を組み合わせることにより、さらに高度な処理が可能になります。
repeat〜loop命令の繰り返しを、途中で強制的に脱出させるのがbreak命令です。
repeat 5
if cnt=2 : break
mes "繰り返し["+cnt+"]"
loop
上の例では、システム変数が2になった時点、つまり3回目のループになると、if命令の判断によって、break命令が実行されるしくみになっています。
break命令が実行されると、繰り返しの回数がまだ残っていても、強制的に繰り返しから抜け出し、loop命令の次にある命令から実行を続けます。
break命令以降(上の例では、mes命令)は実行されません。
この命令を使うと、たとえば次のようなスクリプトが作成可能です。
repeat
getkey a,1
if a>0 : break
await 10
loop
上のスクリプトでは、マウスの左ボタンを押すまで待つループになります。
repeat命令の回数指定を省略するかまたはマイナス値を指定すると無限ループになります。それを利用してボタンの状態が1になるまでは、ずっと同じところを繰り返すようになっています。
ボタンが押されると、break命令が実行され繰り返しから抜け出します。
いままでは、このようなスクリプトはgoto命令を使って繰り返しの構造を記述する必要がありましたが、repeat〜loopとbreak命令を使うことにより、ラベルを用意することなく手軽に条件付きの無限ループが実現できます。
continue命令は、逆に繰り返しをやり直すための命令です。
repeat 5
if cnt=2 : continue
mes "cnt="+cnt
loop
上の例では、システム変数cntが2になった時点で、continue命令が実行されるしくみになっています。continue命令が実行されると、repeat命令まで戻り次の繰り返しを実行します。
上のスクリプトが実行されると、
cnt=0
cnt=1
cnt=3
cnt=4
のような表示になり、システム変数cntが2の時だけmes命令が実行されないのがわかります。
最初はわかりにくいかもしれませんが、continue命令は、loop命令の場所ではないが、loop命令と同じ働きをするとも言えます。
繰り返しのカウンタは、continue命令が実行された場合でも、loop命令と同様1つ増加します。もし、最後の繰り返しでcontinue命令が実行されると、repeat〜loopが終わった状態、つまりloop命令の次の命令から実行を続けます。
さらにもう1つ、continue命令にはパラメータを指定する使い方が存在します。
continueの後に、数値または数値型変数を指定することにより、繰り返しのカウンタ
を示すシステム変数cntの内容を変更することができます。
たとえば、「continue 1」と指定した場合は、システム変数cntの内容は1になり、
その値のままrepeat命令の次から繰り返しを続けます。
パラメータを省略して、ただの「continue」だけの場合はloop命令と同様の処理、
数値を指定すると、カウンタの値を変更して繰り返しをやり直すことになります。
ですから、
repeat 1
await 10
getkey a,1
if a=0 : continue 0
loop
このようなスクリプトでは、通常1回だけしか実行されないはずの、repeat〜loopの
繰り返しですが、マウスの左ボタンが押されていない場合は、カウンタが0に戻され
無限ループの状態になります。これで、ボタンを押すまで待つという動作になります。
このbreak命令と、continue命令は、ともにrepeat〜loop命令の中で使用しなければ
なりません。また、repeat〜loop命令の中であれば、いくつでも使用できます。
注意しなければならないのは、プログラムの流れとしてrepeat〜loop命令は、順番につながっていなければなりません。repeat命令があったら、そこから下の行に必ずloop命令がなければいけないということです。
repeat命令だけを、gosubでジャンプしたサブルーチンの中で実行したり、
goto命令でスクリプト上の別な場所にジャンプしてloop命令を実行させたりして、
repeat〜loop命令の順番が狂ってしまうとコンパイラはエラーを出してしまいます。
repeat〜loop命令は、多重に使うことができます。
repeat 5
if cnt=2 : continue
repeat 2
mes "中のループcnt="+cnt
loop
mes "外のループcnt="+cnt
loop
上の例では、わかりやすいようにTABを入れて記述していますが、5回繰り返す構造の
中に、さらに2回繰り返すrepeat〜loop命令があります。
繰り返しが多重になった場合でも、break、continue命令は対応するループに対して機能します。これは、システム変数cntが、やはり対応したループに対しての値を示すのと同様です。
repeat〜loop命令の中からgoto命令などで別な場所にプログラム制御が移ると、
次に再びrepeat命令を実行した場合に、多重の繰り返しになってしまいます。
必ずrepeat〜loop命令は、正常にループ終了するか、break命令で抜けるように
してください。goto命令で脱出すると多重ループになりエラーが発生します。
repeat〜loop命令は、通常32まで多重に繰り返し処理が可能です。
-
メモリノートパッド命令
メモリノートパッド命令セットは、行単位で文字列を扱うことのできるユニークで
便利な機能です。これにより、テキストファイルを読み込み解析したり加工することが容易になります。
また、コンボボックスやリストボックスを表示するための命令(combox,listbox命令)
パラメータ指定に使う文字列や、ディレクトリの内容を調べるdirlist命令が
返す文字列なども、メモリノートパッド命令を使うことでシンプルに処理できるようになります。
メモリノートパッド命令は、簡単に言えばWindowsの「メモ帳」のようなテキスト
エディタを使うような感覚で、複数行を含んだ文字列を扱うための命令セットです。
通常の文字列は、「ABCDEFG」のように任意の文字が集まったものです。
複数行を含んだ文字列というのは、「ABCD\nEFGH」のように間に改行(\n)があり
1行目は「ABCD」、2行目は「EFGH」というようにちょっと複雑な構造になっている文字列のことです。
テキストエディタなどでロード・セーブすることのできるテキストファイルも、
このような複数行を含んだ文字列と言えます。
これらの文字列を行単位で取り出したり、修正をしたりすることがメモリノートパッド命令で可能です。
命令 おもな機能 備考
--------------------------------------------------------------------------
notesel メモリノートパッドとして扱う変数の指定
noteadd 指定行に内容追加 挿入/上書きモードあり
noteget 指定行の内容読み出し
notedel 指定行の削除
noteload ファイルから内容読み込み
notesave 内容をファイルに書き出し
noteunsel 以前に選択されていた変数に復帰する
noteinfo メモリノートパッドに関する情報を取得する
notemax 全体の行数を取得する
notesize 全体のサイズ(バイト数)を取得する
基本的な使い方は、まずnotesel命令で文字列型の変数を指定します。
それ以降は、メモリノートパッド命令はすべて、そこで指定した変数が対象になります。
指定した変数は、文字列型である必要があります。
notesel命令で変数を指定した後は、自由にnoteinfo,noteadd,noteget,notedel命令を使って変数の内容(文字列)にアクセスすることができるようになります。
例:
a="ONION\nTOMATO\nCARROT"
notesel a
noteget b,0
print "index0="+b
noteget b,1
print "index1="+b
noteget b,2
print "index2="+b
stop
上の例では、変数aに「ONION」「TOMATO」「CARROT」という3行が代入されています。
まずnotesel命令で、変数aを指定してから、各行の内容をnoteget命令を使って取り出して表示しています。
メモリノートパッド命令では、行の指定に「インデックス」という単位を使用しています。
最初の行はインデックス0、その次はインデックス1、そのまた次はインデックス2…というふうに続きます。
行数だと最初は1行目ということになりますが、インデックスは0から始まるので注意してください。
つまり、「noteget b,0」は最初の行を変数bに読み出す…という意味になります。
例:
a="ONION\nTOMATO\nCARROT"
notesel a
noteadd "POTATO"
mes a
stop
上の例では、変数aに代入されている「ONION」「TOMATO」「CARROT」という3つの要素に、「POTATO」という行を追加しています。4行目の「mes a」で、その結果を表示しているので確認することができます。
内容を追加するには、noteadd命令を使用します。「noteadd "POTATO"」は、最後の行に「POTATO」を追加します。
noteadd "POTATO",1
と指定をすると、インデックス1の位置に追加されます。
それまでインデックス1以降にあった内容は下にずれることになります。また、
noteadd "POTATO",1,0
は、同じくインデックス1の位置に追加されますが同じ行に上書きで追加されます。
それまでインデックス1にあった内容は消去され、かわりに指定した内容になります。
指定したインデックスの行を削除する命令も用意されています。
notedel 1
は、インデックス1を削除します。
これらのメモリノートパッド命令は、他の命令と組み合わせた時に威力を発揮します。
メモリノートパッド命令は、テキストファイル、mesbox命令で入力される複数行
テキスト、dirlist命令の結果、comboxおよびlistbox命令で指定するパラメータの
処理に使用することができます。
また、1行単位で取り出した文字列は、poke,peek命令などで1文字単位で扱うことが
可能です。
例:
notesel a
noteload "aaa.txt"
idx=0
repeat notemax
noteget b,idx
print "index"+idx+"="+b
idx++
loop
stop
上の例では、"aaa.txt"という名前のテキストファイルを読み込み、そのすべての行を
インデックス番号とともに表示します。
noteload命令を使用することにより、変数に確保されたメモリバッファのサイズを
読み込みファイルに合わせて調節します。
全体の行数がわからない場合は、noteinfo関数か、notemaxを使用します。
notemaxは、メモリノートパッドの対象になっているテキストの行数が代入されている
マクロでシステム変数と同じように使用することができます。
例:
sdim a,32000
sdim tmem,32000
tmem=""
fname=""
;
dirlist a,"*.*"
sel=0
objsize 160,24
listbox sel,150,a ; ID=0
button "SELECT",*ok ; ID=1
pos 180,0
mesbox tmem,450,200 ; ID=2
stop
*ok
notesel a
noteget fname,sel
exist fname
if (strsize=0)or(strsize>32000) : goto *lderr
bload fname,tmem
objprm 2,tmem
stop
*lderr
dialog "LOAD ERROR!"
stop
これは、メモリノートパッド命令と、その他の命令を組み合わせたサンプルです。
カレントディレクトリにあるファイル一覧をリストボックスに表示して、そこで
選んだファイルの内容を、右側にあるメッセージボックスの中に表示します。
dirlist命令やlistbox命令で使われている文字列は、いずれもメモリノートパッド
命令で扱うことのできる複数行のテキストです。
最初は複雑に感じるかもしれませんが、多くのデータを一度に扱うことができ、
使い方次第で応用範囲がさらに広がります。
-
システム変数
システム変数はシステム起動時、または特定の命令を実行した時に自動的に
値が代入される変数です。普通の変数と同じように参照することができますが、
代入文(=)により値を代入することはできません。
一部のシステム変数には、return命令により値を代入することが可能です。
変数名 設定される内容
-----------------------------------------------------------------------
system 未定義
hspstat HSPランタイムの情報を取得する(*1)
hspver HSPのバージョン番号(*2)
cnt repeat〜loopループのカウンター
err エラーコード
stat 色々な命令のステータスなどを代入する汎用システム変数
mousex マウスカーソルのX座標
mousey マウスカーソルのY座標
mousew マウスホイール値
strsize getstr命令で読み出したByte数
refstr 文字列を保存する汎用のシステム変数
refdval 実数値を保存する汎用のシステム変数
looplev repeat〜loopのネストレベル
sublev サブルーチン(モジュール)のネストレベル
wparam 割り込み時に保存されるWindowsのシステム値(wParam)
lparam 割り込み時に保存されるWindowsのシステム値(lParam)
iparam 割り込み要因を示す値
thismod 現在の有効なモジュール変数
notemax メモリノートパッドの行数
notesize メモリノートパッドの文字数
hwnd 現在のウィンドウハンドル
hdc 現在のデバイスコンテキスト
hinstance 現在のインスタンスハンドル
ginfo_mx スクリーン上のマウスカーソルX座標
ginfo_my スクリーン上のマウスカーソルY座標
ginfo_act アクティプなウィンドウID
ginfo_sel 操作先ウィンドウID
ginfo_wx1 ウィンドウの左上X座標
ginfo_wy1 ウィンドウの左上Y座標
ginfo_wx2 ウィンドウの右下X座標
ginfo_wy2 ウィンドウの右下Y座標
ginfo_vx ウィンドウのスクロールX座標
ginfo_vy ウィンドウのスクロールY座標
ginfo_sizex ウィンドウ全体のXサイズ
ginfo_sizey ウィンドウ全体のYサイズ
ginfo_winx 画面のクライアントXサイズ
ginfo_winy 画面のクライアントYサイズ
ginfo_sx 画面の初期化Xサイズ
ginfo_sy 画面の初期化Yサイズ
ginfo_mesx メッセージの出力Xサイズ
ginfo_mesy メッセージの出力Yサイズ
ginfo_r 現在設定されているカラーコード(R)
ginfo_g 現在設定されているカラーコード(G)
ginfo_b 現在設定されているカラーコード(B)
ginfo_paluse デスクトップのカラーモード
ginfo_dispx デスクトップ全体のXサイズ
ginfo_dispy デスクトップ全体のYサイズ
ginfo_cx カレントポジションのX座標
ginfo_cy カレントポジションのY座標
ginfo_intid メッセージ割り込み時のウィンドウID
dir_cur カレントディレクトリ(フォルダ)
dir_exe 実行ファイルがあるディレクトリ(フォルダ)
dir_win Windowsディレクトリ(フォルダ)
dir_sys Windowsシステムディレクトリ(フォルダ)
dir_cmdline コマンドライン文字列
dir_desktop デスクトップディレクトリ(フォルダ)
dir_mydoc マイドキュメントディレクトリ(フォルダ)
*1 以下の情報がすべて合計された値になります。
( デバッグモード = 1 )
( IMEが有効 = 2 )
( Macintosh版HSP = $80 )
( IMEをサポートしないOS = $100 )
*2 バージョンコード + マイナーバージョンコードの値になります。
(3.0は$3000になる)
3.拡張文法
-
モジュール
モジュール機能は、スクリプトを整理し再利用可能にするための仕組みです。
ある程度HSPを習得した中上級者には、モジュール機能は便利なものになる
はずです。モジュール内で扱う変数をまとめて保存するモジュール変数や、
ローカル変数など多彩な応用が可能になっています。
また、モジュール機能を使わない人であっても、他の人がモジュール機能を
使って追加した新しい命令を使うことが可能です。これは、DLLによる拡張
プラグインの仕組みと変わりません。
たとえば、「test1.as」というソーススクリプトがあったとしましょう。
このソーススクリプトには、変数aと変数bを使っているとします。
別な人が、「test2.as」というソーススクリプトを作ったとして、そこに
とても便利なサブルーチンがあったとしたら、どうなるでしょう。
「test2.as」で変数aと変数bという名前を使っていなければ問題なく、
そのままサブルーチンだけを持ってくることができるかもしれません。
しかし、もし「test2.as」でも変数aと変数bを別な用途で使っていたとしたら
とてもやっかいです。
HSPモジュール機能を使うと、「test1.as」から「test2.as」のスクリプトを
呼び出すことが可能になりますが、「test1.as」と「test2.as」で使われて
いる変数は(たとえ名前が同じであっても)独立したものとして扱われます。
また、この独立したスクリプト内のサブルーチンを、新規命令として登録
することができ、パラメータを渡したり、受け取ったりすることが可能です。
過去に作ったモジュールを再利用したり、人に使ってもらうために公開したり、
誰か他の人が作ったモジュールを使うなど、HSPスクリプトをより広く応用
することが可能になります。
HSPモジュールを使いこなすためには、モジュール指定命令、ユーザー拡張命令
などについて覚える必要があります。これらは、単体でも便利な機能を
提供する命令です。一度に覚えようとしないで、わかるところから1つづつ
マスターしていきましょう。
ユーザー定義命令は、HSPモジュール機能とともに追加された命令の1つで、
新しい名前の命令をユーザーが任意に追加できるというものです。
これは、HSPモジュール機能とは別に単体で使っても非常に強力なものと
なるでしょう。
■ユーザー定義命令
例:
goto *main
#deffunc routine
mes "sub-routine"
return
*main
routine
stop
HSPの命令には「routine」はありませんから、いままでならエラーになって
しまうところですが、実際にこのスクリプトを実行すると、「sub-routine」
という表示がされて、「routine」という命令が実行されます。
ユーザー定義命令は、「#deffunc」という命令によって定義できます。
#deffunc 命令の名前
で、新しい名前の命令が追加されます。
これ以降、新しい命令が出てきた場合には、「#deffunc」のある場所に
サブルーチンジャンプします。
つまり、
例:
goto *main
*routine
mes "sub-routine"
return
*main
gosub *routine
のようなスクリプトでも、
例:
goto *main
#deffunc routine
mes "sub-routine"
return
*main
routine
でも同じということです。
ただし、「#deffunc」には1つだけ注意点があります。
「#deffunc」は実際に命令を使う位置よりも前に置くこと。
これはたとえば、gosub命令の場合は呼び出すサブルーチン(ラベル)が
gosub命令よりも前にあっても、後にあっても問題はありませんでした。
「#deffunc」では追加した命令が使えるようになるのは、「#deffunc」
の定義位置から先になります。
これは、スクリプトのコンパイル時に新規キーワードが変数か命令かを
決定するために、あらかじめ定義されていることが必要なためです。
「#deffunc」を使って新しい命令を作る場合は、サブルーチンを先に、
メインのスクリプトはその後にするような構成を取るように心がけて
みてください。
またユーザー定義命令は、サブルーチンにパラメータを渡すことを
可能にしています。
例:
goto *main
#deffunc routine int prm1, int prm2
mes "パラメータ1は、"+prm1+"です。"
mes "パラメータ2は、"+prm2+"です。"
return
*main
routine 10,20
いままでのgosub命令では、値をサブルーチンに渡す時には、あらかじめ
決められた変数に値を入れて、呼び出すしかありませんでした。
ユーザー定義命令では、それに代わってスマートな方法で値を渡すことを
可能にしています。
また、渡すパラメータは数値だけでなく、文字列、変数(配列)など
いくつものバリエーションがあります。
#deffunc命令では、
#deffunc 新規命令の名前 パラメータータイプ1 エイリアス名1,…
という書式でパラメーターの情報を指定します。
パラメータータイプは、以下の中から選ぶことができます。
タイプ 内容
-------------------------------------------
int 整数値
var 変数(配列なし)
array 変数(配列あり)
str 文字列
double 実数値
label ラベル
local ローカル変数
エイリアス名は、渡されたパラメーターの内容を示すもので、変数と
ほとんど同じ感覚で使用することができます。
ただし、varとarrayの使い分けには注意が必要です。
例:
#deffunc routine1 var prm
mes "変数の内容は、"+prm
return
#deffunc routine2 array prm
mes "変数の内容は、"+prm
return
上の例では、「routine1 a(1)」のように呼び出した場合、「a(1)」
という指定がそのままパラメーターとして渡されます。
それに対して、「routine2 a(1)」の場合は、「a」だけがパラメーター
として渡されます。ですから、routine2では、a(0)の内容が表示
されることになります。また、エイリアスとしてのprmは、routine1の
場合は、「prm.1」という指定をすることはできない(エラーとなります)
のに対して、routine2は「prm.1」という指定が可能です。
このように、変数パラメーターの受け渡しには2つの種類があることを
覚えておいてください。
パラメータータイプ「local」は少し特殊な指定です。これは、厳密には
パラメーターではなく新規命令の動作を指定するものです。
例:
#deffunc routine1 int prm,local a
mes "ローカル変数="+a
a=prm
return
上のようにlocalは、パラメーター記述の最後に付加して指定することを
推奨します。localに続いて指定された名前は、ローカル変数として
新規命令が実行された時点で初期化されます。通常、HSPの変数はグローバル
なものとして何らかの値を常に保持していますが、ローカル変数の場合は
この命令が実行される時に作成され、命令の終了とともに破棄されます。
ローカル変数は、命令の再帰(自分自身を呼び出すこと)を行なう場合などで
変数の値を独自に保持しておく時などに有効です。その他、変数名の局所化
などプログラムを整理する際にも役立ちますが、ローカル変数を多用する
ことは、実行効率や速度を求める場面では、初期化のためのオーバーヘッドが
あることを留意してください。
特殊な用途として、パラメータータイプの替わりに「onexit」を記述することで、
クリーンアップ命令として登録することができます。
クリーンアップ命令は、HSPスクリプト実行の終了時に自動的に呼び出されます。
例:
#deffunc 名前 onexit
モジュールによって機能を拡張した場合などにその後始末、システムやメモリの解放などを
行なうために利用することができます。
■ユーザー定義関数
ユーザー定義関数は、ユーザー定義命令と同様に新規の関数を作成するものです。
#defcfunc 新規関数の名前 パラメータータイプ1 エイリアス名1,…
のように、ユーザー定義命令と同じ書式で定義することができます。
#defcfuncにより、式の中で評価される関数の動作をスクリプトで記述する
ことができます。
例:
#defcfunc half int a
return a/2
上の例では、halfという名前の関数を登録しています。
halfは、パラメーターの半分の値を返す関数として作られています。
たとえば、式の中で「half(4)」のように使用することで、「2」という値に
加工されます。
関数が返す値は、return命令のパラメーターで指定します。
返値で指定された値と型がそのまま式に反映されます。
■関数と命令の違いについて
関数と命令という2つの機能呼び出し方法が標準で用意されています。
この2つは、どちらも必要に応じてユーザーが選択することができますが、
以下のようなルールで運用されることを推奨しています。
命令 = パラメーターをもとに動作する機能を提供するもの
関数 = パラメーターを一定の法則で加工して値を返すもの
システムが提供する多くの機能は、命令として提供しており、関数のサポートは
算術関数など必要以上の混乱をしない範囲に留めています。
特に初心者などに公開されるスクリプトについては、関数を多用すると
理解し難いものになる場合もあります。
■モジュール定義命令
モジュールは、変数名やラベル名を独立して扱えるソースの単位を指します。
例:
#module
#deffunc test1
a=a+1
mes "test1が呼び出されたのは、"+a+"回です。"
return
#global
モジュールは、必ず「#module」で始まり「#global」を最後に書くのが
お約束だと思って下さい。
この例では、test1という新規命令を呼び出すたびに、変数aに
保存されている回数がカウントアップしていきます。
これを呼び出す側の例として、以下のようなスクリプトを作ってみます。
例:
a=5
repeat a
test1
loop
mes "aの内容="+a
stop
通常のサブルーチン呼び出しと考えると、変数aの名前がtest1の中でも
使用されているため、正しく動作しないはずです。
しかし、モジュール定義命令を使ってソースが分離されているため、
モジュールの中にある変数aと、外にある変数aが別なものとして扱われて
いるので、上のスクリプトは正しく動作します。
このように、「#module」〜「#global」で区切られた区間と
それ以外の区間をまったく別な空間として変数やラベルの名前が重複していても、
まったく問題なくそれぞれのスクリプトが動作するという点が、
モジュールの基本的な概念です。独立した機能を持ったサブルーチンを、
ユーザー定義命令により完全に分離することで、スクリプトの再利用や
カプセル化を進めることができます。
また、モジュール定義の際に名前を付加することができます。
例:
#module mo
#deffunc test1
a=a+1
mes "test1が呼び出されたのは、"+a+"回です。"
return
#global
上の例では、「mo」という名前のモジュールが定義されます。
名前を省略して「#module」だけにした場合でも、他と重複しないように
「_m数値」というモジュール名がシステム側で自動的に付けられます。
モジュールを複数定義した場合には、このモジュール名により識別
されています。
もし、モジュールの外から、モジュール内の変数を参照したい場合には
「変数名@モジュール名」という書式を使うことができます。逆に、
モジュール内部から外(#global部分)の変数を参照する場合には、
「変数名@」という書式により参照することができます。
ただし、この書式はモジュール内部と外部に依存関係ができてしまうため
ソースの完全な分離ではなくなってしまいますので、推奨はされません。
■モジュール変数の定義
モジュール変数は、複数の変数やデータをまとめて管理することができる
データ格納方法を提供します。複数の変数をモジュール内に隠蔽することに
より、大量のデータをシンプルに整理することができる便利な機能です。
モジュール内部で使用する変数をモジュール変数と呼び、それらをモジュール
単位で保存するため、モジュールの型を持つ変数を作成することができます。
モジュール変数を作成する準備として以下のような定義を行なっておく
必要があります。
#module a x,y,z
上の例では、aというモジュールにx,y,zという3つの変数を持たせています。
#module命令は、従来からあるように「a」という名前を持つ空間を定義する
ための命令ですが、3.0では「a」という名前に対応した変数を定義することが
できるようになっています。モジュール「a」が使用する変数x,y,zという意味で、
このx,y,zをモジュール変数と呼びます。
モジュール変数を使うためには、モジュールの型を持つ変数を作成しておく
必要があります。
newmod v,a
上の例では、モジュール「a」のための変数vを初期化します。
これで変数vには、モジュール「a」が持つモジュール変数x,y,zという
内容が丸ごと格納されることになります。
変数は、最初に整数値0の状態で初期化されます。ただし、モジュールごとに
初期化のための命令を用意することも可能です。
#modinit
x=1:y=2:z=3
return
上の例は、モジュール変数初期化のためのルーチン(コンストラクタ)を定義して
います。#modinitで定義される初期化ルーチンは、1つのモジュールにつき
1つだけ書くことができます。
#modinitが定義されているモジュールは、newmod命令を使用した時に自動的に
初期化ルーチンが呼び出されます。
#modinitは、#deffuncと同様に引数を指定することができます。
#module a x,y,z
#modinit int p1,int p2,int p3
x=p1:y=p2:z=p3
return
#global
newmod v,a,1,2,3
上のように定義されている場合に、newmod命令が実行された場合は、
newmodに記述されたパラメーターがそのまま渡されます。
最初は分かりにくいかもしれませんが、変数vは複数の変数をまとめて入れて
おくことのできる入れ物になっています。複数のファイルが1つのフォルダに
格納されているのと同じようなイメージです。
格納されている変数、つまりモジュール変数の内容にアクセスするためには、
モジュール内で処理するための命令を専用に定義する必要があります。
#modfunc viewxyz
mes "x="+x+"/y="+y+"/z="+z
return
上の例は、モジュール変数x,y,zを表示するための命令定義です。
引数の指定などは、#deffuncと同様に行なうことができますが、この命令を
呼び出すためには、命令の引数として最初にモジュール型の変数を指定する
必要があります。
つまり、viewxyzという命令を呼び出すためには、
newmod v,a
viewxyz v
という記述をしなければなりません。
これで、モジュール型の変数vに格納されているx,y,zの内容をviewxyzという
ユーザー定義命令の中で表示させることができます。
見かけ上は、vという変数1つにx,y,zという3つの要素を入れておくことが
できるようになり、データをセットで扱う場面などでは有効です。
#modfuncで定義したルーチン内では、自分自身のモジュール変数を表わす
システム変数thismodを使用することができます。
thismodは、モジュール変数を処理するルーチン内から、別な命令・関数を
呼び出すためのモジュール変数として指定する場合に使用します。
また、モジュール型の変数も配列を使用することができます。
この場合に、いくつか特殊な使用方法が用意されています。
先ほどのnewmod命令は、モジュール型の配列変数に新しい値を代入するための命令です。
newmod v,a
は、v.0という配列に代入されますが、もう一度実行した場合は、v.1代入
されます。つまり、newmod命令は変数vの配列で空いている場所を自動的に
確保してデータを格納するための命令です。
逆に、newmod命令で格納した配列要素を削除することもできます。
delmod v.0
上の例では、変数vの要素0にあたる内容を削除します。
削除された要素は、これ以降使用できなくなり、新たにnewmod命令が実行
された時に再利用されます。
また、必要な場合は、delmod命令によりモジュール変数が破棄された際に
自動的に呼び出されるルーチン(デストラクタ)を定義することも可能です。
#modterm
mes "BYEBYE"
return
上の例では、モジュール変数が破棄された時に「BYEBYE」を表示します。
指定された要素が使用中であるかどうかは、moduseという関数で調べる
ことができます。
if moduse(v.0)=0 : mes "v.0は使用されていない"
また、配列の要素がどこまで使用可能かどうかは、length関数で得ることが
できます。
mes "配列要素の最大="+length(v)
さらに、モジュール型の変数で使用可能な要素すべてを繰り返し処理する
ためのforeach命令が用意されています。
foreach命令は、repeat命令と同じように使用できますが、ループ回数の
代わりにモジュール型の変数名を指定します。
以降は、loop命令までの間をすべての要素の数だけ繰り返します。
繰り返しの際に、システム変数cntが要素の値として変化します。
システム変数cntは、delmod命令で削除された要素はスキップされます。
つまり、
foreach v
viewxyz v.cnt
loop
のように書くと、モジュール型の変数vで有効な要素すべてに対して、
viewxyzという命令を実行するという意味になります。
-
プリプロセッサ命令
プリプロセッサ命令は、プログラム実行時ではなく、コンパイル時に解釈し
実行される命令のことです。プリプロセッサ命令は、他の命令と区別がつく
ように、行の最初に「#」に続けて記述しなければなりません。
プリプロセッサ命令により、スクリプトの記述そのものをカスタマイズする
ことも可能になります。ただし、使いすぎるとプログラムそのものがわかり
にくくなったりするので、HSPを一通り使った上級者の方に使用をおすすめ
します。
プリプロセッサ命令は、通常「#」から始まる1行が対象となりますが、
最後が「\」で終わるプリプロセッサ行は次行に継続されます。
1行に収まらない定義を行なう場合に、利用することができます。
例:
#define aaa mes "AAA"\
:mes "BBB"\
:mes "CCC"
上の例では、この3行すべてが#defineプリプロセッサ命令として解釈されます。
プリプロセッサ命令として装備されている命令は以下の通りです。
#include "filename" [別ファイルを結合]
"filename"で指定されたファイルも同時にコンパイルされます。
スクリプトエディタで入りきらないスクリプトも、includeで別ファイルに
分割すればコンパイルすることができるようになります。
#define 新規名称 元名称 [新規名称を登録する]
新しい別名(エイリアス)を追加するためのものです。
HSPの従来ある命令の名前を、別な名前でも使用できるようになります。
新規名称は、予約されている命令語や変数名と重ならない20文字以内の、
スペースを含まない英文字列でなければなりません。
例:
#define pr print
pr "message..."
stop
上のように#defineの後に、新規名称と元の名称をスペースで区切り記述
します。すると、「pr」という命令が新しく登録され、「print」命令と
まったく同様に使うことができるようになります。
元の名称は、命令の名前である必要はありません。数値や、記号なども
新規の名称として登録することが可能です。
例:
#define is =
#define plus +
a is 5 plus 10
print "A="+a
stop
上の例では、「=」という記号を「is」という言葉に、「+」という記号を
「plus」という言葉にそれぞれ置き換えるように定義しています。
すると、「a is 5 plus 10」という行は、「a=5+10」と同じことになります。
パラメーターを使用して展開することも可能です。
例:
#define reset(%1) %1=10
reset a
mes "A="+a
stop
上の例では、「reset a」を「a=10」というスクリプトに変換します。
このほか、特殊展開パラメーターなど多くのオプションが用意されています。
詳しくは、「#defineマクロについて」の項を参照してください。
#const マクロ名 数値式 [マクロ名の定数定義]
指定されたマクロ名に置換え文字列を設定します。
#defineと同様ですが、#constは定数(数値)の置き換えを行なう場合に
あらかじめ計算を行なった結果を置き換えます。
例:
#const KAZU 100+50
a=KAZU
↓(展開後)
a=150
あらかじめソース内で使用する値が確定している場合、ソースの
高速化に有効です。すでに定義されているマクロを含めることも可能
なので、
例:
#const ALL 50
#const KAZU 100*ALL
a=KAZU
↓(展開後)
a=5000
のように使用することができます。
計算式は、整数のみで演算子および数値の記述スタイルは、スクリプトで
使用している式と同様のものが使えます。
例:
#const KAZU $5+3*10
a=KAZU
↓(展開後)
a=35
#undef マクロ名 [マクロ名の取り消し]
すでに登録されているマクロ名を取り消します。
登録されていないマクロ名に対して指定してもエラーにはならず
無視されます。
#if 数値式 [数値からコンパイル制御]
#ifdef マクロ名 [マクロ定義からコンパイル制御]
#ifndef マクロ名 [マクロ定義からコンパイル制御]
#else [コンパイル制御を反転]]
#endif [コンパイル制御ブロック終了]
コンパイルのON/OFFを指定します。
#ifは指定した数値が0ならば以降のコンパイル出力をOFFにして
コンパイル結果を無視します。数値が0以外の場合は、出力がONとなります。
このコンパイル制御は、#endifが出るまでの区間を対象にします。
#if、#ifdef、#ifndefのいずれかには、#endifがペアで存在している
必要があります。
例:
#if 0
mes "ABC" ; この部分は無視されます
a=111 ; この部分は無視されます
mes "DEF" ; この部分は無視されます
#endif
#ifの指定には式を使うことも可能なので、
例:
#define VER 5
#if VER<3
mes "ABC" ; この部分は無視されます
a=111 ; この部分は無視されます
mes "DEF" ; この部分は無視されます
#endif
のような使い方もできます。計算式の記述は#const命令と同様です。
#ifdefは、指定したマクロ名が定義されていれば出力をONに、そうでない
場合は、出力をOFFにします。
マクロ名は、#defineや#constによって定義されたものになります。
例:
#define SW
#ifdef SW
mes "ABC" ; この部分はコンパイルされます
a=111 ; この部分はコンパイルされます
mes "DEF" ; この部分はコンパイルされます
#endif
#ifndefは、#ifdefとは逆に指定したマクロ名が定義されていれば出力をOFFに、
そうでない場合は、出力をONにします。
また、ブロック内に#elseを入れることで条件が逆の場合の動作を記述
することができます。
例:
#ifdef SW
mes "AAA" ; SWが定義されている場合
#else
mes "BBB" ; SWが定義されていない場合
#endif
また、#if、#ifdef、#ifndef〜#endifのプロックを入れ子にすることも
可能です。
例:
#ifdef SW
#ifdef SW2
mes "AAA" ; SWとSW2が定義されている場合
#else
mes "BBB" ; SWが定義されている場合
#endif
#endif
#uselib "filename" 外部DLLの指定
#func 新規名称 関数名 タイプ 外部DLL呼び出し命令登録
外部DLL内のプログラムを呼び出すための命令を増やすことができます。
これにより、HSP本体のプログラムから、C言語やDelphiなどで作成した
DLL内の関数を呼び出すことが可能になります。
func命令により、外部の関数もHSPの命令として定義できるので、
HSPを自由に機能拡張することが可能です。外部DLL作成の方法や、
HSPとのパラメータ受け渡しの詳細は、「拡張プラグイン作成リファレンスマニュアル」を参照してください。
普通に使う場合には、まったく必要のない命令ですので、特に覚えて
おかなくても問題ありません。
-
#defineマクロについて
#defineマクロは、あくまで個人がスクリプトを書きやすくカスタマイズしたい
場合に使うもので、初心者向きではありません。ここで説明した機能も、
頻繁に利用するものではありませんので、必要な場合にのみ参照してください。
#defineマクロは、基本的に置き換え文字列を登録します。
例:
#define hyouji mes
hyouji "AAAAA..."
↓(展開後)
mes "AAAAA..."
#define、#const命令の直後に「global」を入れることで、すべてのモジュールで
永続的に利用することのできるマクロを作成することができます。
例:
#module
#define global test 0x1234
#global
a=test ; aに0x1234が代入される
通常は、モジュール内で#defineを定義した場合には、それ以外のモジュール
およびグローバルなエリアでは、同じ名前は認識されません。
global指定を入れることで、それ以降のすべての場所で定義した名前を
マクロで置き換えることができるようになります。
単純な置き換えマクロの他に、引数付きの展開が可能です。
引数は、マクロ名の後にカッコで囲んだ%1,%2,%3…の引数名で指定を
行ないます。
引数は必ず「%数値」で指定する必要があり、数値は1から順番に記述
してください。CやC++のプリプロセッサのようにシンボル名では指定
できないので注意してください。
例:
#define hyouji(%1) mes "prm="+%1
hyouji "AAAAA..."
↓(展開後)
mes "prm="+"AAAAA..."
また、引数に初期(デフォルト)値を設定することが可能です。
例:
#define hyouji(%1="PRM=",%2=123) mes %1+%2
hyouji "AAA",a
hyouji "BBB"
hyouji ,b
↓(展開後)
mes "AAA"+a
mes "BBB"+123
mes "PRM="+b
初期(デフォルト)値は、マクロを使用した時に省略された場合に
自動的に補完される値です。初期値を省略された場合は、補完されません。
マクロ引数の指定では#defineで指定する側では、カッコで囲んで
いますが、実際に使用する時にはカッコなしで指定してください。
#define hyouji(%1) mes "prm="+%1
hyouji("AAAAA...")
のような記述はエラーになるので注意してください。
ただし、ctypeオプションを使用することで以下のようなカッコ付き記述が
可能になります。
#define ctype kansu(%1) (%1*5+1)
a=kansu(5)
このオプションは、計算式など命令部分以外にマクロを使用したい時に
有効です。一見、C言語などの関数のように振舞いますが、実際にはマクロで
置き換えているだけなので、応用範囲は狭いので注意してください。
この記述方法は、本来のHSP文法とは異なるため自分のスタイルで記述したい
というカスタマイズ用途以外での利用は推奨していません。
マクロの展開時に特殊な動作を行なうキーワードを設定することが可能です。
この特殊キーワードは、主にことなるマクロ間でパラメータを共有したり、
入れ子構造をスタックによって実現するためのものです。
#define start(%1) %tstart %s1 mes "START"
#define owari %tstart mes %o
ここで指定されている「%s1」や「%o」などが特殊展開マクロです。
これを使ったサンプルは、以下のように展開されます。
start "OK" → mes "START"
owari → mes "OK"
このように、異なるマクロ間でデータを共有させることが可能になります。
特殊展開マクロは、以下の種類と機能があります。
マクロ 機能
---------------------------------------------
%t タグ名を設定する
%n ユニークなラベル名を生成する
%i ユニークなラベル名を生成してスタックに積む
%o スタックに積まれた文字列を取り出す
%p スタックに積まれた文字列を取り出す(スタック維持)
%s 引数パラメーターをスタックに積む
%c 改行を行なう
特殊展開マクロは、「%」に続けて英文字1文字+パラメータで表現します。
以降のキーワードと識別するために、特殊展開マクロの後には半角スペースを
入れて下さい。「%tabc aaa」のようスペースを含む部分までが特殊展開マクロ
と判断されます。
特殊展開マクロでは、一般的なスタック(First In Last Out)を持っています。
このスタックは、同じタグ名を持つマクロで共有させることができます。
タグ名は、「%tタグ名」のように「%t」に続けて半角英文字16字以内で指定
します。先の例では「%tstart」と指定された「start」がタグ名にあたります。
「%s」は、引数パラメーターをスタックに積むための特殊展開マクロです。
「%s1」と指定すると、「%1」のパラメータをスタックに1段積みます。
スタックに積まれた文字列を取り出す場合は、「%o」を使用します。
「%o」は、スタックに積まれた文字列を取り出して展開します。スタックなので、
最後に積まれたものが最初に取り出されます。「%o0」と指定すると、
スタックを取り出しますが文字列の展開は行ないません(スタック取り出しのみ)。
スタックを戻さずに内容だけを取り出すのが「%p」です。「%p0」は、次に
取り出されるスタックの内容を展開します。「%p1」は、もう一段深いスタック
を取り出します。以降、「%p0」〜「%p9」までを指定することが可能です。
ラベル生成の例を以下に示します。
#define start %tstart *%i
#define owari %tstart await 20:stick a:if a=0 : goto *%o
これを使ったサンプルは、以下のように展開されます。
start → *_start_0000
owari → await 20:stick a:if a=0 : goto *_start_0000
「%i」は、他と重ならないようなユニークなラベル名を生成してスタックに
1段積みます。「%i0」と指定するとラベル名をスタックに1段積みますが、
展開は行ないません。また、「%n」は、ユニークなラベル名を生成して展開
するだけで、スタックには積みません。
上の例では、ラベル名生成によってラベルを新しく作成して、ループ構造を
実現しています。この方法を使えば、入れ子になってもラベル名が重なる
ことのないループ構造を構築することができます。
また、1つのソーススクリプトファイル内ですべてのスタックが取り出されて
いなかったマクロ(タグ名)は、コンパイル時にエラーが報告されます。
かならず、すべてのスタックが取り出されて終わるようなマクロ命令の構成に
しておいてください。
※標準定義マクロのwhile〜wend、do〜until、for〜nextは特殊展開マクロによって作られています。
特殊な場面において、「%c」によって改行を挟んで展開することが可能です。
「%c」の部分で行が分割されて展開されます。主に複数のプリプロセス文に
展開されるようなマクロを定義する用途などに使用することができます。
ただし、現状ですべてのプリプロセッサがマクロ展開に対応しているわけでは
ありません。多用しすぎると、かえって見難くなることもありますので、
よくご理解の上お使いください。
例:
#define def(%1,%2) #deffunc %1@ %c mes@hsp %2@
def test,a
return
def test2,a
return
-
標準マクロ定義ファイル
プリプロセッサでは、commonディレクトリにある「hspdef.as」を標準の
マクロ定義として必ず最初に読み込みます。
「hspdef.as」には、システムで定義するシンボル名やマクロ、基本的な
モジュールなどが追加されていく予定です。
ユーザーは「hspdef.as」を編集しないように注意してください。
個別にカスタマイズを行ないたい場合は、「userdef.as」を用意することで
「hspdef.as」と同様に自動的に読み込まれます。「userdef.as」ファイルが
存在しない場合は、適用されません。
標準マクロ定義ファイルは、以下の順に検索されます。
ソースファイルのあるディレクトリにある「hspdef.as」
↓
commonディレクトリにある「hspdef.as」
ファイルが見つからない場合は無視されます。
また、プリプロセッサが自動的に追加するマクロがあります。
以下のマクロは、自動的に追加され、#ifdef、#ifndef命令などでこれらの
マクロを判別して分岐させることが可能です。
命令 内容
----------------------------------------------------
_debug デバッグモード時
__hsp30__ ver3.0以降使用時
__file__ 使用時点で解析されているファイル名
__line__ 使用時点で解析されている行番号
__date__ 使用時点の日付
__time__ 使用時点の時刻
__hspver__ HSPバージョン番号(*)
*上位8bit、下位8bitがメジャー・マイナーバージョンを示します。
標準マクロは、より個人が書きやすい記述を実現するために用意されたものです。
C言語など、すでに慣れた形式でスクリプトを記述したい場合にお使いください。
見かけ上、命令と同様に動作するほか、同様のマクロを新しく定義する
ことも可能です。詳しくは、別項「#defineマクロについて」を参照してください。
以前のスクリプトを動かす際に、新しく追加されたマクロ名がすでに変数名や
ラベル名として使われているとエラーになります。doやfor、nextなど短い単語は
衝突する可能性が高いので、注意してください。もし、衝突してしまっている
場合は、変数名・ラベル名を別なものに置き換えれば動作させることができます。
・do〜untilマクロ
untilに続く条件が満たされるまで、doからuntilまでの部分を繰り返します。
条件が満たされている場合でも、最低一回はdo〜until内を実行します。
untilに続く条件を省略した場合は、繰り返しを行ないません。
また、_continueにより繰り返しの先頭から再開、_breakにより繰り返しを脱出することができます。
例:
a=0
do
a=a+1:mes "A="+a
until a>5 ; aが5以上になるまでdo以下を繰り返す
・while〜wendマクロ
whileに続く条件が満たされている間だけ、whileからwendまでを繰り返します。
条件が満たされていない場合はねwhileからwendまでを実行しません。
whileに続く条件を省略した場合は、無限に繰り返しを行ないます。
_continueにより繰り返しの先頭から再開、_breakにより繰り返しを脱出することができます。
例:
a=0
while a<5
a=a+1:mes "A="+a
wend ; aが5以下の間だけwhile以下を繰り返す
・for〜nextマクロ
for 変数名,初期値(0),終値(0),増分(1)
をパラメーターとして指定すると、for〜nextの間を指定回数繰り返します。
カッコ内は省略した場合の値です。変数名は省略できません。
指定された変数をカウンターとして使用し、初期値から始まって、
1回繰り返すごとに増分を足していきます。終値に達した時点で、
繰り返しから抜けます(終値はループに含みません)。
最初から終値の条件が満たされている場合は、繰り返しを実行しません。
また、_continueにより繰り返しの先頭から再開、_breakにより繰り返しを脱出することができます。
例:
for a,0,5,1
mes "A="+a
next ; aが0から4の間(5回)繰り返す
この例では、変数aは0,1,2,3,4と5回繰り返してループを終わります。
増分にマイナス値を指定することも可能です。
例:
for a,5,0,-1
mes "A="+a
next ; aが5から1の間(5回)繰り返す
この場合、変数aは5,4,3,2,1と5回繰り返してループを終わります。
forマクロは、内部でマクロ展開後に特殊な新規命令exgotoを生成します。
exgoto命令はforマクロのための補助命令で単体で使用することは推奨
していません。
・switch〜case〜swendマクロ
switch〜case〜swendは、ブロック内に複数の条件判断と処理をまとめて書くことが
できる構文です。
switch 比較元
でswitchブロックを開始します。
比較元のパラメーターは、変数または式を指定することができます。
switch以降は、
case 比較値
を置くことで、これ以降に「比較元」が「比較値」と同じだった場合に処理する
内容を記述することができます。
caseは、ブロック内に複数記述することができ、それぞれの比較値ごとの処理を
指定できます。
caseの比較が正しい場合は、swbreakが存在するまで以降の命令を実行します。
また、caseの替わりに
default
を置くと、caseで指定したどの比較値にもあてはまらない条件の場合に以降が
実行されます。
switchブロックが終了した場合は、
swend
を必ず最後に書いておく必要があります。
以下は、switchマクロを使用したスクリプトの例です。
例:
a=0
switch a ; aを比較対象とする
case 0 ; aが0だった場合
mes "A=0"
swbreak ; case0の条件実行終了
case 1 ; aが1だった場合
mes "A=1"
default ; aが0以外だった場合
mes "A!=0"
swbreak
swend
この例では、変数aの内容が0か1かそれ以外かで条件分岐を行なっています。
「case 0」以降は、「swbreak」までが実行されますが、「case 1」の場合は、
「swbreak」が存在しないため、「default」以降に実行される「mes "A!=0"」も
含めて実行されるので注意してください。
-
API呼び出し
HSP3では、外部のDLLがエクスポートする関数を呼び出す機能を利用できます。
これはあらかじめ指定した引数でDLLを呼び出すための機能で、
ver2.5以降のHSP拡張プラグインを含めて柔軟な使い方が可能です。
DLL呼び出しの概要は以下のものになります。
#uselib "filename" 外部DLLの指定
HSPから呼び出す外部DLLのファイル名を指定します。
DLLのファイル名は、拡張子も含めて完全に書く必要があります。
ファイル名を省略した場合は、実行時にスクリプトからDLL名を指定
してリンクを行なうことになります。
#func 新規名称 関数名 タイプ 外部DLL呼び出し命令登録
外部DLLを呼び出すための新しい命令を登録します。
新規名称、関数名、タイプをスペースで区切って書きます。
関数名は、"関数名"のようにダブルクォートで囲むことで、DLLの完全な
エクスポート名を記述することができます。
ダブルクォートで囲んでいない場合は、「_関数名@16」というVC++の
エクスポート規約に基づいた名前に変換されます。
タイプには、引数の詳細を記述します。
#deffuncと同様に、引数の型を「,」で区切って指定してください。
引数の数や、型の順番に制限はありません。
引数の型として使用できる文字列は以下の通りです。
型 内容
-------------------------------------------------------------
int 整数値(32bit)
var 変数のデータポインタ(32bit)
str 文字列ポインタ(32bit)
wstr unicode文字列ポインタ(32bit)
sptr ポインタ整数値または文字列のポインタ(32bit)
wptr ポインタ整数値またはunicode文字列のポインタ(32bit)
double 実数値(64bit)
label ラベルポインタ(32bit)
float 実数値(32bit)
pval PVal構造体のポインタ(32bit)
bmscr BMSCR構造体のポインタ(32bit)
comobj COMOBJ型変数のデータポインタ(32bit)
prefstr システム変数refstrのポインタ(32bit)
pexinfo EXINFO構造体のポインタ(32bit)
nullptr ヌルポインタ(32bit)
以下は、4つの引数を指定して実行する例です。
例:
#uselib "test.dll"
#func test "_func@16" var,int,int.int
test a,1,2,3 ; test.dllのfunc(&a,1,2,3)が呼び出される
DLLからの関数インポートは、最初に命令が実行された時点で行なわれます。
インポートされる関数名が見つからない場合は、命令を実行した時点で
エラーになります。(起動時にはエラーになりません)
外部API呼び出しの戻り値は、32bit整数としてシステム変数statに代入
されます。
タイプに数値を指定した場合は、ver2.5以降のDLLタイプ指定と互換性のある
引数が自動的に設定されます。
これにより、HSP2.61までの拡張プラグインをそのまま利用可能です。
ただし、ver2.5とは以下の点で互換性の注意が必要です。
- BMSCR構造体は、flagからcolorまでのフィールドのみ参照できます。
- PVal構造体は、ver2.5のPVAL2構造体と互換があります。
- PVal構造体のflagフィールド(型タイプ値)やlenフィールド(配列情報)をDLL側で書き換えることはできません。
- PVal構造体から文字列型の配列変数にアクセスすることはできません。
これ以外の点においては、HSP ver2.5と同等の情報が受け渡されます。
また、関数名の前に「onexit」を入れることにより、終了呼び出し関数として
登録することができます。
例:
#func test onexit "_func@16" str,int,int
上の例では、アプリケーション終了時に自動的に"_func@16"が呼び出されます。
#funcと同様に、#cfunc命令により関数として登録することも可能です。
#cfunc 新規名称 "関数名" タイプ名1,… 外部DLL呼び出し関数登録
引数パラメーターは、#func命令と同じものを使用することができます。
#cfunc命令によって登録された新規名称は、関数として式の中に記述することが
可能です。
例:
#uselib "test.dll"
#cfunc test "_func@16" var,int,int.int
res=test(a,1,2,3) ; test.dllのfunc(&a,1,2,3)が呼び出される
登録された関数の戻り値として、外部呼出しの結果取得された整数値(32bit int)
をそのまま返します。
HSP2.5互換の呼び出しでは、システム変数statに返される値を関数の戻り値とします。
-
COMコンポーネント呼び出し
HSP3では、COMオブジェクト型変数と、COMインターフェースの定義および
呼び出しを行なうための機能を利用できます。
COMコンポーネントの機能を使用するには、COMオブジェクト型変数を作成する
必要があります。通常は、newcom命令を実行して、指定したCOMのクラスや
インターフェースに対応したCOMオブジェクト型変数を作成します。以降、
作成された変数を介して、メソッドを呼び出すことができるようになります。
COMオブジェクト型変数は、COMオブジェクトのインターフェースポインタを
格納しており、オブジェクトの生成と破棄はHSP内部で管理されます。
(明示的に破棄を行なうdelcom命令も用意されています。)
最も手軽にCOMを利用する手段として、オートメーションを介したアクセスが
可能です。この方法は、IDispatchインターフェースを提供している
オートメーションオブジェクトを使用するときに用いることができます。
例:
newcom ie, "InternetExplorer.Application"
上の例では、"InternetExplorer.Application"というプログラムID (ProgID)
を持つオブジェクトを作成し、オブジェクトのインターフェースポインタを
変数ieに格納します。プログラムIDは、VBScriptやJavaScript等で使われている
クラスID定義文字列と同様のものです。
プログラムIDの代わりに、GUIDによるクラスID
("{0002DF01-0000-0000-C000-000000000046}" の形式の文字列)
を指定することも可能です。
COMオブジェクト型変数が作成された後は、プロパティの参照や設定、
メソッドの呼び出しが可能になります。
COMオブジェクト型変数では、配列要素としてプロパティを示す文字列を
指定することで、プロパティの参照と設定を行なうことができます。
例:
ie("Visible")=1
上の例は、COMオブジェクトとして初期化された変数ieの"Visible"という
名前のプロパティに1という整数値を設定するものです。
例:
mes "ウィンドウ位置("+ie("Left")+","+ie("Top")+")"
mes "ウィンドウサイズ("+ie("Width")+","+ie("Height")+")"
上の例では、プロパティの内容を参照して表示を行なっています。
COMオブジェクトが返すプロパティの値は、HSP内部で適切に型変換されて
そのまま使用することができるようになります。
COMオブジェクトのメソッドを実行する場合は、mcall命令を使用します。
例:
mcall ie,"Navigate","http://www.onionsoft.net/"
上の例では、"Navigate"というメソッドを"http://www.onionsoft.net/"という
文字列型の引数を渡して実行します。
引数の数や、型はそのままメソッドに渡されることになります。
実行したメソッドの返値は、comres命令で設定された変数に代入されます。
また、メソッド実行が成功した場合にはシステム変数statは0になり、
エラーが起こった場合には、システム変数statに結果コード(HRESULT値)が
代入されます。
mcall命令の特殊な記述方法として、以下のように書くことも可能です。
例:
ie->"Navigate" "http://www.onionsoft.net/"
変数に続いて「->」とメソッド名を記述し、パラメーターを指定します。
これは、C++等と近い記述方法を利用したい人のためにあるもので、
コンパイラによって自動的にmcall命令に置き換えられます。
COMオブジェクトのプロパティに"$coclass","$interface" を指定することで
オブジェクトのcoclass名・interface名を取得することが可能です。
pobj("$coclass") : coclass名
pobj("$interface") : interface名
オートメーション(IDispatch)を使わずに直接COMインターフェース
(カスタムインターフェース)のメソッドを呼び出すことも可能です。
#usecom インターフェース名 "IID文字列" ["CLSID文字列"] COMインターフェース登録
カスタムインターフェースを使用するため、インターフェース名の
定義を行います。"IID文字列"にはインターフェースIDを文字列形式の
GUID ("{000214EE-0000-0000-C000-000000000046}"のような文字列)で
指定します。"CLSID文字列"には、クラスIDを文字列形式のGUIDで
指定しますが、省略することもできます。
"CLSID文字列"を指定した場合には、newcom命令の第2パラメータに
そのインターフェース名を指定することが可能です。この場合には
#usecom命令のクラスIDを持つオブジェクトを作成し、指定された
インターフェースを取得してCOMオブジェクト型変数に格納します。
#comfunc 新規名称 メソッドインデックス タイプ名1,… COMメソッド登録
#usecom命令によりインターフェースの定義を行なった直後に、#comfunc命令で
COMメソッド及び引数パラメーターを登録することができます。
タイプ名の指定は#func命令の場合と同じです。タイプ名にwstrを指定すると、
メソッドの引数としてunicode(OLESTR)文字列を渡すことができます。
(unicodeからHSP文字列の変換には、cnvwtos関数を利用することができます)
例:
; hsp3.exeへのショートカットshortcut.lnkを作成する
;
#define CLSID_ShellLink "{00021401-0000-0000-C000-000000000046}"
#define IID_IShellLinkA "{000214EE-0000-0000-C000-000000000046}"
#define IID_IPersistFile "{0000010b-0000-0000-C000-000000000046}"
#usecom IShellLinkA IID_IShellLinkA
#comfunc IShellLink_SetPath 20 str
#usecom IPersistFile IID_IPersistFile
#comfunc IPersistFile_Save 6 wstr,int
newcom slink, CLSID_ShellLink
IShellLink_SetPath slink, dirinfo(1)+"\\hsp3.exe"
IPersistFile_Save slink, dirinfo(0)+"\\shortcut.lnk", 1
mes "ショートカットを作成しました。"
delcom slink
end
また、生成されたインターフェースから別のインターフェースを問い合わせる
querycom命令が用意されています。ただし、mcall命令の実行時には
自動的に必要なインターフェースを問い合わせるようになっているので、
COMオブジェクトが目的のインターフェースを提供していることがあらかじめ
わかっている場合には、あえてquerycom命令を実行する必要はありません。
COMオブジェクト型変数を作成するもう1つの方法として、
ActiveXコントロールを配置するためのaxobj命令が用意されています。
axobj命令は、指定されたクラスID(CLSID)またはプログラムID(ProgID)から、
ActiveXコントロールをHSPのウィンドウ内に配置します。
axobj命令で指定された変数は、COMオブジェクト型変数として初期化されます。
例:
axobj ie, "Shell.Explorer.2",640,480
ie->"Navigate" "www.onionsoft.net"
axobj命令で生成されたウィンドウは、HSPが管理する配置オブジェクトとして
登録されます。axobj命令実行後には、オブジェクトIDがシステム変数statに
代入されます。
axobj命令で生成されたウィンドウの破棄は、cls命令などで画面の初期化が
行なわれた際に行なわれます。clrobj命令などで明示的に破棄することも
可能です。ただし、COMオブジェクト型変数として初期化された変数は、
そのまま残されるため、ユーザーが破棄するようにしてください。
COMオブジェクト型変数の破棄は、別な値が代入された時やHSP終了時に
自動的に行なわれるためメモリリーク等が発生することはありませんが、
使用不可能になったCOMのポインタが残ってしまうため、意識して破棄して
おくことを推奨します。
なお、axobj命令を使用するには、実行環境にAtl.dllまたはAtl71.dllが
インストールされていなければいけません。これらのDLLがない場合には
エラーになります。
また、COMイベントを管理するための機能が利用可能です。これにより、
COMオブジェクトから通知されるイベントの通知をスクリプトで取得する
ことができます。
comevent p1,p2,p3,*label
p1 : イベント管理オブジェクトを格納する変数名
p2 : イベント取得元の変数名
p3 : コネクションポイントGUID
*label : イベントサブルーチンのラベル
p2で指定された変数(COMオブジェクト型)から任意のイベントを取得するための
準備を行ないます。p2で指定されたCOMオブジェクトは、すでにnewcom命令により
初期化されている必要があります。p1で指定された変数を、イベント処理を行なう
ための特別なCOMオブジェクト型として初期化します。
p3でコネクションポイントGUIDを文字列形式で指定します。
p3の指定を省略した場合は、IProvideClassInfo2によって得られるデフォルトの
コネクションポイントを検索します。
*labelでイベント処理サブルーチンのラベルを指定します。
イベント取得の準備に失敗した場合は、エラーが発生します。
成功した場合は、これ以降イベントが発生するたびに*labelで指定された場所に
サブルーチンジャンプの割り込みが発生します。
*labelで指定されたイベントサブルーチンでは、comevdisp関数、comevarg命令により
イベントの内容を細かく取得することが可能です。
すでにイベントの取得が開始されている変数に対して、
再度comevent命令を実行した場合は、以前のイベントキューの設定は無効になります。
イベントの取得は、delcom命令によりCOMオブジェクトが破棄されるまで継続されます。
例:
#define IID_DWebBrowserEvents2 "{34A715A0-6587-11D0-924A-0020AFC7AC4D}"
axobj ie, "Shell.Explorer.2", 640, 480
comevent ie_event, ie, IID_DWebBrowserEvents2, *event
stop
*event
; COMイベント処理
title "EVENT="+comevdisp(ie_event)
return
上の例では、IEコンポーネントのイベントDWebBrowserEvents2を取得
して、*eventサブルーチンを呼び出しています。
発生したイベントの種類を識別するディスパッチID(DISPID)を取得するため、
comevdisp関数を使用します。
comevarg命令を実行するとイベントのパラメータを取得することができます。
comevarg p1,p2,p3,*label
p1 : 結果が代入される変数名
p2 : イベント管理COMオブジェクト変数名
p3 : パラメータのインデックス (0〜)
p4 : 取得モード (0=通常の変換, 1=文字列に変換, 2=Variant型)
p2で指定された変数(イベント管理オブジェクトを格納したCOMオブジェクト型変数)
のイベント処理サブルーチン内でイベントのパラメータ(引数)が取得され、
その結果がp1に代入されます。p3は引数のインデックスで、最初の引数を
取得する場合には0を、2番目の引数を取得するには1を指定します。
p3は取得モードで、省略するか0を指定した場合は、HSP標準の変数型に
変換されます。1を指定した場合は文字列に変換した状態で取得されます。
2を取得すると、以下のVariant型変数として取得されます。
HSP3では、COMのための変数型として、Variant型変数を使うことができます。
Variant型変数はCOMオートメーションで使用されるさまざまな型のデータが
格納される変数です。COMイベントのパラメータとして参照型(ByRef)の変数が
指定された場合に、その参照先を書き換えることができるように、HSP3に
導入されています。また、参照型でないパラメータもVariant型の変数として
取得することが可能です。
Variant型変数は、COMイベント処理サブルーチンの中でcomevarg命令を実行
する際に、第4パラメータに2を指定することによって取得できます。
Variant 変数は、COM型変数の場合と同じように、プロパティ名を指定すると
それぞれ以下の値を参照できます。プロパティ名の大文字・小文字は区別
されません。
以下は、変数vをVariant型変数とした時に参照できる特殊なプロパティです。
- v("value") : Variantに格納されている値
v に格納されている値を参照します。例えば、整数型(VT_I4)の
Variantなら a = v("value") とすると変数 a が整数型になり、
値が代入されます。v("value")への代入も可能です。
v("val")やv("")で参照することも可能です。
- v("isbyref") : 参照かどうかを示す値
Variantが参照型(byRef)の場合には1を返します。
- v("isarray") : SafeArrayかどうかを示す値
Variantが配列(SafeArray)の場合には1を返します。
- v("vartype") : VariantのVARTYPE値
2 (VT_I2), 3 (VT_I4), 8 (VT_BSTR) などといったVARTYPE値を
参照します。代入時( v("vartype")=2 など)は型の変換を試みます。
型変換に失敗するとエラーになります。v("vt")でも指定可能です。
- v("vtmask") : VariantのVARTYPE値のマスク値
VARTYPE値のVT_BYREFとVT_ARRAYを取り除いた値を返します。
- v("refptr") : VariantのVARTYPE値
vが参照型(VT_BYREF)のとき参照ポインタを返します。
vが参照型(VT_BYREF)でないときはエラーになります。
また、Variant型変数ではSafeArrayをある程度扱えるようにしています。
SafeArrayを格納しているVariant型変数では以下のプロパティが有効です。
- v("value",n) : SafeArray の要素 n の値
SafeArrayの要素nの値を参照します。この例は1次元のSafeArray
の場合で、例えば2次元配列ではv("value",m,n)とします。単に
v("value")とするとSafeArrayを格納したVariant型を返します。
- v("arraylbound",n) : SafeArrayの次元nの要素の下限
- v("arrayubound",n) : SafeArrayの次元nの要素の上限
- v("arraycount",n) : SafeArrayの次元nの要素の要素数
それぞれ、指定された次元の要素の下限、上限、要素数を返します。
nを省略すると1が指定されます。
- v("arrayptr") : SafeArray のポインタ
格納されているSafeArrayを取得します(戻り値は整数型)。
代入を行うと、与えられたSafeArrayを格納します。
- v("bstrptr") : BSTR文字列 のポインタ
格納されている文字列(BSTR)ポインタを取得します。
COMオブジェクトのプロパティ取得時に、プロパティ名の前にピリオドを
つけておくと、プロパティを Variant 型で返します。(メソッド呼び出し時に
返される戻り値についても同様です。)
vname = pDoc(".Title") ; vname は Variant 型
name = vname("value") ; name は文字列型
上の例は
name = pDoc("Title") ; name は文字列型
と書いた場合と同じです。
また、
dimtype a, vartype("variant"), 20
などとして明示的にVariant型配列を確保することも出来ます。
Variant型とHSPの配列を相互に変換するための、sarrayconv命令が
追加されています。
sarrayconv p1, p2, p3, [p4]
p1 : 結果を格納する変数
p2 : 変換元の変数
p3(0) : 変換のモード
p4(0) : バイナリーデータのサイズ
p3=0:配列変数p2全体からSafeArrayを作成し、Variant型変数p1に
格納します。
p3=1:Variant型変数p2に格納されているSafeArrayを配列変数p1に
格納します。p1の領域は再確保されます。
p3=2:変数p2からp4バイト分だけのバイナリデータからSafeArray
(VT_UI1型)を作成し、p1に格納します。
p3=3:Variant型変数p2に格納されている1次元SafeArray (VT_UI1型
またはVT_I1型)のバイナリデータを変数p1に格納します。
変数p1の領域はあらかじめ確保されている必要があります。
-
HSPテンプレート(AHT)機能
HSPテンプレート(AHT)機能は、HSP3.1以降で追加されたもので、
ソースの自動生成及び外部データとの連携を行なうための様々な仕組みを提供します。
AHTには、様々な役割があります。
- 新しいHSPソーススクリプトを自動生成するためのルールを取り決める
- 再利用可能なHSPソーススクリプト同士の相互依存関係を定める
- HSPで使用可能なデータ形式やそのツールの依存関係を定める
つまり、誰でも手軽にHSPのソーススクリプトを生成するための方法と、
ひな型となるスクリプトやツールを簡単に利用するための仕組みを
サポートするものだと考えてください。
HSPでは、スクリプトを再利用するための手段として、モジュールや
マクロ、プラグインなどを提供してきました。しかしこれらは、
それぞれのユーザーが独自のルールで作成し、公開を行なってきました。
AHTは、これを決められたルールで書式化することで、各種の定型
スクリプトを共通の方法で、より手軽に再利用・連携を行なうことを
目指しています。
テンプレートは、HSP3.1から導入される新しい概念です。
一般的なプログラム言語で使われるテンプレートという概念は、
コードの抽象化を行なうための高度なメカニズムを指すことが多いのですが、
HSPの場合はもっと単純に「ひな型」を提供することに主眼を置いて、
より手軽にスクリプトを再利用するために活用されることになります。
AHTは、再利用可能なHSPソーススクリプトの情報及び、管理を行なう
ツールを含めた仕組みの総称です。
AHTで使用する、定義ファイルは拡張子「.aht」を持つ、「AHTファイル」と呼ばれます。
AHTファイルは、HSP3のソーススクリプトファイル(.hsp)と互換性があります。
AHTファイルをそのままHSP3のソースとしてコンパイルを行なうことが可能です。
AHTファイルは、プリプロセッサ命令を使用してAHTヘッダと呼ばれる定義情報が指定されています。また、特別な書式のコメントを使用してダイアログインターフェース定義を行なっています。
AHTファイルは、従来のHSP3ソーススクリプトを手軽にひな型として再利用するための形式です。最小限の修正で、従来のスクリプトをAHTファイルとして扱うことができます。
AHTについての詳細は、別途ドキュメントaht.txtを参照してください。
4.HSPの基本動作概念
-
HSPのタスク
HSPは中間言語処理によるシングルタスクのインタプリタです。
HSPと他のWindowsアプリケーションはマルチタスクで同時に走らせることができます。
ただし、そのために1つだけHSPのスクリプトを作る上で約束事があります。
HSPでは「キーを押さないと進まないなどの無限にループになる可能性のある部分では、
必ずwaitかawait命令を入れる必要がある」という約束事を覚えておいてください。
waitやawait命令はWindowsの他のタスクに空き時間を回すための重要な役割があります。
これを守らないと、無限ループでWindowsのほぼすべてのタスクを奪ってしまい、
マルチタスク動作に影響が出ます。その結果、ウィンドウが正常にドラッグできなくなったり、
タスクの切り替えができなくなったりと変な状態になります。
(Windowsそれものが動かなくなるなどの致命的な状態にはなりません。
誤ってHSPで無限ループを作ってしまった場合は、[Ctrl]+[Alt]+[Del]を同時に押して
HSPのタスクを終了させればもとの状態に戻ります)
しかし、この約束事を気にしすぎる必要もありません。1秒以内に確実に終わる程度の
ループであれば、waitを入れる必要はありません。waitを入れることでさらに処理速度が
遅くなってしまいます。
最も問題になるのは、たとえば「マウスのボタンを押すまで待つ」というような部分を、
例:
*mwait
getkey a,0
if a=0 : goto *mwait
のように記述すると、そこで無限ループになってしまいます。これを、
例:
*mwait
getkey a,0
await 5
if a=0 : goto *mwait
このように修正すれば、無限ループは回避され正常にタスクが実行されます。
「await 5」は、非常に短い単位でのウェイトなので、これによってボタンの入力が
しにくくなることもありません。
await命令はループ内の時間経過を一定に保つための命令です。
指定した時間だけ待つには、wait命令を使用してください。
CPU(Windows)に対する負担はawait命令もwait命令も変わりありません。
-
画面とウィンドウ
HSPの中心となる機能は、画面に文字や画像、そして点、線などを描画する
ものです。HSPでは複数の描画バッファが用意されていて、それぞれに
ウィンドウを割り当て、複数のウィンドウ画面を操作することが可能です。
HSPでは描画対象となる仮想的な画面を複数持つことができます。
これらの仮想画面は、ウィンドウIDと呼ばれる数値で管理されます。
ウィンドウID0は、最初に現れる画面を指します。2つ以上のウィンドウを
開くことがないのであれば、ウィンドウIDは特に意識せずに使用できます。
HSPのメイン画面とは別に新しいウィンドウを開いたり、メモリ上に仮想
画面を作成する場合には、ウィンドウID1以降を使うことになります。
ウィンドウIDの値に制限はありませんが、ID1から順番に使用するように
してください。
新しい仮想画面は、初期化してから使用しなければなりません。そのための
命令がscreen命令およびbuffer命令です。screen命令で初期化をすると、
その画面は新しいウィンドウとしてディスプレイ上に表示されます。
(このウィンドウは標準でサイズを変更することができます。)
それに対して、buffer命令で初期化をすると、その画面はメモリ上に存在
するだけとなり、ディスプレイからはその内容は見えません。このような
画面は、ほかの画面に画像の一部をコピーするためのテンポラリとして、
また一時的な画像の保存場所などに使用することができます。
screenやbuffer命令などでウィンドウIDを初期化した後は、その画面に
対して自由に描画を行なうことができます。mes命令により文字を表示
したり、boxf命令による塗りつぶしやline命令による直線の描画など
色々な命令が用意されています。
複数のウィンドウIDを使用している場合は、描画の対象をgsel命令によって
変更することができます。また、gcopy命令やgzoom命令により別なウィンドウ
IDの画面に描かれている画像をコピーしてくることが可能です。
画面は、cls命令により再度初期化することができます。
また、picload命令により画像を読み込んだ場合にも初期化されます。
高速に画面全体を切り替えてアニメーションなどを行なう場合には、
redraw命令により再描画スイッチをOFFにしておき、画面の書き換えを
行なった後、再描画スイッチをONにしてください。これにより、画面の
書き換え中の結果が画面に反映されなくなり、スムーズで高速な書き換え
を行なうようになります。また、書き換えの際にはcls命令は使わずに
boxf命令などで画面をクリアするようにしてください。
-
画像ファイルの利用
画面内に表示する画像データとして、標準的な画像フォーマットのファイル
を読み込んで使用することができます。
拡張子 フォーマット
--------------------------------------------------------------------
bmp Windows標準ビットマップ画像データ
jpg JPEG形式画像圧縮データ
gif GIF形式画像圧縮データ(アニメーションを除く)
ico Windows標準アイコン画像データ
画像の読み込みは、picload命令によって行ないます。ファイル名を指定する
ことで、自動的にフォーマットを判別して読み込みます。
また、メモリストリーム機能を使用することで、メモリ上に存在する
ファイルデータから画像を読み込むことも可能です。
pngフォーマットについては、COM機能を利用して読み込むことが可能です。
詳しくは、「HSP3支援モジュール」を参照してください。
-
カレントポジション
メッセージの出力、グラフィックデータのコピー、ボタンの配置などは
カレントポジションと呼ばれる座標を対象に行なわれます。
カレントポジションはテキストエディタのカーソルのようなもので、
メッセージが出力された後は、カレントポジションも改行した次の行に
自動的に移動します。
カレントポジションは、pos命令によって変更することが可能です。また、
objsize命令によって、カレントポジションの移動量を調節することができます。
cls命令などで画面が初期化された時は、カレントポジションも(0,0)にリセ
ットされます。
-
配置オブジェクト
HSPでは、押しボタン、入力ボックスなどの部品を配置オブジェクトと呼び、画面内で
自由に配置することが可能です。
HSPでは、標準で以下のようなオブジェクトを使用することができます。
オブジェクト名 配置命令 内容
--------------------------------------------------------------------
ボタン button 押されると指定ラベルのプログラムを実行
入力ボックス input 数値や文字列を入力
メッセージボックス mesbox 複数行の文字列を入力
チェックボックス chkbox ON/OFFチェックマーク切り替え
コンボボックス combox 複数要素から選択可能な枠
リストボックス listbox 複数要素から選択可能な枠
それぞれのオブジェクトには、オブジェクトIDという番号が割り振られ管理されています。
オブジェクトIDは、0から始まる整数値で、配置命令の実行後にシステム変数statに
代入されます。通常は、画面内に配置した順に自動的に0,1,2,3…と数値が割り振られます。
オブジェクトIDが必要な時は、オブジェクトの一部を後から消したい時、状態を変更したい
時などです。また、押しボタンが押された時には、システム変数statに押されたボタンの
オブジェクトIDが代入されます。
オブジェクトは簡単に配置して使うことができますが、より奥深い使い方をマスターすれば、
さらに高度なスクリプトを書くことも可能になります。
オブジェクトの内容を後から変更するための、objprm命令や、オブジェクトにWin32メッセージを
直接送るsendmsg命令はそのような高度な使用のために用意された命令です。
ここに挙げた配置オブジェクト以外にも、Windowsがサポートするコントロールを
winobj命令により追加できるほか、axobj命令によりActiveXコントロールを直接
追加することも可能です。
-
カレントカラー
メッセージの出力、点、線、矩形の描画などに使用される色がカレントカラー
です。これは、palcolor命令、color命令で変更することができます。
cls命令などで画面が初期化された時は、カレントカラーは黒色にリセットされます。
また、システム変数ginfo_r、ginfo_g、ginfo_bでカレントカラーのRGBをそれぞれ参照することができます。
-
メモリバッファの使用
通常の変数や、配列変数が使用しているメモリをファイルにセーブしたり、
ファイルからロードをするための命令が用意されています。
メモリバッファは、Windowsが許す限りのメモリを扱うことができ、上限はありません。
メモリバッファのファイル入出力は、通常bload命令、bsave命令で行ないます。
また、テキストファイルを扱うためにベットnoteload命令、notesave命令
が用意されています。詳しくは、「メモリノートパッド命令」の項を参照してください。
-
マルチメディア再生
HSP3では、WAV形式のPCM音声ファイル、SMF(MID)形式の標準MIDIファイル、
CDの音声トラック再生、AVI/MPEG動画ファイルやMP3/WMA等の波形圧縮
ファイルなどを手軽に扱うことができます。
また、MCIコントロールデバイスとして登録されている機器のコントロール
も可能です。
再生するためのファイルは、mmload命令によってHSPに登録され、mmplay命令で
再生を開始することができます(再生中断はmmstop命令)。
それぞれのサウンドは、ループ再生、再生終了までのウエイトを選択できます。
ただし、MIDIのループ再生には問題があり完全なループ演奏にはなりません。
WindowsのMIDIシーケンサーが演奏開始まで時間がかかるのと、MIDIデータには
最初に音源を初期化するコードや音色の指定などで時間がかかる場合が多いため
演奏終了から、ループまでがうまくつながらないことが多いからです。
ですから、この機能はあくまで簡易のループということをご了承ください。
そもそもループポインタが指定できないので、前奏まで戻るのも変なんですが、
ゲーム中にBGMが終わってしまうのが寂しいのを避けるためと割り切って使う
ことはできるかもしれません。
MIDIのデバイスドライバによっては、MIDI演奏をストップした直後に、再びMIDI
演奏を開始するとWindowsがフリーズしたり演奏されないものがあるようです。
そのような場合には、MIDI演奏終了後に1〜2秒ほどのウエイト(wait 20など)を
入れてから、次の演奏を開始するようにしてみてください。
WAV形式のPCM音声は、最初にすべてメモリにロードされてから再生されるので
ループ再生も問題なく行われます。ただし、WAVファイルのサイズだけメモリ
を占有するので、あまりにも巨大なファイルは、mci命令で再生するようにしてください。
-
コンソール版HSP
HSP3では、コマンドプロンプト上で動作するテキスト表示のみのランタイムを
標準で同梱しています。
コンソール版HSP(HSPCL)は、以下のような場面で使うことができます。
- バッチファイルの代用として単純処理を行なう
- WindowsベースのWEBサーバー上でのCGI実行する
- メモリやCPUの負担をより軽くしてHSPスクリプトを実行する
HSPCLを使用する場合は、スクリプトの先頭に以下の行を付加して下さい。
#runtime "hsp3cl"
ランタイムが切り替わり、自動的にコマンドライン上で動作する状態になります。
尚、ウィンドウ、オブジェクト、マルチメディアに関する命令は使用できません。
sample/hspclフォルダに、HSPCL用のサンプルが収録されているほか、
sample/hspcl/cgiフォルダにCGIとして動作させる場合のサンプルがあります。
HSPCLでは、専用のinput命令が実装されています。書式は以下の通りです。
input p1,p2,p3 標準入力を取得
p1=変数名 : 情報を格納する変数名
p2=1〜 : 変数に代入される最大文字数
p3=0〜(0) : 改行コード認識フラグ(0=なし/1=認識)
・説明
標準入力の内容をp1で指定された変数に代入します。
p1で指定された変数は文字列型に変更され結果が代入されます。
この場合、文字列のサイズは、p2で指定した文字数までとなります。
p2の指定が省略された場合は、変数に代入できる最大値となります。
p3を省略するか、0を指定した場合は標準入力すべて(EOFまで)を
そのまま取得します。p3に1が指定された場合は、改行コード(13)を
終端として認識します。標準入力として、キーボード入力(コンソール)
を使用する場合には、p3を1にすることにより[Enter]キーで入力を
確定させることが可能になります。
通常は、文字列終端(文字コード0)までを取得しますが、p3の値に
16を加算することで、文字コード0を含む標準入力バッファ内容すべてを
変数バッファに取り込みます。バイナリデータなど0を含むコードを
取得する場合に指定するようにしてください。
入力結果の文字数はシステム変数strsizeに保存されます。
それ以外の機能は、HSP3相当として使用することが可能です。
拡張プラグインや、COM関連命令も使用可能です。(ただし、プラグイン側が
BMSCR構造体を取得して使用するような場合に動作エラーとなることがあります。)
実行ファイル作成、PACKFILEの埋め込み、暗号化などもサポートしています。
-
割り込み
色々な要因による割り込み処理がサポートされています。
割り込み処理のために以下の命令が用意されています。
onkey goto/gosub *label キー割り込み実行指定
onclick goto/gosub *label マウスクリック割り込み実行指定
oncmd goto/gosub *label,p1 ウィンドウメッセージ割り込み実行指定
onexit goto/gosub *label プログラム終了時に割り込み
onerror goto/gosub *label エラー発生時に割り込み
button goto/gosub "name",*label ボタンを押した時の割り込み
*label : 割り込み時に実行されるラベル
onkey命令でラベルを指定すると、それ以降はHSPのウィンドウがアクティブな
時にキー入力が発生するたびに*labelで指定したラベルにジャンプ
(またはサブルーチンジャンプ)します。
onclick命令でラベルを指定すると、それ以降はHSPのウィンドウ上でマウス
クリックが行なわれるたびに*labelで指定したラベルにジャンプ
(またはサブルーチンジャンプ)します。
oncmd命令は、ウィンドウに特定のメッセージが通知された時の処理を
設定するためのものです。(詳しくは、リファレンスを参照してください。)
button命令も割り込み設定の1つとして考えることができます。
配置したボタンが押された時の処理を設定することができます。
onexit命令は、クローズボックスや[Alt]+[F4]によりプログラムが
中断された場合の処理を設定します。
onerror命令は、スクリプトが原因でHSP内部でエラーが発生した時の、
処理を設定します。
onerror命令によりエラー後の処理を指定した場合であっても、
必要な処理が終わったら、そのままアプリケーションの実行は再開
せずに、なるべくend命令で終了させてください。
onerror命令は、エラーから回復させるものではありません。
エラー発生の原因によっては、HSPのシステム自体が不安定になったり
障害が発生することも有り得ます。
onerror命令を使う場面としては、実行ファイル作成時にエラーが
発生した場合にアプリケーション側で独自のエラー表示を行ないたい
場合や、特定のエラーが発生する場合にだけデバッグのための表示を
行なうなどが考えられます。
割り込みによるジャンプ(on??? gosubを使わない割り込み)が発生した
場合には、サブルーチンやrepeat〜loopのネストはすべて0(初期状態)に
戻されます。サブルーチン先で割り込みジャンプが行なわれる場合などは
メイン側にプログラム制御を戻すようにしてください。
キーやマウス入力による割り込みは、stop命令および、wait、await命令で
停止している時にのみ割り込みを受け付けます。
また、割り込みによりジャンプを行なった後は以下のシステム変数が
セットされます。
割り込み要因 iparam wparam lparam
--------------------------------------------------------------
onkey 文字コード wParam lParam
onclick マウスボタンID wParam lParam
oncmd メッセージID wParam lParam
onexit 終了要因 ウィンドウID lParam
onerror 0(なし) エラー番号 エラー発生行番号
システム変数iparamには、割り込み要因ごとのパラメータが代入されます。
また、wparam,lparamはWindowsメッセージとして渡されたパラメータが
そのまま格納されています。
イベント割り込み実行の一時的なON/OFFをすることも可能です。
onkey 0
で一時的にキー割り込みを停止します。
onkey 1
で一時停止したキー割り込みを再開させることができます。
同様に、
onclick 0 / onclick 1 / onerror 0 / onerror 1 / onexit 0 / onexit 1
なども使用できます。
onexit命令は、Windowsシャットダウン時(再起動、電源を落とす等)にも
割り込み処理が実行されます。
これにより、スクリプト実行中にシャットダウンが起こった場合でも、
それを検知して適切な終了処理を行なうことが可能になりましたが、
以下のような制限がありますので、終了時を判定するスクリプトを作成
する場合は、留意しておいてください。
onexitでジャンプされた直後は、システム変数iparamに終了要因が値として
保存されています。
iparam = 0 の場合は、ユーザーの意思でプログラムを終了。
iparam = 1 の場合は、Windowsシャットダウンによる終了です。
Windowsシャットダウン時の終了処理には、await、wait、stop命令
などでシステムにアイドルタイム(待ち時間)を発生させた場合には、
シャットダウン処理を中止します(シャットダウンされません)。
await、wait、stop命令を使わずにend命令で終了した場合には、
そのままシャットダウン処理が継続されます。
シャットダウン処理を中止させないで、終了処理を行ないたい場合には、
待ち時間の発生する命令(await、wait、stop命令など)は使用できません。
(ただし、コモンダイアログ(dialog命令)などは使用できます)
最小限の終了処理だけを行なって、そのまま終了するようにしてください。
-
標準モジュール名
HSPがシステムで使用している標準キーワードは「@hsp」というモジュール名の
空間に割り当てられています。
これは、たとえばmes命令であれば、「mes@hsp」という名前が正式な名称であることを
意味します。ただし、通常のグローバルな空間でも使用できるように「@hsp」がない
名称も別名として登録されているので、いままで通りの命令名でそのまま使用することが
できます。
たとえば、mes命令であれば「#define global mes mes@hsp」が最初から定義されている
のと同じです。(プリプロセッサ処理後に、標準キーワードは「@hsp」が付けられた
正規の名称に展開されます。コンパイル時に出力される「hsptmp.i」を開いてみると
わかると思います。)
これにより、標準キーワードとして登録されている名称そのものを別名にしたり、
ユーザーが定義し直すことが可能になります。
以下は、mes命令をマクロにより置き換えている例です。
例:
#undef mes
#define mes(%1) mes@hsp "MES->"+%1
mes "メッセージです。"
stop
「mes」というキーワードを、#undef命令により取り消した後、再定義しています。
HSPで使用される標準キーワードすべては、同様に取り消し、再定義することが可能です。
以下は、mes命令をユーザー定義命令に置き換えている例です。
例:
#module
#deffunc mes str _p1
_y=csry
color 0,0,0
pos csrx+1,_y+1
mes@hsp _p1
color 0,192,255
pos csrx,_y
mes@hsp _p1
return
#global
mes "mes命令を影文字にしてみました。"
標準キーワードの再定義は、それ以降のキーワードすべてに影響があるため
注意して使用してください。
-
コモンディレクトリ
「#include」命令で挿入されるファイルは、通常はソースファイルと
同じ(カレント)ディレクトリにあるものが使われますが、そこにない場合は、
コモンディレクトリにあるものを使います。
コモンディレクトリは、HSED3.EXEやHSP3.EXEと同じディレクトリにある
「common」という名前になります。
たとえば、「c:\hsp」というディレクトリにHSED3.EXEがあり、
「c:\script」というディレクトリで「test.as」というスクリプトを編集して
いるとすると、「#include」命令でファイルをサーチする順番は、
1. 「c:\script」にあるファイルをサーチ
2. なければ「c:\hsp\common」にあるファイルをサーチ
3. それでもなければエラー
のようになります。
拡張プラグインを使うためのファイル、(hspext.asなど)は、すべて
コモンディレクトリに置かれています。
また、hsp3util.asなど、よく使われるファイルも格納されています。
-
エラーメッセージ
スクリプトの書き間違いや、指定のミスなどでHSPの実行中にエラーを
発見した時には、エラーコードとエラー行番号が表示されるようになっています。
エラー番号とその内容は、以下の通りです。
1 "システムエラーが発生しました"
通常は表示されないエラーです。ファイルが破損している場合や、
予期しない事態が起こった時に表示されます。
2 "文法が間違っています"
関数と命令の記述方法が間違っている時や、
変数名、ラベル名が間違っている時に表示されます。
3 "パラメータの値が異常です"
パラメータの値が許容範囲を越えている場合に表示されます。
4 "計算式でエラーが発生しました"
計算式の書き方が間違っていたり、使用できない記号や演算をしようと
した時に表示されます。
5 "パラメータの省略はできません"
パラメータの省略ができない部分が省略されている時に表示されます。
6 "パラメータの型が違います"
パラメータに指定された型(文字列型、数値型など)が、規定のものではない
時に表示されます。変数が指定されている場合は、変数の型が間違っています。
7 "配列の要素が無効です"
配列の要素として指定した値が、dim、sdim命令などで設定した数を
越えている時に表示されます。
8 "有効なラベルが指定されていません"
ラベルとして指定すべきパラメータが間違っている場合や、
ラベルを示す「*」の後に何もない時に表示されます。
9 "サブルーチンやループのネストが深すぎます"
gosub命令、repeat命令を多重に実行しすぎた時に表示されます。
10 "サブルーチン外のreturnは無効です"
gosub命令で呼ばれていないのに、return命令が実行された時に表示されます。
11 "repeat外でのloopは無効です"
repeat命令がないのに、loop命令が実行された時に表示されます。
12 "ファイルが見つからないか無効な名前です"
ファイル操作をする時に、指定されたファイルが見つからなかったか、
またはアクセスできないファイルである時に表示されます。
13 "画像ファイルがありません"
picload命令で読み込むための画像ファイルが見つからない時に表示されます。
14 "外部ファイル呼び出し中のエラーです"
exec命令で外部ファイルを呼び出す際に、何らかの問題が発生した時に
表示されます。
15 "計算式でカッコの記述が違います"
計算式で使われている括弧「(、)」の書式が正しくない、または対応が
おかしい時に表示されます。
16 "パラメータの数が多すぎます"
命令に指定されたパラメータの数が多すぎる時に表示されます。
17 "文字列式で扱える文字数を越えました"
文字列を扱う上での許容量を越えた時に表示されます。
18 "代入できない変数名を指定しています"
システム変数や予約キーワードに対して代入しようとした時に表示されます。
19 "0で除算しました"
0で割り算をしようとした場合に表示されます。
20 "バッファオーバーフローが発生しました"
文字列変数のためにsdim命令や、dim命令で確保したサイズをオーバーした場合や、
変数バッファを超えてアクセスを行なおうとした場合に表示されます。
21 "サポートされない機能を選択しました"
gcopy命令でパレットモード時に半透明コピーを実行しようとした場合など、
機能としてサポートされない設定が行なわれている場合に表示されます。
22 "計算式のカッコが深すぎます"
計算式が複雑すぎて評価中にスタックオーバーが起こった場合や
何らかの理由で正しく計算が行なわれなかった時に表示されます。
通常、表示されることはありません。これが表示される場合は、
システムに致命的なエラーが発生したことを示しています。
23 "変数名が指定されていません"
パラメーターとして変数名を指定すべき場所に間違った記述がされていると
表示されます。
24 "整数以外が指定されています"
パラメーターに整数のみを指定すべき場所で他の型が検出された時に
表示されます。
25 "配列の要素書式が間違っています"
配列要素の書き方が間違っている場合や、配列要素を書いては
いけない場所に書かれている時に表示されます。
26 "メモリの確保ができませんでした"
システムの物理メモリを確保できなかった時に表示されます。
これが表示される場合は、致命的なエラーとなります。
27 "タイプの初期化に失敗しました"
標準型及びプラグインによる拡張型の初期化に失敗した時に表示されます。
これが表示される場合は、システムに致命的なエラーがあることを
示しています。
28 "関数に引数が設定されていません"
関数のパラメーターが正しく記述されていない場合に表示されます。
29 "スタック領域のオーバーフローです"
サブルーチン呼び出しや、式の評価の処理中にスタックが破壊された
場合に表示されます。通常、表示されることはありません。
これが表示される場合は、システムに致命的なエラーが発生したことを
示しています。
30 "無効な名前がパラメーターに指定されています"
パラメーターとして無効な名称が使用されている場合に表示されます。
実態のないエイリアスやローカル変数が参照された場合にも表示される
ことがあります。
31 "異なる型を持つ配列変数に代入しました"
初期化されている型と異なる型の値を配列に代入しようとした場合に
表示されます。
32 "関数のパラメーター記述が不正です"
関数のパラメーター書式が間違っている場合や、カッコが足りない時に
表示されます。
33 "オブジェクト数が多すぎます"
ウィンドウ内に配置されるオブジェクトが設定された制限値を越えた
場合に表示されます。
34 "配列・関数として使用できない型です"
配列をサポートしていない型で配列指定をした場合や、
関数でないキーワードを関数として使用しようとした時に表示されます。
35 "モジュール変数が指定されていません"
パラメーターにモジュール変数を指定すべき場所に間違った内容が
書かれている場合に表示されます。
36 "モジュール変数の指定が無効です"
パラメーターに指定されたモジュール変数が間違ったモジュールで
初期化されている場合に表示されます。
通常、表示されることはありません。これが表示される場合は、
システムに致命的なエラーが発生したことを示しています。
37 "変数型の変換に失敗しました"
変数や値の型を変換ができなかった時やサポートされていない
場合に表示されます。
38 "外部DLLの呼び出しに失敗しました"
外部DLLの関数呼び出しの先のアドレス取得に失敗した場合に表示されます。
39 "外部オブジェクトの呼び出しに失敗しました"
COMオブジェクトの呼び出し中にエラーが発生した場合に表示されます。
40 "関数の戻り値が設定されていません。"
ユーザー関数として定義されているスクリプト中に、return命令で
戻り値を設定していなかった場合に表示されます。
41 "関数を命令として記述しています。"
関数として定義されているキーワードを命令の書式で記述している場合に表示されます。
命令の名前を間違って書いているか、HSP2から関数化された名前を誤って
使用している可能性があります。
-
HSPシステムの許容範囲
現バージョンでのシステムリソースの許容範囲は以下の通りです。
この値をオーバーしてしまった場合、正常な動作の保証はできません。
ソースファイル(.AS)の最大サイズ 無制限
オブジェクトファイル(.AX)の最大サイズ 無制限
宣言できるラベルの最大数 無制限
宣言できる変数の最大数 無制限
識別されるラベル・変数の最大文字数 59文字(半角)
命令内で使用できる文字列の最大 無制限
変数に保持できる文字列の最大 無制限(メモリが許す限り)
変数に保持できる配列の最大 無制限(ただし4次元まで)
定義可能なプラグインの最大数 合計8192タイプまで
プラグインで拡張可能な命令最大数 1タイプあたり65536まで
定義可能なモジュールの最大数 無制限
モジュール内のユーザー定義命令最大数 無制限
oncmd命令で定義可能な割り込み最大数 無制限
ウィンドウIDの最大数 無制限
1画面内のオブジェクト数 16384個(1024個で警告あり)
表示できるウィンドウの最大サイズ 無制限(メモリが許す限り)
表示できる画像の最大サイズ 無制限
- PACKFILEと暗号化
HSPでは、実行ファイルを作成する際に、読み込まれるファイルをまとめて
1つの実行ファイルに埋め込むことが可能です。
これを、ファイルのパックと呼んでおり、まとめるファイル一覧の情報を
記録したファイルをパックファイル(PACKFILE)と言います。
パックファイルには、無制限に複数のファイルを指定することができます。
パックファイル内で階層を表現することはできません。
ファイル名は、拡張子も含めて19文字までが識別対象になります。
(ロングファイル名でも認識します。)
また、1つの実行ファイルにパックするのではなく、独立したファイルに
パックすることも可能です。この独立したファイルをDPMファイルと呼び、
拡張子が「.dpm」になります。
実行ファイルを作成した場合に、ファイルを読み込みのために検索される順序は、
以下の通りです。
1. 実行ファイルにパックされたファイル
2. 実行ファイルと同じ場所に置かれた「data.dpm」にパックされたファイル
3. カレントディレクトリにあるファイル
パックする際に、暗号化を施すことができます。
これにより、実行ファイルやDPMファイルを解析されることを難しくします。
暗号化されたファイルを扱う場合には、いくつかの方法があり、
解析のされにくさも異なります。
- 実行ファイルに暗号化してパック
HSP2.61と同様に、パックされる内容をもとに生成された暗号キーを使用して、
暗号化を行ないます。標準的な方法です。
- DPMファイルに暗号化してパック(1)
スクリプトエディタのメニューから、「DPMファイル作成」機能を使用して作成します。
作成されたDPMファイルは、暗号化されている場合にはエディタ等でデータの確認が
難しくなりますが、HSPを使って用意に中身を取り出すことが可能です。
実行ファイルにパックする場合よりも、セキュリティは低くなります。
- DPMファイルに暗号化してパック(2)
HSP3.0から追加された、個別の暗号キーを設定した状態でDPMファイルを作成します。
作成されたDPMファイルは、暗号化に使用されたキーコード(32bit値)をスクリプトから
指定しない限り正しく開くことができません。
暗号キーをスクリプト内に持っているため解析が難しく、
実行ファイルにパックする場合よりも、セキュリティは高くなります。
暗号キー設定によるDPMファイルを作成は、スクリプトから設定をする必要があります。
詳しくは、サンプルスクリプトの「mkpack.hsp」を参照してください。
#epack命令により暗号化されたファイルをbload命令で読み込む場合は、
ファイルのオフセット値を指定することができませんので注意してください。
HSPが提供する暗号化機能は、必ずしも完全なセキュリティを保障するものではありません。
問題が発覚したり、セキュリティホールが発見された場合には、今後も適宜対応して
いきたいと考えています。また、ファイル解析や改ざんなどに対する対処は、
今後も継続していく予定です。