# mod_layerbutton-vpad.hsp

common\ mod_layerbutton-vpad.hsp

    /* /////////////////////////////////////////////////////////////////////////////
    mod_layerbutton-vpad モジュール
    --------------------------------------------------------------------------------
    %dll ; モジュール名
    mod_layerbutton-vpad
    %ver ; バージョン
    1.1
    %date ; 更新日
    2026/1/7
    %author ; 著作者
    MIZUSHIKI
    %note
    layerbutton命令を利用してバーチャルパッドを作成 (mod_layerbuttonのおまけモジュール)
    %type
    拡張命令
    %url
    https://suwa.pupu.jp/HSP/index.html
    %port ; 対応環境
    Win
    */ /////////////////////////////////////////////////////////////////////////////
    #if 0
    %index ;========================================================================
    AnalogCon
    アナログパッドコントローラを作成
    %group ;------------------------------------------------------------------------
    オブジェクト制御命令
    %prm   ;------------------------------------------------------------------------
    p1,p2,p3,p4,p5,p6,p7
    p1=0〜(0) : パッド画像素材を持つウインドウID (要celdiv)
    p2=0〜(0) : パッドのノブ画像素材を持つウインドウID (要celdiv)
    p3=0.0〜 : コントローラの表示倍率(実数)
    p4=0〜(0) : layerbuttonのグループID
    p5=変数 : アナログコントローラのX軸の入力値が格納される変数を登録
    p6=変数 : アナログコントローラのY軸の入力値が格納される変数を登録
    p7=0,1(0) : オプション-範囲外まで動かしたとき本体を追従させる
    %inst  ;------------------------------------------------------------------------
    p1,p2の画像素材は、あらかじめceldivによって分割しておく必要があります。
    celdivの第4,第5引数による中心座標も必ず指定しておいてください。
    画像は「通常/フォーカス/押下」の3状態を並べて用意することで、各状態に応じた表示が可能です。
    通常状態の画像1枚だけを用意して3状態すべてで兼用することもできます。
    （2枚の場合は「通常」と「フォーカス／押下」の2状態として扱われます。）

    p7のオプションに1を指定すると、ノブを範囲外まで動かした際に本体も追従します。
    この設定により、反転操作でノブを逆方向へ動かす際に、例え初期位置から離れていても常に一定のスライド量で反対側まで操作できるといった利点があります。

    laybtn_enableで無効にするとコントローラは表示されなくなり、有効に戻すと再び表示されます。

    ※ AnalogCon特有の仕様として、p4表示倍率はdouble型配列も指定できます。
       その場合、配列の各要素が以下の通りに割り当てられます。
       [ 0:SHOW, 1:FOCUS, 2:PRESS ]
    %href  ;-----------------------------------------------------------------------
    JujikeyCon
    ButtonCon
    BeanCon

    %index ;========================================================================
    JujikeyCon
    十字キーコントローラを作成
    %group ;------------------------------------------------------------------------
    オブジェクト制御命令
    %prm   ;------------------------------------------------------------------------
    p1,p2,p3,p4,p5,p6
    p1=0〜(0) : 十字キー画像素材を持つウインドウID (要celdiv)
    p2=0〜(0) : 十字キーどうしの隙間
    p3=0.0〜 : コントローラの表示倍率(実数)
    p4=0〜(0) : layerbuttonのグループID
    p5=変数 : 十字キーコントローラの入力値が格納される変数を登録
    p6=0〜(0) : 非トリガータイプキー指定
    %inst  ;------------------------------------------------------------------------
    p1の画像素材は、あらかじめceldivで分割しておく必要があります。
    画像は「通常/フォーカス/押下」の3状態を並べたものを、さらに「左上右下」の順に繋げて、合計で12分割の画像になるようにします。
    「左上右下」で同じ画像を使用する場合は、「通常/フォーカス/押下」の3状態1組を用意するだけで、全方向に共通して適用されます。

    p5で登録した変数には、キーの押下状態が毎フレーム更新されます。
    代入される値はstick命令と同じで、「左:1」「上:2」「右:4」「下:8」の値を合算したものとなります。
    また、p6もstick命令と同様の設定であり、非トリガータイプキー指定を行うことで、押しっぱなしの状態も検出可能です。

    laybtn_enableで無効にするとコントローラは表示されなくなり、有効に戻すと再び表示されます。
    %href  ;------------------------------------------------------------------------
    AnalogCon
    ButtonCon
    BeanCon

    %index ;========================================================================
    ButtonCon
    4ボタンコントローラの作成
    %group ;------------------------------------------------------------------------
    オブジェクト制御命令
    %prm   ;------------------------------------------------------------------------
    p1,p2,p3,p4,p5,p6
    p1=0〜(0) : ボタン画像素材を持つウインドウID (要celdiv)
    p2=0〜(0) : ボタンどうしの隙間
    p3=0.0〜 : コントローラの表示倍率(実数)
    p4=0〜(0) : layerbuttonのグループID
    p5=変数 : ボタンコントローラの入力値が格納される変数を登録
    p6=0〜(0) : 非トリガータイプキー指定
    %inst  ;------------------------------------------------------------------------
    p1の画像素材は、あらかじめceldivで分割しておく必要があります。
    画像は「通常/フォーカス/押下」3状態を並べたものを、さらに「左側/上側/右側/下側」の順に繋げて、合計で12分割の画像になるようにします。
    「左側/上側/右側/下側」で同じ画像を使用する場合は、「通常/フォーカス/押下」の3状態1組を用意するだけで、全方向に共通して適用されます。

    p5で登録した変数には、ボタンの押下状態が毎フレーム更新されます。
    代入される値はJujikeyConと同じように、「左側:1」「上側:2」「右側:4」「下側:8」の値を合算したものとなります。
    また、p6もJujikeyConと同様の設定であり、非トリガータイプキー指定を行うことで、押しっぱなしの状態も検出可能です。

    laybtn_enableで無効にするとコントローラは表示されなくなり、有効に戻すと再び表示されます。

    ※ ボタンに文字やマークを表示させたい場合は、各ボタン用の画像を用意するのが手っ取り早いです。
    %href  ;------------------------------------------------------------------------
    AnalogCon
    JujikeyCon
    BeanCon

    %index ;========================================================================
    BeanCon
    長方形型の1ボタンコントローラ(角度指定可能)の作成
    %group ;------------------------------------------------------------------------
    オブジェクト制御命令
    %prm   ;------------------------------------------------------------------------
    p1,p2,p3,p4,p5,p6
    p1=0〜(0) : 回転させて使うボタン画像素材を持つウインドウID (要celdiv)
    p2=0.0〜 : 角度値(ラジアン)
    p3=0.0〜 : コントローラの表示倍率(実数)
    p4=0〜(0) : layerbuttonのグループID
    p5=変数 : ボタンコントローラの入力値が格納される変数を登録
    p6=0,1(0) : 非トリガータイプキー指定
    %inst  ;------------------------------------------------------------------------
    p1の画像素材は、あらかじめceldivで分割しておく必要があります。
    回転処理に必要なのでceldivの第4,第5引数の中心座標も必ず指定しておいてください。
    画像は「通常/フォーカス/押下」の3状態を並べたものを用意してください。

    p2で回転角度を指定できますが、回転されるのは画像とヒットエリアのみであり、objlayer_axis_xなどのオブジェクトの座標/サイズ値は変化しません。
    また、(M_PI*2)以上を指定した場合は楕円形のヒットエリアとして扱われます。

    p5で登録した変数には、ボタンの押下状態が毎フレーム更新されます。
    押されたときには1が代入されます。
    p6の非トリガータイプキーに1を指定することで、押しっぱなしの状態も検出可能です。

    laybtn_enableで無効にするとコントローラは表示されなくなり、有効に戻すと再び表示されます。
    %href  ;------------------------------------------------------------------------
    AnalogCon
    JujikeyCon
    ButtonCon
    % ;=============================================================================
    #endif

    #include "mod_layerbutton.hsp"

    #ifndef AnalogCon

    #module modlaybtn_vpad
    celx=0:cely=0:celofsx=0:celofsy=0:celmax=0:_arA=0:num_Analogpad=0:num_jujikey=0:num_btnkey=0:num_beankey=0  ; 未初期化警告避け
    #define global AnalogCon(%1=0,%2=0,%3,%4=0,%5,%6,%7=0) if pChk@modlaybtn_vpad("%3"){dup _arA@modlaybtn_vpad,%3:AnalogCon@modlaybtn_vpad %1,%2,-1.0,%4,%5,%6,%7}else{AnalogCon@modlaybtn_vpad %1,%2,%3,%4,%5,%6,%7}
    #deffunc AnalogCon@modlaybtn_vpad int cel_pad, int cel_nub, double ratio, int group, var out_ax, var out_ay, int zurizuri
    	getCelSize@modlaybtn cel_pad, celx, cely, celofsx, celofsy, celmax
    	out_ax = 0.0 : out_ay = 0.0
    	ratio_ = ratio
    	if ratio != -1.0 {
    		d_ana(num_Analogpad*7) = 0.0, 0.0, 0.0, 0.0, double(ratio), double(ratio), double(ratio)
    	}else {
    		d_ana(num_Analogpad*7) = 0.0, 0.0, 0.0, 0.0, double(_arA(0)), double(_arA(limit(1,0,length(_arA)-1))), double(_arA(limit(2,0,length(_arA)-1)))
    		ratio_ = double(_arA(0))
    	}
    	i_ana(num_Analogpad*6) = cel_pad, cel_nub, group, zurizuri, varptr(out_ax), varptr(out_ay)
    	pos ginfo_cx-s4n5(ratio_*celx/2), ginfo_cy-s4n5(ratio_*cely/2)
    	layerbutton s4n5(ratio_*celx),s4n5(ratio_*cely), num_Analogpad,group {
    		laybtn_settings 3, 28, 37
    		laybtn_hitarea -1, objlayer_size_x/2,objlayer_size_y/2, objlayer_size_x  ; 円形ヒットエリア
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_ana(objlayer_option*6+2), -1
    			if stat == 0 : return  ; disenable時は描画しない
    			if layerbtn_clickx!=-1 && layerbtn_clicky!=-1 {  ; クリック/タッチ中 (ポーズ時は操作させない)
    				layerbtn_clickx_ = double(layerbtn_clickx) + d_ana(objlayer_option*7+2)
    				layerbtn_clicky_ = double(layerbtn_clicky) + d_ana(objlayer_option*7+3)
    				rr = double(objlayer_size_x)/2  ; スティックが動く範囲の半径
    				dx = -layerbtn_clickx_ + layerbtn_mousex
    				dy = -layerbtn_clicky_ + layerbtn_mousey
    				_dist = dx*dx + dy*dy
    				if _dist > rr*rr {
    					dist = sqrt(_dist)
    					layerbtn_mousex_ = double(dx * rr) / dist + layerbtn_clickx_
    					layerbtn_mousey_ = double(dy * rr) / dist + layerbtn_clicky_
    					if i_ana(objlayer_option*6+3) : d_ana(objlayer_option*7+2)-=layerbtn_mousex_-layerbtn_mousex : d_ana(objlayer_option*7+3)-=layerbtn_mousey_-layerbtn_mousey
    				}else{
    					layerbtn_mousex_ = double(layerbtn_mousex)
    					layerbtn_mousey_ = double(layerbtn_mousey)
    				}
    				// パッドのアナログ値
    				d_ana(objlayer_option*7+0) = (layerbtn_mousex_ - (layerbtn_clickx_))*2 / objlayer_size_x
    				d_ana(objlayer_option*7+1) = (layerbtn_mousey_ - (layerbtn_clicky_))*2 / objlayer_size_y
    				// 表示用の補正
    				layerbtn_mousex_ -= objlayer_size_x/2
    				layerbtn_mousey_ -= objlayer_size_y/2
    				layerbtn_clickx_ -= objlayer_size_x/2
    				layerbtn_clicky_ -= objlayer_size_y/2
    			}else {
    				d_ana(objlayer_option*7+2)=0.0 : d_ana(objlayer_option*7+3)=0.0
    				d_ana(objlayer_option*7+0)=0.0 : d_ana(objlayer_option*7+1)=0.0
    				// 表示用の補正
    				layerbtn_mousex_ = 0.0
    				layerbtn_mousey_ = 0.0
    				layerbtn_clickx_ = layerbtn_mousex_
    				layerbtn_clicky_ = layerbtn_mousey_
    			}
    			// pad, nub 描画
    			switch (layerbtn_stat|1^1)  ; _SELECTED状態を除去して分岐 [(layerbtn_stat & $FFFE)でもOK]
    			case LAYBTN_FOCUS_IN : ratio_ = d_ana(objlayer_option*7+4+1) : swbreak
    			case LAYBTN_PRESS_IN : ratio_ = d_ana(objlayer_option*7+4+2) : swbreak
    			default : ratio_ = d_ana(objlayer_option*7+4+0)
    			swend
    			laybtn_ezcel i_ana(objlayer_option*6+0), 0,,,,,,, layerbtn_clickx_, layerbtn_clicky_, ratio_,ratio_  ; ezcelの裏技 : 第9引数から ボタン画像ずらし量, 強制倍率 を指定できる
    			laybtn_ezcel i_ana(objlayer_option*6+1), 0,,,,,,, layerbtn_mousex_, layerbtn_mousey_, ratio_,ratio_
    			dupptr out_ax_, i_ana(objlayer_option*6+4), 8, 3
    			dupptr out_ay_, i_ana(objlayer_option*6+5), 8, 3
    			out_ax_ = d_ana(objlayer_option*7+0)
    			out_ay_ = d_ana(objlayer_option*7+1)
    		}
    		return
    	}
    	num_Analogpad++
    	return

    #deffunc JujikeyCon int cel_juji, int sukima, double ratio, int group, var out_key, int trig
    	getCelSize@modlaybtn cel_juji, celx, cely, celofsx, celofsy, celmax
    	pxConL = ginfo_cx : pyConL = ginfo_cy : ratio_ = ratio
    	i_juji(num_jujikey*6) = cel_juji, celmax, group, varptr(out_key), trig, 0
    	; 左
    	pos pxConL-s4n5(ratio*(celx+sukima)), pyConL-s4n5(ratio*(cely/2))
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_jujikey,group {
    		laybtn_settings 3,12,37  ; 設定 : ボタン外からスライドしてもクリック + ボタンを押しても消さない
    		laybtn_hitarea 5, 0,0, objlayer_size_x/2,-objlayer_size_y/2, objlayer_size_x-ratio_*8,objlayer_size_y/2, objlayer_size_x/2,objlayer_size_y*3/2, 0,objlayer_size_y  ; ヒットエリア調整 : 斜め入力できるように
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_juji(objlayer_option*6+2), -1
    			if stat : laybtn_ezcel i_juji(objlayer_option*6+0),(0\i_juji(objlayer_option*6+1))  ; ボタン描画 (disenable時は描画しない)
    			_out_key = 0  ; 初期化 (オブジェクトIDが並んでいるので左〜下は順番に一気に呼び出されるから、一時変数として使っても混線しない)
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key |= 1
    		}
    		return
    	}
    	; 上
    	pos pxConL-s4n5(ratio*(celx/2)), pyConL-s4n5(ratio*(cely+sukima))
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_jujikey,group {
    		laybtn_settings 3,12,37  ; 設定 : ボタン外からスライドしてもクリック + ボタンを押しても消さない
    		laybtn_hitarea 5, 0,0, objlayer_size_x,0, objlayer_size_x*3/2,objlayer_size_y/2, objlayer_size_x/2,objlayer_size_y-ratio_*8, -objlayer_size_x/2,objlayer_size_y/2  ; ヒットエリア調整 : 斜め入力できるように
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_juji(objlayer_option*6+2), -1
    			if stat : laybtn_ezcel i_juji(objlayer_option*6+0),(3\i_juji(objlayer_option*6+1))  ; ボタン描画 (disenable時は描画しない)
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key |= 2
    		}
    		return
    	}
    	; 右
    	pos pxConL+s4n5(ratio*sukima), pyConL-s4n5(ratio*cely/2)
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_jujikey,group {
    		laybtn_settings 3,12,37  ; 設定 : ボタン外からスライドしてもクリック + ボタンを押しても消さない
    		laybtn_hitarea 5, ratio_*8,objlayer_size_y/2, objlayer_size_x/2,-objlayer_size_y/2, objlayer_size_x,0, objlayer_size_x,objlayer_size_y, objlayer_size_x/2,objlayer_size_y*3/2  ; ヒットエリア調整 : 斜め入力できるように
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_juji(objlayer_option*6+2), -1
    			if stat : laybtn_ezcel i_juji(objlayer_option*6+0),(6\i_juji(objlayer_option*6+1))  ; ボタン描画 (disenable時は描画しない)
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key |= 4
    		}
    		return
    	}
    	; 下
    	pos pxConL-s4n5(ratio*celx/2), pyConL+s4n5(ratio*sukima)
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_jujikey,group {
    		laybtn_settings 3,12,37  ; 設定 : ボタン外からスライドしてもクリック + ボタンを押しても消さない
    		laybtn_hitarea 5, objlayer_size_x/2,ratio_*8, objlayer_size_x*3/2,objlayer_size_y/2, objlayer_size_x,objlayer_size_y, 0,objlayer_size_y, -objlayer_size_x/2,objlayer_size_y/2  ; ヒットエリア調整 : 斜め入力できるように
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_juji(objlayer_option*6+2), -1
    			if stat : laybtn_ezcel i_juji(objlayer_option*6+0),(9\i_juji(objlayer_option*6+1))  ; ボタン描画 (disenable時は描画しない)
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key |= 8
    			dupptr out_key_, i_juji(objlayer_option*6+3), 4, 4  ; 最後のオブジェクトなのでout_keyを書き換える
    			out_key_ = (_out_key | i_juji(objlayer_option*6+5) ^ i_juji(objlayer_option*6+5)) | (_out_key & i_juji(objlayer_option*6+4))
    			i_juji(objlayer_option*6+5) = _out_key  ; 前回のkeyを記憶
    		}
    		return
    	}
    	num_jujikey++
    	return

    #deffunc ButtonCon int cel_btn, int sukima, double ratio, int group, var out_key, int trig
    	getCelSize@modlaybtn cel_btn, celx, cely, celofsx, celofsy, celmax
    	pxConL=ginfo_cx : pyConL=ginfo_cy : ratio_=ratio : sukima_=sukima
    	i_btn(num_btnkey*6) = cel_btn, celmax, group, varptr(out_key), trig, 0
    	; 左
    	pos pxConL-(ratio*(celx+sukima)), pyConL-(ratio*(cely/2))
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_btnkey,group {
    		laybtn_settings 3,12,37  ; 設定 : 同グループ押下中ならボタン外からスライドしてもクリック + ボタンを押しても消さない
    		laybtn_hitarea -4, (objlayer_size_x/2+ratio_*sukima_)/4+objlayer_size_x/2,-(objlayer_size_y/2+ratio_*sukima_)/4+objlayer_size_y/2,objlayer_size_x, objlayer_size_x/2,objlayer_size_y/2,objlayer_size_x, (objlayer_size_x/2+ratio_*sukima_)/4+objlayer_size_x/2,(objlayer_size_y/2+ratio_*sukima_)/4+objlayer_size_y/2,objlayer_size_x  ; ヒットエリア調整 : 斜め入力できるように
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_btn(objlayer_option*6+2), -1
    			if stat : laybtn_ezcel i_btn(objlayer_option*6+0),(0\i_btn(objlayer_option*6+1))  ; ボタン描画 (disenable時は描画しない)
    			_out_key = 0  ; 初期化 (オブジェクトIDが並んでいるので左〜下は順番に一気に呼び出されるから、一時変数として使っても混線しない)
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key |= 1
    		}
    		return
    	}
    	; 上
    	pos pxConL-(ratio*(celx/2)), pyConL-(ratio*(cely+sukima))
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_btnkey,group {
    		laybtn_settings 3,12,37  ; 設定 : 同グループ押下中ならボタン外からスライドしてもクリック + ボタンを押しても消さない
    		laybtn_hitarea -4, -(objlayer_size_x/2+ratio_*sukima_)/4+objlayer_size_x/2,(objlayer_size_y/2+ratio_*sukima_)/4+objlayer_size_y/2,objlayer_size_x, objlayer_size_x/2,objlayer_size_y/2,objlayer_size_x, (objlayer_size_x/2+ratio_*sukima_)/4+objlayer_size_x/2,(objlayer_size_y/2+ratio_*sukima_)/4+objlayer_size_y/2,objlayer_size_x  ; ヒットエリア調整 : 斜め入力できるように
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_btn(objlayer_option*6+2), -1
    			if stat : laybtn_ezcel i_btn(objlayer_option*6+0),(3\i_btn(objlayer_option*6+1))  ; ボタン描画 (disenable時は描画しない)
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key |= 2
    		}
    		return
    	}
    	; 右
    	pos pxConL+(ratio*sukima), pyConL-(ratio*cely/2)
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_btnkey,group {
    		laybtn_settings 3,12,37  ; 設定 : 同グループ押下中ならボタン外からスライドしてもクリック + ボタンを押しても消さない
    		laybtn_hitarea -4, -(objlayer_size_x/2+ratio_*sukima_)/4+objlayer_size_x/2,-(objlayer_size_y/2+ratio_*sukima_)/4+objlayer_size_y/2,objlayer_size_x, objlayer_size_x/2,objlayer_size_y/2,objlayer_size_x, -(objlayer_size_x/2+ratio_*sukima_)/4+objlayer_size_x/2,(objlayer_size_y/2+ratio_*sukima_)/4+objlayer_size_y/2,objlayer_size_x  ; ヒットエリア調整 : 斜め入力できるように
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_btn(objlayer_option*6+2), -1
    			if stat : laybtn_ezcel i_btn(objlayer_option*6+0),(6\i_btn(objlayer_option*6+1))  ; ボタン描画 (disenable時は描画しない)
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key |= 4
    		}
    		return
    	}
    	; 下
    	pos pxConL-(ratio*celx/2), pyConL+(ratio*sukima)
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_btnkey,group {
    		laybtn_settings 3,12,37  ; 設定 : 同グループ押下中ならボタン外からスライドしてもクリック + ボタンを押しても消さない
    		laybtn_hitarea -4, -(objlayer_size_x/2+ratio_*sukima_)/4+objlayer_size_x/2,-(objlayer_size_y/2+ratio_*sukima_)/4+objlayer_size_y/2,objlayer_size_x, objlayer_size_x/2,objlayer_size_y/2,objlayer_size_x, (objlayer_size_x/2+ratio_*sukima_)/4+objlayer_size_x/2,-(objlayer_size_y/2+ratio_*sukima_)/4+objlayer_size_y/2,objlayer_size_x  ; ヒットエリア調整 : 斜め入力できるように
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_btn(objlayer_option*6+2), -1
    			if stat : laybtn_ezcel i_btn(objlayer_option*6+0),(9\i_btn(objlayer_option*6+1))  ; ボタン描画 (disenable時は描画しない)
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key |= 8
    			dupptr out_key_, i_btn(objlayer_option*6+3), 4, 4  ; 最後のオブジェクトなのでout_keyを書き換える
    			out_key_ = (_out_key | i_btn(objlayer_option*6+5) ^ i_btn(objlayer_option*6+5)) | (_out_key & i_btn(objlayer_option*6+4))
    			i_btn(objlayer_option*6+5) = _out_key  ; 前回のkeyを記憶
    		}
    		return
    	}
    	num_btnkey++
    	return

    #deffunc BeanCon int cel_bean, double rad, double ratio, int group, var out_key, int trig
    	getCelSize@modlaybtn cel_bean, celx, cely, celofsx, celofsy, celmax
    	rad_=rad
    	i_bean(num_beankey*6) = cel_bean, celmax, group, varptr(out_key), trig, 0
    	d_bean(num_beankey*2) = ratio, rad
    	pos ginfo_cx-(ratio*celx/2), ginfo_cy-(ratio*cely/2)
    	layerbutton s4n5(ratio*celx),s4n5(ratio*cely), num_beankey,group {
    		laybtn_settings 3,12,37  ; 設定 : 同グループ押下中ならボタン外からスライドしてもクリック + ボタンを押しても消さない
    		if lparam == objlayer_cmdinit {
    			if rad_ < M_PI*2 {
    				laybtn_hitarea -3, objlayer_size_x/2,objlayer_size_y/2, objlayer_size_x,objlayer_size_y, rad_  ; ヒットエリア
    			}else: if objlayer_size_x == objlayer_size_y {
    				laybtn_hitarea -1, objlayer_size_x/2,objlayer_size_y/2, objlayer_size_x  ; 円形ヒットエリア
    			}else {
    				laybtn_hitarea -2, objlayer_size_x/2,objlayer_size_y/2, objlayer_size_x,objlayer_size_y, rad_  ; 楕円形ヒットエリア
    			}
    		}
    		if lparam == objlayer_cmddraw {
    			laybtn_enable i_bean(objlayer_option*6+2), -1
    			if stat {  ; ボタン描画 (disenable時は描画しない)
    				pos objlayer_axis_x+objlayer_size_x/2, objlayer_axis_y+objlayer_size_y/2
    				switch (layerbtn_stat|1^1)  ; _SELECTED状態を除去して分岐 [(layerbtn_stat & $FFFE)でもOK]
    				case LAYBTN_FOCUS_IN : id_celdiv = 1 : swbreak
    				case LAYBTN_PRESS_IN : id_celdiv = 2 : swbreak
    				default : id_celdiv = 0
    				swend
    				celput i_bean(objlayer_option*6+0), limit(id_celdiv,0,i_bean(objlayer_option*6+1)-1), d_bean(objlayer_option*2+0),d_bean(objlayer_option*2+0), d_bean(objlayer_option*2+1)
    			}
    			if layerbtn_stat & LAYBTN_PRESS_IN : _out_key = 1 : else : _out_key = 0
    			dupptr out_key_, i_bean(objlayer_option*6+3), 4, 4  ; out_keyを書き換える
    			out_key_ = (_out_key | i_bean(objlayer_option*6+5) ^ i_bean(objlayer_option*6+5)) | (_out_key & i_bean(objlayer_option*6+4))
    			i_bean(objlayer_option*6+5) = _out_key  ; 前回のkeyを記憶
    		}
    		return
    	}
    	num_beankey++
    	return
    #defcfunc local s4n5 double p1
    	if p1<0 : return int(p1-0.5)
    	return int(p1+0.5)

    //関数に渡されたパラメータが変数か確認する
    #defcfunc pChk@modlaybtn_vpad str _chkStr
    	chkStr = _chkStr : chkShift = 0
    	chkStr = strtrim(chkStr,3)
    	flg = 0
    	repeat strlen(chkStr)
    		if 'a'<=peek(chkStr,cnt)&&peek(chkStr,cnt)<='z' :flg=1 :continue
    		if 'A'<=peek(chkStr,cnt)&&peek(chkStr,cnt)<='Z' :flg=1 :continue
    		if peek(chkStr,cnt)=='_' :flg=1 :continue
    		if peek(chkStr,cnt)=='@' :flg=1 :continue
    		if flg=0 : break
    		if '0'<=peek(chkStr,cnt)&&peek(chkStr,cnt)<='9' :continue
    		flg = 0 : break
    	loop
    	return flg
    #global

    #endif