• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

MIDITrail をピカピカにする。鍵盤方向自動切替・多ポート・歌詞対応等


Commit MetaInfo

Revision8a4022645f8fe7bc79e837e3487cc4029982e03a (tree)
Time2018-04-12 09:46:52
Authoryoshy <yoshy@user...>
Commiteryoshy

Log Message

Merge branch 'develop' into master/yossiepon

Change Summary

Incremental Difference

--- a/MIDITrail/MIDITrail.rc
+++ b/MIDITrail/MIDITrail.rc
@@ -79,6 +79,10 @@ BEGIN
7979 MENUITEM "Stars", IDM_ENABLE_STARS
8080 MENUITEM "Counter", IDM_ENABLE_COUNTER
8181 MENUITEM "Background Image", IDM_ENABLE_BACKGROUNDIMAGE
82+// >>> add 20180404 yossiepon begin
83+ MENUITEM "Time Indicator", IDM_ENABLE_TIMEINDICATOR
84+ MENUITEM "Grid Box", IDM_ENABLE_GRIDBOX
85+// <<< add 20180404 yossiepon end
8286 MENUITEM SEPARATOR
8387 MENUITEM "Auto save viewpoint", 32838
8488 MENUITEM SEPARATOR
@@ -309,9 +313,9 @@ END
309313
310314 STRINGTABLE
311315 BEGIN
312-// >>> modify 20180404 yossiepon begin
313- IDS_APP_TITLE "MIDITrail 1.2.3 mod. yossiepon_20180404"
314-// <<< modify 20180404 yossiepon end
316+// >>> modify 20180412 yossiepon begin
317+ IDS_APP_TITLE "MIDITrail 1.2.3 mod. yossiepon_20180412"
318+// <<< modify 20180412 yossiepon end
315319 IDC_MIDITRAIL "MIDITRAIL"
316320 END
317321
--- a/MIDITrail/MIDITrailApp.cpp
+++ b/MIDITrail/MIDITrailApp.cpp
@@ -76,6 +76,10 @@ MIDITrailApp::MIDITrailApp(void)
7676 m_isEnableCounter = true;
7777 m_isEnableFileName = false;
7878 m_isEnableBackgroundImage = true;
79+// >>> add 20180404 yossiepon begin
80+ m_isEnableTimeIndicator = true;
81+ m_isEnableGridBox = true;
82+// <<< add 20180404 yossiepon end
7983
8084 //シーン種別
8185 m_SceneType = Title;
@@ -683,6 +687,18 @@ LRESULT MIDITrailApp::_WndProcImpl(
683687 result = _OnMenuEnableEffect(MTScene::EffectBackgroundImage);
684688 if (result != 0) goto EXIT;
685689 break;
690+// >>> add 20180404 yossiepon begin
691+ case IDM_ENABLE_TIMEINDICATOR:
692+ //表示効果:タイムインジケータ
693+ result = _OnMenuEnableEffect(MTScene::EffectTimeIndicator);
694+ if (result != 0) goto EXIT;
695+ break;
696+ case IDM_ENABLE_GRIDBOX:
697+ //表示効果:グリッドボックス
698+ result = _OnMenuEnableEffect(MTScene::EffectGridBox);
699+ if (result != 0) goto EXIT;
700+ break;
701+// <<< add 20180404 yossiepon end
686702 case IDM_WINDOWSIZE:
687703 //ウィンドウサイズ設定
688704 result = _OnMenuWindowSize();
@@ -1275,6 +1291,14 @@ int MIDITrailApp::_OnMenuEnableEffect(
12751291 case MTScene::EffectBackgroundImage:
12761292 m_isEnableBackgroundImage = m_isEnableBackgroundImage ? false : true;
12771293 break;
1294+// >>> add 20180404 yossiepon begin
1295+ case MTScene::EffectTimeIndicator:
1296+ m_isEnableTimeIndicator = !m_isEnableTimeIndicator;
1297+ break;
1298+ case MTScene::EffectGridBox:
1299+ m_isEnableGridBox = !m_isEnableGridBox;
1300+ break;
1301+// <<< add 20180404 yossiepon end
12781302 default:
12791303 break;
12801304 }
@@ -2138,7 +2162,10 @@ int MIDITrailApp::_ChangeMenuStyle()
21382162 IDM_ENABLE_PITCHBEND,
21392163 IDM_ENABLE_STARS,
21402164 IDM_ENABLE_COUNTER,
2141- IDM_ENABLE_BACKGROUNDIMAGE,
2165+// >>> add 20180404 yossiepon begin
2166+ IDM_ENABLE_TIMEINDICATOR,
2167+ IDM_ENABLE_GRIDBOX,
2168+// <<< add 20180404 yossiepon end
21422169 IDM_WINDOWSIZE,
21432170 IDM_OPTION_MIDIOUT,
21442171 IDM_OPTION_MIDIIN,
@@ -2178,6 +2205,10 @@ int MIDITrailApp::_ChangeMenuStyle()
21782205 { MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED }, //IDM_ENABLE_STARS
21792206 { MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED }, //IDM_ENABLE_COUNTER
21802207 { MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED }, //IDM_ENABLE_BACKGROUNDIMAGE
2208+// >>> add 20180404 yossiepon begin
2209+ { MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED }, //IDM_ENABLE_TIMEINDICATOR
2210+ { MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED, MF_ENABLED }, //IDM_ENABLE_GRIDBOX
2211+// <<< add 20180404 yossiepon end
21812212 { MF_ENABLED, MF_ENABLED, MF_GRAYED, MF_GRAYED, MF_ENABLED, MF_GRAYED }, //IDM_WINDOWSIZE
21822213 { MF_ENABLED, MF_ENABLED, MF_GRAYED, MF_GRAYED, MF_ENABLED, MF_GRAYED }, //IDM_OPTION_MIDIOUT
21832214 { MF_ENABLED, MF_ENABLED, MF_GRAYED, MF_GRAYED, MF_ENABLED, MF_GRAYED }, //IDM_OPTION_MIDIIN
@@ -2798,6 +2829,14 @@ int MIDITrailApp::_UpdateMenuCheckmark()
27982829 //背景画像表示
27992830 _CheckMenuItem(IDM_ENABLE_BACKGROUNDIMAGE, m_isEnableBackgroundImage);
28002831
2832+// >>> add 20180404 yossiepon begin
2833+ //タイムインジケータ表示
2834+ _CheckMenuItem(IDM_ENABLE_TIMEINDICATOR, m_isEnableTimeIndicator);
2835+
2836+ //グリッドボックス表示
2837+ _CheckMenuItem(IDM_ENABLE_GRIDBOX, m_isEnableGridBox);
2838+// <<< add 20180404 yossiepon end
2839+
28012840 //自動視点保存
28022841 _CheckMenuItem(IDM_AUTO_SAVE_VIEWPOINT, m_isAutoSaveViewpoint);
28032842
@@ -2840,6 +2879,10 @@ void MIDITrailApp::_UpdateEffect()
28402879 m_pScene->SetEffect(MTScene::EffectCounter, m_isEnableCounter);
28412880 m_pScene->SetEffect(MTScene::EffectFileName, m_isEnableFileName);
28422881 m_pScene->SetEffect(MTScene::EffectBackgroundImage, m_isEnableBackgroundImage);
2882+// >>> add 20180404 yossiepon begin
2883+ m_pScene->SetEffect(MTScene::EffectTimeIndicator, m_isEnableTimeIndicator);
2884+ m_pScene->SetEffect(MTScene::EffectGridBox, m_isEnableGridBox);
2885+// <<< add 20180404 yossiepon end
28432886 }
28442887 return;
28452888 }
--- a/MIDITrail/MIDITrailApp.h
+++ b/MIDITrail/MIDITrailApp.h
@@ -43,9 +43,9 @@ using namespace SMIDILib;
4343 #define WM_FILEPATH_POSTED (WM_USER + 100)
4444
4545 //メニュースタイル制御
46-// >>> modify 20161223 yossiepon begin
47-#define MT_MENU_NUM (32)
48-// <<< modify 20161223 yossiepon end
46+// >>> modify 20180404 yossiepon begin
47+#define MT_MENU_NUM (34)
48+// <<< modify 20180404 yossiepon end
4949 #define MT_PLAYSTATUS_NUM (6)
5050
5151 //デバイスロスト警告メッセージ
@@ -181,6 +181,10 @@ private:
181181 bool m_isEnableCounter;
182182 bool m_isEnableFileName;
183183 bool m_isEnableBackgroundImage;
184+// >>> add 20180404 yossiepon begin
185+ bool m_isEnableTimeIndicator;
186+ bool m_isEnableGridBox;
187+// <<< add 20180404 yossiepon end
184188
185189 //シーン種別
186190 SceneType m_SceneType;
--- a/MIDITrail/MIDITrailVersion.h
+++ b/MIDITrail/MIDITrailVersion.h
@@ -16,8 +16,10 @@
1616 //******************************************************************************
1717
1818 //バージョン文字列
19-#define MIDITRAIL_VERSION_STRING_X86 _T("1.2.3 (x86), mod. yossiepon_20180404")
20-#define MIDITRAIL_VERSION_STRING_X64 _T("1.2.3 (x64), mod. yossiepon_20180404")
19+// >>> modify 20180412 yossiepon begin
20+#define MIDITRAIL_VERSION_STRING_X86 _T("1.2.3 (x86), mod. yossiepon_20180412")
21+#define MIDITRAIL_VERSION_STRING_X64 _T("1.2.3 (x64), mod. yossiepon_20180412")
22+// <<< modify 20180412 yossiepon end
2123
2224 //コピーライト
2325 #define MIDITRAIL_COPYRIGHT _T("Copyright (C) 2010-2017 WADA Masashi");
--- a/MIDITrail/MTGridBox.h
+++ b/MIDITrail/MTGridBox.h
@@ -36,11 +36,13 @@ public:
3636 //生成
3737 int Create(LPDIRECT3DDEVICE9 pD3DDevice, const TCHAR* pSceneName, SMSeqData* pSeqData);
3838
39+// >>> modify function to virtual 20180404 yossiepon begin
3940 //更新
40- int Transform(LPDIRECT3DDEVICE9 pD3DDevice, float rollAngle);
41+ virtual int Transform(LPDIRECT3DDEVICE9 pD3DDevice, float rollAngle);
4142
4243 //描画
43- int Draw(LPDIRECT3DDEVICE9 pD3DDevice);
44+ virtual int Draw(LPDIRECT3DDEVICE9 pD3DDevice);
45+// <<< modify function to virtual 20180404 yossiepon end
4446
4547 //解放
4648 void Release();
--- a/MIDITrail/MTGridBoxMod.cpp
+++ b/MIDITrail/MTGridBoxMod.cpp
@@ -20,6 +20,7 @@ using namespace YNBaseLib;
2020 //******************************************************************************
2121 MTGridBoxMod::MTGridBoxMod(void)
2222 {
23+ m_isEnable = true;
2324 }
2425
2526 //******************************************************************************
@@ -48,14 +49,6 @@ int MTGridBoxMod::Transform(
4849 D3DXMatrixIdentity(&moveMatrix);
4950 D3DXMatrixIdentity(&worldMatrix);
5051
51- if(rollAngle < 0.0f) {
52- rollAngle += 360.0f;
53- }
54-
55- if((rollAngle > 120.0f) && (rollAngle < 300.0f)) {
56- rollAngle -= 180.0f;
57- }
58-
5952 //回転行列
6053 D3DXMatrixRotationX(&rotateMatrix, D3DXToRadian(rollAngle));
6154
@@ -71,3 +64,31 @@ int MTGridBoxMod::Transform(
7164
7265 return result;
7366 }
67+
68+//******************************************************************************
69+// 描画
70+//******************************************************************************
71+int MTGridBoxMod::Draw(
72+ LPDIRECT3DDEVICE9 pD3DDevice
73+ )
74+{
75+ int result = 0;
76+
77+ if (!m_isEnable) goto EXIT;
78+
79+ result = MTGridBox::Draw(pD3DDevice);
80+ if (result != 0) goto EXIT;
81+
82+EXIT:;
83+ return result;
84+}
85+
86+//******************************************************************************
87+// 表示設定
88+//******************************************************************************
89+void MTGridBoxMod::SetEnable(
90+ bool isEnable
91+ )
92+{
93+ m_isEnable = isEnable;
94+}
--- a/MIDITrail/MTGridBoxMod.h
+++ b/MIDITrail/MTGridBoxMod.h
@@ -27,5 +27,15 @@ public:
2727 //更新
2828 virtual int Transform(LPDIRECT3DDEVICE9 pD3DDevice, float rollAngle);
2929
30+ //描画
31+ virtual int Draw(LPDIRECT3DDEVICE9 pD3DDevice);
32+
33+ //表示設定
34+ void SetEnable(bool isEnable);
35+
36+private:
37+
38+ //表示可否
39+ bool m_isEnable;
3040 };
3141
--- a/MIDITrail/MTNoteBoxMod.cpp
+++ b/MIDITrail/MTNoteBoxMod.cpp
@@ -365,15 +365,11 @@ int MTNoteBoxMod::_UpdateVertexOfActiveNotes(
365365 );
366366 if (result != 0) goto EXIT;
367367
368- //発音中ノートがピッチベンドで移動する場合
369368 //発音終了までオリジナルのノートを非表示にする
370369 if (!(m_pNoteStatusMod[i].isHide)) {
371- if ((m_pNotePitchBend->GetValue(note.portNo, note.chNo) != 0)
372- && (m_pNotePitchBend->GetSensitivity(note.portNo, note.chNo) != 0)) {
373- result = _HideNoteBox(m_pNoteStatusMod[i].index);
374- if (result != 0) goto EXIT;
375- m_pNoteStatusMod[i].isHide = true;
376- }
370+ result = _HideNoteBox(m_pNoteStatusMod[i].index);
371+ if (result != 0) goto EXIT;
372+ m_pNoteStatusMod[i].isHide = true;
377373 }
378374
379375 activeNoteNum++;
--- a/MIDITrail/MTNoteDesignMod.cpp
+++ b/MIDITrail/MTNoteDesignMod.cpp
@@ -67,6 +67,22 @@ unsigned long MTNoteDesignMod::GetRippleReleaseDuration()
6767 }
6868
6969 //******************************************************************************
70+// 描画元(リップル画像)ブレンド指定
71+//******************************************************************************
72+D3DBLEND MTNoteDesignMod::GetRippleSrcBlend()
73+{
74+ return m_RippleSrcBlend;
75+}
76+
77+//******************************************************************************
78+// 描画元(リップル画像)ブレンド指定
79+//******************************************************************************
80+D3DBLEND MTNoteDesignMod::GetRippleDestBlend()
81+{
82+ return m_RippleDestBlend;
83+}
84+
85+//******************************************************************************
7086 // 波紋上書き回数
7187 //******************************************************************************
7288 unsigned long MTNoteDesignMod::GetRippleOverwriteTimes()
@@ -247,6 +263,14 @@ int MTNoteDesignMod::_LoadConfFile(
247263 result = confFile.GetInt(_T("ReleaseDuration"), &m_RippleReleaseDuration, 250);
248264 if (result != 0) goto EXIT;
249265
266+ //描画元(リップル画像)ブレンド指定 Default: D3DBLEND_SRCALPHA(5)
267+ result = confFile.GetInt(_T("SrcBlend"), (int *)&m_RippleSrcBlend, 5);
268+ if (result != 0) goto EXIT;
269+
270+ //描画先(背景画像)ブレンド指定 Default: D3DBLEND_ONE(2)
271+ result = confFile.GetInt(_T("DestBlend"), (int *)&m_RippleDestBlend, 2);
272+ if (result != 0) goto EXIT;
273+
250274 //波紋上書き回数
251275 result = confFile.GetInt(_T("OverwriteTimes"), &m_RippleOverwriteTimes, 3);
252276 if (result != 0) goto EXIT;
--- a/MIDITrail/MTNoteDesignMod.h
+++ b/MIDITrail/MTNoteDesignMod.h
@@ -30,6 +30,8 @@ public:
3030 unsigned long GetRippleReleaseDuration();
3131
3232 //波紋描画情報取得
33+ D3DBLEND GetRippleSrcBlend();
34+ D3DBLEND GetRippleDestBlend();
3335 unsigned long GetRippleOverwriteTimes();
3436 float GetRippleSpacing();
3537
@@ -72,14 +74,19 @@ protected:
7274
7375 private:
7476
75- //ディケイ時間
77+ //波紋ディケイ時間
7678 int m_RippleDecayDuration;
77- //リリース時間
79+ //波紋リリース時間
7880 int m_RippleReleaseDuration;
7981
80- //上書き回数
82+ //波紋描画元(リップル画像)ブレンド指定
83+ D3DBLEND m_RippleSrcBlend;
84+ //波紋描画先(背景画像)ブレンド指定
85+ D3DBLEND m_RippleDestBlend;
86+
87+ //波紋上書き回数
8188 int m_RippleOverwriteTimes;
82- //描画間隔
89+ //波紋描画間隔
8390 float m_RippleSpacing;
8491 };
8592
--- a/MIDITrail/MTNoteRippleMod.cpp
+++ b/MIDITrail/MTNoteRippleMod.cpp
@@ -391,9 +391,9 @@ int MTNoteRippleMod::Draw(
391391 pD3DDevice->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
392392 pD3DDevice->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
393393
394- //レンダリングステート設定:加算合成
395- pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE);
396- pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
394+ //レンダリングステート設定:ブレンド指定値
395+ pD3DDevice->SetRenderState(D3DRS_SRCBLEND, m_NoteDesignMod.GetRippleSrcBlend());
396+ pD3DDevice->SetRenderState(D3DRS_DESTBLEND, m_NoteDesignMod.GetRippleDestBlend());
397397
398398 //プリミティブ描画
399399 if (m_ActiveNoteNum > 0) {
@@ -403,8 +403,8 @@ int MTNoteRippleMod::Draw(
403403 }
404404
405405 //レンダリングステート設定:通常のアルファ合成
406- pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
407406 pD3DDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
407+ pD3DDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
408408
409409 EXIT:;
410410 return result;
--- a/MIDITrail/MTPianoKeyboard.cpp
+++ b/MIDITrail/MTPianoKeyboard.cpp
@@ -1599,20 +1599,20 @@ int MTPianoKeyboard::Transform(
15991599 }
16001600
16011601 // >>> add 20120729 yossiepon begin
1602+// >>> modify 20180411 yossiepon begin
16021603 //******************************************************************************
16031604 // 移動
16041605 //******************************************************************************
16051606 int MTPianoKeyboard::Transform(
16061607 LPDIRECT3DDEVICE9 pD3DDevice,
1607- D3DXVECTOR3 moveVector1,
1608- D3DXVECTOR3 moveVector2,
1609- float scale,
1610- float z,
1608+ D3DXVECTOR3 basePosVector,
1609+ D3DXVECTOR3 playbackPosVector,
16111610 float rollAngle
16121611 )
16131612 {
16141613 return YN_SET_ERR("Program error.", 0, 0);
16151614 }
1615+// <<< modify 20180411 yossiepon end
16161616 // <<< add 20120729 yossiepon end
16171617
16181618 //******************************************************************************
--- a/MIDITrail/MTPianoKeyboard.h
+++ b/MIDITrail/MTPianoKeyboard.h
@@ -47,7 +47,14 @@ public:
4747 //更新
4848 int Transform(LPDIRECT3DDEVICE9 pD3DDevice, D3DXVECTOR3 moveVector, float rollAngle);
4949 // >>> add 20120729 yossiepon begin
50- virtual int Transform(LPDIRECT3DDEVICE9 pD3DDevice, D3DXVECTOR3 moveVector1, D3DXVECTOR3 moveVector2, float scale, float z, float rollAngle);
50+// >>> modify 20180411 yossiepon begin
51+ virtual int Transform(
52+ LPDIRECT3DDEVICE9 pD3DDevice,
53+ D3DXVECTOR3 basePosVector,
54+ D3DXVECTOR3 playbackPosVector,
55+ float rollAngle
56+ );
57+// <<< modify 20180411 yossiepon end
5158 // <<< add 20120729 yossiepon end
5259
5360
--- a/MIDITrail/MTPianoKeyboardCtrlMod.cpp
+++ b/MIDITrail/MTPianoKeyboardCtrlMod.cpp
@@ -12,8 +12,6 @@
1212 #include "YNBaseLib.h"
1313 #include "MTPianoKeyboardCtrlMod.h"
1414 #include "MTPianoKeyboardMod.h"
15-#include "MTNoteRippleMod.h"
16-#include "MTNoteLyrics.h"
1715
1816 using namespace YNBaseLib;
1917
@@ -29,7 +27,7 @@ using namespace YNBaseLib;
2927 //******************************************************************************
3028 MTPianoKeyboardCtrlMod::MTPianoKeyboardCtrlMod(void)
3129 {
32- m_MaxPortIndex = 0;
30+ m_MaxKeyboardIndex = 0;
3331 ZeroMemory(m_KeyDownRateMod, sizeof(float) * SM_MAX_CH_NUM* SM_MAX_CH_NUM * SM_MAX_NOTE_NUM);
3432 }
3533
@@ -54,7 +52,7 @@ int MTPianoKeyboardCtrlMod::Create(
5452 {
5553 int result = 0;
5654 unsigned long index = 0;
57- unsigned long portIndex = 0;
55+ unsigned long keyboardIndex = 0;
5856 unsigned char portNo = 0;
5957 SMTrack track;
6058
@@ -77,20 +75,32 @@ int MTPianoKeyboardCtrlMod::Create(
7775 result = pSeqData->GetPortList(&m_PortList);
7876 if (result != 0) goto EXIT;
7977
80- //ポート番号に昇順のインデックスを振る
81- //ポート 0番 3番 5番 に出力する場合のインデックスはそれぞれ 0, 1, 2
8278 for (index = 0; index < SM_MAX_PORT_NUM; index++) {
83- m_PortIndex[index] = -1;
79+ m_KeyboardIndex[index] = -1;
8480 }
85- for (index = 0; index < m_PortList.GetSize(); index++) {
86- m_PortList.GetPort(index, &portNo);
87- m_PortIndex[portNo] = portIndex;
88- portIndex++;
89- if(portIndex == m_KeyboardDesignMod.GetKeyboardMaxDispNum()){
90- break;
81+
82+ //シングルキーボードでない場合
83+ if (!isSingleKeyboard) {
84+ //ポート番号に昇順のキーボードインデックスを振る
85+ //ポート 0番 3番 5番 に出力する場合のインデックスはそれぞれ 0, 1, 2
86+ for (index = 0; index < m_PortList.GetSize(); index++) {
87+ m_PortList.GetPort(index, &portNo);
88+ m_KeyboardIndex[portNo] = keyboardIndex;
89+ keyboardIndex++;
90+ if(keyboardIndex == m_KeyboardDesignMod.GetKeyboardMaxDispNum()){
91+ break;
92+ }
9193 }
94+ m_MaxKeyboardIndex = (unsigned char)keyboardIndex;
95+ }
96+ //シングルキーボードの場合
97+ else {
98+ //キーボードデザインをシングルモードに設定
99+ m_KeyboardDesignMod.SetKeyboardSingle();
100+ //ポートとキーボードの対応を1:1に固定
101+ m_KeyboardIndex[0] = 0;
102+ m_MaxKeyboardIndex = 1;
92103 }
93- m_MaxPortIndex = (unsigned char)portIndex;
94104
95105 //トラック取得
96106 result = pSeqData->GetMergedTrack(&track);
@@ -112,7 +122,6 @@ int MTPianoKeyboardCtrlMod::Create(
112122 m_pNotePitchBend = pNotePitchBend;
113123
114124 //シングルキーボードフラグ
115- //※フラグを受け取っても使用しない。ポート別シングルキーボードで常に動作する
116125 m_isSingleKeyboard = isSingleKeyboard;
117126
118127 EXIT:;
@@ -129,23 +138,23 @@ int MTPianoKeyboardCtrlMod::_CreateKeyboards(
129138 )
130139 {
131140 int result = 0;
132- unsigned char portIndex = 0;
141+ unsigned char index = 0;
133142 LPDIRECT3DTEXTURE9 pTexture = NULL;
134143
135- for (portIndex = 0; portIndex < m_MaxPortIndex; portIndex++) {
144+ for (index = 0; index < m_MaxKeyboardIndex; index++) {
136145 try {
137- m_pPianoKeyboard[portIndex] = new MTPianoKeyboardMod;
146+ m_pPianoKeyboard[index] = new MTPianoKeyboardMod;
138147 }
139148 catch (std::bad_alloc) {
140149 result = YN_SET_ERR("Could not allocate memory.", 0, 0);
141150 goto EXIT;
142151 }
143152
144- result = m_pPianoKeyboard[portIndex]->Create(pD3DDevice, pSceneName, pSeqData, pTexture);
153+ result = m_pPianoKeyboard[index]->Create(pD3DDevice, pSceneName, pSeqData, pTexture);
145154 if (result != 0) goto EXIT;
146155
147156 //先頭オブジェクトで作成したテクスチャを再利用する
148- pTexture = m_pPianoKeyboard[portIndex]->GetTexture();
157+ pTexture = m_pPianoKeyboard[index]->GetTexture();
149158 }
150159
151160 EXIT:;
@@ -163,107 +172,52 @@ int MTPianoKeyboardCtrlMod::Transform(
163172 int result = 0;
164173 unsigned char portNo = 0;
165174 unsigned char chNo = 0;
166- D3DXVECTOR3 vectorLU;
167- D3DXVECTOR3 vectorRU;
168- D3DXVECTOR3 vectorLD;
169- D3DXVECTOR3 vectorRD;
170- D3DXVECTOR3 moveVector1;
171- D3DXVECTOR3 moveVector2;
175+ int index;
176+ D3DXVECTOR3 basePosVector;
177+ D3DXVECTOR3 playbackPosVector;
178+
179+ //アクティブポートフラグクリア
180+ for (index = 0; index < SM_MAX_PORT_NUM; index++) {
181+ m_isActivePort[index] = false;
182+ }
172183
173184 //現在発音中ノートの頂点更新
174185 result = _TransformActiveNotes(pD3DDevice);
175186 if (result != 0) goto EXIT;
176187
177- //再生面頂点座標取得
178- m_NoteDesignMod.GetPlaybackSectionVirtexPos(
179- 0,
180- &vectorLU,
181- &vectorRU,
182- &vectorLD,
183- &vectorRD
184- );
185-
186- float boardHeight = vectorLU.y - vectorLD.y;
187- float keyboardWidth = m_KeyboardDesignMod.GetPortOriginX(0) * -2.0f;
188-
189- float rippleSpacing = m_NoteDesignMod.GetRippleSpacing();
190-
191188 //移動ベクトル:再生面に追従する
192- moveVector2 = m_NoteDesignMod.GetWorldMoveVector();
193- moveVector2.x += m_NoteDesignMod.GetPlayPosX(m_CurTickTime);
189+ playbackPosVector = m_NoteDesignMod.GetWorldMoveVector();
190+ playbackPosVector.x += m_NoteDesignMod.GetPlayPosX(m_CurTickTime);
194191
195192 unsigned char lastPortNo = 0;
196193
197- m_PortList.GetPort(m_PortList.GetSize()-1, &lastPortNo);
194+ if (!m_isSingleKeyboard) {
195+ //シングルキーボードでない場合、最終ポート番号を取得
196+ m_PortList.GetPort(m_PortList.GetSize()-1, &lastPortNo);
197+ }
198+ else {
199+ //シングルキーボードの場合、最終ポート番号は0固定
200+ lastPortNo = 0;
201+ }
198202
199203 for(portNo = 0; portNo <= lastPortNo; portNo ++) {
200204
201- int portIndex = m_PortIndex[portNo];
205+ //ポート番号からキーボードインデックスを取得
206+ //シングルキーボードの場合、インデックスは0固定
207+ int keyboardIndex = !m_isSingleKeyboard ? m_KeyboardIndex[portNo] : 0;
202208
203- if(portIndex == -1) {
209+ if(keyboardIndex == -1) {
204210 continue;
205211 }
206212
207- //ピッチベンドシフトの最大量を求める
208- float maxAbsPitchBendShift = 0.0f;
209- float curMaxPitchBendShift = 0.0f;
210-
211- for (chNo = 0; chNo < SM_MAX_CH_NUM; chNo++) {
212-
213- float pitchBendShift = _GetPichBendShiftPosX(portNo, chNo);
214- if(maxAbsPitchBendShift < fabs(pitchBendShift)) {
215-
216- curMaxPitchBendShift = pitchBendShift;
217- maxAbsPitchBendShift = fabs(pitchBendShift);
218- }
219- }
220-
221213 //移動ベクトル:キーボード基準座標
222- moveVector1 = m_KeyboardDesignMod.GetKeyboardBasePos(portIndex, 0, keyboardWidth / boardHeight);
214+ basePosVector = m_KeyboardDesignMod.GetKeyboardBasePos(keyboardIndex, rollAngle);
223215
224216 //移動ベクトル:ピッチベンドシフトを反映
225- moveVector1.x += curMaxPitchBendShift;
226-
227- if(rollAngle < 0.0f) {
228- rollAngle += 360.0f;
229- }
230-
231- float portWidth = m_KeyboardDesignMod.GetChStep() * 16.0f;
232-
233- if((rollAngle > 120.0f) && (rollAngle < 300.0f)) {
234-
235- //鍵盤の1/2の幅だけ高音側に
236- moveVector1.x += m_KeyboardDesignMod.GetWhiteKeyStep() / 2.0f;
237-
238- //ポート原点Y
239- moveVector1.y -= portWidth * (m_PortList.GetSize() - portIndex - 1) * (keyboardWidth / boardHeight);
240-
241- //鍵盤の原点をCh15に
242- moveVector1.y -= m_KeyboardDesignMod.GetChStep() * (keyboardWidth / boardHeight) * 15.0f;
243-
244- //鍵盤の1/4の高さだけ下に
245- moveVector1.y -= m_KeyboardDesignMod.GetWhiteKeyHeight() / 4.0f;
246-
247- //鍵盤の長さ+リップルマージン+歌詞マージンだけ手前に
248- moveVector1.z -= m_KeyboardDesignMod.GetWhiteKeyLen() + rippleSpacing * (MTNOTELYRICS_MAX_LYRICS_NUM + MTNOTERIPPLE_MAX_RIPPLE_NUM) * (keyboardWidth / boardHeight);
249-
250- } else {
251-
252- //鍵盤の1/2の幅だけ高音側に
253- moveVector1.x += m_KeyboardDesignMod.GetWhiteKeyStep() / 2.0f;
254-
255- //ポート原点Y
256- moveVector1.y += portWidth * (m_PortList.GetSize() - portIndex - 1) * (keyboardWidth / boardHeight);
257-
258- //鍵盤の1/4の高さだけ下に
259- moveVector1.y -= m_KeyboardDesignMod.GetWhiteKeyHeight() / 4.0f;
260-
261- //リップルマージン+歌詞マージンだけ奥に
262- moveVector1.z += 0.002f * (MTNOTELYRICS_MAX_LYRICS_NUM + MTNOTERIPPLE_MAX_RIPPLE_NUM) * (keyboardWidth / boardHeight);
263- }
217+ basePosVector.x += GetMaxPitchBendShift(portNo);
264218
265219 //キーボード移動
266- result = m_pPianoKeyboard[portIndex]->Transform(pD3DDevice, moveVector1, moveVector2, boardHeight / keyboardWidth, vectorLU.z, rollAngle);
220+ result = m_pPianoKeyboard[keyboardIndex]->Transform(pD3DDevice, basePosVector, playbackPosVector, rollAngle);
267221 if (result != 0) goto EXIT;
268222 }
269223
@@ -312,8 +266,8 @@ int MTPianoKeyboardCtrlMod::_UpdateNoteStatus(
312266 //ノートOFF後(キー復帰済み)
313267 else {
314268 //ノート情報を破棄
315- //複数チャンネルのキー状態をポート別に集約する
316- result = m_pPianoKeyboard[m_PortIndex[note.portNo]]->ResetKey(note.noteNo);
269+ //発音中のキーをリセットする
270+ result = m_pPianoKeyboard[_GetKeyboardIndexFromNote(note)]->ResetKey(note.noteNo);
317271 if (result != 0) goto EXIT;
318272
319273 pNoteStatus->isActive = false;
@@ -322,6 +276,12 @@ int MTPianoKeyboardCtrlMod::_UpdateNoteStatus(
322276 pNoteStatus->keyDownRate = 0.0f;
323277 }
324278
279+ //状態更新後、発音中であれば
280+ if (pNoteStatus->isActive) {
281+ //アクティブポートフラグを立てる
282+ m_isActivePort[note.portNo] = true;
283+ }
284+
325285 EXIT:;
326286 return result;
327287 }
@@ -338,6 +298,7 @@ int MTPianoKeyboardCtrlMod::_UpdateVertexOfActiveNotes(
338298 unsigned long elapsedTime = 0;
339299 SMNote note;
340300 D3DXCOLOR noteColor;
301+ unsigned char notePortNo;
341302
342303 ZeroMemory(m_KeyDownRateMod, sizeof(float) * SM_MAX_CH_NUM* SM_MAX_CH_NUM * SM_MAX_NOTE_NUM);
343304
@@ -358,21 +319,32 @@ int MTPianoKeyboardCtrlMod::_UpdateVertexOfActiveNotes(
358319
359320 //ノートの色
360321 noteColor = m_NoteDesignMod.GetNoteBoxColor(note.portNo, note.chNo, note.noteNo);
361-
322+
323+ //シングルキーボードでない場合
324+ if (!m_isSingleKeyboard) {
325+ //ノートのポート番号を取得
326+ notePortNo = note.portNo;
327+ }
328+ //シングルキーボードの場合
329+ else {
330+ //ノートのポート番号を0固定に
331+ notePortNo = 0;
332+ }
333+
362334 //発音対象キーを回転
363335 // すでに同一ノートに対して頂点を更新している場合
364336 // 押下率が前回よりも上回る場合に限り頂点を更新する
365- if (m_KeyDownRateMod[note.portNo][note.chNo][note.noteNo] < m_pNoteStatus[i].keyDownRate) {
337+ if (m_KeyDownRateMod[notePortNo][note.chNo][note.noteNo] < m_pNoteStatus[i].keyDownRate) {
366338 //複数チャンネルのキー状態をポート別に集約する
367- result = m_pPianoKeyboard[m_PortIndex[note.portNo]]->PushKey(
368- note.chNo,
369- note.noteNo,
370- m_pNoteStatus[i].keyDownRate,
371- elapsedTime,
372- &noteColor
373- );
339+ result = m_pPianoKeyboard[_GetKeyboardIndexFromNote(note)]->PushKey(
340+ note.chNo,
341+ note.noteNo,
342+ m_pNoteStatus[i].keyDownRate,
343+ elapsedTime,
344+ &noteColor
345+ );
374346 if (result != 0) goto EXIT;
375- m_KeyDownRateMod[note.portNo][note.chNo][note.noteNo] = m_pNoteStatus[i].keyDownRate;
347+ m_KeyDownRateMod[notePortNo][note.chNo][note.noteNo] = m_pNoteStatus[i].keyDownRate;
376348 }
377349 }
378350
@@ -388,19 +360,25 @@ int MTPianoKeyboardCtrlMod::Draw(
388360 )
389361 {
390362 int result = 0;
391- unsigned char portIndex = 0;
363+ unsigned char index = 0;
392364 unsigned long count = 0;
393365 unsigned long dispNum = 0;
394366
395367 if (!m_isEnable) goto EXIT;
396368
369+ //レンダリングステート設定:Zバッファへの書き込みオフ
370+// pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE);
371+
397372 //キーボードの描画
398- for (portIndex = 0; portIndex < m_MaxPortIndex; portIndex++) {
373+ for (index = 0; index < m_MaxKeyboardIndex; index++) {
399374
400- result = m_pPianoKeyboard[portIndex]->Draw(pD3DDevice);
375+ result = m_pPianoKeyboard[index]->Draw(pD3DDevice);
401376 if (result != 0) goto EXIT;
402377 }
403378
379+ //レンダリングステート設定:Zバッファへの書き込みオン
380+// pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);
381+
404382 EXIT:;
405383 return result;
406384 }
@@ -423,8 +401,8 @@ void MTPianoKeyboardCtrlMod::Reset()
423401 result = m_NoteListRT.GetNote(m_pNoteStatus[i].index, &note);
424402 //if (result != 0) goto EXIT;
425403
426- //複数チャンネルのキー状態をポート別に集約する
427- result = m_pPianoKeyboard[m_PortIndex[note.portNo]]->ResetKey(note.noteNo);
404+ //発音中のキーをリセットする
405+ result = m_pPianoKeyboard[_GetKeyboardIndexFromNote(note)]->ResetKey(note.noteNo);
428406 //if (result != 0) goto EXIT;
429407 }
430408 m_pNoteStatus[i].isActive = false;
@@ -435,3 +413,53 @@ void MTPianoKeyboardCtrlMod::Reset()
435413
436414 return;
437415 }
416+
417+int MTPianoKeyboardCtrlMod::_GetKeyboardIndexFromNote(const SMNote &note)
418+{
419+ //シングルキーボードでない場合
420+ if (!m_isSingleKeyboard) {
421+ //ノートのピアノ番号を取得
422+ return m_KeyboardIndex[note.portNo];
423+ }
424+ //シングルキーボードの場合
425+ else {
426+ //ノートのピアノ番号を0固定に
427+ return 0;
428+ }
429+}
430+
431+//******************************************************************************
432+// ピッチベンドシフトの最大量を求める
433+//******************************************************************************
434+float MTPianoKeyboardCtrlMod::GetMaxPitchBendShift(unsigned char portNo) {
435+
436+ float max = 0.0f;
437+ float cur = 0.0f;
438+
439+ //シングルキーボードでない場合、指定のポート番号から求める
440+ //シングルキーボードの場合、シーケンスに含まれるポート番号すべてから求める
441+ int portListSize = !m_isSingleKeyboard ? 1 : m_PortList.GetSize();
442+
443+ for (int i = 0; i < portListSize; i++) {
444+
445+ if (m_isSingleKeyboard) {
446+ m_PortList.GetPort(i, &portNo);
447+ }
448+
449+ if (!m_isActivePort[portNo]) {
450+ continue;
451+ }
452+
453+ for (unsigned char chNo = 0; chNo < SM_MAX_CH_NUM; chNo++) {
454+
455+ float pitchBendShift = _GetPichBendShiftPosX(portNo, chNo);
456+ if(max < fabs(pitchBendShift)) {
457+
458+ cur = pitchBendShift;
459+ max = fabs(pitchBendShift);
460+ }
461+ }
462+ }
463+
464+ return cur;
465+}
\ No newline at end of file
--- a/MIDITrail/MTPianoKeyboardCtrlMod.h
+++ b/MIDITrail/MTPianoKeyboardCtrlMod.h
@@ -58,8 +58,13 @@ private:
5858
5959 //ポートリスト
6060 SMPortList m_PortList;
61- int m_PortIndex[SM_MAX_PORT_NUM];
62- unsigned char m_MaxPortIndex;
61+
62+ //アクティブポートフラグ
63+ bool m_isActivePort[SM_MAX_PORT_NUM];
64+
65+ //キーボードインデックス
66+ int m_KeyboardIndex[SM_MAX_PORT_NUM];
67+ unsigned char m_MaxKeyboardIndex;
6368
6469 //キー押下率配列
6570 float m_KeyDownRateMod[SM_MAX_CH_NUM][SM_MAX_CH_NUM][SM_MAX_NOTE_NUM];
@@ -73,6 +78,9 @@ private:
7378 );
7479 virtual int _UpdateVertexOfActiveNotes(LPDIRECT3DDEVICE9 pD3DDevice);
7580
81+ int _GetKeyboardIndexFromNote(const SMNote &note);
82+
83+ float GetMaxPitchBendShift(unsigned char portNo);
7684 };
7785
7886
--- a/MIDITrail/MTPianoKeyboardDesign.cpp
+++ b/MIDITrail/MTPianoKeyboardDesign.cpp
@@ -916,6 +916,16 @@ unsigned long MTPianoKeyboardDesign::GetKeyboardMaxDispNum()
916916 return (unsigned long)m_KeyboardMaxDispNum;
917917 }
918918
919+// >>> add 20180404 yossiepon begin
920+//******************************************************************************
921+// キーボード表示数設定
922+//******************************************************************************
923+void MTPianoKeyboardDesign::SetKeyboardSingle()
924+{
925+ m_KeyboardMaxDispNum = 1;
926+}
927+// <<< add 20180404 yossiepon end
928+
919929 //******************************************************************************
920930 // キー表示範囲:開始
921931 //******************************************************************************
--- a/MIDITrail/MTPianoKeyboardDesign.h
+++ b/MIDITrail/MTPianoKeyboardDesign.h
@@ -67,10 +67,8 @@ public:
6767
6868 //ポート原点座標取得
6969 float GetPortOriginX(unsigned char portNo);
70-// >>> modify 20120728 yossiepon begin
71- virtual float GetPortOriginY(unsigned char portNo);
72- virtual float GetPortOriginZ(unsigned char portNo);
73-// <<< modify 20120728 yossiepon end
70+ float GetPortOriginY(unsigned char portNo);
71+ float GetPortOriginZ(unsigned char portNo);
7472
7573 //キー種別取得
7674 KeyType GetKeyType(unsigned char noteNo);
@@ -182,13 +180,15 @@ public:
182180 );
183181
184182 //キーボード基準座標取得
185-// >>> modify 20120728 yossiepon begin
186- virtual D3DXVECTOR3 GetKeyboardBasePos(unsigned char portNo, unsigned char chNo);
187-// <<< modify 20120728 yossiepon end
183+ D3DXVECTOR3 GetKeyboardBasePos(unsigned char portNo, unsigned char chNo);
188184
189185 //キーボード最大表示数取得
190186 unsigned long GetKeyboardMaxDispNum();
191187
188+// >>> add 20180404 yossiepon begin
189+ void SetKeyboardSingle();
190+// <<< add 20180404 yossiepon end
191+
192192 //キー表示範囲取得
193193 unsigned char GetKeyDispRangeStart();
194194 unsigned char GetKeyDispRangeEnd();
--- a/MIDITrail/MTPianoKeyboardDesignMod.cpp
+++ b/MIDITrail/MTPianoKeyboardDesignMod.cpp
@@ -12,6 +12,8 @@
1212 #include "DXColorUtil.h"
1313 #include "MTConfFile.h"
1414 #include "MTPianoKeyboardDesignMod.h"
15+#include "MTNoteRippleMod.h"
16+#include "MTNoteLyrics.h"
1517
1618
1719 //******************************************************************************
@@ -75,24 +77,209 @@ void MTPianoKeyboardDesignMod::_Initialize()
7577 }
7678
7779 //******************************************************************************
80+// キーボード基準座標取得
81+//******************************************************************************
82+D3DXVECTOR3 MTPianoKeyboardDesignMod::GetKeyboardBasePos(
83+ int keyboardIndex,
84+ float angle
85+ )
86+{
87+ float ox, oy, oz = 0.0f;
88+
89+ //ロール角度によって描画方法を切り替える
90+ angle += angle < 0.0f ? 360.0f : 0.0f;
91+ bool flip = !((angle > 120.0f) && (angle < 300.0f));
92+
93+ //ポート単位の原点座標
94+ ox = GetPortOriginX();
95+ oy = GetPortOriginY(keyboardIndex, flip);
96+ oz = GetPortOriginZ(keyboardIndex, flip);
97+
98+ return D3DXVECTOR3(ox, oy, oz);
99+}
100+
101+//******************************************************************************
102+// ポート原点X座標取得
103+//******************************************************************************
104+float MTPianoKeyboardDesignMod::GetPortOriginX()
105+{
106+ // angle: 120°〜300°(rotateX: 90°, rotateZ: 90°)
107+ // +z
108+ // |
109+ // -x<----------0---------->+x
110+ // | -RippleMargin
111+ // +----+----+
112+ // | | | @:OriginX
113+ // | | |
114+ // | | |
115+ // | | |
116+ // @----+----+
117+ // Note #0 | #127
118+ // -z
119+
120+ // angle: 0°〜120°or 300°〜360°(rotateX: -90°, rotateZ: 90°)
121+ // +z
122+ // |
123+ // Note #0 | #127
124+ // +----+----+
125+ // | | | @:OriginX
126+ // | | |
127+ // | | |
128+ // | | |
129+ // @----+----+
130+ // | +RippleMargin
131+ // -x<----------0---------->+x
132+ // |
133+ // -z
134+
135+ float originX = -GetPlaybackSectionHeight() / 2.0f;
136+
137+ //鍵盤の1/2の幅だけ高音側に移動
138+ originX += GetWhiteKeyStep() * GetKeyboardResizeRatio() / 2.0f;
139+
140+ return originX;
141+}
142+
143+//******************************************************************************
78144 // ポート原点Y座標取得
79145 //******************************************************************************
80146 float MTPianoKeyboardDesignMod::GetPortOriginY(
81- unsigned char portNo
147+ int keyboardIndex,
148+ bool flip
82149 )
83150 {
84- return 0;
151+ // angle: 120°〜300°(rotateX: 90°, rotateZ: 90°)
152+ // +y
153+ // |
154+ // | Ch.15
155+ // |
156+ // | +--------------+
157+ // | portC +--------------@ Ch.0
158+ // | Ch.15
159+ // |
160+ // +z<---0---------------------------------------------->-z
161+ // | +--------------+
162+ // | portB +--------------@ Ch.0
163+ // | Ch.15
164+ // |
165+ // | +--------------+ @:OriginY(for portA,B,C)
166+ // | portA +--------------@ Ch.0
167+ // |
168+ // -y
169+
170+ // angle: 0°〜120°or 300°〜360°(rotateX: -90°, rotateZ: 90°)
171+ // +y
172+ // Ch.15 |
173+ // |
174+ // +--------------+ |
175+ // portA +--------------@ Ch.0 |
176+ // Ch.15 |
177+ // |
178+ // +z<----------------------------------------0-------------->-z
179+ // +--------------+ |
180+ // portB +--------------@ Ch.0 |
181+ // Ch.15 |
182+ // |
183+ // +--------------+ |
184+ // portC +--------------@ Ch.0 |
185+ // |
186+ // | @:OriginY(for portA,B,C)
187+ // -y
188+
189+ float portWidth = GetPortWidth();
190+
191+ // TODO シングルキーボードの判定方法を再検討
192+ int keyboardDispNum = GetKeyboardMaxDispNum() > 1 ? m_PortList.GetSize() : 1;
193+
194+ float originY;
195+
196+ if (!flip) {
197+ originY = -portWidth * (float)(keyboardDispNum - keyboardIndex * 2) / 2.0f;
198+
199+ //チャネル間隔の62.5%の高さだけ下に
200+ originY -= GetChStep() * 0.625f;
201+ }
202+ else {
203+ originY = portWidth * (float)(keyboardDispNum - (keyboardIndex + 1) * 2) / 2.0f;
204+
205+ //チャネル間隔の37.5%の高さだけ上に
206+ originY += GetChStep() * 0.375f;
207+ }
208+
209+ return originY;
85210 }
86211
87212 //******************************************************************************
88213 // ポート原点Z座標取得
89214 //******************************************************************************
90215 float MTPianoKeyboardDesignMod::GetPortOriginZ(
91- unsigned char portNo
216+ int keyboardIndex,
217+ bool flip
92218 )
93219 {
220+ // angle: 120°〜300°(rotateX: 90°, rotateZ: 90°)
221+ // +z
222+ // |
223+ // -x<----------0---------->+x
224+ // | -RippleMargin
225+ // +----+----+
226+ // | | | @:OriginZ
227+ // | | |
228+ // | | |
229+ // | | |
230+ // @----+----+
231+ // Note #0 | #127
232+ // -z
233+
234+ // angle: 0°〜120°or 300°〜360°(rotateX: -90°, rotateZ: 90°)
235+ // +z
236+ // |
237+ // Note #0 | #127
238+ // +----+----+
239+ // | | | @:OriginZ
240+ // | | |
241+ // | | |
242+ // | | |
243+ // @----+----+
244+ // | +RippleMargin
245+ // -x<----------0---------->+x
246+ // |
247+ // -z
248+
249+ float originZ;
250+
251+ if (!flip) {
252+ originZ = -(GetWhiteKeyLen() * GetKeyboardResizeRatio() + GetRippleMargin());
253+ }
254+ else {
255+ originZ = GetRippleMargin();
256+ }
94257
95- return 0;
258+ return originZ;
259+}
260+
261+//******************************************************************************
262+// ノートボックス高さ取得
263+//******************************************************************************
264+float MTPianoKeyboardDesignMod::GetNoteBoxHeight()
265+{
266+ return m_NoteBoxHeight;
267+}
268+
269+//******************************************************************************
270+// ノートボックス幅取得
271+//******************************************************************************
272+float MTPianoKeyboardDesignMod::GetNoteBoxWidth()
273+{
274+ return m_NoteBoxWidth;
275+}
276+
277+//******************************************************************************
278+// ノート間隔取得
279+//******************************************************************************
280+float MTPianoKeyboardDesignMod::GetNoteStep()
281+{
282+ return m_NoteStep;
96283 }
97284
98285 //******************************************************************************
@@ -104,6 +291,95 @@ float MTPianoKeyboardDesignMod::GetChStep()
104291 }
105292
106293 //******************************************************************************
294+// キーボード高さ取得
295+//******************************************************************************
296+float MTPianoKeyboardDesignMod::GetKeyboardHeight()
297+{
298+ return GetBlackKeyHeight();
299+}
300+
301+//******************************************************************************
302+// キーボード幅取得
303+//******************************************************************************
304+float MTPianoKeyboardDesignMod::GetKeyboardWidth()
305+{
306+ return GetWhiteKeyStep() * (float)(SM_MAX_NOTE_NUM - 53);
307+}
308+
309+//******************************************************************************
310+// グリッド高さ取得
311+//******************************************************************************
312+float MTPianoKeyboardDesignMod::GetGridHeight()
313+{
314+ return GetNoteStep() * 127.0f;
315+}
316+
317+//******************************************************************************
318+// グリッド幅取得
319+//******************************************************************************
320+float MTPianoKeyboardDesignMod::GetGridWidth()
321+{
322+ return GetChStep() * 15.0f;
323+}
324+
325+//******************************************************************************
326+// ポート高さ取得
327+//******************************************************************************
328+float MTPianoKeyboardDesignMod::GetPortHeight()
329+{
330+ return GetGridHeight();
331+}
332+
333+//******************************************************************************
334+// ポート幅取得
335+//******************************************************************************
336+float MTPianoKeyboardDesignMod::GetPortWidth()
337+{
338+ return GetChStep() * 16.0f;
339+}
340+
341+//******************************************************************************
342+// 再生面高さ取得
343+//******************************************************************************
344+float MTPianoKeyboardDesignMod::GetPlaybackSectionHeight()
345+{
346+ return GetGridHeight() + GetNoteBoxHeight();
347+}
348+
349+//******************************************************************************
350+// 再生面幅取得
351+//******************************************************************************
352+float MTPianoKeyboardDesignMod::GetPlaybackSectionWidth()
353+{
354+ return GetGridWidth() + GetNoteBoxWidth();
355+}
356+
357+//******************************************************************************
358+// 波紋描画間隔取得
359+//******************************************************************************
360+float MTPianoKeyboardDesignMod::GetRippleSpacing()
361+{
362+ return m_RippleSpacing;
363+}
364+
365+//******************************************************************************
366+// 波紋描画マージン取得
367+//******************************************************************************
368+float MTPianoKeyboardDesignMod::GetRippleMargin()
369+{
370+ return GetRippleSpacing() * (MTNOTELYRICS_MAX_LYRICS_NUM + MTNOTERIPPLE_MAX_RIPPLE_NUM);
371+}
372+
373+//******************************************************************************
374+// キーボードリサイズ比取得
375+//******************************************************************************
376+float MTPianoKeyboardDesignMod::GetKeyboardResizeRatio()
377+{
378+ //キーボード基準の相対座標に適用するリサイズ比
379+ return GetPlaybackSectionHeight() / GetKeyboardWidth();
380+}
381+
382+//******************************************************************************
107383 // 発音中キーカラー取得
108384 //******************************************************************************
109385 D3DXCOLOR MTPianoKeyboardDesignMod::GetActiveKeyColor(
@@ -168,25 +444,6 @@ D3DXCOLOR MTPianoKeyboardDesignMod::GetActiveKeyColor(
168444 }
169445
170446 //******************************************************************************
171-// キーボード基準座標取得
172-//******************************************************************************
173-D3DXVECTOR3 MTPianoKeyboardDesignMod::GetKeyboardBasePos(
174- unsigned char portNo,
175- unsigned char chNo,
176- float scale
177- )
178-{
179- float ox, oy, oz = 0.0f;
180-
181- //ポート単位の原点座標
182- ox = GetPortOriginX(portNo);
183- oy = GetPortOriginY(portNo);
184- oz = GetPortOriginZ(portNo);
185-
186- return D3DXVECTOR3(ox, oy, oz);
187-}
188-
189-//******************************************************************************
190447 // 設定ファイル読み込み
191448 //******************************************************************************
192449 int MTPianoKeyboardDesignMod::_LoadConfFile(
@@ -212,6 +469,13 @@ int MTPianoKeyboardDesignMod::_LoadConfFile(
212469 //----------------------------------
213470 result = confFile.SetCurSection(_T("Scale"));
214471 if (result != 0) goto EXIT;
472+
473+ result = confFile.GetFloat(_T("NoteBoxHeight"), &m_NoteBoxHeight, 0.1f);
474+ if (result != 0) goto EXIT;
475+ result = confFile.GetFloat(_T("NoteBoxWidth"), &m_NoteBoxWidth, 0.1f);
476+ if (result != 0) goto EXIT;
477+ result = confFile.GetFloat(_T("NoteStep"), &m_NoteStep, 0.1f);
478+ if (result != 0) goto EXIT;
215479 result = confFile.GetFloat(_T("ChStep"), &m_ChStep, 0.5f);
216480 if (result != 0) goto EXIT;
217481
@@ -230,6 +494,16 @@ int MTPianoKeyboardDesignMod::_LoadConfFile(
230494 m_ActiveKeyColorList[i] = DXColorUtil::MakeColorFromHexRGBA(hexColor);
231495 }
232496
497+ //----------------------------------
498+ //波紋情報
499+ //----------------------------------
500+ result = confFile.SetCurSection(_T("Ripple"));
501+ if (result != 0) goto EXIT;
502+
503+ //波紋描画間隔
504+ result = confFile.GetFloat(_T("Spacing"), &m_RippleSpacing, 0.002f);
505+ if (result != 0) goto EXIT;
506+
233507 EXIT:;
234508 return result;
235509 }
--- a/MIDITrail/MTPianoKeyboardDesignMod.h
+++ b/MIDITrail/MTPianoKeyboardDesignMod.h
@@ -27,13 +27,52 @@ public:
2727 //初期化
2828 virtual int Initialize(const TCHAR* pSceneName, SMSeqData* pSeqData);
2929
30+ //キーボード基準座標取得
31+ D3DXVECTOR3 GetKeyboardBasePos(
32+ int keyboardIndex,
33+ float angle
34+ );
35+
3036 //ポート原点座標取得
31- virtual float GetPortOriginY(unsigned char portNo);
32- virtual float GetPortOriginZ(unsigned char portNo);
37+ float GetPortOriginX();
38+ float GetPortOriginY(int keyboardIndex, bool flip);
39+ float GetPortOriginZ(int keyboardIndex, bool flip);
40+
41+ //ノートボックス高さ・幅取得
42+ float GetNoteBoxHeight();
43+ float GetNoteBoxWidth();
44+
45+ //ノート間隔取得
46+ float GetNoteStep();
3347
3448 //チャンネル間隔取得
3549 float GetChStep();
3650
51+ //キーボード高さ・幅取得
52+ float GetKeyboardHeight();
53+ float GetKeyboardWidth();
54+
55+ //グリッド高さ・幅取得
56+ float GetGridHeight();
57+ float GetGridWidth();
58+
59+ //ポート高さ・幅取得
60+ float GetPortHeight();
61+ float GetPortWidth();
62+
63+ //再生面高さ・幅取得
64+ float GetPlaybackSectionHeight();
65+ float GetPlaybackSectionWidth();
66+
67+ //波紋描画間隔取得
68+ float GetRippleSpacing();
69+
70+ //波紋描画マージン取得
71+ float GetRippleMargin();
72+
73+ //キーボードリサイズ比取得
74+ float GetKeyboardResizeRatio();
75+
3776 //発音中キーカラー取得
3877 D3DXCOLOR GetActiveKeyColor(
3978 unsigned char chNo,
@@ -42,9 +81,6 @@ public:
4281 D3DXCOLOR* pNoteColor = NULL
4382 );
4483
45- //キーボード基準座標取得
46- virtual D3DXVECTOR3 GetKeyboardBasePos(unsigned char portNo, unsigned char chNo, float scale);
47-
4884 protected:
4985
5086 virtual void _Initialize();
@@ -52,9 +88,18 @@ protected:
5288
5389 private:
5490
91+ //ノートボックス高さ
92+ float m_NoteBoxHeight;
93+ //ノートボックス幅
94+ float m_NoteBoxWidth;
95+ //ノート間隔
96+ float m_NoteStep;
5597 //チャンネル間隔
5698 float m_ChStep;
5799
100+ //波紋描画間隔
101+ float m_RippleSpacing;
102+
58103 //発音中キー色情報
59104 D3DXCOLOR m_ActiveKeyColorList[16];
60105
--- a/MIDITrail/MTPianoKeyboardMod.cpp
+++ b/MIDITrail/MTPianoKeyboardMod.cpp
@@ -77,10 +77,8 @@ EXIT:;
7777 //******************************************************************************
7878 int MTPianoKeyboardMod::Transform(
7979 LPDIRECT3DDEVICE9 pD3DDevice,
80- D3DXVECTOR3 moveVector1,
81- D3DXVECTOR3 moveVector2,
82- float scale,
83- float z,
80+ D3DXVECTOR3 basePosVector,
81+ D3DXVECTOR3 playbackPosVector,
8482 float rollAngle
8583 )
8684 {
@@ -89,21 +87,17 @@ int MTPianoKeyboardMod::Transform(
8987 D3DXMATRIX rotateMatrix1;
9088 D3DXMATRIX rotateMatrix2;
9189 D3DXMATRIX rotateMatrix3;
92- D3DXMATRIX moveMatrix1;
93- D3DXMATRIX moveMatrix2;
94- D3DXMATRIX moveMatrix3;
95- D3DXMATRIX worldMatrix1;
96- D3DXMATRIX worldMatrix2;
90+ D3DXMATRIX basePosMatrix;
91+ D3DXMATRIX playbackPosMatrix;
92+ D3DXMATRIX worldMatrix;
9793
9894 //行列初期化
9995 D3DXMatrixIdentity(&scaleMatrix);
10096 D3DXMatrixIdentity(&rotateMatrix1);
10197 D3DXMatrixIdentity(&rotateMatrix2);
102- D3DXMatrixIdentity(&rotateMatrix3);
103- D3DXMatrixIdentity(&moveMatrix1);
104- D3DXMatrixIdentity(&moveMatrix2);
105- D3DXMatrixIdentity(&worldMatrix1);
106- D3DXMatrixIdentity(&worldMatrix2);
98+ D3DXMatrixIdentity(&basePosMatrix);
99+ D3DXMatrixIdentity(&playbackPosMatrix);
100+ D3DXMatrixIdentity(&worldMatrix);
107101
108102 //回転行列
109103
@@ -112,33 +106,33 @@ int MTPianoKeyboardMod::Transform(
112106 }
113107
114108 if((rollAngle > 120.0f) && (rollAngle < 300.0f)) {
115- D3DXMatrixRotationX(&rotateMatrix1, D3DXToRadian(90.0f));
116- D3DXMatrixRotationZ(&rotateMatrix2, D3DXToRadian(90.0f));
109+ D3DXMatrixRotationX(&rotateMatrix1, D3DX_PI / 2.0f);
110+ D3DXMatrixRotationZ(&rotateMatrix2, D3DX_PI / 2.0f);
117111 } else {
118- D3DXMatrixRotationX(&rotateMatrix1, D3DXToRadian(-90.0f));
119- D3DXMatrixRotationZ(&rotateMatrix2, D3DXToRadian(90.0f));
112+ D3DXMatrixRotationX(&rotateMatrix1, -D3DX_PI / 2.0f);
113+ D3DXMatrixRotationZ(&rotateMatrix2, D3DX_PI / 2.0f);
120114 }
121115
122116 D3DXMatrixRotationX(&rotateMatrix3, D3DXToRadian(rollAngle));
123117
124118 //移動行列
125- D3DXMatrixTranslation(&moveMatrix1, moveVector1.x, moveVector1.y, moveVector1.z);
126- D3DXMatrixTranslation(&moveMatrix2, moveVector2.x, moveVector2.y, moveVector2.z);
127- D3DXMatrixTranslation(&moveMatrix3, 0.0f, 0.0f, z / scale);
119+ D3DXMatrixTranslation(&basePosMatrix, basePosVector.x, basePosVector.y, basePosVector.z);
120+ D3DXMatrixTranslation(&playbackPosMatrix, playbackPosVector.x, playbackPosVector.y, playbackPosVector.z);
128121
129122 //スケール行列
123+ float scale = m_KeyboardDesignMod.GetKeyboardResizeRatio();
130124 D3DXMatrixScaling(&scaleMatrix, scale, scale, scale);
131125
132- //行列の合成:ピッチベンド移動1→鍵盤向き補正回転1・2→グリッド面まで移動3→ホイール回転3→スケール→再生面追従移動2
133- D3DXMatrixMultiply(&worldMatrix1, &moveMatrix1, &rotateMatrix1);
134- D3DXMatrixMultiply(&worldMatrix2, &worldMatrix1, &rotateMatrix2);
135- D3DXMatrixMultiply(&worldMatrix1, &worldMatrix2, &moveMatrix3);
136- D3DXMatrixMultiply(&worldMatrix2, &worldMatrix1, &rotateMatrix3);
137- D3DXMatrixMultiply(&worldMatrix1, &worldMatrix2, &scaleMatrix);
138- D3DXMatrixMultiply(&worldMatrix2, &worldMatrix1, &moveMatrix2);
126+ //行列の合成:スケール→原点移動→回転1・2(鍵盤向き補正)→回転3(ホイール角度)→再生位置追従移動
127+ D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &scaleMatrix);
128+ D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &basePosMatrix);
129+ D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &rotateMatrix1);
130+ D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &rotateMatrix2);
131+ D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &rotateMatrix3);
132+ D3DXMatrixMultiply(&worldMatrix, &worldMatrix, &playbackPosMatrix);
139133
140134 //変換行列設定
141- m_PrimitiveKeyboard.Transform(worldMatrix2);
135+ m_PrimitiveKeyboard.Transform(worldMatrix);
142136
143137 //EXIT:;
144138 return result;
--- a/MIDITrail/MTPianoKeyboardMod.h
+++ b/MIDITrail/MTPianoKeyboardMod.h
@@ -34,7 +34,12 @@ public:
3434 );
3535
3636 //更新
37- virtual int Transform(LPDIRECT3DDEVICE9 pD3DDevice, D3DXVECTOR3 moveVector1, D3DXVECTOR3 moveVector2, float scale, float z, float rollAngle);
37+ int Transform(
38+ LPDIRECT3DDEVICE9 pD3DDevice,
39+ D3DXVECTOR3 basePosVector,
40+ D3DXVECTOR3 playbackPosVector,
41+ float rollAngle
42+ );
3843
3944 //キー状態変更
4045 virtual int PushKey(
--- a/MIDITrail/MTScene.h
+++ b/MIDITrail/MTScene.h
@@ -34,7 +34,11 @@ public:
3434 EffectStars,
3535 EffectCounter,
3636 EffectBackgroundImage,
37- EffectFileName
37+ EffectFileName,
38+// >>> add 20180404 yossiepon begin
39+ EffectTimeIndicator,
40+ EffectGridBox,
41+// <<< add 20180404 yossiepon end
3842 };
3943
4044 typedef std::map<std::string, float> MTViewParamMap;
--- a/MIDITrail/MTScenePianoRoll2DMod.cpp
+++ b/MIDITrail/MTScenePianoRoll2DMod.cpp
@@ -17,6 +17,7 @@
1717 //******************************************************************************
1818 MTScenePianoRoll2DMod::MTScenePianoRoll2DMod(void)
1919 {
20+ m_IsSingleKeyboard = true;
2021 }
2122
2223 //******************************************************************************
--- a/MIDITrail/MTScenePianoRoll3DMod.cpp
+++ b/MIDITrail/MTScenePianoRoll3DMod.cpp
@@ -388,6 +388,14 @@ void MTScenePianoRoll3DMod::SetEffect(
388388 case EffectBackgroundImage:
389389 m_BackgroundImage.SetEnable(isEnable);
390390 break;
391+// >>> add 20180404 yossiepon begin
392+ case EffectTimeIndicator:
393+ m_TimeIndicator.SetEnable(isEnable);
394+ break;
395+ case EffectGridBox:
396+ m_GridBoxMod.SetEnable(isEnable);
397+ break;
398+// <<< add 20180404 yossiepon end
391399 default:
392400 break;
393401 }
--- a/MIDITrail/MTTimeIndicator.cpp
+++ b/MIDITrail/MTTimeIndicator.cpp
@@ -23,6 +23,9 @@ MTTimeIndicator::MTTimeIndicator(void)
2323 m_CurPos = 0.0f;
2424 m_CurTickTime = 0;
2525 m_isEnableLine = false;
26+// >>> add 20180404 yossiepon begin
27+ m_isEnable = true;
28+// <<< add 20180404 yossiepon end
2629 }
2730
2831 //******************************************************************************
@@ -203,6 +206,12 @@ int MTTimeIndicator::Draw(
203206 {
204207 int result = 0;
205208
209+// >>> add 20180404 yossiepon begin
210+
211+ if (!m_isEnable) goto EXIT;
212+
213+// <<< add 20180404 yossiepon end
214+
206215 // >>> add 20120728 yossiepon begin
207216
208217 //テクスチャステージ設定
@@ -377,3 +386,12 @@ D3DXVECTOR3 MTTimeIndicator::GetMoveVector()
377386 return D3DXVECTOR3(m_CurPos, 0.0f, 0.0f);
378387 }
379388
389+//******************************************************************************
390+// 表示設定
391+//******************************************************************************
392+void MTTimeIndicator::SetEnable(
393+ bool isEnable
394+ )
395+{
396+ m_isEnable = isEnable;
397+}
--- a/MIDITrail/MTTimeIndicator.h
+++ b/MIDITrail/MTTimeIndicator.h
@@ -57,6 +57,11 @@ public:
5757 //移動ベクトル取得
5858 D3DXVECTOR3 GetMoveVector();
5959
60+// >>> add 20180404 yossiepon begin
61+ //表示設定
62+ void SetEnable(bool isEnable);
63+// <<< add 20180404 yossiepon end
64+
6065 private:
6166
6267 DXPrimitive m_Primitive;
@@ -65,6 +70,11 @@ private:
6570 MTNoteDesign m_NoteDesign;
6671 bool m_isEnableLine;
6772
73+// >>> add 20180404 yossiepon begin
74+ //表示可否
75+ bool m_isEnable;
76+// <<< add 20180404 yossiepon end
77+
6878 unsigned long m_CurTickTime;
6979
7080 //頂点バッファ構造体
--- a/MIDITrail/resource.h
+++ b/MIDITrail/resource.h
@@ -68,7 +68,13 @@
6868 #define IDM_ADD_FILE 32837
6969 // <<< add 20120728 yossiepon end
7070 #define IDM_AUTO_SAVE_VIEWPOINT 32838
71+// >>> add 20180404 yossiepon begin
72+#define IDM_ENABLE_GRIDBOX 32839
73+// <<< add 20180404 yossiepon end
7174 #define IDM_VIEW_PIANOROLLRAIN2D 32840
75+// >>> add 20180404 yossiepon begin
76+#define IDM_ENABLE_TIMEINDICATOR 32841
77+// <<< add 20180404 yossiepon end
7278 #define IDM_ENABLE_BACKGROUNDIMAGE 32842
7379 #define IDC_STATIC -1
7480
--- a/MIDITrail/template/conf/PianoRoll2D.ini
+++ b/MIDITrail/template/conf/PianoRoll2D.ini
@@ -64,7 +64,11 @@ SizeRatio=1.4
6464 ;Duration=1600
6565 DecayDuration=100
6666 ReleaseDuration=250
67+;-- D3dBlendType : ZERO=1, ONE=2, SRCALPHA=5, INVSRCALPHA=6, DESTALPHA=7, INVDESTALPHA=8
68+SrcBlend=5
69+DestBlend=2
6770 OverwriteTimes=3
71+;-- e.g.) BlackBG : Src/Dest/Overwrite = 5/2/3, PictureBG : Src/Dest/Overwrite = 5/2/1
6872 Spacing=0.002
6973
7074 [Stars]
--- a/MIDITrail/template/conf/PianoRoll3D.ini
+++ b/MIDITrail/template/conf/PianoRoll3D.ini
@@ -64,7 +64,11 @@ SizeRatio=1.4
6464 ;Duration=1600
6565 DecayDuration=100
6666 ReleaseDuration=250
67+;-- D3dBlendType : ZERO=1, ONE=2, SRCALPHA=5, INVSRCALPHA=6, DESTALPHA=7, INVDESTALPHA=8
68+SrcBlend=5
69+DestBlend=2
6770 OverwriteTimes=3
71+;-- e.g.) BlackBG : Src/Dest/Overwrite = 5/2/3, PictureBG : Src/Dest/Overwrite = 5/2/1
6872 Spacing=0.002
6973
7074 [Stars]
--- a/readme_mod_yossiepon.txt
+++ b/readme_mod_yossiepon.txt
@@ -1,24 +1,36 @@
11 ピカピカMIDITrail 鍵盤方向自動切替・多ポート・歌詞対応等
22
3-MIDITrail 1.2.3 mod. yossiepon_20180404
3+MIDITrail 1.2.3 mod. yossiepon_20180412
44 mail: yoshy@users.sourceforge.jp
55
6-改造点 20180404:
7-・1.2.3をマージ
6+改造点 20180412:
7+・[UPDATE] 1.2.3をマージ
8+・[ADD] リップルと背景画像のブレンド方法を指定できる設定を追加
9+ →INIファイル中のRippleセクション SrcBlendおよびDestBlend
10+・[FIX] 多ポートのシーケンスでPianoRoll2Dのキーボードが1つに集約されない不具合を修正
11+・[FIX] PianoRoll3Dで多ポート時のキーボード基準位置がずれている不具合を修正
812
913 改造点 20170528:
10-・シーケンス中のテキスト取得時にRTRIMをかけるように修正
11-・タイトルがない場合にファイル名を表示するように修正
14+・[FIX] タイトル(シーケンス名)が空の場合、ファイル名を代替表示するよう修正
15+・[FIX] シーケンス中のテキスト取得時にRTRIMをかけるように修正
16+
17+改造点 20161226:
18+・[FIX] original 1.2.1 からの取り込みを保留していた機能を反映
19+ #30547 機能追加:音階色指定
20+ #32427 機能追加:押下状態のキーにノートの色を反映する
21+・[UPDATE] PianoRoll2D/3DMod : ActiveKeyColorType=NOTE に対応
22+・[ADD] 波紋上書き回数および波紋間の描画間隔を指定できる設定を追加
23+ →INIファイル中のRippleセクション OverwriteTimesおよびSpacing
1224
1325 改造点 20161223:
14-・1.2.2をベースに再マージ
26+・[UPDATE] 1.2.2をベースに再マージ
1527
1628 改造点 20140920:
17-・1.2.1bをベースに再マージ(とりあえず動く程度)
18-・x64版のバイナリを追加
29+・[UPDATE] 1.2.1bをベースに再マージ(とりあえず動く程度)
30+・[ADD] x64版のバイナリを追加
1931
2032 改造点 20121229:
21-・PianoRoll3D: 逆方向にライトを追加しました
33+・[ADD] PianoRoll3D: 逆方向にライトを追加しました
2234
2335 改造点 20120728-30:
2436 ・改造箇所をなるべく別ソースに出すように作り直した