mod_layerbutton.hsp

common\ mod_layerbutton.hsp

/* /////////////////////////////////////////////////////////////////////////////
mod_layerbutton モジュール
--------------------------------------------------------------------------------
%dll ; モジュール名 
mod_layerbutton
%ver ; バージョン 
1.1
%date ; 更新日 
2025/9/24
%author ; 著作者 
MIZUSHIKI
%note
layerobj命令を利用して、ちょっとリッチなアニメーション付きボタンを比較的簡単に作成することができます。
*/ /////////////////////////////////////////////////////////////////////////////
#ifndef __mod_layerbutton__  // 二重定義を防止
#define __mod_layerbutton__
//------------------------------------------------------------------------------
// mod_layerbutton モジュール本体
//------------------------------------------------------------------------------
#module modlaybtn
//--------------------------------------
// ダミーラベル
//--------------------------------------
*dummy : return

//--------------------------------------
// グローバル定数
//--------------------------------------
// layerobj内で簡単にオブジェクトの座標やサイズを取得する定数
#define global objlayer_info_option 15
#define global objlayer_axis_x (objinfo(wparam,objlayer_info_axis)<<16>>16)
#define global objlayer_axis_y (objinfo(wparam,objlayer_info_axis)>>16)
#define global objlayer_size_x (objinfo(wparam,objlayer_info_size)<<16>>16)
#define global objlayer_size_y (objinfo(wparam,objlayer_info_size)>>16)
#define global objlayer_axis_x2 ((objinfo(wparam,objlayer_info_axis)<<16>>16)+(objinfo(wparam,objlayer_info_size)<<16>>16))
#define global objlayer_axis_y2 ((objinfo(wparam,objlayer_info_axis)>>16)+(objinfo(wparam,objlayer_info_size)>>16))
#define global objlayer_option objinfo(wparam,objlayer_info_option)
; 一応サブルーチン外でも使えるようにしておく(隠し要素?)
#define global ctype objinfo_axis_x(%1) (objinfo(%1,objlayer_info_axis)<<16>>16)
#define global ctype objinfo_axis_y(%1) (objinfo(%1,objlayer_info_axis)>>16)
#define global ctype objinfo_size_x(%1) (objinfo(%1,objlayer_info_size)<<16>>16)
#define global ctype objinfo_size_y(%1) (objinfo(%1,objlayer_info_size)>>16)
#define global ctype objinfo_axis_x2(%1) ((objinfo(%1,objlayer_info_axis)<<16>>16)+(objinfo(%1,objlayer_info_size)<<16>>16))
#define global ctype objinfo_axis_y2(%1) ((objinfo(%1,objlayer_info_axis)>>16)+(objinfo(%1,objlayer_info_size)>>16))
#define global ctype objinfo_option(%1) objinfo(%1,objlayer_info_option)

// layerbutton用 global定数
#define global LAYBTN_SELECTED           1
#define global LAYBTN_SHOW_IN            2
#define global LAYBTN_FOCUS_IN           4
#define global LAYBTN_FOCUS_OUT          8
#define global LAYBTN_PRESS_IN           16
#define global LAYBTN_PRESS_IN_SELECTED  17  ; option_keepVisible==1のときのみ使用
#define global LAYBTN_PRESS_OUT          32
#define global LAYBTN_SHOW_OUT           64
#define global LAYBTN_SHOW_OUT_SELECTED  65
#define global LAYBTN_COMPLETE           128
#define global LAYBTN_COMPLETE_SELECTED  129
#define global LAYBTN_GROUP_DELETED      256

// layerbutton用 global変数
#define global LAYERBTN_KEY_REPEAT_FRAME LAYERBTN_KEY_REPEAT_FRAME@modlaybtn
; LAYERBTN_KEY_REPEAT_FRAME = 16  ; デフォルト値 16

//--------------------------------------
// 環境による定数や使用できない命令を定義
//--------------------------------------
#ifdef _HSP3DISH
	#if __hspver__ >= 0x370a
		#undef objlayer_info_axis
		#undef objlayer_info_size
		#define global objlayer_info_axis 19
		#define global objlayer_info_size 20
	#else  ; !__hspver__ >= 0x370a
		#undef objlayer_info_option
		#define global objlayer_info_option 13
	#endif ; /__hspver__ >= 0x370a
	#undef gmode  ; gmode : p4に256を指定できないバグに簡易対処 (HSP3Dishにおいては調べた限り255までで計算しきっているので255制限をしてしまう)
	#define global gmode(%1=0,%2=32,%3=32,%4=0) gmode@hsp %1,%2,%3,limit(%4,0,255)
	#define BMSCR_GMODE 25
	#define BMSCR_GFRATE 36
	#define BMSCR_MEM_OBJ 41
	#define BMSCR_OBJMAX 42
	#define BMSCR_CELSIZE 52
	#define _SIZE_MEMOBJ 25
#else  ; !_HSP3DISH
	#define BMSCR_GMODE 35
	#define BMSCR_GFRATE 65
	#define BMSCR_MEM_OBJ 71
	#define BMSCR_OBJMAX 72
	#define BMSCR_CELSIZE 84
	#define _SIZE_MEMOBJ 18
	// HSP3Dish以外でmtlist,mtinfoを疑似的に使えるようにする(layerbutton内で使いたいため)
	#undef mtlist
	#undef mtinfo
	#deffunc mtlist array mt
		getkey __key, 1 : return __key
	#deffunc mtinfo array mi, int id
		mi = __key, mousex, mousey, -1 : return
#endif  ; /_HSP3DISH
// オブジェクト数を減らした後か先かtermが呼び出されるタイミングが違う(?)
#ifdef _hspemscripten  ; emscripten上では確認できたので確定する
	#define TERMTRAP 1
#else  ; !_hspemscripten
	#define TERMTRAP 0
#endif ; /_hspemscripten

//--------------------------------------
// layerbutton用に命令を再定義
//--------------------------------------
// objsel上書き : layerbutton用のfocusフラグを操作したいため
#undef objsel
#define global objsel(%1=0) :\
	if (%1)==-2{ :\
		_layobjIndex@modlaybtn = getLayobjverIndex@modlaybtn(ginfo_sel) :\
		if _layobjIndex@modlaybtn != -1 { :\
			dupptr bm@modlaybtn, objinfo_bmscr(0), (BMSCR_OBJMAX@modlaybtn+1)*4 :\
			repeat bm@modlaybtn(BMSCR_OBJMAX@modlaybtn) :\
				if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue } :\
				if isLaybtnObj_@modlaybtn(_layobjIndex@modlaybtn,cnt) == 0 { continue } :\
				Clear_flagBits_@modlaybtn _layobjIndex@modlaybtn,cnt, FLAGBT_FOCUS@modlaybtn :\
			loop :\
		} :\
	}else:if (%1)>=0{ :\
		if ((objinfo((%1), 0)>>16)==3) && ((objinfo((%1), 0) & $FFFF) & $8000)!=0 { :\
			_layobjIndex@modlaybtn = getLayobjverIndex@modlaybtn(ginfo_sel) :\
			if _layobjIndex@modlaybtn != -1 { :\
				dupptr bm@modlaybtn, objinfo_bmscr(%1), (BMSCR_OBJMAX@modlaybtn+1)*4 :\
				repeat bm@modlaybtn(BMSCR_OBJMAX@modlaybtn) :\
					if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue } :\
					if isLaybtnObj_@modlaybtn(_layobjIndex@modlaybtn,cnt) == 0 { continue } :\
					if groupId_@modlaybtn(_layobjIndex@modlaybtn,cnt) == groupId_@modlaybtn(_layobjIndex@modlaybtn,(%1)) && cnt == (%1) { :\
						Add_flagBits_@modlaybtn _layobjIndex@modlaybtn,cnt, FLAGBT_FOCUS@modlaybtn :\
					}else { :\
						Clear_flagBits_@modlaybtn _layobjIndex@modlaybtn,cnt, FLAGBT_FOCUS@modlaybtn :\
					} :\
				loop :\
			} :\
		} :\
	} :\
	objsel@hsp %1

// redraw上書き : layerbuttonのlayerobj割り込み処理を自前で行うため[redraw前にすべて描画させる]
#undef redraw
#define global redraw(%1=1,%2=0,%3=0,%4=0,%5=0) layerbutton_redraw@modlaybtn %1:redraw@hsp %1,%2,%3,%4,%5
#ifdef redraw@fix_mtinfo_js
	// ezlocal-dish-js対策 : HSP3.7β10正式版より前のバージョンではmtinfo周りのバグ修正でredrawを上書きしているため
	#undef redraw
	#define global redraw(%1=1,%2=0,%3=0,%4=0,%5=0) layerbutton_redraw@modlaybtn %1:redraw@fix_mtinfo_js %1,%2,%3,%4,%5
#endif

//--------------------------------------
// モジュール内定数
//--------------------------------------
#define FLAGBT_SHOWING 1
#define FLAGBT_FOCUS 2
#define FLAGBT_PUSHING 4
#define FLAGBT_PUSHING_IN 8
#define FLAGBT_SELECTED 16
#define FLAGBT_SHOWOUT 32
#define FLAGBT_SHOWOUTED 64
#define FLAGBT_LAST_RUN 128
#define FLAGBT_CONDITION_TERMED 256
#define FLAGBT_CONDITION_DISABLE 512
#define FLAGBT_CONDITION_PREV_SELECTED 1024
#define FLAGBT_OPTION_MOUSE_DISABLED 2048
#define FLAGBT_OPTION_MOUSE_SELECT_ON_PRESS 4096
#define FLAGBT_OPTION_KEY_DISABLE 8192
#define FLAGBT_OPTION_KEY_NO_FOCUS_START 16384
#define FLAGBT_OPTION_KEY_NO_WASD 32768
#define FLAGBT_OPTION_KEY_NO_ULDR 65536
#define FLAGBT_OPTION_KEY_NO_SPACE 131072
#define FLAGBT_OPTION_KEY_NO_ENTER 262144
#define FLAGBT_OPTION_KEEP_VISIBLE 524288
#define FLAGBT_OPTION_KEEP_PRESS_ANIME 1048576
#define FLAGBT_OPTION_KEEP_RETURN_SHOW 2097152
#define FLAGBT_OPTION_FOCUS_PRESS_STOP 4194304
#define FLAGBT_OPTION_FOCUSOUT_IMMEDIATELY 8388608
#define FLAGBT_OPTION_MOUSE_DRAG_IN_PRESS 16777216
#define FLAGBT_OPTION_MOUSE_DRAG_IN_PRESS_GROUP 33554432
#define FLAGBT_OPTION_MOUSE_DRAG_OUT_PRESS_KEEP 67108864
#define FLAGBT_OPTION_KEY_REPEAT 134217728
#define FLAGBT_OPTION_USE_HITTEST 268435456

#define SHOW_IN_FRAME p5@_modlaybtn
#define FOCUS_IN_FRAME p6@_modlaybtn
#define PRESS_IN_FRAME p7@_modlaybtn
#define SHOW_OUT_FRAME p8@_modlaybtn
#define FOCUS_OUT_FRAME p9@_modlaybtn
#define PRESS_OUT_FRAME p10@_modlaybtn

//--------------------------------------
// 未初期化警告避け
//--------------------------------------
p5@_modlaybtn=0
p6@_modlaybtn=0
p7@_modlaybtn=0
p9@_modlaybtn=0
p8@_modlaybtn=0
p10@_modlaybtn=0
flagBits@_modlaybtn=0
layerbtn_stat=0
layerbtn_cnt=0
subeteFlags=0
dorekaFlags=0
SPdorekaFlags=0
yongestId=0
disablekeyInput=0
focusedId=0
SPmtiChanged=0
mtl_num=0
mae_mtis_num=0
mae_mousex=0
mae_mousey=0
mae_mtis1=0
mae_mtis2=0
mae_mtis3=0
hasMultiGroups=0
nw=""
winIDs_count=0:winIDs=0
drawlabel_0=0:lobjlabel_0=0:pbmscr_0=0
drawlabel_1=0:lobjlabel_1=0:pbmscr_1=0
drawlabel_2=0:lobjlabel_2=0:pbmscr_2=0
drawlabel_3=0:lobjlabel_3=0:pbmscr_3=0
drawlabel_4=0:lobjlabel_4=0:pbmscr_4=0
drawlabel_5=0:lobjlabel_5=0:pbmscr_5=0
drawlabel_6=0:lobjlabel_6=0:pbmscr_6=0
drawlabel_7=0:lobjlabel_7=0:pbmscr_7=0
mtl=0:mti=0
lobj_lb=0
celx=0:cely=0
celofsx=0:celofsy=0
celmax=0
gm=0:gf=0
ezpBmscrs=0
cos_ang1=0
sin_ang1=0
cos_ang1_4=0
cos_ang1_5=0
cos_ang1_6=0
cos_ang1_7=0
cos_ang1_8=0
cos_ang1_9=0
cos_ang1_10=0
cos_ang1_11=0
cos_ang1_12=0
GlobalLastKey=0
GlobalFrame=0
GlobalKeyPressFrame=0

//--------------------------------------
// layerbutton用 命令
//--------------------------------------
// layerbuttonの指定グループを非表示処理に遷移させる
#deffunc laybtn_hide int id
	_layobjIndex = getLayobjverIndex@modlaybtn(ginfo_sel)
	if _layobjIndex == -1 : return
	dupptr bm, objinfo_bmscr(0), (BMSCR_OBJMAX+1)*4
	repeat bm(BMSCR_OBJMAX)
		if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
		if isLaybtnObj_@modlaybtn(_layobjIndex,cnt) == 0 { continue }
		if groupId_@modlaybtn(_layobjIndex,cnt) != id { continue }
		if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_CONDITION_DISABLE { continue }  ; disableなら処理しない
		Add_flagBits_@modlaybtn _layobjIndex,cnt, FLAGBT_SHOWOUT  ; showoutビットを立ててSHOW_OUT開始
	loop
	return

// layerbutton指定グループのオブジェクトの個数を取得する
#defcfunc laybtn_length int id
	num = 0
	_layobjIndex = getLayobjverIndex@modlaybtn(ginfo_sel)
	if _layobjIndex == -1 : return num
	dupptr bm, objinfo_bmscr(0), (BMSCR_OBJMAX+1)*4
	repeat bm(BMSCR_OBJMAX)
		if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
		if isLaybtnObj_@modlaybtn(_layobjIndex,cnt) == 0 { continue }
		if groupId_@modlaybtn(_layobjIndex,cnt) != id { continue }
		num++
	loop
	return num

// layerbutton指定グループのオブジェクトに有効・無効の設定をする
#define global laybtn_enable(%1,%2=1) laybtn_enable@modlaybtn %1,%2
#deffunc laybtn_enable@modlaybtn int id, int enable
	if enable < 0 : return laybtn_isEnabled@modlaybtn(id)
	_layobjIndex = getLayobjverIndex@modlaybtn(ginfo_sel)
	if _layobjIndex == -1 : return
	dupptr bm, objinfo_bmscr(0), (BMSCR_OBJMAX+1)*4
	repeat bm(BMSCR_OBJMAX)
		if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
		if isLaybtnObj_@modlaybtn(_layobjIndex,cnt) == 0 { continue }
		if groupId_@modlaybtn(_layobjIndex,cnt) != id { continue }
		if enable == 0 {
			Add_flagBits_@modlaybtn _layobjIndex,cnt, FLAGBT_CONDITION_DISABLE  ; disableビットを立てて無効化
			Clear_flagBits_@modlaybtn _layobjIndex,cnt, (FLAGBT_PUSHING|FLAGBT_SHOWOUT)  ; pushing|showoutビットを下ろす
		}else {
			Clear_flagBits_@modlaybtn _layobjIndex,cnt, FLAGBT_CONDITION_DISABLE  ; disableビットを下ろして有効化
		}
	loop
	return
// (モジュール内使用) layerbutton指定オブジェクトが有効かどうかを調べる
#defcfunc laybtn_isEnabled@modlaybtn int id
	flg = 0
	_layobjIndex = getLayobjverIndex@modlaybtn(ginfo_sel)
	if _layobjIndex == -1 : return flg
	dupptr bm, objinfo_bmscr(0), (BMSCR_OBJMAX+1)*4
	repeat bm(BMSCR_OBJMAX)
		if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
		if isLaybtnObj_@modlaybtn(_layobjIndex,cnt) == 0 { continue }
		if groupId_@modlaybtn(_layobjIndex,cnt) != id { continue }
		if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_CONDITION_DISABLE { continue }  ; disableなら処理しない
		flg = 1 : break
	loop
	return flg
	
// layerbuttonの指定グループの指定オブジェクトをフォーカスさせたり、取得したりする
#define global laybtn_focus(%1=-1,%2=-1) laybtn_focus@modlaybtn %1,%2
#deffunc laybtn_focus@modlaybtn int id, int _p1
	_layobjIndex = getLayobjverIndex@modlaybtn(ginfo_sel)
	if _layobjIndex == -1 : return -1
	dupptr bm, objinfo_bmscr(0), (BMSCR_OBJMAX+1)*4
	if id == -1 {  ; 現在focusを持つグループIDを取得
		ret = -1
		repeat bm(BMSCR_OBJMAX)
			if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
			if isLaybtnObj_@modlaybtn(_layobjIndex,cnt) == 0 { continue }
			if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_CONDITION_DISABLE { continue }  ; disableなら処理しない
			if (flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_FOCUS) == 0 { continue }  ; focusビット確認
			// focus見つけた
			ret = groupId_@modlaybtn(_layobjIndex,cnt) : break
		loop
		return ret
	}
	if _p1 >= 0 {  ; グループ内で指定番目のオブジェクトをfocusする
		cc = 0 : ret = -1
		repeat bm(BMSCR_OBJMAX)
			if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
			if isLaybtnObj_@modlaybtn(_layobjIndex,cnt) == 0 { continue }
			if groupId_@modlaybtn(_layobjIndex,cnt) != id { continue }
			;if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_CONDITION_DISABLE { continue }  ; disableなら処理しない
			;if (flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_FOCUS) == 0 { ret = cc : break }  ; focusビット確認
			if cc == _p1 : ret = cnt : break
			cc++
		loop
		if ret !=-1 : objsel ret
		return ret
	}
	// -1 : グループ内で何番目のオブジェクトがfocusを持つか返す
	// -2~-5 : focusを1つ隣に移動させる (focusedIdが必要なのでまず探す)
	cc = 0 : ret = -1
	repeat bm(BMSCR_OBJMAX)
		if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
		if isLaybtnObj_@modlaybtn(_layobjIndex,cnt) == 0 { continue }
		if groupId_@modlaybtn(_layobjIndex,cnt) != id { continue }
		;if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_CONDITION_DISABLE { continue }  ; disableなら処理しない
		if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_FOCUS { ret = cc : break }  ; focusビット確認
		cc++
	loop
	if _p1 == -1 : return ret  ; グループ内で何番目のオブジェクトがfocusを持つか返す
	// layerbutton_cmddrawから抜粋
	switch _p1
	case -2 : stk = 1 : swbreak
	case -3 : stk = 2 : swbreak
	case -4 : stk = 4 : swbreak
	case -5 : stk = 8 : swbreak
	default : return -1
	swend
					if ret != -1 {
						_px = objinfo_axis_x(ret) + objinfo_size_x(ret) / 2
						_py = objinfo_axis_y(ret) + objinfo_size_y(ret) / 2
					}
					dd2 = 0.0
					tikaiId = -1  ; 一番近い移動先ID
					repeat bm(BMSCR_OBJMAX)
						if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
						if isLaybtnObj_@modlaybtn(_layobjIndex,cnt) == 0 { continue }
						if groupId_@modlaybtn(_layobjIndex,cnt) != id { continue }  // groupId@_modlaybtn
						; if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_OPTION_KEY_DISABLE { continue }  ; option[キー操作無効]ビットが立っているものはスキップ
						_stk = stk
						; if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_OPTION_KEY_NO_WASD { _stk = _stk | $3c000 ^ $3c000 }  ; option[WASDキー操作無効]ビットが立っていたら
						; if flagBits_@modlaybtn(_layobjIndex,cnt) & FLAGBT_OPTION_KEY_NO_ULDR { _stk = _stk | $F ^ $F }  ; option[上下左右キー操作無効]ビットが立っていたら
						if _stk & $4001 {
							xx = (objinfo_axis_x(cnt) + objinfo_size_x(cnt) / 2)
							if ret == -1 {
								dd = double(-xx)
							}else {
								if xx >= (_px - objinfo_size_x(ret)/2) { continue }
								if objinfo_axis_y(cnt)<=_py && _py<objinfo_axis_y2(cnt) {
									yy = _py
								}else {
									yy = (objinfo_axis_y(cnt) + objinfo_size_y(cnt) / 2)
								}
								dd = limitf((1.0-absf(cos.atan( yy-_py , xx-_px ))),0.000001)*(absf(double(xx-_px)*(xx-_px)*(xx-_px))+absf(double(yy-_py)*(yy-_py)*(yy-_py)))
							}
							if dd2 == 0 || dd2 > dd { dd2 = dd : tikaiId = cnt }
							; if GlobalLastKey != (_stk & $4001) : GlobalKeyPressFrame = GlobalFrame
							; GlobalLastKey = _stk & $4001
						}else : if _stk & $8002 {
							yy = (objinfo_axis_y(cnt) + objinfo_size_y(cnt) / 2)
							if ret == -1 {
								dd = double(-yy)
							}else {
								if yy >= (_py - objinfo_size_y(ret)/2) { continue }
								if objinfo_axis_x(cnt)<=_px && _px<objinfo_axis_x2(cnt) {
									xx = _px
								}else {
									xx = (objinfo_axis_x(cnt) + objinfo_size_x(cnt) / 2)
								}
								dd = limitf((1.0-absf(sin.atan( yy-_py , xx-_px ))),0.000001)*(absf(double(xx-_px)*(xx-_px)*(xx-_px))+absf(double(yy-_py)*(yy-_py)*(yy-_py)))
							}
							if dd2 == 0 || dd2 > dd { dd2 = dd : tikaiId = cnt }
							; if GlobalLastKey != (_stk & $8002) : GlobalKeyPressFrame = GlobalFrame
							; GlobalLastKey = _stk & $8002
						}else : if _stk & $10004 {
							xx = (objinfo_axis_x(cnt) + objinfo_size_x(cnt) / 2)
							if ret == -1 {
								dd = double(xx)
							}else {
								if xx <= (_px + objinfo_size_x(ret)/2) { continue }
								if objinfo_axis_y(cnt)<=_py && _py<objinfo_axis_y2(cnt) {
									yy = _py
								}else {
									yy = (objinfo_axis_y(cnt) + objinfo_size_y(cnt) / 2)
								}
								dd = limitf((1.0-absf(cos.atan( yy-_py , xx-_px ))),0.000001)*(absf(double(xx-_px)*(xx-_px)*(xx-_px))+absf(double(yy-_py)*(yy-_py)*(yy-_py)))
							}
							if dd2 == 0 || dd2 > dd { dd2 = dd : tikaiId = cnt }
							; if GlobalLastKey != (_stk & $10004) : GlobalKeyPressFrame = GlobalFrame
							; GlobalLastKey = _stk & $10004
						}else : if _stk & $20008 {
							yy = (objinfo_axis_y(cnt) + objinfo_size_y(cnt) / 2)
							if ret == -1 {
								dd = double(yy)
							}else {
								if yy <= (_py + objinfo_size_y(ret)/2) { continue }
								if objinfo_axis_x(cnt)<=_px && _px<objinfo_axis_x2(cnt) {
									xx = _px
								}else {
									xx = (objinfo_axis_x(cnt) + objinfo_size_x(cnt) / 2)
								}
								dd = limitf((1.0-absf(sin.atan( yy-_py , xx-_px ))),0.000001)*(absf(double(xx-_px)*(xx-_px)*(xx-_px))+absf(double(yy-_py)*(yy-_py)*(yy-_py)))
							}
							if dd2 == 0 || dd2 > dd { dd2 = dd : tikaiId = cnt }
							; if GlobalLastKey != (_stk & $20008) : GlobalKeyPressFrame = GlobalFrame
							; GlobalLastKey = _stk & $20008
						}
					loop
					if tikaiId != -1 {
						if ret != -1 || (flagBits_@modlaybtn(_layobjIndex,tikaiId) & FLAGBT_OPTION_KEY_NO_FOCUS_START) == 0 {  ; option[キーフォーカススタート無効]ビットが立っている場合はフォーカススタートをしない
							objsel tikaiId ;: ret = tikaiId
						}else {
							tikaiId = -1
						}
					}
	return tikaiId

// layerbutton内イージング関数 : layerbuttonアニメーションの補助を行う
#define global ctype laybtn_ease(%1,%2,%3=0,%4=-1) laybtn_ease@modlaybtn((%1),(%2),(%4), layerbtn_stat@modlaybtn,layerbtn_cnt@modlaybtn,(%3))
#defcfunc laybtn_ease@modlaybtn double min, double max, int _type, int state, int count, int tien
	if min != int(min) || max != int(max) {
		// 実数
		if state & LAYBTN_SHOW_IN {
			if (p5@_modlaybtn-tien) <= 0 : return max
			if _type >= 0 : type = _type : else : type = ease_quartic_out
			setease min, max, type
			return geteasef(limit(count-tien,0), limit(p5@_modlaybtn-tien,0))
		}else : if state & LAYBTN_FOCUS_IN {
			if (p6@_modlaybtn-tien) <= 0 : return max
			if _type >= 0 : type = _type : else : type = ease_quartic_out
			setease min, max, type
			return geteasef(limit(count-tien,0), limit(p6@_modlaybtn-tien,0))
		}else : if state & LAYBTN_FOCUS_OUT {
			if (p9@_modlaybtn-tien) <= 0 : return max
			if _type >= 0 : type = _type : else : type = ease_quad_out : if flagBits@_modlaybtn & FLAGBT_OPTION_FOCUSOUT_IMMEDIATELY : type = ease_quartic_in
			setease min, max, type
			return geteasef(limit(count-tien,0), limit(p9@_modlaybtn-tien,0))
		}else : if state & LAYBTN_PRESS_IN {
			if (p7@_modlaybtn-tien) <= 0 : return max
			if _type >= 0 : type = _type : else : type = ease_quartic_out
			setease min, max, type
			return geteasef(limit(count-tien,0), limit(p7@_modlaybtn-tien,0))
		}else : if state & LAYBTN_PRESS_OUT {
			if (p10@_modlaybtn-tien) <= 0 : return max
			if _type >= 0 : type = _type : else : type = ease_quad_out
			setease min, max, type
			return geteasef(limit(count-tien,0), limit(p10@_modlaybtn-tien,0))
		}else : if state & LAYBTN_SHOW_OUT {
			if (p8@_modlaybtn-tien) <= 0 : return max
			if _type >= 0 : type = _type : else : type = ease_quad_out
			setease min, max, type
			return geteasef(limit(count-tien,0), limit(p8@_modlaybtn-tien,0))
		}
	}else {
		// 整数
		if state & LAYBTN_SHOW_IN {
			if (p5@_modlaybtn-tien) <= 0 : return int(max)
			if _type >= 0 : type = _type : else : type = ease_quartic_out
			setease min, max, type
			return getease(limit(count-tien,0), limit(p5@_modlaybtn-tien,0))
		}else : if state & LAYBTN_FOCUS_IN {
			if (p6@_modlaybtn-tien) <= 0 : return int(max)
			if _type >= 0 : type = _type : else : type = ease_quartic_out
			setease min, max, type
			return getease(limit(count-tien,0), limit(p6@_modlaybtn-tien,0))
		}else : if state & LAYBTN_FOCUS_OUT {
			if (p9@_modlaybtn-tien) <= 0 : return int(max)
			if _type >= 0 : type = _type : else : type = ease_quartic_out : if flagBits@_modlaybtn & FLAGBT_OPTION_FOCUSOUT_IMMEDIATELY : type = ease_quartic_in
			setease min, max, type
			return getease(limit(count-tien,0), limit(p9@_modlaybtn-tien,0))
		}else : if state & LAYBTN_PRESS_IN {
			if (p7@_modlaybtn-tien) <= 0 : return int(max)
			if _type >= 0 : type = _type : else : type = ease_quartic_out
			setease min, max, type
			return getease(limit(count-tien,0), limit(p7@_modlaybtn-tien,0))
		}else : if state & LAYBTN_PRESS_OUT {
			if (p10@_modlaybtn-tien) <= 0 : return int(max)
			if _type >= 0 : type = _type : else : type = ease_quad_out
			setease min, max, type
			return getease(limit(count-tien,0), limit(p10@_modlaybtn-tien,0))
		}else : if state & LAYBTN_SHOW_OUT {
			if (p8@_modlaybtn-tien) <= 0 : return int(max)
			if _type >= 0 : type = _type : else : type = ease_quad_out
			setease min, max, type
			return getease(limit(count-tien,0), limit(p8@_modlaybtn-tien,0))
		}
	}
	return -1

// 矩形内mes(一度描画したらサイズが記憶されるMAX64個)  ; 未初期化避けもうちょっと良い方法ないかな
#define global laybtn_mes(%1,%2=0,%3=0,%4=0,%5=0,%6=0,%7=64) %tlaybtn_mes wd@%i=wd@%p:px@%p=px@%p:py@%p=py@%p:tp@%p=tp@%p:fh@%p=fh@%p:sx@%p=sx@%p:sy@%p=sy@%p:dx@%p=dx@%p:dy@%p=dy@%p:cn@%p=cn@%p : laybtn_mes@modlaybtn %1, (%2), objlayer_axis_x+(%5), objlayer_axis_y+(%6), objlayer_axis_x+(%5)+objlayer_size_x, objlayer_axis_y+(%6)+objlayer_size_y, (%3), (%4), wd@%p,px@%p,py@%p,tp@%p,fh@%p,sx@%p,sy@%p,dx@%p,dy@%p,cn@%o, %7
#deffunc laybtn_mes@modlaybtn str wd, int tp, int ax, int ay, int bx, int by, int px, int py, array p_wd, array p_px, array p_py, array p_tp, array p_fh, array p_sx, array p_sy, array p_dx, array p_dy, var p_cn, int num_cache
	if wd == "" : return
	_layobjIndex = getLayobjverIndex@modlaybtn(ginfo_sel)
	if _layobjIndex == -1 : return
#ifndef _HSP3DiSH
	mref bm, 67
    dim lf,15
    dupptr lf, bm.49, 60
	fh = 0 : repeat 15 : fh+=lf(cnt) : loop
#else
	dupptr bm, objinfo_bmscr(0), (159+1)*4
	fh = 0 : repeat 17 : fh+=bm(142+cnt) : loop
	fh += bm(159)<<16
#endif
	cc = -1
	repeat limit(p_cn,0,num_cache)
		c = (((p_cn\num_cache)-cnt+num_cache-1)\num_cache)
		if p_wd(c) == wd : if p_px(c) == px && p_py(c) == py && p_tp(c) == tp && p_fh(c) == fh && p_sx(c) == (bx-ax) && p_sy(c) == (by-ay) : cc = c : break
	loop
	if cc!=-1 {
		pos ax + p_dx(cc), ay + p_dy(cc) : mes wd, tp
	}else{
		sx = bx-ax : sy = by-ay : p_sx(p_cn\num_cache)=sx : p_sy(p_cn\num_cache)=sy
		p_wd(p_cn\num_cache)=wd : sz=0 : pos -ginfo_sx,-ginfo_sy
		notesel p_wd(p_cn\num_cache) : repeat notemax : noteget nw,cnt : mes nw,tp : sz=limit(ginfo(14),sz) : loop
		pos ax+sx*limit(px,0,2)/2-sz*limit(px,0,2)/2,ay+sy*limit(py,0,2)/2-ginfo(15)*notemax*limit(py,0,2)/2
		p_dx(p_cn\num_cache)=ginfo_cx-ax : p_dy(p_cn\num_cache)=ginfo_cy-ay
		noteunsel : mes wd,tp
		p_px(p_cn\num_cache)=px : p_py(p_cn\num_cache)=py : p_tp(p_cn\num_cache)=tp : p_fh(p_cn\num_cache)=fh
		p_cn++
	}
	return
// (モジュール内使用) gsquareを用いた半透明ボックス描画等
#deffunc boxfa@modlaybtn int ax, int ay, int bx, int by
	pdx=ax,bx,bx,ax : pdy=ay,ay,by,by : gsquare -1,pdx,pdy : return
#deffunc trianglefa@modlaybtn int ax, int ay, int bx, int by, int cx, int cy
	pdx=ax,bx,cx,ax : pdy=ay,by,cy,ay : gsquare -1,pdx,pdy : return
#deffunc rboxfa@modlaybtn int x1, int y1, int x2, int y2, int r1, int div
	div_ = div
	if div_ <= 0 {
	    div_ = 4 + r1 * 8 / 25  // 6 + (r1 - 5) * (12 - 6) / (25 - 5)  ; 6〜12 
	    if div_ < 4 : div_ = 4
	    if div_ > 12 : div_ = 12
	}
	boxfa@modlaybtn x1+r1, y1, x2-r1, y2
    boxfa@modlaybtn x1, y1+r1, x1+r1, y2-r1
    boxfa@modlaybtn x2-r1, y1+r1, x2, y2-r1
	getDivCache@modlaybtn div_
	cx_ = x1+r1, x2-r1, x2-r1, x1+r1
	cy_ = y1+r1, y1+r1, y2-r1, y2-r1
    repeat 4
		cnt2=cnt
        repeat div_
            x3 = cx_(cnt2) + cos_ang1(cnt2+cnt*4)*r1
            y3 = cy_(cnt2) + sin_ang1(cnt2+cnt*4)*r1
            x4 = cx_(cnt2) + cos_ang1(cnt2+(cnt+1)*4)*r1
            y4 = cy_(cnt2) + sin_ang1(cnt2+(cnt+1)*4)*r1
            trianglefa@modlaybtn cx_(cnt2),cy_(cnt2), x3,y3, x4,y4
        loop
    loop
	return
#const double DEG2RADER (M_PI/180.0)
#deffunc getDivCache@modlaybtn int _div  // アールのための div_:4~12 の cos,sin で一度計算したものはキャッシュ
	if _div==4 {
		if cos_ang1_4(0)==0 {
			ddim cos_ang1_4, (_div+1)*4
			ddim sin_ang1_4, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_4
		dup sin_ang1, sin_ang1_4

	}else : if _div==5 {
		if cos_ang1_5(0)==0 {
			ddim cos_ang1_5, (_div+1)*4
			ddim sin_ang1_5, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_5
		dup sin_ang1, sin_ang1_5
		
	}else : if _div==6 {
		if cos_ang1_6(0)==0 {
			ddim cos_ang1_6, (_div+1)*4
			ddim sin_ang1_6, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_6
		dup sin_ang1, sin_ang1_6
		
	}else : if _div==7 {
		if cos_ang1_7(0)==0 {
			ddim cos_ang1_7, (_div+1)*4
			ddim sin_ang1_7, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_7
		dup sin_ang1, sin_ang1_7
		
	}else : if _div==8 {
		if cos_ang1_8(0)==0 {
			ddim cos_ang1_8, (_div+1)*4
			ddim sin_ang1_8, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_8
		dup sin_ang1, sin_ang1_8
		
	}else : if _div==9 {
		if cos_ang1_9(0)==0 {
			ddim cos_ang1_9, (_div+1)*4
			ddim sin_ang1_9, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_9
		dup sin_ang1, sin_ang1_9
		
	}else : if _div==10 {
		if cos_ang1_10(0)==0 {
			ddim cos_ang1_10, (_div+1)*4
			ddim sin_ang1_10, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_10
		dup sin_ang1, sin_ang1_10
		
	}else : if _div==11 {
		if cos_ang1_11(0)==0 {
			ddim cos_ang1_11, (_div+1)*4
			ddim sin_ang1_11, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_11
		dup sin_ang1, sin_ang1_11
		
	}else : if _div==12 {
		if cos_ang1_12(0)==0 {
			ddim cos_ang1_12, (_div+1)*4
			ddim sin_ang1_12, (_div+1)*4
		}
		dup cos_ang1, cos_ang1_12
		dup sin_ang1, sin_ang1_12
		
	}else {
		ddim cos_ang1_X, (_div+1)*4
		ddim sin_ang1_X, (_div+1)*4
		dup cos_ang1, cos_ang1_X
		dup sin_ang1, sin_ang1_X
	}
	if cos_ang1(0) == 0.0 {
		repeat 4
					if cnt=0 {ang0_=180.0
			}else : if cnt=1 {ang0_=270.0
			}else : if cnt=2 {ang0_=0.0
			}else : if cnt=3 {ang0_=90.0 }
			cnt2=cnt
			repeat _div+1
				ang1_ = ang0_ + 90.0 * cnt/_div
				cos_ang1(cnt2+cnt*4) = cos(ang1_*DEG2RADER)
				sin_ang1(cnt2+cnt*4) = sin(ang1_*DEG2RADER)
			loop
		loop
	}
	return

#deffunc rboxfa_auto@modlaybtn int x1, int y1, int x2, int y2, int kyoseiR
	if kyoseiR == -1 {
	    ww = abs(x2 - x1)
	    hh = abs(y2 - y1)
		rr = (ww+hh)/40
		if rr > ww/2 : rr = ww/2
		if rr > hh/2 : rr = hh/2
	}else : if kyoseiR > 0 {
		rr = kyoseiR
	}else {
		boxfa@modlaybtn x1,y1,x2,y2
		return
	}
    if rr < 1 : rr = 1
	rboxfa@modlaybtn x1,y1,x2,y2, rr,0
	return
#deffunc colboxfa@modlaybtn int col1, int ax, int ay, int bx, int by
	cols=ginfo_r,ginfo_g,ginfo_b
	color col1>>16&$FF,col1>>8&$FF,col1&$FF
	boxfa@modlaybtn ax,ay,bx,by
	color cols(0),cols(1),cols(2)
	return
#deffunc colrboxfa_auto@modlaybtn int col1, int ax, int ay, int bx, int by, int kyoseiR
	cols=ginfo_r,ginfo_g,ginfo_b
	color col1>>16&$FF,col1>>8&$FF,col1&$FF
	rboxfa_auto@modlaybtn ax,ay,bx,by, kyoseiR
	color cols(0),cols(1),cols(2)
	return

// layerobj内で使用できる個別stick
#define global laybtn_stick(%1,%2=0,%3=1) %tolunq %i0 if(0){key@%p=0:mae_stk@%p=0:mae_frm@%p=0}:if lparam=6&mae_frm@%p!=GlobalFrame@modlaybtn{stk@%p=0:getkey key@%p,37:stk@%p|=key@%p*$1:getkey key@%p,38:stk@%p|=key@%p*$2:getkey key@%p,39:stk@%p|=key@%p*$4:getkey key@%p,40:stk@%p|=key@%p*$8:getkey key@%p,32:stk@%p|=key@%p*$10:getkey key@%p,13:stk@%p|=key@%p*$20:getkey key@%p,17:stk@%p|=key@%p*$40:getkey key@%p,27:stk@%p|=key@%p*$80:getkey key@%p,1:stk@%p|=key@%p*$100:getkey key@%p,2:stk@%p|=key@%p*$200:getkey key@%p,9:stk@%p|=key@%p*$400:getkey key@%p,90:stk@%p|=key@%p*$800:getkey key@%p,88:stk@%p|=key@%p*$1000:getkey key@%p,67:stk@%p|=key@%p*$2000:getkey key@%p,65:stk@%p|=key@%p*$4000:getkey key@%p,87:stk@%p|=key@%p*$8000:getkey key@%p,68:stk@%p|=key@%p*$10000:getkey key@%p,83:stk@%p|=key@%p*$20000:if %3!=0&ginfo_act==-1{stk@%p=0}:%1=stk@%p|mae_stk@%p^mae_stk@%p:%1|=(stk@%p&%2):mae_stk@%p=stk@%p:mae_frm@%p=GlobalFrame@modlaybtn}else{%1=(mae_stk@%p&%2)} %o0

// layerbuttonの位置サイズの変更
#define global laybtn_width(%1,%2=-2147483648,%3=-2147483648,%4=-2147483648,%5=-2147483648) laybtn_width@modlaybtn %1,%2,%3,%4,%5
#deffunc laybtn_width@modlaybtn int id, int ax, int ay, int bx, int by
	_layobjIndex = getLayobjverIndex@modlaybtn(ginfo_sel)
	if _layobjIndex == -1 : return
	dupptr bm, objinfo_bmscr(0), (BMSCR_OBJMAX+1)*4
	if bm(BMSCR_OBJMAX) <= id : return  ; idが範囲外なら何もしない
	if isLaybtnObj_@modlaybtn(_layobjIndex,id) == 0 : return  ; layerbuttonオブジェクトでなければ何もしない
	dupptr mem_obj, bm(BMSCR_MEM_OBJ), _SIZE_MEMOBJ*(id+1)*4
	if bx!=-2147483648 || by!=-2147483648 {
		axis_x = objinfo(id,objlayer_info_axis)<<16>>16
		axis_y = objinfo(id,objlayer_info_axis)>>16
		if bx!=-2147483648 : axis_x = bx
		if by!=-2147483648 : axis_y = by
		mem_obj(_SIZE_MEMOBJ*id+objlayer_info_axis) = (axis_x&$FFFF)|(axis_y<<16)
	}
	if ax!=-2147483648 || ay!=-2147483648 {
		size_x = objinfo(id,objlayer_info_size)<<16>>16
		size_y = objinfo(id,objlayer_info_size)>>16
		if ax!=-2147483648 : size_x = ax : if size_x < 0 : size_x = 0
		if ay!=-2147483648 : size_y = ay : if size_y < 0 : size_y = 0
		mem_obj(_SIZE_MEMOBJ*id+objlayer_info_size) = (size_x&$FFFF)|(size_y<<16)
	}
	return

//--------------------------------------
// 苦肉の策でウィンドウIDを8個まで変数手打ちしてdup
//--------------------------------------
// (モジュール内使用) dupによる変数セットと初期化&拡張
#deffunc SET_LAYOBJVAR@modlaybtn int wp
	index = -1
	repeat winIDs_count
		if winIDs(cnt) == ginfo_sel : index = cnt : break
	loop
	if index == -1 {
		winIDs(winIDs_count) = ginfo_sel
		index = winIDs_count
		maxObjIDs(index) = 0
		winIDs_count++
		if winIDs_count > 8 : return -1  ; 8個まで
	}
	if maxObjIDs(index) >= wp {
		expand = 0  ; 拡張しない
	}else {
		expand = 1  ; 拡張する
		maxObjIDs(index) = wp
	}
	// dupを利用して変数セット
	switch index
	case 0
		if expand {
			state_0(wp)=0
			mx_0(wp)=0
			my_0(wp)=0
			tx_0(wp)=0
			ty_0(wp)=0
			mt_id_0(wp)=0
			count_0(wp)=0
			groupId_0(wp)=0
			flagBits_0(wp)=0
			mtis1_0(wp*10+9)=0
			mtis2_0(wp*10+9)=0
			mtis3_0(wp*10+9)=0
			mtis_num_0(wp)=0
			p5_0(wp)=0
			p6_0(wp)=0
			p7_0(wp)=0
			p8_0(wp)=0
			p9_0(wp)=0
			p10_0(wp)=0
			hitxy_num_0(wp)=0
			hitxy1_0(wp)=0
			hitxy2_0(wp)=0
			hitxy3_0(wp)=0
			hitxy4_0(wp)=0
			hitxy5_0(wp)=0
			hitxy6_0(wp)=0
			hitxy7_0(wp)=0
			hitxy8_0(wp)=0
			if vartype(drawlabel_0)!=1 : ldim drawlabel_0,1
			drawlabel_0(wp)=*dummy
			if vartype(lobjlabel_0)!=1 : ldim lobjlabel_0,1
			lobjlabel_0(wp)=*dummy
		}
		dup pBmscr@_modlaybtn, pBmscr_0
		dup state@_modlaybtn, state_0(wp)
		dup mx@_modlaybtn, mx_0(wp)
		dup my@_modlaybtn, my_0(wp)
		dup tx@_modlaybtn, tx_0(wp)
		dup ty@_modlaybtn, ty_0(wp)
		dup mt_id@_modlaybtn, mt_id_0(wp)
		dup count@_modlaybtn, count_0(wp)
		drawlabel@_modlaybtn = drawlabel_0(wp)
		dup groupId@_modlaybtn, groupId_0(wp)
		dup flagBits@_modlaybtn, flagBits_0(wp)
		dup mtis1@_modlaybtn, mtis1_0(wp*10)
		dup mtis2@_modlaybtn, mtis2_0(wp*10)
		dup mtis3@_modlaybtn, mtis3_0(wp*10)
		dup mtis_num@_modlaybtn, mtis_num_0(wp)
		dup p5@_modlaybtn, p5_0(wp)
		dup p6@_modlaybtn, p6_0(wp)
		dup p7@_modlaybtn, p7_0(wp)
		dup p8@_modlaybtn, p8_0(wp)
		dup p9@_modlaybtn, p9_0(wp)
		dup p10@_modlaybtn, p10_0(wp)
		dup hitxy_num@_modlaybtn, hitxy_num_0(wp)
		if hitxy_num@_modlaybtn != 0 {
			dup hitxy1@_modlaybtn, hitxy1_0(wp)
			dup hitxy2@_modlaybtn, hitxy2_0(wp)
			dup hitxy3@_modlaybtn, hitxy3_0(wp)
			dup hitxy4@_modlaybtn, hitxy4_0(wp)
			dup hitxy5@_modlaybtn, hitxy5_0(wp)
			dup hitxy6@_modlaybtn, hitxy6_0(wp)
			dup hitxy7@_modlaybtn, hitxy7_0(wp)
			dup hitxy8@_modlaybtn, hitxy8_0(wp)
		}
		swbreak
	case 1
		if expand {
			state_1(wp)=0
			mx_1(wp)=0
			my_1(wp)=0
			tx_1(wp)=0
			ty_1(wp)=0
			mt_id_1(wp)=0
			count_1(wp)=0
			groupId_1(wp)=0
			flagBits_1(wp)=0
			mtis1_1(wp*10+9)=0
			mtis2_1(wp*10+9)=0
			mtis3_1(wp*10+9)=0
			mtis_num_1(wp)=0
			p5_1(wp)=0
			p6_1(wp)=0
			p7_1(wp)=0
			p8_1(wp)=0
			p9_1(wp)=0
			p10_1(wp)=0
			hitxy_num_1(wp)=0
			hitxy1_1(wp)=0
			hitxy2_1(wp)=0
			hitxy3_1(wp)=0
			hitxy4_1(wp)=0
			hitxy5_1(wp)=0
			hitxy6_1(wp)=0
			hitxy7_1(wp)=0
			hitxy8_1(wp)=0
			if vartype(drawlabel_1)!=1 : ldim drawlabel_1,1
			drawlabel_1(wp)=*dummy
			if vartype(lobjlabel_1)!=1 : ldim lobjlabel_1,1
			lobjlabel_1(wp)=*dummy
		}
		dup pBmscr@_modlaybtn, pBmscr_1
		dup state@_modlaybtn, state_1(wp)
		dup mx@_modlaybtn, mx_1(wp)
		dup my@_modlaybtn, my_1(wp)
		dup tx@_modlaybtn, tx_1(wp)
		dup ty@_modlaybtn, ty_1(wp)
		dup mt_id@_modlaybtn, mt_id_1(wp)
		dup count@_modlaybtn, count_1(wp)
		drawlabel@_modlaybtn = drawlabel_1(wp)
		dup groupId@_modlaybtn, groupId_1(wp)
		dup flagBits@_modlaybtn, flagBits_1(wp)
		dup mtis1@_modlaybtn, mtis1_1(wp*10)
		dup mtis2@_modlaybtn, mtis2_1(wp*10)
		dup mtis3@_modlaybtn, mtis3_1(wp*10)
		dup mtis_num@_modlaybtn, mtis_num_1(wp)
		dup p5@_modlaybtn, p5_1(wp)
		dup p6@_modlaybtn, p6_1(wp)
		dup p7@_modlaybtn, p7_1(wp)
		dup p8@_modlaybtn, p8_1(wp)
		dup p9@_modlaybtn, p9_1(wp)
		dup p10@_modlaybtn, p10_1(wp)
		dup hitxy_num@_modlaybtn, hitxy_num_1(wp)
		if hitxy_num@_modlaybtn != 0 {
			dup hitxy1@_modlaybtn, hitxy1_1(wp)
			dup hitxy2@_modlaybtn, hitxy2_1(wp)
			dup hitxy3@_modlaybtn, hitxy3_1(wp)
			dup hitxy4@_modlaybtn, hitxy4_1(wp)
			dup hitxy5@_modlaybtn, hitxy5_1(wp)
			dup hitxy6@_modlaybtn, hitxy6_1(wp)
			dup hitxy7@_modlaybtn, hitxy7_1(wp)
			dup hitxy8@_modlaybtn, hitxy8_1(wp)
		}
		swbreak
	case 2
		if expand {
			state_2(wp)=0
			mx_2(wp)=0
			my_2(wp)=0
			tx_2(wp)=0
			ty_2(wp)=0
			mt_id_2(wp)=0
			count_2(wp)=0
			groupId_2(wp)=0
			flagBits_2(wp)=0
			mtis1_2(wp*10+9)=0
			mtis2_2(wp*10+9)=0
			mtis3_2(wp*10+9)=0
			mtis_num_2(wp)=0
			p5_2(wp)=0
			p6_2(wp)=0
			p7_2(wp)=0
			p8_2(wp)=0
			p9_2(wp)=0
			p10_2(wp)=0
			hitxy_num_2(wp)=0
			hitxy1_2(wp)=0
			hitxy2_2(wp)=0
			hitxy3_2(wp)=0
			hitxy4_2(wp)=0
			hitxy5_2(wp)=0
			hitxy6_2(wp)=0
			hitxy7_2(wp)=0
			hitxy8_2(wp)=0
			if vartype(drawlabel_2)!=1 : ldim drawlabel_2,1
			drawlabel_2(wp)=*dummy
			if vartype(lobjlabel_2)!=1 : ldim lobjlabel_2,1
			lobjlabel_2(wp)=*dummy
		}
		dup pBmscr@_modlaybtn, pBmscr_2
		dup state@_modlaybtn, state_2(wp)
		dup mx@_modlaybtn, mx_2(wp)
		dup my@_modlaybtn, my_2(wp)
		dup tx@_modlaybtn, tx_2(wp)
		dup ty@_modlaybtn, ty_2(wp)
		dup mt_id@_modlaybtn, mt_id_2(wp)
		dup count@_modlaybtn, count_2(wp)
		drawlabel@_modlaybtn = drawlabel_2(wp)
		dup groupId@_modlaybtn, groupId_2(wp)
		dup flagBits@_modlaybtn, flagBits_2(wp)
		dup mtis1@_modlaybtn, mtis1_2(wp*10)
		dup mtis2@_modlaybtn, mtis2_2(wp*10)
		dup mtis3@_modlaybtn, mtis3_2(wp*10)
		dup mtis_num@_modlaybtn, mtis_num_2(wp)
		dup p5@_modlaybtn, p5_2(wp)
		dup p6@_modlaybtn, p6_2(wp)
		dup p7@_modlaybtn, p7_2(wp)
		dup p8@_modlaybtn, p8_2(wp)
		dup p9@_modlaybtn, p9_2(wp)
		dup p10@_modlaybtn, p10_2(wp)
		dup hitxy_num@_modlaybtn, hitxy_num_2(wp)
		if hitxy_num@_modlaybtn != 0 {
			dup hitxy1@_modlaybtn, hitxy1_2(wp)
			dup hitxy2@_modlaybtn, hitxy2_2(wp)
			dup hitxy3@_modlaybtn, hitxy3_2(wp)
			dup hitxy4@_modlaybtn, hitxy4_2(wp)
			dup hitxy5@_modlaybtn, hitxy5_2(wp)
			dup hitxy6@_modlaybtn, hitxy6_2(wp)
			dup hitxy7@_modlaybtn, hitxy7_2(wp)
			dup hitxy8@_modlaybtn, hitxy8_2(wp)
		}
		swbreak
	case 3
		if expand {
			state_3(wp)=0
			mx_3(wp)=0
			my_3(wp)=0
			tx_3(wp)=0
			ty_3(wp)=0
			mt_id_3(wp)=0
			count_3(wp)=0
			groupId_3(wp)=0
			flagBits_3(wp)=0
			mtis1_3(wp*10+9)=0
			mtis2_3(wp*10+9)=0
			mtis3_3(wp*10+9)=0
			mtis_num_3(wp)=0
			p5_3(wp)=0
			p6_3(wp)=0
			p7_3(wp)=0
			p8_3(wp)=0
			p9_3(wp)=0
			p10_3(wp)=0
			hitxy_num_3(wp)=0
			hitxy1_3(wp)=0
			hitxy2_3(wp)=0
			hitxy3_3(wp)=0
			hitxy4_3(wp)=0
			hitxy5_3(wp)=0
			hitxy6_3(wp)=0
			hitxy7_3(wp)=0
			hitxy8_3(wp)=0
			if vartype(drawlabel_3)!=1 : ldim drawlabel_3,1
			drawlabel_3(wp)=*dummy
			if vartype(lobjlabel_3)!=1 : ldim lobjlabel_3,1
			lobjlabel_3(wp)=*dummy
		}
		dup pBmscr@_modlaybtn, pBmscr_3
		dup state@_modlaybtn, state_3(wp)
		dup mx@_modlaybtn, mx_3(wp)
		dup my@_modlaybtn, my_3(wp)
		dup tx@_modlaybtn, tx_3(wp)
		dup ty@_modlaybtn, ty_3(wp)
		dup mt_id@_modlaybtn, mt_id_3(wp)
		dup count@_modlaybtn, count_3(wp)
		drawlabel@_modlaybtn = drawlabel_3(wp)
		dup groupId@_modlaybtn, groupId_3(wp)
		dup flagBits@_modlaybtn, flagBits_3(wp)
		dup mtis1@_modlaybtn, mtis1_3(wp*10)
		dup mtis2@_modlaybtn, mtis2_3(wp*10)
		dup mtis3@_modlaybtn, mtis3_3(wp*10)
		dup mtis_num@_modlaybtn, mtis_num_3(wp)
		dup p5@_modlaybtn, p5_3(wp)
		dup p6@_modlaybtn, p6_3(wp)
		dup p7@_modlaybtn, p7_3(wp)
		dup p8@_modlaybtn, p8_3(wp)
		dup p9@_modlaybtn, p9_3(wp)
		dup p10@_modlaybtn, p10_3(wp)
		dup hitxy_num@_modlaybtn, hitxy_num_3(wp)
		if hitxy_num@_modlaybtn != 0 {
			dup hitxy1@_modlaybtn, hitxy1_3(wp)
			dup hitxy2@_modlaybtn, hitxy2_3(wp)
			dup hitxy3@_modlaybtn, hitxy3_3(wp)
			dup hitxy4@_modlaybtn, hitxy4_3(wp)
			dup hitxy5@_modlaybtn, hitxy5_3(wp)
			dup hitxy6@_modlaybtn, hitxy6_3(wp)
			dup hitxy7@_modlaybtn, hitxy7_3(wp)
			dup hitxy8@_modlaybtn, hitxy8_3(wp)
		}
		swbreak
	case 4
		if expand {
			state_4(wp)=0
			mx_4(wp)=0
			my_4(wp)=0
			tx_4(wp)=0
			ty_4(wp)=0
			mt_id_4(wp)=0
			count_4(wp)=0
			groupId_4(wp)=0
			flagBits_4(wp)=0
			mtis1_4(wp*10+9)=0
			mtis2_4(wp*10+9)=0
			mtis3_4(wp*10+9)=0
			mtis_num_4(wp)=0
			p5_4(wp)=0
			p6_4(wp)=0
			p7_4(wp)=0
			p8_4(wp)=0
			p9_4(wp)=0
			p10_4(wp)=0
			hitxy_num_4(wp)=0
			hitxy1_4(wp)=0
			hitxy2_4(wp)=0
			hitxy3_4(wp)=0
			hitxy4_4(wp)=0
			hitxy5_4(wp)=0
			hitxy6_4(wp)=0
			hitxy7_4(wp)=0
			hitxy8_4(wp)=0
			if vartype(drawlabel_4)!=1 : ldim drawlabel_4,1
			drawlabel_4(wp)=*dummy
			if vartype(lobjlabel_4)!=1 : ldim lobjlabel_4,1
			lobjlabel_4(wp)=*dummy
		}
		dup pBmscr@_modlaybtn, pBmscr_4
		dup state@_modlaybtn, state_4(wp)
		dup mx@_modlaybtn, mx_4(wp)
		dup my@_modlaybtn, my_4(wp)
		dup tx@_modlaybtn, tx_4(wp)
		dup ty@_modlaybtn, ty_4(wp)
		dup mt_id@_modlaybtn, mt_id_4(wp)
		dup count@_modlaybtn, count_4(wp)
		drawlabel@_modlaybtn = drawlabel_4(wp)
		dup groupId@_modlaybtn, groupId_4(wp)
		dup flagBits@_modlaybtn, flagBits_4(wp)
		dup mtis1@_modlaybtn, mtis1_4(wp*10)
		dup mtis2@_modlaybtn, mtis2_4(wp*10)
		dup mtis3@_modlaybtn, mtis3_4(wp*10)
		dup mtis_num@_modlaybtn, mtis_num_4(wp)
		dup p5@_modlaybtn, p5_4(wp)
		dup p6@_modlaybtn, p6_4(wp)
		dup p7@_modlaybtn, p7_4(wp)
		dup p8@_modlaybtn, p8_4(wp)
		dup p9@_modlaybtn, p9_4(wp)
		dup p10@_modlaybtn, p10_4(wp)
		dup hitxy_num@_modlaybtn, hitxy_num_4(wp)
		if hitxy_num@_modlaybtn != 0 {
			dup hitxy1@_modlaybtn, hitxy1_4(wp)
			dup hitxy2@_modlaybtn, hitxy2_4(wp)
			dup hitxy3@_modlaybtn, hitxy3_4(wp)
			dup hitxy4@_modlaybtn, hitxy4_4(wp)
			dup hitxy5@_modlaybtn, hitxy5_4(wp)
			dup hitxy6@_modlaybtn, hitxy6_4(wp)
			dup hitxy7@_modlaybtn, hitxy7_4(wp)
			dup hitxy8@_modlaybtn, hitxy8_4(wp)
		}
		swbreak
	case 5
		if expand {
			state_5(wp)=0
			mx_5(wp)=0
			my_5(wp)=0
			tx_5(wp)=0
			ty_5(wp)=0
			mt_id_5(wp)=0
			count_5(wp)=0
			groupId_5(wp)=0
			flagBits_5(wp)=0
			mtis1_5(wp*10+9)=0
			mtis2_5(wp*10+9)=0
			mtis3_5(wp*10+9)=0
			mtis_num_5(wp)=0
			p5_5(wp)=0
			p6_5(wp)=0
			p7_5(wp)=0
			p8_5(wp)=0
			p9_5(wp)=0
			p10_5(wp)=0
			hitxy_num_5(wp)=0
			hitxy1_5(wp)=0
			hitxy2_5(wp)=0
			hitxy3_5(wp)=0
			hitxy4_5(wp)=0
			hitxy5_5(wp)=0
			hitxy6_5(wp)=0
			hitxy7_5(wp)=0
			hitxy8_5(wp)=0
			if vartype(drawlabel_5)!=1 : ldim drawlabel_5,1
			drawlabel_5(wp)=*dummy
			if vartype(lobjlabel_5)!=1 : ldim lobjlabel_5,1
			lobjlabel_5(wp)=*dummy
		}
		dup pBmscr@_modlaybtn, pBmscr_5
		dup state@_modlaybtn, state_5(wp)
		dup mx@_modlaybtn, mx_5(wp)
		dup my@_modlaybtn, my_5(wp)
		dup tx@_modlaybtn, tx_5(wp)
		dup ty@_modlaybtn, ty_5(wp)
		dup mt_id@_modlaybtn, mt_id_5(wp)
		dup count@_modlaybtn, count_5(wp)
		drawlabel@_modlaybtn = drawlabel_5(wp)
		dup groupId@_modlaybtn, groupId_5(wp)
		dup flagBits@_modlaybtn, flagBits_5(wp)
		dup mtis1@_modlaybtn, mtis1_5(wp*10)
		dup mtis2@_modlaybtn, mtis2_5(wp*10)
		dup mtis3@_modlaybtn, mtis3_5(wp*10)
		dup mtis_num@_modlaybtn, mtis_num_5(wp)
		dup p5@_modlaybtn, p5_5(wp)
		dup p6@_modlaybtn, p6_5(wp)
		dup p7@_modlaybtn, p7_5(wp)
		dup p8@_modlaybtn, p8_5(wp)
		dup p9@_modlaybtn, p9_5(wp)
		dup p10@_modlaybtn, p10_5(wp)
		dup hitxy_num@_modlaybtn, hitxy_num_5(wp)
		if hitxy_num@_modlaybtn != 0 {
			dup hitxy1@_modlaybtn, hitxy1_5(wp)
			dup hitxy2@_modlaybtn, hitxy2_5(wp)
			dup hitxy3@_modlaybtn, hitxy3_5(wp)
			dup hitxy4@_modlaybtn, hitxy4_5(wp)
			dup hitxy5@_modlaybtn, hitxy5_5(wp)
			dup hitxy6@_modlaybtn, hitxy6_5(wp)
			dup hitxy7@_modlaybtn, hitxy7_5(wp)
			dup hitxy8@_modlaybtn, hitxy8_5(wp)
		}
		swbreak
	case 6
		if expand {
			state_6(wp)=0
			mx_6(wp)=0
			my_6(wp)=0
			tx_6(wp)=0
			ty_6(wp)=0
			mt_id_6(wp)=0
			count_6(wp)=0
			groupId_6(wp)=0
			flagBits_6(wp)=0
			mtis1_6(wp*10+9)=0
			mtis2_6(wp*10+9)=0
			mtis3_6(wp*10+9)=0
			mtis_num_6(wp)=0
			p5_6(wp)=0
			p6_6(wp)=0
			p7_6(wp)=0
			p8_6(wp)=0
			p9_6(wp)=0
			p10_6(wp)=0
			hitxy_num_6(wp)=0
			hitxy1_6(wp)=0
			hitxy2_6(wp)=0
			hitxy3_6(wp)=0
			hitxy4_6(wp)=0
			hitxy5_6(wp)=0
			hitxy6_6(wp)=0
			hitxy7_6(wp)=0
			hitxy8_6(wp)=0
			if vartype(drawlabel_6)!=1 : ldim drawlabel_6,1
			drawlabel_6(wp)=*dummy
			if vartype(lobjlabel_6)!=1 : ldim lobjlabel_6,1
			lobjlabel_6(wp)=*dummy
		}
		dup pBmscr@_modlaybtn, pBmscr_6
		dup state@_modlaybtn, state_6(wp)
		dup mx@_modlaybtn, mx_6(wp)
		dup my@_modlaybtn, my_6(wp)
		dup tx@_modlaybtn, tx_6(wp)
		dup ty@_modlaybtn, ty_6(wp)
		dup mt_id@_modlaybtn, mt_id_6(wp)
		dup count@_modlaybtn, count_6(wp)
		drawlabel@_modlaybtn = drawlabel_6(wp)
		dup groupId@_modlaybtn, groupId_6(wp)
		dup flagBits@_modlaybtn, flagBits_6(wp)
		dup mtis1@_modlaybtn, mtis1_6(wp*10)
		dup mtis2@_modlaybtn, mtis2_6(wp*10)
		dup mtis3@_modlaybtn, mtis3_6(wp*10)
		dup mtis_num@_modlaybtn, mtis_num_6(wp)
		dup p5@_modlaybtn, p5_6(wp)
		dup p6@_modlaybtn, p6_6(wp)
		dup p7@_modlaybtn, p7_6(wp)
		dup p8@_modlaybtn, p8_6(wp)
		dup p9@_modlaybtn, p9_6(wp)
		dup p10@_modlaybtn, p10_6(wp)
		dup hitxy_num@_modlaybtn, hitxy_num_6(wp)
		if hitxy_num@_modlaybtn != 0 {
			dup hitxy1@_modlaybtn, hitxy1_6(wp)
			dup hitxy2@_modlaybtn, hitxy2_6(wp)
			dup hitxy3@_modlaybtn, hitxy3_6(wp)
			dup hitxy4@_modlaybtn, hitxy4_6(wp)
			dup hitxy5@_modlaybtn, hitxy5_6(wp)
			dup hitxy6@_modlaybtn, hitxy6_6(wp)
			dup hitxy7@_modlaybtn, hitxy7_6(wp)
			dup hitxy8@_modlaybtn, hitxy8_6(wp)
		}
		swbreak
	case 7
		if expand {
			state_7(wp)=0
			mx_7(wp)=0
			my_7(wp)=0
			tx_7(wp)=0
			ty_7(wp)=0
			mt_id_7(wp)=0
			count_7(wp)=0
			groupId_7(wp)=0
			flagBits_7(wp)=0
			mtis1_7(wp*10+9)=0
			mtis2_7(wp*10+9)=0
			mtis3_7(wp*10+9)=0
			mtis_num_7(wp)=0
			p5_7(wp)=0
			p6_7(wp)=0
			p7_7(wp)=0
			p8_7(wp)=0
			p9_7(wp)=0
			p10_7(wp)=0
			hitxy_num_7(wp)=0
			hitxy1_7(wp)=0
			hitxy2_7(wp)=0
			hitxy3_7(wp)=0
			hitxy4_7(wp)=0
			hitxy5_7(wp)=0
			hitxy6_7(wp)=0
			hitxy7_7(wp)=0
			hitxy8_7(wp)=0
			if vartype(drawlabel_7)!=1 : ldim drawlabel_7,1
			drawlabel_7(wp)=*dummy
			if vartype(lobjlabel_7)!=1 : ldim lobjlabel_7,1
			lobjlabel_7(wp)=*dummy
		}
		dup pBmscr@_modlaybtn, pBmscr_7
		dup state@_modlaybtn, state_7(wp)
		dup mx@_modlaybtn, mx_7(wp)
		dup my@_modlaybtn, my_7(wp)
		dup tx@_modlaybtn, tx_7(wp)
		dup ty@_modlaybtn, ty_7(wp)
		dup mt_id@_modlaybtn, mt_id_7(wp)
		dup count@_modlaybtn, count_7(wp)
		drawlabel@_modlaybtn = drawlabel_7(wp)
		dup groupId@_modlaybtn, groupId_7(wp)
		dup flagBits@_modlaybtn, flagBits_7(wp)
		dup mtis1@_modlaybtn, mtis1_7(wp*10)
		dup mtis2@_modlaybtn, mtis2_7(wp*10)
		dup mtis3@_modlaybtn, mtis3_7(wp*10)
		dup mtis_num@_modlaybtn, mtis_num_7(wp)
		dup p5@_modlaybtn, p5_7(wp)
		dup p6@_modlaybtn, p6_7(wp)
		dup p7@_modlaybtn, p7_7(wp)
		dup p8@_modlaybtn, p8_7(wp)
		dup p9@_modlaybtn, p9_7(wp)
		dup p10@_modlaybtn, p10_7(wp)
		dup hitxy_num@_modlaybtn, hitxy_num_7(wp)
		if hitxy_num@_modlaybtn != 0 {
			dup hitxy1@_modlaybtn, hitxy1_7(wp)
			dup hitxy2@_modlaybtn, hitxy2_7(wp)
			dup hitxy3@_modlaybtn, hitxy3_7(wp)
			dup hitxy4@_modlaybtn, hitxy4_7(wp)
			dup hitxy5@_modlaybtn, hitxy5_7(wp)
			dup hitxy6@_modlaybtn, hitxy6_7(wp)
			dup hitxy7@_modlaybtn, hitxy7_7(wp)
			dup hitxy8@_modlaybtn, hitxy8_7(wp)
		}
		swbreak
	swend
	return index
// (モジュール内使用) 指定されたginfo_selの入っているwinIDsのインデックスを取得
#defcfunc getLayobjverIndex@modlaybtn int id
	index = -1
	repeat winIDs_count
		if winIDs(cnt) == id : index = cnt : break
	loop
	return index
// (モジュール内使用) オブジェクトID(wp)がlayerbuttonで使用しているオブジェクトかどうかを判定
#defcfunc isLaybtnObj_@modlaybtn int id, int wp
	if id == -1 : return 0 
	if maxObjIDs(id) < wp : return 0
	switch id
	case 0 : return state_0(wp) > 0 : swbreak
	case 1 : return state_1(wp) > 0 : swbreak
	case 2 : return state_2(wp) > 0 : swbreak
	case 3 : return state_3(wp) > 0 : swbreak
	case 4 : return state_4(wp) > 0 : swbreak
	case 5 : return state_5(wp) > 0 : swbreak
	case 6 : return state_6(wp) > 0 : swbreak
	case 7 : return state_7(wp) > 0 : swbreak
	swend
	return 0
// (モジュール内使用) オブジェクトID(wp)のグループを取得
#defcfunc groupId_@modlaybtn int id, int wp
	if id == -1 : return 0
	if maxObjIDs(id) < wp : return 0
	switch id
	case 0 : return groupId_0(wp) : swbreak
	case 1 : return groupId_1(wp) : swbreak
	case 2 : return groupId_2(wp) : swbreak
	case 3 : return groupId_3(wp) : swbreak
	case 4 : return groupId_4(wp) : swbreak
	case 5 : return groupId_5(wp) : swbreak
	case 6 : return groupId_6(wp) : swbreak
	case 7 : return groupId_7(wp) : swbreak
	swend
	return 0
// (モジュール内使用) bmscrポインタを取得[まだ1個も作られてないと呼び出し時エラーになるので、確実に作られたときに保存している]
#defcfunc pBmscr_@modlaybtn int id
	if id == -1 : return 0
	switch id
	case 0 : return pBmscr_0 : swbreak
	case 1 : return pBmscr_1 : swbreak
	case 2 : return pBmscr_2 : swbreak
	case 3 : return pBmscr_3 : swbreak
	case 4 : return pBmscr_4 : swbreak
	case 5 : return pBmscr_5 : swbreak
	case 6 : return pBmscr_6 : swbreak
	case 7 : return pBmscr_7 : swbreak
	swend
	return 0
// (モジュール内使用) オブジェクトID(wp)のフラグ状態を取得
#defcfunc flagBits_@modlaybtn int id, int wp
	if id == -1 : return 0
	if maxObjIDs(id) < wp : return 0
	switch id
	case 0 : return flagBits_0(wp) : swbreak
	case 1 : return flagBits_1(wp) : swbreak
	case 2 : return flagBits_2(wp) : swbreak
	case 3 : return flagBits_3(wp) : swbreak
	case 4 : return flagBits_4(wp) : swbreak
	case 5 : return flagBits_5(wp) : swbreak
	case 6 : return flagBits_6(wp) : swbreak
	case 7 : return flagBits_7(wp) : swbreak
	swend
	return 0
// (モジュール内使用) オブジェクトID(wp)のマウス記録位置xを取得
#defcfunc mx_@modlaybtn int id, int wp
	if id == -1 : return 0
	if maxObjIDs(id) < wp : return 0
	switch id
	case 0 : return mx_0(wp) : swbreak
	case 1 : return mx_1(wp) : swbreak
	case 2 : return mx_2(wp) : swbreak
	case 3 : return mx_3(wp) : swbreak
	case 4 : return mx_4(wp) : swbreak
	case 5 : return mx_5(wp) : swbreak
	case 6 : return mx_6(wp) : swbreak
	case 7 : return mx_7(wp) : swbreak
	swend
	return 0
// (モジュール内使用) オブジェクトID(wp)のマウス記録位置yを取得
#defcfunc my_@modlaybtn int id, int wp
	if id == -1 : return 0
	if maxObjIDs(id) < wp : return 0
	switch id
	case 0 : return my_0(wp) : swbreak
	case 1 : return my_1(wp) : swbreak
	case 2 : return my_2(wp) : swbreak
	case 3 : return my_3(wp) : swbreak
	case 4 : return my_4(wp) : swbreak
	case 5 : return my_5(wp) : swbreak
	case 6 : return my_6(wp) : swbreak
	case 7 : return my_7(wp) : swbreak
	swend
	return 0
// (モジュール内使用) オブジェクトID(wp)がHitTest設定をしているか、していたら頂点数を取得
#defcfunc hitxy_num_@modlaybtn int id, int wp
	if id == -1 : return 0 
	if maxObjIDs(id) < wp : return 0
	switch id
	case 0 : return hitxy_num_0(wp) : swbreak
	case 1 : return hitxy_num_1(wp) : swbreak
	case 2 : return hitxy_num_2(wp) : swbreak
	case 3 : return hitxy_num_3(wp) : swbreak
	case 4 : return hitxy_num_4(wp) : swbreak
	case 5 : return hitxy_num_5(wp) : swbreak
	case 6 : return hitxy_num_6(wp) : swbreak
	case 7 : return hitxy_num_7(wp) : swbreak
	swend
	return 0
#deffunc dups_hitxy_@modlaybtn int id, int wp
	if id == -1 : return 0 
	if maxObjIDs(id) < wp : return 0
	switch id
	case 0 : dup hitxy1_, hitxy1_0(wp) : dup hitxy2_, hitxy2_0(wp) : dup hitxy3_, hitxy3_0(wp) : dup hitxy4_, hitxy4_0(wp) : dup hitxy5_, hitxy5_0(wp) : dup hitxy6_, hitxy6_0(wp) : dup hitxy7_, hitxy7_0(wp) : dup hitxy8_, hitxy8_0(wp) : swbreak
	case 1 : dup hitxy1_, hitxy1_1(wp) : dup hitxy2_, hitxy2_1(wp) : dup hitxy3_, hitxy3_1(wp) : dup hitxy4_, hitxy4_1(wp) : dup hitxy5_, hitxy5_1(wp) : dup hitxy6_, hitxy6_1(wp) : dup hitxy7_, hitxy7_1(wp) : dup hitxy8_, hitxy8_1(wp) : swbreak
	case 2 : dup hitxy1_, hitxy1_2(wp) : dup hitxy2_, hitxy2_2(wp) : dup hitxy3_, hitxy3_2(wp) : dup hitxy4_, hitxy4_2(wp) : dup hitxy5_, hitxy5_2(wp) : dup hitxy6_, hitxy6_2(wp) : dup hitxy7_, hitxy7_2(wp) : dup hitxy8_, hitxy8_2(wp) : swbreak
	case 3 : dup hitxy1_, hitxy1_3(wp) : dup hitxy2_, hitxy2_3(wp) : dup hitxy3_, hitxy3_3(wp) : dup hitxy4_, hitxy4_3(wp) : dup hitxy5_, hitxy5_3(wp) : dup hitxy6_, hitxy6_3(wp) : dup hitxy7_, hitxy7_3(wp) : dup hitxy8_, hitxy8_3(wp) : swbreak
	case 4 : dup hitxy1_, hitxy1_4(wp) : dup hitxy2_, hitxy2_4(wp) : dup hitxy3_, hitxy3_4(wp) : dup hitxy4_, hitxy4_4(wp) : dup hitxy5_, hitxy5_4(wp) : dup hitxy6_, hitxy6_4(wp) : dup hitxy7_, hitxy7_4(wp) : dup hitxy8_, hitxy8_4(wp) : swbreak
	case 5 : dup hitxy1_, hitxy1_5(wp) : dup hitxy2_, hitxy2_5(wp) : dup hitxy3_, hitxy3_5(wp) : dup hitxy4_, hitxy4_5(wp) : dup hitxy5_, hitxy5_5(wp) : dup hitxy6_, hitxy6_5(wp) : dup hitxy7_, hitxy7_5(wp) : dup hitxy8_, hitxy8_5(wp) : swbreak
	case 6 : dup hitxy1_, hitxy1_6(wp) : dup hitxy2_, hitxy2_6(wp) : dup hitxy3_, hitxy3_6(wp) : dup hitxy4_, hitxy4_6(wp) : dup hitxy5_, hitxy5_6(wp) : dup hitxy6_, hitxy6_6(wp) : dup hitxy7_, hitxy7_6(wp) : dup hitxy8_, hitxy8_6(wp) : swbreak
	case 7 : dup hitxy1_, hitxy1_7(wp) : dup hitxy2_, hitxy2_7(wp) : dup hitxy3_, hitxy3_7(wp) : dup hitxy4_, hitxy4_7(wp) : dup hitxy5_, hitxy5_7(wp) : dup hitxy6_, hitxy6_7(wp) : dup hitxy7_, hitxy7_7(wp) : dup hitxy8_, hitxy8_7(wp) : swbreak
	swend		
	return
#deffunc Set_mxy_@modlaybtn int id, int wp, int ax, int ay
	if id == -1 : return
	if maxObjIDs(id) < wp : return
	switch id
	case 0 : mx_0(wp) = ax : my_0(wp) = ay : swbreak
	case 1 : mx_1(wp) = ax : my_1(wp) = ay : swbreak
	case 2 : mx_2(wp) = ax : my_2(wp) = ay : swbreak
	case 3 : mx_3(wp) = ax : my_3(wp) = ay : swbreak
	case 4 : mx_4(wp) = ax : my_4(wp) = ay : swbreak
	case 5 : mx_5(wp) = ax : my_5(wp) = ay : swbreak
	case 6 : mx_6(wp) = ax : my_6(wp) = ay : swbreak
	case 7 : mx_7(wp) = ax : my_7(wp) = ay : swbreak
	swend
	return
#deffunc Set_txy_@modlaybtn int id, int wp, int ax, int ay
	if id == -1 : return
	if maxObjIDs(id) < wp : return
	switch id
	case 0 : tx_0(wp) = ax : ty_0(wp) = ay : swbreak
	case 1 : tx_1(wp) = ax : ty_1(wp) = ay : swbreak
	case 2 : tx_2(wp) = ax : ty_2(wp) = ay : swbreak
	case 3 : tx_3(wp) = ax : ty_3(wp) = ay : swbreak
	case 4 : tx_4(wp) = ax : ty_4(wp) = ay : swbreak
	case 5 : tx_5(wp) = ax : ty_5(wp) = ay : swbreak
	case 6 : tx_6(wp) = ax : ty_6(wp) = ay : swbreak
	case 7 : tx_7(wp) = ax : ty_7(wp) = ay : swbreak
	swend
	return
// (モジュール内使用) オブジェクトID(wp)の、layerbutton後の{}範囲へアクセスするlabelを保存
#deffunc Set_drawlabel_@modlaybtn int id, int wp, label lb
	if id == -1 : return
	if maxObjIDs(id) < wp : return
	switch id
	case 0 : drawlabel_0(wp) = lb : swbreak
	case 1 : drawlabel_1(wp) = lb : swbreak
	case 2 : drawlabel_2(wp) = lb : swbreak
	case 3 : drawlabel_3(wp) = lb : swbreak
	case 4 : drawlabel_4(wp) = lb : swbreak
	case 5 : drawlabel_5(wp) = lb : swbreak
	case 6 : drawlabel_6(wp) = lb : swbreak
	case 7 : drawlabel_7(wp) = lb : swbreak
	swend
	return
// (モジュール内使用) オブジェクトID(wp)の、layerobjのgosub先へアクセスするlabelを保存
#deffunc Set_lobjlabel_@modlaybtn int id, int wp, label lb
	if id == -1 : return
	if maxObjIDs(id) < wp : return
	switch id
	case 0 : lobjlabel_0(wp) = lb : swbreak
	case 1 : lobjlabel_1(wp) = lb : swbreak
	case 2 : lobjlabel_2(wp) = lb : swbreak
	case 3 : lobjlabel_3(wp) = lb : swbreak
	case 4 : lobjlabel_4(wp) = lb : swbreak
	case 5 : lobjlabel_5(wp) = lb : swbreak
	case 6 : lobjlabel_6(wp) = lb : swbreak
	case 7 : lobjlabel_7(wp) = lb : swbreak
	swend
	return
// (モジュール内使用) オブジェクトID(wp)の、layerobjのgosub先へアクセスするlabelを取得
#deffunc Get_lobjlabel_@modlaybtn int id, int wp, var vlb
	if id == -1 : vlb = *dummy : return
	if maxObjIDs(id) < wp : vlb = *dummy : return
	switch id
	case 0 : vlb = lobjlabel_0(wp) : swbreak
	case 1 : vlb = lobjlabel_1(wp) : swbreak
	case 2 : vlb = lobjlabel_2(wp) : swbreak
	case 3 : vlb = lobjlabel_3(wp) : swbreak
	case 4 : vlb = lobjlabel_4(wp) : swbreak
	case 5 : vlb = lobjlabel_5(wp) : swbreak
	case 6 : vlb = lobjlabel_6(wp) : swbreak
	case 7 : vlb = lobjlabel_7(wp) : swbreak
	default : vlb = *dummy
	swend
	return
// (モジュール内使用) オブジェクトID(wp)のフラグ状態を追加
#deffunc Add_flagBits_@modlaybtn int id, int wp, int flags
	if id == -1 : return
	if maxObjIDs(id) < wp : return
	switch id
	case 0 : flagBits_0(wp) |= flags : swbreak
	case 1 : flagBits_1(wp) |= flags : swbreak
	case 2 : flagBits_2(wp) |= flags : swbreak
	case 3 : flagBits_3(wp) |= flags : swbreak
	case 4 : flagBits_4(wp) |= flags : swbreak
	case 5 : flagBits_5(wp) |= flags : swbreak
	case 6 : flagBits_6(wp) |= flags : swbreak
	case 7 : flagBits_7(wp) |= flags : swbreak
	swend
	return
#deffunc Add_flagBits@_modlaybtn int flags
	flagBits@_modlaybtn |= flags
	return
// (モジュール内使用) オブジェクトID(wp)のフラグ状態を削除
#deffunc Clear_flagBits_@modlaybtn int id, int wp, int flags
	if id == -1 : return
	if maxObjIDs(id) < wp : return
	switch id
	case 0 : flagBits_0(wp) = flagBits_0(wp) | flags ^ flags : swbreak
	case 1 : flagBits_1(wp) = flagBits_1(wp) | flags ^ flags : swbreak
	case 2 : flagBits_2(wp) = flagBits_2(wp) | flags ^ flags : swbreak
	case 3 : flagBits_3(wp) = flagBits_3(wp) | flags ^ flags : swbreak
	case 4 : flagBits_4(wp) = flagBits_4(wp) | flags ^ flags : swbreak
	case 5 : flagBits_5(wp) = flagBits_5(wp) | flags ^ flags : swbreak
	case 6 : flagBits_6(wp) = flagBits_6(wp) | flags ^ flags : swbreak
	case 7 : flagBits_7(wp) = flagBits_7(wp) | flags ^ flags : swbreak
	swend
	return
#deffunc Clear_flagBits@_modlaybtn int flags
	flagBits@_modlaybtn = flagBits@_modlaybtn | flags ^ flags
	return

//--------------------------------------
// モジュール内で簡易的に使用するための定数と命令
//--------------------------------------
//  [option] マウスによる操作をさせない
//  [option] マウスクリックで即Selectedする
//  [option] ボタンを押した後に非表示処理させない
//  [condition] prev_selected
#define option_mouseDisabled@_modlaybtn ((flagBits@_modlaybtn & FLAGBT_OPTION_MOUSE_DISABLED)!=0)
#define option_mouseSelectOnPress@_modlaybtn ((flagBits@_modlaybtn & FLAGBT_OPTION_MOUSE_SELECT_ON_PRESS)!=0)
#define option_keepVisible@_modlaybtn ((flagBits@_modlaybtn & FLAGBT_OPTION_KEEP_VISIBLE)!=0)
#define prev_selected@_modlaybtn ((flagBits@_modlaybtn & FLAGBT_CONDITION_PREV_SELECTED)!=0)

//--------------------------------------
// layerbuttonで使用する layerobjのcmdinit,cmddraw,cmdterm の各種処理
//--------------------------------------
// cmdinit
#deffunc layerbutton_cmdinit@modlaybtn int _p4, int _p5, int _p6, int _p7, int _p8, int _p9, int _p10, label lb1, label lb2
	// layerobjの初期化
	SET_LAYOBJVAR@modlaybtn wparam
	layobjIndex = stat
	pBmscr@_modlaybtn = objinfo_bmscr(wparam)
	p5@_modlaybtn = _p5 : p6@_modlaybtn = _p6 : p7@_modlaybtn = _p7 : p8@_modlaybtn = _p8 : p9@_modlaybtn = _p9 : p10@_modlaybtn = _p10
	state@_modlaybtn=LAYBTN_SHOW_IN : count@_modlaybtn=0 : mt_id@_modlaybtn=0
	mx@_modlaybtn=objinfo_axis_x(wparam)-1 : my@_modlaybtn=objinfo_axis_y(wparam)-1
	tx@_modlaybtn=mx@_modlaybtn : ty@_modlaybtn=my@_modlaybtn
	groupId@_modlaybtn = _p4 : flagBits@_modlaybtn = 1  ; グループをセット、showingビットを立てる
	Set_drawlabel_@modlaybtn layobjIndex, wparam, lb1  ; dup経由は上手くいかないので専用命令
	drawlabel@_modlaybtn = lb1
	Set_lobjlabel_@modlaybtn layobjIndex, wparam, lb2  ; dup経由は上手くいかないので専用命令
	SetStat@modlaybtn wparam
	return

// cmddraw
#deffunc layerbutton_cmddraw@modlaybtn label lb
	SET_LAYOBJVAR@modlaybtn wparam
	layobjIndex = stat
	// layerbutton_redraw@modlaybtnの中で、下記のフラグやオプションが取得されている
	; yongestId
	; focusedId
	; dorekaFlags
	; subeteFlags
	; hasMultiGroups
	; disableKeyInput

	// flagBits@_modlaybtn に以下のフラグが入っている
	; FLAGBT_SHOWING                      : showing
	; FLAGBT_FOCUS                        : focus
	; FLAGBT_PUSHING                      : pushing
	; FLAGBT_PUSHING_IN                   : pushingIn
	; FLAGBT_SELECTED                     : selected
	; FLAGBT_SHOWOUT                      : showout
	; FLAGBT_SHOWOUTED                    : showouted
	; FLAGBT_LAST_RUN                     : last_run
	; FLAGBT_CONDITION_TERMED             : [condition] termed
	; FLAGBT_CONDITION_DISABLE            : [condition] disable
	; FLAGBT_CONDITION_PREV_SELECTED      : [condition] prev_selected  // このprev_selected、バグの温床として結構な癌だけど取り除けない..._SELECTEDを1回だけ通知したいことに使ってるから、、、何か対案はないか?
	; FLAGBT_OPTION_〜                    : [option] 〜

	// subeteFlagsにdisableビットが立っている場合は、 オブジェクトをenable扱いする
	disable = ((subeteFlags & FLAGBT_CONDITION_DISABLE) != 0)  ; disable時は強制フリーズ
	if disable == 0 {
		// どれかにselectedが立っていてる場合は、これ以上キー入力やマウスタッチ操作をさせないためshowingを立てたい
		if dorekaFlags & FLAGBT_SELECTED {
			// ただし、option_keepVisible==1のときは複数押せるためこの制限はしない、、、のだけど、オプションによってはPRESS_IN→_OUTの終わりまで操作させないためFLAGBT_SHOWINGを活用することもしたい(STATE遷移処理部で実現)
			if option_keepVisible@_modlaybtn == 0 {
				dorekaFlags |= FLAGBT_SHOWING  ; showing立てて以下のフォーカス等の処理をさせない
			}
		}
		// 自身が一番若いIDなら処理(グループ内で1回だけ実行される)
		if wparam == yongestId {
			if (subeteFlags & FLAGBT_SHOWOUTED)!=0 {  ; groupすべてshowoutedし終わった!
				if (subeteFlags & FLAGBT_LAST_RUN) == 0 {  ; すでにlast_runビットフラグをセットし終わってるか、し終わっていなかったら、
					// ここで一斉にgroup内すべてにlast_runビットフラグ立て(すべて同時にCOMPLETEを実行させるため)
					repeat bm(BMSCR_OBJMAX) 
						if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }
						if isLaybtnObj_@modlaybtn(layobjIndex,cnt) == 0 { continue }
						if groupId_@modlaybtn(layobjIndex,cnt) != groupId@_modlaybtn { continue }
						Add_flagBits_@modlaybtn layobjIndex,cnt, FLAGBT_LAST_RUN  ; last_runビットを立てる
					loop
					dorekaFlags |= FLAGBT_SHOWING  ; showingも立てて以下のフォーカス等の処理をさせない
				}
			}else {
				// どれかにshowoutが立っていたらgroupすべてにshowingも立て、非表示処理を開始する[showout_startビット(showout|showingビット)]
				if (dorekaFlags & FLAGBT_SHOWOUT)!=0 && (subeteFlags & FLAGBT_SHOWING)==0 {
					// ここで一斉にgroup内すべてにフラグ立て(すべて同時にSHOW_OUTさせるため)
					repeat bm(BMSCR_OBJMAX) 
						if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }
						if isLaybtnObj_@modlaybtn(layobjIndex,cnt) == 0 { continue }
						if groupId_@modlaybtn(layobjIndex,cnt) != groupId@_modlaybtn { continue }
						Add_flagBits_@modlaybtn layobjIndex,cnt, (FLAGBT_SHOWING|FLAGBT_SHOWOUT)  ; showout_startビット(showout|showingビット)を立てる
					loop
					dorekaFlags |= FLAGBT_SHOWING  ; showing立てて以下のフォーカス等の処理をさせない
				}
			}
			// キー入力による[フォーカス移動、決定] (グループで一回だけ呼ばれるし、複数グループを持っているときはフォーカスのあるオブジェクトのみが対象なので、実質ループの中で1回だけ実行される)
			if (dorekaFlags & FLAGBT_SHOWING)==0 && disableKeyInput==0 && (focusedId!=-1 || hasMultiGroups=0) {
				trig = $100
				if focusedId != -1 {
					if flagBits_@modlaybtn(layobjIndex,focusedId) & FLAGBT_OPTION_KEY_REPEAT {  ; キーリピート設定
						if GlobalLastKey : trig |= $3C03F
					}
				}
				laybtn_stick stk, trig  ; stickもどき(layerobjの中で使用できる)
				stk |= layerbtn_stickVar@modlaybtn
				GlobalLastKey &= stk  ; 前回と同じキー(GlobalLastKey)をまだ押し続けてたら、GlobalLastKeyの内容が生き残る
				if trig != $100 && GlobalLastKey != 0 {  ; OPTION_KEY_REPEAT かつ 前回と同じキーを含んでいるとき
					if (GlobalFrame - GlobalKeyPressFrame) < (LAYERBTN_KEY_REPEAT_FRAME@modlaybtn & $FFFF) {
						stk = stk| $3C03F^$3C03F
					}else {
						if (LAYERBTN_KEY_REPEAT_FRAME@modlaybtn>>16 & $FFFF) == 0 {
							if (GlobalFrame - GlobalKeyPressFrame)\(LAYERBTN_KEY_REPEAT_FRAME@modlaybtn/2) : stk = stk| $3C03F^$3C03F
						}else {
							if (GlobalFrame - GlobalKeyPressFrame)\(LAYERBTN_KEY_REPEAT_FRAME@modlaybtn>>16 & $FFFF) : stk = stk| $3C03F^$3C03F
						}
					}
				}
				if (stk & $30) != 0 && focusedId != -1 {
					;; [決定]
					_stk = stk
					if flagBits_@modlaybtn(layobjIndex,focusedId) & FLAGBT_OPTION_KEY_NO_SPACE { _stk = _stk | $10 ^ $10 }  ; option[スペースキー操作無効]ビットが立っていたら
					if flagBits_@modlaybtn(layobjIndex,focusedId) & FLAGBT_OPTION_KEY_NO_ENTER { _stk = _stk | $20 ^ $20 }  ; option[エンターキー操作無効]ビットが立っていたら
					if _stk & $30 {
						if (flagBits_@modlaybtn(layobjIndex,focusedId) & FLAGBT_OPTION_KEY_DISABLE)==0 {  ; option[キー操作無効]ビットが立っている場合はスキップ
							Add_flagBits_@modlaybtn layobjIndex,focusedId, (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED|FLAGBT_SHOWOUTED)  ; pushing|pushingIn|selected|showouted [option分岐でカウンタリセットしたいがここでは無理なので強制的にshowoutedビット(借りビット)立て、個別処理内で必要なければ下ろしてもらう]
							;Set_mxy_@modlaybtn layobjIndex,focusedId, _mx, _my  ; 一応、座標を残す
							;Set_txy_@modlaybtn layobjIndex,focusedId, _mx, _my  ; FLAGBT_PUSHING False → True のタッチ時
						}
						if GlobalLastKey != (_stk & $30) : GlobalKeyPressFrame = GlobalFrame
						GlobalLastKey = _stk & $30
					}
				}
				if stk & $3C00F {
					;; [フォーカス移動]
					if focusedId != -1 {
						px = objinfo_axis_x(focusedId) + objinfo_size_x(focusedId) / 2
						py = objinfo_axis_y(focusedId) + objinfo_size_y(focusedId) / 2
					}
					dd2 = 0.0
					tikaiId = -1  ; 一番近い移動先ID
					repeat bm(BMSCR_OBJMAX)
						if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
						if isLaybtnObj_@modlaybtn(layobjIndex,cnt) == 0 { continue }
						if groupId_@modlaybtn(layobjIndex,cnt) != groupId@_modlaybtn { continue }
						if flagBits_@modlaybtn(layobjIndex,cnt) & FLAGBT_OPTION_KEY_DISABLE { continue }  ; option[キー操作無効]ビットが立っているものはスキップ
						_stk = stk
						if flagBits_@modlaybtn(layobjIndex,cnt) & FLAGBT_OPTION_KEY_NO_WASD { _stk = _stk | $3c000 ^ $3c000 }  ; option[WASDキー操作無効]ビットが立っていたら
						if flagBits_@modlaybtn(layobjIndex,cnt) & FLAGBT_OPTION_KEY_NO_ULDR { _stk = _stk | $F ^ $F }  ; option[上下左右キー操作無効]ビットが立っていたら
						if _stk & $4001 {
							xx = (objinfo_axis_x(cnt) + objinfo_size_x(cnt) / 2)
							if focusedId == -1 {
								dd = double(-xx)
							}else {
								if xx >= (px - objinfo_size_x(focusedId)/2) { continue }
								if objinfo_axis_y(cnt)<=py && py<objinfo_axis_y2(cnt) {
									yy = py
								}else {
									yy = (objinfo_axis_y(cnt) + objinfo_size_y(cnt) / 2)
								}
								dd = limitf((1.0-absf(cos.atan( yy-py , xx-px ))),0.000001)*(absf(double(xx-px)*(xx-px)*(xx-px))+absf(double(yy-py)*(yy-py)*(yy-py)))
							}
							if dd2 == 0 || dd2 > dd { dd2 = dd : tikaiId = cnt }
							if GlobalLastKey != (_stk & $4001) : GlobalKeyPressFrame = GlobalFrame
							GlobalLastKey = _stk & $4001
						}else : if _stk & $8002 {
							yy = (objinfo_axis_y(cnt) + objinfo_size_y(cnt) / 2)
							if focusedId == -1 {
								dd = double(-yy)
							}else {
								if yy >= (py - objinfo_size_y(focusedId)/2) { continue }
								if objinfo_axis_x(cnt)<=px && px<objinfo_axis_x2(cnt) {
									xx = px
								}else {
									xx = (objinfo_axis_x(cnt) + objinfo_size_x(cnt) / 2)
								}
								dd = limitf((1.0-absf(sin.atan( yy-py , xx-px ))),0.000001)*(absf(double(xx-px)*(xx-px)*(xx-px))+absf(double(yy-py)*(yy-py)*(yy-py)))
							}
							if dd2 == 0 || dd2 > dd { dd2 = dd : tikaiId = cnt }
							if GlobalLastKey != (_stk & $8002) : GlobalKeyPressFrame = GlobalFrame
							GlobalLastKey = _stk & $8002
						}else : if _stk & $10004 {
							xx = (objinfo_axis_x(cnt) + objinfo_size_x(cnt) / 2)
							if focusedId == -1 {
								dd = double(xx)
							}else {
								if xx <= (px + objinfo_size_x(focusedId)/2) { continue }
								if objinfo_axis_y(cnt)<=py && py<objinfo_axis_y2(cnt) {
									yy = py
								}else {
									yy = (objinfo_axis_y(cnt) + objinfo_size_y(cnt) / 2)
								}
								dd = limitf((1.0-absf(cos.atan( yy-py , xx-px ))),0.000001)*(absf(double(xx-px)*(xx-px)*(xx-px))+absf(double(yy-py)*(yy-py)*(yy-py)))
							}
							if dd2 == 0 || dd2 > dd { dd2 = dd : tikaiId = cnt }
							if GlobalLastKey != (_stk & $10004) : GlobalKeyPressFrame = GlobalFrame
							GlobalLastKey = _stk & $10004
						}else : if _stk & $20008 {
							yy = (objinfo_axis_y(cnt) + objinfo_size_y(cnt) / 2)
							if focusedId == -1 {
								dd = double(yy)
							}else {
								if yy <= (py + objinfo_size_y(focusedId)/2) { continue }
								if objinfo_axis_x(cnt)<=px && px<objinfo_axis_x2(cnt) {
									xx = px
								}else {
									xx = (objinfo_axis_x(cnt) + objinfo_size_x(cnt) / 2)
								}
								dd = limitf((1.0-absf(sin.atan( yy-py , xx-px ))),0.000001)*(absf(double(xx-px)*(xx-px)*(xx-px))+absf(double(yy-py)*(yy-py)*(yy-py)))
							}
							if dd2 == 0 || dd2 > dd { dd2 = dd : tikaiId = cnt }
							if GlobalLastKey != (_stk & $20008) : GlobalKeyPressFrame = GlobalFrame
							GlobalLastKey = _stk & $20008
						}
					loop
					if tikaiId != -1 {
						if focusedId != -1 || (flagBits_@modlaybtn(layobjIndex,tikaiId) & FLAGBT_OPTION_KEY_NO_FOCUS_START) == 0 {  ; option[キーフォーカススタート無効]ビットが立っている場合はフォーカススタートをしない
							objsel tikaiId : focusedId = tikaiId
						}
					}
				}
			}
			// マウス処理出張 [フォーカス解除、フォーカス発生]
			;; [フォーカス解除]
			if focusedId != -1 {
				if (dorekaFlags & FLAGBT_SHOWING)==0 && (flagBits_@modlaybtn(layobjIndex,focusedId) & FLAGBT_OPTION_MOUSE_DISABLED)==0 {
					if SPmtiChanged && (dorekaFlags & FLAGBT_PUSHING)==0 {  ; マウス,タッチが変化していて、かつ他ボタンを押していないとき
						isAnyObjectHit = 0
						if mtl_num == 0 {  ; クリックなし : カーソルが座標に入っているか
							_mx = mousex : _my = mousey
							if hittest_@modlaybtn(layobjIndex,focusedId, _mx, _my) {
								isAnyObjectHit = 1
							}
						}else {  ; クリック(タッチ)あり : どれかが座標に入っているか
							repeat mtl_num
								mtinfo mti, mtl(cnt) : if mti(3)>=0 : mti(3)++
								_mx = mti(1) : _my = mti(2)
								if hittest_@modlaybtn(layobjIndex,focusedId, _mx, _my) {
									isAnyObjectHit = 1 : break
								}
							loop
						}
						if isAnyObjectHit {
							Set_mxy_@modlaybtn layobjIndex,focusedId, _mx, _my  ; 一応、座標を残す
						}else {
							// フォーカスされていたが、マウスがオブジェクト範囲外に出たとき
							Clear_flagBits_@modlaybtn layobjIndex,focusedId, FLAGBT_FOCUS  ; focusビットを下ろす
							focusedId = -1
						}
					}
				}
			}
			;; [フォーカス発生]
			if focusedId == -1 {
				if (dorekaFlags & FLAGBT_SHOWING)==0 && (dorekaFlags & FLAGBT_PUSHING)==0 {
					if SPmtiChanged {  ; マウス,タッチが変化している
						repeat bm(BMSCR_OBJMAX)
							if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
							if isLaybtnObj_@modlaybtn(layobjIndex,cnt) == 0 { continue }
							if groupId_@modlaybtn(layobjIndex,cnt) != groupId@_modlaybtn { continue }
							if flagBits_@modlaybtn(layobjIndex,cnt) & FLAGBT_OPTION_MOUSE_DISABLED { continue }  ; option[キー操作無効]ビットが立っているものはスキップ
							isAnyObjectHit = 0  ; マウス,タッチの座標がどれかのオブジェクト範囲内に入っているか
							if mtl_num == 0 {
								_mx = mousex : _my = mousey
								if hittest_@modlaybtn(layobjIndex,cnt, _mx, _my) {
									isAnyObjectHit = 1
								}
							}else {
								cn_ = cnt
								repeat mtl_num
									mtinfo mti, mtl(cnt) : if mti(3)>=0 : mti(3)++
									if mti(3) == -1 {
										// バグ(?)対処 : タッチとマウス両方で操作して変な感じになったとき、クリックしていなくてもmti(3)==-1が残り続けるバグがある(?)
										getkey mti(0), 1 : if mti(0) == 0 : break  ; クリックしていないなら判定しない
										mti(1) = mousex, mousey  ; mtinfo の mti(3)==-1 の mti(1),mti(2) はバグ(?)でデータが残り続けることがあるので上書きする
									}
									_mx = mti(1) : _my = mti(2)
									if hittest_@modlaybtn(layobjIndex,cn_, _mx, _my) {
										isAnyObjectHit = 1 : break
									}
								loop
							}
							if isAnyObjectHit {
								focusedId = cnt
								objsel focusedId  ; 改造objselによるフォーカス&focusビット立て (複数フォーカスすることがあるので)
								Set_mxy_@modlaybtn layobjIndex,focusedId, _mx, _my  ; 一応、座標を残す
								break
							}
						loop
					}
				}
			}
		}
		// 以下は、各ボタンの座標などを用いるため、グループ内1回だけでなくボタン個別に処理を行う
		// マウスまたはタッチによる[フォーカス、プッシュ、セレクト]
		if (dorekaFlags & FLAGBT_SHOWING)==0 && (option_mouseDisabled@_modlaybtn)==0 {
			;; [フォーカス] (上記の if wparam == yongestId {} 内でほとんど処理するようになった)
			// MOUSE_DRAG_IN_PRESSオプションがあるとき、カーソルのインアウトだけでPRESS_IN,PRESS_OUTみたいな処理をさせる
			if flagBits@_modlaybtn & FLAGBT_OPTION_MOUSE_DRAG_IN_PRESS {
				if SPmtiChanged && mtl_num > 0 {  ; マウス,タッチが変化している (mtlist取得可能)
					isAnyObjectHit = 0
					repeat mtl_num
						mtinfo mti, mtl(cnt) : if mti(3)>=0 : mti(3)++
						if mti(3) == -1 {
							// バグ(?)対処 : タッチとマウス両方で操作して変な感じになったとき、クリックしていなくてもmti(3)==-1が残り続けるバグがある(?)
							getkey mti(0), 1 : if mti(0) == 0 : break  ; クリックしていないなら判定しない
							mti(1) = mousex, mousey  ; mtinfo の mti(3)==-1 の mti(1),mti(2) はバグ(?)でデータが残り続けることがあるので上書きする
						}
						// 新規タッチでなくとも範囲内に入ったらFOCUS→PRESSさせたい
						if hittest@_modlaybtn(mti(1), mti(2)) {
							// オブジェクト範囲内だった
							isAnyObjectHit = 1 : break
						}
					loop
					if flagBits@_modlaybtn & FLAGBT_OPTION_MOUSE_DRAG_IN_PRESS_GROUP {  ; グループ内で先に他ボタンをタッチ中じゃないとヒットにしない
						if (dorekaFlags & FLAGBT_PUSHING)==0 : isAnyObjectHit = 0
					}
					if isAnyObjectHit {
						// オブジェクト範囲内に入っていた
						if focusedId == -1 : focusedId = wparam : objsel focusedId  ; 改造objselによるフォーカス&focusビット立て
						mx@_modlaybtn = mti(1) : my@_modlaybtn = mti(2)  ; 一応、座標を残す
						if (flagBits@_modlaybtn & FLAGBT_PUSHING)==0 {
							tx@_modlaybtn = mti(1) : ty@_modlaybtn = mti(2)  ; FLAGBT_PUSHING False → True のタッチ時
						}
						if option_mouseSelectOnPress@_modlaybtn {
							// マウスクリック即決定
							if (flagBits@_modlaybtn & FLAGBT_PUSHING_IN)==0 {
								Add_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED|(FLAGBT_SHOWOUTED*(option_keepVisible@_modlaybtn!=0)))  ; (pushing|pushingIn)ビットを立てる[optionでカウンタリセットも]
							}
						}else {
							mt_id@_modlaybtn = mti(3)  ; タッチした指IDを記憶
							if (flagBits@_modlaybtn & FLAGBT_PUSHING_IN)==0 {
								Add_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|(FLAGBT_SHOWOUTED*(option_keepVisible@_modlaybtn!=0)))  ; (pushing|pushingIn)ビットを立てる[optionでカウンタリセットも]
							}
						}
					}else {
						// オブジェクト範囲外だった
						if (flagBits@_modlaybtn & FLAGBT_OPTION_MOUSE_DRAG_OUT_PRESS_KEEP)==0 {  ; オプション : PRESS_INキープ
							if flagBits@_modlaybtn & FLAGBT_PUSHING_IN {
								Clear_flagBits@_modlaybtn FLAGBT_PUSHING_IN  ; pushingInビットを下ろす - (focus|pushing)ビットは指を離したときに任せる
							}
						}
					}
				}
			}
			;; [プッシュ、セレクト]
			if mt_id@_modlaybtn == 0 {
				// 指IDの記憶がない(非タッチ中)
				repeat mtl_num
					mtinfo mti, mtl(cnt) : if mti(3)>=0 : mti(3)++
					if mti(3) == -1 {
						// バグ(?)対処 : タッチとマウス両方で操作して変な感じになったとき、クリックしていなくてもmti(3)==-1が残り続けるバグがある(?)
						getkey mti(0), 1 : if mti(0) == 0 : continue  ; クリックしていないなら判定しない
						mti(1) = mousex, mousey  ; mtinfo の mti(3)==-1 の mti(1),mti(2) はバグ(?)でデータが残り続けることがあるので上書きする
					}
					flg_touch = 0  ; 前回のタッチ情報と比較して増えた指IDかどうか(新規タッチのみ見る)
					repeat mtis_num@_modlaybtn
						if mtis3@_modlaybtn(cnt) == mti(3) { flg_touch = 1 : break }
					loop
					if flg_touch { continue }
					// 新規タッチだった
					if hittest@_modlaybtn(mti(1), mti(2)) {
						// オブジェクト範囲内だった
						objsel wparam : focusedId = wparam  ; 改造objselによるフォーカス&focusビット立て
						mx@_modlaybtn = mti(1) : my@_modlaybtn = mti(2)  ; 一応、座標を残す
						if (flagBits@_modlaybtn & FLAGBT_PUSHING)==0 {
							tx@_modlaybtn = mti(1) : ty@_modlaybtn = mti(2)  ; FLAGBT_PUSHING False → True のタッチ時
						}
						if option_mouseSelectOnPress@_modlaybtn {
							// マウスクリック即決定
							Add_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED|(FLAGBT_SHOWOUTED*(option_keepVisible@_modlaybtn!=0)))  ; (pushing|pushingIn)ビットを立てる[optionでカウンタリセットも]
						}else {
							mt_id@_modlaybtn = mti(3)  ; タッチした指IDを記憶
							Add_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|(FLAGBT_SHOWOUTED*(option_keepVisible@_modlaybtn!=0)))  ; (pushing|pushingIn)ビットを立てる[optionでカウンタリセットも]
						}
					}
				loop
			}else {
				// 指IDの記憶がある(タッチ中)
				flg_touch = 0  ; まだタッチ中か離したかのフラグ(記憶したタッチ指IDが存在するか)
				repeat mtl_num
					mtinfo mti, mtl(cnt) : if mti(3)>=0 : mti(3)++
					if mti(3) == -1 {
						// バグ(?)対処 : タッチとマウス両方で操作して変な感じになったとき、クリックしていなくてもmti(3)==-1が残り続けるバグがある(?)
						getkey mti(0), 1 : if mti(0) == 0 : continue  ; クリックしていないなら判定しない
						mti(1) = mousex, mousey  ; mtinfo の mti(3)==-1 の mti(1),mti(2) はバグ(?)でデータが残り続けることがあるので上書きする
					}
					if mt_id@_modlaybtn != mti(3) { continue }  ; タッチした指IDと一致しない場合はスキップ
					// タッチ指IDから前回のxy座標を取得
					repeat mtis_num@_modlaybtn
						if mtis3@_modlaybtn(cnt) == mti(3) {
							px = mtis1@_modlaybtn(cnt) : py = mtis2@_modlaybtn(cnt)  ; 前回のxy座標
							if (flagBits@_modlaybtn & FLAGBT_OPTION_MOUSE_DRAG_OUT_PRESS_KEEP)==0 {  ; オプション : PRESS_INキープ
								// 前回は範囲外だったが、今回範囲内になったとき
								if hittest@_modlaybtn(px, py) {
								}else {
									if hittest@_modlaybtn(mti(1), mti(2)) {
										Add_flagBits@_modlaybtn FLAGBT_PUSHING_IN  ; オブジェクト範囲内に指が入っている = pushingInビットを立てる
									}
								}
								// 前回は範囲内だったが、今回範囲外になったとき
								if hittest@_modlaybtn(px, py) {
									if hittest@_modlaybtn(mti(1), mti(2)) {	
									}else {
										Clear_flagBits@_modlaybtn FLAGBT_PUSHING_IN  ; オブジェクト範囲内に指が出た = pushingInビットを下ろす
									}
								}
							}
							break
						}
					loop
					mx@_modlaybtn = mti(1) : my@_modlaybtn = mti(2)
					flg_touch = 1
				loop
				if flg_touch == 0 {  ; 指を離した(オブジェクト範囲内で指を離していたらそれをselectしたことになる)
					repeat mtis_num@_modlaybtn  ; 前回のタッチ情報から探してxy座標を取得
						if mtis3@_modlaybtn(cnt) == mt_id@_modlaybtn { mti(1) = mtis1@_modlaybtn(cnt), mtis2@_modlaybtn(cnt) : break }
					loop
					if hittest@_modlaybtn(mti(1), mti(2)) || (flagBits@_modlaybtn & FLAGBT_OPTION_MOUSE_DRAG_OUT_PRESS_KEEP)!=0 {  ; オプション : PRESS_INキープ
						// オブジェクト範囲内で指を離した
						Add_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED)  ; selectedビットを立てる : FLAGBT_OPTION_MOUSE_DRAG_IN_PRESSのとき、何故か範囲外としてpushingInを外されたのに、ここでselectedされることがある。selectedされたのならpushingInも居てもらう必要があるので(pushing|pushingIn)ビットも一緒にAddする
					}else {
						// オブジェクト範囲外で指を離した
						Clear_flagBits@_modlaybtn (FLAGBT_FOCUS|FLAGBT_PUSHING|FLAGBT_PUSHING_IN)  ; (focus|pushing|pushingIn)ビットを下ろす
					}
					mt_id@_modlaybtn = 0
					mx@_modlaybtn = mti(1) : my@_modlaybtn = mti(2)
				}
			}
			// 今回のタッチ情報を記憶しておく
			mtis_num@_modlaybtn = mtl_num
			repeat mtl_num
				mtinfo mti, mtl(cnt) : if mti(3)>=0 : mti(3)++
				mtis1@_modlaybtn(cnt) = mti(1)
				mtis2@_modlaybtn(cnt) = mti(2)
				mtis3@_modlaybtn(cnt) = mti(3)
			loop
		}
		
		// STATE遷移
		if (state@_modlaybtn & LAYBTN_COMPLETE) == 0 /* COMPLETEではない */ {
			// いつでもlast_runビットが立っていたら終了処理(COMPLETE)に移行したい
			if (flagBits@_modlaybtn & FLAGBT_LAST_RUN) {
				state@_modlaybtn = LAYBTN_COMPLETE + ((flagBits@_modlaybtn & FLAGBT_SELECTED)!=0)  ; COMPLETE + _SELECTED
				count@_modlaybtn = 0
			}else {
				if (state@_modlaybtn & LAYBTN_SHOW_OUT) == 0 /* まだSHOW_OUTでもない */ {
					// いつでもshowout_startビット(showout+showingビット)が立っていたら非表示処理(SHOW_OUT)に移行したい
					if (flagBits@_modlaybtn & (FLAGBT_SHOWING|FLAGBT_SHOWOUT)) == (FLAGBT_SHOWING|FLAGBT_SHOWOUT) {
						state@_modlaybtn = LAYBTN_SHOW_OUT + ((flagBits@_modlaybtn & FLAGBT_SELECTED)!=0)  ; SHOW_OUT + _SELECTED
						count@_modlaybtn = 0
					}
				}
			}
		}
		if state@_modlaybtn == LAYBTN_SHOW_IN {
			if count@_modlaybtn >= (p5@_modlaybtn) {
				if flagBits@_modlaybtn & FLAGBT_SHOWING {
					Clear_flagBits@_modlaybtn FLAGBT_SHOWING  ; showingビットを下ろす
				}
				if flagBits@_modlaybtn & FLAGBT_FOCUS {
					state@_modlaybtn = LAYBTN_FOCUS_IN  ; focusビットが立っていたらFOCUS_IN
					count@_modlaybtn = 0
				}
				if flagBits@_modlaybtn & FLAGBT_PUSHING_IN {
					state@_modlaybtn = LAYBTN_PRESS_IN  ; pushingビットが立っていたらPRESS_IN
					count@_modlaybtn = 0
				}
			}
		}
		if flagBits@_modlaybtn & FLAGBT_OPTION_FOCUS_PRESS_STOP {  ; [option] 他にフォーカスが移ったらFOCUS,PRESSアニメーション中でも強制停止
			switch state@_modlaybtn
			case LAYBTN_FOCUS_IN
			case LAYBTN_FOCUS_OUT
			case LAYBTN_PRESS_IN
			case LAYBTN_PRESS_IN_SELECTED
			case LAYBTN_PRESS_OUT
				if focusedId != -1 && focusedId != wparam {
					Clear_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED)  ; (pushing|pushingIn|selected)ビットを下ろして、この後PRESS_OUTになるようにする
					state@_modlaybtn = LAYBTN_SHOW_IN  ; SHOW_INのcountラストから
					count@_modlaybtn = (p5@_modlaybtn)
				}
				swbreak
			swend
		}
		if state@_modlaybtn == LAYBTN_FOCUS_IN {
			if count@_modlaybtn >= (p6@_modlaybtn) {
				if (flagBits@_modlaybtn & FLAGBT_FOCUS)==0 {
					state@_modlaybtn = LAYBTN_FOCUS_OUT  ; focusビットが外れていたらFOCUS_OUT
					count@_modlaybtn = 0  ; 通常0から
				}
			}else : if (flagBits@_modlaybtn & FLAGBT_OPTION_FOCUSOUT_IMMEDIATELY) != 0 {  ; オプション
				if (flagBits@_modlaybtn & FLAGBT_FOCUS)==0 {
					state@_modlaybtn = LAYBTN_FOCUS_OUT  ; focusビットが外れていたらFOCUS_OUT
					count@_modlaybtn = limit(p9@_modlaybtn - count@_modlaybtn, 0)  ; [option]フォーカスが外れたときに即FOCUS_OUTする
				}
			}
			if flagBits@_modlaybtn & FLAGBT_PUSHING_IN {
				state@_modlaybtn = LAYBTN_PRESS_IN  ; pushingビットが立っていたらPRESS_IN
				count@_modlaybtn = 0
			}
		}
		if state@_modlaybtn == LAYBTN_FOCUS_OUT {
			if count@_modlaybtn >= (p9@_modlaybtn) {
				if flagBits@_modlaybtn & FLAGBT_FOCUS {
					state@_modlaybtn = LAYBTN_FOCUS_IN  ; focusビットが立っていたら再FOCUS_IN
					count@_modlaybtn = 0
				}else {
					state@_modlaybtn = LAYBTN_SHOW_IN  ; focusビットが立っていなかったらSHOW_INのcountラストから
					count@_modlaybtn = (p5@_modlaybtn)
				}
			}else : if (flagBits@_modlaybtn & FLAGBT_OPTION_FOCUSOUT_IMMEDIATELY) != 0 {  ; オプション
				if flagBits@_modlaybtn & FLAGBT_FOCUS {
					state@_modlaybtn = LAYBTN_FOCUS_IN  ; focusビットが立っていたら再FOCUS_IN
					count@_modlaybtn = limit(p6@_modlaybtn - count@_modlaybtn, 0)  ; [option]フォーカスが外れたときに即FOCUS_OUTする
				}
			}
			if flagBits@_modlaybtn & FLAGBT_PUSHING_IN {
				state@_modlaybtn = LAYBTN_PRESS_IN  ; pushingビットが立っていたらPRESS_IN
				count@_modlaybtn = 0
			}
		}
		if state@_modlaybtn & LAYBTN_PRESS_IN {
			state@_modlaybtn = LAYBTN_PRESS_IN
			if option_keepVisible@_modlaybtn {  ; option[ボタン決定後非表示にしない]があるとき
				if flagBits@_modlaybtn & FLAGBT_SHOWOUTED {  ; カウンタリセットとしてshowoutedビット(借りビット)が立っていたら
					Clear_flagBits@_modlaybtn FLAGBT_SHOWOUTED  ; showoutedビットを下ろして
					count@_modlaybtn = 0  ; 最初からカウントさせる
				}
				if count@_modlaybtn >= (p7@_modlaybtn) {
					if (flagBits@_modlaybtn & FLAGBT_SELECTED)!=0 && prev_selected@_modlaybtn != 0 {  ; selectedビットが立っていて、かつ、prev_selectedビットも立つ、
						                                                                              ; つまりは前回、LAYBTN_PRESS_IN_SELECTED を投げた。今回は、
						Clear_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED)  ; (pushing|pushingIn|selected)ビットを下ろして、この後PRESS_OUTになるようにする
					}
				}
				if flagBits@_modlaybtn & FLAGBT_SELECTED {  ; selectedビットが立っていて
					if count@_modlaybtn == 0 || prev_selected@_modlaybtn == 0 {  ; countが0 または 前回selectedビットが立っていなかったら
						state@_modlaybtn |= 1  ; PRESS_IN_SELECTED
						if flagBits@_modlaybtn & FLAGBT_OPTION_KEEP_PRESS_ANIME {
							Add_flagBits@_modlaybtn FLAGBT_SHOWING
						}
					}
				}
				if flagBits@_modlaybtn & FLAGBT_OPTION_KEEP_PRESS_ANIME {  ; option[]
					if (flagBits@_modlaybtn & FLAGBT_SHOWING) == 0 {  ; 自分が決定したのではなく、
						if (dorekaFlags & FLAGBT_SHOWING) != 0 {      ; 他が_SHOWINGを立てていたら、
							Clear_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED)  ; 即PRESS_OUT即FOCUS_INへカウントに構わず遷移するように促す
							count@_modlaybtn = (p7@_modlaybtn)
						}
					}
				}
				// selectedビットが立っていたかを記憶
				if flagBits@_modlaybtn & FLAGBT_SELECTED {
					if prev_selected@_modlaybtn == 0 : Add_flagBits@_modlaybtn FLAGBT_CONDITION_PREV_SELECTED  ; [condition] prev_selected
				}else {
					if prev_selected@_modlaybtn != 0 : Clear_flagBits@_modlaybtn FLAGBT_CONDITION_PREV_SELECTED  ; [condition] prev_selected
				}
			}else {
				// カウンタリセット用のshowoutedビット(借りビット)が立つ可能性があるが、これはoption_keepVisible==1のときに使う。必要ないので下ろす
				Clear_flagBits@_modlaybtn FLAGBT_SHOWOUTED  ; showoutedビットを下ろす
			}
			if count@_modlaybtn >= (p7@_modlaybtn) {
				if (flagBits@_modlaybtn & FLAGBT_PUSHING_IN)==0 {
					state@_modlaybtn = LAYBTN_PRESS_OUT  ; pushingInビットが外れていたらPRESS_OUT
					count@_modlaybtn = 0
				}
				if flagBits@_modlaybtn & FLAGBT_SELECTED {  ; selectedビットが立っていたら
					if option_keepVisible@_modlaybtn == 0 {  ; option[ボタン決定後非表示にしない]が無いとき
						Add_flagBits@_modlaybtn FLAGBT_SHOWOUT  ; showoutビットを立ててSHOW_OUT開始(1つshowoutビットを立てたらグループ全体に伝播する)
					}
				}
			}
		}
		if state@_modlaybtn == LAYBTN_PRESS_OUT {
			if option_keepVisible@_modlaybtn {  ; option[ボタン決定後非表示にしない]があるとき
				if flagBits@_modlaybtn & FLAGBT_SHOWOUTED {  ; カウンタリセットとしてshowoutedビット(借りビット)が立っていたら
					Clear_flagBits@_modlaybtn FLAGBT_SHOWOUTED  ; showoutedビットを下ろして
					state@_modlaybtn = LAYBTN_PRESS_IN  ; 再PRESS_INして
					count@_modlaybtn = 0  ; 最初からカウントさせる
					if flagBits@_modlaybtn & FLAGBT_SELECTED {  ; selectedビットが立っていたら、count@_modlaybtn==0なので
						state@_modlaybtn |= 1  ; PRESS_IN_SELECTED
						if flagBits@_modlaybtn & FLAGBT_OPTION_KEEP_PRESS_ANIME {
							Add_flagBits@_modlaybtn FLAGBT_SHOWING
						}
					}
					// selectedビットが立っていたかを記憶
					if flagBits@_modlaybtn & FLAGBT_SELECTED {
						if prev_selected@_modlaybtn == 0 : Add_flagBits@_modlaybtn FLAGBT_CONDITION_PREV_SELECTED  ; [condition] prev_selected
					}else {
						if prev_selected@_modlaybtn != 0 : Clear_flagBits@_modlaybtn FLAGBT_CONDITION_PREV_SELECTED  ; [condition] prev_selected
					}
				}
				if flagBits@_modlaybtn & FLAGBT_OPTION_KEEP_PRESS_ANIME {  ; option[]
					if (flagBits@_modlaybtn & FLAGBT_SHOWING) == 0 {  ; 自分が決定したのではなく、
						if (dorekaFlags & FLAGBT_SHOWING) != 0 {      ; 他が_SHOWINGを立てていたら、
							Clear_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED)  ; 即PRESS_OUT即FOCUS_INへカウントに構わず遷移するように促す
							count@_modlaybtn = (p10@_modlaybtn)
						}
					}
				}
			}
			if count@_modlaybtn >= (p10@_modlaybtn) {
				if flagBits@_modlaybtn & FLAGBT_PUSHING_IN {
					state@_modlaybtn = LAYBTN_PRESS_IN  ; pushingInビットが立っていたら再PRESS_IN
					count@_modlaybtn = 0
				}else {
					if option_keepVisible@_modlaybtn && (flagBits@_modlaybtn & FLAGBT_OPTION_KEEP_RETURN_SHOW)!=0 {  ; option[]
						state@_modlaybtn = LAYBTN_SHOW_IN  ; pushingInビットが立ってなかったらSHOW_INのcountラストから
						count@_modlaybtn = (p5@_modlaybtn)
						Clear_flagBits@_modlaybtn FLAGBT_FOCUS
					}else {
						state@_modlaybtn = LAYBTN_FOCUS_IN  ; pushingInビットが立ってなかったらFOCUS_INのcountラストから
						count@_modlaybtn = (p6@_modlaybtn)
					}
					if flagBits@_modlaybtn & FLAGBT_OPTION_KEEP_PRESS_ANIME {
						Clear_flagBits@_modlaybtn FLAGBT_SHOWING
					}
				}
			}
			if option_keepVisible@_modlaybtn == 0 {  ; option[ボタン決定後非表示にしない]が無いとき
				if flagBits@_modlaybtn & FLAGBT_SELECTED {  ; selectedビットが立っていたら
					Add_flagBits@_modlaybtn FLAGBT_SHOWOUT  ; showoutビットを立ててSHOW_OUT開始(1つshowoutビットを立てたらグループ全体に伝播する)
				}
			}
		}
		if state@_modlaybtn & LAYBTN_SHOW_OUT {
			if count@_modlaybtn >= (p8@_modlaybtn) {
				if (flagBits@_modlaybtn & FLAGBT_SHOWOUTED)==0 {
					Add_flagBits@_modlaybtn FLAGBT_SHOWOUTED  ; showoutedビットを立てる
					Clear_flagBits@_modlaybtn FLAGBT_SHOWOUT  ; 保険でshowoutビットを下ろす[単体でlast_runビット((focus|selected)以外のすべてのビット)になってしまう可能性を潰す]
				}
			}
		}
		if state@_modlaybtn & LAYBTN_COMPLETE {
			count@_modlaybtn = 0
			layerbtn_stat@modlaybtn = state@_modlaybtn : layerbtn_cnt@modlaybtn = count@_modlaybtn
			layerbtn_mousex@modlaybtn = mx@_modlaybtn-objinfo_axis_x(wparam) : layerbtn_mousey@modlaybtn = my@_modlaybtn-objinfo_axis_y(wparam)
			layerbtn_clickx@modlaybtn = -1 : layerbtn_clicky@modlaybtn = -1
			gosub lb  ; オブジェクト削除前の objlayer_cmddraw のうちに COMPLETE を処理させる
			clrobj wparam,wparam  ; 自身のオブジェクトを削除
			dupptr ctx, objinfo(wparam, 17), 4*11
			ctx(10) = objlayer_cmddraw  ; lparamの上書き (HSP3Dish.jsではredraw内のlayerobj処理でlparamが変わらないため)
			Add_flagBits@_modlaybtn FLAGBT_CONDITION_TERMED  ; [option]termedビットを立てる : objlayer_cmdterm を1回だけ処理させるため(layerobjの中でclrobjしてる弊害)
		}
	}else {
		// disable時
		if flagBits@_modlaybtn & (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED) {
			Clear_flagBits@_modlaybtn (FLAGBT_PUSHING|FLAGBT_PUSHING_IN|FLAGBT_SELECTED)  ; (pushing|pushingIn|selected)ビットを下ろして、この後PRESS_OUTになるようにする
			state@_modlaybtn = LAYBTN_SHOW_IN  ; SHOW_INのcountラストから
			count@_modlaybtn = (p5@_modlaybtn)
		}
	}
	layerbtn_stat@modlaybtn = state@_modlaybtn | disable ^ disable : layerbtn_cnt@modlaybtn = count@_modlaybtn  ; disableのときは_SELECTEDを外す
	count@_modlaybtn++
	layerbtn_mousex@modlaybtn = mx@_modlaybtn-objinfo_axis_x(wparam) : layerbtn_mousey@modlaybtn = my@_modlaybtn-objinfo_axis_y(wparam)
	if flagBits@_modlaybtn & FLAGBT_PUSHING {
		layerbtn_clickx@modlaybtn = tx@_modlaybtn-objinfo_axis_x(wparam) : layerbtn_clicky@modlaybtn = ty@_modlaybtn-objinfo_axis_y(wparam)
	}else {
		layerbtn_clickx@modlaybtn = -1 : layerbtn_clicky@modlaybtn = -1
	}
	return

// cmdterm
#deffunc layerbutton_cmdterm@modlaybtn
	SET_LAYOBJVAR@modlaybtn wparam
	layobjIndex = stat
	// 同じグループの中で削除される最後のオブジェクトかどうか確認
	dupptr bm, objinfo_bmscr(wparam), (BMSCR_OBJMAX+1)*4
	count@_modlaybtn = 0
	repeat bm(BMSCR_OBJMAX)
		if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
		if isLaybtnObj_@modlaybtn(layobjIndex,cnt) == 0 { continue }
		if groupId_@modlaybtn(layobjIndex,cnt) != groupId@_modlaybtn { continue }
		count@_modlaybtn++
	loop
	state@_modlaybtn = 0
	layerbtn_stat@modlaybtn = ((count@_modlaybtn + TERMTRAP + acquired_termTrap) == 1) * LAYBTN_GROUP_DELETED  ; グループすべて削除されていたとき
	layerbtn_cnt@modlaybtn = (count@_modlaybtn + TERMTRAP + acquired_termTrap)
	if (count@_modlaybtn + TERMTRAP + acquired_termTrap) == 0 : acquired_termTrap = 1  ; 環境がイマイチ把握できないので後天的にTERMTRAPを機能させる(※ 最初の1回だけLAYBTN_GROUP_DELETEDがオブジェクト2つ残っているときに発動する)
	layerbtn_mousex@modlaybtn = mx@_modlaybtn-objinfo_axis_x(wparam) : layerbtn_mousey@modlaybtn = my@_modlaybtn-objinfo_axis_y(wparam)
	layerbtn_clickx@modlaybtn = -1 : layerbtn_clicky@modlaybtn = -1
	return

// layerbuttonのlayerobj割り込み処理を自前で行うためのredraw前にすべて描画させる処理
#deffunc layerbutton_redraw@modlaybtn int p1
	if (p1 & 1) == 0 : return
	GlobalFrame++ ; GlobalLastKey = 0
	// HSP3Dish.jsの場合、バグ回避のためこのredraw 1直前でオブジェクト数分描画repeatさせる <- グループの描画順やオブジェクト削除時の処理を踏まえ、Dish.jsでない場合にも採用する
	__layobjIndex = getLayobjverIndex@modlaybtn(ginfo_sel) : if __layobjIndex == -1 : return
	_pBmscr = pBmscr_@modlaybtn(__layobjIndex) : if _pBmscr == 0 : return  ; まだオブジェクト作ってない
	dupptr bm, _pBmscr, (BMSCR_OBJMAX+1)*4
	numIds_layobj = 0  ; オブジェクトが途中で削除されて描画回数が減る可能性があるので、先に数えておく
	;ids_layobj = 0
	numGropus_layobj = 0  ; グループ数
	;groups_layobj = 0
	flg_ctx = 0  ; lparam上書き用ctx取得フラグ
	repeat bm(BMSCR_OBJMAX)
		if (objinfo(cnt, 0)>>16) != 3 || ((objinfo(cnt, 0) & $FFFF) & $8000) == 0 { continue }  ; (layerobj | 同グループ) 以外はじく
		if isLaybtnObj_@modlaybtn(__layobjIndex,cnt) == 0 { continue }
		// layerobj ID
		ids_layobj(numIds_layobj) = cnt  ; layerobjのIDを保存
		numIds_layobj++
		// グループID
		groups_layobj(numGropus_layobj) = groupId_@modlaybtn(__layobjIndex,cnt)  ; グループIDを一旦末尾に保持
		numGropus_layobj++
		repeat numGropus_layobj - 1
			if groups_layobj(cnt) == groups_layobj(numGropus_layobj - 1) : numGropus_layobj-- : break  ; 既に同じグループIDを持っていたら、numを減らして末尾に入れたグループはなかったことにする
		loop
		if flg_ctx == 0 : flg_ctx=1 : dupptr ctx, objinfo(cnt, 17), 4*11  ; lparam上書きのためのctxを取得(オブジェクトが無いときはdupperしない)
	loop
	if numIds_layobj == 0 : return  ; layerobjが無いときは帰る

	// 初期化が必要な項目をここに混ぜさせてもらう
	if (LAYERBTN_KEY_REPEAT_FRAME@modlaybtn & $FFFF) <= 0 : LAYERBTN_KEY_REPEAT_FRAME@modlaybtn = 16				

	SPmtiChanged = 0
	// タッチ,マウス情報が変化したか確認
	mtlist mtl : mtl_num = stat  ; HSP3DISHではないとき用の改造済み
	if mae_mousex != mousex || mae_mousey != mousey : SPmtiChanged = 1
	if SPmtiChanged == 0 {
		repeat limit(mtl_num, 0, mae_mtis_num)
			mtinfo mti, mtl(cnt) : if mti(3)>=0 : mti(3)++
			if mae_mtis1(cnt) != mti(1) : SPmtiChanged = 1 : break
			if mae_mtis2(cnt) != mti(2) : SPmtiChanged = 1 : break
			if mae_mtis3(cnt) != mti(3) : SPmtiChanged = 1 : break
		loop
	}

	// グループIDをsortvalで小さい順に並べ替えるために、今回使わなかった配列部分はINT_MAXで埋める(dim使用回避)
	if numGropus_layobj > 1 {
		repeat length(groups_layobj)-numGropus_layobj, numGropus_layobj
			groups_layobj(cnt) = 2147483647
		loop
		sortval groups_layobj, 0  ; 小さい順にソート
	}
	// 各グループごとに描画
	repeat numGropus_layobj
		now_groupId = groups_layobj(cnt)  ; 現在のグループID

		// まず、同じグループの中で各種フラグやオプションを取得
		yongestId = -1 : focusedId = -1
		dorekaFlags = 0 : subeteFlags = -1 : SPdorekaFlags = 0
		hasMultiGroups = 0 : disableKeyInput = 0
		repeat numIds_layobj
			if (objinfo(ids_layobj(cnt), 0)>>16) != 3 || ((objinfo(ids_layobj(cnt), 0) & $FFFF) & $8000) == 0 { continue }  ; 途中で削除されていたらスキップ
			SPdorekaFlags |= flagBits_@modlaybtn(__layobjIndex,ids_layobj(cnt))
			// 異なるグループでfocusを持っていた場合はdisableKeyInputでフラグを立ててフォーカス等の処理をさせない
			if groupId_@modlaybtn(__layobjIndex,ids_layobj(cnt)) != now_groupId {
				if (flagBits_@modlaybtn(__layobjIndex,ids_layobj(cnt)) & FLAGBT_CONDITION_DISABLE) == 0 && (flagBits_@modlaybtn(__layobjIndex,ids_layobj(cnt)) & (FLAGBT_OPTION_MOUSE_DISABLED|FLAGBT_OPTION_KEY_DISABLE)) != (FLAGBT_OPTION_MOUSE_DISABLED|FLAGBT_OPTION_KEY_DISABLE) {  ; disableビットが立っていなくて、(+キーもマウスも無効で)
					hasMultiGroups = 1
					// 他グループがfocusを持っている場合はキー入力を受け付けなくしたい
					if flagBits_@modlaybtn(__layobjIndex,ids_layobj(cnt)) & FLAGBT_FOCUS { disableKeyInput = 1 }
				}
				continue
			}
			// 同じグループだった
			if flagBits_@modlaybtn(__layobjIndex,ids_layobj(cnt)) & FLAGBT_FOCUS { focusedId = ids_layobj(cnt) }  ; focusビット確認(objselによって立てられる)
			dorekaFlags |= flagBits_@modlaybtn(__layobjIndex,ids_layobj(cnt))
			subeteFlags &= flagBits_@modlaybtn(__layobjIndex,ids_layobj(cnt))
		loop
	
		// 各グループごとの若い順にcmddrawを呼び出す
		repeat numIds_layobj
			if (objinfo(ids_layobj(cnt), 0)>>16) != 3 || ((objinfo(ids_layobj(cnt), 0) & $FFFF) & $8000) == 0 { continue }  ; 途中で削除されていたらスキップ
			if now_groupId != groupId_@modlaybtn(__layobjIndex,ids_layobj(cnt)) { continue }  ; 現在のグループIDと違う場合はスキップ
			if yongestId == -1 : yongestId = ids_layobj(cnt)  ; グループの中で一番若いID
			Get_lobjlabel_@modlaybtn __layobjIndex, ids_layobj(cnt), lobj_lb  ; layerobjにセットしたラベルを取得
			if lparam != objlayer_cmddraw : ctx(10) = objlayer_cmddraw  ; lparam上書き
			ctx(9) = ids_layobj(cnt)  ; wparam上書き
			ctx(8) = objinfo(ids_layobj(cnt), 16)  ; iparam上書き
			gosub lobj_lb
		loop
	loop
	// タッチ,マウス情報の記憶
	;mtlist mtl : mtl_num = stat  ; HSP3DISHではないとき用の改造済み
	mae_mtis_num = mtl_num
	repeat mtl_num
		mtinfo mti, mtl(cnt) : if mti(3)>=0 : mti(3)++
		mae_mtis1(cnt) = mti(1)
		mae_mtis2(cnt) = mti(2)
		mae_mtis3(cnt) = mti(3)
	loop
	mae_mousex = mousex : mae_mousey = mousey
	// 
	layerbtn_stickVar@modlaybtn = 0
	return

// layerobj のあと、statにオブジェクトIDがセットされない環境があるので代入してしまう
#deffunc SetStat@modlaybtn int p1
	return p1

// layerbutton命令 : layerobjで簡易アニメーションボタンを作成する命令
; p1,p2 : ボタンサイズ
; p3 : id
; p4 : group
; p5 : SHOW_IN_FRAME
; p6 : FOCUS_IN_FRAME
; p7 : PRESS_IN_FRAME
; p8 : SHOW_OUT_FRAME
; p9 : FOCUS_OUT_FRAME
; p10 : PRESS_OUT_FRAME
#define global layerbutton(%1,%2,%3=0, %4=0,%5=0,%6=0,%7=0,%8=0,%9=0,%10=0) %tmodlaybtn if(1):p1@modlaybtn=%1:p2@modlaybtn=%2:p3@modlaybtn=%3:p4@modlaybtn=%4:p5@modlaybtn=%5:p6@modlaybtn=%6:p7@modlaybtn=%7:p8@modlaybtn=%8:p9@modlaybtn=%9:p10@modlaybtn=%10}:wp@modlaybtn=wparam:lp@modlaybtn=lparam:ip@modlaybtn=iparam:layerobj p1@modlaybtn,p2@modlaybtn,3+256,*%i,p3@modlaybtn:\
SetStat@modlaybtn wparam:dupptr ctx,objinfo(stat,17),4*11:ctx(8)=ip@modlaybtn,wp@modlaybtn,lp@modlaybtn:\
if(0){ :\
*%p _ISR :\
	if lparam == objlayer_cmdinit { :\
		layerbutton_cmdinit@modlaybtn p4@modlaybtn,p5@modlaybtn,p6@modlaybtn,p7@modlaybtn,p8@modlaybtn,p9@modlaybtn,p10@modlaybtn, *%p _DRAW, *%p _LOBJ :\
		return :\
	} :\
	if lparam == objlayer_cmddraw { :\
		layerbutton_cmddraw@modlaybtn *%p _TERM :\
		return :\
	} :\
	if lparam == objlayer_cmdterm { :\
		layerbutton_cmdterm@modlaybtn :\
		return :\
	} :\
	return :\
} :\
if(0):*%p:if lparam==objlayer_cmddraw:return:else:*%p _LOBJ:gosub *%p _ISR:*%p _TERM:if(flagBits@_modlaybtn & FLAGBT_CONDITION_TERMED@modlaybtn):return:else :gosub drawlabel@_modlaybtn:return:*%p _DRAW:if(1){ %o0

// layerbutton用オプション設定命令
;  p1 : キーボード / 1)キー入力によるフォーカス移動をしない, 2)[キー入力はさせるが]最初にフォーカスが無いときキー入力でフォーカスを発生させない (そもそも、複数グループが表示されているときはフォーカススタートしないけど)
;  p2 : マウス / 1)マウスによる操作をさせない、2)マウスクリックで即Selectedする
;  p3 : 表示処理 /  1)ボタンを押した後に非表示処理させない, 2)FOCUS_IN中にフォーカスが外れたときFOCUS_INの表示時間を待たずに即FOCUS_OUTする[laybtn_cntがカウントの途中(focus_out表示時間-フォーカスが外れた時の_cnt)から始まります。focus_inとfocus_outの表示時間を同じにしないとシームレスにつながらなくなるので注意してください。]
#deffunc laybtn_settings int _p1, int _p2, int _p3
	if lparam != 1 : return
	SET_LAYOBJVAR@modlaybtn wparam
	layobjIndex = stat
	// laybtn_settingsによるパラメータ設定
	;;; キー入力
	// キーによるフォーカス移動をしない
	if _p1 & 1 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEY_DISABLE
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEY_DISABLE
	}
	// キーによるフォーカススタートをしない
	if _p1 & 2 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_FOCUS_START
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_FOCUS_START
	}
	// キーによるWASD移動をしない
	if _p1 & 4 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_WASD
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_WASD
	}
	// キーによる上下左右移動をしない
	if _p1 & 8 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_ULDR
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_ULDR
	}
	// キーによるスペースキー決定をしない
	if _p1 & 16 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_SPACE
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_SPACE
	}
	// キーによるエンターキー決定をしない
	if _p1 & 32 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_ENTER
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEY_NO_ENTER
	}
	// キーリピートを有効にする
	if _p1 & 64 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEY_REPEAT
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEY_REPEAT
	}

	;;; マウス操作
	// マウスによる操作をさせない
	if _p2 & 1 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_DISABLED
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_DISABLED
	}
	// マウスクリックで即Selectedする
	if _p2 & 2 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_SELECT_ON_PRESS
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_SELECT_ON_PRESS
	}
	// 範囲外マウスクリックでもドラッグして中に入れれば押したことにする
	if _p2 & 4 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_DRAG_IN_PRESS
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_DRAG_IN_PRESS
	}
	// 範囲外マウスクリックでもドラッグして中に入れれば押したことにする(すでにグループでタッチスタートしていた場合のみ)
	if _p2 & 8 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_DRAG_IN_PRESS_GROUP
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_DRAG_IN_PRESS_GROUP
	}
	// 一度マウスクリックしたらPRESS_INをキープ
	if _p2 & 16 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_DRAG_OUT_PRESS_KEEP
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_MOUSE_DRAG_OUT_PRESS_KEEP
	}
	
	;;; 表示関係
	// ボタンを押した後に非表示処理させない
	if _p3 & 1 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEEP_VISIBLE
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEEP_VISIBLE
	}
	// ボタンを押した後に非表示処理させない とき、ボタン決定後PRESS_IN,_OUT表示しきるまで他ボタンをフォーカスしたり押したりできないようにする
	if _p3 & 2 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEEP_PRESS_ANIME
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEEP_PRESS_ANIME
	}
	// ボタンを押した後に非表示処理させない とき、ボタン決定後SHOW_INまで戻す
	if _p3 & 4 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_KEEP_RETURN_SHOW
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_KEEP_RETURN_SHOW
	}
	// 他にフォーカスが移ったときにアニメーション強制停止
	if _p3 & 8 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_FOCUS_PRESS_STOP
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_FOCUS_PRESS_STOP
	}
	// フォーカスが外れたときに即FOCUS_OUTする
	if _p3 & 16 {
		Add_flagBits@_modlaybtn FLAGBT_OPTION_FOCUSOUT_IMMEDIATELY
	}else {
		Clear_flagBits@_modlaybtn FLAGBT_OPTION_FOCUSOUT_IMMEDIATELY
	}
	return

#define global laybtn_hitarea(%1=1,%2=0,%3=0,%4=0,%5=0,%6=0,%7=0,%8=0,%9=0,%10=0,%11=0,%12=0,%13=0,%14=0,%15=0,%16=0) laybtn_hitarea@modlaybtn %1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14,%15,%16
#deffunc laybtn_hitarea@modlaybtn int nn, int _p1, int _p2, int _p3, int _p4, double __p5, int _p6, int _p7, int _p8, int _p9, int _p10, int _p11, int _p12, int _p13, int _p14, int _p15, int _p16
	if lparam != 1 : return
	_p5 = int(__p5)
	SET_LAYOBJVAR@modlaybtn wparam
	layobjIndex = stat
	if nn >= 0 {
		// 多角形
		hitxy_num@_modlaybtn = limit(nn, 0, 8)
		SET_LAYOBJVAR@modlaybtn wparam  ; hitxy_num != 0 のとき、変数をdupしてもらえる
		layobjIndex = stat
		hitxy1@_modlaybtn = (_p2<<16) | (_p1&$FFFF)
		hitxy2@_modlaybtn = (_p4<<16) | (_p3&$FFFF)
		hitxy3@_modlaybtn = (_p6<<16) | (_p5&$FFFF)
		hitxy4@_modlaybtn = (_p8<<16) | (_p7&$FFFF)
		hitxy5@_modlaybtn = (_p10<<16) | (_p9&$FFFF)
		hitxy6@_modlaybtn = (_p12<<16) | (_p11&$FFFF)
		hitxy7@_modlaybtn = (_p14<<16) | (_p13&$FFFF)
		hitxy8@_modlaybtn = (_p16<<16) | (_p15&$FFFF)
	}else : if nn == -1 {
		// 円形
		hitxy_num@_modlaybtn = nn
		SET_LAYOBJVAR@modlaybtn wparam  ; hitxy_num != 0 のとき、変数をdupしてもらえる
		layobjIndex = stat
		hitxy1@_modlaybtn = (_p2<<16) | (_p1&$FFFF)
		hitxy2@_modlaybtn = (_p3&$FFFF)
	}else : if nn == -3 {
		// 長方形角度付き
		hitxy_num@_modlaybtn = nn
		SET_LAYOBJVAR@modlaybtn wparam  ; hitxy_num != 0 のとき、変数をdupしてもらえる
		layobjIndex = stat
		__p5_ = __p5
		hitxy1@_modlaybtn = (_p2<<16) | (_p1&$FFFF)
		hitxy2@_modlaybtn = (_p4<<16) | (_p3&$FFFF)
		hitxy3@_modlaybtn = lpeek(__p5_,0)
		hitxy4@_modlaybtn = lpeek(__p5_,4)
	}else : if nn == -4 {
		// カプセル形
		hitxy_num@_modlaybtn = nn
		SET_LAYOBJVAR@modlaybtn wparam  ; hitxy_num != 0 のとき、変数をdupしてもらえる
		layobjIndex = stat
		hitxy1@_modlaybtn = (_p2<<16) | (_p1&$FFFF)
		hitxy2@_modlaybtn = (_p3&$FFFF)
		hitxy3@_modlaybtn = (_p5<<16) | (_p4&$FFFF)
		hitxy4@_modlaybtn = (_p6&$FFFF)
		hitxy5@_modlaybtn = (_p8<<16) | (_p7&$FFFF)
		hitxy6@_modlaybtn = (_p9&$FFFF)
		hitxy7@_modlaybtn = (_p11<<16) | (_p10&$FFFF)
		hitxy8@_modlaybtn = (_p12&$FFFF)
	}else : if nn == -2 {
		// 楕円形角度付き
		hitxy_num@_modlaybtn = nn
		SET_LAYOBJVAR@modlaybtn wparam  ; hitxy_num != 0 のとき、変数をdupしてもらえる
		layobjIndex = stat
		__p5_ = __p5
		hitxy1@_modlaybtn = (_p2<<16) | (_p1&$FFFF)
		hitxy2@_modlaybtn = (_p4<<16) | (_p3&$FFFF)
		hitxy3@_modlaybtn = lpeek(__p5_,0)
		hitxy4@_modlaybtn = lpeek(__p5_,4)
	}
	return
#defcfunc hittest@_modlaybtn int hitx, int hity
	if hitxy_num@_modlaybtn == 0 {
		return ( objinfo_axis_x(wparam)<=hitx && hitx<objinfo_axis_x(wparam)+objinfo_size_x(wparam) && objinfo_axis_y(wparam)<=hity && hity<objinfo_axis_y(wparam)+objinfo_size_y(wparam) )
	}else : if hitxy_num@_modlaybtn > 0 {
		// 多角形
		repeat 1
			_pxy(0) = objinfo_axis_x(wparam)+(hitxy1@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy1@_modlaybtn>>16)
			if hitxy_num@_modlaybtn == 1 : break
			_pxy(2) = objinfo_axis_x(wparam)+(hitxy2@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy2@_modlaybtn>>16)
			if hitxy_num@_modlaybtn == 2 : break
			_pxy(4) = objinfo_axis_x(wparam)+(hitxy3@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy3@_modlaybtn>>16)
			if hitxy_num@_modlaybtn == 3 : break
			_pxy(6) = objinfo_axis_x(wparam)+(hitxy4@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy4@_modlaybtn>>16)
			if hitxy_num@_modlaybtn == 4 : break
			_pxy(8) = objinfo_axis_x(wparam)+(hitxy5@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy5@_modlaybtn>>16)
			if hitxy_num@_modlaybtn == 5 : break
			_pxy(10) = objinfo_axis_x(wparam)+(hitxy6@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy6@_modlaybtn>>16)
			if hitxy_num@_modlaybtn == 6 : break
			_pxy(12) = objinfo_axis_x(wparam)+(hitxy7@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy7@_modlaybtn>>16)
			if hitxy_num@_modlaybtn == 7 : break
			_pxy(14) = objinfo_axis_x(wparam)+(hitxy8@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy8@_modlaybtn>>16)
		loop
		return in_polygon@modlaybtn(hitxy_num@_modlaybtn, _pxy, hitx, hity)
	}else : if hitxy_num@_modlaybtn == -1 {
		// 円形
		return in_circle@modlaybtn(objinfo_axis_x(wparam)+(hitxy1@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy1@_modlaybtn>>16), (hitxy2@_modlaybtn<<16>>16), hitx, hity)
	}else : if hitxy_num@_modlaybtn == -3 {
		// 長方形角度付き
		return in_rect_ang@modlaybtn(objinfo_axis_x(wparam)+(hitxy1@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy1@_modlaybtn>>16), (hitxy2@_modlaybtn<<16>>16),(hitxy2@_modlaybtn>>16), hitxy3@_modlaybtn, hitxy4@_modlaybtn, hitx, hity)
	}else : if hitxy_num@_modlaybtn == -4 {
		// カプセル形
		if in_capsule@modlaybtn(objinfo_axis_x(wparam)+(hitxy1@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy1@_modlaybtn>>16), (hitxy2@_modlaybtn<<16>>16), objinfo_axis_x(wparam)+(hitxy3@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy3@_modlaybtn>>16), (hitxy4@_modlaybtn<<16>>16), hitx, hity) : return 1
		if (hitxy6@_modlaybtn<<16>>16) == 0 : return 0
		if in_capsule@modlaybtn(objinfo_axis_x(wparam)+(hitxy3@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy3@_modlaybtn>>16), (hitxy4@_modlaybtn<<16>>16), objinfo_axis_x(wparam)+(hitxy5@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy5@_modlaybtn>>16), (hitxy6@_modlaybtn<<16>>16), hitx, hity) : return 1
		if (hitxy8@_modlaybtn<<16>>16) == 0 : return 0
		if in_capsule@modlaybtn(objinfo_axis_x(wparam)+(hitxy5@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy5@_modlaybtn>>16), (hitxy6@_modlaybtn<<16>>16), objinfo_axis_x(wparam)+(hitxy7@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy7@_modlaybtn>>16), (hitxy8@_modlaybtn<<16>>16), hitx, hity) : return 1
		return 0
	}else : if hitxy_num@_modlaybtn == -2 {
		// 楕円形角度付き
		return in_ellipse_ang@modlaybtn(objinfo_axis_x(wparam)+(hitxy1@_modlaybtn<<16>>16), objinfo_axis_y(wparam)+(hitxy1@_modlaybtn>>16), (hitxy2@_modlaybtn<<16>>16),(hitxy2@_modlaybtn>>16), hitxy3@_modlaybtn, hitxy4@_modlaybtn, hitx, hity)
	}
	return 0
#defcfunc hittest_@modlaybtn int id, int wp, int hitx, int hity
	_hitxy_num = hitxy_num_@modlaybtn(id,wp)
	if _hitxy_num == 0 {
		return ( objinfo_axis_x(wp)<=hitx && hitx<objinfo_axis_x(wp)+objinfo_size_x(wp) && objinfo_axis_y(wp)<=hity && hity<objinfo_axis_y(wp)+objinfo_size_y(wp) )
	}else : if _hitxy_num > 0 {
		dups_hitxy_@modlaybtn id, wp
		repeat 1
			_pxy(0) = objinfo_axis_x(wp)+(hitxy1_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy1_@modlaybtn>>16)
			if _hitxy_num == 1 : break
			_pxy(2) = objinfo_axis_x(wp)+(hitxy2_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy2_@modlaybtn>>16)
			if _hitxy_num == 2 : break
			_pxy(4) = objinfo_axis_x(wp)+(hitxy3_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy3_@modlaybtn>>16)
			if _hitxy_num == 3 : break
			_pxy(6) = objinfo_axis_x(wp)+(hitxy4_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy4_@modlaybtn>>16)
			if _hitxy_num == 4 : break
			_pxy(8) = objinfo_axis_x(wp)+(hitxy5_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy5_@modlaybtn>>16)
			if _hitxy_num == 5 : break
			_pxy(10) = objinfo_axis_x(wp)+(hitxy6_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy6_@modlaybtn>>16)
			if _hitxy_num == 6 : break
			_pxy(12) = objinfo_axis_x(wp)+(hitxy7_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy7_@modlaybtn>>16)
			if _hitxy_num == 7 : break
			_pxy(14) = objinfo_axis_x(wp)+(hitxy8_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy8_@modlaybtn>>16)
		loop
		return in_polygon@modlaybtn(_hitxy_num, _pxy, hitx, hity)
	}else : if _hitxy_num == -1 {
		// 円形
		dups_hitxy_@modlaybtn id, wp
		return in_circle@modlaybtn(objinfo_axis_x(wp)+(hitxy1_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy1_@modlaybtn>>16), (hitxy2_@modlaybtn<<16>>16), hitx, hity)
	}else : if _hitxy_num == -3 {
		// 長方形角度付き
		dups_hitxy_@modlaybtn id, wp
		return in_rect_ang@modlaybtn(objinfo_axis_x(wp)+(hitxy1_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy1_@modlaybtn>>16), (hitxy2_@modlaybtn<<16>>16),(hitxy2_@modlaybtn>>16), hitxy3_@modlaybtn, hitxy4_@modlaybtn, hitx, hity)
	}else : if _hitxy_num == -4 {
		// カプセル形
		dups_hitxy_@modlaybtn id, wp
		if in_capsule@modlaybtn(objinfo_axis_x(wp)+(hitxy1_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy1_@modlaybtn>>16), (hitxy2_@modlaybtn<<16>>16), objinfo_axis_x(wp)+(hitxy3_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy3_@modlaybtn>>16), (hitxy4_@modlaybtn<<16>>16), hitx, hity) : return 1
		if (hitxy6_@modlaybtn<<16>>16) == 0 : return 0
		if in_capsule@modlaybtn(objinfo_axis_x(wp)+(hitxy3_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy3_@modlaybtn>>16), (hitxy4_@modlaybtn<<16>>16), objinfo_axis_x(wp)+(hitxy5_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy5_@modlaybtn>>16), (hitxy6_@modlaybtn<<16>>16), hitx, hity) : return 1
		if (hitxy8_@modlaybtn<<16>>16) == 0 : return 0
		if in_capsule@modlaybtn(objinfo_axis_x(wp)+(hitxy5_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy5_@modlaybtn>>16), (hitxy6_@modlaybtn<<16>>16), objinfo_axis_x(wp)+(hitxy7_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy7_@modlaybtn>>16), (hitxy8_@modlaybtn<<16>>16), hitx, hity) : return 1
		return 0
	}else : if _hitxy_num == -2 {
		// 楕円形角度付き
		dups_hitxy_@modlaybtn id, wp
		return in_ellipse_ang@modlaybtn(objinfo_axis_x(wp)+(hitxy1_@modlaybtn<<16>>16), objinfo_axis_y(wp)+(hitxy1_@modlaybtn>>16), (hitxy2_@modlaybtn<<16>>16),(hitxy2_@modlaybtn>>16), hitxy3_@modlaybtn, hitxy4_@modlaybtn, hitx, hity)
	}
	return 0
#defcfunc in_polygon@modlaybtn int nn, array pxy, int hitx, int hity
	inside = 0
	repeat nn
		i = cnt
		j = (i + 1) \ nn
		xi = pxy(i*2) : yi = pxy(i*2+1)
		xj = pxy(j*2) : yj = pxy(j*2+1)
		dx = xj - xi
		dy = yj - yi
		dx1 = hitx - xi
		dy1 = hity - yi
		if (dx*dy1 - dy*dx1 == 0) {
			if ((dx1*dx >= 0) && (dx1*dx <= dx*dx) && (dy1*dy >= 0) && (dy1*dy <= dy*dy)) {
				inside = 1 : break
			}
		}
		if ((yi > hity) != (yj > hity)) {
			dx2 = xj - xi
			dy2 = yj - yi
			if (dy2 > 0) {
				if (dx1 * dy2 < dx2 * dy1) { inside = inside ^ 1 }
			} else {
				if (dx1 * dy2 > dx2 * dy1) { inside = inside ^ 1 }
			}
		}
	loop
	return inside
#defcfunc in_circle@modlaybtn int _cx, int _cy, int _d, int hitx, int hity
    dx = hitx - _cx
    dy = hity - _cy
    rr = _d/2 * _d/2
	return (dx*dx + dy*dy <= rr)
#defcfunc in_ellipse@modlaybtn int _cx, int _cy, int _w, int _h, int hitx, int hity
    dx = hitx - _cx
    dy = hity - _cy
    return ( double(dx*dx) * _h*_h *4 + double(dy*dy) * _w*_w *4 <= double(_w*_w) * _h*_h )
#defcfunc in_ellipse_ang@modlaybtn int _cx, int _cy, int _w, int _h, int ang1, int ang2, int hitx, int hity
	ang = 0.0 : lpoke ang,0,ang1 : lpoke ang,4,ang2
	if ang == 0.0 {
		return in_ellipse@modlaybtn(_cx,_cy,_w,_h,hitx,hity)
	}
    dx = hitx - _cx
    dy = hity - _cy
    cc = cos(ang)
    ss = sin(ang)
    xx_ = cc * dx + ss * dy
    yy_ = ss *-dx + cc * dy
    return (xx_*xx_ * _h*_h *4 + yy_*yy_ * _w*_w *4 <= double(_w)*_w * _h*_h)
#defcfunc in_rect_ang@modlaybtn int _cx, int _cy, int _w, int _h, int ang1, int ang2, int hitx, int hity
	ang = 0.0 : lpoke ang,0,ang1 : lpoke ang,4,ang2
    cosA = cos(ang)
    sinA = sin(ang)
    dx = double(hitx - _cx)
    dy = double(hity - _cy)
    lx = dx * cosA + dy * sinA
    ly = -dx * sinA + dy * cosA
    return (absf(lx) <= (double(_w) / 2.0) && absf(ly) <= (double(_h) / 2.0))
#defcfunc in_capsule@modlaybtn int cx1, int cy1, int r1, int cx2, int cy2, int r2, int hitx, int hity
    dx = hitx - cx1 : dy = hity - cy1
    if ( double(dx)*dx + double(dy)*dy <= double(r1)*r1/4 ) : return 1
    dx = hitx - cx2 : dy = hity - cy2
    if ( double(dx)*dx + double(dy)*dy <= double(r2)*r2/4 ) : return 1
    vx = cx2 - cx1 : vy = cy2 - cy1
    wx = hitx  - cx1 : wy = hity  - cy1
    len2  = double(vx)*vx + double(vy)*vy
    if ( len2 <= 0.0 ) : return 0
    nn_   = double(vx)*wx + double(vy)*wy
    if ( nn_ <= 0.0 ) : return 0
    if ( nn_ >= len2 ) : return 0
    cross = double(vx)*wy - double(vy)*wx
    left  = cross*cross * len2
    term  = double(r1)*len2/2 + double(r2-r1)*nn_/2
    right = term*term
    return ( left <= right )

// stat, cnt
#define global layerbtn_stat layerbtn_stat@modlaybtn
#define global layerbtn_cnt layerbtn_cnt@modlaybtn
#define global layerbtn_mousex layerbtn_mousex@modlaybtn
#define global layerbtn_mousey layerbtn_mousey@modlaybtn
#define global layerbtn_clickx layerbtn_clickx@modlaybtn
#define global layerbtn_clicky layerbtn_clicky@modlaybtn
#define global layerbtn_stickVar layerbtn_stickVar@modlaybtn

// 簡単描画 : celput利用
#define global laybtn_ezcel(%1=1,%2=0,%3="",%4=0,%5=0,%6=0,%7=0,%8=0,%9=0,%10=0,%11=-1.0,%12=-1.0) laybtn_ezcel@modlaybtn %1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12
#deffunc laybtn_ezcel@modlaybtn int id, int fi, str wd, int tp, int zx1, int zy1, int zx2, int zy2, int zx3, int zy3, double rx1, double ry1
;  id  : celloadした画像素材を持つウインドウID
;  fi  : 分割画像No.先頭値(fi+0〜fi+2までを使います)
;  wd  : 表示する文字列
;  tp  : mesオプション
;  zx1 : 中心から文字をずらす量(x方向)
;  zy1 : 中心から文字をずらす量(y方向)
;  zx2 : ボタンを押し込んだ時に文字をずらす量(x方向)
;  zy2 : ボタンを押し込んだ時に文字をずらす量(y方向)
;  zx3 : ボタン画像ずらし量(x方向) [裏技]
;  zy3 : ボタン画像ずらし量(y方向) [裏技]
;  rx1 : ボタンサイズによらず表示倍率を強制的に指定(x方向) [裏技]
;  ry1 : ボタンサイズによらず表示倍率を強制的に指定(y方向) [裏技]
	if lparam != objlayer_cmddraw : return
	getCelSize@modlaybtn id, celx, cely, celofsx, celofsy, celmax
	if tp & 16 : getGMdata@modlaybtn gm, gf
	if rx1 != -1.0 : if objlayer_size_x!=0 && rx1!=0.0 : celofsx += double(objlayer_size_x)/2/rx1 - celofsx : celx = double(objlayer_size_x) / rx1
	if ry1 != -1.0 : if objlayer_size_x!=0 && rx1!=0.0 : celofsy += double(objlayer_size_y)/2/ry1 - celofsy : cely = double(objlayer_size_y) / ry1
	// ボタン状態で分岐
	switch layerbtn_stat
	case LAYBTN_SHOW_IN
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,laybtn_ease(0, 256) : celput id, limit(fi+0,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		if tp & 16 : gmode gm,,,gf
		if layerbtn_cnt >= SHOW_IN_FRAME@modlaybtn/5 : laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3  ; フェードの途中から表示させる
		swbreak
	case LAYBTN_FOCUS_IN
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,limit((256-laybtn_ease(0,256))*10,0,256) : celput id, limit(fi+0,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,laybtn_ease(0,256) : celput id, limit(fi+1,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		if tp & 16 : gmode gm,,,gf
		laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		swbreak
	case LAYBTN_FOCUS_OUT
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,limit((256-laybtn_ease(0,256))*10,0,256) : celput id, limit(fi+1,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,laybtn_ease(0,256) : celput id, limit(fi+0,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		if tp & 16 : gmode gm,,,gf
		laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		swbreak
	case LAYBTN_PRESS_IN
	case LAYBTN_PRESS_IN_SELECTED
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,limit((256-laybtn_ease(0,256))*5,0,256) : celput id, limit(fi+1,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,laybtn_ease(0,256) : celput id, limit(fi+2,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		if tp & 16 : gmode gm,,,gf
		if layerbtn_cnt < PRESS_IN_FRAME@modlaybtn/5 {  ; それっぽいタイミングで移動させる
			laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		}else {
			laybtn_mes wd,tp, 1,1, zx1+zx2+zx3,zy1+zy2+zy3
		}
		swbreak
	case LAYBTN_PRESS_OUT
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,limit((256-laybtn_ease(0,256))*5,0,256) : celput id, limit(fi+2,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		gmode 3,,,laybtn_ease(0,256) : celput id, limit(fi+1,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
		if tp & 16 : gmode gm,,,gf
		if layerbtn_cnt < PRESS_OUT_FRAME@modlaybtn/5 {  ; それっぽいタイミングで移動させる
			laybtn_mes wd,tp, 1,1, zx1+zx2+zx3,zy1+zy2+zy3
		}else {
			laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		}
		swbreak
	case LAYBTN_SHOW_OUT
	case LAYBTN_SHOW_OUT_SELECTED
		pos objlayer_axis_x+celofsx*objlayer_size_x/celx+zx3, objlayer_axis_y+celofsy*objlayer_size_y/cely+zy3
		if layerbtn_stat & LAYBTN_SELECTED {
			gmode 3,,,laybtn_ease(256, 0) : celput id, limit(fi+2,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
			if tp & 16 : gmode gm,,,gf
			if layerbtn_cnt < SHOW_OUT_FRAME@modlaybtn/5 : laybtn_mes wd,tp, 1,1, zx1+zx2+zx3,zy1+zy2+zy3  ; フェードの途中で非表示にする
		} else {
			gmode 3,,,laybtn_ease(256, 0) : celput id, limit(fi+0,0,celmax-1), 1.0*objlayer_size_x/celx, 1.0*objlayer_size_y/cely
			if tp & 16 : gmode gm,,,gf
			if layerbtn_cnt < SHOW_OUT_FRAME@modlaybtn/5 : laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		}
		swbreak
	swend
	return
// (モジュール内使用) celdivサイズを取得
#deffunc getCelSize@modlaybtn int id, var celx_, var cely_, var celofsx_, var celofsy_, var celmax_
	if length(ezpBmscrs) <= id : ezpBmscrs(id) = 0
	if ezpBmscrs(id) == 0 {
		g_sel = ginfo_sel : gsel id : layerobj 1,1,0,*dummy : ezpBmscrs(id) = objinfo_bmscr(0) : clrobj stat,stat : gsel g_sel
	}
	dupptr ezbm, ezpBmscrs(id), (BMSCR_CELSIZE+2)*4
	celx_ = ezbm(BMSCR_CELSIZE)&0xFFFF
	cely_ = ezbm(BMSCR_CELSIZE)>>16
	celofsx_ = ezbm(BMSCR_CELSIZE+1)&0xFFFF
	celofsy_ = ezbm(BMSCR_CELSIZE+1)>>16
	if celx_ == 0 || cely_ == 0 {
		celmax_ = 1
	}else {
		celmax_ = (ezbm(1)/celx_) * ((ezbm(2)+cely_-1)/cely_)
	}
	return
// (モジュール内使用) gmode,gfrateを取得
#deffunc getGMdata@modlaybtn var gmode_, var gfrate_
	dupptr ezbm, objinfo_bmscr(0), (BMSCR_GFRATE+1)*4
	gmode_ = ezbm(BMSCR_GMODE)
	gfrate_ = ezbm(BMSCR_GFRATE)
	return

// 簡単描画 : boxf利用
#define global laybtn_ezbox(%1=$01000000,%2=$01000000,%3=$01000000,%4="",%5=0,%6=0,%7=0,%8=0,%9=0,%10=-1,%11=0,%12=0,%13=0,%14=0) laybtn_ezbox@modlaybtn %1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14
#deffunc laybtn_ezbox@modlaybtn int col1, int col2, int col3, str wd, int tp, int zx1, int zy1, int zx2, int zy2, int r1, int zx3, int zy3, int sx1, int sy1
;  col1 : boxカラー(通常表示)[$AARRGGBB]
;  col2 : boxカラー(フォーカス時)[$AARRGGBB]
;  col3 : boxカラー(押し込み時)[$AARRGGBB]
;  wd   : 表示する文字列
;  tp   : mesオプション
;  zx1  : 中心から文字をずらす量(x方向)
;  zy1  : 中心から文字をずらす量(y方向)
;  zx2  : ボタンを押し込んだ時に文字をずらす量(x方向)
;  zy2  : ボタンを押し込んだ時に文字をずらす量(y方向)
;  r1   : 長方形の角の丸みサイズ R(アール)
;  zx3 : ボタン全体ずらし量(x方向) [裏技]
;  zy3 : ボタン全体ずらし量(y方向) [裏技]
;  sx1 : ボタンサイズの拡縮量(x方向) [裏技]
;  sy1 : ボタンサイズの拡縮量(y方向) [裏技]
	if lparam != objlayer_cmddraw : return
	if tp & 16 : getGMdata@modlaybtn gm, gf
	// ボタン状態で分岐
	switch layerbtn_stat
	case LAYBTN_SHOW_IN
		if (col1 & $FF000000) != $01000000 {
			cola = col1 >> 24 & 0xFF : if cola == 0 : cola = 256
			gmode 3,,,laybtn_ease(0, cola) : colrboxfa_auto@modlaybtn col1, objlayer_axis_x-sx1+zx3, objlayer_axis_y-sy1+zy3, objlayer_axis_x2+sx1+zx3, objlayer_axis_y2+sy1+zy3, r1
		}
		if tp & 16 : gmode gm,,,gf
		if layerbtn_cnt >= SHOW_IN_FRAME@modlaybtn/5 : laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3  ; フェードの途中から表示させる
		swbreak
	case LAYBTN_FOCUS_IN
		if (col1 & $FF000000) != $01000000 || (col2 & $FF000000) != $01000000 {
			cola1 = col1 >> 24 & 0xFF : if cola1 == 0 : cola1 = 256
			cola2 = col2 >> 24 & 0xFF : if cola2 == 0 : cola2 = 256
			gmode 3,,,laybtn_ease(cola1,cola2)
			colrboxfa_auto@modlaybtn laybtn_ease(col1>>16&0xFF,col2>>16&0xFF)<<16|laybtn_ease(col1>>8&0xFF,col2>>8&0xFF)<<8|laybtn_ease(col1&0xFF,col2&0xFF), objlayer_axis_x-sx1+zx3, objlayer_axis_y-sy1+zy3, objlayer_axis_x2+sx1+zx3, objlayer_axis_y2+sy1+zy3, r1
		}
		if tp & 16 : gmode gm,,,gf
		laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		swbreak
	case LAYBTN_FOCUS_OUT
		if (col1 & $FF000000) != $01000000 || (col2 & $FF000000) != $01000000 {
			cola2 = col2 >> 24 & 0xFF : if cola2 == 0 : cola2 = 256
			cola1 = col1 >> 24 & 0xFF : if cola1 == 0 : cola1 = 256
			gmode 3,,,laybtn_ease(cola2,cola1)
			colrboxfa_auto@modlaybtn laybtn_ease(col2>>16&0xFF,col1>>16&0xFF)<<16|laybtn_ease(col2>>8&0xFF,col1>>8&0xFF)<<8|laybtn_ease(col2&0xFF,col1&0xFF), objlayer_axis_x-sx1+zx3, objlayer_axis_y-sy1+zy3, objlayer_axis_x2+sx1+zx3, objlayer_axis_y2+sy1+zy3, r1
		}
		if tp & 16 : gmode gm,,,gf
		laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		swbreak
	case LAYBTN_PRESS_IN
	case LAYBTN_PRESS_IN_SELECTED
		if (col2 & $FF000000) != $01000000 || (col3 & $FF000000) != $01000000 {
			cola2 = col2 >> 24 & 0xFF : if cola2 == 0 : cola2 = 256
			cola3 = col3 >> 24 & 0xFF : if cola3 == 0 : cola3 = 256
			gmode 3,,,laybtn_ease(cola2,cola3)
			colrboxfa_auto@modlaybtn laybtn_ease(col2>>16&0xFF,col3>>16&0xFF)<<16|laybtn_ease(col2>>8&0xFF,col3>>8&0xFF)<<8|laybtn_ease(col2&0xFF,col3&0xFF), objlayer_axis_x-sx1+zx3, objlayer_axis_y-sy1+zy3, objlayer_axis_x2+sx1+zx3, objlayer_axis_y2+sy1+zy3, r1
		}
		if tp & 16 : gmode gm,,,gf
		if layerbtn_cnt < PRESS_IN_FRAME@modlaybtn/5 {  ; それっぽいタイミングで移動させる
			laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		}else {
			laybtn_mes wd,tp, 1,1, zx1+zx2+zx3,zy1+zy2+zy3
		}
		swbreak
	case LAYBTN_PRESS_OUT
		if (col2 & $FF000000) != $01000000 || (col3 & $FF000000) != $01000000 {
			cola3 = col3 >> 24 & 0xFF : if cola3 == 0 : cola3 = 256
			cola2 = col2 >> 24 & 0xFF : if cola2 == 0 : cola2 = 256
			gmode 3,,,laybtn_ease(cola3,cola2)
			colrboxfa_auto@modlaybtn laybtn_ease(col3>>16&0xFF,col2>>16&0xFF)<<16|laybtn_ease(col3>>8&0xFF,col2>>8&0xFF)<<8|laybtn_ease(col3&0xFF,col2&0xFF), objlayer_axis_x-sx1+zx3, objlayer_axis_y-sy1+zy3, objlayer_axis_x2+sx1+zx3, objlayer_axis_y2+sy1+zy3, r1
		}
		if tp & 16 : gmode gm,,,gf
		if layerbtn_cnt < PRESS_OUT_FRAME@modlaybtn/5 {  ; それっぽいタイミングで移動させる
			laybtn_mes wd,tp, 1,1, zx1+zx2+zx3,zy1+zy2+zy3
		}else {
			laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		}
		swbreak
	case LAYBTN_SHOW_OUT
	case LAYBTN_SHOW_OUT_SELECTED
		if layerbtn_stat & LAYBTN_SELECTED {
			if (col3 & $FF000000) != $01000000 {
				cola = col3 >> 24 & 0xFF : if cola == 0 : cola = 256
				gmode 3,,,laybtn_ease(cola, 0) : colrboxfa_auto@modlaybtn col3, objlayer_axis_x-sx1+zx3, objlayer_axis_y-sy1+zy3, objlayer_axis_x2+sx1+zx3, objlayer_axis_y2+sy1+zy3, r1
			}
			if tp & 16 : gmode gm,,,gf
			if layerbtn_cnt < SHOW_OUT_FRAME@modlaybtn/5 : laybtn_mes wd,tp, 1,1, zx1+zx2+zx3,zy1+zy2+zy3  ; フェードの途中で非表示にする
		} else {
			if (col1 & $FF000000) != $01000000 {
				cola = col1 >> 24 & 0xFF : if cola == 0 : cola = 256
				gmode 3,,,laybtn_ease(cola, 0) : colrboxfa_auto@modlaybtn col1, objlayer_axis_x-sx1+zx3, objlayer_axis_y-sy1+zy3, objlayer_axis_x2+sx1+zx3, objlayer_axis_y2+sy1+zy3, r1
			}
			if tp & 16 : gmode gm,,,gf
			if layerbtn_cnt < SHOW_OUT_FRAME@modlaybtn/5 : laybtn_mes wd,tp, 1,1, zx1+zx3,zy1+zy3
		}
		swbreak
	swend
	return

#global
#endif // __mod_layerbutton__

#if 0
// hs ファイル //////////////////////////////////////////////////////////////
%type
拡張命令
%url
https://suwa.pupu.jp/HSP/index.html
%port
Win


%index
layerbutton
ちょっとリッチなアニメーション付きボタンを作成
%group
オブジェクト制御命令
%prm
p1,p2,p3,p4,p5,p6,p7,p8,p9,p10 {}
p1,p2 : レイヤーボタンのXYサイズ(ドット単位)
p3=0〜(0) : オプション値
p4=0〜(0) : グループID
p5=0〜(0) : SHOW_IN フレーム数
p6=0〜(0) : FOCUS_IN フレーム数
p7=0〜(0) : PRESS_IN フレーム数
p8=0〜(0) : SHOW_OUT フレーム数
p9=0〜(0) : FOCUS_OUT フレーム数
p10=0〜(0) : PRESS_OUT フレーム数

%inst
layerobj命令を利用して、ちょっとリッチなアニメーション付きボタンを比較的簡単に作成することができます。
カレントポジションにレイヤーボタンオブジェクトを配置します。

layerbutton命令末尾に{}を記述するという少し特殊な書き方でサブルーチンを指定します。
{}で括られたサブルーチンの最後には必ず return を書いてください。

{}内のサブルーチンが redraw 1 前に呼び出され、layerobjと同じようにシステム変数iparam,wparam,lparamが設定された状態で処理されます。
lparam が objlayer_cmddraw のときに、layerbtn_stat にボタンの状態が代入され、layerbtn_cnt にその状態になってからのフレーム数が入ります。
このボタン状態とフレーム数を利用して、ユーザーがボタンオブジェクトを描画することでアニメーションボタンの作成を実現します。
html{
<table border="1" cellpadding="10">
<tr>
  <td scope="col"><b>layerbtn_stat</b></td>
  <td scope="col"><b>値</b></td>
  <td scope="col"><b>状態</b></td>
</tr>
<tr>
  <td>LAYBTN_SHOW_IN</td>
  <td>2</td>
  <td>ボタンの表示を開始。</td>
</tr>
<tr>
  <td>LAYBTN_FOCUS_IN</td>
  <td>4</td>
  <td>フォーカス状態。マウスを乗せたり、キー入力でフォーカスさせたとき。</td>
</tr>
<tr>
  <td>LAYBTN_FOCUS_OUT</td>
  <td>8</td>
  <td>フォーカス状態解除。マウスをボタン外に移動させたり、キー入力で別のボタンにフォーカスを移動させたとき。</td>
</tr>
<tr>
  <td>LAYBTN_PRESS_IN</td>
  <td>16</td>
  <td>ボタンを押し込んだ状態。ボタンをクリックしている間や、エンターキー等でボタンを決定したとき。</td>
</tr>
<tr>
  <td>LAYBTN_PRESS_IN_SELECTED</td>
  <td>17</td>
  <td>ボタンが決定された瞬間のみ。
  <br>「決定された瞬間」とは、マウス/タッチの場合はボタンを押してさらにボタン範囲内で離した瞬間、キーボードの場合は押した瞬間です。
  <br>※ laybtn_settings命令で設定を「ボタンを押した後に非表示(SHOW_OUT)処理させない」にしている場合にのみ呼び出されます。</td>
</tr>
<tr>
  <td>LAYBTN_PRESS_OUT</td>
  <td>32</td>
  <td>ボタンを押し込んだ状態を解除。ボタンをクリックしたままマウスをボタン外に移動させたとき。</td>
</tr>
<tr>
  <td>LAYBTN_SHOW_OUT</td>
  <td>64</td>
  <td>非表示処理中の状態。ボタンが決定されたあと同一グループのすべてのボタンが非表示(SHOW_OUT)処理を開始する。</td>
</tr>
<tr>
  <td>LAYBTN_SHOW_OUT_SELECTED</td>
  <td>65</td>
  <td>非表示処理中の状態。ボタンが決定されたあと同一グループのすべてのボタンが非表示(SHOW_OUT)処理を開始する。
  <br>グループの中で決定されたボタンのみ_SELECTED状態となる。</td>
</tr>
<tr>
  <td>LAYBTN_COMPLETE</td>
  <td>128</td>
  <td>グループ内のすべてのオブジェクトの非表示(SHOW_OUT)処理がすべて完了したとき。</td>
</tr>
<tr>
  <td>LAYBTN_COMPLETE_SELECTED</td>
  <td>129</td>
  <td>グループ内のすべてのオブジェクトの非表示(SHOW_OUT)処理がすべて完了したとき。
  <br>グループの中で決定されたボタンのみ_SELECTED状態となる。</td>
</tr>
</table>
}html

デフォルトでマウス操作やキー入力によるフォーカス検知やボタン決定をサポートしています。

p3 で layerobj と同じように任意の整数値をオプション値として保存することができます。
オプション値は拡張システム変数 objlayer_option [objinfo(wparam,objlayer_info_option)] によって取り出せます。

p4 にグループIDを設定すると、そのグループごとにボタン選択やフォーカス移動を分けることができます。
また、グループIDの若い順に描画されるのでオブジェクトの重なる順番を制御できます。

p5 〜 p10 にそれぞれの状態の表示にかけるフレーム数を指定します。

laybtn_ease()関数を使うことで、layerbtn_cnt に連動したイージング値を簡単に取得できます。
他にも、laybtn_mes命令や拡張システム変数 objlayer_axis_x, objlayer_axis_y, objlayer_size_x, objlayer_size_y, objlayer_axis_x2, objlayer_axis_y2, objlayer_option 等のボタンを描画するための便利な機能が使えます。
やや特殊な用途に用いる layerbtn_mousex, layerbtn_mousey, layerbtn_clickx, layerbtn_clicky もあります。
- layerbtn_mousex(y) : オブジェクト上を通過したカーソルの最後の座標。クリック/タッチ中はオブジェクト外の座標でも代入されます。
- layerbtn_clickx(y) : オブジェクト上でクリック/タッチを開始した座標。クリック/タッチ中でない場合は -1 が代入されます。

作成したlayerbuttonオブジェクトは通常、ボタンを押した後に非表示(SHOW_OUT)処理が行われることで自動的に削除されます。

layerbuttonオブジェクトを強制的に削除したい場合は、laybtn_hide または clrobj を使用してください。
また、objsel命令を使うことで layerbuttonオブジェクトにフォーカスを当てることができます。
(objsel に -2 を指定すると、layerbuttonオブジェクトからフォーカスを除去することができるようにしています。)

オブジェクトIDが必要な場合は、{}の直後の行でstatを参照してください。

ゲームパッド等からの入力に対応するため layerbtn_stickVar 変数を用意しました。
この変数に対して、stick 命令と同じ形式の値を毎フレーム代入することで、フォーカスの移動やボタンの決定を行えるようになります。
(変数の内容は毎フレームの冒頭で自動的に 0 にリセットされます。)

[命令の一部改造 : redraw, objsel]
%sample
#include "mod_layerbutton.hsp"

celload dir_tv+"btn_hard.png", -1;celid_auto
cel_id = stat
celdiv cel_id, 80, 24
log = ""
pos 10, 50
layerbutton 180,60, cel_id, 0, 30,20,8, 15,10,4 {
	if lparam == objlayer_cmddraw {
		color 0,0,0 : objcolor 255,255,255
		font msgothic, 18, 1
		mes_zurasi = 0,0
		// ボタン状態で分岐
		switch layerbtn_stat
		case LAYBTN_SHOW_IN
			pos objlayer_axis_x-laybtn_ease(200, 0), objlayer_axis_y
			gmode 3,,,255 : celput cel_id, 0, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
			mes_zurasi = -laybtn_ease(200, 0), 0
			swbreak
		case LAYBTN_FOCUS_IN
			pos objlayer_axis_x, objlayer_axis_y
			gmode 3,,,256 : celput cel_id, 0, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
			pos objlayer_axis_x, objlayer_axis_y
			gmode 3,,,laybtn_ease(0,256) : celput cel_id, 1, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
			swbreak
		case LAYBTN_FOCUS_OUT
			pos objlayer_axis_x, objlayer_axis_y
			gmode 3,,,256 : celput cel_id, 0, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
			pos objlayer_axis_x, objlayer_axis_y
			gmode 3,,,laybtn_ease(256,0) : celput cel_id, 1, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
			swbreak
		case LAYBTN_PRESS_IN
			if layerbtn_cnt == 0 : log += "LAYBTN_PRESS_IN (cnt=0)" +"\n"
			pos objlayer_axis_x, objlayer_axis_y
			gmode 3,,,256 : celput cel_id, 2, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
			mes_zurasi = 0,3
			swbreak
		case LAYBTN_PRESS_OUT
			pos objlayer_axis_x, objlayer_axis_y
			gmode 3,,,256 : celput cel_id, 2, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
			mes_zurasi = 0,3
			swbreak
		case LAYBTN_SHOW_OUT
		case LAYBTN_SHOW_OUT_SELECTED
			pos objlayer_axis_x-laybtn_ease(0, 200, tien/2), objlayer_axis_y
			if layerbtn_stat & LAYBTN_SELECTED {
				if layerbtn_cnt == 0 : log += "LAYBTN_SHOW_OUT_SELECTED (cnt=0)" +"\n"
				gmode 3,,,256 : celput cel_id, 2, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
				mes_zurasi = -laybtn_ease(0, 200, tien/2), 3
			} else {
				gmode 3,,,256 : celput cel_id, 0, 1.0*objlayer_size_x/80, 1.0*objlayer_size_y/24
				mes_zurasi = -laybtn_ease(0, 200, tien/2), 0
			}
			swbreak
		case LAYBTN_COMPLETE
		case LAYBTN_COMPLETE_SELECTED
			if layerbtn_stat & LAYBTN_SELECTED {
				log += "LAYBTN_COMPLETE_SELECTED" +"\n"
			}
			return
			swbreak
		swend
		laybtn_mes "ボタン id="+objlayer_option,4, 1,1, mes_zurasi(0),mes_zurasi(1)

	}else : if lparam == objlayer_cmdterm {
		if layerbtn_stat == LAYBTN_GROUP_DELETED {
			log += "objlayer_cmdterm : グループの削除完了" +"\n"
		}
	}
	return
}
repeat
	redraw 0 : color 255,255,255 : boxf : color : pos 0,0 : font msgothic,16
	mes log
	redraw 1
	await 1000/60
loop

%href
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt


%index
laybtn_settings
layerbuttonオブジェクトの動作を設定する
%group
オブジェクト制御命令
%prm
p1,p2,p3
p1=0〜(0) : キーボード入力に関する設定
p2=0〜(0) : マウスに関する設定
p3=0〜(0) : 表示処理等に関する設定

%inst
layerbuttonオブジェクトの動作処理を一部変更できます。
laybtn_settings 命令は layerbutton サブルーチン{}内の先頭に書いてください。

p1,p2,p3 に割り当てる値はそれぞれ加算して複数設定できます。

html{
<table border="1" cellpadding="10">
<tr>
  <td scope="col"><b>p1</b></td>
  <td scope="col"><b>キーボード入力に関する設定の効果</b></td>
</tr>
<tr>
  <td>+1</td>
  <td>キー入力による操作を無効にする。</td>
</tr>
<tr>
  <td>+2</td>
  <td>キー入力で新たなフォーカスを発生させない。
  <br>フォーカスの発生をobjselを使ってスクリプト側で制御したい場合等に用います。
  <br>※ 通常、表示されているグループIDが1つだけの場合は移動(上下左右またはWASD)キーでフォーカスが発生するようになっています。(複数グループが同時に表示されている場合は、キー入力でのフォーカス発生はしません。)</td>
</tr>
<tr>
  <td>+4</td>
  <td>ボタン間のフォーカス移動キーにWASDキーを含めない。</td>
</tr>
<tr>
  <td>+8</td>
  <td>ボタン間のフォーカス移動キーに上下左右キーを含めない。</td>
</tr>
<tr>
  <td>+16</td>
  <td>ボタンの決定キーにスペースキーを含めない。</td>
</tr>
<tr>
  <td>+32</td>
  <td>ボタンの決定キーにエンターキーを含めない。</td>
</tr>
<tr>
  <td>+64</td>
  <td>ボタン間のフォーカス移動キーや決定キーを押し続けたときのキーリピートを有効にする。
  <br>※ キーリピートの間隔は 60fps を前提とした待機フレーム数で設定されています。30fps など異なるフレームレートで使用する場合は、グローバル変数 LAYERBTN_KEY_REPEAT_FRAME を変更してください。初期値は 16 です。  
  <br>※ LAYERBTN_KEY_REPEAT_FRAME は「初期ディレイ」と「リピート間隔」の両方に使用されます。  
  <br> - 押し続けた最初の待ち時間(初期ディレイ)は LAYERBTN_KEY_REPEAT_FRAME の値になります。  
  <br> - その後のリピート間隔は (LAYERBTN_KEY_REPEAT_FRAME / 2) になります。  
  <br>※ LAYERBTN_KEY_REPEAT_FRAME に (『リピート間隔』<<16 | 『初期ディレイ』) の形式で値を設定することで、両方を個別に指定することもできます。</td>
</tr>
</table>
}html

html{
<table border="1" cellpadding="10">
<tr>
  <td scope="col"><b>p2</b></td>
  <td scope="col"><b>マウス/タッチに関する設定の効果</b></td>
</tr>
<tr>
  <td>+1</td>
  <td>マウス/タッチによる操作を無効にする。</td>
</tr>
<tr>
  <td>+2</td>
  <td>マウスクリック/タッチで即ボタン決定をする。
  <br>※ 通常、クリックし続けたままボタン外に移動してクリックを離すと決定せずキャンセルされますが、この設定をするとボタンを押した瞬間に決定します。</td>
</tr>
<tr>
  <td>+4</td>
  <td>ボタン範囲外でのクリック/タッチ操作後に、範囲内へスライドさせた場合でもボタンが押されたとみなす。</td>
</tr>
<tr>
  <td>+8</td>
  <td>「[+4]範囲外→範囲内スライドもボタンを押す。」設定を、同一グループ内の他ボタンが先にクリック/タッチ中の状態でのみ許可されるようにする。
  <br>※ 指をずらして近傍ボタンを同時押しさせたいが、無関係な他オブジェクトのスライド操作による干渉を避けたい場合に用いてください。</td>
</tr>
<tr>
  <td>+16</td>
  <td>ボタンをクリック/タッチして一度 LAYBTN_PRESS_IN 状態になると、範囲外へスライドしても指を離すまで LAYBTN_PRESS_IN が維持され、必ず決定される。</td>
</tr>
</table>
}html

html{
<table border="1" cellpadding="10">
<tr>
  <td scope="col"><b>p3</b></td>
  <td scope="col"><b>動作処理等に関する設定の効果</b></td>
</tr>
<tr>
  <td>+1</td>
  <td>ボタンを押しても非表示(SHOW_OUT)処理に移行せず消えないようにする。
  <br>ボタンを何回も押せるようにしたいときに用います。
  <br>※ この設定をすると、ボタンを押したとき LAYBTN_PRESS_IN だけでなく、決定した瞬間を判別できるよう LAYBTN_PRESS_IN_SELECTED も発生するようになります。
  <br>※ 「決定した瞬間」とは、マウスの場合はクリックして離した瞬間、キーボードの場合は押した瞬間です。</td>
</tr>
<tr>
  <td>+2</td>
  <td>「[+1]ボタンを押しても非表示(SHOW_OUT)処理に移行せず消えないようにする。」のとき、ボタン決定後 PRESS_IN,PRESS_OUT のアニメーションが終わるまで他をフォーカスできなくする。
  <br>※ 何回も連打されたり、次々とボタンが押されてしまうのを防ぎます。</td>
</tr>
<tr>
  <td>+4</td>
  <td>「[+1]ボタンを押しても非表示(SHOW_OUT)処理に移行せず消えないようにする。」のとき、ボタン決定後 FOCUS_IN で留まらずに待機状態(SHOW_IN)まで戻るようにする。
  <br>※ ボタンを離したときフォーカス状態表示を残したくない場合に設定してください。</td>
</tr>
<tr>
  <td>+8</td>
  <td>他のボタンにフォーカスが移ったとき、移動前のボタンの FOCUS_IN,FOCUS_OUT,PRESS_IN,PRESS_OUT を強制的に停止して待機状態(SHOW_IN)に戻す。
</td>
</tr>
<tr>
  <td>+16</td>
  <td>FOCUS_IN の表示が完了する前にフォーカスが外れたとき FOCUS_OUT を即座に開始させる。
  <br>通常は、FOCUS_IN → FOCUS_OUT それぞれの指定フレーム数をカウントしてから待機状態(SHOW_IN)に戻ります。
  <br>フォーカスを付けてすぐ外したときの FOCUS_IN,FOCUS_OUT 表示時間が長く感じた場合に利用してください。
  <br>※ フォーカスをすぐに外した場合、FOCUS_OUT の表示は FOCUS_IN にかかった時間と同じフレーム数で行われます。(FOCUS_OUT になったときの layerbtn_cnt が 0 からでなくカウント途中[FOCUS_OUT表示フレーム数指定-フォーカスが外れた時のcnt値]から始まるようになるため。)
  <br>※ laybtn_ease() の FOCUS_OUT 時のデフォルトのイージングタイプが ease_quartic_in になります。
  <br>※ layerbutton命令での FOCUS_IN と FOCUS_OUT の表示フレーム数は同じに設定してください。異なる場合、アニメーションがシームレスにつながらず、表示に違和感が生じる可能性があります。</td>
</tr>
</table>
}html

%sample
#include "mod_layerbutton.hsp"

log  = "設定" +"\n"
log += "・キー入力で新たなフォーカスを発生させない" +"\n"
log += "・マウスクリック/タッチで即ボタン決定をする" +"\n"
log += "・ボタンを押しても非表示(SHOW_OUT)処理に移行せず消えないようにする" +"\n"
log += "・ボタン決定後 PRESS アニメーションが終わるまで他をフォーカスやクリックできなくする" +"\n\n"
pos 200,100
repeat 3
id = cnt : pos ,ginfo_cy+10
layerbutton 172,66, id, 5, 30,30,10, 50,30,5 {
	laybtn_settings 2,2,3  ; ボタン設定
	color 0,0,0 : objcolor 255,255,255 : font msgothic, 18, 1
	laybtn_ezbox $FF0000, $FFFF00, $FF8800, "テキスト id="+objlayer_option,4
	if lparam == objlayer_cmddraw {
		switch layerbtn_stat
		case LAYBTN_PRESS_IN_SELECTED
			log += "select!! wp="+wparam+" opt="+objlayer_option +"\n"
			swbreak
		swend
	}
	return
}
loop
repeat
	redraw 0 : color 255,255,255 : boxf : color : pos 0,0 : font msgothic,14
	mes log
	redraw 1
	await 1000/60
loop

%href
layerbutton
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_mes
layerbuttonサブルーチン内用テキスト表示
%group
画面制御命令
%prm
"strings",sw,ax,ay,zx,zy
"strings" : 表示するメッセージ、または変数
sw : オプション[mes命令と同様] (0)
ax, ay : アラインメント モード (0, 0)
zx, zy : 描画位置のオフセット量 (0, 0)

%inst
layerbuttonオブジェクトの矩形範囲を基準として文字列を描画します。

引数 ax, ay で、横方向, 縦方向のアラインメントを指定できます。

ax : 0 = 左寄せ, 1 = 中央寄せ, 2 = 右寄せ
ay : 0 = 上寄せ, 1 = 中央寄せ, 2 = 下寄せ

たとえば、layerbuttonオブジェクトの中心に文字列を描画したい場合は ax,ay を 1,1 にしてください。
さらに、中心から位置をずらしたい場合は、引数 zx,zy を指定することで調整可能です。

引数 sw のオプションは mes命令と同じものです。指定値は mes命令のコマンドヘルプを参照してください。

%sample
#include "mod_layerbutton.hsp"

pos 100,100
layerbutton 180,60 {
	if lparam == objlayer_cmddraw {
		color 0,255,0 : boxf objlayer_axis_x, objlayer_axis_y, objlayer_axis_x2, objlayer_axis_y2
		color 0,0,0
		laybtn_mes "ボタン中心",0, 1,1
	}
	return
}
repeat
	redraw 0 : color 255,255,255 : boxf : color : pos 0,0
	redraw 1
	await 1000/60
loop

%href
layerbutton
laybtn_settings
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_ease
layerbuttonサブルーチン内用イージング値の取得
%group
拡張入出力関数
%prm
(p1,p2,p3,p4)
p1 : 出力される最小値(整数値または実数値)
p2 : 出力される最大値(整数値または実数値)
p3=0〜(0) : 遅延フレーム数
p4 : 計算式のタイプ値

%inst
p1 と p2 で指定された最小値・最大値の範囲内で、任意の計算式に基づき補間されたイージング関数の結果値を取得します。
この結果値は、layerbutton 命令の p5 〜 p10 に設定された各ボタン状態の表示にかけるフレーム数(時間範囲)に対し、layerbtn_cnt の値を経過時間として算出されます。

p3 の遅延フレーム数は、同一グループ内で複数のボタンを作成する場合に、2つ目以降の SHOW_IN 表示等を意図的に遅らせ、段階的に表示させる用途に使用します。

イージングの計算式タイプは、LAYBTN_SHOW_IN などのボタン状態ごとにデフォルトのタイプが決まっています。
これを、引数 p4 で計算式タイプを強制することができます。
イージングの計算式タイプについて詳しくは、setease命令のコマンドヘルプを参照してください。

html{
<table border="1" cellpadding="10">
<tr>
  <td scope="col"><b>ボタン状態</b></td>
  <td scope="col"><b>イージングタイプ</b></td>
</tr>
<tr>
  <td>LAYBTN_SHOW_IN<br>LAYBTN_FOCUS_IN<br>LAYBTN_PRESS_IN</td>
  <td>ease_quartic_out</td>
</tr>
<tr>
  <td>LAYBTN_SHOW_OUT<br>LAYBTN_FOCUS_OUT(※)<br>LAYBTN_PRESS_OUT</td>
  <td>ease_quad_out</td>
</tr>
</table>
}html
※ laybtn_settings命令で設定を「FOCUS_IN の表示が完了する前にフォーカスが外れたとき FOCUS_OUT を即座に開始させる」にしている場合、LAYBTN_FOCUS_OUT のデフォルトタイプは ease_quartic_in になります。
%sample
#include "mod_layerbutton.hsp"

// ボタン作成
pos 10,100
repeat 4
	tien = 10*cnt
	pos ,ginfo_cy+10
	layerbutton 180,60, tien, 0, 30+tien,20,0, 15+tien/2,10,0 {
		if lparam == objlayer_cmddraw {
			color 0,0,0 : font msgothic, 18, 1
			ti = objlayer_option
			// ボタン状態で分岐 (+イージングで表示位置,色を変える)
			switch layerbtn_stat
			case LAYBTN_SHOW_IN
				color 0,0,255 : boxf objlayer_axis_x-laybtn_ease(200, 0, ti), objlayer_axis_y, objlayer_axis_x2-laybtn_ease(200, 0, ti), objlayer_axis_y2
				color 250,250,250 : laybtn_mes "遅延="+ti,0, 1,1, -laybtn_ease(200, 0, ti)
				swbreak
			case LAYBTN_FOCUS_IN
				color laybtn_ease(0,128),0,255 : boxf objlayer_axis_x, objlayer_axis_y, objlayer_axis_x2, objlayer_axis_y2
				color 250,250,250 : laybtn_mes "遅延="+ti,0, 1,1
				swbreak
			case LAYBTN_FOCUS_OUT
				color laybtn_ease(128,0),0,255 : boxf objlayer_axis_x, objlayer_axis_y, objlayer_axis_x2, objlayer_axis_y2
				color 250,250,250 : laybtn_mes "遅延="+ti,0, 1,1
				swbreak
			case LAYBTN_PRESS_IN
				color 128,128,255 : boxf objlayer_axis_x, objlayer_axis_y, objlayer_axis_x2, objlayer_axis_y2
				color 250,250,250 : laybtn_mes "遅延="+ti,0, 1,1
				swbreak
			case LAYBTN_SHOW_OUT
			case LAYBTN_SHOW_OUT_SELECTED
				if layerbtn_stat & LAYBTN_SELECTED { color 128,128,255 } else { color 0,0,255 }
				boxf objlayer_axis_x-laybtn_ease(0, 200, ti/2), objlayer_axis_y, objlayer_axis_x2-laybtn_ease(0, 200, ti/2), objlayer_axis_y2
				color 250,250,250 : laybtn_mes "遅延="+ti,0, 1,1, -laybtn_ease(0, 200, ti/2)
				swbreak
			swend
		}
		return
	}
loop
// 表示ループ
repeat
	redraw 0 : color 255,255,255 : boxf : color : pos 0,0 : font msgothic,17
	redraw 1
	await 1000/60
loop

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_hide
layerbuttonの指定グループを非表示(SHOW_OUT)処理にして削除する
%group
オブジェクト制御命令
%prm
p1
p1=0〜(0) : グループID

%inst
指定したグループIDを持つボタンを非表示(SHOW_OUT)処理に移行します。
非表示(SHOW_OUT)処理が実行完了した後、ボタンは削除されます。

グループIDは layerbutton命令の p4 で指定します。

%sample

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_length
layerbutton指定グループ内のオブジェクト数を取得
%group
オブジェクト制御命令
%prm
(p1)
p1=0〜(0) : グループID

%inst
指定したグループIDを持つボタンの現在の個数を取得します。
非表示(SHOW_OUT)処理中も含めてカウントされます。
非表示(SHOW_OUT)処理が完了して削除されたオブジェクトはカウントされなくなります。

グループIDは layerbutton命令の p4 で指定します。

%sample

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_enable
layerbuttonの指定グループのオブジェクトに有効・無効の設定をする
%group
オブジェクト制御命令
%prm
p1,p2
p1=0〜(0) : グループID
p2=0〜(1) : 0なら無効、1なら有効、-1なら状態を取得

%inst
指定したグループIDを持つボタン全体にオブジェクトの有効・無効の設定を行います。
無効状態にするとマウスやキー入力などすべての操作を受け付けなくなります。

グループIDは layerbutton命令の p4 で指定します。

p2 に -1 を指定した場合、p1 のグループが有効か無効かの状態が stat に代入されます。
1 : 有効状態
0 : 無効状態

%sample

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_width
layerbuttonオブジェクトのサイズや位置を変更する
%group
オブジェクト制御命令
%prm
p1,p2,p3,p4,p5
p1=0〜 : オブジェクトID
p2=0〜(INT_MIN) : オブジェクトの幅(1ドット単位)
p3=0〜(INT_MIN) : オブジェクトの高さ(1ドット単位)
p4=0〜(INT_MIN) : オブジェクトのX座標位置(1ドット単位)
p5=0〜(INT_MIN) : オブジェクトのY座標位置(1ドット単位)

%inst
指定したオブジェクトIDのボタンのサイズや位置を変更します。

パラメータを省略した場合は、現在の設定が使用されます。

%sample

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_focus
layerbuttonの指定グループ内の指定オブジェクトにフォーカスを移動させる
%group
オブジェクト制御命令
%prm
p1,p2
p1=0〜(-1) : グループID
p2=0〜(-1) : オブジェクトが何番目かを表す番号(グループIDの中でオブジェクトIDの若い順)

%inst
p1 にグループID、p2 にそのグループ内でオブジェクトIDの若い順に何番目か(0〜)を指定すると、そのオブジェクトにフォーカスが移動します。

p1 に -1 を指定すると、現在フォーカスを持っているグループIDが stat に代入されます。
また、存在するグループIDを p1 に指定し、p2 に -1 を指定すると、そのグループ内で現在フォーカスを持っているオブジェクトが「オブジェクトIDの若い順で何番目か(0〜)」を stat に代入します。

さらに、p2 に -2 〜 -5 を指定すると、フォーカスを1つ隣のオブジェクトに移動させることもできます。
移動先は以下の通りです。
-2 : 左
-3 : 上
-4 : 右
-5 : 下

移動に失敗したときは stat に -1 が代入され、成功したときはオブジェクトIDが代入されます。(何番目かを表す番号ではなく、オブジェクトIDです。)

%sample

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_width
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_ezcel
layerbuttonのcelputを利用した簡単描画
%group
画面制御命令
%prm
id,no,"strings",zx1,zy1,zx2,zy2
id=0〜(1) : 画像素材を持つウインドウID
no=0〜(0) : 分割画像No.(SHOW_INで使用する画像No.)
"strings" : 表示するメッセージ、または変数
sw=0〜(0) : mesオプション[mes命令と同様]
zx1 : 文字を中心位置からずらす量(x方向)
zy1 : 文字を中心位置からずらす量(y方向)
zx2 : ボタン押し込み時に文字をさらにずらす量(x方向)
zy2 : ボタン押し込み時に文字をさらにずらす量(y方向)

%inst
layerbutton はサブルーチン内で layerbtn_stat の各種状態に合わせてユーザーが描画処理をする必要があります。
この命令を利用することで「表示」「フォーカス」「決定」「非表示」の一連の描画処理を1命令で簡易的に指定できます。

描画には celput を利用しており、事前に celdiv で分割サイズを指定しておく必要があります。
celload で読み込む画像は SHOW_IN, FOCUS_IN, PRESS_IN に対応する画像を順に並べておいてください。

引数 no に SHOW_IN で使用する分割画像No.を指定することで、FOCUS_IN(+1), PRESS_IN(+2) の画像No.も指定したことになります。

より細かく描画を制御したい場合は、layerbtn_stat, layerbtn_cnt を利用して個別に描画を記述してください。


上記引数の後に続けて、以下引数も指定することができます。
zx3 : ボタン画像ずらし量(x方向)
zy3 : ボタン画像ずらし量(y方向)
rx1 : ボタンサイズによらず画像の表示倍率を強制的に指定(x方向)
ry1 : ボタンサイズによらず画像の表示倍率を強制的に指定(y方向)

%sample
#include "mod_layerbutton.hsp"

celload dir_tv + "btn_hard.png", -1;celid_auto
cel_id = stat
celdiv cel_id, 80, 24
log = ""
pos 50, 50
repeat 3
	pos ,ginfo_cy+10
	bt_opt += 100
	layerbutton 180,60, bt_opt, 0, 30,20,5, 15,10,2 {
		if lparam != objlayer_cmddraw : return  ; _cmddraw以外無視
		font msgothic,16,1 : color 240,240,255 : objcolor 0,0,100  ; 文字色 / 縁取り色
		laybtn_ezcel cel_id, 0, "ezcelボタン "+objlayer_option,4, 0,-1, 0,3  ; ボタン描画
		if layerbtn_stat != LAYBTN_COMPLETE_SELECTED : return  ; 押したボタン以外無視
		log += "LAYBTN_COMPLETE_SELECTED" +"\n"
		log += "- OPT="+objlayer_option+", ObjID="+wparam +"\n"
		return
	}
loop
repeat
	redraw 0 : color 255,255,255 : boxf : color : pos 0, 0 : font msgothic, 16
	mes log
	redraw 1
	await 1000/60
loop

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_ezbox
layerbuttonの角丸長方形による簡単描画
%group
画面制御命令
%prm
id,no,"strings",zx1,zy1,zx2,zy2, r
col1=$000000〜$FFffffff(0) : 通常表示 ARGB形式 カラーコード値
col2=$000000〜$FFffffff(0) : フォーカス時 ARGB形式 カラーコード値
col3=$000000〜$FFffffff(0) : 押し込み時 ARGB形式 カラーコード値
"strings" : 表示するメッセージ、または変数
sw=0〜(0) : mesオプション[mes命令と同様]
zx1 : 文字を中心位置からずらす量(x方向)
zy1 : 文字を中心位置からずらす量(y方向)
zx2 : ボタン押し込み時に文字をさらにずらす量(x方向)
zy2 : ボタン押し込み時に文字をさらにずらす量(y方向)
r=0〜(Auto) : 長方形の角の丸みサイズ R(アール)

%inst
layerbuttonはサブルーチン内で layerbtn_stat の各種状態に合わせてユーザーが描画処理をする必要があります。
この命令を利用することで「表示」「フォーカス」「決定」「非表示」の一連の描画処理を1命令で簡易的に指定できます。

gsquare を用いた半透明塗りつぶしを利用しています。
引数 col1, col2, col3 にそれぞれ通常表示、フォーカス時、押し込み時のカラーコードを ARGB形式で指定します。
$FFffffff は #AARRGGBB 形式であり、先頭の FF(AA)部が不透明度(アルファ値)を表します。
なお、$RRGGBB のようにアルファ値 AA を省略するなどして 00 が指定された場合は、 アルファ値 $FF(255) を補完し、 0xFFRRGGBB として解釈します。

自動で角丸長方形を描画しますが、引数 r で角の丸みサイズを変更でき、0 にすると矩形を描画します。

より細かく描画を制御したい場合は、layerbtn_stat, layerbtn_cnt を利用して個別に描画を記述してください。


上記引数の後に続けて、以下引数も指定することができます。
zx3 : ボタン全体のずらし量(x方向)
zy3 : ボタン全体のずらし量(y方向)
sx1 : ボタンサイズの拡大または縮小ピクセル数(x方向)
sy1 : ボタンサイズの拡大または縮小ピクセル数(y方向)

%sample
#include "mod_layerbutton.hsp"

log = ""
pos 50, 50
repeat 3
	pos ,ginfo_cy+10
	bt_opt += 100
	layerbutton 180,60, bt_opt, 0, 30,10,5, 15,5,2 {
		if lparam != objlayer_cmddraw : return  ; _cmddraw以外無視
		font msgothic,16,1 : color 240,240,255 : objcolor 0,0,100  ; 文字色 / 縁取り色
		laybtn_ezbox $0000FF, $8800FF, $8888FF, "ezboxボタン "+objlayer_option,4  ; ボタン描画
		if layerbtn_stat != LAYBTN_COMPLETE_SELECTED : return  ; 押したボタン以外無視
		log += "LAYBTN_COMPLETE_SELECTED" +"\n"
		log += "- OPT="+objlayer_option+", ObjID="+wparam +"\n"
		return
	}
loop
repeat
	redraw 0 : color 255,255,255 : boxf : color : pos 0,0 : font msgothic,16
	mes log
	redraw 1
	await 1000/60
loop

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_stick
layerbuttonサブルーチン内用キー入力情報取得
%group
拡張入出力制御命令
%prm
p1,p2,p3
p1=変数 : 読み込むための変数
p2=0〜(0) : 非トリガータイプキー指定
p3=0〜1(1) : ウィンドウアクティブチェックON/OFF

%inst
layerbuttonサブルーチン内で独立した stick命令としてキー入力情報を取得できます。

layerbuttonサブルーチン外で標準の stick命令を使用していたとしても併用できます。
もし、layerbutton の1つ1つに laybtn_stick を記述したとしても機能します。

使い方は stick命令のコマンドヘルプを参照してください。

layerbutton だけでなく layerobj のサブルーチン内でも使用できます。

%sample
#include "mod_layerbutton.hsp"

pos 100,100
layerbutton 180,100 {
	laybtn_settings 0,0,1 
	if lparam == objlayer_cmddraw {
		laybtn_stick lb_stk, $3C00F  ; ← laybtn_stick
		if lb_stk != 0 : lb_count++
		stick ng_stk                 ; ← stick : メインループ内で使ってるからうまく取得できない
		if ng_stk != 0 : ng_count++
		color 200,200,255 : boxf objlayer_axis_x, objlayer_axis_y, objlayer_axis_x2, objlayer_axis_y2
		color
		laybtn_mes "laybtn_stick="+lb_stk+"\n検出回数:"+lb_count
		color 255,0,0
		laybtn_mes "\n\n\nNG_stick="+ng_stk+"\n検出回数:"+ng_count +"\n\n↑ 標準のstickは1ループに1回しか検出できません。"
	}
	return
}
repeat
	redraw 0 : color 255,255,255 : boxf : pos 0,0
	stick stk, $3C00F                ; ← メインループでstick使用
	if stk != 0 : count++
	color 160,160,160
	mes "非トリガータイプキー指定 : $3C00F"
	color
	mes "stick="+stk+"\n検出回数:"+count
	redraw 1
	await 1000/60
loop

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat
layerbtn_cnt

%index
laybtn_hitarea
layerbuttonオブジェクトのタッチ範囲を変更して設定する
%group
オブジェクト制御命令
%prm
n, x1,y1, x2,y2, ..., x8,y8
n : 座標データの数
x1,y1〜 : 座標データ (最大8個まで)

%inst
layerbuttonオブジェクトのヒットテスト範囲を任意の形状に変更できます。
laybtn_hitarea 命令は layerbutton サブルーチン{}内の先頭に書いてください。

座標データは、x1,y1, x2,y2, ..., xN,yN の形式で指定します。
指定できる座標点は最大8個までで、八角形までの形状に対応しています。

各座標は、layerbuttonオブジェクトの左上の位置(pos)を基点とした相対座標です。

引数 n に、座標データの数を指定します。

例えば、三角形のヒットエリアを定義するには、以下のように記述します。
laybtn_hitarea 3, 0,0, 100,0, 100,50

また、引数 n に負数を指定すると以下のようなヒットテスト範囲を設定できます。

html{
<table border="1" cellpadding="10">
<tr>
  <td scope="col"><b>引数</b></td>
  <td scope="col"><b>詳細</b></td>
  <td scope="col"><b>タイプ</b></td>
</tr>
<tr>
  <td>-1, x,y, D</td>
  <td>x,y : 中心座標
  <br>D : 直径</td>
  <td>円形</td>
</tr>
<tr>
  <td>-2, x,y, W,H, ang</td>
  <td>x,y : 中心座標
  <br>W : 幅
  <br>H : 高さ
  <br>ang : 角度値(ラジアン) [double値]</td>
  <td>楕円形(角度付き)</td>
</tr>
<tr>
  <td>-3, x,y, W,H, ang</td>
  <td>x,y : 中心座標
  <br>W : 幅
  <br>H : 高さ
  <br>ang : 角度値(ラジアン) [double値]</td>
  <td>長方形(角度付き)</td>
</tr>
<tr>
  <td>-4, x1,y1,D1, x2,y2,D2</td>
  <td>x1,y1 : 中心座標 (1つ目の円)
  <br>D1 : 直径 (1つ目の円)
  <br>x2,y2 : 中心座標 (2つ目の円)
  <br>D2 : 直径 (2つ目の円)</td>
  <td>カプセル型 (2つの円とそれらを結ぶ接線に囲まれた範囲)
  <br>※ 正確な範囲ではなく、近似的な計算によるものです。
  <br>
  <br>x3,y3,D3,...と引数を続けて指定することで、鎖状に最大4つの円までを繋げた範囲として設定できます。</td>
</tr>
</table>
}html

%sample
#include "mod_layerbutton.hsp"

pos 150,100
layerbutton 120,60 {
	// ヒットテスト範囲を設定 : n, x1,y1, x2,y2, ... (座標点は最大8個の八角形まで)
	laybtn_hitarea 3, -50,0, 120,0, 120,60  ; 三角形
	if lparam == objlayer_cmddraw {
		color 230,230,255 : boxf objlayer_axis_x, objlayer_axis_y, objlayer_axis_x2, objlayer_axis_y2  ; オブジェクトの矩形範囲
		color 100,100,100
		if layerbtn_stat == LAYBTN_FOCUS_IN : color 255
		arr = -50,0, 120,0, 120,60
		pos  objlayer_axis_x+arr(0), objlayer_axis_y+arr(1)  ; ヒット範囲描画
		line objlayer_axis_x+arr(2), objlayer_axis_y+arr(3)
		line objlayer_axis_x+arr(4), objlayer_axis_y+arr(5)
		line objlayer_axis_x+arr(0), objlayer_axis_y+arr(1)
		font msgothic,12
		laybtn_mes "\nヒット範囲 ",0, 2,0
	}
	return
}
repeat
	redraw 0 : color 255,255,255 : boxf : color : pos 0,0
	redraw 1
	await 1000/60
loop

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
layerbtn_stat
layerbtn_cnt

%index
layerbtn_stat
layerbuttonのボタン状態が代入される
%group
拡張システム変数
%prm

%inst
layerbutton のサブルーチン内で利用するもので、ボタンの現在の状態が代入されています。

ボタンの状態には以下のものがあります。
html{
<table border="1" cellpadding="10">
<tr>
  <td scope="col"><b>layerbtn_stat</b></td>
  <td scope="col"><b>値</b></td>
  <td scope="col"><b>状態</b></td>
</tr>
<tr>
  <td>LAYBTN_SHOW_IN</td>
  <td>2</td>
  <td>ボタンの表示を開始。</td>
</tr>
<tr>
  <td>LAYBTN_FOCUS_IN</td>
  <td>4</td>
  <td>フォーカス状態。マウスを乗せたり、キー入力でフォーカスさせたとき。</td>
</tr>
<tr>
  <td>LAYBTN_FOCUS_OUT</td>
  <td>8</td>
  <td>フォーカス状態解除。マウスをボタン外に移動させたり、キー入力で別のボタンにフォーカスを移動させたとき。</td>
</tr>
<tr>
  <td>LAYBTN_PRESS_IN</td>
  <td>16</td>
  <td>ボタンを押し込んだ状態。ボタンをクリックしている間や、エンターキー等でボタンを決定したとき。</td>
</tr>
<tr>
  <td>LAYBTN_PRESS_IN_SELECTED</td>
  <td>17</td>
  <td>ボタンが決定した瞬間のみ。
  <br>※ laybtn_settings命令で設定を「ボタンを押した後に非表示(SHOW_OUT)処理させない」にしている場合にのみ呼び出される。
  <br>※ 「決定した瞬間」とは、マウスの場合はクリックして離した瞬間、キーボードの場合は押した瞬間です。</td>
</tr>
<tr>
  <td>LAYBTN_PRESS_OUT</td>
  <td>32</td>
  <td>ボタンを押し込んだ状態を解除。ボタンをクリックしたままマウスをボタン外に移動させたとき。</td>
</tr>
<tr>
  <td>LAYBTN_SHOW_OUT</td>
  <td>64</td>
  <td>非表示処理中の状態。ボタンが決定されたあと同一グループのすべてのボタンが非表示(SHOW_OUT)処理を開始する。</td>
</tr>
<tr>
  <td>LAYBTN_SHOW_OUT_SELECTED</td>
  <td>65</td>
  <td>非表示処理中の状態。ボタンが決定されたあと同一グループのすべてのボタンが非表示(SHOW_OUT)処理を開始する。
  <br>グループの中で決定されたボタンのみ_SELECTED状態となる。</td>
</tr>
<tr>
  <td>LAYBTN_COMPLETE</td>
  <td>128</td>
  <td>グループ内のすべてのオブジェクトの非表示(SHOW_OUT)処理がすべて完了したとき。</td>
</tr>
<tr>
  <td>LAYBTN_COMPLETE_SELECTED</td>
  <td>129</td>
  <td>グループ内のすべてのオブジェクトの非表示(SHOW_OUT)処理がすべて完了したとき。
  <br>グループの中で決定されたボタンのみ_SELECTED状態となる。</td>
</tr>
</table>
}html

上記は lparam が objlayer_cmddraw のときのものです。
lparam が objlayer_cmdterm のときは以下になります。

html{
<table border="1" cellpadding="10">
<tr>
  <td scope="col">layerbtn_stat</td>
  <td scope="col">値</td>
  <td scope="col">状態</td>
</tr>
<tr>
  <td>LAYBTN_GROUP_DELETED</td>
  <td>256</td>
  <td>グループ内のボタンの非表示(SHOW_OUT)処理が完了して、すべてのオブジェクトが削除されたとき。</td>
</tr>
</table>
}html

%sample

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_cnt

%index
layerbtn_cnt
layerbuttonのボタン状態が変更されてからの経過フレーム数
%group
拡張システム変数
%prm

%inst
layerbutton のサブルーチン内で利用するもので、ボタンの状態が変更されて何フレーム目かの値が代入されます。

%sample

%href
layerbutton
laybtn_settings
laybtn_mes
laybtn_ease
laybtn_hide
laybtn_length
laybtn_enable
laybtn_width
laybtn_focus
laybtn_stick
laybtn_ezcel
laybtn_ezbox
laybtn_hitarea
layerbtn_stat


%
// /hs ファイル /////////////////////////////////////////////////////////////

================================================================================
- Changelogs
--------------------------------------------------------------------------------
 1.1      2025/ 9/24
---------------------
- mod_layerbutton-keybd.hspとsample12を同梱
- laybtn_focus命令を追加
- laybtn_settingsにボタン間移動や決定を押しっぱなしで連続入力できる機能を追加
- laybtn_ezboxにおけるアール部の計算処理を高速化
- layerbtn_stickVarシステム変数を追加
- laybtn_ezboxのPRESS_OUTの表示処理に誤りがあったのを修正
- キーボード操作によるボタンフォーカスの移動先計算を再修正
- LAYBTN_GROUP_DELETEDが環境によっては2回呼ばれてしまうバグを修正
- その他の細かい箇所の変更と修正

 1.0.2    2025/ 9/13
---------------------
- laybtn_ezboxでPRESS_OUT描画時に一部の色が正しく表示されない不具合を修正
- キーボード操作によるボタンフォーカスの移動先計算を微修正
- その他の細かい箇所の変更と修正

 1.0.1    2025/ 9/10
---------------------
- 環境によって発生していたタッチID判定処理の不具合を修正

 1.0      2025/ 9/ 9
---------------------
- 公開
================================================================================
#endif