システムカスタマイズについてダラダラやるよーその8

システムカスタマイズについてダラダラやるよーその7 - 永字八法の続き。
NScripterのシステムカスタマイズについて、1から話をしてみようと思う。その第8回目。
今回は、ボイスについて。

ボイスについて。

色々見て回った限り、ほうぼうの意見を汲み取って、本稿ではボイスについて、下記のような仕様とします。

ボイスモード

ボイスモードはシングルとマルチの2種類があります。
シングルは従来のものに近いもので、ボイスのチャンネルを一つしか用意しません。
なので、ボイスを再生中であっても、次のボイスが始まれば今のボイス再生は止まると言うものです。
マルチはそうではなく、次々に新しいチャンネルを使って、多重再生します。
(ちなみにこの仕様は、オートモードにも大いに関係してきます)
これはプレイヤーがコンフィグで選択できるようにすべきです。

ボイスボリューム

キャラクター毎に設定できるようにします。
これはコンフィグもしくは好感度確認画面でできるべきです。
デフォルトは50で、0〜100の範囲です。
0にした場合は、ボリュームを0ではなく再生しない、ボイスが存在しないように扱うとします。
また、そのために、キャラクター名とボリュームの結びつけを行います。

どうやって指定するか。

前回でも使ったタグを使います。

[キャラクター名/ボイスファイル名]
「声がついたよ!」\

ボイスはだいたいvoiceファイルに入れ、拡張子は.oggでしょうから、これらはシステムの方で補完するのがいいでしょうね。

[モブの介/v00001]
「モブの俺にセリフが!?」\

この場合、voice\v00001.oggが再生されるとします。

現在のスクリプト

00.txt
;$V2000G1000S800,600L10000
01.txt
*start
	gosub *start_window
	gosub *start_cast
	gosub *start_textwindow
	gosub *start_text
	gosub *start_nameplate
	gosub *start_if
	gosub *start_if1
	gosub *start_if2
	gosub *start_if3
	gosub *start_if4
	gosub *start_if5
	gosub *start_if6
	gosub *start_skip
	gosub *start_sound
	gosub *start_sprite
	gosub *start_global
10.txt
click

[キャラ1/0001]
うぐう。\

名前欄が消えるかな?\

[キャラ2/0002]
が、がお。\

もう一度、消えるかな?\

[キャラ3/0003]
ぶらーぼ\

[キャラ15/0004]

[キャラ4/0006]
あ\

[/0007]
い\

[キャラ6/0008]
う\
え\
お\
か\
き\
く\
け\
こ\
さ\
し\
す\
せ\
そ\
た\
ち\
つ\
て\
と\
98.txt
end
*define
	gosub *define_numalias
	gosub *define_global
	gosub *define_window
	gosub *define_background
	gosub *define_cast
	gosub *define_textwindow
	gosub *define_text
	gosub *define_nameplate
	gosub *define_bexec
	gosub *define_debug
	gosub *define_exec
	gosub *define_fileexist
	gosub *define_if
	gosub *define_newsposition
	gosub *define_skip
	gosub *define_sound
	gosub *define_sprite

game
99.txt
*define_numalias

	; numalias 定義用の一時変数
	mov %0,100 ; 100番から。
	
	; スプライト番号は逆に奥から。
	mov %1,900

return

*define_global

	; グローバル変数を使いますよ。
	globalon
	; グローバル用numaliasの定義変数
	mov %2,1000

	; グローバル変数の初期化をしたかしていないかのフラグ。
	numalias global_initialize,%2:inc %2

return

*define_window

	; メニューは全部消す。
	deletemenu
	
	; ウィンドウサイズを保存する変数。
	numalias window_width,%0:inc %0
	numalias window_height,%0:inc %0

return

*start_window

	; これからずっと使う、ウィンドウのサイズを取得しておく
	getwindowsize %window_width,%window_height

return

*define_background

	; 画像の読み込みのログを取る。
	; これがないと、画像鑑賞が面倒になるので。
	filelog

return

*define_cast

	; 立ち絵の処理
	; 立ち絵のスプライト並びでの位置を決めます。
	numalias sp_casts,%1:dec %1
	humanz sp_casts
	
	; キャラクターの総数を設定する。
	numalias cast_max,10 ; とりあえず、10人
	; キャラクターは名前で判別する。
	; キャラクターにはそれぞれ好感度とボイスボリュームを設定できるとする。

	; キャラクター名を番号に変換する命令
	defsub name2number
	numalias n2n_name,%0:inc %0
	numalias n2n_number,%0:inc %0
	numalias n2n_hit,%0:inc %0

return

*start_cast

	; 立ち絵の高さを決めます。
	; 画面サイズを変えてもデフォルトのままなので、
	; 画面サイズを動的に取得してそれに合わせた設定にします。
	underline %window_height-1

return

; キャラクター名を番号に変える関数。
; 該当がなければ0が戻ってくる。
*name2number

	getparam i%n2n_number,$n2n_name
	; まずは0に設定する。
	mov %%n2n_number,0 

	; キャラクターの名前や数が変われば、以下の行も適当にコピペしたりして編集してください。
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ1":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ2":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ3":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ4":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ5":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ6":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ7":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ8":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ9":if_int_return %n2n_hit,0
	inc %%n2n_number:cmp %n2n_hit,$n2n_name,"キャラ10":if_int_return %n2n_hit,0

	; 最終的には、やはり0に設定する。
	mov %%n2n_number,0 
return

*define_textwindow

	; テキストウィンドウ用のスプライト番号を定義
	numalias sp_textwindow,%1:dec %1
	
	; 念の為に作っておく。文字スプライト用のスプライト番号
	numalias sp_text,%1:dec %1

	; テキストウィンドウをスプライトの位置まで引っ込ませる。
	windowback

	; テキストウィンドウの画像タグを格納する変数(グローバル変数)
	numalias textwindow_file,%2:inc %2
	; テキストウィンドウの不透明度の変数(グローバル)
	numalias textwindow_alpha,%2:inc %2

	; テキストウィンドウの大きさの変数
	numalias textwindow_width,%0:inc %0
	numalias textwindow_height,%0:inc %0
	
	; テキストウィンドウの左上の位置の変数
	numalias textwindow_x,%0:inc %0
	numalias textwindow_y,%0:inc %0
	
	; 表示する文字のフォントの大きさの変数
	numalias font_width,%0:inc %0
	numalias font_height,%0:inc %0
	
	; 文字間横と縦の変数
	numalias font_space,%0:inc %0
	numalias line_space,%0:inc %0
	
	; 文字を太字にするかどうかの変数
	numalias font_bold,%0:inc %0
	
	; 文字にシャドウをつけるかどうかの変数
	numalias font_shadow,%0:inc %0
	
	; ルビ用フォントの大きさの変数
	numalias font_ruby_width,%0:inc %0
	numalias font_ruby_height,%0:inc %0
	
	; フォントの色
	numalias font_color,%0:inc %0
	numalias font_color_clickable,%0:inc %0
	numalias font_color_choose,%0:inc %0
	numalias font_color_choosed,%0:inc %0
	
	; 以上のフォントデータから、文字列スプライト用のタグを作って格納する変数
	numalias font_sprite,%0:inc %0
	
	; テキストウィンドウと、実際の表示領域までのスペースの変数
	numalias textwindow_padding_top,%0:inc %0
	numalias textwindow_padding_bottom,%0:inc %0
	numalias textwindow_padding_left,%0:inc %0
	numalias textwindow_padding_right,%0:inc %0
	
	; 実際の表示領域の大きさの変数
	numalias textwindow_area_width,%0:inc %0
	numalias textwindow_area_height,%0:inc %0
	
	; テキストウィンドウの文字数と行数の変数
	numalias textwindow_col,%0:inc %0
	numalias textwindow_row,%0:inc %0

	; 自作のテキストウィンドウ初期化命令の定義
	defsub set_textwindow

return

*start_textwindow

	; テキストウィンドウの画像と不透明度を定義
	if %global_initialize=0 mov $textwindow_file,":c;>600,200,#888888"
	if %global_initialize=0 mov %textwindow_alpha,255

	; 色の設定
	mov $font_color,"#FFFFFF"
	mov $font_color_clickable,"#0000FF"
	mov $font_color_choose,"#FF0000"
	mov $font_color_choosed,"FF00FF"

	; エフェクト中もテキストウィンドウが消えないようにする。
	erasetextwindow 0

	; 念のため、右クリックを殺しておく。
	rmode 0

	; 一度実行しておく。
	set_textwindow

return

; テキストウィンドウを設定した値に変更する。
*set_textwindow

	; テキストウィンドウの画像読み込み
	lsph sp_textwindow,$textwindow_file,0,0,%textwindow_alpha
	
	; テキストウィンドウのサイズを取得
	getspsize sp_textwindow,%textwindow_width,%textwindow_height

	; テキストウィンドウの配置場所の決定(左下にしている)
	news_position %textwindow_x,%textwindow_y,%window_width,%window_height,%textwindow_width,%textwindow_height,-1,1

	; 各種フォントの設定
	mov %font_width,22
	mov %font_height,22
	mov %font_space,2
	mov %line_space,2
	mov %font_bold,0
	mov %font_shadow,1
	mov %font_ruby_width,11
	mov %font_ruby_height,11
	
	; フォントの各値を、文字列スプライトで使えるように文字列化しておく。
	itoa $font_width,%font_width
	itoa $font_height,%font_height
	itoa $font_space,%font_space
	mov $font_sprite,":s/"+$font_width+","+$font_height+","+$font_space+";"
	
	; パディングの設定
	mov %textwindow_padding_top,8
	mov %textwindow_padding_bottom,8
	mov %textwindow_padding_left,12
	mov %textwindow_padding_right,12
	
	; 実際の表示領域の広さを計算する。
	mov %textwindow_area_width,%textwindow_width-%textwindow_padding_left-%textwindow_padding_right
	mov %textwindow_area_height,%textwindow_height-%textwindow_padding_top-%textwindow_padding_bottom

	; 表示領域の広さから、行数や文字数を計算する。
	mov %textwindow_col,%textwindow_area_width/(%font_width+%font_space)
	mov %textwindow_row,%textwindow_area_height/(%font_height+%line_space+%font_ruby_height)

	; 数値を反映した値にする。
	setwindow %textwindow_x+%textwindow_padding_top,%textwindow_y+%textwindow_padding_left,%textwindow_col,1+%textwindow_row,%font_width,%font_height,%font_space,%line_space+%font_ruby_height,0,%font_bold,%font_shadow,#000000,%textwindow_x,%textwindow_y,%window_width,%window_height
	; ルビも設定する。
	rubyon %font_ruby_width,%font_ruby_height

	; テキストウィンドウの位置を設定
	amsp sp_textwindow,%textwindow_x,%textwindow_y

return

; テキストウィンドウを表示する。
*print_textwindow

	vsp sp_textwindow,1
	vsp sp_text,1

return

; テキストウィンドウを非表示にする。
*delete_textwindow

	vsp sp_textwindow,0
	vsp sp_text,0

return

*define_text
	; システムカスタマイズの宣言
	textgosub *text_lb
	pretextgosub *pretext_lb

	; 既読スキップ有りで。
	kidokuskip

	; テキストウィンドウに表示している文字を取得するための変数
	numalias text_pre,%0:inc %0
	numalias text_before,%0:inc %0
	numalias text_after,%0:inc %0

	; テキストスピード(グローバル変数)
	numalias text_speed,%2:inc %2

	; texton/textoffを上書き
	defsub texton
	defsub textoff

	; テキストウィンドウを表示しているかいないかを格納する変数
	numalias text_visible,%0:inc %0
	
	; pretext用タグ取得変数
	numalias gettag1,%0:inc %0
	numalias gettag2,%0:inc %0
	numalias gettag3,%0:inc %0

	; 発言者名
	numalias talker_name,%0:inc %0
	; 実際に表示する名前
	numalias talker_label,%0:inc %0
	; 現在再生しているボイスファイル。
	numalias voice_playing,%0:inc %0
	; 仮の再生ファイル
	numalias voice_temp,%0:inc %0

return

*start_text

	; 文字速度の初期設定
	if %global_initialize=0 mov %text_speed,40
	
	; 文字速度をそれに設定する。
	textspeed %text_speed

return

*pretext_lb

	; タグを取得する。
	gettag $gettag1,$gettag2,$gettag3

	; 現在の表示内容を取得しておく。
	getlogtext $text_pre,0
	len %text_pre,$text_pre

	; $gettag1が空でなければ、ネームプレート処理をする。
	notif_str_gosub $gettag1,"",*pretext_lb_talker

	; 念のため、表示
	texton
	print 1
	
	; 念のため、文字速度を設定
	textspeed %text_speed

	; ボイスがあった時の処理
	notif_str_gosub $gettag2,"",*pretext_lb_voice

return

*pretext_lb_talker

	; $gettag1があれば、それを表示する名前にする。
	mov $talker_name,$gettag1
	mov $talker_label,$gettag1