if文を何度も呼ぶのは気が引けるのでEasy3DForHSP3のe3dgetkeyboardstate命令を利用するのはいかがでしょうか。
以下は一例ですが、全体の半分は各キーへの名前の定義に当ててあるので、実部はそれほど大きくありません。
#include "e3dhsp3.as"
#include "hsp3util.as"
//使用する変数の領域を定義
dir = dir_cur //自身の存在するアドレス
time = 0 //ログを取り始めてからの総フレーム数
note = "" //ログの保存先。行数が多いと鈍足になるので適時ハードに保存
page = 0 //ハードに保存したログの枚数
list = "" //dirlist命令への引数用途の変数。実際の意味は無い
getdatestr t1 //t1 = 日時。ファイル名は[/]が使えないので[/]を変換
t1 = strmid(t1,0,4)+"年"+strmid(t1,5,2)+"月"+strmid(t1,8,2)+"日"
gettimestr t2 //t2 = 時刻。ファイル名は[:]が使えないので[:]を変換
t2 = strmid(t2,0,2)+"時"+strmid(t2,3,2)+"分"+strmid(t2,6,2)+"秒"
dim prekeybuf, 256 //1フレーム前の各キーの入力状態
dim keybuf, 256 //現フレームの各キーの入力状態
dim keycount, 256 //ログを取り始めてからの各キーの入力数
sdim keyname, 64, 256 //各キーの名前
repeat 256 //各キーに仮の名称を付ける
keyname(cnt) = strf("unassigned($%02X)",cnt)
loop
//各キーに適当な名称を定義
keyname(VK_LBUTTON) = "左クリック"//$01 ;マウス 左クリック
keyname(VK_RBUTTON) = "右クリック"//$02 ;マウス 右クリック
keyname(VK_CANCEL) = "Ctrl+Break (CANCEL名義)"// $03
keyname(VK_MBUTTON) = "車輪クリック"//$04 ;/* NOT contiguous with L & RBUTTON */
keyname(VK_BACK) = "BackSpace (BACK名義)"// $08
keyname(VK_TAB) = "Tab"// $09
keyname(VK_CLEAR) = "非NumLock時のテンキー5 (CLEAR名義)"// $0C
keyname(VK_RETURN) = "Enter (RETURN名義)"// $0D
keyname(VK_SHIFT) = "Shift"// $10
keyname(VK_CONTROL) = "Ctrl"//$11
keyname(VK_MENU) = "Alt (MENU名義)"// $12
keyname(VK_PAUSE) = "Pause"// $13
keyname(VK_CAPITAL) = "Shift+CapsLock (CAPITAL名義)"//$14
keyname(VK_KANA) = "ひらがな/カタカナ (KANA名義)"// $15
keyname(VK_JUNJA) = "(JUNJA名義 $17)"// $17
keyname(VK_FINAL) = "(FINAL名義 $18)"// $18
keyname(VK_KANJI) = "Alt+半角/全角(HANJA名義)"// $19
keyname(VK_ESCAPE) = "Esc"// $1B ;エスケープキー
keyname(VK_CONVERT) = "(CONVERT名義 $1C)"//$1C
keyname(VK_NONCONVERT) = "(NONCONVERT名義 $1D)"// $1D
keyname(VK_ACCEPT) = "(ACCEPT名義 $1E)"// $1E
keyname(VK_MODECHANGE) = "(MODECHANGE名義 $1F)" // $1F
keyname(VK_SPACE) = "Space"// $20 ;スペースキー
keyname(VK_PRIOR) = "PageUp (PRIOR名義)"// $21
keyname(VK_NEXT) = "PageDown (NEXT名義)"// $22
keyname(VK_END) = "End"// $23
keyname(VK_HOME) = "Home"// $24
keyname(VK_LEFT) = "←"// $25 ;左矢印キー
keyname(VK_UP) = "↑"// $26 ;上矢印キー
keyname(VK_RIGHT) = "→"// $27 ;右矢印キー
keyname(VK_DOWN) = "↓"// $28 ;下矢印キー
keyname(VK_SELECT) = "(SELECT名義 $29)"// $29
keyname(VK_PRINT) = "(PRINT名義 $2A)"// $2A
keyname(VK_EXECUTE) = "(EXECUTE名義 $2B)"//$2B
keyname(VK_SNAPSHOT) = "(SNAPSHOT名義 $2C)"// $2C
keyname(VK_INSERT) = "Insert"// $2D
keyname(VK_DELETE) = "Delete"// $2E
keyname(VK_HELP) = "(HELP名義 $2F)"// $2F
word = "@"
repeat 10 //数字
wpoke word, 0, 20354+cnt*256
keyname($30+cnt) = word
loop
repeat 26 //アルファベット
wpoke word, 0, 24706+cnt*256
keyname($41+cnt) = word
loop
keyname(VK_LWIN) = "ウィンドウズキー左 (LWIN名義)"// $5B
keyname(VK_RWIN) = "ウィンドウズキー右 (RWIN名義)"// $5C
keyname(VK_APPS) = "Applicationキー[右クリックと等価] (APPS名義)"// $5D
keyname(VK_SLEEP) = "(SLEEP名義 $5F)"// $5F
word = "テンキーの@"
repeat 10 //テンキーの数字
wpoke word, 10, 20354+cnt*256
keyname($60+cnt) = word
loop
keyname(VK_MULTIPLY) = "テンキーの*"// $6A
keyname(VK_ADD) = "テンキーの+"// $6B
keyname(VK_SEPARATOR) = "(SEPARATOR名義 $6C)"//$6C
keyname(VK_SUBTRACT) = "テンキーの−"// $6D
keyname(VK_DECIMAL) = "テンキーの."//$6E
keyname(VK_DIVIDE) = "テンキーの/"// $6F
word = "F@@"
repeat 24 //ファンクションキー
if cnt+1<10 {
wpoke word, 4, 0
wpoke word, 2, 20354+(cnt+1)*256
} else {
wpoke word, 2, 20354+((cnt+1)/10)*256
wpoke word, 4, 20354+((cnt+1)\10)*256
}
keyname($70+cnt) = word
loop
keyname(VK_NUMLOCK) = "NumLock"//$90
keyname(VK_SCROLL) = "ScrollLock"// $91
keyname(VK_OEM_FJ_JISHO) = "(OEM_FJ_JISHO名義 $92)"// $92 ;// 'Dictionary' key
keyname(VK_OEM_FJ_MASSHOU) = "(OEM_FJ_MASSHOU名義 $93)"//$93 ;// 'Unregister word' key
keyname(VK_OEM_FJ_TOUROKU) = "(OEM_FJ_TOUROKU名義 $94)"//$94 ;// 'Register word' key
keyname(VK_OEM_FJ_LOYA) = "(OEM_FJ_LOYA名義 $95)"// $95 ;// 'Left OYAYUBI' key
keyname(VK_OEM_FJ_ROYA) = "(OEM_FJ_ROYA名義 $96)"// $96 ;// 'Right OYAYUBI' key
keyname(VK_LSHIFT) = "左のShift"// $A0
keyname(VK_RSHIFT) = "右のShift"// $A1
keyname(VK_LCONTROL) = "左のCtrl"// $A2
keyname(VK_RCONTROL) = "右のCtrl"// $A3
keyname(VK_LMENU) = "左のAlt"// $A4
keyname(VK_RMENU) = "右のAlt"// $A5
keyname(VK_OEM_1) = "(OEM_1名義 $BA)"// $BA ;// ';:' for US
keyname(VK_OEM_PLUS) = "(OEM_PLUS名義 $BB)"// $BB ;// '+' any country
keyname(VK_OEM_COMMA) = "(OEM_COMMA名義 $BC)"//$BC ;// ',' any country
keyname(VK_OEM_MINUS) = "(OEM_MINUS名義 $BD)"//$BD ;// '-' any country
keyname(VK_OEM_PERIOD) = "(OEM_PERIOD名義 $BE)"// $BE ;// '.' any country
keyname(VK_OEM_2) = "(OEM_2名義 $BF)"// $BF ;// '/?' for US
keyname(VK_OEM_3) = "(OEM_3名義 $C0)"// $C0 ;// '`~' for US
word = "(OEM_@名義 $@@)"
repeat 5 //OEM_の4番目以降
keyname($DB+cnt) = strf("OEM_%01d名義 $%02X)",cnt+4,$DB+cnt)
loop
keyname(VK_OEM_102) = "(OEM_102名義 $E2)"//$E2 ;// "<>" or "\|" on RT 102-key kbd.
//バッファ1の描画
buffer 1, 640, 500, 0
repeat 32
line -1, cnt*15, 640, cnt*15
line -1, cnt*15+14, 640, cnt*15+14
loop
repeat 8
line cnt*80, -1, cnt*80, 480
line cnt*80+79, -1, cnt*80+79, 480
loop
font msgothic, 12
for x, 0, 8, 1
for y, 0, 32, 1
pos x*80+2, y*15+2
mes strmid(keyname(x*32+y),0,13)
next
next
list = "左クリック", "右クリック", "Enter", "Space"
repeat 4
pos cnt*160, 484
mes list(cnt)+" 回"
loop
//マクロ定義(SAVE_NAMEはstrf関数の%が干渉したのでマクロにできず、残念)
#define SAVE_DIR "入力ログのページ保管庫"
; #define ctype SAVE_NAME(%1) strf("ログの%04dページ目.txt",%1)
//スクリーン0の描画
screen 0, 640, 500, 0
pos 0, 0
color 255, 255, 255
gmode 4, 640, 480, 256
gcopy 1, 0, 0
//ログの保存先フォルダの作成と終了時の処理の定義
dirlist list, SAVE_DIR, 5 //listは飾り。dirlist命令の返り値が目当て
if stat = 0 : mkdir SAVE_DIR
onexit goto *ひゃっはー //実は結構危険な命令。使用時はヘルプ熟読の事
//ログの記録を担当するループ
repeat
time = cnt
e3dgetkeyboardstate keybuf
redraw_flag = 0
repeat 256
change_flag = keybuf(cnt)-prekeybuf(cnt)
//全域のredraw命令は処理が重いので、キー状態の変更時のみする方針で
if change_flag ! 0 {
if change_flag = 1 { //キーを押した場合
color 255, 255, 0
log = "入力"
} else { //change_flag=-1、つまりキーから指を離した場合
color 255, 255, 255
log = "解放"
keycount(cnt)+ //キーの入力とは指を離した瞬間だと考える
}
boxf (cnt/32)*80, (cnt\32)*15, (cnt/32)*80+79, (cnt\32)*15+14
pos (cnt/32)*80, (cnt\32)*15
color 255, 255, 255
gmode 4, 80, 15, 256
gcopy 1, (cnt/32)*80, (cnt\32)*15, 80, 15
notesel note
noteadd strf("[%10d] "+keyname(cnt)+" を"+log,time)
if notemax >= 100 { //ログが100行を超えたらハードに保存
chdir dir+"\\"+SAVE_DIR
notesel note
notesave strf("["+t1+" "+t2+"]ログの%04d枚目.txt",page)
note = "" //ハードに保存したのでnoteを初期化
page+ //page数は1枚足す
}
redraw_flag = 1 //全域の再描画フラグ
}
loop
if redraw_flag { //前述の全域再描画フラグが立っている場合は全域再描画
gmode 0, 640, 20
pos 0, 480
gcopy 1, 0, 480
font msmincho, 16
color
list = VK_LBUTTON, VK_RBUTTON, VK_RETURN, VK_SPACE
repeat 4
pos 60+cnt*160, 482
mes keycount(list(cnt))
loop
redraw 1
redraw 0
}
memcpy prekeybuf, keybuf, 256*4, 0, 0 //古いキー状態の更新
wait 3
loop
//終了時の処理
*ひゃっはー
chdir dir+"\\"+SAVE_DIR
//メモリに駐在しているログをハードに保存
notesel note
notesave strf("["+t1+" "+t2+"]ログの%04d枚目.txt",page)
//ついでに総入力回数もハードに保存
note = ""
notesel note
repeat 256
if keycount(cnt) > 0 : noteadd keyname(cnt)+" "+keycount(cnt)+"回"
loop
notesave "["+t1+" "+t2+"]キーの総入力回数.txt"
end //強制終了。onexit命令使用時の最重要必須命令