1.概要

このページでは、吉里吉里ヒント集で紹介した
「吉里吉里プロフェッショナル版」の実装手順が示されています。

 

2.目次

  1. 概要
  2. 目次
  3. 利用規約
  4. 謝辞
  5. プロフェッショナル版
    1. サンプル一覧
    2. 簡易メニュー
    3. 文字のフェード表示
    4. ボイスシステム
    5. セーブ・ロード画面
  6. 更新履歴
 

3.利用規約

  • このページに記載されていることについては別に制約はかけませんので、ご自由にお使い下さいませ。
  • サポートなどは一切できませんし、質問なども答えられません。問題などが発生した場合、自力で解決できる方のみご利用下さいませ。
    なお、これらの追加機能はあやえも研究所が作成したものです。吉里吉里開発者のW.Dee氏にこれらの機能について直接問い合わせるのはご遠慮下さい。
  • 吉里吉里のKAGをマスターしていて、かつTJSを使える方のみを対象としています。どちらかというと中級者向けです。説明不足も多々ありますが、ご了承下さいませ。
  • 動作確認は、吉里吉里2 2.28安定版rev2のみで行っています。他のバージョンでは個別に動作確認して下さいませ。
 

5.謝辞

これらの追加機能ヒントを作成するにあたって、以下のサイトを参考にさせていただきました。
 

6.プロフェッショナル版

これらの機能は、CircleMebius製作「月下之煌(げっかのきらめき)」にて実装されているものを、さらにバージョンアップさせて洗練させたものです。


実際の製品としての動作実績がありますので、安心してご利用下さい。
体験版でどんな動作なのかご確認することもできます。

また、機能概要を説明したサンプルをご用意しています。
サンプルはこちらからダウンロードして下さい

初期状態の吉里吉里から導入したサンプルを入れています。
画像など、こちらからサイズやファイル名を参考にして、コピーしてお使い下さい。

なお、ソースの追加部分には全て”mebius”というコメントを入れていますので、初期状態からの変更部分はこの文字列を検索することですぐに発見できます。

6.1 サンプル一覧

以下に、サンプルの一覧を掲載しています。
解説もありますので、一度ご覧下さい。
総合サンプルに全ての解説が入っていますので、こちらが便利です。

また、画像など、こちらのサンプルをダウンロードして参考にして画像生成などをしていただければ、ファイル名などのミスもなくスムーズにできると思います。
内容 実行サンプル 画像・ボイスデータ
サンプル
総合サンプル
(下記全てを含みます)
ダウンロード ダウンロード
簡易メニューのみ ダウンロード ダウンロード
文字のフェード表示のみ ダウンロード
ボイスシステムのみ ダウンロード ダウンロード
セーブ・ロード画面のみ ダウンロード ダウンロード
 

6.2 簡易メニュー

機能

kirikiri_screenshot02
  • 簡易メニュー(下が命令、右が保存、左が設定、上がシステム)
  • マウスが指定領域内に入ったら表示、領域から出たら消去(常に表示・常に非表示も可能)
  • キーボード操作対応
  • ツールチップヒントの表示機能
  • 簡易メニュー内でスライダーの使用も可能
  • オートセーブ機能付き(オートセーブ内容は、新しい順に表示されます)
この簡易メニューは自信を持ってご提供できる機能ですので、是非お役立て下さい。

なお、特に制約を受けそうな制限は以下の通りです。
  • 現状では、オートセーブに対応した記述になっています。0~99のスロットまで(プレイ画面表記上では1~100まで)が通常の保存用スロットで、100~109まで(プレイ画面表記上では自動1~自動10まで)が自動保存用スロットです。
これについては修正は可能ですが、変数で一括に処理とかはしておらず、ソース中の条件値や値を一つ一つ修正していかなければなりません。なので、この項目を修正する場合は少々時間がかかる場合があります。(とはいえ、構造が分かれば数日ぐらいで修正できる程度だとは思いますが)

それでは、以下に実装方法を記します。

 

Config.tjsでの処理

  • サンプルでは「画面サイズ」は800×600を想定しています。もし違うサイズで実装する場合、個別に調整願います。(”800″とか”600″とかの文字列で検索すれば、修正箇所はすぐに見つかります)
  • メッセージレイヤの数を変更します。簡易メニューだけでも5枚のメッセージレイヤを用います。それに合うようにnumMessageLayersの数を増やします。
  • もし初期設定のままなら、「メッセージレイヤの色と不透明度」でframeOpacity
    = 0とします。でないと文字枠が出てしまいます。文字枠は全景レイヤーに用意するか、もしくはmessage0などに画像を指定し直して下さい。
  • セーブ画像を使う場合、サムネイルを保存するように設定しておきます。(saveThumbnail
    = trueに)
  • サムネイルの保存サイズも適切なものにします。デフォルトのサンプルのまま用いるのであれば、横118pixelで保存します。(thumbnailWidth
    = 118に)。大きさはどの数値でも問題ありませんので、適宜合うように調整して下さい。
  • サムネイルの画質をよくするため、サムネイル保存モードで、24ビットにしておきます。(thumbnailDepth
    = 24)
  • 利用可能な栞の数(numBookMarks)を適切な数値にしておきます。(ここでは110個と想定してます)
 

Mainwindow.tjs

まずは簡易メニューの変数定義を追加します。
Mainwindow.tjsのfunction KAGWindow()直前の変数定義に、以下の命令を追加します。
        var holdPeriodEventQueue = 
[]; // 保留にされたムービーのピリオドイベントキュー var isLeavePeriodEvent = false; // ムービーのピリオドイベントを保留にするかどうか var isWaitPeriodEvent = false; // ムービーのピリオドイベント待ち状態かどうか var waitedPeriodEventStorageName = void; // ピリオドイベント待ちをコールしたストレージ名 //↓--------------------------------------- ここから追加部分-- //mebius:変数追加分 var autosaveLoadedFlag = false; var timermove_qexec;//簡易メニュー表示用タイマー var timermove_qsave; var timermove_qconf; var timermove_qsys; var movemode_qexec = 0; var movemode_qsave = 0; var movemode_qconf = 0; var movemode_qsys = 0; var qmenuExec_LoadButton;//簡易メニューボタン var qmenuExec_SaveButton; var qmenuExec_ConfigButton; var qmenuExec_HistryButton; var qmenuExec_VoiceButton; var qmenuExec_SkipButton; var qmenuExec_AutoButton; var qmenuExec_EraseButton; var qmenuExec_MenuButton; var qmenuSave_UpButton; var qmenuSave_DownButton; var qmenuSave_EntryButton = []; var qmenuConfig_FullScrButton; var qmenuConfig_WindowButton; var qmenuConfig_2ndReadButton; var qmenuSystem_ReturnTopButton; var qmenuSystem_ExitButton; var qmenuLayer_Exec;//簡易メニューのレイヤナンバーを保持する変数 var qmenuLayer_Save; var qmenuLayer_Config; var qmenuLayer_System; var qmenuLayer_Hint; //↑--------------------------------------- ここまで追加部分-- //------------------------------------------------------ コンストラクタ -- function KAGWindow(ismain = true, width = 0, height = 0) { // コンストラクタ // 引数 : ismain : メインウィンドウとして作成されるのかどうか super.Window(); // 親クラスのコンストラクタを呼ぶ // コンフィギュレーション isMain = ismain; if(ismain) {
コンストラクタ内部に簡易メニューの部分を記述します。
function KAGWindow()の中に、以下の命令を追加します。
        //------------------------------------------------------ コンストラクタ --

        function KAGWindow(ismain = true, width = 0, height = 0)
        {
                // コンストラクタ
                // 引数 : ismain : メインウィンドウとして作成されるのかどうか
                super.Window(); // 親クラスのコンストラクタを呼ぶ

                // コンフィギュレーション

                // (中略)

                // ウィンドウサイズの調整
                if(width != 0 && height != 0)
                {
                        // 与えられたサイズを適用
                        scWidth = width;
                        scHeight = height;
                }
                setInnerSize(scWidth, scHeight);

                // quake 用タイマの作成
                quakeTimer = new Timer(onQuakeTimerInterval, '');
                add(quakeTimer);
                quakeTimer.interval = 50;

//↓--------------------------------------- ここから追加部分--
                //mebius:簡易メニュー用タイマー定義
                timermove_qexec = new Timer(onTimerMoveQExec, '');
                timermove_qexec.interval = 10;
                timermove_qexec.enabled = false;

                timermove_qsave = new Timer(onTimerMoveQSave, '');
                timermove_qsave.interval = 10;
                timermove_qsave.enabled = false;

                timermove_qconf = new Timer(onTimerMoveQConfig, '');
                timermove_qconf.interval = 10;
                timermove_qconf.enabled = false;

                timermove_qsys = new Timer(onTimerMoveQSystem, '');
                timermove_qsys.interval = 10;
                timermove_qsys.enabled = false;
//↑--------------------------------------- ここまで追加部分--

                // 背景レイヤの作成
                fore.messages = [];
                back.messages = [];
                fore.layers = [];
                back.layers = [];
                fore.base = new BaseLayer(this, null, "表-背景");
                add(fore.base);
                fore.base.setImageSize(scWidth, scHeight);
                fore.base.setSizeToImageSize();
                back.base = new BaseLayer(this, fore.base, "裏-背景");
                add(back.base);

セーブ時のサムネイルに、簡易メニューを入れないようにします。
function lockSnapshot()に、以下の命令を追加します。
        function lockSnapshot()
        {
                // スナップショットをロックする
                // 初めてスナップショットがロックされた時点での画面を保存する
                if(snapshotLockCount == 0)
                {
//↓--------------------------------------- ここから追加部分--
                        //mebius:簡易メニュー類はスナップショットから外す。
                        var mes2 = false;
                        var mes3 = false;
                        var mes4 = false;
                        var mes5 = false;
                        var mes6 = false;
                        var slider_object_show_temp = false;
//↑--------------------------------------- ここまで追加部分--

                        if(snapshotLayer === void)
                                snapshotLayer = new Layer(this, primaryLayer);
                        snapshotLayer.setImageSize(scWidth, scHeight);
                        snapshotLayer.face = dfAlpha;

//↓--------------------------------------- ここから追加部分--
                        //mebius:簡易メニュー類はスナップショットから外す。
                        if (kag.fore.messages[qmenuLayer_Exec].visible)
                        {
                                mes2 = true;
                                kag.fore.messages[qmenuLayer_Exec].visible = false;
                        }
                        if (kag.fore.messages[qmenuLayer_Save].visible)
                        {
                                mes3 = true;
                                kag.fore.messages[qmenuLayer_Save].visible = false;
                        }
                        if (kag.fore.messages[qmenuLayer_Config].visible)
                        {
                                mes4 = true;
                                kag.fore.messages[qmenuLayer_Config].visible = false;
                                if (slider_object.foreControlLayer.Sliders[0].visible)//簡易メニューのスライダーが表示中なら消去
                                {
                                        slider_object_show_temp = true;
                                        slider_object.setOptions(%[forevisible:false]);
                                }
                        }
                        if (kag.fore.messages[qmenuLayer_System].visible)
                        {
                                mes5 = true;
                                kag.fore.messages[qmenuLayer_System].visible = false;
                        }
                        if (kag.fore.messages[qmenuLayer_Hint].visible)
                        {
                                mes6 = true;
                                kag.fore.messages[qmenuLayer_Hint].visible = false;
                        }
//↑--------------------------------------- ここまで追加部分--

                        snapshotLayer.piledCopy(0, 0, kag.fore.base, 0, 0, scWidth, scHeight);

//↓--------------------------------------- ここから追加部分--
                        //mebius:簡易メニュー類はスナップショットから外す。
                        if (mes2)
                        {
                                kag.fore.messages[qmenuLayer_Exec].visible = true;
                        }
                        if (mes3)
                        {
                                kag.fore.messages[qmenuLayer_Save].visible = true;
                        }
                        if (mes4)
                        {
                                kag.fore.messages[qmenuLayer_Config].visible = true;
                                if (slider_object_show_temp)
                                        slider_object.setOptions(%[forevisible:true]);
                        }
                        if (mes5)
                        {
                                kag.fore.messages[qmenuLayer_System].visible = true;
                        }
                        if (mes6)
                        {
                                kag.fore.messages[qmenuLayer_Hint].visible = true;
                        }
//↑--------------------------------------- ここまで追加部分--

                }
                snapshotLockCount ++;
        }
オートセーブ機能に対応させておきます。
オートセーブ機能を使わない場合は、この部分は入れなくても大丈夫です。(入れておいても問題ありません)
function loadBookMark()、function saveBookMarkWithAsk()、function loadBookMarkWithAsk()に、以下の命令を追加します。
2箇所ほど、元々ある行の位置を変更する行(else文の中に入れる行)があるので注意して下さい。
        function loadBookMark(num, loaduser = true)
        {
                // 栞番号 num からデータを読み出す
//↓--------------------------------------- ここから追加部分--
                autosaveLoadedFlag = true;//mebius:オートセーブ読み込み直後に再び保存しない対策。
//↑--------------------------------------- ここまで追加部分--
                return loadBookMarkFromFile(getBookMarkFileNameAtNum(num), loaduser);
        }

//↓--------------------------------------- ここから追加部分--
        function saveBookMarkWithAsk(num,autoon,autostr)//mebius:引数追加(autoon,autostr)
//↑--------------------------------------- ここまで追加部分--
        {
                // 栞番号 num に栞を設定する
                // そのとき、設定するかどうかをたずねる
                if(readOnlyMode) return false;
                if(bookMarkProtectedStates[num]) return false;
                var prompt = "栞 ";
//↓--------------------------------------- ここから追加部分--
                //mebius:autoonがtrueならstrを番号として使う。
                if(autoon)
                        prompt += autostr;
                else
                        if(num < numBookMarks) prompt += (num+1);//元々あるこの行は、elseの中に入れます。
//↑--------------------------------------- ここまで追加部分--
                if(bookMarkDates[num] != "") // bookMarkDates が空文字の場合は栞は存在しない
                        prompt += "「" + bookMarkNames[num] + "」";
                prompt += "に「"+ pcflags.currentPageName + "」をはさみますか?";
                var result = askYesNo(prompt);
                if(result) return saveBookMark(num);
                return false;
        }

//↓--------------------------------------- ここから追加部分--
        function loadBookMarkWithAsk(num,autoon,autostr)//mebius:引数追加(autoon,autostr)
//↑--------------------------------------- ここまで追加部分--
        {
                // 栞番号 num から栞を読み出す
                // そのとき、読み出すかどうかをたずねる
                if(num < numBookMarks && bookMarkDates[num] == "") // bookMarkDates が空文字の場合は栞は存在しない
                        return false;
                var prompt = "栞 ";
//↓--------------------------------------- ここから追加部分--
                //mebius:autoonがtrueならstrを番号として使う。
                if(autoon)
                        prompt += autostr;
                else
                        if(num < numBookMarks) prompt += (num+1);//元々あるこの行は、elseの中に入れます。
//↑--------------------------------------- ここまで追加部分--
                prompt += "「"+ bookMarkNames[num] + "」をたどりますか?";
                var result = askYesNo(prompt);
                if(result) return loadBookMark(num);
                return false;
        }

マウスが該当エリアに入ったら、簡易メニューを表示する命令を追加します。
それぞれの座標は個別に修正して下さい。
ウィンドウモード(全画面表示でない)場合、簡易メニューを表示させたままマウスカーソルをウィンドウから外した場合、簡易メニューが表示されたままになります。そのため、上下左右の端に表示しない領域を少し確保しておく方がいいかと思います。
なお、座標(800,600)にマウスカーソルがある場合、何も表示しないように注意して下さい。理由は次のキーボード対応の項目の影響によるものです。
function onMouseDown(x, y)の後に、以下の命令を追加します。
        function onMouseDown(x, y)
        {
                lastMouseDownX = x;
                lastMouseDownY = y;
                super.onMouseDown(...);
        }

//↓--------------------------------------- ここから追加部分--
        //mebius:マウス移動時に簡易メニューの表示判定
        function onMouseMove(x, y, shift)
        {
                //マウスが簡易メニュー(下:命令)表示領域なら、簡易メニュー(下:命令)を表示する。
                if (sf.qmenu_exec_mode == 1 && f.qmenu_enabled)
                {
                        if (x > 160 && x < 725 && y > 565 && y < 600)
                                showQExecMenu('scroll');
                        else
                                hideQExecMenu('scroll');
                }

                //マウスが簡易メニュー(右:セーブ)表示領域なら、簡易メニュー(右:セーブ)を表示する。
                if (sf.qmenu_save_mode == 1 && f.qmenu_enabled)
                {
                        if (x > 760  && y > 5 && y < 553)
                        {
                                showQSaveMenu('scroll');
                        }
                        else 
                        {
                                hideQSaveMenu('scroll');
                        }
                }

                //マウスが簡易メニュー(左:設定)表示領域なら、簡易メニュー(左:設定)を表示する。
                if (sf.qmenu_config_mode == 1 && f.qmenu_enabled)
                {
                        if (x <130  && y > 5 && y < 440)
                        {
                                showQConfigMenu('scroll');
                        }
                        else 
                        {
                                hideQConfigMenu('scroll');
                        }
                }

                //マウスが簡易メニュー(上:システム)表示領域なら、簡易メニュー(上:システム)を表示する。
                if (sf.qmenu_system_mode == 1 && f.qmenu_enabled)
                {
                        if (x > 250 && x < 750 && y >= 0 && y < 25)
                                showQSystemMenu('scroll');
                        else
                                hideQSystemMenu('scroll');
                }

                super.onMouseMove(...);
        }
//↑--------------------------------------- ここまで追加部分--

        //------------------------------------------------------- キーボード操作 --

        function processKeys(key, shift)
        {
キーボード対応させます。
「移動表示」の場合、上下左右キーで各簡易メニューを表示します。
キャンセルはESCキーで、ESCキーを押すと座標(800,600)にマウスカーソルを移動させています。
function processKeys(key, shift)に、以下の命令を追加します。
        //------------------------------------------------------- キーボード操作 --

        function processKeys(key, shift)
        {
                if(checkProceedingKey(key, shift)) return;

                if(key == #'F')
                {
                        // 次の選択肢/未読まで進む
                        skipToNextStopByKey();
                        return;
                }

                // (中略)

                if(key == #'R' || (key == VK_UP && (shift & ssShift)))
                {
                        // メッセージ履歴を表示
                        showHistoryByKey();
                        return;
                }

//↓--------------------------------------- ここから追加部分--
                //mebius:キーボード対応。PageUP、PageDownで簡易メニューのページ変更。
                if(key == VK_PRIOR || key == VK_NEXT)
                {
                        //簡易セーブの場合、ページ変更
                        if (kag.fore.messages[qmenuLayer_Save].visible == true)
                        {
                                if (key == VK_PRIOR)
                                {
                                        if (sf.saveload_page == 0)
                                                sf.saveload_page = 10;
                                        else
                                                sf.saveload_page--;

                                        kag.redrawQSaveMenu();
                                }
                                else if (key == VK_NEXT)
                                {
                                        if (sf.saveload_page == 10)
                                                sf.saveload_page = 0;
                                        else
                                                sf.saveload_page++;

                                        kag.redrawQSaveMenu();
                                }
                                return;
                        }
                }
//↑--------------------------------------- ここまで追加部分--

                if(key == VK_ESCAPE)
                {
//↓--------------------------------------- ここから追加部分--
                        //mebius:キーボード対応
                        //簡易メニュー(下:命令)、簡易メニュー(右:セーブ)上なら非表示にする
                        if(f.qmenu_enabled && kag.fore.messages[qmenuLayer_Exec].visible == true && sf.qmenu_exec_mode > 0)
                        {
                                if (sf.qmenu_exec_mode == 2)
                                {
                                        kag.fore.base.setCursorPos(800,600);
                                        kag.focusedLayer = null;
                                        return;
                                }
                                else if (sf.qmenu_exec_mode == 1)
                                {
                                        hideQExecMenu('nowait');
                                        kag.fore.base.setCursorPos(800,600);
                                        kag.focusedLayer = null;
                                        return;
                                }
                        }
                        else if (f.qmenu_enabled && fore.messages[qmenuLayer_Save].visible == true)
                        {
                                if (sf.qmenu_save_mode == 2)
                                {
                                        kag.fore.base.setCursorPos(800,600);
                                        kag.focusedLayer = null;
                                        return;
                                }
                                else if (sf.qmenu_save_mode == 1)
                                {
                                        hideQSaveMenu('nowait');
                                        hideQMenuHint();
                                        kag.fore.base.setCursorPos(800,600);
                                        kag.focusedLayer = null;
                                        return;
                                }
                        }
                        else if (f.qmenu_enabled && fore.messages[qmenuLayer_Config].visible == true)
                        {
                                if (sf.qmenu_config_mode == 2)
                                {
                                        kag.fore.base.setCursorPos(800,600);
                                        kag.focusedLayer = null;
                                        return;
                                }
                                else if (sf.qmenu_config_mode == 1)
                                {
                                        hideQConfigMenu('nowait');
                                        hideQMenuHint();
                                        kag.fore.base.setCursorPos(800,600);
                                        kag.focusedLayer = null;
                                        return;
                                }
                        }
                        else if (f.qmenu_enabled && fore.messages[qmenuLayer_System].visible == true)
                        {
                                if (sf.qmenu_system_mode == 2)
                                {
                                        kag.fore.base.setCursorPos(800,600);
                                        kag.focusedLayer = null;
                                        return;
                                }
                                else if (sf.qmenu_system_mode == 1)
                                {
                                        hideQSystemMenu('nowait');
                                        hideQMenuHint();
                                        kag.fore.base.setCursorPos(800,600);
                                        kag.focusedLayer = null;
                                        return;
                                }
                        }
//↑--------------------------------------- ここまで追加部分--

                        // メッセージを消す
                        if(typeof this.rightClickMenuItem != "undefined" &&
                                rightClickMenuItem.enabled)
                        {
                                rightClickMenuItem.click(); // クリックをエミュレート
                                return;
                        }
                }

//↓--------------------------------------- ここから追加部分--
                //mebius:キーボード対応
                if(f.qmenu_enabled)
                {
                        if(key == VK_UP && fore.messages[qmenuLayer_System].visible == false)
                        {
                                if (sf.qmenu_system_mode == 1)
                                        showQSystemMenu('nowait');
                                return;
                        }
                        if(key == VK_LEFT && fore.messages[qmenuLayer_Config].visible == false)
                        {
                                if (sf.qmenu_config_mode == 1)
                                        showQConfigMenu('nowait');
                                return;
                        }
                        if(key == VK_DOWN && kag.fore.messages[qmenuLayer_Exec].visible == false)
                        {
                                if (sf.qmenu_exec_mode == 1)
                                        showQExecMenu('nowait');
                                return;
                        }
                        if(key == VK_RIGHT && fore.messages[qmenuLayer_Save].visible == false)
                        {
                                if (sf.qmenu_save_mode == 1)
                                        showQSaveMenu('nowait');
                                /*
                                if (qmenuSave_UpButton !== void)
                                {
                                        kag.focusedLayer = qmenuSave_UpButton;
                                        //kag.fore.base.setCursorPos(768,14);
                                        //qmenuSave_UpButton.focus();
                                        tf.qsavefocus = true;
                                }
                                */
                                return;
                        }
                }
//↑--------------------------------------- ここまで追加部分--

        }
マウスホイールに対応させます。
function onMouseWheel(shift, delta, x, y)に、以下の命令を追加します。
        function onMouseWheel(shift, delta, x, y)
        {
                // ホイールが回転した
                super.onMouseWheel(...);

//↓--------------------------------------- ここから追加部分--
                //mebius:マウスが簡易メニュー(右:セーブ)表示領域なら、ページ変更する。
                if (sf.qmenu_save_mode >= 1 && f.qmenu_enabled && fore.messages[qmenuLayer_Save].visible == true)
                {
                        if (x > 760  && y > 5 && y < 570)
                        {
                                if (delta > 0)
                                        upPageQSaveMenuClick();
                                else if (delta < 0)
                                        downPageQSaveMenuClick();
                        }
                        return;
                }
//↑--------------------------------------- ここまで追加部分--

                if(!historyLayer.visible)
                {
                        if(delta > 0)
                                showHistoryByKey(); // メッセージ履歴を表示
                        else if(System.getTickCount() - lastHistoryHiddenTick > 150) 
                                        onPrimaryClick(); // クリックをエミュレート
                        // ↑ tick を比較しているのは、メッセージ履歴を隠す操作とホイールを
                        // 手前に回す操作が連続した場合に勝手に読み進むのをある程度防ぐ仕掛け
                }
                else
                {
                        // メッセージ履歴にイベントを垂れ流す
                        historyLayer.windowMouseWheel(shift, delta, x, y);
                }
        }

簡易メニューの本体部分の命令です。
ここで各ボタンの座標や画像、処理方法などを記します。
個別に対応するように修正して下さい。
ボタンを押した後の処理も、個別に追加・修正して下さい。(function ~Click()という命令に記述します)
クイックセーブ・クイックロードボタンは入れていませんが、命令を参考にしてボタンを増やして、処理させればすぐにできると思います。

MainWindow.tjsの最後の方にある「タグハンドラ群の終わり」の後ぐらいに、以下の命令を追加します。
        waittrig : function(elm)
        {
                // トリガを待つ
                return waitTrigger(elm);
        } incontextof this,

        //----------------------------------------------- タグハンドラ群の終わり --

                interrupt : function(elm) { return -2; } incontextof this ];
        }

//↓--------------------------------------- ここから追加部分--
        //--------------------------------------- mebius:命令群 --
        //----簡易メニュー共通---------------------------------------------------------

        //簡易メニューのレイヤー定義
        function defineQMenuLayers()
        {
                //定義されたシステム変数から、メッセージレイヤナンバーを抜き出して保持します。
                var exec_layer = sf.qmenu_exec_layer;
                var save_layer = sf.qmenu_save_layer;
                var config_layer = sf.qmenu_config_layer;
                var system_layer = sf.qmenu_system_layer;
                var hint_layer = sf.qmenu_hint_layer;

                qmenuLayer_Exec = +exec_layer.substr(7);
                qmenuLayer_Save = +save_layer.substr(7);
                qmenuLayer_Config = +config_layer.substr(7);
                qmenuLayer_System = +system_layer.substr(7);
                qmenuLayer_Hint = +hint_layer.substr(7);
        }

        //----簡易メニュー(下:命令)---------------------------------------------------------

        //簡易メニュー(下:命令)を作成
        function makeQExecMenu(backmode)
        {
                var destlayer;
                if (backmode == 'back')
                        destlayer = back.messages[qmenuLayer_Exec];
                else
                        destlayer = fore.messages[qmenuLayer_Exec];

                destlayer.face = dfBoth;

                //読込ボタン
                if (qmenuExec_LoadButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec01";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(158,550,'  読込','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.loadQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_LoadButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_LoadButton.showFocusImage = false;

                        destlayer.locate(180,577);
                        destlayer.addButton(qtxtElm);
                }

                //保存ボタン
                if (qmenuExec_SaveButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec02";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(229,550,'  保存','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.saveQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_SaveButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_SaveButton.showFocusImage = false;

                        destlayer.locate(250,577);
                        destlayer.addButton(qtxtElm);
                }

                //設定ボタン
                if (qmenuExec_ConfigButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec11";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(388,550,'  設定','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.configQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_ConfigButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_ConfigButton.showFocusImage = false;

                        destlayer.locate(410,577);
                        destlayer.addButton(qtxtElm);
                }

                //履歴ボタン
                if (qmenuExec_HistryButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec03";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(448,550,'  履歴','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.historyQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_HistryButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_HistryButton.showFocusImage = false;

                        destlayer.locate(470,577);
                        destlayer.addButton(qtxtElm);
                }

                //ボイス再生ボタン
                if (qmenuExec_VoiceButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec09";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(501,550,' 音声再生','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.voiceQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_VoiceButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_VoiceButton.showFocusImage = false;

                        destlayer.locate(520,577);
                        destlayer.addButton(qtxtElm);
                }

                //スキップボタン
                if (qmenuExec_SkipButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec04";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(547,550,'  早送り','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.skipQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_SkipButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_SkipButton.showFocusImage = false;

                        destlayer.locate(570,577);
                        destlayer.addButton(qtxtElm);
                }

                //自動再生ボタン
                if (qmenuExec_AutoButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec05";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(596,550,' 自動再生','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.autoQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_AutoButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_AutoButton.showFocusImage = false;

                        destlayer.locate(620,577);
                        destlayer.addButton(qtxtElm);
                }

                //消去ボタン
                if (qmenuExec_EraseButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec06";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(644,550,' 文字枠消去','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.eraseQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_EraseButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_EraseButton.showFocusImage = false;

                        destlayer.locate(670,577);
                        destlayer.addButton(qtxtElm);
                }

                //メニューボタン
                /*
                if (qmenuExec_MenuButton === void)
                {
                        var qtxtElm = %[];

                        qtxtElm.graphic = "qmenu_exec07";
                        qtxtElm.hint = '';
                        qtxtElm.visible = true;
                        qtxtElm.onenter = "kag.makeQMenuHint(644,550,'メニュー表示','qmenu_hint_base01')";
                        qtxtElm.onleave = "kag.hideQMenuHint()";
                        qtxtElm.exp = "kag.menuQExecMenuClick()";
                        qtxtElm.rc = "";
                        //qtxtElm.enterse ='';
                        //qtxtElm.entersebuf = '';
                        //qtxtElm.leavese = '';
                        //qtxtElm.leavesebuf = '';

                        qmenuExec_MenuButton = new LinkButtonLayer(this, destlayer);
                        qmenuExec_MenuButton.showFocusImage = false;

                        destlayer.locate(670,577);
                        destlayer.addButton(qtxtElm);
                }
                */

        }

        //簡易メニュー(下:命令)を表示
        function showQExecMenu(mvmode,backmode)
        {
                var destlayer;

                if(skipMode && sf.qmenu_exec_mode != 2) return;

                if (backmode == "back")
                        destlayer = back.messages[qmenuLayer_Exec];
                else
                        destlayer = fore.messages[qmenuLayer_Exec];

                if (!movemode_qexec)
                {
                        if (destlayer.visible == false)
                                makeQExecMenu();

                        if (mvmode == "scroll")  //"scroll"なら移動表示
                        {
                                destlayer.visible = true;
                                movemode_qexec = 1;
                                timermove_qexec.enabled = true;
                        }
                        else        //"nowait"なら瞬間表示
                        {
                                destlayer.visible = true;
                                destlayer.top = 0;
                        }
                }

        }

        //簡易メニュー(下:命令)の消去
        function hideQExecMenu(mvmode)
        {
                if (!movemode_qexec)
                {
                        if (mvmode == "scroll")  //"scroll"なら移動表示
                        {
                                if (f.qmenu_enabled && fore.messages[qmenuLayer_Exec].visible == true)
                                        //kag.fore.messages[qmenuLayer_Exec].visible = true;
                                        movemode_qexec = 2;
                                        timermove_qexec.enabled = true;
                        }
                        else        //"nowait"なら瞬間消去
                        {
                                fore.messages[qmenuLayer_Exec].top = sf.qmenu_exec_movepixel;
                                fore.messages[qmenuLayer_Exec].visible = false;
                                deleteQExecMenu();
                        }
                }
        }

        //簡易メニュー(下:命令)を消去
        function deleteQExecMenu()
        {
                if(qmenuExec_LoadButton !== void)
                {
                        invalidate qmenuExec_LoadButton;
                        qmenuExec_LoadButton = void;
                }
                if(qmenuExec_SaveButton !== void)
                {
                        invalidate qmenuExec_SaveButton;
                        qmenuExec_SaveButton = void;
                }
                if(qmenuExec_ConfigButton !== void)
                {
                        invalidate qmenuExec_ConfigButton;
                        qmenuExec_ConfigButton = void;
                }
                if(qmenuExec_HistryButton !== void)
                {
                        invalidate qmenuExec_HistryButton;
                        qmenuExec_HistryButton = void;
                }
                if(qmenuExec_VoiceButton !== void)
                {
                        invalidate qmenuExec_VoiceButton;
                        qmenuExec_VoiceButton = void;
                }
                if(qmenuExec_SkipButton !== void)
                {
                        invalidate qmenuExec_SkipButton;
                        qmenuExec_SkipButton = void;
                }
                if(qmenuExec_AutoButton !== void)
                {
                        invalidate qmenuExec_AutoButton;
                        qmenuExec_AutoButton = void;
                }
                if(qmenuExec_EraseButton !== void)
                {
                        invalidate qmenuExec_EraseButton;
                        qmenuExec_EraseButton = void;
                }
                if(qmenuExec_MenuButton !== void)
                {
                        invalidate qmenuExec_MenuButton;
                        qmenuExec_MenuButton = void;
                }
                fore.messages[qmenuLayer_Exec].clear();
        }

        //簡易メニュー(下:命令)の表示用タイマ
        function onTimerMoveQExec() {
                var movespeed = sf.qmenu_exec_movespeed;//動く速度
                switch (movemode_qexec) {
                        case 0://ストップ
                                timermove_qexec.enabled = false;
                                break;
                        case 1://表示
                                if (fore.messages[qmenuLayer_Exec].top > 0) {
                                        fore.messages[qmenuLayer_Exec].top -= movespeed;
                                } else {
                                        timermove_qexec.enabled = false;
                                        movemode_qexec = 0;
                                }
                                break;
                        case 2://消去
                                if (fore.messages[qmenuLayer_Exec].top < sf.qmenu_exec_movepixel) {
                                        fore.messages[qmenuLayer_Exec].top += movespeed;
                                } else {
                                        timermove_qexec.enabled = false;
                                        movemode_qexec = 0;
                                        kag.fore.messages[qmenuLayer_Exec].visible = false;
                                        deleteQExecMenu();
                                }
                                break;
                }
        }

        function checkTextDrawing()//エラー回避のため、文字表示中は処理させないための判定用。
        {
                if ((!clickWaiting && !inSleep) || kag.skipMode>0 || kag.autoMode)
                        return true;
                else
                        return false;

        }

        function loadQExecMenuClick()//ロードボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*load');
        }

        function saveQExecMenuClick()//セーブボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*save');
        }

        function configQExecMenuClick()//コンフィグボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*config');
        }

        function historyQExecMenuClick()//履歴ボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*history');
        }

        function voiceQExecMenuClick()//ボイス再生ボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                //if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*playvoice');
        }

        function skipQExecMenuClick()//スキップボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                //if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*skipmode');
        }

        function autoQExecMenuClick()//自動再生ボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                //if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*autoplay');
        }

        function eraseQExecMenuClick()//文字枠消去ボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*erasetextwindow');
        }

        function menuQExecMenuClick()//メニューボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                if (sf.qmenu_exec_mode != 2) kag.hideQExecMenu();
                kag.callExtraConductor('qmenu.ks','*openmenu');
        }

        //----簡易メニュー(右:セーブ)---------------------------------------------------------

        //簡易メニュー(右:セーブ)を作成
        function makeQSaveMenu(backmode)
        {
                var destlayer;
                if (backmode == 'back')
                        destlayer = back.messages[qmenuLayer_Save];
                else
                        destlayer = fore.messages[qmenuLayer_Save];

                destlayer.face = dfBoth;

                //上ボタン
                if (qmenuSave_UpButton === void)
                {
                        var qsaveElm = %[];

                        qsaveElm.graphic = "qmenu_save_changepage01";
                        qsaveElm.hint = '';
                        qsaveElm.visible = true;
                        if (sf.saveload_page == 0)
                                qsaveElm.onenter = "kag.makeQMenuHint(573,17,'  最後のページに移動します。','qmenu_hint_base02')";
                        else
                                qsaveElm.onenter = "kag.makeQMenuHint(573,17,'  前のページに移動します。','qmenu_hint_base02')";
                        qsaveElm.onleave = "kag.hideQMenuHint()";
                        qsaveElm.exp = "kag.upPageQSaveMenuClick()";
                        qsaveElm.rc = "";
                        //qsaveElm.enterse ='';
                        //qsaveElm.entersebuf = '';
                        //qsaveElm.leavese = '';
                        //qsaveElm.leavesebuf = '';

                        qmenuSave_UpButton = new LinkButtonLayer(this, destlayer);
                        qmenuSave_UpButton.showFocusImage = false;

                        destlayer.locate(767,13);
                        destlayer.addButton(qsaveElm);

                }

                //各エントリ作成
                for (var i=0;i<10;i++)
                {
                        if (qmenuSave_EntryButton[i] === void)
                        {
                                var qsaveElm = %[];
                                var entry = i;

                                if (sf.saveload_page == 10)//オートセーブの場合、表示位置を修正
                                {
                                        entry = sf.autosave_entry - i-1;
                                        if (entry < 0) entry+=10;//負になった場合、+10して整数にする
                                }

                                if (sf.saveload_page == 10)
                                        qsaveElm.graphic = "qmenu_save_highlight01";
                                else
                                        qsaveElm.graphic = "qmenu_save_highlight01";
                                qsaveElm.hint = '';
                                qsaveElm.visible = true;
                                qsaveElm.onenter = "kag.makeQSaveMenuHint("+i+"+sf.saveload_page*10,420,44+48*"+entry+")";
                                qsaveElm.onleave = "kag.hideQMenuHint()";
                                qsaveElm.exp = "kag.lEntryQSaveMenuClick("+i+")";
                                qsaveElm.rc = "kag.rEntryQSaveMenuClick("+i+")";
                                //qsaveElm.enterse ='';
                                //qsaveElm.entersebuf = '';
                                //qsaveElm.leavese = '';
                                //qsaveElm.leavesebuf = '';

                                qmenuSave_EntryButton[i] = new LinkButtonLayer(this, destlayer);
                                qmenuSave_EntryButton[i].showFocusImage = false;

                                destlayer.locate(767,44+48*entry);
                                destlayer.addButton(qsaveElm);


                                //----------エントリ内容を画像で表示する場合----------

                                if (sf.saveload_page == 10)//オートセーブの場合
                                {
                                        //ベース画像読み込み
                                        var tmplayer = new Layer(this, destlayer);
                                        tmplayer.loadImages("qmenu_save_entry02");
                                        destlayer.copyRect(767,44+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                                        invalidate tmplayer;

                                        //「自動」文字描画
                                        var tmplayer = new Layer(this, destlayer);
                                        tmplayer.loadImages("qmenu_save_mozi_auto");
                                        destlayer.operateRect(767, 50+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                        invalidate tmplayer;

                                        //数値
                                        var tmplayer = new Layer(this, destlayer);

                                        if (entry < 9)//1桁の場合
                                        {
                                                switch (entry) {
                                                        case 0: tmplayer.loadImages("qmenu_save_mozi01");break;
                                                        case 1: tmplayer.loadImages("qmenu_save_mozi02");break;
                                                        case 2: tmplayer.loadImages("qmenu_save_mozi03");break;
                                                        case 3: tmplayer.loadImages("qmenu_save_mozi04");break;
                                                        case 4: tmplayer.loadImages("qmenu_save_mozi05");break;
                                                        case 5: tmplayer.loadImages("qmenu_save_mozi06");break;
                                                        case 6: tmplayer.loadImages("qmenu_save_mozi07");break;
                                                        case 7: tmplayer.loadImages("qmenu_save_mozi08");break;
                                                        case 8: tmplayer.loadImages("qmenu_save_mozi09");break;
                                                }
                                                destlayer.operateRect(777, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                        }
                                        else//2桁の場合
                                        {
                                                //オートセーブのスロットを10より多く作る場合、個別に修正して下さい。
                                                tmplayer.loadImages("qmenu_save_mozi01");
                                                destlayer.operateRect(774, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                                tmplayer.loadImages("qmenu_save_mozi00");
                                                destlayer.operateRect(781, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                        }

                                        invalidate tmplayer;

                                }
                                else//通常セーブの場合
                                {
                                        //ベース画像読み込み
                                        var tmplayer = new Layer(this, destlayer);
                                        tmplayer.loadImages("qmenu_save_entry01");
                                        destlayer.copyRect(767,44+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                                        invalidate tmplayer;

                                        //表示位置調整
                                        var num = i+1+sf.saveload_page*10;

                                        if (num < 10)//1桁の場合
                                        {
                                                var tmplayer = new Layer(this, destlayer);
                                                switch (num) {
                                                        case 1: tmplayer.loadImages("qmenu_save_mozi01");break;
                                                        case 2: tmplayer.loadImages("qmenu_save_mozi02");break;
                                                        case 3: tmplayer.loadImages("qmenu_save_mozi03");break;
                                                        case 4: tmplayer.loadImages("qmenu_save_mozi04");break;
                                                        case 5: tmplayer.loadImages("qmenu_save_mozi05");break;
                                                        case 6: tmplayer.loadImages("qmenu_save_mozi06");break;
                                                        case 7: tmplayer.loadImages("qmenu_save_mozi07");break;
                                                        case 8: tmplayer.loadImages("qmenu_save_mozi08");break;
                                                        case 9: tmplayer.loadImages("qmenu_save_mozi09");break;
                                                }
                                                destlayer.operateRect(777, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                                invalidate tmplayer;
                                        }
                                        else if (num == 100)//3桁の場合(ここでは100のみ)
                                        {
                                                var tmplayer = new Layer(this, destlayer);
                                                tmplayer.loadImages("qmenu_save_mozi01");
                                                destlayer.operateRect(769, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                                tmplayer.loadImages("qmenu_save_mozi00");
                                                destlayer.operateRect(776, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                                tmplayer.loadImages("qmenu_save_mozi00");
                                                destlayer.operateRect(783, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                                invalidate tmplayer;
                                        }
                                        else//2桁の場合
                                        {
                                                var tmplayer = new Layer(this, destlayer);
                                                var num_10 = num\10;
                                                var num_1 = num%10;

                                                switch (num_10) {//10の位
                                                        case 1: tmplayer.loadImages("qmenu_save_mozi01");break;
                                                        case 2: tmplayer.loadImages("qmenu_save_mozi02");break;
                                                        case 3: tmplayer.loadImages("qmenu_save_mozi03");break;
                                                        case 4: tmplayer.loadImages("qmenu_save_mozi04");break;
                                                        case 5: tmplayer.loadImages("qmenu_save_mozi05");break;
                                                        case 6: tmplayer.loadImages("qmenu_save_mozi06");break;
                                                        case 7: tmplayer.loadImages("qmenu_save_mozi07");break;
                                                        case 8: tmplayer.loadImages("qmenu_save_mozi08");break;
                                                        case 9: tmplayer.loadImages("qmenu_save_mozi09");break;
                                                }
                                                destlayer.operateRect(774, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                                invalidate tmplayer;

                                                var tmplayer = new Layer(this, destlayer);
                                                switch (num_1) {//1の位
                                                        case 0: tmplayer.loadImages("qmenu_save_mozi00");break;
                                                        case 1: tmplayer.loadImages("qmenu_save_mozi01");break;
                                                        case 2: tmplayer.loadImages("qmenu_save_mozi02");break;
                                                        case 3: tmplayer.loadImages("qmenu_save_mozi03");break;
                                                        case 4: tmplayer.loadImages("qmenu_save_mozi04");break;
                                                        case 5: tmplayer.loadImages("qmenu_save_mozi05");break;
                                                        case 6: tmplayer.loadImages("qmenu_save_mozi06");break;
                                                        case 7: tmplayer.loadImages("qmenu_save_mozi07");break;
                                                        case 8: tmplayer.loadImages("qmenu_save_mozi08");break;
                                                        case 9: tmplayer.loadImages("qmenu_save_mozi09");break;
                                                }
                                                destlayer.operateRect(781, 65+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                                invalidate tmplayer;

                                        }

                                        //最新の場合、「最新」を追加
                                        if (num == sf.new_savedata+1)
                                        {
                                                var tmplayer = new Layer(this, destlayer);
                                                tmplayer.loadImages("qmenu_save_mozi_new");
                                                destlayer.operateRect(767, 50+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight,omPsNormal,255);
                                                invalidate tmplayer;
                                        }
                                }

                                //----------エントリ内容をフォントで表示する場合----------
                                /*
                                //番号色
                                var txtcolor = 0x000000;
                                var autotxtcolor = 0x550000;
                                var shadowcolor = 0xffffff;

                                if (sf.saveload_page == 10)//オートセーブの場合
                                {
                                        var str;
                                        //ベース画像読み込み
                                        var tmplayer = new Layer(this, destlayer);
                                        tmplayer.loadImages("qmenu_save_entry02");
                                        destlayer.copyRect(767,44+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                                        invalidate tmplayer;

                                        if (entry == 9)
                                                str = entry+1;
                                        else
                                                str = " " + (entry+1);
                                        destlayer.drawText(770, 55+48*entry, "自動", autotxtcolor,255,kag.chDefaultAntialiased,64,shadowcolor,0,1,1);
                                        destlayer.drawText(777, 67+48*entry, str, autotxtcolor,255,kag.chDefaultAntialiased,64,shadowcolor,0,1,1);
                                }
                                else//通常セーブの場合
                                {
                                        //表示位置調整
                                        var num = i+1+sf.saveload_page*10;

                                        //ベース画像読み込み
                                        var tmplayer = new Layer(this, destlayer);
                                        tmplayer.loadImages("qmenu_save_entry01");
                                        destlayer.copyRect(767,44+48*entry, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                                        invalidate tmplayer;

                                        if (num < 10)
                                                destlayer.drawText(780, 57+48*entry, num, txtcolor,255,kag.chDefaultAntialiased,64,shadowcolor,0,1,1);
                                        else if (num == 100)
                                                destlayer.drawText(773, 57+48*entry, num, txtcolor,255,kag.chDefaultAntialiased,64,shadowcolor,0,1,1);
                                        else
                                                destlayer.drawText(776, 57+48*entry, num, txtcolor,255,kag.chDefaultAntialiased,64,shadowcolor,0,1,1);

                                        //最新の場合、「最新」を追加
                                        if (num == sf.new_savedata+1)
                                                destlayer.drawText(770, 72+48*entry, "最新", 0xff0000,255,kag.chDefaultAntialiased,64,shadowcolor,0,1,1);
                                }
                                */

                        }
                }

                //下ボタン
                if (qmenuSave_DownButton === void)
                {
                        var qsaveElm = %[];

                        qsaveElm.graphic = "qmenu_save_changepage02";
                        qsaveElm.hint = '';
                        qsaveElm.visible = true;
                        if (sf.saveload_page == 10)
                                qsaveElm.onenter = "kag.makeQMenuHint(573,526,'  最初のページに戻ります。','qmenu_hint_base02')";
                        else
                                qsaveElm.onenter = "kag.makeQMenuHint(573,526,'  次のページに移動します。','qmenu_hint_base02')";
                        qsaveElm.onleave = "kag.hideQMenuHint()";
                        qsaveElm.exp = "kag.downPageQSaveMenuClick()";
                        qsaveElm.rc = "";
                        //qsaveElm.enterse ='';
                        //qsaveElm.entersebuf = '';
                        //qsaveElm.leavese = '';
                        //qsaveElm.leavesebuf = '';

                        qmenuSave_DownButton = new LinkButtonLayer(this, destlayer);
                        qmenuSave_DownButton.showFocusImage = false;

                        destlayer.locate(767,524);
                        destlayer.addButton(qsaveElm);
                }

        }

        //簡易メニュー(右:セーブ)を消去
        function deleteQSaveMenu()
        {
                if(qmenuSave_UpButton !== void)
                {
                        invalidate qmenuSave_UpButton;
                        qmenuSave_UpButton = void;
                }
                if(qmenuSave_DownButton !== void)
                {
                        invalidate qmenuSave_DownButton;
                        qmenuSave_DownButton = void;
                }
                for (var i=0;i<10;i++)
                {
                        if(qmenuSave_EntryButton[i] !== void)
                        {
                                invalidate qmenuSave_EntryButton[i];
                                qmenuSave_EntryButton[i] = void;
                        }
                }
                fore.messages[qmenuLayer_Save].clear();
        }

        //簡易メニュー(右:セーブ)を表示
        function showQSaveMenu(mvmode,backmode)
        {
                var destlayer;

                if(skipMode && sf.qmenu_save_mode != 2) return;

                if (backmode == "back")
                        destlayer = back.messages[qmenuLayer_Save];
                else
                        destlayer = fore.messages[qmenuLayer_Save];

                if (!movemode_qsave)
                {
                        if (destlayer.visible == false)
                                makeQSaveMenu();

                        if (mvmode == "scroll")  //"scroll"なら移動表示
                        {
                                destlayer.visible = true;
                                movemode_qsave = 1;
                                timermove_qsave.enabled = true;
                        }
                        else        //"nowait"なら瞬間表示
                        {
                                destlayer.visible = true;
                                destlayer.left = 0;
                        }
                }

        }

        //簡易メニュー(右:セーブ)を再描画
        function redrawQSaveMenu()
        {
                deleteQSaveMenu();
                fore.messages[qmenuLayer_Save].clear();
                makeQSaveMenu();
        }

        //簡易メニュー(右:セーブ)を隠す
        function hideQSaveMenu(mvmode)
        {
                if (!movemode_qsave)
                {
                        if (mvmode == "scroll")  //"scroll"なら移動表示
                        {
                                if (f.qmenu_enabled && fore.messages[qmenuLayer_Save].visible == true)
                                        //fore.messages[qmenuLayer_Save].visible = true;
                                        movemode_qsave = 2;
                                        timermove_qsave.enabled = true;
                        }
                        else        //"nowait"なら瞬間表示
                        {
                                fore.messages[qmenuLayer_Save].visible = false;
                                fore.messages[qmenuLayer_Save].left = sf.qmenu_save_movepixel;
                                deleteQSaveMenu();
                        }
                }
        }

        //簡易メニュー(右:セーブ)の表示用タイマ
        function onTimerMoveQSave() {
                var movespeed = sf.qmenu_save_movespeed;//動く速度
                switch (movemode_qsave) {
                        case 0://ストップ
                                timermove_qsave.enabled = false;
                                break;
                        case 1://表示
                                if (fore.messages[qmenuLayer_Save].left > 0) {
                                        fore.messages[qmenuLayer_Save].left -= movespeed;
                                } else {
                                        timermove_qsave.enabled = false;
                                        movemode_qsave = 0;
                                }
                                break;
                        case 2://消去
                                if (fore.messages[qmenuLayer_Save].left < sf.qmenu_save_movepixel) {
                                        fore.messages[qmenuLayer_Save].left += movespeed;
                                } else {
                                        timermove_qsave.enabled = false;
                                        movemode_qsave = 0;
                                        fore.messages[qmenuLayer_Save].visible = false;
                                        deleteQSaveMenu();
                                }
                                break;
                }
        }


        //簡易メニュー(右:セーブ)のツールチップヒント作成
        function makeQSaveMenuHint(num,x,y)
        {
                if(skipMode) return;
                var txtcolor = 0x000000;//文字色

                var text = kag.getBookMarkPageName(num);
                kag.fore.messages[qmenuLayer_Hint].face = dfBoth;

                //ベース画像の読み込み
                var tmplayer = new Layer(this, kag.fore.messages[qmenuLayer_Hint]);
                tmplayer.loadImages("qmenu_save_hint_base");
                kag.fore.messages[qmenuLayer_Hint].copyRect(0, 0, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                invalidate tmplayer;

                // サムネイル画像の読み込み
                var tmplayer = new Layer(this, kag.fore.messages[qmenuLayer_Hint]);
                var tnname = kag.getBookMarkFileNameAtNum(num);

                if(Storages.isExistentStorage(tnname) && kag.bookMarkDates[num] != '')
                {
                        tmplayer.loadImages(tnname);
                }
                else
                {
                        // サムネイル画像が手動で削除されたときの対処
                        if(kag.bookMarkDates[num] != '')
                        {
                                kag.bookMarkNames[num] = ''; // 栞名
                                kag.bookMarkDates[num] = ''; // 保存年月日
                                if(kag.scflags.bookMarkComments !== void)
                                        kag.scflags.bookMarkComments[num] = ''; // コメント
                                kag.setBookMarkMenuCaptions();
                        }

                        tmplayer.loadImages("dummy");  // No Data
                }

                kag.fore.messages[qmenuLayer_Hint].copyRect(3, 3, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                invalidate tmplayer;

                kag.fore.messages[qmenuLayer_Hint].left = x;
                kag.fore.messages[qmenuLayer_Hint].top = y;
                kag.fore.messages[qmenuLayer_Hint].setSize(344, 94);
                kag.fore.messages[qmenuLayer_Hint].font.height = 12;

                // 番号を表示
                var str = string (num + 1);
                var ty = kag.fore.messages[qmenuLayer_Hint].font.getTextHeight(str);
                if (sf.saveload_page == 10)//オートセーブの場合
                {
                        var entry = sf.autosave_entry - num + 100;
                        if (entry <= 0) entry+=10;
                        if (entry == 10)
                                str = "自動" + string (entry);  //自動セーブデータは「自動」と表示する
                        else
                                str = "自動 " + string (entry); //位置調整のため半角スペースを追加
                        kag.fore.messages[qmenuLayer_Hint].drawText(301, 4, str, txtcolor);
                }
                else
                        kag.fore.messages[qmenuLayer_Hint].drawText(322, 4, str, txtcolor);

                // 栞の保存名を表示
                var str = kag.bookMarkNames[num];
                if(str == '') str = '情報なし';
                if (sf.saveload_page == 10) str = "(自動)"+ str;        //オートセーブデータは「自動」を追加する

                //シナリオ中の日付表示をする場合、ラベルに':'(半角コロン)の区切り記号をつけたら、
                //その区切り記号より前を「シナリオ中の日付」、それより後を「サブタイトル」と設定することができます。
                //セーブ・ロード画面でもこの機能を使う場合、
                //saveload.ksのfunction SaveDataItemLayer(window, parent, num)内部も同様に変更して下さい。
                //var sepnum = str.indexOf(":");//詳細情報

                //シナリオ中の日付表示
                /*
                if (sepnum != -1)
                {
                        kag.fore.messages[6].drawText(129, 25, str.substring(0,sepnum), txtcolor);
                        str = str.substring(sepnum+1);
                }
                */

                //サブタイトル表示
                kag.fore.messages[qmenuLayer_Hint].drawText(143, 45, str, txtcolor);

                //上書き禁止の表示
                if (kag.bookMarkProtectedStates[num])
                {
                        kag.fore.messages[qmenuLayer_Hint].drawText(217, 5, "(上書き禁止)", 0xff0000);
                }

                // 日付を表示
                if(kag.bookMarkDates[num] == '')
                {
                        str = " ----/--/-- --:--";
                }
                else
                {
                        if (sf.new_savedata == num)//最新のものは"最新"を追加
                                kag.fore.messages[qmenuLayer_Hint].drawText(187, 77, "(最新)", 0xff0000);
                        if (num == ((sf.autosave_entry == 0)? 10:sf.autosave_entry) + 99)//オートセーブの最新のものには(新)を追加
                                kag.fore.messages[qmenuLayer_Hint].drawText(187, 77, "(新)", 0xff0000);
                        if (num == (sf.autosave_entry + 100))//オートセーブの最古のものには(古)を追加
                                kag.fore.messages[qmenuLayer_Hint].drawText(187, 77, "(古)", 0xff0000);
                        str = kag.bookMarkDates[num];
                }

                kag.fore.messages[qmenuLayer_Hint].drawText(233, 77, str, txtcolor);
                kag.fore.messages[qmenuLayer_Hint].visible = true;

        }

        //簡易メニューなどのツールチップヒント作成
        function makeQMenuHint(x,y,str,imgfile,destlayer)//imgtypeは画像ファイル名
        {
                if(skipMode) return;

                if (sf.qmenu_hint)
                {
                        if (destlayer == '')
                                destlayer = kag.fore.messages[qmenuLayer_Hint];
                        destlayer.face = dfBoth;

                        //ベース画像の読み込み
                        var tmplayer = new Layer(this, destlayer);
                        if (imgfile != '')
                                tmplayer.loadImages(imgfile);
                        destlayer.copyRect(0, 0, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                        invalidate tmplayer;

                        destlayer.left = x;
                        destlayer.top = y;

                        destlayer.drawText(8, 6, str, 0x000000);
                        destlayer.visible = true;
                }

        }

        //簡易メニューのツールチップヒントを隠す
        function hideQMenuHint(destlayer)
        {
                if (destlayer == '')
                        destlayer = kag.fore.messages[qmenuLayer_Hint];
                destlayer.visible = false;
                destlayer.clear();
        }

        //ページUPボタン処理
        function upPageQSaveMenuClick()
        {
                if (checkTextDrawing()) return;//エラー回避

                if (sf.saveload_page == 0)
                        sf.saveload_page = 10;
                else
                        sf.saveload_page--;

                kag.redrawQSaveMenu();
                //showQSaveMenu(0);
        }

        //各セーブエントリボタン処理(左クリック(セーブ))
        function lEntryQSaveMenuClick(num)
        {
                if (checkTextDrawing()) return;//エラー回避
                if (sf.saveload_page < 10)
                        kag.saveBookmarkAutoMode(num+sf.saveload_page*10);
        }

        //各セーブエントリボタン処理(右クリック(ロード))
        function rEntryQSaveMenuClick(num)
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.loadBookmarkAutoMode(num+sf.saveload_page*10);
        }

        //ページDOWNボタン処理
        function downPageQSaveMenuClick()
        {
                if (checkTextDrawing()) return;//エラー回避

                if (sf.saveload_page == 10)
                        sf.saveload_page = 0;
                else
                        sf.saveload_page++;
                kag.redrawQSaveMenu();
                //showQSaveMenu(0);
        }

        //----簡易メニュー(左:設定)---------------------------------------------------------

        //簡易メニュー(左:設定)を作成
        function makeQConfigMenu(backmode)
        {
                var destlayer;

                if (backmode == 'back')
                        destlayer = back.messages[qmenuLayer_Config];
                else
                        destlayer = fore.messages[qmenuLayer_Config];

                destlayer.face = dfBoth;

                var tmplayer = new Layer(this, destlayer);
                tmplayer.loadImages("qmenu_config_base");
                destlayer.copyRect(0, 0, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                invalidate tmplayer;

                if (fullScreened)//フルスクリーンの場合
                {
                        //全画面ボタン
                        var tmplayer = new Layer(this, destlayer);
                        tmplayer.loadImages("qmenu_config01on");
                        destlayer.copyRect(17, 79, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                        invalidate tmplayer;

                        //ウィンドウボタン

                        if (qmenuConfig_WindowButton === void)
                        {
                                var qconfElm = %[];

                                qconfElm.graphic = "qmenu_config02";
                                qconfElm.hint = '';
                                qconfElm.visible = true;
                                qconfElm.onenter = "kag.makeQMenuHint(110,101,'   窓表示にします。','qmenu_hint_base02')";
                                qconfElm.onleave = "kag.hideQMenuHint()";
                                qconfElm.exp = "kag.hideQMenuHint(),kag.windowQConfigMenuClick()";
                                qconfElm.rc = "";
                                //qconfElm.enterse ='';
                                //qconfElm.entersebuf = '';
                                //qconfElm.leavese = '';
                                //qconfElm.leavesebuf = '';

                                qmenuConfig_WindowButton = new LinkButtonLayer(this, destlayer);
                                qmenuConfig_WindowButton.showFocusImage = false;

                                destlayer.locate(17,104);
                                destlayer.addButton(qconfElm);
                        }
                }
                else//ウィンドウモードの場合
                {
                        //全画面ボタン
                        if (qmenuConfig_FullScrButton === void)
                        {
                                var qconfElm = %[];

                                qconfElm.graphic = "qmenu_config01";
                                qconfElm.hint = '';
                                qconfElm.visible = true;
                                qconfElm.onenter = "kag.makeQMenuHint(110,75,'   全画面表示にします。','qmenu_hint_base02')";
                                qconfElm.onleave = "kag.hideQMenuHint()";
                                qconfElm.exp = "kag.hideQMenuHint(),kag.fullScrQConfigMenuClick()";
                                qconfElm.rc = "";
                                //qconfElm.enterse ='';
                                //qconfElm.entersebuf = '';
                                //qconfElm.leavese = '';
                                //qconfElm.leavesebuf = '';

                                qmenuConfig_FullScrButton = new LinkButtonLayer(this, destlayer);
                                qmenuConfig_FullScrButton.showFocusImage = false;

                                destlayer.locate(17,79);
                                destlayer.addButton(qconfElm);
                        }

                        //ウィンドウボタン
                        var tmplayer = new Layer(this, destlayer);
                        tmplayer.loadImages("qmenu_config02on");
                        destlayer.copyRect(17, 104, tmplayer, 0, 0, tmplayer.imageWidth, tmplayer.imageHeight);
                        invalidate tmplayer;
                }

                if (sf.readtxt_fast)//既読文章瞬間表示オンの場合
                {
                        //無ボタン
                        if (qmenuConfig_2ndReadButton === void)
                        {
                                var qconfElm = %[];

                                qconfElm.graphic = "qmenu_config03on";
                                qconfElm.hint = '';
                                qconfElm.visible = true;
                                qconfElm.onenter = "kag.makeQMenuHint(110,283,' 既読文章を通常速度にします。','qmenu_hint_base02')";
                                qconfElm.onleave = "kag.hideQMenuHint()";
                                qconfElm.exp = "kag.hideQMenuHint(),kag.readtxtOffQConfigMenuClick()";
                                qconfElm.rc = "";
                                //qconfElm.enterse ='';
                                //qconfElm.entersebuf = '';
                                //qconfElm.leavese = '';
                                //qconfElm.leavesebuf = '';

                                qmenuConfig_2ndReadButton = new LinkButtonLayer(this, destlayer);
                                qmenuConfig_2ndReadButton.showFocusImage = false;

                                destlayer.locate(40,283);
                                destlayer.addButton(qconfElm);
                        }
                }
                else//既読文章瞬間表示オフの場合
                {
                        //有ボタン
                        if (qmenuConfig_2ndReadButton === void)
                        {
                                var qconfElm = %[];

                                qconfElm.graphic = "qmenu_config03";
                                qconfElm.hint = '';
                                qconfElm.visible = true;
                                qconfElm.onenter = "kag.makeQMenuHint(110,283,' 既読文章を瞬間表示にします。','qmenu_hint_base02')";
                                qconfElm.onleave = "kag.hideQMenuHint()";
                                qconfElm.exp = "kag.hideQMenuHint(),kag.readtxtOnQConfigMenuClick()";
                                qconfElm.rc = "";
                                //qconfElm.enterse ='';
                                //qconfElm.entersebuf = '';
                                //qconfElm.leavese = '';
                                //qconfElm.leavesebuf = '';

                                qmenuConfig_2ndReadButton = new LinkButtonLayer(this, destlayer);
                                qmenuConfig_2ndReadButton.showFocusImage = false;

                                destlayer.locate(40,283);
                                destlayer.addButton(qconfElm);
                        }
                }
        }

        //簡易メニュー(左:設定)を消去
        function deleteQConfigMenu()
        {
                if(qmenuConfig_FullScrButton !== void)
                {
                        invalidate qmenuConfig_FullScrButton;
                        qmenuConfig_FullScrButton = void;
                }
                if(qmenuConfig_WindowButton !== void)
                {
                        invalidate qmenuConfig_WindowButton;
                        qmenuConfig_WindowButton = void;
                }
                if(qmenuConfig_2ndReadButton !== void)
                {
                        invalidate qmenuConfig_2ndReadButton;
                        qmenuConfig_2ndReadButton = void;
                }
                fore.messages[qmenuLayer_Config].clear();
        }

        //簡易メニュー(左:設定)を表示
        function showQConfigMenu(mvmode,backmode)
        {
                var destlayer;

                if(skipMode && sf.qmenu_config_mode != 2) return;

                if (backmode == "back")
                        destlayer = back.messages[qmenuLayer_Config];
                else
                        destlayer = fore.messages[qmenuLayer_Config];

                if (!movemode_qconf)
                {
                        if (destlayer.visible == false)
                        {
                                makeQConfigMenu();
                        }

                        if (mvmode == "scroll")  //"scroll"なら移動表示
                        {
                                destlayer.visible = true;
                                movemode_qconf = 1;
                                timermove_qconf.enabled = true;
                        }
                        else        //"nowait"なら瞬間表示
                        {
                                destlayer.visible = true;
                                destlayer.left = 0;

                                //スライダー表示
                                var sliderelm = %[];
                                sliderelm.forevisible = true;
                                sliderelm.page = "qmenu";
                                slider_object.setOptions(sliderelm);

                        }
                }

        }

        //簡易メニュー(左:設定)を隠す
        function hideQConfigMenu(mvmode)
        {
                if (!movemode_qconf)
                {
                        //スライダー消去
                        var sliderelm = %[];
                        sliderelm.forevisible = false;
                        //sliderelm.backvisible = false;
                        slider_object.setOptions(sliderelm);

                        if (mvmode == "scroll")  //"scroll"なら移動表示
                        {
                                if (f.qmenu_enabled && fore.messages[qmenuLayer_Config].visible == true)
                                        //fore.messages[qmenuLayer_Config].visible = false;
                                        movemode_qconf = 2;
                                        timermove_qconf.enabled = true;
                        }
                        else        //"nowait"なら瞬間表示
                        {
                                fore.messages[qmenuLayer_Config].visible = false;
                                fore.messages[qmenuLayer_Config].left = -sf.qmenu_config_movepixel;
                                deleteQConfigMenu();
                        }
                }
        }

        //簡易メニュー(左:設定)の表示用タイマ
        function onTimerMoveQConfig() {
                var movespeed = sf.qmenu_config_movespeed;//動く速度
                switch (movemode_qconf) {
                        case 0://ストップ
                                timermove_qconf.enabled = false;
                                break;
                        case 1://表示
                                if (fore.messages[qmenuLayer_Config].left < 0) {
                                        fore.messages[qmenuLayer_Config].left += movespeed;
                                } else {
                                        //スライダー表示
                                        var sliderelm = %[];
                                        sliderelm.forevisible = true;
                                        sliderelm.page = "qmenu";
                                        slider_object.setOptions(sliderelm);

                                        timermove_qconf.enabled = false;
                                        movemode_qconf = 0;
                                }
                                break;
                        case 2://消去
                                if (fore.messages[qmenuLayer_Config].left > -sf.qmenu_config_movepixel) {
                                        fore.messages[qmenuLayer_Config].left -= movespeed;
                                } else {
                                        timermove_qconf.enabled = false;
                                        movemode_qconf = 0;
                                        fore.messages[qmenuLayer_Config].visible = false;
                                        deleteQConfigMenu();
                                }
                                break;
                }
        }

        function fullScrQConfigMenuClick()//フルスクリーンボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                kag.onFullScreenMenuItemClick();
                deleteQConfigMenu();
                makeQConfigMenu();
        }

        function windowQConfigMenuClick()//窓モードボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                kag.onWindowedMenuItemClick();
                deleteQConfigMenu();
                makeQConfigMenu();
        }

        function readtxtOnQConfigMenuClick()//既読瞬間表示オンボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                sf.readtxt_fast = true;
                kag.userCh2ndSpeed = 0;
                setUserSpeed();
                deleteQConfigMenu();
                makeQConfigMenu();
        }

        function readtxtOffQConfigMenuClick()//既読瞬間表示オフボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                sf.readtxt_fast = false;
                kag.userCh2ndSpeed = -1;
                setUserSpeed();
                deleteQConfigMenu();
                makeQConfigMenu();
        }

        //----簡易メニュー(上:システム)---------------------------------------------------------

        //簡易メニュー(上:システム)を作成
        function makeQSystemMenu(backmode)
        {
                var destlayer;

                if (backmode == 'back')
                        destlayer = back.messages[qmenuLayer_System];
                else
                        destlayer = fore.messages[qmenuLayer_System];

                destlayer.face = dfBoth;

                //最初に戻るボタン
                if (qmenuSystem_ReturnTopButton === void)
                {
                        var qsysElm = %[];

                        qsysElm.graphic = "qmenu_sys_menu01";
                        qsysElm.hint = '';
                        qsysElm.visible = true;
                        qsysElm.onenter = "kag.makeQMenuHint(500,32,'   最初に戻ります。','qmenu_hint_base02')";
                        qsysElm.onleave = "kag.hideQMenuHint()";
                        qsysElm.exp = "kag.hideQMenuHint(),kag.returnTopQSystemMenuClick()";
                        qsysElm.rc = "";
                        //qsysElm.enterse ='';
                        //qsysElm.entersebuf = '';
                        //qsysElm.leavese = '';
                        //qsysElm.leavesebuf = '';

                        qmenuSystem_ReturnTopButton = new LinkButtonLayer(this, destlayer);
                        qmenuSystem_ReturnTopButton.showFocusImage = false;

                        destlayer.locate(590,0);
                        destlayer.addButton(qsysElm);
                }

                //終了ボタン
                if (qmenuSystem_ExitButton === void)
                {
                        var qsysElm = %[];

                        qsysElm.graphic = "qmenu_sys_menu02";
                        qsysElm.hint = '';
                        qsysElm.visible = true;
                        qsysElm.onenter = "kag.makeQMenuHint(550,32,'    終了します。','qmenu_hint_base02')";
                        qsysElm.onleave = "kag.hideQMenuHint()";
                        qsysElm.exp = "kag.hideQMenuHint(),kag.exitQSystemMenuClick()";
                        qsysElm.rc = "";
                        //qsysElm.enterse ='';
                        //qsysElm.entersebuf = '';
                        //qsysElm.leavese = '';
                        //qsysElm.leavesebuf = '';

                        qmenuSystem_ExitButton = new LinkButtonLayer(this, destlayer);
                        qmenuSystem_ExitButton.showFocusImage = false;

                        destlayer.locate(640,0);
                        destlayer.addButton(qsysElm);
                }
        }

        //簡易メニュー(上:システム)を表示
        function showQSystemMenu(mvmode,backmode)
        {
                var destlayer;

                if(skipMode && sf.qmenu_system_mode != 2) return;

                if (backmode == "back")
                        destlayer = back.messages[qmenuLayer_System];
                else
                        destlayer = fore.messages[qmenuLayer_System];

                if (!movemode_qsys)
                {
                        if (destlayer.visible == false)
                                makeQSystemMenu();

                        if (mvmode == "scroll")  //"scroll"なら移動表示
                        {
                                destlayer.visible = true;
                                movemode_qsys = 1;
                                timermove_qsys.enabled = true;
                        }
                        else        //"nowait"なら瞬間表示
                        {
                                destlayer.visible = true;
                                destlayer.top = 0;
                        }
                }

        }

        //簡易メニュー(上:システム)の消去
        function hideQSystemMenu(mvmode)
        {
                if (!movemode_qsys)
                {
                        if (mvmode == "scroll")  //"scroll"なら移動表示
                        {
                                if (f.qmenu_enabled && fore.messages[qmenuLayer_System].visible == true)
                                        //kag.fore.messages[qmenuLayer_System].visible = true;
                                        movemode_qsys = 2;
                                        timermove_qsys.enabled = true;
                        }
                        else        //"nowait"なら瞬間表示
                        {
                                fore.messages[qmenuLayer_System].top = -sf.qmenu_system_movepixel;
                                fore.messages[qmenuLayer_System].visible = false;
                                deleteQSystemMenu();
                        }
                }
        }

        //簡易メニュー(上:システム)を消去
        function deleteQSystemMenu()
        {
                if(qmenuSystem_ReturnTopButton !== void)
                {
                        invalidate qmenuSystem_ReturnTopButton;
                        qmenuSystem_ReturnTopButton = void;
                }
                if(qmenuSystem_ExitButton !== void)
                {
                        invalidate qmenuSystem_ExitButton;
                        qmenuSystem_ExitButton = void;
                }
                fore.messages[qmenuLayer_System].clear();
        }

        //簡易メニュー(上:システム)の表示用タイマ
        function onTimerMoveQSystem() {
                var movespeed = sf.qmenu_system_movespeed;//動く速度
                switch (movemode_qsys) {
                        case 0://ストップ
                                timermove_qsys.enabled = false;
                                break;
                        case 1://表示
                                if (fore.messages[qmenuLayer_System].top < 0) {
                                        fore.messages[qmenuLayer_System].top += movespeed;
                                } else {
                                        timermove_qsys.enabled = false;
                                        movemode_qsys = 0;
                                }
                                break;
                        case 2://消去
                                if (fore.messages[qmenuLayer_System].top > -sf.qmenu_system_movepixel) {
                                        fore.messages[qmenuLayer_System].top -= movespeed;
                                } else {
                                        timermove_qsys.enabled = false;
                                        movemode_qsys = 0;
                                        kag.fore.messages[qmenuLayer_System].visible = false;
                                        deleteQSystemMenu();
                                }
                                break;
                }
        }

        function returnTopQSystemMenuClick()//最初に戻るボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                kag.callExtraConductor('qmenu.ks','*returntop');
        }

        function exitQSystemMenuClick()//終了ボタン処理
        {
                if (checkTextDrawing()) return;//エラー回避
                kag.hideQMenuHint();
                kag.callExtraConductor('qmenu.ks','*exit_game');
        }

        //----オートセーブ用---------------------------------------------------------
        //オートセーブ対応セーブコマンド
        function saveBookmarkAutoMode(num)
        {
                var result;
                if(sf.save_ask)//確認をする場合
                        if (sf.saveload_page == 10)
                        {
                                var autonum = (sf.autosave_entry-num+100);
                                if (autonum<=0) autonum+=10;
                                result = kag.saveBookMarkWithAsk(num,true,"自動"+autonum);
                        }
                        else
                                result = kag.saveBookMarkWithAsk(num);
                else//確認をしない場合
                        if (sf.saveload_page == 10)
                                result = kag.saveBookMark(num,true,"自動"+(sf.autosave_entry-num));
                        else
                                result = kag.saveBookMark(num);

                if (result)
                {
                        sf.new_savedata = num;

                        if(sf.qmenu_save_mode) kag.redrawQSaveMenu();
                }

                return result;
        }

        //オートセーブ対応ロードコマンド
        function loadBookmarkAutoMode(num)
        {
                var result;
                if(sf.save_ask)//確認をする場合
                        if (sf.saveload_page == 10)
                        {
                                var autonum = (sf.autosave_entry-num+100);
                                if (autonum<=0) autonum+=10;
                                result = kag.loadBookMarkWithAsk(num,true,"自動"+autonum);
                        }
                        else
                                result = kag.loadBookMarkWithAsk(num);
                else//確認をしない場合
                        if (sf.saveload_page == 10)
                                result = kag.loadBookMark(num,true,"自動"+(sf.autosave_entry-num));
                        else
                                result = kag.loadBookMark(num);

                return result;
        }
//↑--------------------------------------- ここまで追加部分--

}



// TJS スクリプトはここで終わり
 

MessageLayer.tjs

右クリック対応のボタンを定義しておきます。
MessageLayer.tjsのclass LinkButtonLayerにあるfunction onMouseUp()の中に、以下の命令を追加します。
        function onMouseUp(x, y, button, shift)
        {
                if(enabled && button == mbLeft && !parent.selProcessLock) parent.onButtonClick(linkNum);
//↓--------------------------------------- ここから追加部分--
                else if(enabled && button == mbRight && !parent.selProcessLock) parent.onRightButtonClick(linkNum);  // mebius:右クリック
//↑--------------------------------------- ここまで追加部分--
                if(this isvalid) super.onMouseUp(...);
        }
function addButton(elm)の中に、以下の命令を追加します。
一行ほど修正する行があるので、注意して下さい。
        function addButton(elm)
        {
                // グラフィカルボタンを配置
                // (中略)

                links[numLinks] = %[
                        type :                  ltButton,
                        graphic :               elm.graphic,
                        graphickey :    elm.graphickey,
                        storage :               elm.storage,
                        target :                elm.target,
                        exp :                   createSoundExpression(elm.exp, elm.clickse, elm.clicksebuf),
                        countPage :             (elm.countpage === void) ? true : +elm.countpage,
                        object :                object,
                        onenter :               object.onenter,
                        onleave :               object.onleave,
                        x :                             [x],
                        y :                             [y],
                        w :                             [object.width],
                        h :                             [object.height],
                        fixed :                 [true],
//↓--------------------------------------- ここから追加部分--
                        lineCount :             1,              // mebius:最後にコンマを追加
                        rc:                     elm.rc          // mebius:右クリック用の処理
//↑--------------------------------------- ここまで追加部分--
                        ];

                numLinks++;
                focusable = true; // フォーカスを受け取れるように
                setSelProcessLock(false); // 選択ロック解除
        }
右クリック対応のプロセスを定義します。
function processLink(n)の後に、以下の命令を追加します。
        function processLink(n)
        {
                // リンク番号 n を処理する
                var ln = links[n];
                if(ln === void) return;

                // 裏画面のハイライトを非表示
                if(comp !== void) comp.highlightLayer.visible = false;

                // 実行
                Scripts.eval(ln.exp) if ln.exp != '';

                if(ln.storage != '' || ln.target != '')
                {
                        window.lockMessageLayerSelProcess(); // 選択をロック
                        if(window.getKeyState(VK_RETURN) || window.getKeyState(VK_SPACE))
                                window.hideMouseCursor();
                                        // キーボードによる操作の場合はマウスカーソルを隠す
                        window.process(ln.storage, ln.target, ln.countPage);
                }
        }

//↓--------------------------------------- ここから追加部分--
        //mebius:右クリック処理用
        function processLink2(n)
        {
                // リンク番号 n を処理する
                var ln = links[n];
                if(ln === void) return;

                // 裏画面のハイライトを非表示  ※これ必要ないかも...?
                if(comp !== void) comp.highlightLayer.visible = false;

                // 右クリック用の処理を実行
                Scripts.eval(ln.rc) if ln.rc != '';
        }

        function onRightButtonClick(num)
        {
                // 番号 num のグラフィカルボタンが右クリックされた
                processLink2(num);
        }
//↑--------------------------------------- ここまで追加部分--
キーボード対応させます。左クリックはリターンで、右クリックはスペースに割り当てています。
もし他のキーに割り当てたい場合、key == VK_SPACEの部分を他のキーに修正して下さい。
function onKeyDown(key, shift)の中に、以下の命令を追加します。
        function onKeyDown(key, shift)
        {
                // キーが押された
                if(window.preProcessKeys(key, shift)) return;

                if(!focusable || !numLinks) { return super.onKeyDown(...); }

                // (中略)

                else if(!selProcessLock && (key == VK_DOWN || key == r || (key == VK_TAB && !(shift & ssShift))))
                {
                        selClickLock = false;
                        if(keyLink == -1 || keyLink == numLinks -1)
                        {
                                var l = focusNext();
                                if(l !== null) return;
                                keyLink = 0;
                        }
                        else
                        {
                                keyLink ++;
                        }
                        var obj = setFocusToLink(keyLink);
                        if(obj !== void) obj.focus();
                }
                else if(key == VK_SPACE || key == VK_RETURN)
                {
                        if(selProcessLock || keyLink == -1)
                                window.checkProceedingKey(key, shift);
//↓--------------------------------------- ここから追加部分--
                        else//mebius:右クリックはスペースで代用。
                        {
                                if (key == VK_SPACE && links[keyLink].rc !='')
                                        processLink2(keyLink);
                                else
                                        processLink(keyLink);
                        }
                        //else//ここは消去
                        //      processLink(keyLink);
//↑--------------------------------------- ここまで追加部分--
                }
                else
                {
                        window.processKeys(key, shift); // window に処理をまかせる
                }
        }
 

スライダー関係

簡易メニュー(左:設定)ではスライダーを用いています。
スライダーを用いずにボタンのみで実現する場合、この項目は不要です。

ここでは、らんかさん作の「スライダー機能実装プラグイン(+画像タブ+トランジション対応)」を利用しています。もし別のスライダープラグインを使っている場合、スライダーの該当箇所を修正して下さい。
どの場所を修正したのかは、DF辺りの比較用ツールを使って比較すると分かりやすいかと思います。

実際は、サンプル内にあるSliderLayer2.tjsとslider.ksのファイルをご利用下さい。
元のファイルとの差分は、ファイル中にコメントで記されています。必要であれば文字列”mebius”で検索して、該当修正箇所をチェックして下さい。

SliderLayer2.tjsの内容は以下の通りです。
/* ---
 スライダーレイヤ
 SliderLayer.tjs 改造 : つまみに画像を使うバージョン

 ※つまみに読み込む画像の縦幅はスライダーの縦幅に合わせてください。
   横幅については 10 がデフォルトです。
   変更したい場合は Slider_tabWidth の数値を書き換えてください。
   画像は以下の二種類が要ります(グラフィカルボタンではないので注意)
     tab1 ... 通常の状態
     tab2 ... スライダーにマウスカーソルが乗っている状態
   画像ファイル名を変更したいときは setSliderTab メソッド内の該当
   部分を書き換えればOKです。

 2004/04/27 - Ranka
--- */
/* --
  2008/07/07 CircleMebius修正版
-- */

class SliderLayer extends Layer
{
        var Slider_min = 0; // 最小値
        var Slider_max = 0; // 最大値
        var Slider_position = 0; // 位置
        var Slider_tabWidth = 10; // つまみサイズ
        var Slider_dragging = false; // ドラッグ中かどうか
        var Slider_dragOriginX; // ドラッグ開始 X 位置
        var Slider_mouseOn = false; // マウスが領域内にあるかどうか

        var SliderTab; // つまみ用オブジェクト

        function SliderLayer(win, par)
        {
                super.Layer(win, par);

                focusable = true; // フォーカスを得られる

                hitType = htMask;
                hitThreshold = 0;
        }

        function finalize()
        {
                invalidate SliderTab if SliderTab !== void;
                super.finalize(...);
        }

        function assign(src)
        {
                // src の情報をこのオブジェクトにコピー
                Slider_min = src.Slider_min;
                Slider_max = src.Slider_max;
                Slider_position = src.Slider_position;
        }

        function setSliderTab(x)
        {
                // スライダーレイヤ上にマウスカーソルがあるかないかで
                // 表示させる画像を変える
                //mebius:タブのファイル名修正
                if(Slider_mouseOn || focused)//←この行も修正しています。
                        SliderTab.loadImages('slider_tab02'); // カーソルが乗っている
                else
                        SliderTab.loadImages('slider_tab01'); // カーソルが乗っていない


                // 画像の表示位置をセット
                SliderTab.left = x;
        }

        function onPaint()
        {
                // onPaint イベント
                // レイヤの内容を描画する
                super.onPaint(...);

                // よく使う値をローカル変数に用意する
                var imw = imageWidth, imh = imageHeight;
                var tabw = Slider_tabWidth;
                var htabw = tabw >> 1;

                // 下敷きを塗る
                fillRect(0, 0, imw, imh, 0);

                //mebius:コメントアウト
                /*
                if(focused)
                {
                        // フォーカスがあるのでハイライトする
                        colorRect(0, 0, width-1, 1, clHighlight, 128);
                        colorRect(0, 1, 1, height-2, clHighlight, 128);
                        colorRect(0, height-1, width, 1, clHighlight, 128);
                        colorRect(width-1, 0, 1, height-1, clHighlight, 128);
                }

                // 中央のへこみ線
                {
                        var himh = imh >> 1;
                        var right = imw - tabw;
                        fillRect(htabw, himh - 1, right, 1, 0x80000000);
                        fillRect(htabw, himh    , right, 1, 0x80ffffff);
                }
                */


                // タブ
                var pos_x = int(
                        (Slider_position-Slider_min) * (imw - tabw - 2) /
                        (Slider_max - Slider_min)) + htabw + 1;
                var x_htabw = pos_x - htabw + this.left;

                if(SliderTab === void)
                {
                        SliderTab = new global.Layer(window, parent);
                        SliderTab.face = dfBoth;

                        // 表示する画像と位置をセット
                        setSliderTab(x_htabw);
                        SliderTab.top = this.top;
                        SliderTab.setSizeToImageSize();

                        SliderTab.hitType = htMask;
                        SliderTab.hitThreshold = 256; // 全域透過

                        SliderTab.visible = true; // 表示
                }
                else
                {
                        // 表示する画像と位置をセット
                        setSliderTab(x_htabw);
                }
        }

        function onKeyDown(key, shift, process)
        {
                // キーが押された
                if(process)
                {
                        if(key == VK_LEFT)
                        {
                                // 左
                                if(shift & ssAlt)
                                        position = Slider_position - 1;
                                else
                                        position = Slider_position - int((Slider_max - Slider_min)/ (Slider_tabWidth-2) / 2);
                                super.onKeyDown(key, shift, false); // 処理をしたのでprocessにfalseを渡す
                        }
                        else if(key == VK_RIGHT)
                        {
                                // 左
                                if(shift & ssAlt)
                                        position = Slider_position + 1;
                                else
                                        position = Slider_position + int((Slider_max - Slider_min)/ (Slider_tabWidth-2) / 2);
                                super.onKeyDown(key, shift, false); // 処理をしたのでprocessにfalseを渡す
                        }
                        else
                        {
                                super.onKeyDown(...);
                        }
                }
                else
                {
                        // process が false の場合は処理は行わない
                        super.onKeyDown(...);
                }
        }

        function onMouseDown(x, y, button)
        {
                // マウスボタンが押された
                focus();

                super.onMouseDown(...);

                var tabw = Slider_tabWidth;
                var htabw = tabw >> 1;
                var pos_x = int(
                        (Slider_position-Slider_min) * (imageWidth - tabw - 2)/(Slider_max - Slider_min)) +
                        htabw + 1;
                if(pos_x - htabw > x)
                {
                        // タブより左
                        position = Slider_position - int((Slider_max - Slider_min)/ (tabw-2));
                }
                else if(pos_x + htabw < x)
                {
                        // タブより右
                        position = Slider_position + int((Slider_max - Slider_min)/ (tabw-2));
                }
                else
                {
                        // タブ
                        // タブのドラッグを開始
                        Slider_dragging = true;
                        Slider_dragOriginX = x - pos_x;
                }
        }

        function onMouseUp(x, y, button)
        {
                // マウスボタンが離された
                super.onMouseUp(...);

                Slider_dragging = false;
        }

        function onMouseMove(x, y)
        {
                // マウスが移動した
                super.onMouseMove(...);

                if(Slider_dragging)
                {
                        // タブをドラッグ
                        position = int(
                                (x - Slider_dragOriginX - (Slider_tabWidth >> 1)) * (Slider_max - Slider_min) /
                                (imageWidth - Slider_tabWidth - 2) + Slider_min);
                }
        }

        function onMouseEnter()
        {
                // マウスがレイヤ領域内に入った
                update();
                Slider_mouseOn = true;
                super.onMouseEnter(...);
        }

        function onMouseLeave()
        {
                // マウスがレイヤ領域から出ていった
                update();
                Slider_mouseOn = false;
                Slider_dragging = false;
                super.onMouseLeave(...);
        }

        function onFocus()
        {
                // フォーカスを得た
                super.onFocus(...);
                update();
        }

        function onBlur()
        {
                // フォーカスを失った
                super.onBlur(...);
                update();
        }

        function onNodeDisabled()
        {
                // レイヤのノードが不可になった
                super.onNodeDisabled(...);
                update();
        }

        function onNodeEnabled()
        {
                // レイヤのノードが有効になった
                super.onNodeEnabled(...);
                update();
        }


        property width
        {
                setter(x)
                {
                        super.width = x;
                        imageWidth = x;
                        update();
                }
                getter
                {
                        return super.width;
                }
        }
        
        property height
        {
                setter(x)
                {
                        super.height = x;
                        imageHeight = x;
                        update();
                }
                getter
                {
                        return super.height;
                }
        }
        
        property max
        {
                setter(x)
                {
                        Slider_max = x;
                        update();
                }
                getter
                {
                        return Slider_max;
                }
        }
        
        property min
        {
                setter(x)
                {
                        Slider_min = x;
                        update();
                }
                getter
                {
                        return Slider_min;
                }
        }
        
        property position
        {
                setter(x)
                {
                        if(x < Slider_min) x = Slider_min;
                        if(x > Slider_max) x = Slider_max;
                        Slider_position = x;
                        update();
                        onChange(Slider_position);
                }
                getter
                {
                        return Slider_position;
                }
        }

        function onChange(pos)
        {
                // onChange
                window.action(%[target:this, type:'onChange', position:pos]);
        }
}
slider.ksの内容は以下の通りです。
@if exp="typeof(global.slider_object) == 'undefined'"
@iscript

// スライダー機能実装プラグイン
// transviewer 改造 : TJS 版
//                  +画像タブ
//                  +トランジション対応
/* --
  2008/07/07 CircleMebius修正版
-- */

Scripts.execStorage("SliderLayer2.tjs");

class LSliderLayer extends SliderLayer
{
        function LSliderLayer()
        {
                super.SliderLayer(...);
        }

        function finalize()
        {
                super.finalize(...);
        }

        function onChange(pos)
        {
                // 親 ( ContolLayer ) にもイベントを通知
                parent.sliderLayerChange(this, pos);
        }
}

class ControlLayer extends Layer // コントロールレイヤクラス
{
        var Sliders = []; // スライダーオブジェクト
        var PosText = []; // 現在値の単位

        var owner; // SliderPlugin オブジェクトへの参照

        //mebius:修正
        var controlLeft   =  0;  // 左からの表示位置
        var controlTop    =  0;  // 上からの表示位置
        var controlWidth  =  800;  // 表示領域(横幅)
        var controlHeight =  600;  // 表示領域(縦幅)

        var bgColor = 0x00000000; // 背景色 ( 0xAARRGGBB )

        var changingByFunction = false;//ユーザーが値を直接変更した時にsliderLayerChange()を実行させないためのフラグ。
        var changingByLayerChange = false;//描画変更時にsliderLayerChange()を実行させないためのフラグ。

        // ▽ドラッグ可能にしたいときはコメントの行を消してね
        /* ---
        var dragOriginX;
        var dragOriginY;
        var dragging = false; // ドラッグ中かどうか
        --- */

        function ControlLayer(win, par, owner)
        {
                super.Layer(win, par);
                this.owner = owner;

                // コントロールレイヤを作成
                setPos(controlLeft, controlTop);
                setImageSize(controlWidth, controlHeight);
                setSizeToImageSize();
                fillRect(0, 0, width, height, bgColor);

                var obj;

                // 表示する文字の大きさ
                font.height = 14;

        //mebius:以下の部分は個別に。
        /* --- スライダー設定 0:文字速度(簡易メニュー) --- */
                //drawText(15, 50, "", 0xffffff, 255, true);
                obj = new LSliderLayer(window, this);
                Sliders[0] = obj;

                obj.left   =   15;  // 左からの表示位置
                obj.top    =  180;  // 上からの表示位置
                obj.width  =   75;  // 横幅
                obj.height =   20;  // 縦幅
                obj.min    =    0;  // 最小値
                obj.max    =  f.txtspeed_max;  // 最大値
                PosText[0] = "%";

                obj.position = f.txtspeed_max-sf.txt_vol;//ポジション
                //↑ここのポジションは、kag.userChSpeedからではなく、システム変数で保持している速度の値を代入しています。
                // 以下のポジションでも同様。各自環境に合うように修正して下さい。

                obj.visible = false;
                obj.cursor  = crArrow;

        /* --- スライダー設定 1:自動的に読み進める速度(簡易メニュー) --- */
                //drawText(15, 50, "", 0xffffff, 255, true);
                obj = new LSliderLayer(window, this);
                Sliders[1] = obj;

                obj.left   =   15;  // 左からの表示位置
                obj.top    =  359;  // 上からの表示位置
                obj.width  =   75;  // 横幅
                obj.height =   20;  // 縦幅
                obj.min    =    0;  // 最小値
                obj.max    = f.autoreadspeed_max;  // 最大値
                PosText[1] = "%";

                obj.position = f.autoreadspeed_max - sf.autoread_vol;//ポジション

                obj.visible = false;
                obj.cursor  = crArrow;

        /* --- スライダー設定 2:文字速度(設定画面用) --- */
                //drawText(15, 50, "", 0xffffff, 255, true);
                obj = new LSliderLayer(window, this);
                Sliders[2] = obj;

                obj.left   =  619;  // 左からの表示位置
                obj.top    =  118;  // 上からの表示位置
                obj.width  =  110;  // 横幅
                obj.height =   20;  // 縦幅
                obj.min    =    0;  // 最小値
                obj.max    =  f.txtspeed_max;  // 最大値
                PosText[2] = "%";

                obj.position = f.txtspeed_max-sf.txt_vol;

                obj.visible = false;
                obj.cursor  = crArrow;

        /* --- スライダー設定 3:自動的に読み進める速度(設定画面用) --- */
                //drawText(15, 50, "", 0xffffff, 255, true);
                obj = new LSliderLayer(window, this);
                Sliders[3] = obj;

                obj.left   =  619;  // 左からの表示位置
                obj.top    =  197;  // 上からの表示位置
                obj.width  =  110;  // 横幅
                obj.height =   20;  // 縦幅
                obj.min    =    0;  // 最小値
                obj.max    =  f.autoreadspeed_max;  // 最大値
                PosText[3] = "%";

                obj.position = f.autoreadspeed_max - sf.autoread_vol;

                obj.visible = false;
                obj.cursor  = crArrow;
        }

        function finalize()
        {
                super.finalize(...);
        }

        function sliderLayerChange(obj, pos)
        {
                // スライダーの位置が変更されたとき
                for (var i = 0; i < Sliders.count; i++)
                {
                        if((obj == Sliders[i]) && !changingByFunction)//mebius:ユーザーからの変更時は実行しない
                        {
                                // 現在の選択数値と単位をスライダーの右に表示
                                /*
                                var lf  = obj.left + obj.width;
                                var wh  = width - lf - 5;
                                var txt = pos + PosText[i];
                                fillRect(lf, obj.top, wh, obj.height, bgColor);
                                drawText(lf + 5, obj.top, txt, 0, 255, true);
                                */

                                // 現在の選択数値を一時変数に入れる
                                tf.SliderPosition[i] = pos;

                                // スライダー変更時のアクションがあれば呼ぶ
                                // mebius:設定画面のスライダーはここで処理してOKですが、
                                // 簡易メニュー部分はここでは処理させない方がいいです。(ファイル名が特定できないので)
                                if (owner.setting && tf.sliders[i] != '')
                                        kag.callExtraConductor('', tf.sliders[i]);

                                //mebius:ここでスライダー変更時の処理を記述します。
                                if (!changingByLayerChange)//レイヤー描画時には処理させない判定
                                {
                                        switch (i){
                                                case 0: sf.txt_vol = f.txtspeed_max-tf.SliderPosition[i];
                                                        kag.userChSpeed=sf.txt_vol;
                                                        if (!sf.readtxt_fast) kag.userCh2ndSpeed=-1;//既読文字速度のスライダーを使わない場合
                                                        kag.setUserSpeed();
                                                        break;
                                                case 1: sf.autoread_vol = f.autoreadspeed_max-tf.SliderPosition[i];
                                                        kag.autoModePageWait=sf.autoread_vol+f.autoreadspeed_min;//改ページウェイト
                                                        //kag.autoModeLineWait=(sf.autoread_vol+f.autoreadspeed_min)\4;//行クリック待ちウェイト
                                                        //autoModeLineWait
                                                        //kag.setUserSpeed();
                                                        break;
                                                case 2: sf.txt_vol = f.txtspeed_max-tf.SliderPosition[i];
                                                        kag.userChSpeed=sf.txt_vol;
                                                        if (!sf.readtxt_fast) kag.userCh2ndSpeed=-1;//既読文字速度のスライダーを使わない場合
                                                        kag.setUserSpeed();
                                                        break;
                                                case 3: sf.autoread_vol = f.autoreadspeed_max-tf.SliderPosition[i];
                                                        kag.autoModePageWait=sf.autoread_vol+f.autoreadspeed_min;//改ページウェイト
                                                        //kag.autoModeLineWait=(sf.autoread_vol+f.autoreadspeed_min)\4;//行クリック待ちウェイト
                                                        //kag.setUserSpeed();
                                                        break;
                                        }
                                }

                                break;
                        }
                }
        }

        // ▽ドラッグ可能にしたいときはコメントの行を消してね
        /* ---
        function onMouseMove(x, y)
        {
                // マウスが移動した
                if(dragging)
                {
                        var px = parent.cursorX;
                        var py = parent.cursorY;
                        var l = px - dragOriginX;
                        var t = py - dragOriginY;
                        setPos(l, t);
                }

                if(y < 10)
                        cursor = crSizeAll;
                else
                        cursor = crDefault;
        }

        function onMouseDown(x, y, button)
        {
                // マウスボタンが押された
                if(y < 10)
                {
                        dragging = true;
                        dragOriginX = x;
                        dragOriginY = y;
                }
        }

        function onMouseUp(x, y, button)
        {
                // マウスボタンが離された
                dragging = false;
        }

        function onMouseLeave()
        {
                // マウスがレイヤ領域から出ていった
                super.onMouseLeave(...);
        }
        --- */

        //mebius:キーボード処理対応。
        function onKeyDown(key, shift)
        {
                // キーが押された
                super.onKeyDown(...);
                
                if(key == VK_ESCAPE)
                {
                        if (f.config_showing)//コンフィグ画面なら
                        {
                                // 右クリック
                                kag.onPrimaryRightClick(); // クリックをエミュレート
                                return;
                        }
                        else    //簡易メニューなら
                        {
                                kag.processKeys(key, shift);
                                return;
                        }
                }

        }
}

class SliderPlugin extends KAGPlugin // スライダープラグインクラス
{
        var window; // ウィンドウへの参照

        var foreControlLayer; // 表画面のコントロールレイヤ
        var backControlLayer; // 裏画面のコントロールレイヤ

        var foreSeen = false; // 表画面のコントロールレイヤが可視か
        var backSeen = false; // 裏画面のコントロールレイヤが可視か

        var setting = false; // エラー回避(^^;

        function SliderPlugin(window)
        {
                super.KAGPlugin(); // スーパークラスのコンストラクタを呼ぶ
                this.window = window; // window への参照を保存する

                // コントロールレイヤを作成
                if(foreControlLayer === void)
                        foreControlLayer = new ControlLayer(window, kag.fore.base, this);
                if(backControlLayer === void)
                        backControlLayer = new ControlLayer(window, kag.back.base, this);

                setting = true;

                // 非表示に
                foreControlLayer.visible = foreSeen = false;
                backControlLayer.visible = backSeen = false;
        }

        function finalize()
        {
                // コントロールレイヤを破棄
                invalidate foreControlLayer if foreControlLayer !== void;
                invalidate backControlLayer if backControlLayer !== void;
                super.finalize(...);
        }

        function show()
        {
                // 親を再設定
                foreControlLayer.parent = window.fore.base;
                backControlLayer.parent = window.back.base;

                // コントロールレイヤを表示
                foreControlLayer.visible = foreSeen = true;
                backControlLayer.visible = backSeen = true;
        }

        function hide()
        {
                // コントロールレイヤを閉じる
                foreControlLayer.visible = foreSeen = false;
                backControlLayer.visible = backSeen = false;
        }

        function setOptions(elm)
        {
                //mebius:表示するスライダーの選択
                //ページごとに、どのスライダーを表示するのかをここで選択します。
                if (elm.page !== void)
                {
                        if (elm.page == "qmenu")//簡易メニューで表示の場合
                        {
                                for (var i=0;foreControlLayer.Sliders[i] !== void;i++)
                                {
                                        if (i==0 || i==1)//表示するスライダー番号(ここを個別に修正します)
                                        {
                                                foreControlLayer.Sliders[i].visible = true;
                                                backControlLayer.Sliders[i].visible = true;
                                                foreControlLayer.Sliders[i].SliderTab.visible = true;
                                                backControlLayer.Sliders[i].SliderTab.visible = true;
                                        }
                                        else
                                        {
                                                foreControlLayer.Sliders[i].visible = false;
                                                backControlLayer.Sliders[i].visible = false;
                                                foreControlLayer.Sliders[i].SliderTab.visible = false;
                                                backControlLayer.Sliders[i].SliderTab.visible = false;
                                        }
                                }
                        }
                        else if (elm.page == "config")//設定画面で表示の場合
                        {
                                for (var i=0;foreControlLayer.Sliders[i] !== void;i++)
                                {
                                        if (i==2 || i==3)//表示するスライダー番号(ここを個別に修正します)
                                        {
                                                foreControlLayer.Sliders[i].visible = true;
                                                backControlLayer.Sliders[i].visible = true;
                                                foreControlLayer.Sliders[i].SliderTab.visible = true;
                                                backControlLayer.Sliders[i].SliderTab.visible = true;
                                        }
                                        else
                                        {
                                                foreControlLayer.Sliders[i].visible = false;
                                                backControlLayer.Sliders[i].visible = false;
                                                foreControlLayer.Sliders[i].SliderTab.visible = false;
                                                backControlLayer.Sliders[i].SliderTab.visible = false;
                                        }
                                }
                        }
                        else//その他の場合
                        {
                                for (var i=0;foreControlLayer.Sliders[i] !== void;i++)
                                {
                                        foreControlLayer.Sliders[i].visible = false;
                                        backControlLayer.Sliders[i].visible = false;
                                        foreControlLayer.Sliders[i].SliderTab.visible = false;
                                        backControlLayer.Sliders[i].SliderTab.visible = false;
                                }
                        }
                }

                // オプションを設定
                if(elm.forevisible !== void)
                        foreControlLayer.visible = foreSeen = +elm.forevisible;
                if(elm.backvisible !== void)
                        backControlLayer.visible = backSeen = +elm.backvisible;
        }

        //mebius:スライダーの位置設定命令
        function setSliderPosition(elm)
        {
                if(elm.position !== void && elm.target !== void)
                {
                        foreControlLayer.changingByFunction = true;
                        foreControlLayer.Sliders[int(elm.target)].position=int(elm.position);
                        foreControlLayer.changingByFunction = false;

                        backControlLayer.changingByFunction = true;
                        backControlLayer.Sliders[int(elm.target)].position=int(elm.position);
                        backControlLayer.changingByFunction = false;
                }
        }

        // KAGPlugin のメソッドのオーバーライド

        function onStore(f, elm)
        {
                // 栞を保存するとき
                var dic = f.sliderControl = %[];
                dic.foreVisible = foreSeen;
                dic.backVisible = backSeen;    // 各情報を辞書配列に記録
        }

        function onRestore(f, clear, elm)
        {
                // 栞を読み出すとき
                var dic = f.sliderControl;
                if(dic === void)
                {
                        // sliderControl の情報が栞に保存されていない
                        foreControlLayer.visible = foreSeen = false;
                        backControlLayer.visible = backSeen = false;
                }
                else
                {
                        // sliderControl の情報が栞に保存されている
                        setOptions(%[
                                forevisible : dic.foreVisible,
                                backvisible : dic.backVisible    // オプションを設定
                        ]);
                }
        }

        function onStableStateChanged(stable)
        {
                // 「安定」( s l p の各タグで停止中 ) か、
                // 「走行中」 ( それ以外 ) かの状態が変わったときに呼ばれる

                // 走行中は無効にする
                // mebius: 常時変更可能に問題があれば、以下のコメントアウトを取り払って下さい。
                //foreControlLayer.enabled = stable;
                //backControlLayer.enabled = stable;
        }

        function onMessageHiddenStateChanged(hidden)
        {
                // メッセージレイヤがユーザの操作によって隠されるとき、
                // 現れるときに呼ばれる
                if(hidden)
                {
                        // メッセージレイヤと一緒に非表示にする
                        if (foreControlLayer !== void) hide();
                }
                else
                {
                        // 再表示する
                        if (foreControlLayer !== void) show();
                }
        }

        function onCopyLayer(toback)
        {
                // レイヤの表←→裏の情報のコピー
                // backlay タグやトランジションの終了時に呼ばれる

                if(toback)
                {
                        // 表→裏
                        var fore = foreControlLayer;
                        var back = backControlLayer;

                        back.visible = fore.visible;
                        backSeen = foreSeen;

                        setting = false;
                        for (var i = 0; i < back.Sliders.count; i++)
                        {
                                back.changingByLayerChange = true;//mebius:レイヤ変更によるフラグ立て
                                back.Sliders[i].position = fore.Sliders[i].position;
                                back.changingByLayerChange = false;
                        }
                        setting = true;
                }
                else
                {
                        // 裏→表
                        var fore = foreControlLayer;
                        var back = backControlLayer;

                        fore.visible = back.visible;
                        foreSeen = backSeen;

                        setting = false;
                        for (var i = 0; i < fore.Sliders.count; i++)
                        {
                                fore.changingByLayerChange = true;//mebius:レイヤ変更によるフラグ立て
                                fore.Sliders[i].position = back.Sliders[i].position;
                                fore.changingByLayerChange = false;
                        }
                        setting = true;
                }
        }

        function onExchangeForeBack()
        {
                // 裏と表の管理情報を交換

                // children = true のトランジションでは、トランジション終了時に
                // 表画面と裏画面のレイヤ構造がそっくり入れ替わるので、
                // それまで 表画面だと思っていたものが裏画面に、裏画面だと思って
                // いたものが表画面になってしまう。ここのタイミングでその情報を
                // 入れ替えれば、矛盾は生じないで済む。

                var tmp;

                tmp = backControlLayer;
                backControlLayer = foreControlLayer;
                foreControlLayer = tmp;

                tmp = backSeen;
                backSeen = foreSeen;
                foreSeen = tmp;
        }
}

tf.SliderPosition = [];  // スライダーの位置

kag.addPlugin(global.slider_object = new SliderPlugin(kag));
        // プラグインオブジェクトを作成し、登録する

@endscript
@endif
;
; コントロールレイヤの表示切り換えマクロ
;
;  @slider forevisible=true  で表画面のスライダーを表示
;  @slider forevisible=false で表画面のスライダーを非表示
;
;  @slider backvisible=true  で裏画面のスライダーを表示
;  @slider backvisible=false で裏画面のスライダーを非表示
;
;mebius:どのスライダーを表示するかを選ぶ命令
;  @slider page="qmenu"   で簡易メニュー用スライダーのみ表示
;  @slider page="config" でコンフィグ用スライダーのみ表示
;
@macro name="slider"
@eval exp="slider_object.setOptions(mp)"
@endmacro
;mebius:位置調整用命令
@macro name="setSliderPosition"
@eval exp="slider_object.setSliderPosition(mp)"
@endmacro
@return


;------------------
; 2006/01/06 Ranka 
;------------------
以下のような命令を入れることで、表示するスライダーを選択することができます。

      実際に使用するときは、以下のようなbackvisibleやforevisible属性と一緒に記述して、トランジションで表示させるといいでしょう。

        次のような命令で、スライダーの位置(値)を変更できます。(マクロはすぐ下の部分で定義しています)
        ここの例では、Slider[2]のスライダーの位置(値)にSlider[0]の位置(tf.SliderPosition[0])を入れています。

        [setSliderPosition target=2 position=&tf.SliderPosition[0]]  

        マクロなどの定義

        簡易メニューに関するマクロや変数定義などを行います。

        first.ksなどのゲームに入る前に、以下の命令を追加します。
        まずはスライダーを用いている場合、スライダープラグインを定義するよりも前の場所に、以下の命令を定義しておきます。
        文字速度などの変数名は、もし既に使っているものがあれば、Devasなどのツールを用いて一括置換しておいて下さい。
        速度の値や上限値なども適当に修正して下さい。
        ;-----------------------------------------------------------------------------
        ;■slider.ksよりも前に定義するもの
        ;-----------------------------------------------------------------------------
        ;初期値。設定の初期化をする時にもこの値を使います。
        [eval exp="f.init_text = 30"]
        [eval exp="f.init_readtext = 30"]
        [eval exp="f.init_autoread = 1000"]
        
        @iscript
        // この定義は、sliderプラグイン定義よりも前に記述しておきます。
        // デフォルトのテキスト速度
        sf.txt_vol = f.init_text if sf.txt_vol  === void;
        // デフォルトの自動で読む速度用
        sf.autoread_vol = f.init_autoread if sf.autoread_vol  === void;
        
        //文字速度最大値(最も遅い)
        f.txtspeed_max = 100;
        //自動で読む速度最大値(最も遅い)
        f.autoreadspeed_max = 5000;
        //自動で読む速度最小値(最も速い)
        f.autoreadspeed_min = 200;
        
        @endscript
        
        上記の命令を追加した後に、スライダープラグインを定義します。
        [call storage="slider.ks"]
        
        first.ksなどのゲームに入る前に、以下の命令を追加します。
        こちらは、スライダープラグインのコールの後に記述します。
        オートセーブが不要であれば、該当箇所は消しても大丈夫だと思います。(そのままでも問題ありません)
        ;-----------------------------------------------------------------------------
        ;■簡易メニュー関連の定義
        ;-----------------------------------------------------------------------------
        @iscript
        //簡易メニュー表示可能/不可能フラグ             0:表示不可、1:表示許可
        f.qmenu_enabled = 0;
        
        //レイヤー定義
        //sf.qmenu_exec_layer:簡易実行メニュー下(命令用)
        //sf.qmenu_save_layer:簡易セーブメニュー右(セーブ用)
        //sf.qmenu_config_layer:簡易設定メニュー左(設定用)
        //sf.qmenu_system_layer:簡易システムメニュー上(システム用)
        //sf.qmenu_hint_layer:ツールチップヒント表示用
        sf.qmenu_exec_layer   = "message2";
        sf.qmenu_save_layer   = "message3";
        sf.qmenu_config_layer = "message4";
        sf.qmenu_system_layer = "message5";
        sf.qmenu_hint_layer   = "message6";
        //上記システム変数を元にレイヤーナンバーを内部で定義します。
        //現状ではメッセージレイヤーは0~9まで(1桁のみ)有効。
        //2桁を使いたければ、defineQMenuLayers()内部を2桁取得に修正して下さい。
        kag.defineQMenuLayers();
        
        //セーブ・ロードのページ数
        sf.saveload_page = 0 if sf.saveload_page === void;
        //最新の栞番号を記録しておくシステム変数
        sf.new_savedata = -1 if sf.new_savedata === void;
        //オートセーブ          0:なし  1:あり
        sf.autosave = 1 if sf.autosave === void;
        //オートセーブ用先頭エントリ    0から9まで
        sf.autosave_entry = 0 if sf.autosave_entry === void;
        //sf.save_ask 0:セーブ・ロード時に確認メッセージを出さない、1:確認メッセージを出す
        sf.save_ask = 1 if sf.save_ask === void;
        //sf.readtxt_fast       0:既読文章は瞬間表示しない      1:既読文章は瞬間表示
        sf.readtxt_fast = 0 if sf.readtxt_fast === void;
        
        //簡易メニュー(下:命令)の表示設定            0:常に非表示、1:領域に入った時だけ表示、2:常に表示
        sf.qmenu_exec_mode = 1 if sf.qmenu_exec_mode === void;
        //簡易メニュー(右:セーブ)の表示設定          0:常に非表示、1:領域に入った時だけ表示、2:常に表示
        sf.qmenu_save_mode = 1 if sf.qmenu_save_mode === void;
        //簡易メニュー(左:設定)の表示設定            0:常に非表示、1:領域に入った時だけ表示、2:常に表示
        sf.qmenu_config_mode = 1 if sf.qmenu_config_mode === void;
        //簡易メニュー(上:システム)の表示設定        0:常に非表示、1:領域に入った時だけ表示、2:常に表示
        sf.qmenu_system_mode = 1 if sf.qmenu_system_mode === void;
        
        //ツールチップヒントの表示設定          0:なし、1:あり
        sf.qmenu_hint = 1 if sf.qmenu_hint === void;
        
        //簡易メニューの移動する距離(=表示する高さor幅)の定義(pixel)
        sf.qmenu_exec_movepixel   = 20;
        sf.qmenu_save_movepixel   = 35;
        sf.qmenu_config_movepixel = 110;
        sf.qmenu_system_movepixel = 24;
        //簡易メニューの動く速度定義(値が大きければ速くなります)
        sf.qmenu_exec_movespeed   = 2;
        sf.qmenu_save_movespeed   = 3;
        sf.qmenu_config_movespeed = 10;
        sf.qmenu_system_movespeed = 2;
        
        
        @endscript
        
        ; スライダー変更時の処理用ラベルの指定
        ; スライダーを設置した順に書いてくださいね
        ; ※設置数とラベル指定の数が合わないと不具合が起きるので、
        ;  処理なし(設定終了時にフラグを立てる等)のスライダーは
        ;   tf.sliders = [ '*test1', '', '*test3' ];
        ;  というように '' だけを書いておいてください
        @eval exp="tf.sliders = [ '', '', '', '']"
        ; tf.SliderPositionの要素を全て-1で初期化します。
        @eval exp="tf.SliderPosition[0] = -1"
        @eval exp="tf.SliderPosition[1] = -1"
        @eval exp="tf.SliderPosition[2] = -1"
        @eval exp="tf.SliderPosition[3] = -1"
        
        [layopt layer=&sf.qmenu_exec_layer visible=false page=fore]
        [layopt layer=&sf.qmenu_exec_layer visible=false page=back]
        [layopt layer=&sf.qmenu_save_layer visible=false page=fore]
        [layopt layer=&sf.qmenu_save_layer visible=false page=back]
        [layopt layer=&sf.qmenu_config_layer visible=false page=fore]
        [layopt layer=&sf.qmenu_config_layer visible=false page=back]
        [layopt layer=&sf.qmenu_system_layer visible=false page=fore]
        [layopt layer=&sf.qmenu_system_layer visible=false page=back]
        [layopt layer=&sf.qmenu_hint_layer visible=false page=fore]
        [layopt layer=&sf.qmenu_hint_layer visible=false page=back]
        
        @position layer=&sf.qmenu_exec_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=fore
        @position layer=&sf.qmenu_exec_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=back
        @position layer=&sf.qmenu_save_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=fore
        @position layer=&sf.qmenu_save_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=back
        @position layer=&sf.qmenu_config_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=fore
        @position layer=&sf.qmenu_config_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=back
        @position layer=&sf.qmenu_system_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=fore
        @position layer=&sf.qmenu_system_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=back
        @position layer=&sf.qmenu_hint_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=fore
        @position layer=&sf.qmenu_hint_layer frame="" left=0 top=0 width=800 height=600 marginl=0 margint=0 marginr=0 marginb=0 page=back
        
        ;-----------------------------------------------------------------------------
        ;■簡易メニュー表示許可                 [qmenu enabled=true][qmenu enabled=false]
        ;-----------------------------------------------------------------------------
        [macro name=qmenu]
        @if exp="mp.enabled"
        [eval exp="f.qmenu_enabled = 1"]
        @else
        [eval exp="f.qmenu_enabled = 0"]
        @endif
        [endmacro]
        
        ;-----------------------------------------------------------------------------
        ;■簡易メニューの描画
        ;       マウス移動で表示の場合(fore画面に描画)        [init_qmenu page="fore"]
        ;       常に表示の場合(back画面に描画)                [init_qmenu page="back"]
        ;(注意)「常に表示([init_qmenu])」の場合、back画面に描画します。
        ;トランジション命令などを用いて、文字枠読み込みなどと同時にこの命令を挿入します。
        ;[init_qmenu page="fore"]は必ずトランジション完了後に行います。
        ; 例:以下のような順番
        ;  [backlay][文字枠読み込み命令][init_qmenu page="back"][trans ...][wt][init_qmenu page="fore"]
        ;-----------------------------------------------------------------------------
        [macro name=init_qmenu]
        @if exp="mp.page == 'fore'"
        @if exp="sf.qmenu_exec_mode ==1"
        ;■各メニュー
        @current layer=&sf.qmenu_exec_layer page=fore
        @er
        [layopt layer=&sf.qmenu_exec_layer page=fore visible=false left=0 top=&sf.qmenu_exec_movepixel]
        @eval exp="kag.deleteQExecMenu()"
        @endif
        @if exp="sf.qmenu_save_mode == 1"
        @current layer=&sf.qmenu_save_layer page=fore
        @er
        [layopt layer=&sf.qmenu_save_layer page=fore visible=false left=&sf.qmenu_save_movepixel top=0]
        @eval exp="kag.deleteQSaveMenu()"
        @endif
        @if exp="sf.qmenu_config_mode == 1"
        @current layer=&sf.qmenu_config_layer page=fore
        @er
        [layopt layer=&sf.qmenu_config_layer page=fore visible=false left=&"-sf.qmenu_config_movepixel" top=0]
        @eval exp="kag.deleteQConfigMenu()"
        @endif
        @if exp="sf.qmenu_system_mode == 1"
        @current layer=&sf.qmenu_system_layer page=fore
        @er
        [layopt layer=&sf.qmenu_system_layer page=fore visible=false left=0 top=&"-sf.qmenu_system_movepixel"]
        @eval exp="kag.deleteQSystemMenu()"
        @endif
        @endif
        
        @if exp="mp.page == 'back'"
        @if exp="sf.qmenu_exec_mode == 2"
        ;■各メニュー
        @current layer=&sf.qmenu_exec_layer page=back
        @er
        [layopt layer=&sf.qmenu_exec_layer page=back visible=true left=0 top=0]
        @eval exp="kag.deleteQExecMenu()"
        @eval exp="kag.makeQExecMenu('back')"
        @eval exp="kag.showQExecMenu('nowait','back')"
        @endif
        @if exp="sf.qmenu_save_mode == 2"
        @current layer=&sf.qmenu_save_layer page=back left=0 top=0
        @er
        [layopt layer=&sf.qmenu_save_layer page=back visible=true]
        @eval exp="kag.deleteQSaveMenu()"
        @eval exp="kag.makeQSaveMenu('back')"
        @eval exp="kag.showQSaveMenu('nowait','back')"
        @endif
        @if exp="sf.qmenu_config_mode == 2"
        @current layer=&sf.qmenu_config_layer page=back left=0 top=0
        @er
        [layopt layer=&sf.qmenu_config_layer page=back visible=true]
        @eval exp="kag.deleteQConfigMenu()"
        @eval exp="kag.makeQConfigMenu('back')"
        @eval exp="kag.showQConfigMenu('nowait','back')"
        @slider page="qmenu" forevisible=false backvisible=true
        @endif
        @if exp="sf.qmenu_system_mode == 2"
        @current layer=&sf.qmenu_system_layer page=back left=0 top=0
        @er
        [layopt layer=&sf.qmenu_system_layer page=back visible=true]
        @eval exp="kag.deleteQSystemMenu()"
        @eval exp="kag.makeQSystemMenu('back')"
        @eval exp="kag.showQSystemMenu('nowait','back')"
        @endif
        @endif
        @current layer=message0
        [endmacro]
        
        
        ;-----------------------------------------------------------------------------
        ;■簡易メニュー消去                     [erase_qmenu]
        ;-----------------------------------------------------------------------------
        [macro name=erase_qmenu]
        [layopt layer=&sf.qmenu_exec_layer visible=false page=back]
        [layopt layer=&sf.qmenu_save_layer visible=false page=back]
        [layopt layer=&sf.qmenu_config_layer visible=false page=back]
        [layopt layer=&sf.qmenu_system_layer visible=false page=back]
        ;スライダー表示中ならスライダー消去
        @if exp="slider_object.foreControlLayer.Sliders[0].visible"
        @slider backvisible=false
        @endif
        [endmacro]
        
        
        ;-----------------------------------------------------------------------------
        ;■オートセーブ                 [autosave]
        ;-----------------------------------------------------------------------------
        [macro name=autosave]
        ;直前のラベルでオートセーブされます
        @if exp="sf.autosave && !kag.autosaveLoadedFlag"
        @eval exp="kag.autosaveLoadedFlag = 0"
        @save place=&"sf.autosave_entry+100" ask=no
        @eval exp="sf.autosave_entry += 1"
        @eval exp="sf.autosave_entry -= 10" cond="sf.autosave_entry >= 10"
        @endif
        [endmacro]
        ここで定義したマクロの使い方を以下で説明します。

        簡易メニューの表示許可、不許可命令:

        [qmenu enabled=false]

        [qmenu enabled=true] 簡易メニューの描画命令:
        (重要)コメントにあるように、[init_qmenu page=”fore”]は必ずトランジション完了後に行います。
        なお、現状ではこのinit_qmenu命令を行った後のカレントメッセージの場所は、message0になります。
        もし問題がある場合、init_qmenuマクロ内の@current layer=message0の部分を修正しておいて下さい。

        [init_qmenu page=”fore”]

        [init_qmenu page=”back”] 簡易メニューの消去命令:
        back画面から消去します。
        文字枠消去命令の中にこの命令を入れておくといいでしょう。

        [erase_qmenu] オートセーブ命令:
        オートセーブを用いる場合、こちらをご利用下さい。

        [autosave]  

        コンフィグ画面での処理

        別にコンフィグ画面などでスライダーがある場合、簡易メニューのスライダーの値とコンフィグ画面でのスライダーの値との整合性に注意する必要があります。
        コンフィグ画面を開く時と閉じる時の2箇所で、整合性を合わせる命令を追加すればOKです。

        コンフィグ画面に入った直後に設置する命令を以下に示します。
        スライダーの数ほど増やしたりした場合、個別に値が同一になるように調整して下さい。
        こちらも、サンプルのconfig.ksを参考にしていただければと思います。
        ;簡易メニューとは別にコンフィグ画面などでスライダーがある場合、値の整合性を取ります。
        ;表示する前に同期するスライダーの値(変更済みのもののみ)を読み込んで、位置を反映させます。
        ;tf.SliderPositionの該当箇所は、変更していたら変更後の数値が、未変更なら-1もしくは未変更の値が入っているようにします。
        ;(サンプルのslider.ksはトランジションをした時にもonChangeを呼ぶので、-1が入ってることはまれですが......)
        ;設定画面のスライダーと簡易メニューのスライダーの値を同じにするために、以下の命令を追加します。
        ;(設定画面を開くとき)
        [qmenu enabled=false]
        ;値の同期(簡易メニューの値が修正されていたら、コンフィグ画面のスライダーに値を代入)
        @setSliderPosition target=2 position=&tf.SliderPosition[0] cond="tf.SliderPosition[0]!=-1"
        @setSliderPosition target=3 position=&tf.SliderPosition[1] cond="tf.SliderPosition[1]!=-1"
        ;変更されたものを初期化(簡易メニューのスライダーポジションを-1にします)
        @eval exp="tf.SliderPosition[0] = -1"
        @eval exp="tf.SliderPosition[1] = -1"
        ;表示するスライダーの変更
        @slider page="config"
        コンフィグ画面でスライダーを表示・非表示する命令は、以下のような命令で可能です。
        ;~~~設定画面の処理をここで記述~~~
        ;スライダーを表示する命令は以下の通り。(fore画面に表示する場合はforevisible=trueでOKです)
        ;@slider backvisible=true
        ;@slider backvisible=false
        
        コンフィグ画面から出るとき、以下の命令を設置します。
        ;(設定画面を閉じるとき)
        [qmenu enabled=true]
        ;値の同期(コンフィグ画面のスライダーの値が修正されていたら、簡易メニューのスライダーに値を代入)
        @setSliderPosition target=0 position=&tf.SliderPosition[2] cond="tf.SliderPosition[2]!=-1"
        @setSliderPosition target=1 position=&tf.SliderPosition[3] cond="tf.SliderPosition[3]!=-1"
        ;変更されたものを初期化(コンフィグ画面で設定したスライダーポジションを-1にします)
        @eval exp="tf.SliderPosition[2] = -1"
        @eval exp="tf.SliderPosition[3] = -1"
        ;表示するスライダーの変更
        @slider page="qmenu"
        

        命令の処理例

        実際に、個別のボタンを押したときに実行する命令の処理例を示しておきます。
        必要であれば参考にして下さい。サンプルのqmenu.ksと同じものです。
        ;-----------------------------------------------------------------------------
        ;■クイックセーブ
        ;-----------------------------------------------------------------------------
        *q_save
        @save ask=false place=99
        @return
        
        ;-----------------------------------------------------------------------------
        ;■クイックロード
        ;-----------------------------------------------------------------------------
        *q_load
        [if exp="sf.save_ask"]
        [if exp="askYesNo('クイックセーブした栞を読み込みますか?') "]
        @load ask=false place=99
        [endif]
        [else]
        @load ask=false place=99
        [endif]
        @return
        
        ;-----------------------------------------------------------------------------
        ;■セーブ
        ;-----------------------------------------------------------------------------
        *save
        @eval exp="f.rclickmode = 2, kag.callExtraConductor('saveload.ks','*saveload')"
        @return
        
        ;-----------------------------------------------------------------------------
        ;■ロード
        ;-----------------------------------------------------------------------------
        *load
        @eval exp="f.rclickmode = 1, kag.callExtraConductor('saveload.ks','*saveload')"
        @return
        
        ;-----------------------------------------------------------------------------
        ;■設定
        ;-----------------------------------------------------------------------------
        *config
        @call storage="config.ks" target="*start-config"
        @return
        
        ;-----------------------------------------------------------------------------
        ;■履歴
        ;-----------------------------------------------------------------------------
        *history
        @eval exp="kag.showHistory()"
        @return
        
        ;-----------------------------------------------------------------------------
        ;■音声再生
        ;-----------------------------------------------------------------------------
        *playvoice
        @pv_playpart char=&f.pv_char voice=&f.pv_voice colorchange=false
        @return
        
        ;-----------------------------------------------------------------------------
        ;■早送り
        ;-----------------------------------------------------------------------------
        *skipmode
        @eval exp="tf.autoMode=1,menuCheckTimer.enabled=true"
        @return
        
        ;-----------------------------------------------------------------------------
        ;■自動再生
        ;-----------------------------------------------------------------------------
        *autoplay
        @eval exp="tf.autoMode=2,menuCheckTimer.enabled=true"
        @return
        
        
        ;-----------------------------------------------------------------------------
        ;■文字消去
        ;-----------------------------------------------------------------------------
        *erasetextwindow
        ;文字枠消去命令を追加します。
        @eval exp="tf.qmenu_enabled_temp = f.qmenu_enabled"
        [qmenu enabled=false]
        @layopt layer=message0 page=fore visible=false
        @layopt layer=0 page=fore visible=false
        @waitclick
        @layopt layer=message0 page=fore visible=true
        @layopt layer=0 page=fore visible=true
        @if exp="tf.qmenu_enabled_temp"
        [qmenu enabled=true]
        @endif
        
        @return
        
        ;-----------------------------------------------------------------------------
        ;■メニュー表示
        ;-----------------------------------------------------------------------------
        *openmenu
        ;メニューにジャンプ
        ;@eval exp="kag.callExtraConductor('rclick.ks','*rclick')"
        @eval exp="kag.hideQMenuHint()"
        @call storage="rclick.ks" target="*rclick"
        
        @return
        
        
        ;-----------------------------------------------------------------------------
        ;■最初に戻る(システムメニュー)
        ;-----------------------------------------------------------------------------
        *returntop
        @gotostart ask=true
        @return
        
        ;-----------------------------------------------------------------------------
        ;■終了(システムメニュー)
        ;-----------------------------------------------------------------------------
        *exit_game
        @close ask=true
        @return
        
        
        もし、上記qmenu.ksの内部で用いられている早送り、自動再生を使用する場合、以下の命令をfirst.ksなどのマクロ定義部分で記述しておきます。
        ;-----------------------------------------------------------------------------
        ;■早送り、自動再生用
        ;-----------------------------------------------------------------------------
        @iscript
        var menuCheckTimer = new Timer (menuCheck, '');
        menuCheckTimer.interval = 20;
        function menuCheck {
            if (tf.autoMode==1)kag.skipToNextStopMenuItem.click();
            if (tf.autoMode==2)kag.autoModeMenuItem.click();
            menuCheckTimer.enabled = false;  // タイマー停止
        }
        @endscript
        
        
         

        画像ファイル

        画像をサンプルファイルからコピーして下さい。
        imageフォルダにボタン画像などがあります。

         

        テスト実行例

        テスト用の実行例として、以下のような例を挙げておきます。
        サンプルに入っているものと似たようなものです。
        ;-----------------------------------------------------------------------------
        ;■テスト実行
        ;-----------------------------------------------------------------------------
        
        @rclick call=true target="*rclick" enabled=true
        
        *restart_point|簡易メニュー
        
        
        [cm]
        
        @eval exp="sf.qmenu_exec_mode = 1"
        @eval exp="sf.qmenu_save_mode = 1"
        @eval exp="sf.qmenu_config_mode = 1"
        @eval exp="sf.qmenu_system_mode = 1"
        
        @backlay
        @image storage="black" layer=base page=back visible=true
        @trans layer=base time=50 method=crossfade
        @wt
        
        *test_point|簡易メニュー概要
        [autosave]
        [qmenu enabled=true]
        
        @backlay
        @image storage="ima_1" layer=base page=back visible=true
        @image storage="textwindow" layer=0 page=back visible=true
        [init_qmenu page="back"]
        @trans layer=base time=500 method=crossfade
        @wt
        [init_qmenu page="fore"]
        
        [er]こちらは、簡易メニューのサンプルです。[r][l]
        簡易メニューは上下左右にそれぞれボタンを配置することによって、プレイヤーが非常に簡単に命令の実行や設定変更ができるようになる機能です。[r][l]
        実際にマウスを上下左右に移動させてみると、表示されます。[r][l]
        ボタンの上にマウスを持って行くと、ツールチップヒントも表示できるようになっていますので、記号だけの表示でも分かりやすくなっています。[r][l]
        下が命令系、右がセーブ・ロード系、左が設定系、上がシステム系です。[r][l]
        上下左右の簡易メニューとツールチップヒントは、それぞれ個別に表示させたり表示させないように設定することも可能です。[r][l]
        例えば、上のシステム系命令だけは使わないということも可能です。[p]
        [er]セーブ機能、設定機能、システム機能については基本的な動作はするようになっていますが、命令系のボタンについてはシステムごとに違うと思われますので、個別に作り込んで下さい。[r][l]
        ま、サンプルとして簡単なものはご提供していますので、そちらを参考にして頂ければと思います。[r][l]
        なお、キーボード操作にも対応しています。[r][l]
        上下左右の方向キーでそれぞれのメニューが表示され、ESCキーでキャンセルできます。[r][l]
        セーブ・ロード部分では、リターンキーがセーブ、スペースキーがロードに割り当てられています。こちらもソースをいじれば変更可能です。[r][p]
        [er]それでは実際に、右側のセーブ系でセーブ・ロードを試してみて下さい。[r][l]
        左クリックでセーブ、右クリックでロード。マウスホイールでページ移動できます。[r][l]
        お次は左側の設定部分もどうぞ。[r][l]
        文字速度も変更されます。[r][l]
        現状では自動再生の速度は、ページ末のウェイトのみ([p]タグ)のみ変更するようになっています。クリック待ちウェイト([l]タグ)も変更したい場合、スライダーのslider.ksファイル中にあるソースの該当箇所のコメントを外せば対応できます。[r][l]
        なお、文字表示中は簡易メニューの各ボタンは操作できないようになっています。文字表示中に実行すると文字表示が変になる可能性があるためですね。[r][l]
        上のシステム系命令も動かしてみましょう。ま、別に最初に戻ったり終了する必要はありません。[r][l]
        効果音などは、適宜個別に追加して下さい。[p]
        [er]現在はマウスカーソルで移動したら表示される形式ですが、常に表示をさせることも可能です。[r][l]
        実際に変更してみましょう。[p]
        
        [qmenu enabled=false]
        @backlay
        @image storage="black" layer=base page=back visible=true
        [erase_qmenu]
        @trans layer=base time=500 method=crossfade
        @wt
        
        @eval exp="sf.qmenu_exec_mode = 2"
        @eval exp="sf.qmenu_save_mode = 2"
        @eval exp="sf.qmenu_config_mode = 2"
        @eval exp="sf.qmenu_system_mode = 2"
        
        @wait time=500
        @backlay
        @image storage="engawa_1" layer=base page=back visible=true
        [qmenu enabled=true]
        [init_qmenu page="back"]
        @trans layer=base time=500 method=crossfade
        @wt
        [init_qmenu page="fore"]
        
        *test_point2|「常に表示」のサンプル
        [autosave]
        
        [er]このように、常に表示をすることができます。[r][l]
        下の命令系メニューのみ常に表示、などもできます。[r][l]
        あまり使わないかもしれませんが、設定で変更できるようにしてもいいかと思います。[p]
        
        [qmenu enabled=false]
        @backlay
        @image storage="black" layer=base page=back visible=true
        [erase_qmenu]
        @trans layer=base time=500 method=crossfade
        @wt
        
        @eval exp="sf.qmenu_exec_mode = 1"
        @eval exp="sf.qmenu_save_mode = 1"
        @eval exp="sf.qmenu_config_mode = 1"
        @eval exp="sf.qmenu_system_mode = 1"
        
        @wait time=500
        @backlay
        @image storage="engawa_1" layer=base page=back visible=true
        [init_qmenu page="back"]
        @trans layer=base time=500 method=crossfade
        @wt
        [init_qmenu page="fore"]
        
        *test_point3|使わない場合のサンプル
        [autosave]
        
        [er]今度は簡易メニューを使えなくしてみました。[r][l]
        [qmenu enabled=false]というタグ一つで、簡易メニューを使わないということもできます。[r][l]
        オープニングやエンディング直前では使わないようにするといいかもしれません。[r][l]
        また、文字枠を消して背景を消す時は、簡易メニューは表示させないようにする方が見た目にも美しくなると思います。[r][l]
        [qmenu enabled=true]
        簡易メニューを使えるようにしました。マウスでの移動表示モードにしています。[r][l]
        [er]なお、おまけとしてオートセーブにも対応しています。右側の簡易メニューのオートセーブのページをご覧下さい。[r][l]
        ここまで見ている段階で、既にいくつか、オートセーブされていると思います。[r][l]
        オートセーブは新しい順に表示されるようになっています。[p]
        [er]なお、全画面表示にした場合、ウィンドウメニューを表示しようとすると、上側の簡易メニューが隠れてしまいます。[r][l]
        そのため、ウィンドウメニューを使う場合は、上側の簡易メニューを使わないようにするか、もしくは表示位置をずらすなどの対処をしましょう。[p]
        
        *test_point4|その他注意事項
        [autosave]
        
        [er]なお、簡易メニューでスライダーを使う場合、コンフィグ画面で設定した値と同期する必要があります。[r][l]
        実装方法を見て、同期する命令を追加するのを忘れないようにしましょう。[r][l]
        実際に設定画面にジャンプしてみます。値を変更してみて、設定画面に共に反映されていることを確認して下さい。[p]
        
        @call storage="config.ks"
        
        [er]後は、画像のデザインを個別にして、効果音を追加すれば簡易メニューの導入ができると思います。[r][l]
        なお、文字枠消去命令や、右クリックメニュー、コンフィグ画面などに移行した前後で、画面の整合性が取れているかのチェックを念入りにしましょう。[r][l]
        きちんと常に表示されるか、変なゴミが残らないかですね。[p]
        
        
        [er]この簡易メニューは非常に使いやすい機能となる、自信を持ってご提供できる機能です。[r][l]
        少しでもお役に立てれば嬉しいです。[r][l]
        説明は以上です。最初に戻ります。[p]
        
        [jump target="*restart_point"][s]
        
        
        *rclick
        @call storage="qmenu.ks" target="*erasetextwindow"
        @return
        
        
         

        残作業のメモ

        残作業を以下にざっと説明します。メモ程度なので他にもいろいろとあるでしょうが、参考までに。
        • 簡易メニューの画像デザインをして、画像ファイルの用意をして、座標を確定します。
        • 画像ファイルはサンプルと同じファイル名で保存するといいでしょう。MainWindow.tjsのfunction
          makeQExecMenu()などのメソッド内部で座標を記述します。
        • ボタンを押した後に処理する部分を作ります。
        • MainWindow.tjsのfunction loadQExecMenuClick()メソッドなどから、それぞれの処理部分にジャンプさせるか、そのメソッド内に処理を記述します。
        • ボタンを押したときの効果音など、細かい部分は個別に作り込んで下さい。(注記:function
          defineQMenuLayers()内部のボタン要素に効果音を定義した場合、エラーが出て正常に動かないことがありました。なので、Click後(function
          loadQExecMenuClick()などの内部)もしくはClick後にジャンプした後に効果音命令を別途処理すると安全に動作すると思います)
        • 他にもボタンが必要な場合、どんどん増産していって下さい。
        • 簡易メニューの「マウス移動で表示」と「常に表示」モードの切り替え時の動作チェックはしっかり行いましょう。
         

        その他注意事項

        • 画像生成時、メッセージレイヤに画像を表示する場合、吉里吉里付属の画像フォーマットコンバータ(krkrtpc.exe)を用いて、ltAddAlpha形式に変換しなければ半透明にならないので注意しましょう。(ボタン画像はそのままでOKだったと思います)
          また、既にltAddAlpha形式になっている画像を再度ltAddAlpha形式に変換したら、アルファ情報が壊れてしまう場合があるようですので注意しましょう。
        • 簡易メニュー(右:セーブ)ボタン画像について、ボタン画像は下の画像より常に上に配置されますので、ボタン部分に画像を配置した場合、数値や文字などが下に隠れてしまい見えなくなってしまいます。そのため、ボタン画像はハイライトのみにして、それぞれの模様は下の画像部分に入れています。(サンプル参照)
        • ボタン画像の座標設定は、全て「常に表示」にしたときに800×600でどこに配置するかの座標を入れます。
        • ウィンドウ上部にメニューバーがある場合、フルスクリーン表示すると、マウスを上部に持って行った場合に簡易メニュー(上:システム)の部分がウィンドウのメニューバーによって一部隠れてしまいます。そのため、ウィンドウのメニューバーを入れたい場合は簡易メニュー(上:システム)の座標をもう少し下に配置するか、簡易メニュー(上:システム)を使わないようにしましょう。
        • 文字描画中に簡易メニューの命令を実行すると文字表示がおかしくなる場合がありますので、クリック待ちの状態でなければ一部ボタンは機能しないようになっています。それ以外の場面で簡易メニューを実行したい場合は、function
          checkTextDrawing()内でのclickWaiting部分を削除して修正して下さい。
        • もしオートセーブ機能が不要であれば、function saveBookmarkAutoMode(num)とfunction loadBookmarkAutoMode(num)、もしくはその呼び出し元のfunction lEntryQSaveMenu(num)とrEntryQSaveMenu(num)を書き換えればいいでしょう。
        • セーブ方式については、sf.autosave_entryに最新のエントリポイントを保持していて、オートセーブをする度に+1されます。表示する際に新しい順番に100から表示されるように場所を入れ替えているだけです。
        • スライダーでは、自動読み進め(オートプレイ)の速度は、改ページ時のウェイト(autoModePageWait、いわゆる[p]タグ)のみ変更しています。行クリック待ち時のウェイト(autoModeLineWait、いわゆる[l]タグ)の速度は変更していませんので、必要に応じて調整して下さい。(コメントアウトを外して調整して下さい)
        • [cm]タグなど、全メッセージレイヤを消去する命令は使わないようにしましょう。簡易メニューまで消されてしまいます。
         

        よくありそうなトラブル

        • 簡易メニューを移動表示にしているけど、初めて表示エリアにマウスカーソルを入れたときに、移動ではなく瞬間的に表示されてしまう。
          →[init_qmenu page=”fore”]命令がトランジションの前にあるために起こります。[trans][wt]命令の後に記述すれば正常に表示されるようになります。
        • ゲーム中にコンフィグ画面で「マウス移動で表示」から「常に表示」に変更して、ゲームに戻ってもすぐに反映してくれず、次のトランジションが起こったときから「常に表示」が反映される。
          →コンフィグ画面が終わったとき、再度文字枠を含めて簡易メニューをトランジションで描画しなおすことで解決できます。
         

        素材

        月下之煌で用いた画像の素材を置いておきます。
        必要であればどうぞ。
        こちらからダウンロードして下さい。

         

        6.3 文字のフェード表示

        機能

        こんな感じで文字をフェードで表示する機能です。
        NScripterにはあるみたいですが、吉里吉里ではありませんでしたので製作しました。

        kirikiri_font_fade01
        • 1文字ずつ透明度を上げながら表示することによって、フェードっぽく見えます。
        • ノーウェイトを含む、ある一定速度より速く表示される速度の場合、フェード表示を無効にします。
        • CPUにあまり負荷がかからないので、追加しても軽く動作します。
        実装方法を以下に示します。

        Config.tjs

        • Config.tjsのメッセージレイヤにおけるフォントの設定で、「縁取り」にします。(defaultEdge
          = trueに)。影付けでも、共に処理なしでも動作上は全く問題ありませんが、縁取りの方が美しく表示されます。
         

        MessageLayer.tjs

        MessageLayer.tjsのfunction MessageLayer()の直前に、以下の命令を追加します。
        フェードの速さやタイミング、フェード表示させない速度の閾値などは、これらの数値を調整して下さい。
        (注意)6文字をフェードさせながら表示させますので、あまりにゆっくりなフェード速度だと違和感が出る可能性があります。
                // リンクタイプ
                var ltNormal = 1;
                var ltButton = 2;
                var ltEdit = 3;
                var ltCheckBox = 4;
        
        //↓--------------------------------------- ここから追加部分--
                //mebius:文字フェード用変数
                var drawtimer = [];
                var timercount = 0;
                var chelm = %[];
                var timer_interval = 40;//フェード状態更新の頻度(ms)
                var timer_addopa = 65;//1回のフェードでどれだけ透明度を上げるか(最高255)
                var first_opa = 50;//最初に描画する時の透明度(最高255)
                var nonfade_limit = 10;//これ以下の値の(表示が速い)文字速度(ms)では、フェード表示させない上限値。
        //↑--------------------------------------- ここまで追加部分--
        
                function MessageLayer(owner, parent, name, id, do_config)
                {
                        // MessageLayer コンストラクタ
                        // owner : オーナー KAG Window
                        // parent : 親レイヤ
        同じくMessageLayer.tjsのfunction MessageLayer()の最後に、以下の命令を追加します。
                function MessageLayer(owner, parent, name, id, do_config)
                {
                        //(中略)
        
                        // リンクをハイライト表示するためのレイヤ
                        highlightLayer = new global.KAGLayer(window, this);
                        highlightLayer.type = layerType;
                        highlightLayer.face = dfAuto;
                        highlightLayer.hitType = htProvince;
                                // 領域画像で当たり判定を行う
        
        //↓--------------------------------------- ここから追加部分--
                        //mebius:文字フェード用タイマー定義
                        drawtimer[0] = new Timer(onDrawTimer0, '');
                        drawtimer[