HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2011
0318
ひらまる割り込みイベントを呼ぶと、ウェイトを無視してしまう。4解決


ひらまる

リンク

2011/3/18(Fri) 16:20:18|NO.37673

以下のプログラムを実行すると、何かのキーを押し続けている間、FPSが上昇します。

#include "d3m.hsp" onkey gosub *KeyEvent repeat color 255,255,255 : boxf color 0,0,0 : pos 0,0 : mes d3getfps() await 1 loop *KeyEvent return
原因を考えたところ、onkeyなどの割り込み命令は、awaitなどが呼ばれたときに判定をすると書いてあったので、
割り込み命令が呼ばれてしまうと、ウェイトを無視して先に進んでしまうのではないかと考えました。
なので、以下のように書いてみたところ、キーを押した際にウェイトを無視して進むことが確認できました。

onkey gosub *KeyEvent wait 10000 mes "待った?" stop *KeyEvent return
await 1のような小さな値であれば、以下のように、
キーイベント内に同じ分だけウェイトを入れることでFPSを安定させることができますが、
ウェイトが大きいと上記のようになり、そうもいきません。

#include "d3m.hsp" onkey gosub *KeyEvent repeat color 255,255,255 : boxf color 0,0,0 : pos 0,0 : mes d3getfps() await 16 loop *KeyEvent await 1 return
これは、バグなのでしょうか、仕様なのでしょうか。
それによって、割り込みイベント内にウェイト処理を入れるかどうかを検討するので、
どなたかご教授お願いします。



この記事に返信する


ken

リンク

2011/3/18(Fri) 17:44:19|NO.37675

waitやawaitで割り込みを受け付けると割り込み後の戻り先はwaitやawaitの次のコマンドに
なります。したがってwait値は無視されることになります。これは仕様といえます。



ひらまる

リンク

2011/3/18(Fri) 18:16:41|NO.37677

回答ありがとうございます。仕様ということで納得しました。
しかし場合によっては厄介な仕様なので、
割り込み可能なウェイト命令と、割り込み不可能なウェイト命令があると便利ですね
ん?

#deffunc EXwait int In_Wait await 0 onclick 0 oncmd 0 onerror 0 onexit 0 onkey 0 await In_Wait onclick 1 oncmd 1 onerror 1 onexit 1 onkey 1 return
で、できるのではないでしょうか。
問題は、全ての割り込み命令を強制的にONにしてしまうので、
割り込み設定をしていないとエラーになる可能性があるというところですね。
割り込みが設定されているかどうかを取得できれば良いのですが、
全ての割り込みラベルを最初に設定しておくか、
割り込まない処理のon〜命令は書かなければ良いので、
自分はこの方法で回避したいと思います。

kenさん回答ありがとうございました!



test

リンク

2011/3/18(Fri) 18:51:46|NO.37678

#module
#uselib "winmm.dll" //timeGetTimeを使用するのに必要 #cfunc timeGetTime "timeGetTime" #deffunc EXawait int time,local end_time if EXawait_time=0{ EXawait_time=timeGetTime() } end_time= EXawait_time+time //ウェイト終了予定時刻 EXawait_time=timeGetTime() //前回awaitした時間を取っておく repeat if timeGetTime()>=end_time:break //終了予定時間を過ぎたら抜ける await 1 loop return #global onkey gosub *keyEvent mes "ウェイト開始" EXawait 5000 ;5秒 mes "ウェイト終了" stop *keyEvent mes "キーが押されました" return
このような方法もあります。timeGetTime()は、Windowsが起動してから今までの時間を取得する関数です。
これは、ウェイト中はずっとawait 1しながらループし続けていて、一定時間たったらループを抜けるという方法です。
ウェイト中もループを回すので、多少ですが負荷が高いかもしれません。



ひらまる

リンク

2011/3/18(Fri) 19:38:20|NO.37679

>Testさん
そうですね timeGetTimeを使った方がウェイト時間も安定しますね。
また、

repeat if timeGetTime()>=end_time:break //ここで様々な処理 await 0 loop
とすることで、負荷は一気に上がりますが、ウェイト時間を有効に使えますね。
アドバイスありがとうございます。



ONION software Copyright 1997-2023(c) All rights reserved.