mod_TimerRepeat.hsp
common\ mod_TimerRepeat.hsp
//
// mod_uniq.hsp - ver.1.1 by MIZUSHIKI
//
#ifndef uniq_start
#define global uniq_start %tunique %i0
#define global ctype uniq(%1) %tunique %1@%p
#define global ctype uniq2(%1) %tunique %1@%p1
#define global ctype uniq3(%1) %tunique %1@%p2
#define global ctype uniq4(%1) %tunique %1@%p3
#define global ctype uniq5(%1) %tunique %1@%p4
#define global ctype uniq6(%1) %tunique %1@%p5
#define global ctype uniq7(%1) %tunique %1@%p6
#define global ctype uniq8(%1) %tunique %1@%p7
#define global ctype uniq9(%1) %tunique %1@%p8
#define global uniq_end %tunique %o0
#endif
//
// mod_TimerRepeat.hsp - ver.2.5 by MIZUSHIKI
//
#ifndef timer_repeat
#define global timer_repeat(%1=10,%2=-1,%3=0,%4=0) %t__timer if pChk@modTimerRepeat("%1"){dup _arA@modTimerRepeat,%1}else{vaA@modTimerRepeat=%1:dup _arA@modTimerRepeat,vaA@modTimerRepeat}:_setTimerLabel@modTimerRepeat %2,%3,*%i,%4 :goto *%i :*%p1 :uniq_start:if(_TimerRepeat_deinit_@modTimerRepeat<=1){uniq(_timer_cnt_@modTimerRepeat)=_TimerRepeat_cnt_@modTimerRepeat}:if _dupdim_@modTimerRepeat>-2{ if _dupdim_@modTimerRepeat>=0{dim uniq(timer_intervals@modTimerRepeat),_dupdim_@modTimerRepeat}: dup _ari@modTimerRepeat,uniq(timer_intervals@modTimerRepeat):return} :if(_TimerRepeat_deinit_@modTimerRepeat<=1) {
#define global timer_init %t__timer *%o :if(_TimerRepeat_init_@modTimerRepeat>=1) { uniq(_timer_cnt_@modTimerRepeat)=_getTimerFCnt_Label@modTimerRepeat(*%p0) :
#define global _init_end %t__timer _TimerRepeat_init_@modTimerRepeat=-1}:if(_TimerRepeat_init_@modTimerRepeat==-1) {goto *%i}
#define global timer_deinit } : if(_TimerRepeat_deinit_@modTimerRepeat>=1) {
#define global _deinit_end } : if(_TimerRepeat_deinit_@modTimerRepeat<=1) {
#define global timer_loop %t__timer } :uniq_end :return :*%o :_get_index@modTimerRepeat *%o
/*
- 基本の型 ---------------------------------------------------------------------
[timer_repeat] -> SetLabel(*A) : goto *B : *A : if(_deinit_<=1){
(定期的処理)
[timer_loop] -> } : return : *B
・timer_repeatスクリプト実行時はSetLabelでrepeat間隔とかを保存するだけ。最初はgoto *Bでtimer_loopまで飛び内部の処理はされない。
・時間になったら *A が呼ばれる (_deinit_==0)
- initあり ---------------------------------------------------------------------
[timer_repeat] -> SetLabel(*A) : goto *B : *A : if(_deinit_<=1){
[timer_init:] -> *B : if(_init_>=1) {
(初期化処理)
[_init_end] -> _init_=-1 } : if(_init_==-1){ goto *C }
(定期的処理)
[timer_loop] -> } : return : *C
・SetLabelしたとき_init_=1になり、その後のgoto *Bはtimer_init:前まで飛び(初期化処理)が実行される。その処理の後goto *Cされる。(_deinit_==0)
・時間になったら *A が呼ばれる (_deinit_==0, _init_==0)
- deinitあり -------------------------------------------------------------------
[timer_repeat] -> SetLabel(*A) : goto *B : *A : if(_deinit_<=1){
(定期的処理)
[timer_deinit] -> } : if(_deinit_>=1) {
(後始末処理)
[timer_loop] -> } : return : *B
・時間になったら *A が呼ばれる (_deinit_==0, _init_==0)
・timer_repeatを回数指定した場合、最後の回は_deinit_=1になり(定期的処理)(後始末処理)両方実行される。
・timer_killされたとき_deinit_=2で *A が呼ばれ、(後始末処理)だけが実行される。
*/
#define global timer_break %t__timer _killTimerLabel_Label@modTimerRepeat *%p1 :return
#define global timer_continue(%1=-1,%2=0) %t__timer _continueTimerCount_Label@modTimerRepeat *%p1,%1 :_continueTimerTimesReset_Label@modTimerRepeat *%p1,%2 :return
#define global timer_cnt uniq(_timer_cnt_@modTimerRepeat)
#define global timer_setTimerSpeed(%1=__timer__id__@modTimerRepeat,%2=10) __timer__temp__@modTimerRepeat=%1 : if pChk@modTimerRepeat("%2"){dup _arA@modTimerRepeat,%2}else{vaA@modTimerRepeat=%2:dup _arA@modTimerRepeat,vaA@modTimerRepeat}: _setTimerSpeed@modTimerRepeat __timer__temp__@modTimerRepeat
#define global timer_kill(%1=__timer__id__@modTimerRepeat) __timer__temp__@modTimerRepeat=%1 : _killTimerLabel@modTimerRepeat __timer__temp__@modTimerRepeat
#define global ctype timer_getTimerTime(%1=__timer__id__@modTimerRepeat) _get_timertime@modTimerRepeat(%1)
#define global ctype timer_getTime timeGetTime@modTimerRepeat()
#define global timer_intervals uniq(timer_intervals@modTimerRepeat)
#module modTimerRepeat
#deffunc _init_@modTimerRepeat
//デバッガに怒られないよう一応初期化
labels=0
ing=0
usingengine=0
mae_nft=0
st=0
_ara=0
_arb=0
_dupdim_=-2
_ari=0
return
#defcfunc timeGetTime@modTimerRepeat
#ifndef _HSP3DISH
#uselib "winmm.dll"
#cfunc _timeGetTime@modTimerRepeat "timeGetTime"
return _timeGetTime@modTimerRepeat()
#else
getreq time24, SYSREQ_TIMER
return time24
#endif
#deffunc _setTimerLabel@modTimerRepeat int num, int fcnt, label _label, int type
;_arA(第5パラメータ) ; 繰り返し間隔のミリ秒(アニメーションの時は各フレーム間の時間間隔の配列になる)
label = _label
if vartype(labels) != 1 {
// 初期化処理
ldim labels,1
}
//既に存在してing中だったら、typeに合わせて無効か終了か終了+再リピートか
index = 0
repeat length.labels-1, 1
if lpeek(labels.cnt,0) == lpeek(label,0) :index=cnt :break
loop
if index!=0 {
if ing(index) == 1 {
switch type
case 1 ://終了のみ
timer_kill label ; timer_deinit内処理を実行
_TimerRepeat_init_=-1 ; timer_repeat内処理すべてすっ飛ばす(timer_init:があっても)
return
swbreak
case 2 ://終了+再リピート
timer_kill label ; timer_deinit内処理を実行
swbreak
default ://無効
_TimerRepeat_init_=-1 ; timer_repeat内処理すべてすっ飛ばす(timer_init:があっても)
return
swend
}
}else {
index = length.labels
}
nums(index) = num : if nums(index)<0 :nums(index)=-1
fcnts(index) = fcnt
labels(index) = label
cnts(index) = fcnt
;intervals(index) = time ; 各timer_repeat内のuniq(timer_intervals@modTimerRepeat)に書くようにした
SetINTERVAL@modTimerRepeat index, _arA ; uniq(timer_intervals@modTimerRepeat)に_arAを書き込みに行く
times(index) = timeGetTime()
times_lastFire(index) = times(index)
ing(index) = 1 : if num == 0 : ing(index) = 0
engine(index) = usingEngine
_TimerRepeat_init_=1 ; timer_init内を実行(timer_init:指示があれば)
return
//
// _TimerRepeat_init_ ; timer_repeat実行時に影響
// 0 : 通常時
// 1 : timer_repeatされて登録されたとき1になりtimer_init内が実行される。init内の最後で-1になる。
// -1 : timer_repeatされたとき既に処理中だと-1になる。-1だとtimer_init内処理がすっ飛ばされた後、さらにtimer_loopまですっ飛ばされて timer_repeaat〜timer_loop までの処理が実行されないで終わる。(timer_init:があっても)
//
// _TimerRepeat_deinit_ ; timer_fire実行時に影響
// 0 : 通常時
// 1 : timer_fireが発動して最後の回数のとき1になりtimer_deinit内"も"実行される。(timer_repeatで回数制限を指定している場合)
// 2 : timer_killでlabelが実行されて、timer_deinit: の中だけ実行されて欲しいとき。
//
#defcfunc GetINTERVAL@modTimerRepeat int i
_dupdim_=-1
gosub labels(i)
_dupdim_=-2
return _ari(cnts(i)\(length._ari))
#deffunc SetINTERVAL@modTimerRepeat int i, array ar
_dupdim_=length(ar)
gosub labels(i)
_dupdim_=-2
foreach ar
_ari(cnt) = ar(cnt)
loop
return
//
// _dupdim_ = -2 : 通常時
// = -1 : gosub labels(i)でtimer_repeat先に飛んで dup _ari, uniq(timer_intervals) して戻ってくる。つまり飛んだ先の uniq(timer_intervals) を貰いに行く為のフラグ。
// >= 0 : gosub labels(i)でtimer_repeat先に飛んで dim uniq(timer_intervals), _dupdim_ : dup _ari, uniq(timer_intervals)して戻ってくる。つまり飛んだ先で uniq(timer_intervals) を初期化+戻った後に _ari に必要分の配列データを書き込む。
//
#define global timer_fire(%1=1) _timer_fire %1
#deffunc _timer_fire int type
nowTime = -1; = timeGetTime()
foreach ing
if ing(cnt) == 0 :continue
if type != 2 : if engine(cnt) != type :continue
if nowTime==-1 : nowTime = timeGetTime()
if nowTime - times_lastFire(cnt) >= GetINTERVAL@modTimerRepeat(cnt) : __timer__id__ = cnt : times_lastFire(cnt) = nowTime : gosub *__timer__WaitLoop__@modTimerRepeat
loop
return
*__timer__WaitLoop__@modTimerRepeat
_TimerRepeat_deinit_ = 0
if nums(__timer__id__) != -1 {
if cnts(__timer__id__) - fcnts(__timer__id__) >= nums(__timer__id__) - 1 {
if cnts(__timer__id__) - fcnts(__timer__id__) >= nums(__timer__id__) :return //もし最後超えても次が来たとき止める。
_TimerRepeat_deinit_ = 1
}
}
_TimerRepeat_init_ = 0 ; timer_init 内は実行しない
_TimerRepeat_cnt_ = cnts(__timer__id__) : cnts(__timer__id__)++
if _TimerRepeat_deinit_ = 1 : ing(__timer__id__) = 0 ; この処理を最後にこのtimer_repeatは終了
gosub labels(__timer__id__)
return
#deffunc _killTimerLabel_Label@modTimerRepeat label _label
label = _label
_killTimerLabel@modTimerRepeat label
return
#deffunc _killTimerLabel@modTimerRepeat var v
if vartype(v)==1{
index = 0
repeat length.labels-1, 1
if lpeek(labels.cnt,0) == lpeek(v,0) :index=cnt :break
loop
if index=0 :return
}else {
index = v
if index = 0 :return
}
if length(labels)<=index :return
if ing(index) == 0 :return
__timer__id__ = index
_TimerRepeat_deinit_ = 2
_TimerRepeat_cnt_ = cnts(index)
ing(index) = 0
gosub labels(index)
_TimerRepeat_deinit_ = 0
return
#deffunc _AllKillTimerLabel onexit
foreach ing
ing(cnt) = 0
loop
return
#deffunc timer_setTimerEngine int type
usingEngine = (type == 1)
return
#defcfunc _getNextFireTime@modTimerRepeat int type
if type=1 : return mae_NFT ;
_NFT = 2147483647
foreach ing
if ing(cnt) == 0 :continue
if _NFT > times_lastFire(cnt)+GetINTERVAL@modTimerRepeat(cnt) : _NFT = times_lastFire(cnt)+GetINTERVAL@modTimerRepeat(cnt)
loop
if _NFT == 2147483647 : return -1
mae_NFT = _NFT - timeGetTime()
if mae_NFT<0 : mae_NFT=0
return mae_NFT
#deffunc _setTimerSpeed@modTimerRepeat var v;, int time
if vartype(v)==1{
index = 0
repeat length.labels-1, 1
if lpeek(labels.cnt,0) == lpeek(v,0) :index=cnt :break
loop
if index=0 :return
}else {
index = v
if index = 0 :return
}
if length(labels)<=index :return
SetINTERVAL@modTimerRepeat index, _arA
;intervals(index) = time
return
#deffunc _continueTimerCount_Label@modTimerRepeat label _label, int count
_continueTimerCount@modTimerRepeat _getc_index@modTimerRepeat(_label), count
return
#deffunc _continueTimerCount@modTimerRepeat int i, int count
if count != -1 {
cnts(i) = count
}
return
#deffunc _continueTimerTimesReset_Label@modTimerRepeat label _label, int bool
_continueTimerTimesReset@modTimerRepeat _getc_index@modTimerRepeat(_label), bool
return
#deffunc _continueTimerTimesReset@modTimerRepeat int i, int bool
if bool=0 :return
times(i) = timeGetTime()
return
#deffunc _get_index@modTimerRepeat label _label
label = _label
index = 0
repeat length.labels-1, 1
if lpeek(labels.cnt,0) == lpeek(label,0) :index=cnt :break
loop
if index=0 :return
mref st,64
st = index
return
#defcfunc _getTimerFCnt_Label@modTimerRepeat label _label
return fcnts( _getc_index@modTimerRepeat(_label) )
#defcfunc _getc_index@modTimerRepeat label _label
label = _label
index = 0
repeat length.labels-1, 1
if lpeek(labels.cnt,0) == lpeek(label,0) :index=cnt :break
loop
if index=0 :return 0
return index
#defcfunc _get_timertime@modTimerRepeat int _index
if _index <= 0 :return -1
if length(labels)<=_index :return -1
if ing(_index) = 0 :return -1
return (timeGetTime@modTimerRepeat() - times@modTimerRepeat(_index))
#define global timer_ease(%1,%2,%3,%4,%5) if pChk@modTimerRepeat("%2"){dup _arA@modTimerRepeat,%2}else{vaA@modTimerRepeat=%2:dup _arA@modTimerRepeat,vaA@modTimerRepeat}:if pChk@modTimerRepeat("%3"){dup _arB@modTimerRepeat,%3}else{vaB@modTimerRepeat=%3:dup _arB@modTimerRepeat,vaB@modTimerRepeat} : _TimerRepeat_easing@modTimerRepeat %1,timeGetTime@modTimerRepeat(),times@modTimerRepeat(__timer__id__@modTimerRepeat),%4,%5
#define global geteaseT(%1,%2,%3,%4,%5,%6,%7) if pChk@modTimerRepeat("%3"){dup _arA@modTimerRepeat,%3}else{vaA@modTimerRepeat=%3:dup _arA@modTimerRepeat,vaA@modTimerRepeat}:if pChk@modTimerRepeat("%5"){dup _arB@modTimerRepeat,%5}else{vaB@modTimerRepeat=%5:dup _arB@modTimerRepeat,vaB@modTimerRepeat} : _TimerRepeat_easing@modTimerRepeat %1,%2,%4,%6,%7
#define global geteaseWithTime(%1,%2,%3,%4,%5,%6,%7) geteaseT %1,%2,%3,%4,%5,%6,%7
//関数に渡されたパラメータが変数か確認する
#defcfunc pChk@modTimerRepeat str _chkStr
chkStr = _chkStr
chkStr = strtrim(chkStr,3)
// uniq()だけ殻割する特殊仕様
if lpeek(chkStr,0)==1902734965 { ;uniq
if wpeek(chkStr,3)==10353 { ;q(
if peek(chkStr,strlen(chkStr)-1)=')' {;uniq(〜)
chkStr = strmid(chkStr,5,strlen(chkStr)-6)
chkStr = strtrim(chkStr,3)
}
}
}
flg = 0
repeat strlen(chkStr)
if 'a'<=peek(chkStr,cnt)&&peek(chkStr,cnt)<='z' :flg=1 :continue
if 'A'<=peek(chkStr,cnt)&&peek(chkStr,cnt)<='Z' :flg=1 :continue
if peek(chkStr,cnt)=='_' :flg=1 :continue
if peek(chkStr,cnt)=='@' :flg=1 :continue
if flg=0 : break
if '0'<=peek(chkStr,cnt)&&peek(chkStr,cnt)<='9' :continue
flg = 0 : break
loop
return flg
#deffunc _TimerRepeat_easing@modTimerRepeat array arZ, int _miriSecZ, int _miriSecA, int type, int _miriSec
miriSec = _miriSec :if miriSec <= 0 :miriSec = 1
miriSecA = _miriSecA ;:if miriSecA < 0 :miriSecA = 0 //マイナス値もありえる。(24.855日以上たつとなる。差分をとっているだけなので問題ない)
miriSecZ = _miriSecZ :if miriSecZ < miriSecA :miriSecZ = miriSecA
if length(_arA) != length(_arB) : return -1.0
dimtype arZ, vartype(_arB), length(_arB)
repeat length(_arB)
setease _arA(cnt), _arB(cnt), type
if vartype(_arB) == 3 {
arZ(cnt) = geteasef( miriSecZ-miriSecA, miriSec )
}else {
arZ(cnt) = getease( miriSecZ-miriSecA, miriSec )
}
loop
per = 1.0*( miriSecZ-miriSecA ) / miriSec
if ( per > 1.0 ) || ( per < 0.0 ) : per = 1.0
return per
//
// mod_waiton.hsp(+タイマーループ割り込み) - ver.1.2.2 by MIZUSHIKI
//
#define global timer_waiton(%1=100) :\
_waitTime_@modTimerRepeat = timeGetTime@modTimerRepeat() :\
_whilecount_@modTimerRepeat=0:\
while 1 :\
_nokoriTime_@modTimerRepeat=%1-(timeGetTime@modTimerRepeat() - _waitTime_@modTimerRepeat)/10 :\
_nokoriTime_2@modTimerRepeat = _nokoriTime_@modTimerRepeat :\
if(_getNextFireTime@modTimerRepeat(0)!=-1 && _nokoriTime_2@modTimerRepeat>_getNextFireTime@modTimerRepeat(1)/10){ _nokoriTime_2@modTimerRepeat=_getNextFireTime@modTimerRepeat(1)/10 } :\
if(_whilecount_@modTimerRepeat==0||_nokoriTime_2@modTimerRepeat>1){if(_nokoriTime_2@modTimerRepeat<=0){_nokoriTime_2@modTimerRepeat=1}:wait@hsp _nokoriTime_2@modTimerRepeat} :\
timer_fire 0 :\
if(_nokoriTime_@modTimerRepeat<=0){ _break } :\
_whilecount_@modTimerRepeat++:\
wend :\
_awaitTime_@modTimerRepeat=timeGetTime@modTimerRepeat()
#define global timer_awaiton(%1=0) :\
if(_awaitTime_@modTimerRepeat=0){ _awaitTime_@modTimerRepeat = timeGetTime@modTimerRepeat() } :\
_whilecount_@modTimerRepeat=0:\
while 1 :\
_nokoriTime_@modTimerRepeat=%1-(timeGetTime@modTimerRepeat() - _awaitTime_@modTimerRepeat) :\
_nokoriTime_2@modTimerRepeat = _nokoriTime_@modTimerRepeat :\
if(_getNextFireTime@modTimerRepeat(0)!=-1 && _nokoriTime_2@modTimerRepeat>_getNextFireTime@modTimerRepeat(1)){ _nokoriTime_2@modTimerRepeat=_getNextFireTime@modTimerRepeat(1) } :\
if(_whilecount_@modTimerRepeat==0||_nokoriTime_2@modTimerRepeat>1){if(_nokoriTime_2@modTimerRepeat<=0){_nokoriTime_2@modTimerRepeat=1}:await@hsp _nokoriTime_2@modTimerRepeat} :\
timer_fire 0 :\
if(_nokoriTime_@modTimerRepeat<=0){ _break } :\
_whilecount_@modTimerRepeat++:\
wend :\
_awaitTime_@modTimerRepeat=timeGetTime@modTimerRepeat()
#define global timer_stop(%1=dummy) :\
_awaitTime_@modTimerRepeat=0 :\
_stop_word_@modTimerRepeat="%1":\
_s_w_nine_@modTimerRepeat=9*(strmid(_stop_word_@modTimerRepeat,-1,4)=="wait"):\
_whilecount_@modTimerRepeat=0:\
while 1 :\
_nokoriTime_2@modTimerRepeat = 214748364 :\
if(_getNextFireTime@modTimerRepeat(0)!=-1){ _nokoriTime_2@modTimerRepeat=_getNextFireTime@modTimerRepeat(1) } :\
if(_whilecount_@modTimerRepeat==0||_nokoriTime_2@modTimerRepeat>(1+_s_w_nine_@modTimerRepeat)){if(_s_w_nine_@modTimerRepeat==0){if(_nokoriTime_2@modTimerRepeat<=0){_nokoriTime_2@modTimerRepeat=1}:await@hsp _nokoriTime_2@modTimerRepeat}else{if(_nokoriTime_2@modTimerRepeat<=9){_nokoriTime_2@modTimerRepeat=10}:wait@hsp _nokoriTime_2@modTimerRepeat/10}} :\
timer_fire 0 :\
wend
#undef wait
#define global wait timer_waiton
#undef await
#define global await timer_awaiton
#undef stop
#define global stop timer_stop
#global
_init_@modTimerRepeat
#endif