code:
;汎用顔グラ制御スクリプト
@HO_PORTRAIT_MANAGE_COMMON(CHARA_ID, CALL_FROM, DIC_OPTIONS)
#DIM CHARA_ID
#DIMS CALL_FROM
#DIMS DIC_OPTIONS
#DIMS DYNAMIC RGB, 3
#DIM CONST CSTR_IDX_START = CSTR_PORTRAIT_IMG_IDX
#DIM  DYNAMIC PRESET_IDX
#DIMS DYNAMIC SET_PARTS, FACE_LAYERNUM
#DIMS DYNAMIC LIST_COLOR_MATRIX
#DIM  DYNAMIC LAYER_IDX
#DIM  DYNAMIC MIXER, 3, 3
#DIMS CONST MIXER_NAME = "R", "G", "B"
#DIMS CONST SID = "CC1"
#DIM  DYNAMIC ITER_I
#DIM  DYNAMIC ITER_J

IF CALL_FROM == "PORTRAIT_EDIT"
	PRESET_IDX = CLOTH_DRAWER_SELECT_PRESET
ELSE
	PRESET_IDX = CFLAG:CHARA_ID:衣装プリセット
ENDIF
;対象のポートレイトプリセットが無効の場合は通常プリセットを使用
IF FACE_PARTS_PRESET_IS_VALID:CHARA_ID:PRESET_IDX
	FACE_PARTS_PRESET_IDX:CHARA_ID:0 = PRESET_IDX
ELSE
	FACE_PARTS_PRESET_IDX:CHARA_ID:0 = 衣装プリセット_通常
ENDIF
CALL RESET_FACE_SPRITE(CHARA_ID)

;DUMMY指定ならRETURN
SIF CSTR:CHARA_ID:キャラ顔グラ == "FACE_DUMMY" && CFLAG:CHARA_ID:ポートレイト画像タイプ == 0 && CSTR:CHARA_ID:(CSTR_IDX_START + IMG_顔) == ""
	RETURN 0
;差分なし固定
IF CFLAG:CHARA_ID:ポートレイト画像タイプ == 2
	IF !SPRITECREATED(CSTR:CHARA_ID:キャラ顔グラ)
		CALL スプライト生成(@"portrait/prt_FIX/%CSTR:CHARA_ID:キャラ顔グラ%", CSTR:CHARA_ID:キャラ顔グラ)
		IF !RESULT
			CSTR:CHARA_ID:キャラ顔グラ '= "FACE_DUMMY"
			RETURN 0
		ENDIF
	ENDIF
	RETURN 2
ENDIF

;CSVにポートレイト情報が定義されている場合。初回のみCSVからポートレイト情報を読み込む
IF CSTR:CHARA_ID:(CSTR_IDX_START + IMG_顔) != "" && !CFLAG:CHARA_ID:ポートレイト情報初回読込
	FOR LOCAL, 0, FACE_LAYERNUM
		SIF CSTR:CHARA_ID:(CSTR_IDX_START + LOCAL) == ""
			CONTINUE
		FACE_PARTS:CHARA_ID:LOCAL = %CSTR:CHARA_ID:(CSTR_IDX_START + LOCAL)%
	NEXT
	FOR LOCAL, 0, FACE_LAYERNUM
		LAYER_IDX = (CSTR_IDX_START + FACE_LAYERNUM + LOCAL)
		SIF CSTR:CHARA_ID:LAYER_IDX == ""
			CONTINUE
		SPLIT CSTR:CHARA_ID:LAYER_IDX, ":", RGB
		IF RESULT > 1
			;'#'区切りのデータの場合','に変換しミキサー指定とみなす
			CSTR:CHARA_ID:LAYER_IDX = %REPLACE(CSTR:CHARA_ID:LAYER_IDX, "#", ",")%
			IF LIST_COUNT(CSTR:CHARA_ID:LAYER_IDX) > 0
				COLOR_MATRIX_NAME:CHARA_ID:LOCAL '= "ミキサー"
				FOR ITER_I, 0, 3
					LIST_COLOR_MATRIX = %LIST_GET(CSTR:CHARA_ID:LAYER_IDX, ITER_I)%
					SPLIT LIST_COLOR_MATRIX, ":", RGB
					FOR ITER_J, 0, 3
						SETVAR @"COLOR_MIXER_%MIXER_NAME:ITER_J%_{ITER_I}:{CHARA_ID}:{LOCAL}:0", TOINT(RGB:ITER_J)
					NEXT
				NEXT
			ELSE
				COLOR_MATRIX_NAME:CHARA_ID:LOCAL '= "カスタム"
				COLOR_MATRIX_RGB:CHARA_ID:LOCAL:0 = TOINT(RGB:0)
				COLOR_MATRIX_RGB:CHARA_ID:LOCAL:1 = TOINT(RGB:1)
				COLOR_MATRIX_RGB:CHARA_ID:LOCAL:2 = TOINT(RGB:2)
			ENDIF
		ELSE
			COLOR_MATRIX_NAME:CHARA_ID:LOCAL = %CSTR:CHARA_ID:LAYER_IDX%
		ENDIF
		;位置調整情報
		FOR ITER_I, 0, FACE_LAYERNUM
			LAYER_IDX = (CSTR_IDX_START + 2 * FACE_LAYERNUM + ITER_I)
			SIF CSTR:CHARA_ID:LAYER_IDX == ""
				CONTINUE
			CALL DIC_KEYS(CSTR:CHARA_ID:LAYER_IDX)
			FOR ITER_J, 0, RESULT
				;DEBUGPRINTFORML %@"%RESULTS:ITER_J%:{CHARA_ID}:{ITER_I}"% = {DIC_GETINT(CSTR:CHARA_ID:LAYER_IDX, RESULTS:ITER_J)}
				SETVAR @"%RESULTS:ITER_J%:{CHARA_ID}:{ITER_I}", DIC_GETINT(CSTR:CHARA_ID:LAYER_IDX, RESULTS:ITER_J)
			NEXT
		NEXT
	NEXT
	IF FACE_PARTS:CHARA_ID:IMG_鼻 == ""
		CALL SET_FACE_DEFAULT_NOSE_PARTS(CHARA_ID)
	ENDIF
	CFLAG:CHARA_ID:ポートレイト情報初回読込 = 1
ENDIF

;パーツ生成
IF FACE_PARTS:CHARA_ID:IMG_顔 == ""
	CALL SET_FACE_SPRITE(CHARA_ID, "FACE_DUMMY")
	CSTR:CHARA_ID:キャラ顔グラ '= "FACE_DUMMY"
	RETURN 0
ENDIF

;身体基本パーツ
CALL SET_FACEIMG(CHARA_ID, IMG_顔, FACE_PARTS:CHARA_ID:IMG_顔)
CALL SET_FACEIMG(CHARA_ID, IMG_身体, FACE_PARTS:CHARA_ID:IMG_身体)
CALL SET_FACEIMG(CHARA_ID, IMG_後髪, FACE_PARTS:CHARA_ID:IMG_後髪)
CALL SET_FACEIMG(CHARA_ID, IMG_前髪, FACE_PARTS:CHARA_ID:IMG_前髪)
CALL SET_FACEIMG(CHARA_ID, IMG_エクステ, FACE_PARTS:CHARA_ID:IMG_エクステ)
CALL SET_FACEIMG(CHARA_ID, IMG_インナーヘア, FACE_PARTS:CHARA_ID:IMG_インナーヘア)
CALL SET_FACEIMG(CHARA_ID, IMG_頭部位, FACE_PARTS:CHARA_ID:IMG_頭部位)
CALL SET_FACEIMG(CHARA_ID, IMG_化粧, FACE_PARTS:CHARA_ID:IMG_化粧)

;汎用パーツから服飾などの外装をセット
CALL SET_FACE_COMMON_OUTFIT(CHARA_ID, SID, PRESET_IDX, SET_PARTS, CALL_FROM)

;表情設定
CALL FACE_COMMON_CC1(CHARA_ID, CALL_FROM, DIC_OPTIONS)

RETURN 1

@FACE_COMMON_CC1(CHARA_ID, CALL_FROM, DIC_OPTIONS)
#DIM CHARA_ID
#DIMS CALL_FROM
#DIMS DIC_OPTIONS
#DIMS CONST SID = "CC1"
#DIMS DYNAMIC SPRITE_NAME
#DIMS DYNAMIC OVL, 10
#DIM  DYNAMIC OVL_CNT
#DIM GID
#DIMS EYE_PARTS_NAME
#DIMS BROW_PARTS_NAME
#DIMS NOSE_PARTS_NAME
#DIMS MOUTH_PARTS_NAME

#DIMS DYNAMIC EMOTIONS

CALL DEL_FACEOVL(CHARA_ID)

;;予め基本の顔グラをセットしておく
;目パーツの定義がされていない場合は、0番パーツを適用する
EYE_PARTS_NAME = %FACE_PARTS:CHARA_ID:IMG_目%
SIF EYE_PARTS_NAME == ""
	EYE_PARTS_NAME '= "CC1_目_0"
BROW_PARTS_NAME = %FACE_PARTS:CHARA_ID:IMG_眉%
SIF BROW_PARTS_NAME == ""
	BROW_PARTS_NAME '= "CC1_眉_0"
NOSE_PARTS_NAME = %FACE_PARTS:CHARA_ID:IMG_鼻%
SIF NOSE_PARTS_NAME == ""
	NOSE_PARTS_NAME '= "CC1_鼻_0"
MOUTH_PARTS_NAME = %FACE_PARTS:CHARA_ID:IMG_口%
SIF MOUTH_PARTS_NAME == ""
	MOUTH_PARTS_NAME '= "CC1_口_0"

CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_通常")
CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_通常")
CALL SET_FACEIMG(CHARA_ID, IMG_鼻, @"%NOSE_PARTS_NAME%")
CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_通常")

SIF CALL_FROM == "ステータス画面"
	RETURN

IF CALL_FROM == "PORTRAIT_EDIT"
	CALL DRAW_FACE_SET_FACEIMG(CHARA_ID, SID, DIC_OPTIONS)
	RETURN
ENDIF

IF CALL_FROM != "DRAW_FACE"
	EMOTIONS = %TOSTR_EMOTION(CHARA_ID)%
ELSE
	EMOTIONS = %DIC_GET(DIC_OPTIONS, "感情")%
ENDIF

SELECTCASE EMOTIONS
	CASE "幸"
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("細目/閉じ(緩)/閉じ(張)/閉じ(張)")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("通常/リラックス/弛緩")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("通常/笑い/笑い")%")
	CASE "悦","良"
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("通常/通常/細目/閉じ(緩)")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("通常/リラックス/弛緩")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("通常/笑い/笑い")%")
	CASE "平"
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("通常/通常/通常/細目")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("通常/通常/リラックス")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("通常/通常/笑い")%")
	CASE "恨","怒","憤"
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("通常/細目/通常/閉じ(緩)")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("怒り")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("怒り/怒り/むす/叫び")%")
	CASE "鬱","悲","憂"
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("通常/細目/閉じ(緩)/閉じ(緩)")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("困り/困り/怒り")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("むす/むす/叫び/あっ")%")
	CASE "狂","恐","怯"
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("通常/閉じ(張_涙)/閉じ(緩)/閉じ(張_涙)")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("困り/困り/しわよせ/しわよせ強")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("むす/むす/叫び/あっ/くいしばり/くいしばり")%")
		SIF GET_FACEIMG(CHARA_ID, IMG_目) != @"%EYE_PARTS_NAME%_閉じ(張_涙)"
			CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_涙")
	CASEELSE
ENDSELECT

IF  CALL_FROM == "DRAW_FACE"
	CALL DRAW_FACE_SET_FACEIMG(CHARA_ID, SID, DIC_OPTIONS)
	RETURN
ENDIF

IF TOSTR_EMOTION(CHARA_ID) == "幸" && IS_LOVER(CHARA_ID)
	IF GET_PALAMLV(PALAM:(CHARA_ID):欲情) > 3
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("細目(発情)/細目(発情)/じと/細目")%")
		CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_赤面")
		IF FLAG:ウフフフラグ
			SIF RAND:3
				CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_吐息")
		ENDIF
	ENDIF
ENDIF

IF CALL_FROM == "コマンド実行後"
	IF IS_SERVEAT(CHARA_ID, "口")
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("細目/閉じ(緩)/閉じ(張)/閉じ(張)")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("通常/むす/舌出し小/あっ/舌出し大/舌出し(唾液)/舌出し(唾液)")%")
		IF IS_SERVEAT(CHARA_ID, "口", "キス")
			CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("通常/むす/むす")%")
			CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_赤面")
		ENDIF
		IF  SUM_NOWEX(CHARA_ID) > 0
			CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("細目(発情)/閉じ(張)/閉じ(張)")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("むす/舌出し小/舌出し(唾液)/舌出し(唾液)/あっ")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("困り/困り/しわよせ")%")
			SIF GET_FACEIMG(CHARA_ID, IMG_目) != "%EYE_PARTS_NAME%_閉じ(張_涙)"
				CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_涙")
			CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_赤面")
			CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_吐息")
			SIF !RAND:3
				CALL SET_FACEOVL(CHARA_ID, OVL_漫符2, "CC1_OVL_漫符_ハート")
			SIF !RAND:3
				CALL SET_FACEOVL(CHARA_ID, OVL_漫符1, "CC1_OVL_漫符_絶頂")
		ENDIF
		GOTO SETSPRITE_COM_AFTER_END
	ENDIF
	IF GROUPMATCH(SELECTCOM, T_N("待機"),T_N("休憩をとる")) && (IS_MTAR(CHARA_ID) || IS_MPLY(CHARA_ID))
		IF GROUPMATCH(TOSTR_EMOTION(CHARA_ID), "幸","悦","良")
			CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("通常/閉じ(緩)/閉じ(緩)")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("通常/リラックス/弛緩")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("通常")%")
		ENDIF
	ENDIF
	IF GROUPMATCH(SELECTCOM, T_N("頭を撫でる"),T_N("髪を梳く"),T_N("櫛で梳かす")) && (IS_MTAR(CHARA_ID) || IS_MPLY(CHARA_ID))
		IF GROUPMATCH(TOSTR_EMOTION(CHARA_ID), "幸","悦","良")
			CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("閉じ(緩)/閉じ(緩)")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("通常/リラックス/弛緩")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("通常/笑い")%")
		ENDIF
	ENDIF
	;絶頂
	SELECTCASE SUM_NOWEX(CHARA_ID)
		CASE 1
			CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("通常/閉じ(張_涙)/細目/閉じ(張_涙)/閉じ(緩)/絶頂")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("困り/困り/しわよせ/弛緩")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("むす/むす/叫び/あっ")%")
			CALL SET_FACEOVL(CHARA_ID, OVL_表情, @"CC1_OVL_表情_%S_R("吐息//")%")
			CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_赤面")
		CASE IS >= 2
			CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("細目(発情)/細目(発情)/閉じ(張_涙)/閉じ(緩)/閉じ(緩)/絶頂/絶頂")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("困り/困り/しわよせ/しわよせ強")%")
			CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("くいしばり/くいしばり/むす/舌出し大/舌出し(唾液)/舌出し(唾液)/叫び/あっ")%")
			CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_吐息")
			CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_赤面")
		CASEELSE
	ENDSELECT
	;漫符など
	IF SUM_NOWEX(CHARA_ID) > 1
		CALL SET_FACEOVL(CHARA_ID, OVL_漫符1, "CC1_OVL_漫符_絶頂")
		IF GROUPMATCH(TOSTR_EMOTION(CHARA_ID), "幸","悦")
			CALL SET_FACEOVL(CHARA_ID, OVL_漫符2, "CC1_OVL_漫符_ハート")
		ENDIF
	ENDIF
	$SETSPRITE_COM_AFTER_END
	;挿入を伴う強絶頂
	IF (IS_V_HOLD(CHARA_ID) || IS_A_HOLD(CHARA_ID)) && SUM_NOWEX(CHARA_ID) >= 7 && !RAND:3
		CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("しわよせ/しわよせ強")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("アヘ_涙/アヘ_涙/アヘ_涙/絶頂_涙/閉じ(張_涙)")%")
		CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("くいしばり/くいしばり/くいしばり/舌出し(唾液)/舌出し(唾液)")%")
		CALL SET_FACEOVL(CHARA_ID, OVL_漫符1, "CC1_OVL_漫符_絶頂")
		CALL SET_FACEOVL(CHARA_ID, OVL_漫符2, "CC1_OVL_漫符_ハート")
		CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_赤面")
		CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_吐息", 1)
	ENDIF
ENDIF
;痛み
IF SOURCE:CHARA_ID:苦痛 > 100
	CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("困り/しわよせ/しわよせ強")%")
	CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%S_R("くいしばり/くいしばり/くいしばり/舌出し(唾液)/舌出し(唾液)/叫び/叫び")%")
	IF SOURCE:CHARA_ID:苦痛 > 300
		CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("閉じ(張_涙)/閉じ(張_涙)/閉じ(緩)/絶頂_涙")%")
	ENDIF
ENDIF
;失神、気絶
IF TCVAR:CHARA_ID:行動不能フラグ || TCVAR:CHARA_ID:失神フラグ || TCVAR:CHARA_ID:離脱フラグ == 離脱フラグ_睡眠
	CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%S_R("困り/困り/しわよせ/弛緩")%")
	CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_NAME%_%S_R("閉じ(緩)")%")
ENDIF

;咥え物系処理
IF !RAND:4 && C_COND("行動:休憩中,設備用途:お茶", "AND", CHARA_ID)
	CALL SET_FACEIMG(CHARA_ID, IMG_口, @"CC1_口_通常")
	CALL SET_FACEIMG(CHARA_ID, IMG_咥物, @"CC1_咥物_菓子_{RAND:4}")
ENDIF

;目隠し
IF IS_EQUIP_TARGET(CHARA_ID, T_N("目隠し"))
	CALL SET_FACEIMG(CHARA_ID, IMG_マスク1, "CC1_マスク1_目隠し_2")
ENDIF

;口枷
IF IS_EQUIP_TARGET(CHARA_ID, T_N("口枷"))
	CALL SET_FACEIMG(CHARA_ID, IMG_口, @"CC1_口_通常")
	CALL SET_FACEIMG(CHARA_ID, IMG_咥物, "CC1_咥物_口枷_0")
ENDIF

IF GET_PALAMLV(PALAM:(CHARA_ID):欲情) > 6 || TCVAR:CHARA_ID:媚薬
	;吐息重ねがけ
	SIF !RAND:2
		CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_吐息", 1)
ENDIF
IF GET_PALAMLV(PALAM:(CHARA_ID):欲情) > 5 || TCVAR:CHARA_ID:媚薬 || IS_DRUNK(CHARA_ID)
	;赤面重ねがけ
	CALL SET_FACEOVL(CHARA_ID, OVL_表情, "CC1_OVL_表情_赤面", 1)
ENDIF

;汁
LOCAL = (CUM_GET_AMOUNT:CHARA_ID:射精部位_顔 + CUM_GET_AMOUNT:CHARA_ID:射精部位_髪)
SELECTCASE LOCAL
	CASE 1 TO 20
		CALL SET_FACEOVL(CHARA_ID, OVL_汁, "CC1_OVL_汁_ぶっかけ1")
	CASE IS >= 21
		CALL SET_FACEOVL(CHARA_ID, OVL_汁, "CC1_OVL_汁_ぶっかけ1")
		CALL SET_FACEOVL(CHARA_ID, OVL_汁, "CC1_OVL_汁_ぶっかけ2")
ENDSELECT

;効果
{
	IF (FLAG:調教モード == 調教_居住区 && IS_SERVEAT(CHARA_ID, "口", "フェラ"))
		|| TCVAR:CHARA_ID:奉仕者フラグ ==  奉仕_手コキフェラ
}
	CALL HO_CHECK_USE_MODULE_ELEMENT(MASTER, "机")
	IF RESULT
		CALL SET_FACEOVL(CHARA_ID, OVL_効果, "UC7_OVL_効果_物陰")
	ENDIF
ENDIF

;矛盾するパーツの組み合わせがセットされている場合、ここで解消する
IF EXIST_FACEIMG(CHARA_ID, "涙")
	IF EXIST_FACEOVL(CHARA_ID, "涙")
		CALL DEL_FACEOVL(CHARA_ID, OVL_表情, "涙")
	ENDIF
ENDIF

;目パーツを参照しデフォルトの鼻パーツを設定
@SET_FACE_DEFAULT_NOSE_PARTS(CHARA_ID)
#DIM CHARA_ID

IF FACE_PARTS:CHARA_ID:IMG_鼻 == "" && FACE_PARTS:CHARA_ID:IMG_目 != ""
	SELECTCASE FACE_PARTS:CHARA_ID:IMG_目
		CASE "CC1_目_10", "CC1_目_12",
			FACE_PARTS:CHARA_ID:IMG_鼻 '= "CC1_鼻_1"
		CASE "CC1_目_8"
			FACE_PARTS:CHARA_ID:IMG_鼻 '= "CC1_鼻_2"
		CASE "CC1_目_4", "CC1_目_5", "CC1_目_6", "CC1_目_11", "CC1_目_14", "CC1_目_15"
			FACE_PARTS:CHARA_ID:IMG_鼻 '= "CC1_鼻_3"
		CASEELSE
			FACE_PARTS:CHARA_ID:IMG_鼻 '= "CC1_鼻_0"
	ENDSELECT
ENDIF


code:
;-------------------------------------------------
;;; ポートレイト生成系関数
;-------------------------------------------------
;-------------------------------------------------
;;; ポートレイトパーツ抽選
;;; 指定されたパーツ名のパーツをランダムに抽選する
;;; 画像管理.ERHにあらかじめパターン数を定義しておく必要がある
;-------------------------------------------------
@PORTRAIT_SELECT_RANDOM_PARTS(CHARA_ID, PARTS_NAME)
#DIM  CHARA_ID
#DIMS PARTS_NAME
#DIMS DYNAMIC PARTS_CANDIDATES_NAME, 100
#DIM  DYNAMIC PARTS_CANDIDATES, 100
#DIM  DYNAMIC MAX_PARTS_NUM
#DIM  DYNAMIC CANDIDATE_COUNT
#DIMS DYNAMIC PARTS_DEF_NAME
#DIM  DYNAMIC PARTS_INDEX
#DIM  DYNAMIC IS_EXCLUDED
#DIM  DYNAMIC EXCLUDE_INDEX
#DIM  DYNAMIC SELECTED_INDEX
#DIMS DYNAMIC EXCLUDE_VAR_NAME

; パーツ名に基づいて最大パーツ数を決定
IF EXISTVAR(@"IMG_%PARTS_NAME%パーツ数")
    MAX_PARTS_NUM = GETVAR(@"IMG_%PARTS_NAME%パーツ数")
ELSE
    RETURN 0
ENDIF

; 除外リスト変数名を構築
EXCLUDE_VAR_NAME '= @"IMG_ランダム生成除外_%PARTS_NAME%"

; 除外リストを考慮して候補パーツを追加
CANDIDATE_COUNT = 0
FOR PARTS_INDEX, 0, MAX_PARTS_NUM
    PARTS_DEF_NAME '= @"CC1_%PARTS_NAME%_{PARTS_INDEX}"
    IS_EXCLUDED = 0

    ; 除外リストをチェック
    IF EXISTVAR(EXCLUDE_VAR_NAME)
        FOR EXCLUDE_INDEX, 0, VARSIZE(EXCLUDE_VAR_NAME)
            ; 除外リスト内の空要素はスキップ
            SIF GETVARS(@"%EXCLUDE_VAR_NAME%:{EXCLUDE_INDEX}") == ""
                CONTINUE
            ; 現在のパーツIDが除外リストに含まれているかチェック
            IF PARTS_DEF_NAME == GETVARS(@"%EXCLUDE_VAR_NAME%:{EXCLUDE_INDEX}")
                IS_EXCLUDED = 1
                BREAK
            ENDIF
        NEXT
    ENDIF

    ; 除外されていなければ候補に追加
    IF !IS_EXCLUDED
        PARTS_CANDIDATES:CANDIDATE_COUNT = PARTS_INDEX
        PARTS_CANDIDATES_NAME:CANDIDATE_COUNT = %PARTS_DEF_NAME%
        CANDIDATE_COUNT ++
    ENDIF
NEXT

SIF !CANDIDATE_COUNT
    RETURN 0

; 候補からランダムに選択
SELECTED_INDEX = PARTS_CANDIDATES:(RAND:CANDIDATE_COUNT)
RESULTS = %PARTS_CANDIDATES_NAME:(SELECTED_INDEX)%
RETURN SELECTED_INDEX

repo_name: napo/erafl

license: unknown


code:
;-------------------------------------------------
;UI描画関連の関数
;-------------------------------------------------
;水平線描画
@DRAW_LINE(STRLINE = "―",COLORCODE = -1, LENGTH = 0)
#DIMS STRLINE
#DIM COLORCODE
#DIM CURRENT_COLOR
#DIM LENGTH

SIF COLORCODE == -1
    COLORCODE = カラー_白

IF LENGTH == 0
    CURRENT_COLOR = GETCOLOR()
    SETCOLOR COLORCODE
    DRAWLINEFORM %STRLINE%
    SETCOLOR CURRENT_COLOR
ELSE
    SIF IS_ZENKAKU(STRLINE)
        LENGTH = LENGTH / 2

    CALLF TAG_PRINT(@"@C:{COLORCODE}@%STRLINE%@/C@" * LENGTH, 1)
ENDIF

@DRAW_LINEH(LENGTH, COLORCODE = -1, STRLINE = "―")
#FUNCTIONS
#DIMS STRLINE
#DIM COLORCODE
#DIM LENGTH

SIF COLORCODE == -1
    COLORCODE = カラー_白
RETURNF @"%STRLINE * LENGTH%"

;;;出力済みのプリント行のうち、残す行を取得
@PRINTLINE_RESERVE()
#DIM DYNAMIC FIRST_LINE
SYS_RESERVE_LINE = LINECOUNT

;;;PRINTLINE_RESRVEを実行した以降をクリア
@PRINTLINE_CLEAR()
CLEARLINE LINECOUNT - SYS_RESERVE_LINE

;================================================================
; カラーバー用の文字列を生成する(HTML_PRINT用)
; @FuncTagSetText_CreateColorBarText　を改変させていただきました
;--------------------------------
;[引数]
;	nBarVol			: バー現在値
;	nBarVolMax		: バー最大値（0以下指定だとnBarVolと同値として扱う）
;	nScaleNum		: 目盛数（半角文字の個数）
;	colorLeft		: バーの左端の色
;	colorRigth		: バーの右端(100%)の色
;	colorEmpty		: バーのEmpty部分の色
;	flgExtra		: 特殊表示フラグ（ビット演算。）
;						0x01	: カラーバーの後ろに現在値と最大値を記述する	" ({nBarVol,5}/{nBarVolMax,5})"
;	strScaleText	: メモリ文字（半角文字。未指定時は%UNICODE(0x2586)%）
;--------------------------------
;[戻り値など]
;	カラーバー用の文字列（色指定タグと■で構成された文字列）
;================================================================
@COLOR_BAR_H( nBarVol, nBarVolMax, nScaleNum, colorLeft, colorRigth, colorEmpty, flgExtra, strScaleText = "" )
#FUNCTIONS
#DIM  nBarVol
#DIM  nBarVolMax
#DIM  nScaleNum
#DIM  colorLeft
#DIM  colorRigth
#DIM  colorEmpty
#DIM  flgExtra
#DIMS strScaleText

#DIM  colorLeft_RGB, 3
#DIM  colorRigth_RGB, 3
#DIM  colorCalc_RGB, 3
#DIM  colorBuf
#DIM  flgEmpty
#DIM  nLoop
#DIMS strBarText

IF STRLENS( strScaleText ) <= 0
    strScaleText '= UNICODE(0x2586)
    ;strScaleText '= UNICODE(0x220E) ;長方形縦長(隙間あり)
    ;strScaleText '= UNICODE(0x2588) ;
    ;strScaleText '= UNICODE(0x2585)
ENDIF

VARSET strBarText, ""

colorLeft_RGB:0 = colorLeft / 256 / 256
colorLeft_RGB:1 = colorLeft / 256 % 256
colorLeft_RGB:2 = colorLeft % 256
colorRigth_RGB:0 = colorRigth / 256 / 256
colorRigth_RGB:1 = colorRigth / 256 % 256
colorRigth_RGB:2 = colorRigth % 256

flgEmpty = 0
FOR nLoop, 0, nScaleNum
    IF nBarVol > nLoop * nBarVolMax / nScaleNum
        colorCalc_RGB:0 = (colorRigth_RGB:0 - colorLeft_RGB:0) * nLoop / MAX( nScaleNum - 1 )
        colorCalc_RGB:1 = (colorRigth_RGB:1 - colorLeft_RGB:1) * nLoop / MAX( nScaleNum - 1 )
        colorCalc_RGB:2 = (colorRigth_RGB:2 - colorLeft_RGB:2) * nLoop / MAX( nScaleNum - 1 )
        colorBuf = FuncColor_ChangeColor( colorLeft, colorCalc_RGB:0, colorCalc_RGB:1, colorCalc_RGB:2 )
        strBarText += @""
    ELSE
        IF flgEmpty == 0
            strBarText += @""
            flgEmpty = 1
        ENDIF
    ENDIF
    strBarText += strScaleText
    IF flgEmpty == 0 || nLoop == nScaleNum - 1
        strBarText += @""
    ENDIF
NEXT

IF (flgExtra & 0x01) > 0
    strBarText += @" ({nBarVol,5}/{nBarVolMax,5})"
ENDIF

RETURNF strBarText


code:
@HO_SET_PORTRAIT_SPRITE(CHARA_ID, CALL_FROM = "", IS_VISIBLE = 1, DIC_OPTIONS = "")
#DIM CHARA_ID
#DIMS CALL_FROM
#DIM IS_VISIBLE
#DIMS DIC_OPTIONS

;口上側で専用の顔グラ出力基準を定義しているならそちらを使う
;定義サンプル @K7_固有顔グラ管理
TRYCCALLFORM K{NO:CHARA_ID}_固有顔グラ管理(CHARA_ID, CALL_FROM, DIC_OPTIONS)
CATCH
    CALL HO_PORTRAIT_MANAGE_COMMON(CHARA_ID, CALL_FROM, DIC_OPTIONS)
ENDCATCH

IF  CSTR:CHARA_ID:キャラ顔グラ != "FACE_DUMMY" && CFLAG:CHARA_ID:ポートレイト画像タイプ == 0
    ;パーツ生成ポートレイト固有処理
    ;-------------------------------------------------
    ;グローリーホール、懺悔室の陰オーバーレイ
    IF C_COND("設備:450,設備:453","OR", CHARA_ID) && TFLAG:奉仕モード
        IF GROUPMATCH(TCVAR:CHARA_ID:奉仕者フラグ, 奉仕_口淫, 奉仕_手コキフェラ, 奉仕_フェラのみ)
            CALL SET_FACEOVL(CHARA_ID, OVL_効果, "顔_効果_物陰_2")
        ENDIF
    ELSEIF TFLAG:覗き見モード
        CALL SET_FACEOVL(MASTER, OVL_効果, "顔_効果_物陰_2")
    ENDIF

    ;編集した顔グラを適用
    ;セットしたパーツ情報からスプライトを作成
    CALL SET_FACE_SPRITE(CHARA_ID)
    ;出力スプライト名をキャラクター変数に格納
    CSTR:CHARA_ID:キャラ顔グラ = %RESULTS%
ENDIF

;見えないキャラは薄くする
{
    IF FLAG:ハウジングモード
        && !FLAG:クエストモード
        && CSTR:CHARA_ID:キャラ顔グラ != "FACE_DUMMY"
        && CFLAG:CHARA_ID:ポートレイト画像タイプ == 0
}
    IF !IS_VISIBLE && CHARA_ID != MASTER && !TCVAR:CHARA_ID:覗き見対象
        CALL 画像複製(@"FACE_{CHARA_ID}_SHADOW", CSTR:CHARA_ID:キャラ顔グラ, "影", 256)
        CSTR:CHARA_ID:キャラ顔グラ '= @"FACE_{CHARA_ID}_SHADOW"
    ENDIF
ENDIF

RETURN

;調教画面のポートレート表示部上部の画像サイズ切替ボタンを押下した際に呼び出される。
;Ｖの場合10～200の範囲で入力値を倍率として設定する
@HO_PORTRAIT_SIZE_SETTING(INPUT_VALUE)
#DIM INPUT_VALUE
PORTRAIT_サイズ設定値 = INPUT_VALUE
PORTRAIT_倍率 = PORTRAIT_サイズ設定定義:PORTRAIT_サイズ設定値

IF PORTRAIT_倍率 == 0
    PRINTFORML ポートレイトの表示倍率を数値で入力してください(10\%～200\%)
    WHILE 1
        INPUT
        IF !INRANGE(RESULT, 10, 200)
            PRINTFORMW 値が不正です
        ELSE
            PORTRAIT_倍率 = RESULT
            BREAK
        ENDIF
    WEND
ENDIF

;NPC顔グラパーツの初期設定
@RANDOM_CHARA_CREATE_PORTRAIT(CHARA_ID)
#DIM CHARA_ID
#DIMS DYNAMIC 髪色
#DIMS DYNAMIC 肌色
#DIMS DYNAMIC 瞳色
#DIM  DYNAMIC 服装IDX

CALL INIT_FACE_SPRITE(CHARA_ID)
VARSET FACE_PARTS:CHARA_ID:0, ""

;パーツ形状
FACE_PARTS:CHARA_ID:IMG_顔 '= @"CC1_顔_{RAND:2}"
FACE_PARTS:CHARA_ID:IMG_後髪 '= @"CC1_後髪_{RAND:IMG_後髪パーツ数}"
IF IS_FEMALE(CHARA_ID)
    FACE_PARTS:CHARA_ID:IMG_身体 '= "CC1_身体_0"
ELSE
    FACE_PARTS:CHARA_ID:IMG_身体 '= "CC1_身体_1"
ENDIF
FACE_PARTS:CHARA_ID:IMG_前髪 '= @"CC1_前髪_{RAND:IMG_前髪パーツ数}"
CALL PORTRAIT_SELECT_RANDOM_PARTS(CHARA_ID, "目")
FACE_PARTS:CHARA_ID:IMG_目 '= @"CC1_目_{RESULT}"
IF RESULT > 0 ;目パーツ0番は目と瞳が一体化しているので瞳をセットしない
    FACE_PARTS:CHARA_ID:IMG_瞳 '= @"CC1_瞳_{RESULT}"
ENDIF
;眉
CALL PORTRAIT_SELECT_RANDOM_PARTS(CHARA_ID, "眉")
FACE_PARTS:CHARA_ID:IMG_眉 '= @"CC1_眉_{RESULT}"

;鼻
CALL PORTRAIT_SELECT_RANDOM_PARTS(CHARA_ID, "鼻")
FACE_PARTS:CHARA_ID:IMG_鼻 '= @"CC1_鼻_{RESULT}"

;口
CALL PORTRAIT_SELECT_RANDOM_PARTS(CHARA_ID, "口")
FACE_PARTS:CHARA_ID:IMG_口 '= @"CC1_口_{RESULT}"

IF TALENT:CHARA_ID:動物耳
    FACE_PARTS:CHARA_ID:IMG_頭部位 '= @"CC1_頭部位_ケモミミ_{RAND:2}"
ENDIF

;パーツの色
;髪
髪色 = %S_R("白/黄/赤/緑/青/黒/栗/桃/橙")%
COLOR_MATRIX_NAME:CHARA_ID:IMG_後髪 = %髪色%
COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪 = %髪色%
COLOR_MATRIX_NAME:CHARA_ID:IMG_眉 = %髪色%
;肌
SIF !RAND:3
    肌色 '= "褐色"
COLOR_MATRIX_NAME:CHARA_ID:IMG_身体 = %肌色%
COLOR_MATRIX_NAME:CHARA_ID:IMG_顔 = %肌色%
;瞳
瞳色 = %S_R("白/黄/赤/緑/青/黒/栗/桃/橙")%
COLOR_MATRIX_NAME:CHARA_ID:IMG_瞳 = %瞳色%
;頭部位
IF TALENT:CHARA_ID:動物耳
    COLOR_MATRIX_NAME:CHARA_ID:IMG_頭部位 = %髪色%
ENDIF

;服
服装IDX = RAND(0, VARSIZE("IMG_服_パーツ名"))
FACE_PARTS:CHARA_ID:IMG_服 '= @"CC1_服_%IMG_服_パーツ名:服装IDX%_{RAND(0, IMG_服_パターン数:服装IDX)}"

CSTR:CHARA_ID:キャラ顔グラ '= @"FACE_{CHARA_ID}"

;顔グラパーツの色編集
@EDIT_PORTRAIT_PARTS_COLOR(CHARA_ID, EDIT_PARTS_NAME, PRESET_IDX = 0)
#DIM CHARA_ID
#DIMS EDIT_PARTS_NAME
#DIM  PRESET_IDX
#DIM  DYNAMIC PARTS_IDX
#DIM  DYNAMIC COLOR_MATRIX, 5, 5
#DIMS DYNAMIC CURRENT_COLOR_PRESET
#DIM  DYNAMIC COL_RGB, 3
#DIMS SKIN_PRESET_NAME = "白","黄色","褐色","青肌","カスタム"
#DIMS HAIR_PRESET_NAME = "白","黄","赤","緑","青","黒","栗","桃","橙","カスタム"
#DIMS OUTER_PRESET_NAME = "白","黄","赤","緑","青","黒","栗","桃","橙","カスタム", "ミキサー"
#DIMS HAT_PRESET_NAME = "白","黄","赤","緑","青","黒","栗","桃","橙","カスタム", "ミキサー", "髪色と同じ値をセット"
#DIM  DYNAMIC MIXER_RGB, 3, 3
#DIMS DYNAMIC MIXER_NAME = "R", "G", "B"
#DIM  DYNAMIC MIXER_X
#DIM  DYNAMIC MIXER_Y
#DIM  DYNAMIC FIRST_LINE
#DIMS DYNAMIC INPUT_VALUES
#DIM  DYNAMIC IS_CUSTOM_COLOR
#DIM  CONST PRESET_BTN_ID = 100000000

FIRST_LINE = LINECOUNT
$INPUT_LOOP
CALL RESET_FACE_SPRITE(CHARA_ID)
CALL HO_SET_PORTRAIT_SPRITE(CHARA_ID, "PORTRAIT_EDIT")

PRINTFORML ◇指定する色を選択してください
PRINTL

SELECTCASE EDIT_PARTS_NAME
    CASE "SKIN"
        CURRENT_COLOR_PRESET = %COLOR_MATRIX_NAME:CHARA_ID:IMG_顔%
        SIF CURRENT_COLOR_PRESET == ""
            CURRENT_COLOR_PRESET '= "白"
        PRINTFORM プリセット：
        FOR LOCAL, 0, VARSIZE("SKIN_PRESET_NAME")
            IF CURRENT_COLOR_PRESET == SKIN_PRESET_NAME:LOCAL
                CALLF TAG_PRINT(@"@C:{カラー_選択中}@@B:{LOCAL + PRESET_BTN_ID}@\{%SKIN_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
            ELSE
                CALLF TAG_PRINT(@"@C:{カラー_白}@@B:{LOCAL + PRESET_BTN_ID}@\{%SKIN_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
            ENDIF
        NEXT
        IF CURRENT_COLOR_PRESET != "カスタム"
            CALL カラーブレンド取得(COLOR_MATRIX, CURRENT_COLOR_PRESET)
            COL_RGB:0 = COLOR_MATRIX:0:0
            COL_RGB:1 = COLOR_MATRIX:1:1
            COL_RGB:2 = COLOR_MATRIX:2:2
        ELSE
            COL_RGB:0 = COLOR_MATRIX_RGB:CHARA_ID:IMG_顔:0
            COL_RGB:1 = COLOR_MATRIX_RGB:CHARA_ID:IMG_顔:1
            COL_RGB:2 = COLOR_MATRIX_RGB:CHARA_ID:IMG_顔:2
        ENDIF
        PRINTL
    CASE "HAIR"
        CURRENT_COLOR_PRESET = %COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪%
        SIF CURRENT_COLOR_PRESET == ""
            CURRENT_COLOR_PRESET '= "白"
        PRINTFORM プリセット：
        FOR LOCAL, 0, VARSIZE("HAIR_PRESET_NAME")
            IF CURRENT_COLOR_PRESET == HAIR_PRESET_NAME:LOCAL
                CALLF TAG_PRINT(@"@C:{カラー_選択中}@@B:{LOCAL + PRESET_BTN_ID}@\{%HAIR_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
            ELSE
                CALLF TAG_PRINT(@"@C:{カラー_白}@@B:{LOCAL + PRESET_BTN_ID}@\{%HAIR_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
            ENDIF
        NEXT
        IF CURRENT_COLOR_PRESET != "カスタム"
            CALL カラーブレンド取得(COLOR_MATRIX, CURRENT_COLOR_PRESET)
            COL_RGB:0 = COLOR_MATRIX:0:0
            COL_RGB:1 = COLOR_MATRIX:1:1
            COL_RGB:2 = COLOR_MATRIX:2:2
        ELSE
            COL_RGB:0 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:0
            COL_RGB:1 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:1
            COL_RGB:2 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:2
        ENDIF
        PRINTL
    CASE "EYE"
        CURRENT_COLOR_PRESET = %COLOR_MATRIX_NAME:CHARA_ID:IMG_瞳%
        SIF CURRENT_COLOR_PRESET == ""
            CURRENT_COLOR_PRESET '= "白"
        PRINTFORM プリセット：
        FOR LOCAL, 0, VARSIZE("HAIR_PRESET_NAME")
            IF CURRENT_COLOR_PRESET == HAIR_PRESET_NAME:LOCAL
                CALLF TAG_PRINT(@"@C:{カラー_選択中}@@B:{LOCAL + PRESET_BTN_ID}@\{%HAIR_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
            ELSE
                CALLF TAG_PRINT(@"@C:{カラー_白}@@B:{LOCAL + PRESET_BTN_ID}@\{%HAIR_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
            ENDIF
        NEXT
        IF CURRENT_COLOR_PRESET != "カスタム"
            CALL カラーブレンド取得(COLOR_MATRIX, CURRENT_COLOR_PRESET)
            COL_RGB:0 = COLOR_MATRIX:0:0
            COL_RGB:1 = COLOR_MATRIX:1:1
            COL_RGB:2 = COLOR_MATRIX:2:2
        ELSE
            COL_RGB:0 = COLOR_MATRIX_RGB:CHARA_ID:IMG_瞳:0
            COL_RGB:1 = COLOR_MATRIX_RGB:CHARA_ID:IMG_瞳:1
            COL_RGB:2 = COLOR_MATRIX_RGB:CHARA_ID:IMG_瞳:2
        ENDIF
        PRINTL
    CASE "CLOTH", "HAT", "ACCESSORY1", "ACCESSORY2", "GLASSES", "MAKEUP", "NECKLACE", "BROW", "NOSE", "MASK1", "MASK2", "BACK", "HAIR_EX", "HAIR_INNER"
        SELECTCASE EDIT_PARTS_NAME
            CASE "CLOTH"
                PARTS_IDX = IMG_服
            CASE "BROW"
                PARTS_IDX = IMG_眉
            CASE "NOSE"
                PARTS_IDX = IMG_鼻
            CASE "HAIR_EX"
                PARTS_IDX = IMG_エクステ
            CASE "HAIR_INNER"
                PARTS_IDX = IMG_インナーヘア
            CASE "HAT"
                PARTS_IDX = IMG_帽子
            CASE "ACCESSORY1"
                PARTS_IDX = IMG_アクセサリ1
            CASE "ACCESSORY2"
                PARTS_IDX = IMG_アクセサリ2
            CASE "GLASSES"
                PARTS_IDX = IMG_眼鏡
            CASE "MAKEUP"
                PARTS_IDX = IMG_化粧
            CASE "NECKLACE"
                PARTS_IDX = IMG_首飾
            CASE "MASK1"
                PARTS_IDX = IMG_マスク1
            CASE "MASK2"
                PARTS_IDX = IMG_マスク2
            CASE "BACK"
                PARTS_IDX = IMG_背面
        ENDSELECT
        IF !PRESET_IDX
            CURRENT_COLOR_PRESET = %COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX%
        ELSE
            CURRENT_COLOR_PRESET = %COLOR_MATRIX_NAME_PRESET:CHARA_ID:PARTS_IDX:PRESET_IDX%
        ENDIF
        SIF CURRENT_COLOR_PRESET == ""
            CURRENT_COLOR_PRESET '= "白"
        PRINTFORM プリセット：
        IF EDIT_PARTS_NAME == "HAT" || EDIT_PARTS_NAME == "BROW" || EDIT_PARTS_NAME == "HAIR_EX" || EDIT_PARTS_NAME == "HAIR_INNER"
            FOR LOCAL, 0, VARSIZE("HAT_PRESET_NAME")
                IF CURRENT_COLOR_PRESET == HAT_PRESET_NAME:LOCAL
                    CALLF TAG_PRINT(@"@C:{カラー_選択中}@@B:{LOCAL + PRESET_BTN_ID}@\{%HAT_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
                ELSE
                    CALLF TAG_PRINT(@"@C:{カラー_白}@@B:{LOCAL + PRESET_BTN_ID}@\{%HAT_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
                ENDIF
            NEXT
        ELSE
            FOR LOCAL, 0, VARSIZE("OUTER_PRESET_NAME")
                IF CURRENT_COLOR_PRESET == OUTER_PRESET_NAME:LOCAL
                    CALLF TAG_PRINT(@"@C:{カラー_選択中}@@B:{LOCAL + PRESET_BTN_ID}@\{%OUTER_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
                ELSE
                    CALLF TAG_PRINT(@"@C:{カラー_白}@@B:{LOCAL + PRESET_BTN_ID}@\{%OUTER_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
                ENDIF
            NEXT
        ENDIF
        IF CURRENT_COLOR_PRESET != "カスタム" && CURRENT_COLOR_PRESET != "ミキサー"
            CALL カラーブレンド取得(COLOR_MATRIX, CURRENT_COLOR_PRESET)
            COL_RGB:0 = COLOR_MATRIX:0:0
            COL_RGB:1 = COLOR_MATRIX:1:1
            COL_RGB:2 = COLOR_MATRIX:2:2
        ELSEIF CURRENT_COLOR_PRESET == "ミキサー"
            FOR LOCAL, 0, 3
                MIXER_RGB:0:LOCAL = GETVAR(@"COLOR_MIXER_R_{LOCAL}:{CHARA_ID}:{PARTS_IDX}:{PRESET_IDX}")
            NEXT
            FOR LOCAL, 0, 3
                MIXER_RGB:1:LOCAL = GETVAR(@"COLOR_MIXER_G_{LOCAL}:{CHARA_ID}:{PARTS_IDX}:{PRESET_IDX}")
            NEXT
            FOR LOCAL, 0, 3
                MIXER_RGB:2:LOCAL = GETVAR(@"COLOR_MIXER_B_{LOCAL}:{CHARA_ID}:{PARTS_IDX}:{PRESET_IDX}")
            NEXT
        ELSE
            IF !PRESET_IDX
                COL_RGB:0 = COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:0
                COL_RGB:1 = COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:1
                COL_RGB:2 = COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:2
            ELSE
                COL_RGB:0 = COLOR_MATRIX_RGB_PRESET_R:CHARA_ID:PARTS_IDX:PRESET_IDX
                COL_RGB:1 = COLOR_MATRIX_RGB_PRESET_G:CHARA_ID:PARTS_IDX:PRESET_IDX
                COL_RGB:2 = COLOR_MATRIX_RGB_PRESET_B:CHARA_ID:PARTS_IDX:PRESET_IDX
            ENDIF
        ENDIF
        PRINTL
    CASE "HEADSUBPARTS"
        CURRENT_COLOR_PRESET = %COLOR_MATRIX_NAME:CHARA_ID:IMG_頭部位%
        SIF CURRENT_COLOR_PRESET == ""
            CURRENT_COLOR_PRESET '= "白"
        PRINTFORM プリセット：
        FOR LOCAL, 0, VARSIZE("HAT_PRESET_NAME")
            IF CURRENT_COLOR_PRESET == HAT_PRESET_NAME:LOCAL
                CALLF TAG_PRINT(@"@C:{カラー_選択中}@@B:{LOCAL + PRESET_BTN_ID}@\{%HAT_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
            ELSE
                CALLF TAG_PRINT(@"@C:{カラー_白}@@B:{LOCAL + PRESET_BTN_ID}@\{%HAT_PRESET_NAME:LOCAL%\}@/B@@/C@", 4)
            ENDIF
        NEXT
        IF CURRENT_COLOR_PRESET != "カスタム"
            CALL カラーブレンド取得(COLOR_MATRIX, CURRENT_COLOR_PRESET)
            COL_RGB:0 = COLOR_MATRIX:0:0
            COL_RGB:1 = COLOR_MATRIX:1:1
            COL_RGB:2 = COLOR_MATRIX:2:2
        ELSE
            COL_RGB:0 = COLOR_MATRIX_RGB:CHARA_ID:IMG_頭部位:0
            COL_RGB:1 = COLOR_MATRIX_RGB:CHARA_ID:IMG_頭部位:1
            COL_RGB:2 = COLOR_MATRIX_RGB:CHARA_ID:IMG_頭部位:2
        ENDIF
        PRINTL
ENDSELECT
PRINTL

IF CURRENT_COLOR_PRESET != "ミキサー"
    CALL HO_PORTRAIT_EDIT_RGB_SLIDER(((COL_RGB:0 / 2) * 256 * 256) + ((COL_RGB:1 / 2)  * 256) + (COL_RGB:2 / 2))
    PRINTL
ELSE
    CALL HO_PORTRAIT_EDIT_MIXER(MIXER_RGB)
    PRINTL
ENDIF
CALLF TAG_PRINT(@"@B:999999999@[この色で決定]@/B@", 5)

REDRAW 1
ONEINPUTS

IF ISNUMERIC(RESULTS)
    RESULT = TOINT(RESULTS)
    SIF RESULT == 999999999
        RETURN

    IF CURRENT_COLOR_PRESET != "ミキサー"
        IS_CUSTOM_COLOR = 0
        IF RESULT < PRESET_BTN_ID
            COL_RGB:0 = (RESULT / 256 / 256) * 2
            COL_RGB:1 = (RESULT / 256 % 256) * 2
            COL_RGB:2 = (RESULT % 256) * 2
            IS_CUSTOM_COLOR = 1
        ELSE
            RESULT = RESULT - PRESET_BTN_ID
        ENDIF
    ELSE
        IF RESULT < PRESET_BTN_ID
            IF !PRESET_IDX
                COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX = %CURRENT_COLOR_PRESET%
            ELSE
                COLOR_MATRIX_NAME_PRESET:CHARA_ID:PARTS_IDX:PRESET_IDX = %CURRENT_COLOR_PRESET%
            ENDIF
            MIXER_Y = RESULT / 3
            MIXER_X = RESULT % 3
            PRINTFORML 値を入力(-200％～200％)
            INPUT
            SETVAR @"COLOR_MIXER_%MIXER_NAME:MIXER_Y%_{MIXER_X}:{CHARA_ID}:PARTS_IDX:PRESET_IDX", RESULT
            REDRAW 0
            CLEARLINE LINECOUNT - FIRST_LINE
            GOTO INPUT_LOOP
        ELSE
            CURRENT_COLOR_PRESET '= ""
            RESULT = RESULT - PRESET_BTN_ID
        ENDIF
    ENDIF
ELSE
    INPUT_VALUES = %RESULTS%
    IF DIC_CONTAINSKEY(INPUT_VALUES, "MIXER_PRESET")
        IF !PRESET_IDX
            COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX = %CURRENT_COLOR_PRESET%
        ELSE
            COLOR_MATRIX_NAME_PRESET:CHARA_ID:PARTS_IDX:PRESET_IDX = %CURRENT_COLOR_PRESET%
        ENDIF
        CALL HO_PORTRAIT_EDIT_MIXER_SET_PRESET(CHARA_ID, PARTS_IDX, PRESET_IDX, DIC_GET(INPUT_VALUES, "MIXER_PRESET"))
        REDRAW 0
        CLEARLINE LINECOUNT - FIRST_LINE
        GOTO INPUT_LOOP
    ENDIF
ENDIF

SELECTCASE EDIT_PARTS_NAME
    CASE "SKIN"
        IF !IS_CUSTOM_COLOR
            COLOR_MATRIX_NAME:CHARA_ID:IMG_顔 =  %SKIN_PRESET_NAME:RESULT%
            COLOR_MATRIX_NAME:CHARA_ID:IMG_身体 = %SKIN_PRESET_NAME:RESULT%
        ELSE
            COLOR_MATRIX_NAME:CHARA_ID:IMG_顔 '= "カスタム"
            COLOR_MATRIX_NAME:CHARA_ID:IMG_身体 '= "カスタム"
        ENDIF
        IF COLOR_MATRIX_NAME:CHARA_ID:IMG_顔 == "カスタム"
            COLOR_MATRIX_RGB:CHARA_ID:IMG_顔:0 = COL_RGB:0
            COLOR_MATRIX_RGB:CHARA_ID:IMG_顔:1 = COL_RGB:1
            COLOR_MATRIX_RGB:CHARA_ID:IMG_顔:2 = COL_RGB:2
            COLOR_MATRIX_RGB:CHARA_ID:IMG_身体:0 = COL_RGB:0
            COLOR_MATRIX_RGB:CHARA_ID:IMG_身体:1 = COL_RGB:1
            COLOR_MATRIX_RGB:CHARA_ID:IMG_身体:2 = COL_RGB:2
        ENDIF
    CASE "HAIR"
        IF !IS_CUSTOM_COLOR
            COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪 =  %HAIR_PRESET_NAME:RESULT%
            COLOR_MATRIX_NAME:CHARA_ID:IMG_後髪 = %HAIR_PRESET_NAME:RESULT%
            ; COLOR_MATRIX_NAME:CHARA_ID:IMG_エクステ = %HAIR_PRESET_NAME:RESULT%
        ELSE
            COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪 '= "カスタム"
            COLOR_MATRIX_NAME:CHARA_ID:IMG_後髪 '= "カスタム"
            ; COLOR_MATRIX_NAME:CHARA_ID:IMG_エクステ '= "カスタム"
        ENDIF
        IF COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪 == "カスタム"
            COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:0 = COL_RGB:0
            COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:1 = COL_RGB:1
            COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:2 = COL_RGB:2
            COLOR_MATRIX_RGB:CHARA_ID:IMG_後髪:0 = COL_RGB:0
            COLOR_MATRIX_RGB:CHARA_ID:IMG_後髪:1 = COL_RGB:1
            COLOR_MATRIX_RGB:CHARA_ID:IMG_後髪:2 = COL_RGB:2
            ; COLOR_MATRIX_RGB:CHARA_ID:IMG_エクステ:0 = COL_RGB:0
            ; COLOR_MATRIX_RGB:CHARA_ID:IMG_エクステ:1 = COL_RGB:1
            ; COLOR_MATRIX_RGB:CHARA_ID:IMG_エクステ:2 = COL_RGB:2
        ENDIF
    CASE "EYE"
        IF !IS_CUSTOM_COLOR
            COLOR_MATRIX_NAME:CHARA_ID:IMG_瞳 =  %HAIR_PRESET_NAME:RESULT%
        ELSE
            COLOR_MATRIX_NAME:CHARA_ID:IMG_瞳 '= "カスタム"
        ENDIF
        IF COLOR_MATRIX_NAME:CHARA_ID:IMG_瞳 == "カスタム"
            COLOR_MATRIX_RGB:CHARA_ID:IMG_瞳:0 = COL_RGB:0
            COLOR_MATRIX_RGB:CHARA_ID:IMG_瞳:1 = COL_RGB:1
            COLOR_MATRIX_RGB:CHARA_ID:IMG_瞳:2 = COL_RGB:2
        ENDIF
    CASE "CLOTH", "ACCESSORY1", "ACCESSORY2", "GLASSES", "MAKEUP", "NECKLACE", "MASK1", "MASK2", "BACK"
        SELECTCASE EDIT_PARTS_NAME
            CASE "CLOTH"
                PARTS_IDX = IMG_服
            CASE "HAT"
                PARTS_IDX = IMG_帽子
            CASE "ACCESSORY1"
                PARTS_IDX = IMG_アクセサリ1
            CASE "ACCESSORY2"
                PARTS_IDX = IMG_アクセサリ2
            CASE "GLASSES"
                PARTS_IDX = IMG_眼鏡
            CASE "MAKEUP"
                PARTS_IDX = IMG_化粧
            CASE "NECKLACE"
                PARTS_IDX = IMG_首飾
            CASE "MASK1"
                PARTS_IDX = IMG_マスク1
            CASE "MASK2"
                PARTS_IDX = IMG_マスク2
            CASE "BACK"
                PARTS_IDX = IMG_背面
        ENDSELECT
        IF !PRESET_IDX
            IF !IS_CUSTOM_COLOR
                COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX =  %OUTER_PRESET_NAME:RESULT%
            ELSE
                COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX '= "カスタム"
            ENDIF
            IF COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX == "カスタム"
                COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:0 = COL_RGB:0
                COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:1 = COL_RGB:1
                COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:2 = COL_RGB:2
            ENDIF
        ELSE
            IF !IS_CUSTOM_COLOR
                COLOR_MATRIX_NAME_PRESET:CHARA_ID:PARTS_IDX:PRESET_IDX =  %OUTER_PRESET_NAME:RESULT%
            ELSE
                COLOR_MATRIX_NAME_PRESET:CHARA_ID:PARTS_IDX:PRESET_IDX '= "カスタム"
            ENDIF
            IF COLOR_MATRIX_NAME_PRESET:CHARA_ID:PARTS_IDX:PRESET_IDX == "カスタム"
                COLOR_MATRIX_RGB_PRESET_R:CHARA_ID:PARTS_IDX:PRESET_IDX = COL_RGB:0
                COLOR_MATRIX_RGB_PRESET_G:CHARA_ID:PARTS_IDX:PRESET_IDX = COL_RGB:1
                COLOR_MATRIX_RGB_PRESET_B:CHARA_ID:PARTS_IDX:PRESET_IDX = COL_RGB:2
            ENDIF
        ENDIF
    CASE "HAT"
        IF !PRESET_IDX
            IF !IS_CUSTOM_COLOR
                IF HAT_PRESET_NAME:RESULT == "髪色と同じ値をセット"
                    IF COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪 != "カスタム"
                        CALL カラーブレンド取得(COLOR_MATRIX, COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪)
                        COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:0 = COLOR_MATRIX:0:0
                        COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:1 = COLOR_MATRIX:1:1
                        COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:2 = COLOR_MATRIX:2:2
                    ELSE
                        COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:0 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:0
                        COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:1 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:1
                        COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:2 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:2
                    ENDIF
                    COLOR_MATRIX_NAME:CHARA_ID:IMG_帽子 '= "カスタム"
                ELSE
                    COLOR_MATRIX_NAME:CHARA_ID:IMG_帽子 =  %HAT_PRESET_NAME:RESULT%
                ENDIF
            ELSE
                COLOR_MATRIX_NAME:CHARA_ID:IMG_帽子 '= "カスタム"
                COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:0 = COL_RGB:0
                COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:1 = COL_RGB:1
                COLOR_MATRIX_RGB:CHARA_ID:IMG_帽子:2 = COL_RGB:2
            ENDIF
        ELSE
            IF !IS_CUSTOM_COLOR
                IF HAT_PRESET_NAME:RESULT == "髪色と同じ値をセット"
                    IF COLOR_MATRIX_NAME_PRESET:CHARA_ID:IMG_前髪:PRESET_IDX != "カスタム"
                        CALL カラーブレンド取得(COLOR_MATRIX, COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪)
                        COLOR_MATRIX_RGB_PRESET_R:CHARA_ID:IMG_帽子:PRESET_IDX = COLOR_MATRIX:0:0
                        COLOR_MATRIX_RGB_PRESET_G:CHARA_ID:IMG_帽子:PRESET_IDX = COLOR_MATRIX:1:1
                        COLOR_MATRIX_RGB_PRESET_B:CHARA_ID:IMG_帽子:PRESET_IDX = COLOR_MATRIX:2:2
                    ELSE
                        COLOR_MATRIX_RGB_PRESET_R:CHARA_ID:IMG_帽子:PRESET_IDX = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:0
                        COLOR_MATRIX_RGB_PRESET_G:CHARA_ID:IMG_帽子:PRESET_IDX = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:1
                        COLOR_MATRIX_RGB_PRESET_B:CHARA_ID:IMG_帽子:PRESET_IDX = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:2
                    ENDIF
                    COLOR_MATRIX_NAME_PRESET:CHARA_ID:IMG_帽子:PRESET_IDX '= "カスタム"
                ELSE
                    COLOR_MATRIX_NAME_PRESET:CHARA_ID:IMG_帽子:PRESET_IDX =  %HAT_PRESET_NAME:RESULT%
                ENDIF
            ELSE
                COLOR_MATRIX_NAME_PRESET:CHARA_ID:IMG_帽子:PRESET_IDX '= "カスタム"
                COLOR_MATRIX_RGB_PRESET_R:CHARA_ID:IMG_帽子:PRESET_IDX = COL_RGB:0
                COLOR_MATRIX_RGB_PRESET_G:CHARA_ID:IMG_帽子:PRESET_IDX = COL_RGB:1
                COLOR_MATRIX_RGB_PRESET_B:CHARA_ID:IMG_帽子:PRESET_IDX = COL_RGB:2
            ENDIF
        ENDIF
    CASE "HEADSUBPARTS", "BROW", "NOSE", "HAIR_EX", "HAIR_INNER"
        SELECTCASE EDIT_PARTS_NAME
            CASE "HEADSUBPARTS"
                PARTS_IDX = IMG_頭部位
            CASE "HAIR_EX"
                PARTS_IDX = IMG_エクステ
            CASE "HAIR_INNER"
                PARTS_IDX = IMG_インナーヘア
            CASE "BROW"
                PARTS_IDX = IMG_眉
            CASE "NOSE"
                PARTS_IDX = IMG_鼻
        ENDSELECT
        IF !IS_CUSTOM_COLOR
            IF HAT_PRESET_NAME:RESULT == "髪色と同じ値をセット"
                IF COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪 != "カスタム"
                    CALL カラーブレンド取得(COLOR_MATRIX, COLOR_MATRIX_NAME:CHARA_ID:IMG_前髪)
                    COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:0 = COLOR_MATRIX:0:0
                    COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:1 = COLOR_MATRIX:1:1
                    COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:2 = COLOR_MATRIX:2:2
                ELSE
                    COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:0 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:0
                    COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:1 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:1
                    COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:2 = COLOR_MATRIX_RGB:CHARA_ID:IMG_前髪:2
                ENDIF
                COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX '= "カスタム"
            ELSE
                COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX =  %HAT_PRESET_NAME:RESULT%
            ENDIF
        ELSE
            COLOR_MATRIX_NAME:CHARA_ID:PARTS_IDX '= "カスタム"
            COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:0 = COL_RGB:0
            COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:1 = COL_RGB:1
            COLOR_MATRIX_RGB:CHARA_ID:PARTS_IDX:2 = COL_RGB:2
        ENDIF
    CASEELSE
ENDSELECT

REDRAW 0
CLEARLINE LINECOUNT - FIRST_LINE
GOTO INPUT_LOOP

;============================
; 疑似スライダ
; RGBスライダーの改変
;============================
@HO_PORTRAIT_EDIT_RGB_SLIDER( nBaseColor )
#LOCALSIZE 4
#DIM nBaseColor

#DIM nColorBuf
#DIM color_RGB, 3
#DIM nSelectMark
#DIM loopColor
#DIM loopRGB
#DIM colorMem
#DIMS strFontMem

colorMem = GETCOLOR()
strFontMem = %GETFONT()%
nColorBuf = nBaseColor

SIF LINEISEMPTY() == 0
    PRINTFORML

color_RGB:0 = nColorBuf / 256 / 256
color_RGB:1 = nColorBuf / 256 % 256
color_RGB:2 = nColorBuf % 256

SETFONT "ＭＳ ゴシック"
FOR loopRGB, 0, 3
    SELECTCASE loopRGB
        CASE 0
            ; R値を変更
            PRINTFORM %@" Ｒ: (%TOSTR(color_RGB:0, "000")%) "%
        CASE 1
            ; G値を変更
            PRINTFORM %@" Ｇ: (%TOSTR(color_RGB:1, "000")%) "%
        CASE 2
            ; B値を変更
            PRINTFORM %@" Ｂ: (%TOSTR(color_RGB:2, "000")%) "%
    ENDSELECT
    FOR loopColor, 0, 130
        ; 0x00～0xFF（0x02刻み）
        nSelectMark = 0
        LOCAL:1 = color_RGB:0
        LOCAL:2 = color_RGB:1
        LOCAL:3 = color_RGB:2
        SELECTCASE loopRGB
            CASE 0
                ; R値を変更
                LOCAL:1 = LIMIT(loopColor * 0x02, 0x00, 0xFF)
                SIF loopColor == ((color_RGB:0 + 3) / 0x02)
                    nSelectMark = 1
            CASE 1
                ; G値を変更
                LOCAL:2 = LIMIT(loopColor * 0x02, 0x00, 0xFF)
                SIF loopColor == ((color_RGB:1 + 3) / 0x02)
                    nSelectMark = 1
            CASE 2
                ; B値を変更
                LOCAL:3 = LIMIT(loopColor * 0x02, 0x00, 0xFF)
                SIF loopColor == ((color_RGB:2 + 3) / 0x02)
                    nSelectMark = 1
        ENDSELECT
        LOCAL = (LOCAL:1 * 256 * 256) + (LOCAL:2 * 256) + (LOCAL:3)
        SETCOLOR LOCAL
        ; 半角サイズの■ボタン。番号はそのカラー値を使用する
        IF nSelectMark == 0
            PRINTBUTTON @"%UNICODE(0x2588)%", LOCAL
        ELSE
            PRINTBUTTON @"%UNICODE(0x2593)%", LOCAL
        ENDIF
        ; IF nSelectMark == 0
        ;     PRINTBUTTON @"-", LOCAL
        ; ELSE
        ;     PRINTBUTTON @"|", LOCAL
        ; ENDIF
    NEXT
    PRINTL
    RESETCOLOR
NEXT

; フォント,色を元に戻す
SETCOLOR colorMem
SETFONT strFontMem

RETURN

@EDIT_PORTRAIT_SELECT_FIXED_PORTRAIT_IMAGE(CHARA_ID)
#DIM CHARA_ID
#DIMS SPRITE_NAME

PRINTFORML ポートレイトとして使用する画像ファイル名を入力してください(ex:001.png)、未入力でキャンセル
PRINTFORML ※画像ファイルは "eraFL/resources/portrait/prt_FIX" フォルダ配下に格納されている必要があります

WHILE 1
    INPUTS
    SIF RESULTS == ""
        RETURN 0
    SPRITE_NAME = %RESULTS%
    CALL スプライト生成(@"portrait/prt_FIX/%SPRITE_NAME%", SPRITE_NAME)
    IF !RESULT
        PRINTFORMW 画像ファイルが存在しません
        CLEARLINE 1
        CONTINUE
    ELSE
        CALL 画像表示_P(SPRITE_NAME, "left", 0, 0, 200, 200, 1)
        CALL 画像描画終了
        PRINTL
        PRINTFORML この画像をポートレイトとして設定します。よろしいですか？
        CALL ASK_MULTI("確定", "別の画像を指定", "キャンセル")
        SELECTCASE RESULT
            CASE 0
                CSTR:CHARA_ID:顔グラファイル名 = %SPRITE_NAME%
                CSTR:CHARA_ID:キャラ顔グラ = %SPRITE_NAME%
                RETURN 1
            CASE 1
            CASEELSE
                RETURN 0
        ENDSELECT
    ENDIF
WEND

@HO_PORTRAIT_EDIT_MIXER(MIXER_RGB)
#DIM REF MIXER_RGB, 0, 0
LOCALS '= ""
LOCALS += @"<font color ='#%CVH(カラー_注釈)%'>◆チャンネルミキサーパラメータを直接指定してより柔軟に色を指定します(上級者向け)</font><br>"
LOCALS += @"<font color ='#%CVH(カラー_注釈)%'>※真っ黒の場合は[デフォルトカラー]を押下してみてください</font><br>"
LOCALS += "<br>"
LOCALS += @"<font color ='#%CVH(カラー_注釈)%'>◆ プリセット</font><br>"
LOCALS += @"<button value ='[MIXER_PRESET:DEFAULT]'>[デフォルトカラー]　</button>"
LOCALS += @"<button value ='[MIXER_PRESET:R_TO_G]'>[赤→緑]　</button>"
LOCALS += @"<button value ='[MIXER_PRESET:R_TO_B]'>[赤→青]　</button>"
LOCALS += @"<button value ='[MIXER_PRESET:G_TO_B]'>[緑→青]　</button>"
LOCALS += @"<button value ='[MIXER_PRESET:G_TO_R]'>[緑→赤]　</button>"
LOCALS += @"<button value ='[MIXER_PRESET:B_TO_R]'>[青→赤]　</button>"
LOCALS += @"<button value ='[MIXER_PRESET:B_TO_G]'>[青→緑]　</button>"
LOCALS += "<br>"
LOCALS += "<br>"
LOCALS += @"<font color ='#%CVH(カラー_注釈)%'>◆ 値直接指定</font><br>"
LOCALS += "R:"
FOR LOCAL, 0, 3
    LOCALS += @"<button value ='{LOCAL}'>[%TOSTR(MIXER_RGB:0:LOCAL, " 000;-000")%]</button>"
NEXT
LOCALS += "<br>"
LOCALS += "G:"
FOR LOCAL, 0, 3
    LOCALS += @"<button value ='{LOCAL + 3}'>[%TOSTR(MIXER_RGB:1:LOCAL, " 000;-000")%]</button>"
NEXT
LOCALS += "<br>"
LOCALS += "B:"
FOR LOCAL, 0, 3
    LOCALS += @"<button value ='{LOCAL + 6}'>[%TOSTR(MIXER_RGB:2:LOCAL, " 000;-000")%]</button>"
NEXT
LOCALS += "<br>"
HTML_PRINT LOCALS

@HO_PORTRAIT_EDIT_MIXER_SET_PRESET(CHARA_ID, PARTS_IDX, PRESET_IDX, PRESET_NAME)
#DIM CHARA_ID
#DIM PARTS_IDX
#DIM PRESET_IDX
#DIMS PRESET_NAME
#DIM MIXER_RGB, 3, 3

SELECTCASE PRESET_NAME
    CASE "DEFAULT"
        MIXER_RGB:0:0 = 100,  0,  0
        MIXER_RGB:1:0 =   0,100,  0
        MIXER_RGB:2:0 =   0,  0,100
    CASE "R_TO_G"
        MIXER_RGB:0:0 =   0,100,  0
        MIXER_RGB:1:0 = 100,  0,  0
        MIXER_RGB:2:0 =   0,  0,100
    CASE "R_TO_B"
        MIXER_RGB:0:0 =   0,  0,100
        MIXER_RGB:1:0 =   0,100,  0
        MIXER_RGB:2:0 = 100,  0,  0
    CASE "G_TO_B"
        MIXER_RGB:0:0 = 100,  0,  0
        MIXER_RGB:1:0 =   0,  0,100
        MIXER_RGB:2:0 =   0,100,  0
    CASE "G_TO_R"
        MIXER_RGB:0:0 =   0,100,  0
        MIXER_RGB:1:0 = 100,  0,  0
        MIXER_RGB:2:0 =   0,  0,100
    CASE "B_TO_R"
        MIXER_RGB:0:0 =   0,  0,200
        MIXER_RGB:1:0 =   0,100,  0
        MIXER_RGB:2:0 = 100,  0,  0
    CASE "B_TO_G"
        MIXER_RGB:0:0 = 100,  0,  0
        MIXER_RGB:1:0 =   0,  0,100
        MIXER_RGB:2:0 =   0,100,  0
    CASEELSE
ENDSELECT

COLOR_MIXER_R_0:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:0:0
COLOR_MIXER_R_1:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:0:1
COLOR_MIXER_R_2:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:0:2
COLOR_MIXER_G_0:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:1:0
COLOR_MIXER_G_1:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:1:1
COLOR_MIXER_G_2:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:1:2
COLOR_MIXER_B_0:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:2:0
COLOR_MIXER_B_1:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:2:1
COLOR_MIXER_B_2:CHARA_ID:PARTS_IDX:PRESET_IDX = MIXER_RGB:2:2

;-------------------------------------------------
;;; ポートレイトパーツのうち、汎用規格に基づいて動作させる処理
;-------------------------------------------------
@SET_FACE_COMMON_OUTFIT(CHARA_ID, SID, PRESET_IDX, SET_PARTS, CALL_FROM)
#DIM  CHARA_ID
#DIMS SID
#DIM  PRESET_IDX
#DIMS REF SET_PARTS
#DIMS CALL_FROM

;汎用パーツ
CALL SET_FACEIMG(CHARA_ID, IMG_頭部位, FACE_PARTS:CHARA_ID:IMG_頭部位)
CALL SET_FACEIMG(CHARA_ID, IMG_化粧, FACE_PARTS:CHARA_ID:IMG_化粧)

;衣装プリセットの設定で可変するパーツ
IF PRESET_IDX && CLOTH_PRESET_IS_VALID:CHARA_ID:PRESET_IDX && FACE_PARTS_PRESET_IS_VALID:CHARA_ID:PRESET_IDX
    SET_PARTS:IMG_アクセサリ1  = %FACE_PARTS_PRESET:CHARA_ID:IMG_アクセサリ1:PRESET_IDX%
    SET_PARTS:IMG_帽子    = %FACE_PARTS_PRESET:CHARA_ID:IMG_帽子:PRESET_IDX%
    SET_PARTS:IMG_眼鏡    = %FACE_PARTS_PRESET:CHARA_ID:IMG_眼鏡:PRESET_IDX%
    SET_PARTS:IMG_マスク1  = %FACE_PARTS_PRESET:CHARA_ID:IMG_マスク1:PRESET_IDX%
    SET_PARTS:IMG_マスク2  = %FACE_PARTS_PRESET:CHARA_ID:IMG_マスク2:PRESET_IDX%
    SET_PARTS:IMG_首飾    = %FACE_PARTS_PRESET:CHARA_ID:IMG_首飾:PRESET_IDX%
    SET_PARTS:IMG_背面    = %FACE_PARTS_PRESET:CHARA_ID:IMG_背面:PRESET_IDX%
    CALL HO_CHECK_NAKED(CHARA_ID)
    IF !RESULT || CALL_FROM == "PORTRAIT_EDIT"
        IF FACE_PARTS_PRESET:CHARA_ID:IMG_服:PRESET_IDX != ""
            SET_PARTS:IMG_服 = %FACE_PARTS_PRESET:CHARA_ID:IMG_服:PRESET_IDX%
        ELSE
            SET_PARTS:IMG_服 '= @"%SID%_服_通常"
        ENDIF
    ELSE
        SET_PARTS:IMG_服   '= @"FACE_DUMMY"
        SET_PARTS:IMG_帽子 '= @"FACE_DUMMY"
        IF STRFINDU(FACE_PARTS_PRESET:CHARA_ID:IMG_首飾:PRESET_IDX, "首輪") == -1
            SET_PARTS:IMG_首飾 '= @"FACE_DUMMY"
        ENDIF
    ENDIF
ELSE
    ;プリセット指定なしのデフォルト状態
    SET_PARTS:IMG_アクセサリ1 =  %FACE_PARTS:CHARA_ID:IMG_アクセサリ1%
    SET_PARTS:IMG_帽子       =  %FACE_PARTS:CHARA_ID:IMG_帽子%
    SET_PARTS:IMG_眼鏡       =  %FACE_PARTS:CHARA_ID:IMG_眼鏡%
    SET_PARTS:IMG_マスク1     = %FACE_PARTS:CHARA_ID:IMG_マスク1%
    SET_PARTS:IMG_マスク2     = %FACE_PARTS:CHARA_ID:IMG_マスク2%
    SET_PARTS:IMG_首飾       =  %FACE_PARTS:CHARA_ID:IMG_首飾%
    SET_PARTS:IMG_背面       =  %FACE_PARTS:CHARA_ID:IMG_背面%

    CALL HO_CHECK_NAKED(CHARA_ID)
    IF !RESULT || CALL_FROM == "PORTRAIT_EDIT"
        IF FACE_PARTS:CHARA_ID:IMG_服 != ""
            SET_PARTS:IMG_服 = %FACE_PARTS:CHARA_ID:IMG_服%
        ELSEIF SPRITECREATED(@"%SID%_服_通常")
            SET_PARTS:IMG_服 '= @"%SID%_服_通常"
        ENDIF
    ELSE
        SET_PARTS:IMG_服   '= @"FACE_DUMMY"
        SET_PARTS:IMG_帽子 '= @"FACE_DUMMY"
        IF STRFINDU(FACE_PARTS:CHARA_ID:IMG_首飾, "首輪") == -1
            SET_PARTS:IMG_首飾 '= @"FACE_DUMMY"
        ENDIF
    ENDIF
ENDIF

CALL SET_FACEIMG(CHARA_ID, IMG_アクセサリ1, SET_PARTS:IMG_アクセサリ1)
CALL SET_FACEIMG(CHARA_ID, IMG_服, SET_PARTS:IMG_服)
CALL SET_FACEIMG(CHARA_ID, IMG_帽子, SET_PARTS:IMG_帽子)
CALL SET_FACEIMG(CHARA_ID, IMG_眼鏡, SET_PARTS:IMG_眼鏡)
CALL SET_FACEIMG(CHARA_ID, IMG_マスク1, SET_PARTS:IMG_マスク1)
CALL SET_FACEIMG(CHARA_ID, IMG_マスク2, SET_PARTS:IMG_マスク2)
CALL SET_FACEIMG(CHARA_ID, IMG_首飾, SET_PARTS:IMG_首飾)
CALL SET_FACEIMG(CHARA_ID, IMG_背面, SET_PARTS:IMG_背面)


code:
;引数の値を顔グラパーツ管理用のキャラクター変数に格納する
;PARTSに指定する値は 画像管理.ERH参照
@SET_FACEIMG(CHARA_ID, PARTS, SPRITE_NAME)
#DIM CHARA_ID
#DIM PARTS
#DIMS SPRITE_NAME
SIF SPRITE_NAME == ""
    RETURN 0
IF !SPRITECREATED (SPRITE_NAME) && SPRITE_NAME != "FACE_DUMMY"
    DEBUGPRINTFORML @SET_FACEIMG:未生成のスプライト"%SPRITE_NAME%"が指定されました
    RETURN 0
ENDIF
FACE_LAYER:CHARA_ID:PARTS = %SPRITE_NAME%

;目のパーツに関しては連動する瞳パーツが存在する場合、あわせてセットする
IF PARTS == IMG_目 && STRFINDU(SPRITE_NAME, "目") != -1
    SPRITE_NAME = %REPLACE(SPRITE_NAME, "_目_", "_瞳_")%
    IF SPRITECREATED(@"%SPRITE_NAME%")
        FACE_LAYER:CHARA_ID:IMG_瞳 = %SPRITE_NAME%
    ELSE
        FACE_LAYER:CHARA_ID:IMG_瞳 '= ""
    ENDIF
    ;特定のパーツのオフセット位置が未設定の場合、顔部位にあわせて位置を補正
ELSEIF PARTS == IMG_咥物 || PARTS == IMG_マスク2
    IF !FACE_PARTS_OFFSET_X:CHARA_ID:PARTS && (FACE_PARTS_OFFSET_X:CHARA_ID:PARTS !=  FACE_PARTS_OFFSET_X:CHARA_ID:IMG_口)
        FACE_PARTS_OFFSET_X:CHARA_ID:PARTS = FACE_PARTS_OFFSET_X:CHARA_ID:IMG_口
    ENDIF
    IF !FACE_PARTS_OFFSET_Y:CHARA_ID:PARTS && (FACE_PARTS_OFFSET_Y:CHARA_ID:PARTS !=  FACE_PARTS_OFFSET_Y:CHARA_ID:IMG_口)
        FACE_PARTS_OFFSET_Y:CHARA_ID:PARTS = FACE_PARTS_OFFSET_Y:CHARA_ID:IMG_口
    ENDIF
ELSEIF PARTS == IMG_マスク1 || PARTS == IMG_眼鏡
    IF !FACE_PARTS_OFFSET_X:CHARA_ID:PARTS && (FACE_PARTS_OFFSET_X:CHARA_ID:PARTS !=  FACE_PARTS_OFFSET_X:CHARA_ID:IMG_目)
        FACE_PARTS_OFFSET_X:CHARA_ID:PARTS = FACE_PARTS_OFFSET_X:CHARA_ID:IMG_目
    ENDIF
    IF !FACE_PARTS_OFFSET_Y:CHARA_ID:PARTS && (FACE_PARTS_OFFSET_Y:CHARA_ID:PARTS !=  FACE_PARTS_OFFSET_Y:CHARA_ID:IMG_目)
        FACE_PARTS_OFFSET_Y:CHARA_ID:PARTS = FACE_PARTS_OFFSET_Y:CHARA_ID:IMG_目
    ENDIF
ENDIF

RETURN 1

@GET_FACEIMG(CHARA_ID, PARTS)
#FUNCTIONS
#DIM CHARA_ID
#DIM PARTS

RETURNF FACE_LAYER:CHARA_ID:PARTS

;引数の値を顔グラオーバーレイパーツ（赤面など）の管理用のキャラクター変数に格納する
;PARTSに指定する値は 画像管理.ERH参照、重複を許可する場合、同名のスプライトを重ねがけできる
@SET_FACEOVL(CHARA_ID, PARTS, SPRITE_NAME, 重複を許可 = 0)
#DIM CHARA_ID
#DIM PARTS
#DIMS SPRITE_NAME
#DIM 重複を許可

IF !SPRITECREATED (SPRITE_NAME) && SPRITE_NAME != "FACE_DUMMY"
    DEBUGPRINTFORML @SET_FACEOVL:未生成のスプライト"%SPRITE_NAME%"が指定されました
    RETURN 0
    ;SPRITE_NAME = "FACE_DUMMY"
ENDIF
;同名オーバーレイが存在し、重複が許可されていない場合は追加しない
FOR LOCAL, PARTS, PARTS + OVL_パーツ上限
    IF (FACE_OVL_LAYER:CHARA_ID:LOCAL == SPRITE_NAME) && !重複を許可
        RETURN 0
    ENDIF
NEXT

FOR LOCAL, PARTS, PARTS + OVL_パーツ上限
    IF (FACE_OVL_LAYER:CHARA_ID:LOCAL == "")
        FACE_OVL_LAYER:CHARA_ID:LOCAL = %SPRITE_NAME%
        IF REGEXPMATCH(SPRITE_NAME, "(?<=.*_)([^_]+$).*", 1)
            SELECTCASE RESULTS
                CASE "赤面", "涙"
                    FACE_OVL_LAYER_OFFSET_X:CHARA_ID:LOCAL = FACE_PARTS_OFFSET_X:CHARA_ID:IMG_目
                    FACE_OVL_LAYER_OFFSET_Y:CHARA_ID:LOCAL = FACE_PARTS_OFFSET_Y:CHARA_ID:IMG_目
                    FACE_OVL_LAYER_SIZE_MOD_X:CHARA_ID:LOCAL = FACE_PARTS_SIZE_MOD_X:CHARA_ID:IMG_目
                    FACE_OVL_LAYER_SIZE_MOD_Y:CHARA_ID:LOCAL = FACE_PARTS_SIZE_MOD_Y:CHARA_ID:IMG_目
                CASEELSE
                    FACE_OVL_LAYER_OFFSET_X:CHARA_ID:LOCAL = 0
                    FACE_OVL_LAYER_OFFSET_Y:CHARA_ID:LOCAL = 0
                    FACE_OVL_LAYER_SIZE_MOD_X:CHARA_ID:LOCAL = 0
                    FACE_OVL_LAYER_SIZE_MOD_Y:CHARA_ID:LOCAL = 0
            ENDSELECT
        ENDIF
        RETURN 1
    ENDIF
NEXT

;パーツ単位でOVL設定をクリア, スプライト名に文字列が指定されているならば、文字列を含むスプライトを削除
@DEL_FACEOVL(CHARA_ID, PARTS = -1, SPRITE_NAME = "")
#DIM CHARA_ID
#DIM PARTS
#DIMS SPRITE_NAME
IF PARTS == -1
    VARSET FACE_OVL_LAYER:CHARA_ID:0, ""
    RETURN
ENDIF

FOR LOCAL, PARTS, PARTS + OVL_パーツ上限
    IF SPRITE_NAME == ""
        FACE_OVL_LAYER:CHARA_ID:LOCAL '= ""
    ELSE
        IF STRFINDU(FACE_OVL_LAYER:CHARA_ID:LOCAL, SPRITE_NAME) != -1
            FACE_OVL_LAYER:CHARA_ID:LOCAL '= ""
        ENDIF
    ENDIF
NEXT

;引数で指定した文字列を含むスプライトが登録されている場合、1を返す
@EXIST_FACEIMG(CHARA_ID, SPRITE_NAME)
#FUNCTION
#DIM CHARA_ID
#DIMS SPRITE_NAME

FOR LOCAL, 0, FACE_LAYERNUM
    IF STRFINDU(FACE_LAYER:CHARA_ID:LOCAL, SPRITE_NAME) != -1
        RETURNF 1
    ENDIF
NEXT
RETURNF 0

@EXIST_FACEOVL(CHARA_ID, SPRITE_NAME)
#FUNCTION
#DIM CHARA_ID
#DIMS SPRITE_NAME

FOR LOCAL, 0, FACE_OVL_LAYERNUM
    IF STRFINDU(FACE_OVL_LAYER:CHARA_ID:LOCAL, SPRITE_NAME) != -1
        RETURNF 1
    ENDIF
NEXT
RETURNF 0

;-------------------------------------------------
; 格納した顔グラパーツを元に顔グラを構築する
;-------------------------------------------------
;キャラ削除時に削除対象キャラのポートレイト情報を破棄する
@DISPOSE_FACE_SPRITE(CHARA_ID)
#DIM CHARA_ID

CALL INIT_FACE_SPRITE(CHARA_ID)
VARSET FACE_PARTS:CHARA_ID:0
VARSET COLOR_MATRIX_NAME:CHARA_ID:0
VARSET COLOR_MATRIX_RGB:CHARA_ID:0:0

;初期化
@INIT_FACE_SPRITE(CHARA_ID)
#DIM CHARA_ID
#DIMS SPRITE_NAME

;固定グラフィックスなら初期化不要
IF CFLAG:CHARA_ID:ポートレイト画像タイプ == 2
    RETURN
ENDIF

VARSET FACE_LAYER:CHARA_ID:0, ""
VARSET FACE_OVL_LAYER:CHARA_ID:0, ""

SPRITE_NAME = %CSTR:CHARA_ID:キャラ顔グラ%
IF SPRITE_NAME != "FACE_DUMMY"
    CALL 画像廃棄(SPRITE_NAME)
ENDIF
CSTR:CHARA_ID:キャラ顔グラ '= ""

@RESET_FACE_SPRITE(CHARA_ID)
#DIM CHARA_ID
#DIMS SPRITE_NAME
VARSET FACE_LAYER:CHARA_ID:0, ""
VARSET FACE_OVL_LAYER:CHARA_ID:0, ""

@SET_FACE_SPRITE(CHARA_ID, SPRITE_OUT = "")
#DIM CHARA_ID
#DIMS SPRITE_OUT
#DIM DYNAMIC GID_OUT

SIF SPRITE_OUT == ""
    SPRITE_OUT '= @"FACE_{CHARA_ID}"

GID_OUT = グラフィックID確認(SPRITE_OUT)
IF GID_OUT > 0
    GCLEAR GID_OUT, 0x00000000
    ;DEBUGPRINTFORML CHARA:%ANAME(CHARA_ID)%,FACE_ID(%SPRITE_OUT%),GID:{GID_OUT} UPDATED
    CALL UPDATE_FACE_SPRITE(CHARA_ID, SPRITE_OUT)
ELSE
    CALL CREATE_FACE_SPRITE(CHARA_ID, SPRITE_OUT)
ENDIF
CALL MERGE_FACE_OVL(CHARA_ID, SPRITE_OUT)

RESULTS = %SPRITE_OUT%
RETURN

;指定されたキャラIDに対応するFACE_LAYERの格納結果から統合した顔グラ用スプライトを生成する
;出力先スプライトが未指定の場合は "FACE_{CHARA_ID}"に対して出力する
@CREATE_FACE_SPRITE(CHARA_ID, SPRITE_OUT = "")
#DIM CHARA_ID
#DIMS SPRITE_OUT
#DIM DYNAMIC GID_OUT

;一旦ダミー画像よりスプライト生成する
DEBUGPRINTFORML @CREATE_FACE_SPRITE:%SPRITE_OUT%
CALL スプライト生成("dummy.webp", SPRITE_OUT)
IF RESULT
    GID_OUT = グラフィックID確認(SPRITE_OUT)
    ;DEBUGPRINTFORML CHARA:%ANAME(CHARA_ID)%,FACE_ID(%SPRITE_OUT%),GID:{GID_OUT} CREATED
    CALL UPDATE_FACE_SPRITE(CHARA_ID, SPRITE_OUT)
ELSE
    GID_OUT = グラフィックID確認(SPRITE_OUT)
    ;DEBUGPRINTFORML  CHARA:%ANAME(CHARA_ID)%,FACE_ID(%SPRITE_OUT%),GID:{GID_OUT} CREATE FAILED
ENDIF

@UPDATE_FACE_SPRITE(CHARA_ID, SPRITE_OUT = "")
#DIM CHARA_ID
#DIMS SPRITE_OUT
#DIM DYNAMIC GID_OUT
#DIM DYNAMIC PRESET_IDX
#DIM DYNAMIC LAYER_ID
PRESET_IDX = FACE_PARTS_PRESET_IDX:CHARA_ID:0

IF SPRITE_OUT != "FACE_DUMMY"
    GID_OUT = グラフィックID確認(SPRITE_OUT)
    FOR LOCAL, 0, VARSIZE("IMG_PARTS_ORDER")
        LAYER_ID = IMG_PARTS_ORDER:LOCAL
        SIF FACE_LAYER:CHARA_ID:LAYER_ID == ""
            CONTINUE
        IF !PRESET_IDX
            IF COLOR_MATRIX_NAME:CHARA_ID:LAYER_ID == "カスタム"
                CALL カスタムカラーマトリクス設定(COLOR_MATRIX_RGB:CHARA_ID:LAYER_ID:0,COLOR_MATRIX_RGB:CHARA_ID:LAYER_ID:1,COLOR_MATRIX_RGB:CHARA_ID:LAYER_ID:2)
            ELSEIF COLOR_MATRIX_NAME:CHARA_ID:LAYER_ID == "ミキサー"
                CALL カラーマトリクスミキサー設定(CHARA_ID, LAYER_ID, PRESET_IDX)
            ENDIF
            {
                CALL 画像合成(GID_OUT, FACE_LAYER:CHARA_ID:LAYER_ID
                    ,FACE_PARTS_OFFSET_X:CHARA_ID:LAYER_ID
                    ,FACE_PARTS_OFFSET_Y:CHARA_ID:LAYER_ID
                    ,SPRITEWIDTH(FACE_LAYER:CHARA_ID:LAYER_ID) + FACE_PARTS_SIZE_MOD_X:CHARA_ID:LAYER_ID
                    ,SPRITEHEIGHT(FACE_LAYER:CHARA_ID:LAYER_ID) + FACE_PARTS_SIZE_MOD_Y:CHARA_ID:LAYER_ID
                    ,COLOR_MATRIX_NAME:CHARA_ID:LAYER_ID
                    ,
                    ,FACE_PARTS_ROTATION:CHARA_ID:LAYER_ID
                    )
            }
        ELSE
            IF GROUPMATCH(LAYER_ID, IMG_服, IMG_帽子, IMG_アクセサリ1, IMG_アクセサリ2, IMG_眼鏡, IMG_マスク1, IMG_マスク2, IMG_化粧, IMG_首飾)
                IF COLOR_MATRIX_NAME_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX == "カスタム"
                    CALL カスタムカラーマトリクス設定(COLOR_MATRIX_RGB_PRESET_R:CHARA_ID:LAYER_ID:PRESET_IDX, COLOR_MATRIX_RGB_PRESET_G:CHARA_ID:LAYER_ID:PRESET_IDX, COLOR_MATRIX_RGB_PRESET_B:CHARA_ID:LAYER_ID:PRESET_IDX)
                ELSEIF COLOR_MATRIX_NAME_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX == "ミキサー"
                    CALL カラーマトリクスミキサー設定(CHARA_ID, LAYER_ID, PRESET_IDX)
                ENDIF
                {
                    CALL 画像合成(GID_OUT, FACE_LAYER:CHARA_ID:LAYER_ID
                        ,FACE_PARTS_OFFSET_X_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX
                        ,FACE_PARTS_OFFSET_Y_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX
                        ,SPRITEWIDTH(FACE_LAYER:CHARA_ID:LAYER_ID) + FACE_PARTS_SIZE_MOD_X_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX
                        ,SPRITEHEIGHT(FACE_LAYER:CHARA_ID:LAYER_ID) + FACE_PARTS_SIZE_MOD_Y_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX
                        ,COLOR_MATRIX_NAME_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX
                        ,
                        ,FACE_PARTS_ROTATION_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX
                        )
                }
            ELSE
                IF COLOR_MATRIX_NAME:CHARA_ID:LAYER_ID == "カスタム"
                    CALL カスタムカラーマトリクス設定(COLOR_MATRIX_RGB:CHARA_ID:LAYER_ID:0,COLOR_MATRIX_RGB:CHARA_ID:LAYER_ID:1,COLOR_MATRIX_RGB:CHARA_ID:LAYER_ID:2)
                ELSEIF COLOR_MATRIX_NAME_PRESET:CHARA_ID:LAYER_ID:PRESET_IDX == "ミキサー"
                    CALL カラーマトリクスミキサー設定(CHARA_ID, LAYER_ID, PRESET_IDX)
                ENDIF
                {
                    CALL 画像合成(GID_OUT, FACE_LAYER:CHARA_ID:LAYER_ID
                        ,FACE_PARTS_OFFSET_X:CHARA_ID:LAYER_ID
                        ,FACE_PARTS_OFFSET_Y:CHARA_ID:LAYER_ID
                        ,SPRITEWIDTH(FACE_LAYER:CHARA_ID:LAYER_ID) + FACE_PARTS_SIZE_MOD_X:CHARA_ID:LAYER_ID
                        ,SPRITEHEIGHT(FACE_LAYER:CHARA_ID:LAYER_ID) + FACE_PARTS_SIZE_MOD_Y:CHARA_ID:LAYER_ID
                        ,COLOR_MATRIX_NAME:CHARA_ID:LAYER_ID
                        ,
                        ,FACE_PARTS_ROTATION:CHARA_ID:LAYER_ID
                        )
                }
            ENDIF
        ENDIF
    NEXT
ENDIF

;指定されたキャラIDに対応するFACE_OVL_LAYERの格納結果から、キャラの顔グラに赤面などのオーバレイを適用する
;SPRITE_NAME が未指定の場合は "FACE_{CHARA_ID}"に対して合成する
;合成対象のスプライトは予め作成されている必要がある
@MERGE_FACE_OVL(CHARA_ID, SPRITE_OUT = "")
#DIM CHARA_ID
#DIMS SPRITE_OUT
#DIM DYNAMIC GID_OUT

SIF SPRITE_OUT == ""
    SPRITE_OUT '= @"FACE_{CHARA_ID}"

IF SPRITE_OUT == @"FACE_{CHARA_ID}" && !SPRITECREATED(@"FACE_{CHARA_ID}")
    DEBUGPRINTFORML @MERGE_FACE_OVL:未生成のスプライト"%SPRITE_OUT%"が合成対象として指定されました
    RETURN 0
ELSEIF !SPRITECREATED(SPRITE_OUT)
    DEBUGPRINTFORML @MERGE_FACE_OVL:未生成のスプライト"%SPRITE_OUT%"が合成対象として指定されました
    RETURN 0
ENDIF

GID_OUT = グラフィックID確認(SPRITE_OUT)

FOR LOCAL, 0, FACE_OVL_LAYERNUM
    SIF FACE_OVL_LAYER:CHARA_ID:LOCAL == ""
        CONTINUE
    {
        CALL 画像合成(GID_OUT, FACE_OVL_LAYER:CHARA_ID:LOCAL
            ,FACE_OVL_LAYER_OFFSET_X:CHARA_ID:LOCAL
            ,FACE_OVL_LAYER_OFFSET_Y:CHARA_ID:LOCAL
            ,SPRITEWIDTH(FACE_OVL_LAYER:CHARA_ID:LOCAL) + FACE_OVL_LAYER_SIZE_MOD_X:CHARA_ID:LOCAL
            ,SPRITEHEIGHT(FACE_OVL_LAYER:CHARA_ID:LOCAL) + FACE_OVL_LAYER_SIZE_MOD_Y:CHARA_ID:LOCAL
            )
    }
NEXT

;-------------------------------------------------
;@DRAW_PORTRAIT
;辞書形式で属性を指定して任意のキャラクターのポートレイトを表示する関数
;-------------------------------------------------
;region @DRAW_PORTRAIT
@DRAW_PORTRAIT(CHARA_ID, DIC_OPTIONS, CALL_FROM = "DRAW_FACE", AUTO_NEWLINE = 0)
#DIM  CHARA_ID
#DIMS DIC_OPTIONS
#DIMS CALL_FROM
#DIM  AUTO_NEWLINE
#DIMS DYNAMIC RECT
#DIMS DYNAMIC PORTRAIT
#DIMS DYNAMIC POS_X
#DIMS DYNAMIC POS_Y
#DIMS DYNAMIC DEPTH
#DIMS DYNAMIC BORDER
#DIMS DYNAMIC IMG_SIZE
#DIMS DYNAMIC DISPLAY

POS_X = %DIC_GET(DIC_OPTIONS, "POS_X")%
SIF POS_X == ""
    POS_X '= "7200"
POS_Y = %DIC_GET(DIC_OPTIONS, "POS_Y")%
SIF POS_Y == ""
    POS_Y '= "0"
DEPTH = %DIC_GET(DIC_OPTIONS, "DEPTH")%
SIF DEPTH == ""
    DEPTH '= "1"
BORDER = %DIC_GET(DIC_OPTIONS, "BORDER")%
SIF BORDER == ""
    BORDER '= "1px"
IMG_SIZE = %DIC_GET(DIC_OPTIONS, "サイズ")%
SIF IMG_SIZE == ""
    IMG_SIZE '= "200px"
DISPLAY = %DIC_GET(DIC_OPTIONS, "DISPLAY")%
SIF DISPLAY == ""
    DISPLAY '= "relative"

CALL RESET_FACE_SPRITE(CHARA_ID)
CALL HO_SET_PORTRAIT_SPRITE(CHARA_ID, CALL_FROM,, DIC_OPTIONS)

RECT     '=  @"rect = '%POS_X%, %POS_Y%, %IMG_SIZE%, %IMG_SIZE%'"
PORTRAIT '= @""
HTML_PRINT @"
%PORTRAIT%
", 1

IF AUTO_NEWLINE && STRFIND(TOLOWER(IMG_SIZE), "px") != -1
    CALL PX_NEWLINE(TOINT(REPLACE(TOLOWER(IMG_SIZE), "px", "")))
    PRINTL
ELSEIF AUTO_NEWLINE && IMG_SIZE != ""
    CALL NEWLINE(TOINT(IMG_SIZE) / 100)
    PRINTL
ENDIF
RETURN 1

@DRAW_FACE_SET_FACEIMG(CHARA_ID, SID, DIC_OPTIONS)
#DIM  CHARA_ID
#DIMS SID
#DIMS DIC_OPTIONS
#DIMS DYNAMIC EYE_PARTS_SET_NAME
#DIMS DYNAMIC BROW_PARTS_NAME
#DIMS DYNAMIC MOUTH_PARTS_NAME
#DIMS DYNAMIC パーツ_目
#DIMS DYNAMIC パーツ_眉
#DIMS DYNAMIC パーツ_口
#DIMS DYNAMIC オーバーレイ_表情
#DIMS DYNAMIC オーバーレイ_表情2
#DIMS DYNAMIC オーバーレイ_表情3
#DIMS DYNAMIC オーバーレイ_漫符
#DIMS DYNAMIC オーバーレイ_漫符2
#DIMS DYNAMIC オーバーレイ_漫符3

EYE_PARTS_SET_NAME = %FACE_PARTS:CHARA_ID:IMG_目%
IF EYE_PARTS_SET_NAME == ""
    IF STRFIND(SID, "CC") != -1
        EYE_PARTS_SET_NAME '= @"%SID%_目_0"
    ELSE
        EYE_PARTS_SET_NAME '= @"%SID%_目"
    ENDIF
ENDIF

BROW_PARTS_NAME = %FACE_PARTS:CHARA_ID:IMG_眉%
SIF BROW_PARTS_NAME == ""
    BROW_PARTS_NAME '= "CC1_眉_0"
MOUTH_PARTS_NAME = %FACE_PARTS:CHARA_ID:IMG_口%
SIF MOUTH_PARTS_NAME == ""
    MOUTH_PARTS_NAME '= "CC1_口_0"

パーツ_目 = %DIC_GET(DIC_OPTIONS, "目")%
パーツ_眉 = %DIC_GET(DIC_OPTIONS, "眉")%
パーツ_口 = %DIC_GET(DIC_OPTIONS, "口")%
オーバーレイ_表情 = %DIC_GET(DIC_OPTIONS, "OVL_表情")%
オーバーレイ_表情2 = %DIC_GET(DIC_OPTIONS, "OVL_表情2")%
オーバーレイ_表情3 = %DIC_GET(DIC_OPTIONS, "OVL_表情3")%
オーバーレイ_漫符 = %DIC_GET(DIC_OPTIONS, "OVL_漫符")%
オーバーレイ_漫符2 = %DIC_GET(DIC_OPTIONS, "OVL_漫符2")%

IF パーツ_目 != ""
    CALL SET_FACEIMG(CHARA_ID, IMG_目, @"%EYE_PARTS_SET_NAME%_%パーツ_目%")
ENDIF
IF パーツ_眉 != ""
    CALL SET_FACEIMG(CHARA_ID, IMG_眉, @"%BROW_PARTS_NAME%_%パーツ_眉%")
ENDIF
IF パーツ_口 != ""
    CALL SET_FACEIMG(CHARA_ID, IMG_口, @"%MOUTH_PARTS_NAME%_%パーツ_口%")
ENDIF
IF オーバーレイ_表情 != ""
    CALL SET_FACEOVL(CHARA_ID, OVL_表情, @"%SID%_OVL_表情_%オーバーレイ_表情%")
ENDIF
IF オーバーレイ_表情2 != ""
    CALL SET_FACEOVL(CHARA_ID, OVL_表情, @"%SID%_OVL_表情_%オーバーレイ_表情2%")
ENDIF
IF オーバーレイ_表情3 != ""
    CALL SET_FACEOVL(CHARA_ID, OVL_表情, @"%SID%_OVL_表情_%オーバーレイ_表情3%")
ENDIF
IF オーバーレイ_漫符 != ""
    CALL SET_FACEOVL(CHARA_ID, OVL_漫符1, @"%SID%_OVL_漫符_%オーバーレイ_漫符%")
ENDIF
IF オーバーレイ_漫符2 != ""
    CALL SET_FACEOVL(CHARA_ID, OVL_漫符2, @"%SID%_OVL_漫符_%オーバーレイ_漫符2%")
ENDIF

;外装パーツの設定(SIDは固定でCC1を使用)
SID '= "CC1"
VARI I
VARI KEYNUM
VARS KEY_NAME, 100
VARS VALUES
CALL DIC_KEYS(DIC_OPTIONS)
KEYNUM = RESULT
SIF !KEYNUM
    RETURN
ARRAYCOPY "RESULTS", "KEY_NAME"
FOR I, 0, KEYNUM
    SIF !EXISTVAR(@"IMG_%KEY_NAME:I%")
        CONTINUE
    SIF GROUPMATCH(KEY_NAME:I, "目", "眉", "口")
        CONTINUE
    VALUES = %DIC_GET(DIC_OPTIONS, KEY_NAME:I)%
    CALL SET_FACEIMG(CHARA_ID, GETVAR(@"IMG_%KEY_NAME:I%"), @"%SID%_%KEY_NAME:I%_%VALUES%")
NEXT
;#endregion


code:
#DIM CONST FACE_LAYERNUM = 30
#DIM CONST FACE_OVL_LAYERNUM = 50

#DIMS CHARADATA FACE_LAYER, FACE_LAYERNUM
#DIMS CHARADATA FACE_OVL_LAYER, FACE_OVL_LAYERNUM

#DIMS SAVEDATA CHARADATA FACE_PARTS, FACE_LAYERNUM
#DIMS SAVEDATA CHARADATA COLOR_MATRIX_NAME, FACE_LAYERNUM
#DIM  SAVEDATA CHARADATA COLOR_MATRIX_RGB, FACE_LAYERNUM, 3
;表示位置調整
#DIM SAVEDATA CHARADATA FACE_PARTS_OFFSET_X, FACE_LAYERNUM
#DIM SAVEDATA CHARADATA FACE_PARTS_OFFSET_Y, FACE_LAYERNUM
#DIM SAVEDATA CHARADATA FACE_PARTS_SIZE_MOD_X, FACE_LAYERNUM
#DIM SAVEDATA CHARADATA FACE_PARTS_SIZE_MOD_Y, FACE_LAYERNUM
#DIM SAVEDATA CHARADATA FACE_PARTS_ROTATION, FACE_LAYERNUM

#DIM CHARADATA FACE_OVL_LAYER_OFFSET_X, FACE_OVL_LAYERNUM
#DIM CHARADATA FACE_OVL_LAYER_OFFSET_Y, FACE_OVL_LAYERNUM
#DIM CHARADATA FACE_OVL_LAYER_SIZE_MOD_X, FACE_OVL_LAYERNUM
#DIM CHARADATA FACE_OVL_LAYER_SIZE_MOD_Y, FACE_OVL_LAYERNUM

#DIM  SAVEDATA CHARADATA FACE_PARTS_PRESET_IS_VALID, CLOTH_PRESET_NUM
#DIMS SAVEDATA CHARADATA FACE_PARTS_PRESET, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA FACE_PARTS_OFFSET_X_PRESET, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA FACE_PARTS_OFFSET_Y_PRESET, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA FACE_PARTS_SIZE_MOD_X_PRESET, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA FACE_PARTS_SIZE_MOD_Y_PRESET, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA FACE_PARTS_ROTATION_PRESET, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIMS SAVEDATA CHARADATA COLOR_MATRIX_NAME_PRESET, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  CHARADATA FACE_PARTS_PRESET_IDX
;三次元以上のCHARA型変数は宣言できないので…
#DIM  SAVEDATA CHARADATA COLOR_MATRIX_RGB_PRESET_R, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MATRIX_RGB_PRESET_G, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MATRIX_RGB_PRESET_B, FACE_LAYERNUM, CLOTH_PRESET_NUM
;チャンネルミキサー
#DIM  SAVEDATA CHARADATA COLOR_MIXER_R_0, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MIXER_R_1, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MIXER_R_2, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MIXER_G_0, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MIXER_G_1, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MIXER_G_2, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MIXER_B_0, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MIXER_B_1, FACE_LAYERNUM, CLOTH_PRESET_NUM
#DIM  SAVEDATA CHARADATA COLOR_MIXER_B_2, FACE_LAYERNUM, CLOTH_PRESET_NUM

;顔グラ用
#DIM CONST PORTRAIT_BASE_SIZEX = 200
#DIM CONST PORTRAIT_BASE_SIZEY = 200
#DIM SAVEDATA PORTRAIT_倍率
#DIM SAVEDATA PORTRAIT_サイズ設定値
#DIMS PORTRAIT_サイズ設定文字列 = "S", "M", "L", "V", "NONE"
#DIM PORTRAIT_サイズ設定定義 = 60, 80, 100, 0, -1
#DIM PORTRAIT_SIZEX
#DIM PORTRAIT_SIZEY
#DIM HO_SHOW_PORTRAIT_IDX
#DIM HO_SHOW_MEMBERNUM
#DIM PARTS_OFFSET_VALUE

#DIM CONST CSTR_PORTRAIT_IMG_IDX = 120
#DIM CONST IMG_後髪 = 0
#DIM CONST IMG_身体 = 1
#DIM CONST IMG_顔 = 2
#DIM CONST IMG_瞳 = 3
#DIM CONST IMG_目 = 4
#DIM CONST IMG_睫毛 = 5
#DIM CONST IMG_鼻 = 6
#DIM CONST IMG_口 = 7
#DIM CONST IMG_服 = 8
#DIM CONST IMG_前髪 = 9
#DIM CONST IMG_眉 = 10
#DIM CONST IMG_頭部位 = 11
#DIM CONST IMG_帽子 = 12
#DIM CONST IMG_アクセサリ1 = 13
#DIM CONST IMG_アクセサリ2 = 15
#DIM CONST IMG_眼鏡 = 16
#DIM CONST IMG_化粧 = 17
#DIM CONST IMG_首飾 = 18
#DIM CONST IMG_エクステ = 19
#DIM CONST IMG_頭部位2 = 20
#DIM CONST IMG_マスク1 = 21
#DIM CONST IMG_マスク2 = 22
#DIM CONST IMG_咥物 = 23
#DIM CONST IMG_背面 = 24
#DIM CONST IMG_インナーヘア = 25
{
    #DIMS CONST IMG_PARTS_DISP_NAME =
        "後髪"
        ,"身体"
        ,"顔"
        ,"瞳"
        ,"目"
        ,"睫毛"
        ,"鼻"
        ,"口"
        ,"服"
        ,"前髪"
        ,"眉"
        ,"頭部位"
        ,"帽子"
        ,"アクセサリ1"
        ,"未使用"
        ,"アクセサリ2"
        ,"眼鏡"
        ,"化粧"
        ,"首飾"
        ,"エクステ"
        ,"頭部位2"
        ,"マスク1"
        ,"マスク2"
        ,"咥物"
        ,"背面"
        ,"インナーヘア"
}
;パーツ表示順の定義
{
    #DIM IMG_PARTS_ORDER =
        IMG_後髪
        ,IMG_背面
        ,IMG_インナーヘア
        ,IMG_身体
        ,IMG_服
        ,IMG_顔
        ,IMG_化粧
        ,IMG_瞳
        ,IMG_目
        ,IMG_睫毛
        ,IMG_鼻
        ,IMG_口
        ,IMG_首飾
        ,IMG_眼鏡
        ,IMG_マスク1
        ,IMG_エクステ
        ,IMG_前髪
        ,IMG_眉
        ,IMG_頭部位
        ,IMG_頭部位2
        ,IMG_帽子
        ,IMG_アクセサリ1
        ,IMG_アクセサリ2
        ,IMG_マスク2
        ,IMG_咥物
}

#DIM  CONST IMG_MAX_CLOTH_PARTSNUM = 100
#DIM  CONST IMG_身体パーツ数   = 2
#DIM  CONST IMG_顔パーツ数   = 8
#DIM  CONST IMG_前髪パーツ数 = 28
#DIM  CONST IMG_後髪パーツ数 = 19
#DIM  CONST IMG_エクステパーツ数 = 8
#DIM  CONST IMG_インナーヘアパーツ数 = 3
#DIM  CONST IMG_目パーツ数   = 17
#DIM  CONST IMG_眉パーツ数   = 7
#DIM  CONST IMG_口パーツ数   = 6
#DIM  CONST IMG_鼻パーツ数   = 5
{
    #DIMS CONST IMG_服_パーツ名 =
        "ローブ"
        ,"ケープ"
        ,"平服"
        ,"ブラウス"
        ,"ドレス"
        ,"ロリータドレス"
        ,"鎧"
        ,"オフショルダー"
        ,"下着"
        ,"特殊"
}
{
    #DIM  CONST IMG_服_パターン数 =
        3
        ,3
        ,6
        ,9
        ,7
        ,3
        ,4
        ,1
        ,5
        ,8
}
#DIMS CONST IMG_帽子_パーツ名 = "ヘッドドレス", "三角帽子", "ティアラ", "ケモミミ", "ヴェール","帽子", "特殊",
#DIM  CONST IMG_帽子_パターン数 = 3, 1, 3, 7, 3, 7, 4
#DIMS CONST IMG_頭部位_パーツ名 = "ケモミミ"
#DIM  CONST IMG_頭部位_パターン数 = 8
#DIMS CONST IMG_アクセサリ1_パーツ名 = "リボン", "リボン(ツインテ)", "コサージュ", "ピアス", "その他"
#DIM  CONST IMG_アクセサリ1_パターン数 = 10, 1, 4, 3, 5
#DIMS CONST IMG_眼鏡_パーツ名 = "眼鏡"
#DIM  CONST IMG_眼鏡_パターン数 = 11
#DIMS CONST IMG_マスク1_パーツ名 = "目隠し",  "眼帯",  "仮面", "目元"
#DIM  CONST IMG_マスク1_パターン数 = 4, 2, 2, 1
#DIMS CONST IMG_マスク2_パーツ名 = "ヴェール"
#DIM  CONST IMG_マスク2_パターン数 = 2
#DIMS CONST IMG_化粧_パーツ名 = "目元", "傷"
#DIM  CONST IMG_化粧_パターン数 = 4, 6
#DIMS CONST IMG_首飾_パーツ名 = "首輪", "首飾", "特殊"
#DIM  CONST IMG_首飾_パターン数 = 3, 9, 3
#DIMS CONST IMG_背面_パーツ名 = "翼", "尻尾"
#DIM  CONST IMG_背面_パターン数 = 3, 3

;ランダム生成からの除外パーツ(特定種族固有のような特殊なパーツなど)
{
    #DIMS CONST IMG_ランダム生成除外_目 =
        "CC1_目_4"
        ,"CC1_目_14"
        ,"CC1_目_15"
}
{
    #DIMS CONST IMG_ランダム生成除外_鼻 =
        "CC1_鼻_4"
}
{
    #DIMS CONST IMG_ランダム生成除外_口 =
        ""
}
{
    #DIMS CONST IMG_ランダム生成除外_眉 =
        "CC1_眉_6"
}

;顔グラオーバーレイ用
;各項目ごとに10枚まで重ねられるように
#DIM CONST OVL_パーツ上限 = 10
#DIM OVL_表情 = 0
#DIM OVL_汁 = 10
#DIM OVL_漫符1 = 20
#DIM OVL_漫符2 = 30
#DIM OVL_効果 = 40

;ポートレイト編集用
#DIM PORTRAIT_EDIT_MODE
#DIM CONST PORTRAIT_EDIT_MODE_顔 = 0
#DIM CONST PORTRAIT_EDIT_MODE_髪 = 1
#DIM CONST PORTRAIT_EDIT_MODE_服 = 2
#DIM CONST PORTRAIT_EDIT_MODE_帽子 = 3
#DIM CONST PORTRAIT_EDIT_MODE_装飾 = 4
#DIM CONST PORTRAIT_EDIT_MODE_眼鏡 = 5
#DIM CONST PORTRAIT_EDIT_MODE_首飾 = 6
#DIM CONST PORTRAIT_EDIT_MODE_位置調整 = 100

#DIMS CONST IMG_目_パターン = "通常", "閉じ(緩)", "細目", "じと", "細目(発情)", "絶頂", "閉じ(張)", "閉じ(張_涙)", "閉じ(緩_涙)", "絶頂_涙", "アヘ_涙"
#DIMS CONST IMG_瞳_パターン = "通常", "閉じ(緩)", "細目", "じと", "細目(発情)", "絶頂", "閉じ(張)", "閉じ(張_涙)", "閉じ(緩_涙)", "絶頂_涙", "アヘ_涙"
#DIMS CONST IMG_眉_パターン = "通常", "リラックス", "弛緩", "怒り", "困り", "しわよせ", "しわよせ強"
#DIMS CONST IMG_口_パターン = "通常", "笑い", "怒り", "叫び", "舌出し大", "舌出し(唾液)", "あっ", "むす", "舌出し小", "くいしばり", "笑い2", "笑い3"
#DIMS CONST IMG_OVL_表情_パターン = "", "赤面"
#DIMS CONST IMG_OVL_表情2_パターン = "", "吐息"
#DIMS CONST IMG_OVL_表情3_パターン = "", "涙"
#DIMS CONST IMG_OVL_汁_パターン = "", "ぶっかけ1", "ぶっかけ2", "ぶっかけ3"
#DIMS CONST IMG_OVL_漫符_パターン = "", "絶頂"
#DIMS CONST IMG_OVL_漫符2_パターン = "", "ハート"


code:
;-------------------------------------------------
;引数のピクセル数が半角スペースいくつ分に相当するかざっくり求める
;等幅フォントじゃないと多分だめ
;-------------------------------------------------
@PX_TO_STRLENSU(PX_SIZE)
#FUNCTION
#DIM PX_SIZE
#DIM PIXEL_PER_CHAR

SIF !PIXEL_PER_CHAR
    PIXEL_PER_CHAR = GETCONFIG("フォントサイズ") * 1000

RETURNF (((PX_SIZE * 2000) / PIXEL_PER_CHAR))

;-------------------------------------------------
;グラフィック表示ライブラリで生成した画像からウィンドウ描画用の文字列を生成
;-------------------------------------------------
@IMAGE_TOWND(画像名, 縦位置, マウスオーバー画像名 = "", 横幅, 縦幅, 画像反転フラグ = 0)
#FUNCTIONS
#DIMS 画像名				;リソース名
#DIMS マウスオーバー画像名	;マウスオーバー時に表示する画像名 省略可
#DIM  拡大比率				;パーセンテージ指定 指定しなければ100
#DIM  横幅					;表示画像のピクセル
#DIM  縦幅					;上に同じ
#DIM  画像縦幅				;ややこしいがフォントサイズ基準のパーセンテージ
#DIM  画像横幅				;上に同じ
#DIM  縦位置				;ピクセル指定 内部でフォントサイズ基準のパーセンテージに変換する
#DIM  画像反転フラグ		;画像反転を行うかのフラグ
SIF PPF == 0
    ;１ピクセルがフォントサイズの何%であるかを10倍の値で取得する（精度向上のため）
    PPF = PIXEL_PERCENT_OF_FONTSIZE() ;どうせコンフィグ変えたら再起動なのだから、一度だけ計算する
IF SPRITECREATED(画像名)
    画像横幅 = 横幅 * PPF / 10 * (GETBIT(画像反転フラグ, 0) ? -1 # 1 )
    画像縦幅 = 縦幅 * PPF / 10 * (GETBIT(画像反転フラグ, 1) ? -1 # 1 )
    縦位置   = (縦位置 * PPF / 10)- (行ずれ回数 * 100);
    LOCALS '= @"@I:\"%画像名%\" \@ マウスオーバー画像名 != "" ? ,srcb='%マウスオーバー画像名%' # \@ ,height='{画像縦幅}' ,width='{画像横幅}' ,ypos='{縦位置}'@@/I@"
    RETURNF LOCALS
ELSE
    DEBUGPRINTFORML @IMAGE_TOWND:画像リソース%画像名%が見つかりませんでした
    RETURNF @""
ENDIF

;-------------------------------------------------
; 任意の二点間に線を引く
;-------------------------------------------------
@DRAW_IMAGE_LINE(POS1_X, POS1_Y, POS2_X, POS2_Y, STYLE = "-", THICK = 50, DEPTH = 2)
#DIM   POS1_X
#DIM   POS1_Y
#DIM   POS2_X
#DIM   POS2_Y
#DIMS  STYLE
#DIM   THICK
#DIM   DEPTH

#DIM   DYNAMIC FROM_X
#DIM   DYNAMIC FROM_Y
#DIM   DYNAMIC DEST_X
#DIM   DYNAMIC DEST_Y

#DIM   DYNAMIC MID_X
#DIM   DYNAMIC MID_Y
#DIM   DYNAMIC DEST
#DIM   DYNAMIC ANGLE
#DIMS  DYNAMIC DIV_RECT

IF POS2_X >= POS1_X
    FROM_X = POS1_X
    FROM_Y = POS1_Y
    DEST_X = POS2_X
    DEST_Y = POS2_Y
ELSE
    FROM_X = POS2_X
    FROM_Y = POS2_Y
    DEST_X = POS1_X
    DEST_Y = POS1_Y
ENDIF

POWER LOCAL:0, DEST_X - FROM_X, 2
POWER LOCAL:1, DEST_Y - FROM_Y, 2
DEST = SQRT(LOCAL:0 + LOCAL:1)
MID_X = (DEST_X - FROM_X)  / 2
MID_Y = (DEST_Y - FROM_Y)  / 2
DEBUGPRINTFORML DEST:{DEST}

GCREATE 10000, DEST, DEST
GCREATE 10001, DEST, DEST
GSETFONT 10000, "Arial", THICK, 0
GSETPEN 10000, 0xFF00FF00, 1
GSETBRUSH 10000, 0xFF00FFCC
GDRAWTEXT 10000, "-" * 100, 0, (DEST / 2) - THICK * 70 / 100
IF DEST_X == FROM_X
    DIV_RECT '= @"rect='{FROM_X}px, {FROM_Y}px, {DEST_X}px, {DEST_Y}px'"
    ANGLE = 90
ELSEIF DEST_Y == FROM_Y
    DIV_RECT '= @"rect='{FROM_X - DEST / 2}px, {FROM_Y - DEST / 2}px, {DEST_X + DEST / 2}px, {DEST_Y + DEST / 2}px'"
    ANGLE = 0
ELSE
    DIV_RECT '= @"rect='{FROM_X - DEST / 2}px, {FROM_Y - DEST / 2}px, {DEST_X + DEST / 2}px, {DEST_Y + DEST / 2}px'"
    ANGLE = CALC_ATAN(DEST_X - FROM_X, DEST_Y - FROM_Y)
ENDIF
GDRAWGWITHROTATE 10001, 10000, ANGLE
SPRITECREATE @"IMG_LINE_{10001}", 10001

LOCALS '= @""
HTML_PRINT @"
%LOCALS%
", 1

;-------------------------------------------------
;@DRAW_STILL
;任意の登録済み一枚絵を出力する
;-------------------------------------------------
;region @DRAW_STILL
@DRAW_STILL(IMG_SRC, DIC_OPTIONS, AUTO_NEWLINE = 1)
#DIMS IMG_SRC
#DIMS DIC_OPTIONS
#DIM  AUTO_NEWLINE
#DIMS DYNAMIC RECT
#DIMS DYNAMIC PORTRAIT
#DIMS DYNAMIC POS_X
#DIMS DYNAMIC POS_Y
#DIMS DYNAMIC DEPTH
#DIMS DYNAMIC BORDER
#DIMS DYNAMIC BORDER_COLOR
#DIMS DYNAMIC IMG_SIZE_X
#DIMS DYNAMIC IMG_SIZE_Y
#DIMS DYNAMIC DISPLAY

POS_X = %DIC_GET(DIC_OPTIONS, "POS_X")%
SIF POS_X == ""
    POS_X '= "0"
POS_Y = %DIC_GET(DIC_OPTIONS, "POS_Y")%
SIF POS_Y == ""
    POS_Y '= "0"
DEPTH = %DIC_GET(DIC_OPTIONS, "DEPTH")%
SIF DEPTH == ""
    DEPTH '= "1"
BORDER = %DIC_GET(DIC_OPTIONS, "BORDER")%
SIF BORDER == ""
    BORDER '= "1px"
BORDER_COLOR = %DIC_GET(DIC_OPTIONS, "BORDER_COLOR")%
SIF BORDER_COLOR == ""
    BORDER_COLOR '= "#C0C0C0"
IMG_SIZE_X = %DIC_GET(DIC_OPTIONS, "SIZE_X")%
SIF IMG_SIZE_X == ""
    IMG_SIZE_X '= "600px"
IMG_SIZE_Y = %DIC_GET(DIC_OPTIONS, "SIZE_Y")%
SIF IMG_SIZE_Y == ""
    IMG_SIZE_Y '= "400px"
DISPLAY = %DIC_GET(DIC_OPTIONS, "DISPLAY")%
SIF DISPLAY == ""
    DISPLAY '= "relative"

RECT     '=  @"rect = '%POS_X%, %POS_Y%, %IMG_SIZE_X%, %IMG_SIZE_Y%'"
PORTRAIT '= @""
HTML_PRINT @"
%PORTRAIT%
", 1

IF AUTO_NEWLINE && STRFIND(IMG_SIZE_Y, "px") != -1
    CALL PX_NEWLINE(TOINT(REPLACE(IMG_SIZE_Y, "px", "")))
    PRINTL
ENDIF


code:
@TAG_INIT(対象, 呼び出し)
#DIM 対象
#DIM 呼び出し
FOR LOCAL, 0, MAX_TAG
	TAG:対象:LOCAL = -1
NEXT

TRYCCALLFORM INIT_TAG_{呼び出し}(対象)
CATCH
ENDCATCH

@ADD_TAG(対象, タグ)
#DIM 対象
#DIM タグ
FOR LOCAL, 0, MAX_TAG
	SIF TAG:対象:LOCAL == タグ
		RETURN 0
NEXT
FOR LOCAL, 0, MAX_TAG
	IF TAG:対象:LOCAL == -1
		TAG:対象:LOCAL = タグ
		RETURN 1
	ENDIF
NEXT

@REMOVE_TAG(対象, タグ)
#DIM 対象
#DIM タグ
FOR LOCAL, 0, MAX_TAG
	IF TAG:対象:LOCAL == タグ
		TAG:対象:LOCAL = -1
		BREAK
	ENDIF
NEXT

@INVERT_TAG(対象, タグ)
#DIM 対象
#DIM タグ
IF HAS_TAG(対象, タグ)
	CALL REMOVE_TAG(対象, タグ)
ELSE
	CALL ADD_TAG(対象, タグ)
ENDIF

@HAS_TAG(対象, タグ)
#FUNCTION
#DIM 対象
#DIM タグ
FOR LOCAL, 0, MAX_TAG
	SIF TAG:対象:LOCAL == タグ
		RETURNF 1
NEXT

RETURNF 0

@IS_TAG_EMPTY(対象)
#FUNCTION
#DIM 対象
FOR LOCAL, 0, MAX_TAG
	SIF TAG:対象:LOCAL != -1
		RETURNF 0
NEXT

RETURNF 1


code:
;≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
; 色
;
;	関数名	:	FuncColor_～～
;≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

;================================================================
; カラー値の算出（RGB指定）
;--------------------------------
;[引数]
;	nRGB:0		: 変動値（Ｒ値)
;	nRGB:1		: 変動値（Ｇ値)
;	nRGB:2		: 変動値（Ｂ値)
;--------------------------------
;[戻り値など]
;	算出したカラー値
;================================================================
@FuncColor_FromRGB( nRGB:0, nRGB:1, nRGB:2 )
#FUNCTION
#LOCALSIZE 4
	#DIM nRGB, 3
	#DIM nResultColor

	LOCAL:0 = LIMIT( nRGB:0, 0x00, 0xFF )
	LOCAL:1 = LIMIT( nRGB:1, 0x00, 0xFF )
	LOCAL:2 = LIMIT( nRGB:2, 0x00, 0xFF )

	nResultColor = (LIMIT( nRGB:0, 0x00, 0xFF ) * 0x010000) + (LIMIT( nRGB:1, 0x00, 0xFF ) * 0x000100) + (LIMIT( nRGB:2, 0x00, 0xFF ) * 0x000001)

	RETURNF nResultColor

;================================================================
; カラー値の算出（HSB指定）
;--------------------------------
;[引数]
;	nHSB:0		: 色相（0～359）
;	nHSB:1		: 彩度（0～255)
;	nHSB:2		: 明度（0～255)
;--------------------------------
;[戻り値など]
;	算出したカラー値
;================================================================
@FuncColor_FromHSB( arrHSB:0, arrHSB:1, arrHSB:2 )
#FUNCTION
	#DIM arrHSB, 3

	#DIM arrRGB, 3
	#DIM nMax
	#DIM nMin
	#DIM nResultColor

	nMax = arrHSB:2
	nMin = nMax - (arrHSB:1 * nMax / 255)

	SELECTCASE arrHSB:0
		CASE 0 TO 59
			arrRGB:0 = nMax
			arrRGB:1 = nMin + ((nMax - nMin) * (arrHSB:0) / 60)
			arrRGB:2 = nMin
		CASE 60 TO 119
			arrRGB:0 = nMin + ((nMax - nMin) * (120 - arrHSB:0) / 60)
			arrRGB:1 = nMax
			arrRGB:2 = nMin
		CASE 120 TO 179
			arrRGB:0 = nMin
			arrRGB:1 = nMax
			arrRGB:2 = nMin + ((nMax - nMin) * (arrHSB:0 - 120) / 60)
		CASE 180 TO 239
			arrRGB:0 = nMin
			arrRGB:1 = nMin + ((nMax - nMin) * (240 - arrHSB:0) / 60)
			arrRGB:2 = nMax
		CASE 240 TO 299
			arrRGB:0 = nMin + ((nMax - nMin) * (arrHSB:0 - 240) / 60)
			arrRGB:1 = nMin
			arrRGB:2 = nMax
		CASE 300 TO 360
			arrRGB:0 = nMax
			arrRGB:1 = nMin
			arrRGB:2 = nMin + ((nMax - nMin) * (360 - arrHSB:0) / 60)
	ENDSELECT

	nResultColor = (arrRGB:0 * 256 * 256) + (arrRGB:1 * 256) + (arrRGB:2)
	RETURNF nResultColor

;================================================================
; カラー値の算出（基準値から変動）
;--------------------------------
;[引数]
;	nBaseColor	: 基準となるカラー値
;	nRGB:0		: 変動値（Ｒ値)
;	nRGB:1		: 変動値（Ｇ値)
;	nRGB:2		: 変動値（Ｂ値)
;--------------------------------
;[戻り値など]
;	算出したカラー値
;================================================================
@FuncColor_ChangeColor( nBaseColor, nRGB:0, nRGB:1, nRGB:2 )
#FUNCTION
#LOCALSIZE 4
	#DIM nBaseColor
	#DIM nRGB, 3
	#DIM nResultColor

	LOCAL:0 = LIMIT( nRGB:0 + ((nBaseColor / 0x010000) % 0x0100), 0x00, 0xFF )
	LOCAL:1 = LIMIT( nRGB:1 + ((nBaseColor / 0x000100) % 0x0100), 0x00, 0xFF )
	LOCAL:2 = LIMIT( nRGB:2 + (nBaseColor % 0x0100),              0x00, 0xFF )

	nResultColor = (LOCAL:0 * 0x010000) + (LOCAL:1 * 0x000100) + (LOCAL:2 * 0x000001)

	RETURNF nResultColor

;================================================================


code:
;≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡
; 文字列操作関連の関数
;
;	関数名	:	FuncString_～～
;≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡≡

;================================================================
; 渡された文字列の長さを取得する。
; ※ STRLENS()はUnicodeの文字の全角半角が判断できないため、追加する
; ※ MSゴシック前提
;--------------------------------
;[引数]
;	strSrcText		:
;--------------------------------
;[戻り値など]
;	渡された文字列の長さ
;================================================================
@FuncString_GetLength( strSrcText )
#FUNCTION
	#DIMS strSrcText

	#DIM  nTextLen

	nTextLen = STRLENS( strSrcText )
	; 一部のユニコード文字が表示上は全角だが、半角と判断されているので、文字数を増やす
	nTextLen += STRCOUNT(strSrcText, UNICODE(0x2610))
	nTextLen += STRCOUNT(strSrcText, UNICODE(0x2611))
	nTextLen += STRCOUNT(strSrcText, UNICODE(0x2612))
	nTextLen += STRCOUNT(strSrcText, UNICODE(0x2764))

	RETURNF nTextLen

;================================================================
; 渡された文字列をユニコードのバイト値文字列に変換する
;--------------------------------
;[引数]
;	strSrcText		:
;--------------------------------
;[戻り値など]
;	変換した文字列
;	例）"あいうえお" → "3042304430463048304A"
;================================================================
@FuncString_ConvertToUnicodeText( strSrcText )
#FUNCTIONS
	#DIMS strSrcText

	#DIMS strUnicodeText
	#DIM  nTextLength
	#DIM  nLoop

	strUnicodeText '= ""
	ENCODETOUNI %strSrcText%
	nTextLength = RESULT:0
	FOR nLoop, 0, nTextLength
		strUnicodeText += TOSTR(RESULT:(nLoop + 1), "X4")
	NEXT

	RETURNF strUnicodeText

;================================================================
; 渡されたユニコードのバイト値文字列を通常の文字列に変換する
;	※FuncString_ConvertToUnicodeText()の再変換用
;--------------------------------
;[引数]
;	strUnicodeText		:
;--------------------------------
;[戻り値など]
;	変換した文字列
;	例）"3042304430463048304A" → "あいうえお"
;================================================================
@FuncString_ConvertFromUnicodeText( strUnicodeText )
#FUNCTIONS
	#DIMS strUnicodeText

	#DIMS strDestText
	#DIMS strBuf
	#DIM  nLoop

	strDestText '= ""
	nLoop = 0
	WHILE 1
		strBuf '= "0x" + SUBSTRING( strUnicodeText, nLoop * 4, 4 )
		IF ISNUMERIC( strBuf ) == 0
			DEBUGPRINTFORML FuncString_ConvertFromUnicodeText() - 不正な値を検出しました（不正値=「%strBuf%」(nLoop={nLoop}), 変換元=「%strUnicodeText%」）
			BREAK
		ENDIF
		strDestText += UNICODE( TOINT( strBuf ) )
		nLoop += 1
		SIF ((nLoop + 1) * 4) > STRLENS(strUnicodeText)
			BREAK
	WEND

	RETURNF strDestText

;================================================================
; 文字列を指定の文字数になるように整形する
;	短ければ、指定の文字数になるように埋め文字を追加する
;	長ければ、後ろの文字を削除する
;--------------------------------
;[引数]
;	strText		: 文字列
;	nLength		: 文字列長（指定した文字列長に足りない場合、strPaddingで埋める）
;	strPadding	: パディング用文字（半角1文字であること）
;	strAlign	: "L"or"R"or"C"
;					"L" = 左詰め
;					"R" = 右詰め
;					"C" = 中央寄せ（不足文字数が奇数の場合、左から埋めていく）
;--------------------------------
;[戻り値など]
;	変換した文字列
;================================================================
@FuncString_Mold( strText, nLength, strPadding=" ", strAlign="L" )
#FUNCTIONS
#LOCALSIZE 4
#LOCALSSIZE 4
	#DIMS strText
	#DIM  nLength
	#DIMS strPadding
	#DIMS strAlign

	#DIM  nCheck

	SELECTCASE nLength - FuncString_GetLength( strText )
		CASE IS > 0
			LOCALS:0 '= FuncString_Padding( strText, nLength, strPadding, strAlign )

		CASE IS < 0
			VARSET LOCALS, ""
			nCheck = 0
			SELECTCASE strAlign
				CASE "L", "C"
					WHILE nCheck < STRLENSU(strText)
						LOCALS:1 '= SUBSTRINGU( strText, nCheck, 1 )
						SIF FuncString_GetLength(LOCALS:0) + FuncString_GetLength(LOCALS:1) > nLength
							BREAK
						LOCALS:0 += LOCALS:1
						nCheck += 1
					WEND
					WHILE FuncString_GetLength(LOCALS) < nLength
						LOCALS:0 += " "
					WEND

				CASE "R"
					WHILE nCheck < STRLENSU(strText)
						LOCAL = STRLENSU(strText)
						LOCALS:1 '= SUBSTRINGU( strText, LOCAL - 1 - nCheck, 1 )
						SIF FuncString_GetLength(LOCALS:0) + FuncString_GetLength(LOCALS:1) > nLength
							BREAK
						LOCALS:0 '= LOCALS:1 + LOCALS:0
						nCheck += 1
					WEND
					WHILE FuncString_GetLength(LOCALS:0) < nLength
						LOCALS:0 '= " " + LOCALS:0
					WEND
			ENDSELECT

		CASE 0
			LOCALS:0 '= strText
	ENDSELECT

	RETURNF LOCALS:0

;================================================================
; 文字列を指定の文字数になるように埋め文字を追加して返す
; 文字列が文字長よりも長い場合はそのまま返す
;--------------------------------
;[引数]
;	strText		: 文字列
;	nLength		: 文字列長（指定した文字列長に足りない場合、strPaddingで埋める）
;	strPadding	: パディング用文字（半角1文字であること）
;	strAlign	: "L"or"R"or"C"
;					"L" = 左詰め
;					"R" = 右詰め
;					"C" = 中央寄せ（不足文字数が奇数の場合、左側の埋め文字が1文字多くなる）
;--------------------------------
;[戻り値など]
;	変換した文字列
;================================================================
@FuncString_Padding( strText, nLength, strPadding, strAlign )
#FUNCTIONS
#LOCALSIZE 4
#LOCALSSIZE 4
	#DIMS strText
	#DIM  nLength
	#DIMS strPadding
	#DIMS strAlign

	#DIM  nPaddingLength

	nPaddingLength = nLength - FuncString_GetLength( strText )
	IF nPaddingLength > 0
		SELECTCASE TOUPPER( strAlign )
			CASE "L", "LEFT"
				LOCALS '= strText + (strPadding * nPaddingLength)
			CASE "R", "RIGHT"
				LOCALS '= (strPadding * nPaddingLength) + strText
			CASE "C", "CENTER"
				LOCAL:1 = (nPaddingLength / 2) + (nPaddingLength % 2)
				LOCAL:2 = nPaddingLength / 2
				LOCALS '= (strPadding * LOCAL:1) + strText + (strPadding * LOCAL:2)
			CASEELSE
				LOCALS '= @"%strText, nLength%"
		ENDSELECT
	ELSE
		LOCALS '= strText
	ENDIF

	RETURNF LOCALS

;================================================================
; 文字の前後に存在する半角スペースを削除する
;--------------------------------
;[引数]
;	strText		: 文字列
;--------------------------------
;[戻り値など]
;	変換した文字列
;================================================================
@FuncString_Trim( strText )
#FUNCTIONS
	#DIMS strText

	#DIM  nIdx

	; 先頭チェック
	WHILE 1
		nIdx = STRFINDU( strText, " ", 0 )
		IF nIdx == 0
			strText '= SUBSTRINGU( strText, 1, -1 )
			CONTINUE
		ENDIF
		BREAK
	WEND

	; 末尾チェック
	WHILE 1
		nIdx = STRFINDU( strText, " ", STRLENSU(strText) - 1 )
		IF nIdx != -1
			strText '= SUBSTRINGU( strText, 0, nIdx )
			CONTINUE
		ENDIF
		BREAK
	WEND

	RETURNF strText

;================================================================
; 文字の前後に存在する半角スペース、全角スペースを削除する
;--------------------------------
;[引数]
;	strText		: 文字列
;--------------------------------
;[戻り値など]
;	変換した文字列
;================================================================
@FuncString_TrimEx( strText )
#FUNCTIONS
	#DIMS strText

	#DIM  nIdx

	; 先頭チェック
	WHILE 1
		nIdx = STRFINDU( strText, " ", 0 )
		IF nIdx == 0
			strText '= SUBSTRINGU( strText, 1, -1 )
			CONTINUE
		ENDIF
		nIdx = STRFINDU( strText, "　", 0 )
		IF nIdx == 0
			strText '= SUBSTRINGU( strText, 1, -1 )
			CONTINUE
		ENDIF
		BREAK
	WEND

	; 末尾チェック
	WHILE 1
		nIdx = STRFINDU( strText, " ", STRLENSU(strText) - 1 )
		IF nIdx != -1
			strText '= SUBSTRINGU( strText, 0, nIdx )
			CONTINUE
		ENDIF
		nIdx = STRFINDU( strText, "　", STRLENSU(strText) - 1 )
		IF nIdx != -1
			strText '= SUBSTRINGU( strText, 0, nIdx )
			CONTINUE
		ENDIF
		BREAK
	WEND

	RETURNF strText

;================================================================
; 文字列を数値に変換する。変換できない場合はデフォルト値を返す
;--------------------------------
;[引数]
;	strText		: 文字列
;	nDefault	: デフォルト値
;--------------------------------
;[戻り値など]
;	変換した数値
;================================================================
@FuncString_ToInt( strText, nDefault = 0 )
#FUNCTION
	#DIMS strText
	#DIM  nDefault

	IF ISNUMERIC( strText ) > 0
		RETURNF TOINT( strText )
	ENDIF
	RETURNF nDefault

;================================================================