3554 lines
94 KiB
C++
3554 lines
94 KiB
C++
//---------------------------------------------------------------------------
|
|
#include <vcl.h>
|
|
#include <Vcl.Imaging.pngimage.hpp>
|
|
#pragma hdrstop
|
|
|
|
#include "GlobalUnit.h"
|
|
#include "UseStylePanel.h"
|
|
#include "MidiTrack.h"
|
|
#include "Undo.h"
|
|
#include "SwitchProgFormUnit.h"
|
|
#include "SwitchTextureForm.h"
|
|
//---------------------------------------------------------------------------
|
|
#pragma package(smart_init)
|
|
|
|
extern int w_xOffDrag, //图片左上角与鼠标距离
|
|
w_yOffDrag;
|
|
|
|
__fastcall TUseStylePanel::TUseStylePanel(TComponent* AOwner)
|
|
: TStylePanel(AOwner)
|
|
{
|
|
m_pContentPanel = NULL;
|
|
m_pPlayTimer = NULL;
|
|
m_bAddWeakupBar = true;
|
|
|
|
m_strTitle = "使用风格";
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::ClearAllItems()
|
|
{
|
|
TStylePanel::ClearAllItems();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::CountTotalLine()
|
|
{
|
|
m_nTotalLine = 0;
|
|
|
|
if( m_pTopItem ){
|
|
//计算总行数
|
|
TCommonItem* pItem = m_pTopItem;
|
|
while( pItem ){ //所有显示的子孙项
|
|
m_nTotalLine++;
|
|
pItem = GetNextItem( pItem );
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool __fastcall TUseStylePanel::Charge4Fonts()
|
|
{
|
|
for( int i=g_aMidiTracks.size()-1; i>=0; i-- ){
|
|
if( g_aMidiTracks[i]->bank!=0xFF ){
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::DoChangeFontProg(TObject* Sender)
|
|
{
|
|
Stop( STOP_ALL );
|
|
|
|
if( Sender )
|
|
SetSelect( m_pFocItem, m_iFocLine );
|
|
|
|
TTrackItem *pItem = (TTrackItem *)m_pSelItem ;
|
|
TTrack* pTrack = pItem->pTrack;
|
|
|
|
TSwitchProgForm *sPf = new TSwitchProgForm( NULL, pTrack->iBank, pTrack->iProg, pTrack->iChanNo );
|
|
|
|
BYTE data[100000];
|
|
int len = 100000;
|
|
GetDemoData( pItem, len, data, sPf->m_iStartBar, sPf->m_lenBar );
|
|
f_MM_LoadDemo( data, len );
|
|
|
|
if( sPf->ShowModal() == mrOk ){
|
|
bool bChanged = false;
|
|
|
|
int iStage = FindItemStage( pItem );
|
|
BYTE iBank = pTrack->iBank,
|
|
iBankSet = sPf->m_iFont==g_idFont ? 0xFF : sPf->m_iFont;
|
|
char iProg = sPf->m_iProg,
|
|
iChno = sPf->m_iChno;
|
|
|
|
if( iBank!=iBankSet || iProg!=pTrack->iProg || iChno!=pTrack->iChanNo ){
|
|
int range = g_Opus.StageRange(iStage),
|
|
iMT = g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec );
|
|
|
|
ChangeFont( LOWORD(range), HIWORD(range), iMT, iBankSet, iProg, iChno, pItem->iType );
|
|
}
|
|
}
|
|
|
|
delete sPf;
|
|
f_MM_LoadDemo( NULL, 0 );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
TTrackItem* TUseStylePanel::FindTrackItem( int iStage, TTrack* pTrk )
|
|
{
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[iStage];
|
|
|
|
for( int i=0; i<pSeg->aItems->Count; i++ ){
|
|
TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[i];
|
|
|
|
if( pTrkItem->pTrack==pTrk )
|
|
return pTrkItem;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::ChangeFont( int iSBar, int iEBar, int iMT, int iBank, int iProg, int iChno, int op )
|
|
{
|
|
int iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ),
|
|
iEStage = iEBar<0 ? g_Opus.StageCount() : GetInsertStage( iEBar+1 );
|
|
|
|
int iDelMT = iMT, iAddMT = -1;
|
|
TMidiTrack *pDelMT = g_aMidiTracks[iMT], *pAddMT = NULL;
|
|
vector<DWORD>* aStagesBefore = new vector<DWORD>,
|
|
* aStagesAfter = new vector<DWORD>;
|
|
vector<TTrack*> aTracksBefore, aTracksAfter;
|
|
|
|
bool bInit = false;
|
|
vector<int> aAddStages;
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
vector<int>::iterator itDelStage = pDelMT->aStages.begin();
|
|
while( itDelStage!=pDelMT->aStages.end() ){
|
|
int iStage = *itDelStage;//pDelMT->aStages[i];
|
|
|
|
if( iStage<iBStage )
|
|
itDelStage++;
|
|
else if( iStage>=iEStage )
|
|
break;
|
|
else{
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[iStage];
|
|
|
|
for( int j=0; j<pStage->aTracks.size(); j++ ){
|
|
TTrack* pTrack = pStage->aTracks[j];
|
|
if( pTrack->iFile==pDelMT->file && pTrack->iChanSpec==pDelMT->chno ){
|
|
int iFBar = g_Opus.StageFirstBar(iStage),
|
|
iLBar = g_Opus.StageLastBar(iStage);
|
|
|
|
aTracksBefore.push_back( new TTrack(pTrack) );
|
|
// aStagesBefore->push_back( MAKELONG(iStage, j) );
|
|
DWORD dwFLT = iFBar + (iLBar<<12) + (j<<24);
|
|
aStagesBefore->push_back( dwFLT );
|
|
|
|
pTrack->iBank = iBank;
|
|
pTrack->iProg = iProg;
|
|
pTrack->iChanSpec = iChno;
|
|
|
|
aTracksAfter.push_back( pTrack );
|
|
// aStagesAfter->push_back( MAKELONG(iStage, j) );
|
|
aStagesAfter->push_back( dwFLT );
|
|
aAddStages.push_back( iStage );
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
itDelStage = pDelMT->aStages.erase( itDelStage );
|
|
}
|
|
}
|
|
|
|
TTrack *pBefore = NULL, *pAfter = NULL;
|
|
int count = aAddStages.size();
|
|
|
|
if( count==0 ){
|
|
delete aStagesBefore;
|
|
delete aStagesAfter;
|
|
|
|
return;
|
|
}
|
|
|
|
int stateDel = pDelMT->state,
|
|
volumeDel = pDelMT->volume,
|
|
panDel = pDelMT->pan,
|
|
iErase = g_Midi.ClearEmptyTrack();
|
|
|
|
int nMTOri = g_aMidiTracks.size();
|
|
pAddMT = g_Midi.GetValidMidiTrack( aAddStages, 0xFF, iChno, iBank, iProg );
|
|
if( nMTOri<g_aMidiTracks.size() ){
|
|
bInit = true;
|
|
|
|
if( iDelMT>=0 ){
|
|
pAddMT->state = stateDel;
|
|
pAddMT->volume = volumeDel;
|
|
pAddMT->pan = panDel;
|
|
}
|
|
}
|
|
|
|
if( iErase>=0 ){
|
|
if( bInit && iErase==iMT ){
|
|
g_aMidiTracks.pop_back();
|
|
g_aMidiTracks.insert( g_aMidiTracks.begin()+iMT, pAddMT );
|
|
|
|
iAddMT = iMT;
|
|
bInit = false;
|
|
}
|
|
else
|
|
bInit = true;
|
|
}
|
|
|
|
pBefore = new TTrack[count];
|
|
pAfter = new TTrack[count];
|
|
|
|
for( int i=0; i<count; i++ ){
|
|
memcpy( &pBefore[i], aTracksBefore[i], sizeof(TTrack) );
|
|
delete aTracksBefore[i];
|
|
|
|
aTracksAfter[i]->iFile = pAddMT->file;
|
|
aTracksAfter[i]->iChanSpec = pAddMT->chno;
|
|
memcpy( &pAfter[i], aTracksAfter[i], sizeof(TTrack) );
|
|
}
|
|
|
|
if( iAddMT<0 )
|
|
iAddMT = g_Midi.GetMidiTrackIndex( pAddMT->file, pAddMT->chno );
|
|
|
|
int iCode = op,
|
|
iExt1 = iDelMT>=0 ? iDelMT + (stateDel<<8) + (volumeDel<<16) + (panDel<<24) : -1,
|
|
iExt2 = iAddMT>=0 ? iAddMT + (pAddMT->state<<8) + (pAddMT->volume<<16) + (pAddMT->pan<<24) : -1;
|
|
|
|
g_Undo.AddUndo( UNDO_MIDI_FONT, op, iSBar, iEBar, (void*)pBefore, (void*)pAfter );
|
|
g_Undo.SetUndoExtra( iExt1, iExt2, -1, aStagesBefore, aStagesAfter );
|
|
|
|
int iShowTrack = -1;
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
if( bInit ){
|
|
m_pContentPanel->InitialVars();
|
|
}
|
|
else{
|
|
if( iDelMT>=0 ){
|
|
int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT );
|
|
if( iST>0 )
|
|
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST );
|
|
}
|
|
}
|
|
}
|
|
|
|
IntegrateStages( iBStage );
|
|
Paint();
|
|
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
if( iAddMT>=0 ){
|
|
if( iAddMT==iDelMT )
|
|
m_pContentPanel->SelectTrack( -1, -1, -1, false );
|
|
|
|
if( iShowTrack<0 )
|
|
iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iAddMT ) - 1;
|
|
|
|
if( iShowTrack>=0 ){
|
|
m_pContentPanel->SelectTrack( iShowTrack, -1, -1, false );
|
|
m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1 );
|
|
}
|
|
}
|
|
|
|
GenerateCompose();
|
|
}
|
|
|
|
if( g_iPreStage==0 ){
|
|
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
|
|
g_lstOpusStages );
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::ChangeTexture( int iSBar, int iEBar, char sType,
|
|
int iMT, TTrack* pSubTrack, int op )
|
|
{
|
|
int iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ),
|
|
iEStage = iEBar<0 ? g_Opus.StageCount() : GetInsertStage( iEBar+1 );
|
|
|
|
vector<DWORD>* aStagesBefore = new vector<DWORD>,
|
|
* aStagesAfter = new vector<DWORD>;
|
|
vector<TTrack*> aTracksBefore, aTracksAfter;
|
|
int iUndoType = iMT<0 ? UNDO_MIDI_ADD : ( pSubTrack ? UNDO_MIDI_SUB : UNDO_MIDI_DEL );
|
|
if( iSBar<0 && iEBar<0 ) {
|
|
if( iMT<0 )
|
|
iUndoType = UNDO_TRKMID_ADD;
|
|
else if( !pSubTrack )
|
|
iUndoType = UNDO_TRKMID_DEL;
|
|
}
|
|
|
|
int iDelMT = iMT,
|
|
iAddMT = -1;
|
|
|
|
if( pSubTrack && pSubTrack->iFile!=0xFF )
|
|
iAddMT = g_Midi.GetMidiTrackIndex( pSubTrack->iFile, pSubTrack->iChanSpec );
|
|
|
|
TMidiTrack* pDelMT = iDelMT<0 ? NULL : g_aMidiTracks[iDelMT],
|
|
* pAddMT = iAddMT<0 ? NULL : g_aMidiTracks[iAddMT];
|
|
BYTE iDelFile = pDelMT ? pDelMT->file : 0xFF,
|
|
iDelChan = pDelMT ? pDelMT->chno : 0xFF,
|
|
iAddFile = pAddMT ? pAddMT->file : 0xFF,
|
|
iAddChan = pAddMT ? pAddMT->chno : 0xFF;
|
|
bool bDrum = false;
|
|
|
|
if( pSubTrack ){
|
|
if( pSubTrack->iChanNo==9 )
|
|
bDrum = true;
|
|
}
|
|
|
|
vector<int> aAddStages;
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
for( int i=iBStage; i<iEStage; i++ ){
|
|
TOpusStage* pStage = g_lstOpusStages[i];
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[i];
|
|
int iFBar = g_Opus.StageFirstBar(i),
|
|
iLBar = g_Opus.StageLastBar(i);
|
|
|
|
TTrack *pDelTrack = NULL,
|
|
*pAddTrack = NULL;
|
|
int iDelTrack = -1,
|
|
iAddTrack = -1;
|
|
|
|
if( iDelChan!=0xFF && ( sType<0 || pStage->iSegType==sType ) ){
|
|
for( int j=0; j<pStage->aTracks.size(); j++ ){
|
|
TTrack* pTmpTrack = pStage->aTracks[j];
|
|
if( iDelFile!=0xFF && pTmpTrack->iFile==iDelFile && pTmpTrack->iChanSpec==iDelChan ){
|
|
pDelTrack = pTmpTrack;
|
|
iDelTrack = j;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pDelTrack ){
|
|
if( !pDelMT || pDelMT->file!=pDelTrack->iFile )
|
|
pDelMT = g_Midi.FindMidiTrack( pDelTrack->iFile, pDelTrack->iChanSpec );
|
|
|
|
pDelMT->DelStage( i );
|
|
|
|
// aStagesBefore->push_back( MAKELONG( i, iDelTrack ) );
|
|
DWORD dwFLT = iFBar + (iLBar<<12) + (iDelTrack<<24);
|
|
aStagesBefore->push_back( dwFLT );
|
|
|
|
if( pSubTrack ){
|
|
aTracksBefore.push_back( new TTrack(pDelTrack) );
|
|
|
|
if( pDelTrack->iStyleLoc!=pSubTrack->iStyleLoc
|
|
|| pDelTrack->iStyleId!=pSubTrack->iStyleId ){
|
|
TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack];
|
|
pTrkItem->pStyle = GetStyleInfo( pSubTrack->iStyleLoc, pSubTrack->iStyleId );
|
|
}
|
|
|
|
memcpy( pDelTrack, pSubTrack, sizeof(TTrack) );
|
|
aTracksAfter.push_back( pDelTrack );
|
|
// aStagesAfter->push_back( MAKELONG(i, iDelTrack) );
|
|
aStagesAfter->push_back( dwFLT );
|
|
|
|
if( pAddMT )
|
|
pAddMT->AddStage( i );
|
|
else
|
|
aAddStages.push_back( i );
|
|
|
|
if( iUndoType!=UNDO_MIDI_SUB )
|
|
iUndoType==UNDO_MIDI_SUB;
|
|
}
|
|
else{
|
|
TTrackItem* pDelItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack];//FindTrackItem( i, pDelTrack );
|
|
TStylePanel::DeleteItem( pDelItem, -1 );
|
|
|
|
aTracksBefore.push_back( pDelTrack );
|
|
pStage->aTracks.erase( pStage->aTracks.begin()+iDelTrack );
|
|
}
|
|
}
|
|
else if( pSubTrack && pStage->iSegType==sType && ( !bDrum || iMT<0 || iDelChan==9 ) ){
|
|
TTrack* pTrk = new TTrack( pSubTrack );
|
|
|
|
if( pAddMT )
|
|
pAddMT->AddStage( i );
|
|
else
|
|
aAddStages.push_back( i );
|
|
|
|
int iTrk = 0;
|
|
if( bDrum ){
|
|
pStage->aTracks.insert( pStage->aTracks.begin(), pTrk );
|
|
}
|
|
else{
|
|
iTrk = pStage->aTracks.size();
|
|
pStage->aTracks.push_back( pTrk );
|
|
}
|
|
|
|
AddTrack( pSeg, pTrk );
|
|
|
|
aTracksAfter.push_back( pTrk );
|
|
// aStagesAfter->push_back( MAKELONG(i, iTrk) );
|
|
DWORD dwFLT = iFBar + (iLBar<<12) + (iTrk<<24);
|
|
aStagesAfter->push_back( dwFLT );
|
|
}
|
|
}
|
|
|
|
TTrack *pBefore = NULL, *pAfter = NULL;
|
|
|
|
int iExt1 = iDelMT>=0 ? iDelMT + (pDelMT->state<<8) + (pDelMT->volume<<16) + (pDelMT->pan<<24) : -1,
|
|
iErase = g_Midi.ClearEmptyTrack();
|
|
|
|
if( !aStagesBefore->empty() ){
|
|
int count = aStagesBefore->size();
|
|
pBefore = new TTrack[count];
|
|
|
|
for( int i=0; i<count; i++ ){
|
|
memcpy( &pBefore[i], aTracksBefore[i], sizeof(TTrack) );
|
|
delete aTracksBefore[i];
|
|
}
|
|
}
|
|
else if( iUndoType==UNDO_MIDI_SUB ){
|
|
iUndoType = UNDO_MIDI_ADD;
|
|
}
|
|
|
|
bool bInit = false;
|
|
if( !aStagesAfter->empty() ){
|
|
if( !pAddMT && !aAddStages.empty() ){
|
|
int nMTOri = g_aMidiTracks.size();
|
|
pAddMT = g_Midi.GetValidMidiTrack( aAddStages, pSubTrack->iFile, pSubTrack->iChanNo,
|
|
pSubTrack->iBank, pSubTrack->iProg );
|
|
|
|
if( nMTOri<g_aMidiTracks.size() )
|
|
bInit = true;
|
|
}
|
|
|
|
int count = aStagesAfter->size();
|
|
pAfter = new TTrack[count];
|
|
|
|
for( int i=0; i<count; i++ ){
|
|
if( pAddMT ) {
|
|
aTracksAfter[i]->iFile = pAddMT->file;
|
|
aTracksAfter[i]->iChanSpec = pAddMT->chno;
|
|
}
|
|
memcpy( &pAfter[i], aTracksAfter[i], sizeof(TTrack) );
|
|
}
|
|
}
|
|
|
|
if( iErase>=0 ){
|
|
if( bInit && iErase==iMT && pAddMT ){
|
|
g_aMidiTracks.pop_back();
|
|
g_aMidiTracks.insert( g_aMidiTracks.begin()+iMT, pAddMT );
|
|
|
|
iAddMT = iMT;
|
|
bInit = false;
|
|
}
|
|
else
|
|
bInit = true;
|
|
}
|
|
|
|
if( pAddMT && iAddMT<0 )
|
|
iAddMT = g_Midi.GetMidiTrackIndex( pAddMT->file, pAddMT->chno );
|
|
|
|
int iCode = op,
|
|
iExt2 = iAddMT>=0 ? iAddMT + (pAddMT->state<<8) + (pAddMT->volume<<16) + (pAddMT->pan<<24) : -1;
|
|
|
|
g_Undo.AddUndo( iUndoType, iCode, iSBar, iEBar, (void*)pBefore, (void*)pAfter );
|
|
g_Undo.SetUndoExtra( iExt1, iExt2, -1, aStagesBefore, aStagesAfter );
|
|
|
|
int iShowTrack = -1;
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
if( bInit ){
|
|
m_pContentPanel->InitialVars();
|
|
}
|
|
else{
|
|
if( iDelMT>=0 ){
|
|
int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT );
|
|
if( iST>0 )
|
|
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST );
|
|
}
|
|
}
|
|
}
|
|
|
|
IntegrateStages( iBStage );
|
|
Paint();
|
|
|
|
if( g_iSegColorMode==1 )
|
|
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_DATA );
|
|
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
if( iAddMT>=0 ){
|
|
if( VIEW_TRACK!=g_iViewMode ){
|
|
Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 );
|
|
}
|
|
else if( iAddMT==iDelMT )
|
|
m_pContentPanel->SelectTrack( -1, -1, -1, false );
|
|
|
|
if( iShowTrack<0 )
|
|
iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iAddMT ) - 1;
|
|
|
|
if( iShowTrack>=0 ){
|
|
m_pContentPanel->SelectTrack( iShowTrack, -1, -1, false );
|
|
m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1 );
|
|
}
|
|
}
|
|
|
|
GenerateCompose();
|
|
}
|
|
|
|
if( g_iPreStage==0 ){
|
|
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
|
|
g_lstOpusStages );
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::DoChangeTexture(TObject* Sender)
|
|
{
|
|
Stop( STOP_ALL );
|
|
|
|
if( Sender )
|
|
SetSelect( m_pFocItem, m_iFocLine );
|
|
|
|
TTrackItem *pItem = (TTrackItem *)m_pSelItem ;
|
|
TTrack* pTrack = pItem->pTrack;
|
|
int stype = pItem->GetSegType();
|
|
char progOri = pTrack->iProgOrig;
|
|
|
|
int iStage = FindItemStage( pItem );
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
int iSBar = g_Opus.StageFirstBar( iStage ),
|
|
lenBar = pStage->aBars.size();
|
|
TStageList m_lstStage;
|
|
TStage *stage = new TStage;
|
|
|
|
TStageList lstStages;
|
|
stage->iSegType = stype;
|
|
stage->iSegKey = pStage->iSegKey;
|
|
stage->nBarNum = lenBar;
|
|
stage->nTrkNum = 0;
|
|
lstStages.push_back( stage );
|
|
|
|
if( stype<=SEGTYPE_FILL ){
|
|
stage->aChords = new TBarChords[lenBar];
|
|
for( int j=0; j<lenBar; j++ ){
|
|
memcpy( &stage->aChords[j],
|
|
&pStage->aBars[j]->aChords,
|
|
sizeof(TBarChords) );
|
|
}
|
|
}
|
|
|
|
TSwitchTextureForm *pProgPar = new TSwitchTextureForm(NULL, (1<<stype), progOri,
|
|
pTrack->iBank, pTrack->iProg, pItem->pStyle,
|
|
pTrack->iChanNo, pTrack->iSegNo, &lstStages, 0);
|
|
|
|
if(pProgPar->ShowModal() == mrOk){
|
|
TTrack subTrk;
|
|
subTrk.iStyleLoc = pProgPar->m_pSetStyle->idLoc;
|
|
subTrk.iStyleId = pProgPar->m_pSetStyle->idStyle;
|
|
subTrk.iSegNo = pProgPar->m_cSetSegNo;
|
|
subTrk.iChanNo = pProgPar->m_cSetchan;
|
|
subTrk.iProgOrig = pProgPar->m_cSetProgOri;
|
|
subTrk.nVol = pProgPar->m_cSetVol;
|
|
subTrk.nVolOrig = pProgPar->m_cSetVolOri;
|
|
|
|
if( pProgPar->m_bSetCur ){
|
|
subTrk.iProg = pProgPar->m_cSetProg;
|
|
subTrk.iChanSpec = subTrk.iChanNo;
|
|
subTrk.iBank = 0xFF;
|
|
subTrk.iFile = 0xFF;
|
|
}
|
|
else{
|
|
subTrk.iProg = pTrack->iProg;
|
|
subTrk.iChanSpec = pTrack->iChanSpec;
|
|
subTrk.iBank = pTrack->iBank;
|
|
subTrk.iFile = pTrack->iFile;
|
|
}
|
|
|
|
int iMT = g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec );
|
|
ChangeTexture( iSBar, iSBar+lenBar-1, stype, iMT, &subTrk, SEGTYPE_TRACK );
|
|
}
|
|
|
|
delete pProgPar;
|
|
delete stage;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::DeleteAllTexture( bool bAddUndo )
|
|
{
|
|
if( g_Midi.IsEmpty() || g_Opus.BarCount()==0 )
|
|
return;
|
|
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
TOpusStageList *lstStageBefore = NULL,
|
|
*lstStageAfter = NULL;
|
|
UINT idLocBefore(-1), idStyleBefore(-1),
|
|
idLocAfter(-1), idStyleAfter(-1);
|
|
int nTrks = g_aMidiTracks.size();
|
|
TMidiTrackList *lstTracksBefore = NULL;
|
|
|
|
if( bAddUndo ){
|
|
lstStageBefore = new TOpusStageList;
|
|
g_Opus.CopyStages( 0, g_Opus.BarCount()-1, lstStageBefore );
|
|
|
|
if( pStyleItem->pStyle ){
|
|
idLocBefore = pStyleItem->pStyle->idLoc;
|
|
idStyleBefore = pStyleItem->pStyle->idStyle;
|
|
}
|
|
|
|
lstTracksBefore = new TMidiTrackList;
|
|
for( int i=0; i<nTrks; i++ )
|
|
lstTracksBefore->push_back( new TMidiTrack(g_aMidiTracks[i]) );
|
|
}
|
|
|
|
for( int i=0; i<g_lstOpusStages.size(); i++ ){
|
|
TOpusStage* pStage = g_lstOpusStages[i];
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyleItem->aItems->Items[i];
|
|
|
|
while( !pStage->aTracks.empty() ){
|
|
TTrackItem* pDelItem = (TTrackItem*)pSeg->aItems->Last();
|
|
TStylePanel::DeleteItem( pDelItem, -1 );
|
|
|
|
TTrack* pTrack = pStage->aTracks.back();
|
|
pStage->aTracks.pop_back();
|
|
}
|
|
}
|
|
|
|
g_Midi.ClearMidiTracks();
|
|
|
|
IntegrateStages( 0 );
|
|
Paint();
|
|
|
|
if( bAddUndo ){
|
|
lstStageAfter = new TOpusStageList;
|
|
g_Opus.CopyStages( 0, g_Opus.BarCount()-1, lstStageAfter );
|
|
|
|
if( pStyleItem->pStyle ){
|
|
idLocAfter = pStyleItem->pStyle->idLoc;
|
|
idStyleAfter = pStyleItem->pStyle->idStyle;
|
|
}
|
|
|
|
g_Undo.AddUndo( UNDO_TRKMID_DELALL, ST_MIDI, idStyleBefore, idStyleAfter,
|
|
(void*)lstStageBefore, (void*)lstStageAfter );
|
|
g_Undo.SetUndoExtra( idLocBefore, idLocAfter, 0, (void*)lstTracksBefore, NULL );
|
|
}
|
|
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
m_pContentPanel->InitialVars();
|
|
GenerateCompose();
|
|
}
|
|
else if( g_iSegColorMode==1 ){
|
|
m_pContentPanel->InvalidateBars( 0, g_Opus.BarCount()-1, BAR_DATA );
|
|
}
|
|
|
|
if( g_iPreStage==0 ){
|
|
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
|
|
g_lstOpusStages );
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
TSegmentItem* TUseStylePanel::AddStage( TOpusStage* pStage )
|
|
{
|
|
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
|
|
|
|
int ind = 0;
|
|
DWORD opts = OPT_DEL|OPT_VOL;
|
|
if( pStage->iSegType<=SEGTYPE_FILL ){
|
|
ind = pStyItem->nSegNum[0] + pStyItem->nSegNum[1];
|
|
opts |= OPT_BRUSH;
|
|
}
|
|
else
|
|
ind = pStyItem->nSegNum[pStage->iSegType];
|
|
|
|
TSegmentItem* pSegItem = pStyItem->AddSegment( pStage->iSegType,
|
|
pStage->iSegNo,
|
|
opts,
|
|
pStage->aBars.size(),
|
|
ind,
|
|
pStage->nVol,
|
|
false );
|
|
opts = OPT_DEL|OPT_FONTPROG|OPT_VOL;
|
|
if( pStage->iSegType<SEGTYPE_INTRO )
|
|
opts |= OPT_TEXTURE;
|
|
|
|
for( int j=0; j<pStage->aTracks.size(); j++ ){
|
|
TTrack* pTrack = pStage->aTracks[j];
|
|
pSegItem->AddTrack( NULL, pTrack, opts, false );
|
|
}
|
|
|
|
return pSegItem;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
int TUseStylePanel::GetDemoData( TCommonItem* pItem, int &nLen, BYTE* pData, int& iStartBar, int& lenBar )
|
|
{
|
|
int ret = 0;
|
|
|
|
if( pItem->iType==SEGTYPE_TRACK ){ //播放单一轨道{
|
|
int iStage = FindItemStage( pItem );
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
TSegmentItem* pSeg = (TSegmentItem*)pItem->up;
|
|
|
|
int stype = pItem->GetSegType();
|
|
TTrack* pTrk = ((TTrackItem*)pItem)->pTrack;
|
|
TStage stage;
|
|
stage.aTracks = new TComposeTrack[1];
|
|
int nStageNum = 1;
|
|
|
|
stage.iSegType = stype;
|
|
stage.iSegKey = pStage->iSegKey;
|
|
stage.nBarNum = lenBar;
|
|
stage.nTrkNum = 1;
|
|
|
|
stage.aTracks->iStyleId = pTrk->iStyleId;// >pStyle->idStyle;
|
|
stage.aTracks->iStyleLoc = pTrk->iStyleLoc;// >pStyle->idLoc;
|
|
|
|
if( stype>=SEGTYPE_INTRO ){
|
|
char cType = (pTrk->iSegNo / 4 + 1) << 4;
|
|
char sno = pTrk->iSegNo % 4;
|
|
stage.aTracks->iSegNo = sno + cType;
|
|
}
|
|
else
|
|
stage.aTracks->iSegNo = pTrk->iSegNo;
|
|
|
|
stage.aTracks->iChanNo = pTrk->iChanNo;
|
|
stage.aTracks->iChanSpec = pTrk->iChanSpec;
|
|
stage.aTracks->iProg = pTrk->iProg;
|
|
stage.aTracks->nVol = pTrk->nVol<0 ? 0 : pTrk->nVol * pSeg->volume / 100.0;
|
|
|
|
if( stype<=SEGTYPE_FILL ){
|
|
stage.aChords = new TBarChords[lenBar];
|
|
for( int j=0; j<lenBar; j++ ){
|
|
memcpy( &stage.aChords[j],
|
|
&pStage->aBars[j]->aChords,
|
|
sizeof(TBarChords) );
|
|
}
|
|
}
|
|
|
|
ret = f_CM_Compose( &nLen, pData, g_iMelodyTimeSignature, g_nMelodyTempo,
|
|
nStageNum, &stage, false, NULL, NULL );
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::PlayDemo( TCommonItem *pItem, int tempo )
|
|
{
|
|
if( !pItem || g_lstOpusStages.size()==0 )
|
|
return;
|
|
|
|
Stop( STOP_ALL );
|
|
|
|
if( pItem->iType!=SEGTYPE_TRACK ){
|
|
GenerateCompose();
|
|
SetTrackParams( false );
|
|
}
|
|
|
|
int iStartBar(0), lenBar(0);
|
|
if( pItem->iType==SEGTYPE_STYLE ){ //播放完整全曲
|
|
f_MM_Play( Handle, 0, TYPE_COMPOSE ); //仅播放编曲
|
|
m_bPlaying = true;
|
|
}
|
|
else{
|
|
int iStage = FindItemStage( pItem );
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
|
|
for( int i=0; i<iStage; i++ ){
|
|
iStartBar += g_lstOpusStages[i]->aBars.size();
|
|
}
|
|
|
|
lenBar = pStage->aBars.size();
|
|
|
|
if( pItem->iType==SEGTYPE_TRACK ){ //播放单一轨道
|
|
BYTE data[100000];
|
|
int len = 100000;
|
|
int ret = GetDemoData( pItem, len, data, iStartBar, lenBar );
|
|
|
|
if( ret==0 ){
|
|
BYTE iBank = ((TTrackItem*)pItem)->pTrack->iBank;
|
|
char* strFile = iBank==0xFF ? NULL : iBank<0x80 ? g_lstFonts[iBank]->strFileName
|
|
: g_lstVSTi[iBank-0x80]->strFileName;
|
|
|
|
f_MM_LoadDemo( data, len );
|
|
f_MM_PlayDemo( Handle, 0, -1, -1, iBank, strFile );
|
|
|
|
m_bPlaying = true;
|
|
}
|
|
else{
|
|
DebugPrint( "Compose error: %d", ret );
|
|
}
|
|
}
|
|
else{
|
|
f_MM_Play( Handle, iStartBar, TYPE_COMPOSE ); //仅播放编曲
|
|
m_bPlaying = true;
|
|
}
|
|
|
|
if( m_bPlaying ){
|
|
if( !m_pPlayTimer ){
|
|
m_pPlayTimer = new TTimer(this);
|
|
}
|
|
m_pPlayTimer->Interval = lenBar * g_dblTimePerBar - 100;
|
|
m_pPlayTimer->OnTimer = PlayEndProc;
|
|
m_pPlayTimer->Enabled = true;
|
|
}
|
|
}
|
|
|
|
if( m_bPlaying )
|
|
m_pPlayItem = pItem;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::PlayEndProc(TObject* Sender)
|
|
{
|
|
Stop(STOP_SELF);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::OnPlayEnd(TMessage &msg)
|
|
{
|
|
Stop(STOP_SELF);
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::SetSelect( TCommonItem *pItem, int iLine )
|
|
{
|
|
TCommonItem * pOldSeg = NULL;
|
|
|
|
if( m_pSelItem && m_pSelItem->iType>=SEGTYPE_VAR
|
|
&& m_pSelItem->iType<=SEGTYPE_ENDING ){
|
|
pOldSeg = m_pSelItem;
|
|
}
|
|
|
|
if( !pItem || pItem->iType==SEGTYPE_STYLE ){
|
|
m_pContentPanel->SelectStage( -1 );
|
|
}
|
|
|
|
TStylePanel::SetSelect( pItem, iLine );
|
|
|
|
if( pOldSeg!=m_pSelItem && m_pSelItem && m_pSelItem->iType>=SEGTYPE_VAR
|
|
&& m_pSelItem->iType<=SEGTYPE_ENDING ){
|
|
TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0];
|
|
|
|
for( int i=0; i<pStyle->aItems->Count; i++ ){
|
|
if( m_pSelItem==pStyle->aItems->Items[i] ){
|
|
m_pContentPanel->SelectStage( i );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
void TUseStylePanel::Stop( DWORD dwSpec )
|
|
{
|
|
if( m_pPlayTimer ){
|
|
delete m_pPlayTimer;
|
|
m_pPlayTimer = NULL;
|
|
}
|
|
|
|
if( m_bPlaying ){
|
|
dwSpec = STOP_SELF;
|
|
|
|
if( m_pPlayItem && m_pPlayItem->iType!=SEGTYPE_TRACK )
|
|
SetTrackParams();
|
|
}
|
|
|
|
TStylePanel::Stop( dwSpec );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
bool TUseStylePanel::HandleHoverEvent(TPoint ptMouse)
|
|
{
|
|
int X = ptMouse.X,
|
|
Y = ptMouse.Y;
|
|
|
|
TCommonItem* pHoverItem = NULL;
|
|
int iHoverLine = -1;
|
|
|
|
TCommonItem* pItem = HitTest( X, Y-m_nTitleHeight, NULL );
|
|
if( pItem && m_pDropItem ){
|
|
if( m_pDropItem->iType==SEGTYPE_TRACK ){
|
|
iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight;
|
|
|
|
pHoverItem = GetTrackHoverItem( pItem, iHoverLine );
|
|
}
|
|
else if( m_pDropItem->iType==SEGTYPE_STYLE ){
|
|
//查看风格是否缺少片段
|
|
if( ((TStyleItem*)m_pDropItem)->nSegNum[0]>0 ){
|
|
pHoverItem = (TCommonItem*)m_aItems->Items[0];
|
|
iHoverLine = -m_iTopLine;
|
|
}
|
|
}
|
|
else{
|
|
int iDropType = m_pDropItem->GetSegType(),
|
|
iHoverType = pItem->GetSegType();
|
|
|
|
if( iDropType==iHoverType //类型相同可替换
|
|
|| ( iHoverType==SEGTYPE_FILL
|
|
|| iHoverType==SEGTYPE_VAR)
|
|
&& (iDropType==SEGTYPE_FILL
|
|
|| iDropType==SEGTYPE_VAR )){ //伴奏与加花可替换
|
|
iHoverLine = (Y - m_nTitleHeight)/m_nItemHeight;
|
|
pHoverItem = pItem;
|
|
}
|
|
}
|
|
}
|
|
|
|
SetUnfoldTimer( pItem, pHoverItem );
|
|
SetHover( pHoverItem, iHoverLine );
|
|
|
|
return pHoverItem!=NULL;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::HandleDropEvent( int iState )
|
|
{
|
|
if( m_pDropItem && m_pHoverItem ){
|
|
Stop();
|
|
|
|
if( m_pDropItem->iType==SEGTYPE_STYLE ){ //应用风格
|
|
PostMessage( Parent->Handle, UM_APPLYSTYLE, 1, LPARAM(m_pDropItem) );
|
|
}
|
|
else{ //应用片段
|
|
int iStage = FindItemStage( m_pHoverItem );
|
|
|
|
if( m_pDropItem->iType==SEGTYPE_TRACK ){ //添加track
|
|
TSegmentItem* pSeg = (TSegmentItem*)m_pHoverItem;
|
|
if( m_pHoverItem->iType==SEGTYPE_TRACK )
|
|
pSeg = (TSegmentItem*)m_pHoverItem->up;
|
|
|
|
TTrack *pSrcTrack = new TTrack( ((TTrackItem*)m_pDropItem)->pTrack ),
|
|
*pDstTrack = NULL;
|
|
|
|
if( pSrcTrack->iChanNo==9 ){
|
|
for( int i=0; i<pSeg->aItems->Count; i++ ){
|
|
TTrackItem* pTmpItem = (TTrackItem*)pSeg->aItems->Items[i];
|
|
if( pTmpItem->pTrack->iChanNo==9 ){
|
|
pDstTrack = pTmpItem->pTrack;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int iMT = -1;
|
|
if( pDstTrack ){
|
|
iMT = g_Midi.GetMidiTrackIndex( pDstTrack->iFile, pDstTrack->iChanSpec );
|
|
}
|
|
else{
|
|
pSrcTrack->iFile = 0xFF;
|
|
pSrcTrack->iChanSpec = pSrcTrack->iChanNo;
|
|
}
|
|
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
int iSBar = FirstBar( iStage ),
|
|
iEBar = iSBar + pStage->aBars.size() - 1;
|
|
|
|
ChangeTexture( iSBar, iEBar, pStage->iSegType, iMT, pSrcTrack, SEGTYPE_TRACK );
|
|
}
|
|
else{
|
|
ReformStage( iStage, (TSegmentItem*)m_pDropItem );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
String TUseStylePanel::ChargeTip( TStyleItem* pItem )
|
|
{
|
|
String strTip = " 风格支付预估\n\n 风格 唱作音符\n";
|
|
strTip += "------------------------\n";
|
|
|
|
char buf[512];
|
|
int nFee = 0;
|
|
for( int i=0; i<m_aStyles.size(); i++ ){
|
|
if( m_aStyles[i]->idLoc==0 && m_aStyles[i]->pOrigin->cost>0 ){
|
|
TPROSTYLE* pStyle = m_aStyles[i];
|
|
|
|
sprintf( buf, "[%4d] %d\n", pStyle->idStyle, pStyle->pOrigin->cost );
|
|
strTip += buf;
|
|
|
|
nFee += pStyle->pOrigin->cost;
|
|
}
|
|
}
|
|
|
|
strTip += "------------------------\n";
|
|
strTip += " 合计 " + IntToStr( nFee );
|
|
|
|
return strTip;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::ApplyStyle( TStyleItem* pSrcStyle )
|
|
{
|
|
g_Midi.ClearMidiTracks();
|
|
|
|
TStyleItem* pDestStyle = (TStyleItem*)m_aItems->Items[0];
|
|
|
|
//Set Undo
|
|
bool bMMUndo = false;
|
|
int nBars = pDestStyle->nBars,
|
|
idLoc = (pDestStyle && pDestStyle->pStyle) ? pDestStyle->pStyle->idLoc : 0,
|
|
idStyle = (pDestStyle && pDestStyle->pStyle) ? pDestStyle->pStyle->idStyle : 0;
|
|
|
|
TAudioTrackList* lstAudio = NULL;
|
|
TOpusStageList* lstStageBefore = new TOpusStageList;
|
|
g_Opus.CopyStages( 0, nBars-1, lstStageBefore );
|
|
|
|
//替换风格
|
|
pDestStyle->pStyle = pSrcStyle->pStyle;
|
|
|
|
int nSegNum[4];
|
|
vector<TSegmentItem*> aSegments[4];
|
|
memset( nSegNum, 0, sizeof(int)*4 );
|
|
|
|
for( int i=0; i<pSrcStyle->aItems->Count; i++ ){
|
|
TSegmentItem* pSegment = (TSegmentItem*)pSrcStyle->aItems->Items[i];
|
|
int stype = pSegment->GetSegType();
|
|
aSegments[stype].push_back( pSegment );
|
|
nSegNum[stype]++;
|
|
}
|
|
|
|
m_pFocItem = NULL;
|
|
m_iFocLine = -1;
|
|
m_pSelItem = NULL;
|
|
m_iSelLine = -1;
|
|
|
|
for( int i=pDestStyle->aItems->Count-1; i>=0; i-- ){
|
|
TSegmentItem* pDestSeg = (TSegmentItem*)pDestStyle->aItems->Items[i];
|
|
TSegmentItem* pSrcSeg = NULL;
|
|
int stype = pDestSeg->iSegType;
|
|
int sno = pDestSeg->iSegNo;
|
|
|
|
if( stype>=SEGTYPE_INTRO ){
|
|
if( nSegNum[stype]>0 ){
|
|
TSegmentItem* pBackup = NULL;
|
|
int t = sno / 2,
|
|
c = sno % 2;
|
|
|
|
for( int j=0; j<nSegNum[stype]; j++ ){
|
|
if( aSegments[stype][j]->iSegNo % 2 == c ){
|
|
if( aSegments[stype][j]->iSegNo / 2 == t ){
|
|
pSrcSeg = aSegments[stype][j];
|
|
break;
|
|
}
|
|
else{
|
|
pBackup = aSegments[stype][j];
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !pSrcSeg ){
|
|
if( pBackup )
|
|
pSrcSeg = pBackup;
|
|
else
|
|
pSrcSeg = aSegments[stype][0]; //大小调不分
|
|
}
|
|
}
|
|
|
|
if( !bMMUndo && ( !pSrcSeg || pSrcSeg->nBars!=pDestSeg->nBars ) ){
|
|
f_MM_AddUndoBefore( -1, NULL );
|
|
|
|
lstAudio = new TAudioTrackList;
|
|
g_Audio.CopyTrackList( 0, nBars, lstAudio );
|
|
|
|
bMMUndo = true;
|
|
}
|
|
}
|
|
else{
|
|
if( stype==SEGTYPE_FILL && nSegNum[SEGTYPE_FILL]==0 ){
|
|
stype = SEGTYPE_VAR;
|
|
}
|
|
else if( stype==SEGTYPE_VAR && nSegNum[SEGTYPE_VAR]==0 ){
|
|
stype = SEGTYPE_FILL;
|
|
}
|
|
|
|
sno = min( sno, nSegNum[stype]-1 );
|
|
pSrcSeg = aSegments[stype][sno];
|
|
}
|
|
|
|
if( pSrcSeg ){
|
|
ReplaceSegment( pDestSeg, pSrcSeg );
|
|
}
|
|
else{ //删除段落
|
|
RemoveSegment( pDestSeg );
|
|
}
|
|
}
|
|
|
|
IntegrateStages( 0 );
|
|
|
|
if( bMMUndo ){
|
|
f_MM_AddUndoAfter( -1, NULL );
|
|
}
|
|
|
|
TOpusStageList* lstStageAfter = new TOpusStageList;
|
|
g_Opus.CopyStages( 0, pDestStyle->nBars-1, lstStageAfter );
|
|
|
|
g_Undo.AddUndo( UNDO_OPUS_STYLE, 0, idLoc, idStyle, (void*)lstStageBefore,
|
|
(void*)lstStageAfter );
|
|
|
|
if( bMMUndo )
|
|
g_Undo.SetUndoExtra( 0, 0, 0, (void*)lstAudio, NULL );
|
|
|
|
if( !pDestStyle->IsUnfold() )
|
|
SetFold( pDestStyle, 0 );
|
|
else if( m_pTopItem!=pDestStyle )
|
|
ScrollView( 0, true );
|
|
else
|
|
InvalidateRgn( Handle, NULL, false );
|
|
|
|
m_pContentPanel->OnStageChanged( 0, MODE_INIT );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::ReplaceSegment( TSegmentItem* pDestSeg, TSegmentItem* pSrcSeg )
|
|
{
|
|
int iStage = FindItemStage( pDestSeg );
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
TStyleItem *pStyItem = (TStyleItem*)m_aItems->Items[0];
|
|
|
|
int nBar = pStage->aBars.size();
|
|
if( pSrcSeg->iSegType>=SEGTYPE_INTRO )
|
|
nBar = pSrcSeg->nBars;
|
|
|
|
bool bPreChange = g_iPreStage==0;
|
|
if( pStage->aBars.size()!=nBar ){ //段落长度调整
|
|
int offset = nBar - pStage->aBars.size();
|
|
int iOrigEnd = FirstBar(iStage) + pStage->aBars.size();
|
|
|
|
if( bPreChange ){
|
|
DuplicateRawBars();
|
|
SendMessage( Parent->Handle, UM_STAGECHANGED, 3, 0 );
|
|
}
|
|
|
|
if( offset!=0 && pStage->iSegType==SEGTYPE_INTRO ){
|
|
if( g_Theme.IsWeadup() && !memcmp( g_aAudioTracks[1]->lstBars[iOrigEnd-1]->aVols,
|
|
g_aAudioTracks[0]->lstBars[0]->aVols,
|
|
POINTS_PER_BAR * sizeof(DWORD) )){
|
|
iOrigEnd--;
|
|
}
|
|
}
|
|
|
|
if( offset>0 ){ //添加小节
|
|
for( int i=0; i<offset; i++ ){
|
|
TBar* pBar = new TBar;
|
|
pStage->aBars.push_back(pBar);
|
|
|
|
for( int j=1; j<g_aAudioTracks.size(); j++ ){
|
|
TWaveBar* pWvBar = new TWaveBar;
|
|
g_aAudioTracks[j]->lstBars.insert( g_aAudioTracks[j]->lstBars.begin() + iOrigEnd, pWvBar );
|
|
}
|
|
}
|
|
|
|
for( int j=1; j<g_aAudioTracks.size(); j++ ){
|
|
f_MM_AudioMove( j, iOrigEnd, -1, 0, offset, MODE_INSERT );
|
|
}
|
|
}
|
|
else{ //删除小节
|
|
iOrigEnd--;
|
|
|
|
for( int i=0; i>offset; i-- ){
|
|
delete pStage->aBars.back();
|
|
pStage->aBars.pop_back();
|
|
|
|
for( int j=1; j<g_aAudioTracks.size(); j++ ){
|
|
delete g_aAudioTracks[j]->lstBars[iOrigEnd+i];
|
|
g_aAudioTracks[j]->lstBars.erase( g_aAudioTracks[j]->lstBars.begin() + iOrigEnd+i );
|
|
}
|
|
}
|
|
|
|
for( int j=1; j<g_aAudioTracks.size(); j++ ){
|
|
f_MM_AudioMove( -1, 0, j, iOrigEnd+offset+1, iOrigEnd+1, MODE_DELETE );
|
|
}
|
|
}
|
|
|
|
pDestSeg->nBars += offset;
|
|
pStyItem->nBars += offset;
|
|
|
|
g_Opus.CountBars();
|
|
}
|
|
|
|
if( pDestSeg->iType != pSrcSeg->iType ){
|
|
pStyItem->nSegNum[pDestSeg->iType]--;
|
|
pStyItem->nSegNum[pSrcSeg->iType]++;
|
|
}
|
|
|
|
pDestSeg->iType = pSrcSeg->iType;
|
|
pStage->nVol = pDestSeg->volume = pSrcSeg->volume;
|
|
pStage->iSegType = pDestSeg->iSegType = pSrcSeg->iSegType;
|
|
pStage->iSegNo = pDestSeg->iSegNo = pSrcSeg->iSegNo;
|
|
|
|
g_Midi.RemoveStage( iStage, false );
|
|
//清空tracks
|
|
while( pStage->aTracks.size()>0 ){
|
|
delete pStage->aTracks.back();
|
|
pStage->aTracks.pop_back();
|
|
}
|
|
|
|
int iSegLine = 0, nTrkBefore = 0, nTrkAfter = 0;
|
|
|
|
if( pStyItem->IsUnfold() ){
|
|
TCommonItem *pItem = pStyItem;
|
|
while( pItem && pItem!=pDestSeg ){
|
|
iSegLine++;
|
|
pItem = GetNextItem( pItem );
|
|
}
|
|
|
|
if( pDestSeg->IsUnfold() ){
|
|
if( m_pSelItem && m_pSelItem->up==pDestSeg ){
|
|
m_pSelItem = NULL;
|
|
m_iSelLine = -1;
|
|
}
|
|
|
|
nTrkBefore = pDestSeg->aItems->Count;
|
|
nTrkAfter = pSrcSeg->aItems->Count;
|
|
|
|
if( m_pTopItem && m_pTopItem->up==pDestSeg ){
|
|
TCommonItem * pItem = m_pTopItem;
|
|
int iTopLine = m_iTopLine;
|
|
while( pItem!=pDestSeg ){
|
|
iTopLine--;
|
|
pItem = GetPrevItem( pItem );
|
|
}
|
|
|
|
ScrollView( iTopLine, true );
|
|
}
|
|
}
|
|
}
|
|
|
|
pDestSeg->ClearSubItems();
|
|
DWORD opts = OPT_DEL|OPT_VOL;
|
|
if( pDestSeg->iSegType<SEGTYPE_INTRO )
|
|
opts |= OPT_TEXTURE;
|
|
|
|
int nMTCount = g_aMidiTracks.size();
|
|
for( int i=0; i<pSrcSeg->aItems->Count; i++ ){
|
|
TTrackItem* pTrkItem = (TTrackItem*)pSrcSeg->aItems->Items[i];
|
|
TTrack * pTrack = new TTrack( pTrkItem->pTrack );
|
|
|
|
pDestSeg->AddTrack( pTrkItem->pStyle, pTrack, opts, false );
|
|
pStage->aTracks.push_back( pTrack );
|
|
|
|
TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iStage, pTrack->iFile, pTrack->iChanNo,
|
|
pTrack->iBank, pTrack->iProg );
|
|
pTrack->iFile = pMT->file;
|
|
pTrack->iChanSpec = pMT->chno;
|
|
}
|
|
|
|
bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0;
|
|
if( bPreChange || !m_pContentPanel->IsVertical() && ( bDeletedMT
|
|
|| nMTCount!=g_aMidiTracks.size() ))
|
|
m_pContentPanel->InitialVars();
|
|
|
|
m_nTotalLine += nTrkAfter - nTrkBefore;
|
|
|
|
if( m_iTopLine>iSegLine ){
|
|
m_iTopLine += nTrkAfter - nTrkBefore;
|
|
}
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::DeleteItem( TCommonItem *pItem, int iLine )
|
|
{
|
|
Stop();
|
|
TStyleItem *pStyItem = (TStyleItem*)m_aItems->Items[0];
|
|
|
|
int iStage = FindItemStage( pItem );
|
|
|
|
if( pItem->iType==SEGTYPE_TRACK ){
|
|
DeleteTrack( iStage, (TTrackItem*)pItem, iLine );
|
|
}
|
|
else{
|
|
RemoveStage( iStage );
|
|
|
|
if( pStyItem->aItems->Count==0 ){
|
|
// g_Midi.ClearMidiTracks();
|
|
ClearAllItems();
|
|
|
|
g_pUseStyle = NULL;
|
|
Paint();
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::DeleteTrack( int iStage, TTrackItem* pTrkItem, int iLine )
|
|
{
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
for( int i=0; i<pStage->aTracks.size(); i++ ){
|
|
TTrack* pTrack = pStage->aTracks[i];
|
|
if( pTrkItem->pTrack==pTrack ){
|
|
int iFirstBar = FirstBar( iStage ),
|
|
iEndBar = iFirstBar + pStage->aBars.size() - 1;
|
|
int iMT= g_Midi.GetMidiTrackIndex( pTrack->iFile, pTrack->iChanSpec );
|
|
|
|
ChangeTexture( iFirstBar, iEndBar, pStage->iSegType, iMT, NULL, SEGTYPE_TRACK );
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
TSegmentItem* TUseStylePanel::InsertSegment( int iStage, TSegmentItem* pSrcSeg, int nBars )
|
|
{
|
|
if( m_aItems->Count==0 ){
|
|
g_pUseStyle = AddStyle( ((TTrackItem*)pSrcSeg->aItems->Items[0])->pStyle );
|
|
}
|
|
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
|
|
int ind = 0;
|
|
DWORD opts = OPT_DEL|OPT_VOL;
|
|
int stype = pSrcSeg->iSegType;
|
|
if( pSrcSeg->iSegType<=SEGTYPE_FILL ){
|
|
stype = SEGTYPE_VAR;
|
|
opts |= OPT_BRUSH;
|
|
}
|
|
|
|
if( iStage<0 || iStage>=pStyleItem->aItems->Count ){
|
|
iStage = pStyleItem->aItems->Count;
|
|
|
|
if( pSrcSeg->iSegType<=SEGTYPE_FILL ){
|
|
ind = pStyleItem->nSegNum[SEGTYPE_VAR]
|
|
+ pStyleItem->nSegNum[SEGTYPE_FILL];
|
|
}
|
|
else
|
|
ind = pStyleItem->nSegNum[pSrcSeg->iSegType];
|
|
}
|
|
else{
|
|
for( int i=0; i<pStyleItem->aItems->Count; i++ ){
|
|
TSegmentItem* pTmpSeg = (TSegmentItem*)pStyleItem->aItems->Items[i];
|
|
|
|
if( pTmpSeg->iSegType<=SEGTYPE_FILL && stype==SEGTYPE_VAR ){
|
|
if( i<iStage )
|
|
ind++;
|
|
else
|
|
pTmpSeg->iInd++;
|
|
}
|
|
else if( pTmpSeg->iSegType==stype ){
|
|
if( i<iStage )
|
|
ind++;
|
|
else
|
|
pTmpSeg->iInd++;
|
|
}
|
|
}
|
|
}
|
|
|
|
TSegmentItem* pDestSeg = new TSegmentItem( pStyleItem, pSrcSeg->iSegType, pSrcSeg->iSegNo,
|
|
opts, nBars, ind, pSrcSeg->volume, false );
|
|
opts = OPT_DEL|OPT_VOL;
|
|
if( pSrcSeg->iSegType<SEGTYPE_INTRO )
|
|
opts |= OPT_TEXTURE;
|
|
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
for( int i=0; i<pStage->aTracks.size(); i++ ){
|
|
TTrack* pTrack = pStage->aTracks[i];
|
|
pDestSeg->AddTrack( NULL, pTrack, opts, false );
|
|
}
|
|
|
|
if( pStyleItem->IsUnfold() ){
|
|
m_nTotalLine++;
|
|
|
|
int iTopStage = FindItemStage( m_pTopItem );
|
|
|
|
if( iTopStage>=iStage ){
|
|
m_iTopLine++;
|
|
}
|
|
}
|
|
|
|
pStyleItem->InsertSegment( iStage, pDestSeg, nBars );
|
|
|
|
return pDestSeg;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::RemoveSegment( TSegmentItem* pItem, bool bSetMM )
|
|
{
|
|
int iStage = FindItemStage( pItem );
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
|
|
int iFirstBar = FirstBar(iStage);
|
|
int iEndBar = iFirstBar + pStage->aBars.size();
|
|
|
|
if( bSetMM && iEndBar>iFirstBar ){
|
|
if( g_iPreStage==0 )
|
|
DuplicateRawBars();
|
|
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
MoveAudio( i, iFirstBar, iEndBar, -1, 0, MODE_DELETE | OPT_BARS );
|
|
}
|
|
}
|
|
|
|
g_Opus.RemoveStage( iStage );
|
|
g_Midi.RemoveStage( iStage, true );
|
|
|
|
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
|
|
|
|
if( m_pTopItem ){
|
|
int iTopStage = FindItemStage( m_pTopItem );
|
|
|
|
if( pStyItem->IsUnfold() ){
|
|
if( iTopStage>iStage ){
|
|
m_iTopLine--;
|
|
|
|
if( pItem->IsUnfold() ){
|
|
m_iTopLine -= pItem->aItems->Count;
|
|
}
|
|
}
|
|
else if( iTopStage==iStage && m_pTopItem!=pItem ){ //展开且TopItem是Track
|
|
TCommonItem* pTmpItem = m_pTopItem;
|
|
m_pTopItem = GetPrevItem( pItem );
|
|
|
|
while( pTmpItem!=m_pTopItem ){
|
|
m_iTopLine--;
|
|
pTmpItem = GetPrevItem( pTmpItem );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TStylePanel::DeleteItem( pItem, -1 );
|
|
|
|
pStyItem->nBars -= iEndBar - iFirstBar;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
int TUseStylePanel::FindItemStage( TCommonItem* pItem )
|
|
{
|
|
int iStage = -1;
|
|
TStyleItem* pStyle = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pSeg = NULL;
|
|
|
|
if( pItem->iType!=SEGTYPE_STYLE ){
|
|
if( pItem->iType==SEGTYPE_TRACK )
|
|
pSeg = (TSegmentItem*)pItem->up;
|
|
else
|
|
pSeg = (TSegmentItem*)pItem;
|
|
|
|
for( int i=0; i<pStyle->aItems->Count; i++ ){
|
|
if( pSeg==pStyle->aItems->Items[i] ){
|
|
iStage = i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
return iStage;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
/*
|
|
TCommonItem* TUseStylePanel::DrawDragStageItem( int iStage )
|
|
{
|
|
TStyleItem* pStyle= (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyle->aItems->Items[iStage];
|
|
|
|
DrawDragImg( pSeg );
|
|
|
|
return pSeg;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
*/
|
|
void TUseStylePanel::SetSelectStage( int iStage )
|
|
{
|
|
if( m_aItems->Count==0 )
|
|
return;
|
|
|
|
TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0];
|
|
if( iStage>=0 && iStage<pStyle->aItems->Count ){
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyle->aItems->Items[iStage];
|
|
|
|
if( !pStyle->IsUnfold() ){
|
|
SetFold( pStyle, 0 );
|
|
}
|
|
|
|
TCommonItem* pItem = GetNextItem( pStyle );
|
|
int iLine = 1;
|
|
while( pItem!=pSeg ){
|
|
pItem = GetNextItem( pItem );
|
|
iLine++;
|
|
}
|
|
|
|
SetSelect( pSeg, iLine - m_iTopLine );
|
|
|
|
ShowSelItem();
|
|
}
|
|
else{
|
|
SetSelect( NULL, -1 );
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::VolumeChanged( TCommonItem *pItem, char volNew )
|
|
{
|
|
char volOld = pItem->iType==SEGTYPE_TRACK ? ((TTrackItem*)pItem)->pTrack->nVol
|
|
: ((TSegmentItem*)pItem)->volume;
|
|
|
|
if( volNew==(char)0x80 ){
|
|
if( pItem->IsMute() )
|
|
volNew = volOld & ~0x80;
|
|
else
|
|
volNew = volOld | 0x80;
|
|
}
|
|
else if( volOld<0 ){
|
|
volNew |= 0x80;
|
|
}
|
|
|
|
int iStage = FindItemStage( pItem );
|
|
|
|
if( iStage<0 )
|
|
return;
|
|
|
|
ChangeVolume( iStage, pItem, volNew );
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::ChangeVolume( int iStage, TCommonItem* pItem, char newVol, bool bAddUndo )
|
|
{
|
|
bool bSetUndo = false;
|
|
int volBefore, volAfter = newVol,
|
|
iUndoType = -1,
|
|
iUndoCode = -1;
|
|
TTrack* pUndoExt = NULL;
|
|
|
|
int iStartBar = FirstBar( iStage ),
|
|
iEndBar = iStartBar + g_lstOpusStages[iStage]->aBars.size();
|
|
|
|
TOpusStage* pStage = g_lstOpusStages[iStage];
|
|
TSegmentItem* pSeg = NULL;
|
|
TTrackItem* pTrkItem = NULL;
|
|
|
|
if( pItem->iType==SEGTYPE_TRACK ){
|
|
pSeg = (TSegmentItem*)pItem->up;
|
|
pTrkItem = (TTrackItem*)pItem;
|
|
}
|
|
else{
|
|
pSeg = (TSegmentItem*)pItem;
|
|
|
|
if( bAddUndo ){
|
|
bSetUndo = true;
|
|
iUndoType = UNDO_STAGE_VOL;
|
|
iUndoCode = MAKELONG( iStage, -1 );
|
|
volBefore = pStage->nVol;
|
|
}
|
|
|
|
pStage->nVol = pSeg->volume = newVol;
|
|
}
|
|
|
|
float fSegVol = pSeg->volume / 100.0;
|
|
|
|
for( int i=0; i<pStage->aTracks.size(); i++ ){
|
|
TTrack* pTrk = pStage->aTracks[i];
|
|
|
|
if( pTrkItem ){
|
|
if( pTrk==pTrkItem->pTrack ){
|
|
if( bAddUndo ){
|
|
bSetUndo = true;
|
|
iUndoType = UNDO_PROG_VOL;
|
|
iUndoCode = MAKELONG( iStage, (pTrk->iFile<<8) + pTrk->iChanSpec );
|
|
volBefore = (char)pTrk->nVol;
|
|
pUndoExt = new TTrack( pTrk );
|
|
}
|
|
|
|
pTrk->nVol = newVol;
|
|
|
|
int vol = pTrk->nVol<0 ? 0 : pTrk->nVol * fSegVol;
|
|
f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, iStartBar, iEndBar,
|
|
pTrk->iChanSpec, vol, pTrk->iFile );
|
|
|
|
if( m_bPlaying && ( pTrkItem==m_pSelItem )){
|
|
f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, 0, iEndBar-iStartBar,
|
|
pTrk->iChanSpec, vol, -1 );
|
|
}
|
|
|
|
int iMT = g_Midi.GetMidiTrackIndex( pTrk->iFile, pTrk->iChanSpec );
|
|
g_Midi.ChangeNotesVolume( iMT, iStartBar, iEndBar, vol );
|
|
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
int iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT );
|
|
m_pContentPanel->InvalidateBars( iStartBar, iEndBar-1, BAR_TRACK | iShowTrack );
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
else if( pTrk->nVol>0 ){
|
|
int vol = pTrk->nVol * fSegVol;
|
|
|
|
f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, iStartBar, iEndBar,
|
|
pTrk->iChanSpec, vol, pTrk->iFile );
|
|
|
|
if( m_bPlaying && pSeg==m_pSelItem->up ){
|
|
f_MM_SetTrackEvent( MIDI_EVENT_VOLUME, 0, iEndBar-iStartBar,
|
|
pTrk->iChanSpec, vol, -1 );
|
|
}
|
|
|
|
int iMT = g_Midi.GetMidiTrackIndex( pTrk->iFile, pTrk->iChanSpec );
|
|
g_Midi.ChangeNotesVolume( iMT, iStartBar, iEndBar, vol );
|
|
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
int iShowTrack = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT );
|
|
m_pContentPanel->InvalidateBars( iStartBar, iEndBar-1, BAR_TRACK | iShowTrack );
|
|
}
|
|
}
|
|
}
|
|
|
|
if( bSetUndo ){
|
|
TUndoLite* pLite = g_Undo.GetLastLite();
|
|
if( pLite && pLite->iType==iUndoType && pLite->iCode==iUndoCode ){
|
|
bool bMuteCurr = volBefore>=0 && volAfter<0 || volBefore<0 && volAfter>=0,
|
|
bMuteLast = ( (int)pLite->pBefore >= 0 && (int)pLite->pAfter < 0
|
|
|| (int)pLite->pBefore < 0 && (int)pLite->pAfter >= 0 );
|
|
|
|
if( bMuteCurr==bMuteLast ){
|
|
bSetUndo = false;
|
|
|
|
if( (char)pLite->pBefore==volAfter )
|
|
g_Undo.CancelUndo();
|
|
else
|
|
pLite->pAfter = (void*)volAfter;
|
|
|
|
if( pUndoExt )
|
|
delete pUndoExt;
|
|
}
|
|
}
|
|
|
|
if( bSetUndo ){
|
|
g_Undo.AddUndo( iUndoType, iUndoCode, iStartBar, iEndBar,
|
|
(void*)volBefore, (void*)volAfter );
|
|
|
|
if( pUndoExt )
|
|
g_Undo.SetUndoExtra( 0, 0, 0, pUndoExt, NULL );
|
|
}
|
|
}
|
|
|
|
if( g_iPreStage==0 ){
|
|
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
|
|
g_lstOpusStages );
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
bool TUseStylePanel::IntegrateStages( int iStageBegin, bool bSetMM )
|
|
{
|
|
iStageBegin--;
|
|
|
|
if( iStageBegin<0 )
|
|
iStageBegin = 0;
|
|
|
|
if( g_lstOpusStages.size()==0 ){
|
|
ClearAllItems();
|
|
g_pUseStyle = NULL;
|
|
}
|
|
|
|
if( g_lstOpusStages.size()<=iStageBegin ){
|
|
return false;
|
|
}
|
|
|
|
bool bIntegrated = false;
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pSegItem1 = (TSegmentItem*)pStyleItem->aItems->Items[iStageBegin];
|
|
|
|
TOpusStageList::iterator iterFirst, iterSecond;
|
|
iterFirst = iterSecond = g_lstOpusStages.begin() + iStageBegin;
|
|
|
|
while( (++iterSecond)!=g_lstOpusStages.end() ){
|
|
TOpusStage *pStage1 = *iterFirst,
|
|
*pStage2 = *iterSecond;
|
|
TSegmentItem* pSegItem2 = (TSegmentItem*)pSegItem1->next;
|
|
|
|
if( pStage1->iSegType<=SEGTYPE_FILL && pStage2->iSegType==pStage1->iSegType
|
|
&& !DiffStages( pStage1, pStage2 ) ){
|
|
if( !pStage1->aTracks.empty() ){
|
|
int num = pStage1->aTracks.size();
|
|
bool* aMatch = new bool[num];
|
|
memset( aMatch, false, sizeof(bool)*num );
|
|
|
|
for( int i=0; i<num; i++ ){
|
|
TTrack* pTrk1 = pStage1->aTracks[i];
|
|
|
|
for( int j=0; j<num; j++ ){
|
|
TTrack* pTrk2 = pStage2->aTracks[j];
|
|
if( !aMatch[j] && pTrk1->iStyleId==pTrk2->iStyleId
|
|
&& pTrk1->iStyleLoc==pTrk2->iStyleLoc
|
|
&& pTrk1->iSegNo==pTrk2->iSegNo
|
|
&& pTrk1->iChanNo==pTrk2->iChanNo
|
|
&& pTrk1->iBank==pTrk2->iBank
|
|
&& pTrk1->iProg==pTrk2->iProg
|
|
&& pTrk1->nVol==pTrk2->nVol ){
|
|
if( pTrk1->iFile==0xFF && pTrk2->iFile!=0xFF ){
|
|
pTrk1->iFile = pTrk2->iFile;
|
|
pTrk1->iChanSpec = pTrk2->iChanSpec;
|
|
}
|
|
|
|
aMatch[j] = true;
|
|
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
delete[] aMatch;
|
|
}
|
|
|
|
pSegItem1->nBars += pSegItem2->nBars;
|
|
for( int i=0; i<pStage2->aBars.size(); i++ ){
|
|
pStage1->aBars.push_back( pStage2->aBars[i] );
|
|
}
|
|
pStage2->aBars.clear();
|
|
|
|
g_Opus.ChangeStageBar( iterFirst - g_lstOpusStages.begin(), pSegItem2->nBars, false );
|
|
|
|
RemoveSegment( pSegItem2, bSetMM );
|
|
|
|
bIntegrated = true;
|
|
iterSecond = iterFirst;
|
|
}
|
|
else{
|
|
iterFirst++;
|
|
pSegItem1 = (TSegmentItem*)pSegItem1->next;
|
|
}
|
|
}
|
|
|
|
CountStyles();
|
|
|
|
HandleWeakup( iStageBegin, bSetMM );
|
|
|
|
return bIntegrated;
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::HandleWeakup( int iStageBegin, bool bSetMM )
|
|
{
|
|
if( !g_Theme.IsWeadup() || g_aAudioTracks.size()<2
|
|
|| g_aAudioTracks[0]->lstBars.empty()
|
|
|| g_aAudioTracks[1]->lstBars.empty() )
|
|
return;
|
|
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pSegItem1 = (TSegmentItem*)pStyleItem->aItems->Items[iStageBegin];
|
|
|
|
TOpusStageList::iterator iterFirst, iterSecond;
|
|
iterFirst = iterSecond = g_lstOpusStages.begin() + iStageBegin;
|
|
|
|
int iFirstBar = FirstBar( iStageBegin );
|
|
|
|
if( iFirstBar==0 ){
|
|
if( pSegItem1->iSegType<=SEGTYPE_FILL ){
|
|
if( m_bAddWeakupBar ){
|
|
TOpusStage *pStage0 = *iterFirst;
|
|
if( !memcmp( g_aAudioTracks[1]->lstBars[0]->aVols,
|
|
g_aAudioTracks[0]->lstBars[1]->aVols,
|
|
POINTS_PER_BAR * sizeof(DWORD) )){
|
|
TBar * pBar0 = new TBar( g_Theme.GetFirstBar() );
|
|
pStage0->aBars.insert( pStage0->aBars.begin(), pBar0 );
|
|
pSegItem1->nBars++;
|
|
pStyleItem->nBars++;
|
|
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
TWaveBar* pWvBar = NULL;
|
|
|
|
if( i==1 ){//音轨1添加弱起小节
|
|
pWvBar = new TWaveBar( g_aAudioTracks[0]->lstBars[0] );
|
|
if( bSetMM )
|
|
f_MM_AudioMove( 1, 0, 0, 0, 1, MODE_INSERT );
|
|
}
|
|
else{//其它音轨添加空白小节
|
|
pWvBar = new TWaveBar;
|
|
if( bSetMM )
|
|
f_MM_AudioMove( i, 0, -1, 0, 1, MODE_INSERT );
|
|
}
|
|
|
|
g_aAudioTracks[i]->lstBars.insert( g_aAudioTracks[i]->lstBars.begin(), pWvBar );
|
|
}
|
|
}
|
|
|
|
iFirstBar += pSegItem1->nBars;
|
|
iterFirst++;
|
|
iterSecond++;
|
|
}
|
|
}
|
|
else{
|
|
m_bAddWeakupBar = true;
|
|
}
|
|
}
|
|
|
|
while( pSegItem1->next && (++iterSecond)!=g_lstOpusStages.end() ){
|
|
TOpusStage *pStage1 = *iterFirst,
|
|
*pStage2 = *iterSecond;
|
|
TSegmentItem* pSegItem2 = (TSegmentItem*)pSegItem1->next;
|
|
|
|
if( pStage1->iSegType==SEGTYPE_INTRO ){
|
|
int iFirstBar2 = iFirstBar + pSegItem2->nBars;
|
|
if( pStage2->iSegType<=SEGTYPE_FILL
|
|
&& !memcmp( g_aAudioTracks[1]->lstBars[iFirstBar2]->aVols,
|
|
g_aAudioTracks[0]->lstBars[1]->aVols,
|
|
POINTS_PER_BAR * sizeof(DWORD) )){
|
|
bool bCopy = true;
|
|
for( int i=0; i<POINTS_PER_BAR; i++ ){
|
|
if( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols[i]!=0 ){
|
|
bCopy = false;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( bCopy ){
|
|
memcpy( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols,
|
|
g_aAudioTracks[0]->lstBars[0]->aVols,
|
|
POINTS_PER_BAR * sizeof(DWORD) );
|
|
if( bSetMM )
|
|
f_MM_AudioMove( 1, iFirstBar2-1, 0, 0, 1, MODE_COPY );
|
|
}
|
|
}
|
|
else{
|
|
if( !memcmp( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols,
|
|
g_aAudioTracks[0]->lstBars[0]->aVols,
|
|
POINTS_PER_BAR * sizeof(DWORD) )){
|
|
memset( g_aAudioTracks[1]->lstBars[iFirstBar2-1]->aVols, 0,
|
|
POINTS_PER_BAR * sizeof(DWORD) );
|
|
|
|
if( bSetMM )
|
|
f_MM_AudioMove( -1, 0, 1, iFirstBar2-1, iFirstBar2, MODE_ERASE );
|
|
}
|
|
}
|
|
}
|
|
|
|
iFirstBar += pSegItem1->nBars;
|
|
iterFirst++;
|
|
pSegItem1 = (TSegmentItem*)pSegItem1->next;
|
|
}
|
|
}
|
|
|
|
int TUseStylePanel::GetInsertStage( int iInsertBar )
|
|
{
|
|
int iFirstBar,
|
|
iDestStage = FindStage( iInsertBar, &iFirstBar );
|
|
|
|
if( iDestStage>=0 ){
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iDestStage];
|
|
|
|
if( iInsertBar!=iFirstBar ){//分段插入
|
|
int nBarNum = pSrcSeg->nBars - ( iInsertBar - iFirstBar );
|
|
|
|
g_Opus.CutStage( iDestStage, iInsertBar );
|
|
g_Midi.CutStage( iDestStage );
|
|
|
|
InsertSegment( iDestStage+1, pSrcSeg, nBarNum );
|
|
pSrcSeg->nBars -= nBarNum;
|
|
pStyleItem->nBars -= nBarNum;
|
|
|
|
iDestStage++;
|
|
}
|
|
}
|
|
else if( iInsertBar>0 ){
|
|
iDestStage = g_lstOpusStages.size();
|
|
}
|
|
|
|
return iDestStage;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
TTrackItem* TUseStylePanel::AddTrack( TSegmentItem* pSeg, TTrack* pSrcTrk, int iInd )
|
|
{
|
|
TTrackItem* pDestTrk = NULL;
|
|
|
|
if( pSeg && pSrcTrk ){
|
|
int nTrksBefore = pSeg->aItems->Count;
|
|
TPROSTYLE* info = GetStyleInfo( pSrcTrk->iStyleLoc, pSrcTrk->iStyleId );
|
|
|
|
if( info ){
|
|
DWORD opts = OPT_DEL|OPT_VOL;
|
|
if( pSeg->iSegType<SEGTYPE_INTRO )
|
|
opts |= OPT_TEXTURE;
|
|
|
|
pDestTrk = pSeg->AddTrack( info, pSrcTrk, opts, false, iInd );
|
|
|
|
int nTrksAfter = pSeg->aItems->Count;
|
|
if( pSeg->IsUnfold() && nTrksAfter!=nTrksBefore ){
|
|
m_nTotalLine += nTrksAfter-nTrksBefore;
|
|
}
|
|
}
|
|
}
|
|
|
|
return pDestTrk;
|
|
}
|
|
|
|
void __fastcall TUseStylePanel::InsertStage( int iInsertBar, TSegmentItem* pSrcSeg )
|
|
{
|
|
Stop();
|
|
|
|
int iDestStage = GetInsertStage( iInsertBar );
|
|
|
|
TOpusStage* pNewStage = new TOpusStage;
|
|
pNewStage->iSegKey = g_iMelodyKey;
|
|
pNewStage->iSegNo = pSrcSeg->iSegNo;
|
|
pNewStage->iSegType = pSrcSeg->iSegType;
|
|
pNewStage->nVol = pSrcSeg->volume;
|
|
|
|
int nBarNum = 0;
|
|
if( pSrcSeg->iSegType>=SEGTYPE_INTRO )
|
|
nBarNum = pSrcSeg->nBars;
|
|
|
|
bool bPreChange = g_iPreStage==0;
|
|
if( bPreChange ){
|
|
DuplicateRawBars();
|
|
}
|
|
|
|
for( int j=0; j<nBarNum; j++ ){
|
|
TBar* pBar = new TBar;
|
|
pNewStage->aBars.push_back(pBar);
|
|
}
|
|
|
|
bool bCountDown = false;
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
bCountDown |= MoveAudio( -1, 0, nBarNum, i, iInsertBar, MODE_INSERT | OPT_BARS );
|
|
}
|
|
|
|
ProduceTracks( pNewStage, pSrcSeg );
|
|
|
|
g_Opus.InsertStage( iDestStage, pNewStage );
|
|
g_Midi.InsertStage( iDestStage );
|
|
|
|
int nMTCountOld = g_aMidiTracks.size();
|
|
for( int i=0; i<pNewStage->aTracks.size(); i++ ){
|
|
TTrack* pTrack = pNewStage->aTracks[i];
|
|
|
|
TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iDestStage, pTrack->iFile, pTrack->iChanNo,
|
|
pTrack->iBank, pTrack->iProg );
|
|
pTrack->iFile = pMT->file;
|
|
pTrack->iChanSpec = pMT->chno;
|
|
}
|
|
|
|
if( bPreChange || nMTCountOld!=g_aMidiTracks.size() )
|
|
m_pContentPanel->InitialVars();
|
|
|
|
InsertSegment( iDestStage, pSrcSeg, nBarNum );
|
|
|
|
IntegrateStages( iDestStage );
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
|
|
m_pContentPanel->OnStageChanged( iDestStage, MODE_INSERT );
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::RemoveStage( int iStage )
|
|
{
|
|
TStyleItem* pStyle = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pSegItem = (TSegmentItem*)pStyle->aItems->Items[iStage];
|
|
|
|
bool bPreChange = g_iPreStage==0;
|
|
if( bPreChange )
|
|
DuplicateRawBars();
|
|
|
|
f_MM_AddUndoBefore( -1, NULL );
|
|
|
|
SetBarsUndo( UNDO_BAR_DELETE, FirstBar(iStage), pSegItem->nBars );
|
|
|
|
RemoveSegment( pSegItem );
|
|
|
|
f_MM_AddUndoAfter( -1, NULL );
|
|
|
|
IntegrateStages( iStage );
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
// InvalidateRgn( Handle, NULL, false );
|
|
|
|
if( bPreChange )
|
|
m_pContentPanel->InitialVars();
|
|
|
|
m_pContentPanel->OnStageChanged( iStage, MODE_DELETE );
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::MoveBars( int iStartBar, int iEndBar, int iInsertBar, int iMode )
|
|
{
|
|
if( iMode==MODE_MOVE && ( iInsertBar>=iStartBar && iInsertBar<=iEndBar+1 ) )//无须移动
|
|
return;
|
|
|
|
Stop();
|
|
|
|
bool bPreChange = g_iPreStage==0;
|
|
if( bPreChange )
|
|
DuplicateRawBars();
|
|
|
|
int nBars = iEndBar - iStartBar + 1,
|
|
nOrigBars = g_Opus.BarCount();
|
|
|
|
if( iMode==MODE_DELETE ){
|
|
SetBarsUndo( UNDO_BAR_DELETE, iStartBar, nBars );
|
|
}
|
|
else if( iMode==MODE_MOVE ){
|
|
SetBarsUndo( UNDO_BAR_MOVE, iStartBar, nBars, iInsertBar );
|
|
}
|
|
|
|
f_MM_AddUndoBefore( -1, NULL );
|
|
|
|
int iDestStage = GetInsertStage( iInsertBar ),
|
|
iSrcStage = FindStage( iStartBar, NULL ),
|
|
iFirstChangeStage = (iMode==MODE_MOVE) ? min(iSrcStage, iDestStage) :
|
|
(iMode==MODE_DELETE) ? iSrcStage : iDestStage;
|
|
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
|
|
if( g_Theme.IsWeadup() && iStartBar==0 && iEndBar==0
|
|
&& ( iMode==MODE_MOVE || iMode==MODE_DELETE )){
|
|
TOpusStage* pFirstStage = g_lstOpusStages[iSrcStage];
|
|
if( pFirstStage->iSegType<=SEGTYPE_FILL ){
|
|
if( !memcmp( g_aAudioTracks[1]->lstBars[0]->aVols,
|
|
g_aAudioTracks[0]->lstBars[0]->aVols,
|
|
POINTS_PER_BAR * sizeof(DWORD) )){
|
|
m_bAddWeakupBar = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
// 音频操作
|
|
bool bCountDown = false;
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
bCountDown |= MoveAudio( i, iStartBar, iEndBar+1, i, iInsertBar, iMode | OPT_BARS );
|
|
}
|
|
|
|
// 曲式操作
|
|
int iBar = iStartBar;
|
|
int nBarCount = 0, nMTCount = g_aMidiTracks.size();
|
|
while( iBar<=iEndBar ){
|
|
int iFirstBar, nOffsetBar;
|
|
|
|
iSrcStage = FindStage( iBar, &iFirstBar ),
|
|
nOffsetBar = iBar-iFirstBar;
|
|
|
|
TSegmentItem* pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iSrcStage];
|
|
|
|
TOpusStage* pOriStage = g_lstOpusStages[iSrcStage];
|
|
TOpusStage* pNewStage = (iMode==MODE_DELETE) ? NULL : new TOpusStage;
|
|
int nCopyBar = pOriStage->aBars.size() - nOffsetBar;
|
|
if( nCopyBar>iEndBar-iBar+1 )
|
|
nCopyBar = iEndBar-iBar+1;
|
|
|
|
if( pNewStage ){
|
|
pNewStage->iSegKey = pOriStage->iSegKey;
|
|
pNewStage->iSegNo = pOriStage->iSegNo;
|
|
pNewStage->iSegType = pOriStage->iSegType;
|
|
pNewStage->nVol = pOriStage->nVol;
|
|
|
|
for( int i=0; i<pOriStage->aTracks.size(); i++ ){
|
|
TTrack * pTrack = new TTrack( pOriStage->aTracks[i] );
|
|
|
|
pNewStage->aTracks.push_back( pTrack );
|
|
}
|
|
}
|
|
|
|
int iCopyBar = nOffsetBar;
|
|
for( int i=0; i<nCopyBar; i++ ){
|
|
if( pNewStage ){
|
|
TBar* pBar = NULL;
|
|
if( iMode==MODE_COPY )
|
|
pBar = new TBar( pOriStage->aBars[iCopyBar] );
|
|
else
|
|
pBar = pOriStage->aBars[iCopyBar];
|
|
|
|
pNewStage->aBars.push_back( pBar );
|
|
}
|
|
|
|
if( iMode==MODE_MOVE || iMode==MODE_DELETE )
|
|
pOriStage->aBars.erase( pOriStage->aBars.begin() + iCopyBar );
|
|
else
|
|
iCopyBar++;
|
|
}
|
|
|
|
if( iMode!=MODE_DELETE ){
|
|
g_lstOpusStages.insert( g_lstOpusStages.begin()+iDestStage, pNewStage );
|
|
g_Midi.CutStage( iDestStage );
|
|
InsertSegment( iDestStage, pSrcSeg, nCopyBar );
|
|
}
|
|
|
|
if( iMode==MODE_MOVE || iMode==MODE_DELETE ){
|
|
if( iMode==MODE_MOVE && iDestStage<=iSrcStage )
|
|
iSrcStage++;
|
|
else{
|
|
iBar -= nCopyBar;
|
|
iEndBar -= nCopyBar;
|
|
}
|
|
|
|
if( pOriStage->aBars.size()==0 ){ //删除原段落
|
|
RemoveSegment( pSrcSeg );
|
|
|
|
if( iMode!=MODE_DELETE && iDestStage>=iSrcStage )
|
|
iDestStage--;
|
|
}
|
|
else{
|
|
pSrcSeg->nBars -= nCopyBar;
|
|
}
|
|
|
|
pStyleItem->nBars -= nCopyBar;
|
|
}
|
|
else if( iDestStage<=iSrcStage ){
|
|
iBar += nCopyBar;
|
|
iEndBar += nCopyBar;
|
|
}
|
|
|
|
g_Opus.CountBars();
|
|
|
|
iBar += nCopyBar;
|
|
|
|
if( iMode!=MODE_DELETE ){
|
|
nBarCount += nCopyBar;
|
|
iDestStage++;
|
|
}
|
|
}
|
|
|
|
if( iMode!=MODE_MOVE )
|
|
g_Opus.CountBars();
|
|
|
|
IntegrateStages( iFirstChangeStage );
|
|
|
|
f_MM_AddUndoAfter( -1, NULL );
|
|
|
|
if( iMode==MODE_COPY ){
|
|
SetBarsUndo( UNDO_BAR_INSERT, iInsertBar, nBars );
|
|
}
|
|
else{
|
|
//计算是否AddWeakupBar
|
|
bool bAddWeakupBar = false;
|
|
int nCurrBars = g_Opus.BarCount();
|
|
|
|
if( iMode==MODE_MOVE && nCurrBars>nOrigBars
|
|
|| iMode==MODE_DELETE && nCurrBars>nOrigBars-nBars )
|
|
bAddWeakupBar = true;
|
|
|
|
if( bAddWeakupBar )
|
|
g_Undo.SetUndoCode( bAddWeakupBar );
|
|
}
|
|
|
|
if( iMode==MODE_DELETE ){
|
|
m_pContentPanel->SelectBars( -1, - 1 );
|
|
|
|
/* if( pStyleItem->aItems->Count==0 ){
|
|
// g_Midi.ClearMidiTracks();
|
|
ClearAllItems();
|
|
g_pUseStyle = NULL;
|
|
}
|
|
*/
|
|
}
|
|
else if( iMode==MODE_COPY || iInsertBar<iStartBar ){
|
|
m_pContentPanel->SelectBars( iInsertBar, iInsertBar + nBars - 1 );
|
|
}
|
|
else if( iInsertBar>iEndBar ){
|
|
m_pContentPanel->SelectBars( iInsertBar - nBars, iInsertBar - 1 );
|
|
}
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
|
|
bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0;
|
|
if( bPreChange || (bDeletedMT || nMTCount!=g_aMidiTracks.size() )
|
|
&& !m_pContentPanel->IsVertical() )
|
|
m_pContentPanel->InitialVars();
|
|
|
|
m_pContentPanel->OnStageChanged( bCountDown ? 0 : iFirstChangeStage, iMode );
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::ReformBars( int iStartBarP, int iEndBarP,
|
|
TSegmentItem* pSrcSeg, bool bAddUndo )
|
|
{
|
|
Stop();
|
|
|
|
int iStartBar = iStartBarP;
|
|
int iChangeStage = -1;
|
|
|
|
TOpusStageList* lstStageBefore = NULL;
|
|
if( bAddUndo ){
|
|
lstStageBefore = new TOpusStageList;
|
|
g_Opus.CopyStages( iStartBarP, iEndBarP, lstStageBefore );
|
|
}
|
|
|
|
while( iStartBar<=iEndBarP ){
|
|
int iFirstBar,
|
|
iStage = FindStage( iStartBar, &iFirstBar );
|
|
TOpusStage* pOriStage = g_lstOpusStages[iStage];
|
|
|
|
if( pOriStage->iSegType>=SEGTYPE_INTRO ){
|
|
iStartBar = iFirstBar + pOriStage->aBars.size();
|
|
}
|
|
else{
|
|
bool bChange = false;
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pOriSegItem = (TSegmentItem*)pStyleItem->aItems->Items[iStage];
|
|
TSegmentItem* pDestSegItem = NULL;
|
|
|
|
if( pOriStage->iSegType==pSrcSeg->iSegType
|
|
&& pOriStage->iSegNo==pSrcSeg->iSegNo
|
|
&& pOriStage->nVol==pSrcSeg->volume
|
|
&& pOriStage->aTracks.size()==pSrcSeg->aItems->Count ){
|
|
if( pOriStage->aTracks.size()>0 ){
|
|
int num = pOriStage->aTracks.size();
|
|
bool* aMatch = new bool[num];
|
|
memset( aMatch, false, sizeof(bool)*num );
|
|
|
|
for( int i=0; i<num; i++ ){
|
|
TTrack* pTrk1 = pOriStage->aTracks[i];
|
|
|
|
bool bFound = false;
|
|
for( int j=0; j<num; j++ ){
|
|
TTrack* pTrk2 = ((TTrackItem*)pSrcSeg->aItems->Items[j])->pTrack;
|
|
if( !aMatch[j] && pTrk1->iStyleId==pTrk2->iStyleId
|
|
&& pTrk1->iStyleLoc==pTrk2->iStyleLoc
|
|
&& pTrk1->iSegNo==pTrk2->iSegNo
|
|
&& pTrk1->iChanNo==pTrk2->iChanNo
|
|
&& pTrk1->iBank==pTrk2->iBank
|
|
&& pTrk1->iProg==pTrk2->iProg
|
|
&& pTrk1->nVol==pTrk2->nVol ){
|
|
bFound = true;
|
|
aMatch[j] = true;
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( !bFound ){
|
|
bChange = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
delete[] aMatch;
|
|
}
|
|
}
|
|
else
|
|
bChange = true;
|
|
|
|
if( !bChange )
|
|
iStartBar = iFirstBar + pOriStage->aBars.size();
|
|
else{
|
|
TOpusStage* pBrushStage = NULL;
|
|
int iEndBar = iFirstBar + pOriStage->aBars.size()-1;
|
|
if( iEndBar>iEndBarP ){
|
|
g_Opus.CutStage( iStage, iEndBarP+1 );
|
|
g_Midi.CutStage( iStage );
|
|
|
|
InsertSegment( iStage+1, pOriSegItem, iEndBar - iEndBarP );
|
|
pOriSegItem->nBars -= iEndBar - iEndBarP;
|
|
pStyleItem->nBars -= iEndBar - iEndBarP;
|
|
|
|
iEndBar = iEndBarP;
|
|
}
|
|
|
|
if( iStartBar>iFirstBar ){
|
|
g_Opus.CutStage( iStage, iStartBar );
|
|
g_Midi.CutStage( iStage );
|
|
|
|
pDestSegItem = InsertSegment( iStage+1, pOriSegItem, iEndBar-iStartBar+1 );
|
|
pOriSegItem->nBars -= iEndBar-iStartBar+1;
|
|
pStyleItem->nBars -= iEndBar-iStartBar+1;
|
|
|
|
iStage++;
|
|
}
|
|
else{
|
|
pBrushStage = pOriStage;
|
|
pDestSegItem = pOriSegItem;
|
|
}
|
|
|
|
ReplaceSegment( pDestSegItem, pSrcSeg );
|
|
|
|
//g_Opus.CountBars();
|
|
|
|
iStartBar = iEndBar + 1;
|
|
|
|
if( iChangeStage<0 )
|
|
iChangeStage = iStage;
|
|
}
|
|
}
|
|
}
|
|
|
|
if( iChangeStage>=0 ){
|
|
IntegrateStages( iChangeStage );
|
|
|
|
if( bAddUndo ){
|
|
TOpusStageList* lstStageAfter = new TOpusStageList;
|
|
g_Opus.CopyStages( iStartBarP, iEndBarP, lstStageAfter );
|
|
|
|
g_Undo.AddUndo( UNDO_BAR_CHANGE, 0, iStartBarP, iEndBarP,
|
|
(void*)lstStageBefore, (void*)lstStageAfter );
|
|
}
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
|
|
m_pContentPanel->OnStageChanged( iChangeStage, MODE_CHANGE );
|
|
}
|
|
else if( lstStageBefore ){
|
|
for( int i=0; i<lstStageBefore->size(); i++ ){
|
|
delete (*lstStageBefore)[i];
|
|
}
|
|
|
|
delete lstStageBefore;
|
|
}
|
|
}
|
|
|
|
void __fastcall TUseStylePanel::ReformStage( int iDestStage, TSegmentItem* pSrcSeg )
|
|
{
|
|
Stop();
|
|
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pDestSeg = (TSegmentItem*)pStyleItem->aItems->Items[iDestStage];
|
|
|
|
int iStartBar = FirstBar( iDestStage ),
|
|
iEndBar = iStartBar + pDestSeg->nBars -1,
|
|
nOffset = 0;
|
|
bool bMMUndo = false;
|
|
|
|
TAudioTrackList* lstAudio = NULL;
|
|
TOpusStageList* lstStageBefore = new TOpusStageList;
|
|
g_Opus.CopyStages( iStartBar, iEndBar, lstStageBefore );
|
|
|
|
if( pSrcSeg->iSegType>=SEGTYPE_INTRO && pSrcSeg->nBars!=pDestSeg->nBars ){
|
|
nOffset = pSrcSeg->nBars - pDestSeg->nBars;
|
|
|
|
if( nOffset<0 ){ //小节减少,复制将删除部分波形
|
|
int nWaveBars = -nOffset;
|
|
lstAudio = new TAudioTrackList;
|
|
|
|
g_Audio.CopyTrackList( iEndBar+nOffset+1, nWaveBars, lstAudio );
|
|
}
|
|
|
|
bMMUndo = true;
|
|
}
|
|
|
|
if( bMMUndo ){
|
|
f_MM_AddUndoBefore( -1, NULL );
|
|
}
|
|
|
|
ReplaceSegment( pDestSeg, pSrcSeg );
|
|
|
|
IntegrateStages( iDestStage );
|
|
|
|
// if( bMMUndo ){
|
|
// f_MM_AddUndoAfter( -1, NULL );
|
|
// }
|
|
|
|
TOpusStageList* lstStageAfter = new TOpusStageList;
|
|
g_Opus.CopyStages( iStartBar, iEndBar+nOffset, lstStageAfter );
|
|
|
|
g_Undo.AddUndo( UNDO_BAR_CHANGE, 0, iStartBar, iEndBar,
|
|
(void*)lstStageBefore, (void*)lstStageAfter );
|
|
|
|
if( bMMUndo ){
|
|
f_MM_AddUndoAfter( -1, NULL );
|
|
g_Undo.SetUndoExtra( nOffset, 0, 0, (void*)lstAudio, NULL );
|
|
}
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
|
|
m_pContentPanel->OnStageChanged( iDestStage, MODE_CHANGE );
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::InitOpus( TStyleItem* pPreStyle, int iMode )
|
|
{
|
|
//清空内容
|
|
ClearGlobalVars( LIST_OPUSSTAGES | LIST_OPUSAUDIOS );
|
|
ClearAllItems();
|
|
|
|
g_pUseStyle = NULL;
|
|
m_bAddWeakupBar = true;
|
|
|
|
if( iMode<0 || !pPreStyle ){
|
|
ClearGlobalVars( LIST_RAWAUDIO );
|
|
m_pContentPanel->InitialVars();
|
|
Paint();
|
|
|
|
return;
|
|
}
|
|
|
|
if( iMode==0 ){
|
|
UINT idLoc, idStyle;
|
|
g_Theme.Get( idLoc, idStyle, g_lstOpusStages );
|
|
|
|
g_pUseStyle = AddStyle( GetStyleInfo( idLoc, idStyle ) );
|
|
|
|
for( int i=0; i<g_lstOpusStages.size(); i++ ){
|
|
TOpusStage* pStage = g_lstOpusStages[i];
|
|
AddStage( pStage );
|
|
}
|
|
|
|
g_aAudioTracks[0]->Hide(false);
|
|
|
|
((TStyleItem*)m_aItems->First())->SetCharge( g_pUseStyle->pStyle->idLoc==0
|
|
&& g_pUseStyle->pStyle->pOrigin->cost>0 );
|
|
}
|
|
else{
|
|
g_pUseStyle = AddStyle( pPreStyle->pStyle );
|
|
|
|
int iFirstStage = g_Theme.IsWeadup() ? 1 : 0;
|
|
int nRepeat = iMode>=2 ? 2 : 1;
|
|
|
|
int nSegNum[4];
|
|
vector<TSegmentItem*> aSegments[4];
|
|
memset( nSegNum, 0, sizeof(int)*4 );
|
|
|
|
for( int i=0; i<pPreStyle->aItems->Count; i++ ){
|
|
TSegmentItem* pSegment = (TSegmentItem*)pPreStyle->aItems->Items[i];
|
|
int stype = pSegment->GetSegType();
|
|
aSegments[stype].push_back( pSegment );
|
|
nSegNum[stype]++;
|
|
}
|
|
|
|
if( g_aAudioTracks[0]->lstBars.size()>0 ){
|
|
DuplicateRawBars();
|
|
|
|
if( iMode==2 )
|
|
MoveAudio( 1, 0, g_aAudioTracks[0]->lstBars.size(), 1, 0, MODE_COPY | OPT_BARS );
|
|
}
|
|
|
|
int iSegNo;
|
|
int nBarCount = 0;
|
|
int nThemeStages = g_Theme.StageCount();
|
|
|
|
while( nRepeat>0 ){
|
|
if( iMode>0 && iMode<=3 && nSegNum[SEGTYPE_INTRO]>0 ){ //添加前奏
|
|
int iM = iMode>=2 ? 2 : 1;
|
|
iSegNo = (iM - nRepeat) % nSegNum[SEGTYPE_INTRO];
|
|
int iChord = g_Theme.GetFirstChord();
|
|
int ctype = LOWORD( iChord ),
|
|
key = HIWORD( iChord );
|
|
|
|
if( ctype==3 ) ctype = 1;
|
|
else if( ctype>1 ) ctype = 0;
|
|
|
|
if( ctype==1 )
|
|
key = ( key + 3 ) % 12;
|
|
|
|
TSegmentItem *pSegment = NULL;
|
|
TSegmentItem* pBackup = NULL;
|
|
|
|
for( int j=0; j<nSegNum[SEGTYPE_INTRO]; j++ ){
|
|
if( aSegments[SEGTYPE_INTRO][j]->iSegNo / 4 == ctype ){
|
|
if( aSegments[SEGTYPE_INTRO][j]->iSegNo % 4 == iSegNo ){
|
|
pSegment = aSegments[SEGTYPE_INTRO][j];
|
|
break;
|
|
}
|
|
else{
|
|
pBackup = aSegments[SEGTYPE_INTRO][j];
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !pSegment ){
|
|
if( pBackup )
|
|
pSegment = pBackup;
|
|
else
|
|
pSegment = aSegments[SEGTYPE_INTRO][0]; //大小调不分
|
|
}
|
|
|
|
TOpusStage* pNewStage = new TOpusStage;
|
|
pNewStage->iSegNo = pSegment->iSegNo;
|
|
pNewStage->iSegType = SEGTYPE_INTRO;
|
|
pNewStage->iSegKey = key;
|
|
pNewStage->nVol = pSegment->volume;
|
|
|
|
int nBarNum = pSegment->nBars;
|
|
for( int i=0; i<nBarNum; i++ ){
|
|
TBar* pBar = new TBar;
|
|
pNewStage->aBars.push_back(pBar);
|
|
}
|
|
|
|
ProduceTracks( pNewStage, pSegment );
|
|
|
|
g_lstOpusStages.push_back( pNewStage );
|
|
|
|
int nWaveBars = nBarNum;
|
|
if( iFirstStage>0 )
|
|
nWaveBars--;
|
|
|
|
if( g_aAudioTracks.size()>1 )
|
|
MoveAudio( -1, 0, nWaveBars, 1, nBarCount, MODE_INSERT | OPT_BARS );
|
|
|
|
InsertSegment( -1, pSegment, nBarNum );
|
|
|
|
nBarCount += nBarNum;
|
|
}
|
|
|
|
//添加主旋律部分
|
|
iSegNo = 0;
|
|
int iStartStage = iFirstStage;
|
|
|
|
if( iMode>2 && nRepeat==1 && nThemeStages>iFirstStage + 2 ){
|
|
iStartStage++;
|
|
if( nSegNum[SEGTYPE_VAR]>1 )
|
|
iSegNo = 1;
|
|
}
|
|
|
|
for( int i=iStartStage; i<nThemeStages; i++ ){
|
|
TOpusStage* pStage = g_Theme.CopyStageAt( i );
|
|
|
|
g_lstOpusStages.push_back( pStage );
|
|
TSegmentItem* pSegItem = AddStage( pStage );
|
|
|
|
nBarCount += pStage->aBars.size();
|
|
|
|
if( i==nThemeStages-1 && nSegNum[SEGTYPE_FILL]>0 && pStage->aBars.size()>1
|
|
&& iMode>0 && iMode<=3 && ( nRepeat>0 && nSegNum[SEGTYPE_INTRO]>0
|
|
|| nRepeat==0 && nSegNum[SEGTYPE_ENDING]>0 )){
|
|
int iFill = 1 % nSegNum[SEGTYPE_FILL];
|
|
TSegmentItem *pSegFill = aSegments[SEGTYPE_FILL][iFill];
|
|
TOpusStage * pFillStage = new TOpusStage;
|
|
|
|
pFillStage->iSegType = SEGTYPE_FILL;
|
|
pFillStage->iSegNo = pSegFill->iSegNo;
|
|
pFillStage->iSegKey = pStage->iSegKey;
|
|
pFillStage->nVol = pStage->nVol;
|
|
pFillStage->aBars.push_back( pStage->aBars.back() );
|
|
|
|
pStage->aBars.pop_back();
|
|
pSegItem->nBars--;
|
|
g_pUseStyle->nBars--;
|
|
|
|
ProduceTracks( pFillStage, pSegFill );
|
|
|
|
g_lstOpusStages.push_back( pFillStage );
|
|
|
|
AddStage( pFillStage );
|
|
}
|
|
}
|
|
|
|
nRepeat--;
|
|
}
|
|
|
|
if( iMode<=3 && nSegNum[SEGTYPE_ENDING]>0 ){ //添加尾奏
|
|
int iChord = g_Theme.GetLastChord();
|
|
int ctype = LOWORD( iChord ),
|
|
key = HIWORD( iChord );
|
|
|
|
if( ctype==3 ) ctype = 1;
|
|
else if( ctype>1 ) ctype = 0;
|
|
|
|
if( ctype==1 )
|
|
key = ( key + 3 ) % 12;
|
|
|
|
TSegmentItem *pSegment = NULL;
|
|
|
|
for( int j=0; j<nSegNum[SEGTYPE_ENDING]; j++ ){
|
|
if( aSegments[SEGTYPE_ENDING][j]->iSegNo / 4 == ctype ){
|
|
pSegment = aSegments[SEGTYPE_ENDING][j];
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( !pSegment ){
|
|
pSegment = aSegments[SEGTYPE_ENDING][0]; //大小调不分
|
|
}
|
|
|
|
TOpusStage* pNewStage = new TOpusStage;
|
|
pNewStage->iSegType = SEGTYPE_ENDING;
|
|
pNewStage->iSegNo = pSegment->iSegNo;
|
|
pNewStage->iSegKey = key;
|
|
pNewStage->nVol = pSegment->volume;
|
|
|
|
int nBarNum = pSegment->nBars;
|
|
for( int i=0; i<nBarNum; i++ ){
|
|
TBar* pBar = new TBar;
|
|
pNewStage->aBars.push_back(pBar);
|
|
}
|
|
|
|
ProduceTracks( pNewStage, pSegment );
|
|
|
|
g_lstOpusStages.push_back( pNewStage );
|
|
|
|
if( g_aAudioTracks.size()>1 )
|
|
MoveAudio( -1, 0, nBarNum, 1, nBarCount, MODE_INSERT | OPT_BARS );
|
|
|
|
InsertSegment( -1, pSegment, nBarNum );
|
|
|
|
nBarCount += nBarNum;
|
|
}
|
|
}
|
|
|
|
g_Opus.CountBars();
|
|
IntegrateStages( 0 );
|
|
g_Midi.SortMidiTracks();
|
|
|
|
SetFold( (TCommonItem*)m_aItems->First(), 0 );
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
// InvalidateRgn( Handle, NULL, false );
|
|
|
|
m_pContentPanel->OnStageChanged( 0, MODE_INIT );
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::SetStyleItem( TStyleItem* pStyItem )
|
|
{
|
|
TStylePanel::SetStyleItem( pStyItem );
|
|
|
|
if( pStyItem ){
|
|
IntegrateStages( 0, false );
|
|
if( g_Midi.IsEmpty() )
|
|
g_Midi.SortMidiTracks();
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::RestoreItems()
|
|
{
|
|
for( int i=0; i<g_lstOpusStages.size(); i++ ){
|
|
AddStage( g_lstOpusStages[i] );
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void __fastcall TUseStylePanel::InsertBlankBar( int iInsertBar )
|
|
{
|
|
Stop();
|
|
|
|
TOpusStage* pNewStage = new TOpusStage;
|
|
TBar * pNewBar = new TBar;
|
|
pNewStage->aBars.push_back( pNewBar ); //添加一个小节
|
|
|
|
int iBarT1 = iInsertBar;
|
|
// 处理弱起
|
|
if( g_bWeakup ){
|
|
if( iInsertBar>0 ){
|
|
int iFirstBar,
|
|
iLastStage = FindStage( iInsertBar-1, &iFirstBar );
|
|
TOpusStage *pLastStage = g_lstOpusStages[iLastStage];
|
|
if( pLastStage->iSegType>SEGTYPE_FILL
|
|
&& !memcmp( g_aAudioTracks[1]->lstBars[iInsertBar-1]->aVols,
|
|
g_aAudioTracks[0]->lstBars[0]->aVols,
|
|
POINTS_PER_BAR * sizeof(DWORD) )){
|
|
iBarT1--;
|
|
}
|
|
}
|
|
}
|
|
|
|
bool bCountDown = false;
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
// 音效处理
|
|
bCountDown |= MoveAudio( -1, 0, 1, i, iInsertBar, MODE_INSERT | OPT_BARS );
|
|
}
|
|
|
|
int iDestStage = GetInsertStage( iInsertBar );
|
|
|
|
TStyleItem* pStyleItem = (TStyleItem*)m_aItems->First();
|
|
|
|
//根据前后小节位置确定和弦与伴奏型
|
|
TSegmentItem *pSrcSeg = NULL;
|
|
int iFirstBar1, iFirstBar2,
|
|
iLastStage = FindStage( iInsertBar-1, &iFirstBar1 ),
|
|
iNextStage = FindStage( iInsertBar, &iFirstBar2 );
|
|
TOpusStage *pLastStage = iLastStage>=0 ? g_lstOpusStages[iLastStage] : NULL,
|
|
*pNextStage = g_lstOpusStages[iNextStage];
|
|
|
|
//是否前一小节可用
|
|
if( pLastStage && pLastStage->iSegType<=SEGTYPE_FILL ){
|
|
pNewStage->iSegKey = pLastStage->iSegKey;
|
|
|
|
TBar *pLastBar = pLastStage->aBars[iInsertBar-iFirstBar1-1];
|
|
pNewBar->iBarKey = pLastBar->iBarKey;
|
|
|
|
for( int i=0; i<g_nChordNumPerBar; i++ ){
|
|
pNewBar->aChords.iKey[i] = pLastBar->aChords.iKey[g_nChordNumPerBar-1];
|
|
pNewBar->aChords.iType[i] = pLastBar->aChords.iType[g_nChordNumPerBar-1];
|
|
}
|
|
pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iLastStage];
|
|
}
|
|
else if( pNextStage->iSegType<=SEGTYPE_FILL ){ //是否后一小节可用
|
|
pNewStage->iSegKey = pNextStage->iSegKey;
|
|
|
|
TBar *pNextBar = pNextStage->aBars[iInsertBar-iFirstBar2];
|
|
pNewBar->iBarKey = pNextBar->iBarKey;
|
|
|
|
for( int i=0; i<g_nChordNumPerBar; i++ ){
|
|
pNewBar->aChords.iKey[i] = pNextBar->aChords.iKey[0];
|
|
pNewBar->aChords.iType[i] = pNextBar->aChords.iType[0];
|
|
}
|
|
pSrcSeg = (TSegmentItem*)pStyleItem->aItems->Items[iNextStage];
|
|
}
|
|
else{ //前后小节皆不可用
|
|
int iSegKey,
|
|
iKey,
|
|
iType = 0;
|
|
|
|
if( pLastStage ){
|
|
iKey = pNewBar->iBarKey = pNewStage->iSegKey = pLastStage->iSegKey;
|
|
|
|
if( pLastStage->iSegNo % 2 > 0 ){
|
|
iKey = ( iKey + 9 ) % 12;
|
|
iType = 1;
|
|
}
|
|
}
|
|
else{
|
|
iKey = pNewBar->iBarKey = pNewStage->iSegKey = pNextStage->iSegKey;
|
|
|
|
if( pNextStage->iSegNo % 2 > 0 ){ //小调
|
|
iKey = ( iKey + 9 ) % 12;
|
|
iType = 1;
|
|
}
|
|
}
|
|
|
|
for( int i=0; i<g_nChordNumPerBar; i++ ){
|
|
pNewBar->aChords.iKey[i] = iKey;
|
|
pNewBar->aChords.iType[i] = iType;
|
|
}
|
|
|
|
for( int i=0; i<g_pPreStyle->aItems->Count; i++ ){
|
|
TSegmentItem* pSegment = (TSegmentItem*)g_pPreStyle->aItems->Items[i];
|
|
int stype = pSegment->GetSegType();
|
|
if( stype==SEGTYPE_VAR || stype==SEGTYPE_FILL ){
|
|
pSrcSeg = pSegment;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
pNewStage->iSegType = pSrcSeg->iSegType;
|
|
pNewStage->iSegNo = pSrcSeg->iSegNo;
|
|
|
|
// ProduceTracks( pNewStage, pSrcSeg );
|
|
|
|
g_Opus.InsertStage( iDestStage, pNewStage );
|
|
g_Midi.InsertStage( iDestStage );
|
|
|
|
InsertSegment( iDestStage, pSrcSeg, 1 );
|
|
|
|
IntegrateStages( iDestStage );
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
|
|
m_pContentPanel->OnStageChanged( iDestStage, MODE_INSERT );
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::CountStyles()
|
|
{
|
|
m_aStyles.clear();
|
|
if( m_aItems->Count==0 )
|
|
return;
|
|
|
|
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
|
|
TPROSTYLE* pStyle = pStyItem->pStyle,
|
|
*pMainStyle = NULL;
|
|
|
|
vector<int> lstCount;
|
|
for( int i=0; i<pStyItem->aItems->Count; i++ ){
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
|
|
for( int j=0; j<pSeg->aItems->Count; j++ ){
|
|
TTrackItem* pTrk = (TTrackItem*)pSeg->aItems->Items[j];
|
|
|
|
bool bMatch = false;
|
|
for( int k=0; k<m_aStyles.size(); k++ ){
|
|
// if( pTrk->pStyle->idLoc==m_aStyles[k]->idLoc
|
|
// && pTrk->pStyle->idStyle==m_aStyles[k]->idStyle ){
|
|
if( pTrk->pStyle==m_aStyles[k] ){
|
|
bMatch = true;
|
|
lstCount[k]++;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( !bMatch ){
|
|
m_aStyles.push_back( pTrk->pStyle );
|
|
lstCount.push_back( 1 );
|
|
}
|
|
}
|
|
}
|
|
|
|
bool bKeep = false;
|
|
bool bCharge = false;
|
|
int maxCount = 0;
|
|
for( int i=0; i<lstCount.size(); i++ ){
|
|
if( lstCount[i]>maxCount ){
|
|
maxCount = lstCount[i];
|
|
pMainStyle = m_aStyles[i];
|
|
}
|
|
|
|
if( pStyle && pStyle->idLoc==m_aStyles[i]->idLoc
|
|
&& pStyle->idStyle==m_aStyles[i]->idStyle ){
|
|
bKeep = true;
|
|
}
|
|
|
|
if( !bCharge && m_aStyles[i]->idLoc==0
|
|
&& m_aStyles[i]->pOrigin->cost>0 ){
|
|
bCharge = true;
|
|
}
|
|
}
|
|
|
|
if( !pStyle || !bKeep ){
|
|
pStyItem->pStyle = pMainStyle;
|
|
|
|
if( m_pTopItem==pStyItem )
|
|
DrawItem( pStyItem, 0, -1 );
|
|
}
|
|
|
|
pStyItem->SetCharge( bCharge );
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::CopyUndoBars( int iStartBar, int iEndBar, TOpusStageList* lstStages,
|
|
TAudioTrackList* lstAudio, bool bFx )
|
|
{
|
|
if( lstStages )
|
|
g_Opus.CopyStages( iStartBar, iEndBar, lstStages );
|
|
|
|
if( lstAudio )
|
|
g_Audio.CopyTrackList( iStartBar, iEndBar-iStartBar+1, lstAudio, bFx );
|
|
}
|
|
|
|
void TUseStylePanel::CopyBars( int iStartBar, int iEndBar, TOpusStageList* lstStages,
|
|
TSegmentList* lstSegments, TAudioTrackList* lstAudio )
|
|
{
|
|
int iBar = iStartBar;
|
|
|
|
while( iBar<=iEndBar ){
|
|
int iFirstBar, iSrcStage = FindStage( iBar, &iFirstBar ),
|
|
nOffsetBar = iBar-iFirstBar;
|
|
TOpusStage* pOriStage = g_lstOpusStages[iSrcStage];
|
|
int nCopyBar = pOriStage->aBars.size() - nOffsetBar;
|
|
|
|
if( nCopyBar>iEndBar-iBar+1 )
|
|
nCopyBar = iEndBar-iBar+1;
|
|
|
|
if( lstStages ){
|
|
TOpusStage* pNewStage = new TOpusStage( pOriStage );
|
|
|
|
for( int i=nOffsetBar; i<nCopyBar; i++ ){
|
|
pNewStage->aBars.push_back( new TBar( pOriStage->aBars[i] ) );
|
|
}
|
|
|
|
for( int j=0; j<pOriStage->aTracks.size(); j++ ){
|
|
pNewStage->aTracks.push_back( new TTrack( pOriStage->aTracks[j] ));
|
|
}
|
|
|
|
lstStages->push_back( pNewStage );
|
|
}
|
|
|
|
iBar += nCopyBar;
|
|
}
|
|
|
|
if( lstAudio ){
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
TAudioTrack* pAudio = CopyAudioTrack( i, iStartBar, iEndBar-iStartBar+1 );
|
|
lstAudio->push_back( pAudio );
|
|
}
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
/*
|
|
void TUseStylePanel::InsertStages( int iInsertBar, TOpusStageList lstStages )
|
|
{
|
|
int iDestStage = GetInsertStage( iInsertBar );
|
|
|
|
for( int i=lstStages.size()-1; i>=0; i-- ){
|
|
TOpusStage* pStage = lstStages[i];
|
|
g_lstOpusStages.insert( g_lstOpusStages.begin()+iDestStage, pStage );
|
|
}
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
*/
|
|
void TUseStylePanel::DeleteBars( int iStartBarP, int iEndBarP, bool bDelWave )
|
|
{
|
|
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
|
|
int iBar = iStartBarP,
|
|
iEndBar = iEndBarP;
|
|
|
|
while( iBar<=iEndBar ){
|
|
int iFirstBar, iSrcStage = FindStage( iBar, &iFirstBar ),
|
|
nOffsetBar = iBar-iFirstBar;
|
|
|
|
TSegmentItem* pSrcSeg = (TSegmentItem*)pStyItem->aItems->Items[iSrcStage];
|
|
TOpusStage* pOriStage = g_lstOpusStages[iSrcStage];
|
|
|
|
int nDelBar = pOriStage->aBars.size() - nOffsetBar;
|
|
if( nDelBar>iEndBar-iBar+1 )
|
|
nDelBar = iEndBar-iBar+1;
|
|
|
|
pOriStage->aBars.erase( pOriStage->aBars.begin() + nOffsetBar,
|
|
pOriStage->aBars.begin() + nOffsetBar + nDelBar );
|
|
iEndBar -= nDelBar;
|
|
|
|
g_Opus.ChangeStageBar( iSrcStage, -nDelBar, true );
|
|
|
|
if( pOriStage->aBars.empty() ){ //删除原段落
|
|
RemoveSegment( pSrcSeg, false );
|
|
}
|
|
else{
|
|
pSrcSeg->nBars -= nDelBar;
|
|
}
|
|
|
|
pStyItem->nBars -= nDelBar;
|
|
}
|
|
|
|
// g_Opus.CountBars();
|
|
|
|
if( bDelWave ){
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
RemoveWaveBars( i, iStartBarP, iEndBarP - iStartBarP + 1 );
|
|
// RemoveAudioEffects( g_aAudioTracks[i]->lstEffects, iStartBarP, iEndBarP+1 );
|
|
}
|
|
}
|
|
|
|
m_pContentPanel->SelectBars( -1, -1 );
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::Undo( bool bUndo )
|
|
{
|
|
if( m_VolTrackBar ){
|
|
delete m_VolTrackBar;
|
|
m_VolTrackBar = NULL;
|
|
}
|
|
|
|
int iMode=-1, iChangeStage = 0;
|
|
TUndoLite* pLite = bUndo ? g_Undo.Undo() : g_Undo.Redo();
|
|
int iType = pLite->iType;
|
|
|
|
if( ( iType<UNDO_MIDI_ADD || iType>UNDO_MIDI_FONT )
|
|
&& ( iType<UNDO_TRKMID_ADD || iType>UNDO_TRKMID_DELALL )
|
|
&& VIEW_STYLE!=g_iViewMode )
|
|
Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_STYLE, 0 );
|
|
|
|
if( iType!=UNDO_STAGE_VOL )
|
|
Stop();
|
|
|
|
if( iType>=UNDO_BAR_INSERT && iType<=UNDO_BAR_CHANGE ){
|
|
if( bUndo && pLite->iCode>0 ){ //处理AddWeakupBar
|
|
m_bAddWeakupBar = true;
|
|
|
|
//删除第一小节
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
TAudioTrack* pAT = g_aAudioTracks[i];
|
|
|
|
delete pAT->lstBars[0];
|
|
pAT->lstBars.erase( pAT->lstBars.begin() );
|
|
}
|
|
|
|
TOpusStage* pStage = g_lstOpusStages[0];
|
|
delete pStage->aBars[0];
|
|
pStage->aBars.erase( pStage->aBars.begin() );
|
|
g_Opus.CountBars();
|
|
|
|
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pSegment = (TSegmentItem*)pStyItem->aItems->Items[0];
|
|
pSegment->nBars--;
|
|
pStyItem->nBars--;
|
|
}
|
|
|
|
int iDelStart = pLite->iBegin,
|
|
iDelEnd = pLite->iEnd,
|
|
iInsStart = pLite->iBegin,
|
|
iInsEnd = pLite->iEnd,
|
|
nBars = pLite->iEnd - pLite->iBegin + 1;
|
|
|
|
TOpusStageList* lstStages = ( iType>=UNDO_BAR_CHANGE && !bUndo || iType==UNDO_BAR_INSERT )
|
|
? (TOpusStageList*)pLite->pAfter
|
|
: (TOpusStageList*)pLite->pBefore;
|
|
|
|
if( iType<UNDO_BAR_CHANGE || pLite->iExt1 )
|
|
f_MM_Undo( bUndo );
|
|
|
|
if( iType==UNDO_BAR_INSERT && bUndo
|
|
|| iType==UNDO_BAR_DELETE && !bUndo ){
|
|
iMode = MODE_DELETE;
|
|
}
|
|
else if( iType==UNDO_BAR_INSERT && !bUndo
|
|
|| iType==UNDO_BAR_DELETE && bUndo ){
|
|
iMode = MODE_INSERT;
|
|
}
|
|
else if( iType==UNDO_BAR_MOVE ){
|
|
iMode = MODE_MOVE;
|
|
|
|
if( bUndo ){
|
|
iDelStart = pLite->iExt1;
|
|
iDelEnd = iDelStart + nBars - 1;
|
|
}
|
|
else{
|
|
iInsStart = pLite->iExt1;
|
|
iInsEnd = iInsStart + nBars - 1;
|
|
}
|
|
}
|
|
else{
|
|
iMode = MODE_CHANGE;
|
|
|
|
if( bUndo )
|
|
iDelEnd += pLite->iExt1;
|
|
else
|
|
iInsEnd += pLite->iExt1;
|
|
}
|
|
|
|
iChangeStage = FindStage( min( iDelStart, iInsStart ), NULL );
|
|
|
|
int nMTCount = g_aMidiTracks.size();
|
|
if( iMode==MODE_DELETE || iMode==MODE_MOVE || iMode==MODE_CHANGE ){
|
|
DeleteBars( iDelStart, iDelEnd, iMode==MODE_CHANGE ? false : true );
|
|
}
|
|
|
|
if( iMode==MODE_INSERT || iMode==MODE_MOVE || iMode==MODE_CHANGE ){
|
|
//还原波形
|
|
if( iMode==MODE_INSERT || iMode==MODE_MOVE ){
|
|
TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1;
|
|
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
TAudioTrack* pAudio = lstAudio ? (*lstAudio)[i-1] : NULL;
|
|
InsertAudioTrack( i, iInsStart, nBars, pAudio );
|
|
}
|
|
}
|
|
|
|
if( iMode==MODE_CHANGE ){
|
|
if( iInsEnd > iDelEnd ){
|
|
TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1;
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
TAudioTrack* pAudio = lstAudio ? (*lstAudio)[i-1] : NULL;
|
|
InsertAudioTrack( i, iDelEnd+1, iInsEnd-iDelEnd, pAudio );
|
|
}
|
|
}
|
|
else if( iInsEnd<iDelEnd ){
|
|
for( int i=1; i<g_aAudioTracks.size(); i++ ){
|
|
RemoveWaveBars( i, iInsEnd+1, iDelEnd-iInsEnd );
|
|
}
|
|
}
|
|
}
|
|
|
|
//还原Segment和OpusStage
|
|
int iStage = GetInsertStage( iInsStart );
|
|
if( iStage<0 )
|
|
iStage = 0;
|
|
|
|
for( int s=0; s<(*lstStages).size(); s++ ){
|
|
TOpusStage* pStage = DuplicateStage( (*lstStages)[s] );
|
|
g_Opus.InsertStage( iStage, pStage );
|
|
g_Midi.InsertStage( iStage );
|
|
|
|
TSegmentItem* pSegment = new TSegmentItem;
|
|
pSegment->iSegType = pStage->iSegType;
|
|
pSegment->iSegNo = pStage->iSegNo;
|
|
pSegment->volume = pStage->nVol;
|
|
pSegment->nBars = pStage->aBars.size();
|
|
|
|
DWORD opts = OPT_DEL|OPT_VOL;
|
|
if( pStage->iSegType<SEGTYPE_INTRO )
|
|
opts |= OPT_TEXTURE;
|
|
|
|
//检查风格有效性
|
|
for( int i=0; i<pStage->aTracks.size(); i++ ){
|
|
TTrack* pTrack = pStage->aTracks[i];
|
|
|
|
TPROSTYLE* pStyle = GetStyleInfo( pTrack->iStyleLoc, pTrack->iStyleId );
|
|
if( pStyle ){
|
|
pSegment->AddTrack( pStyle, pTrack, opts, false );
|
|
|
|
TMidiTrack* pMT = g_Midi.GetValidMidiTrack( iStage, pTrack->iFile, pTrack->iChanSpec,
|
|
pTrack->iBank, pTrack->iProg );
|
|
pTrack->iFile = pMT->file;
|
|
pTrack->iChanSpec = pMT->chno;
|
|
}
|
|
else{
|
|
DebugPrint( "风格文件已失效!\n" );
|
|
|
|
delete pTrack;
|
|
pStage->aTracks.erase( pStage->aTracks.begin() + i );
|
|
i--;
|
|
}
|
|
}
|
|
|
|
InsertSegment( iStage, pSegment, pStage->aBars.size() );
|
|
delete pSegment;
|
|
|
|
iStage++;
|
|
}
|
|
|
|
m_pContentPanel->SelectBars( iInsStart, iInsEnd );
|
|
}
|
|
|
|
IntegrateStages( iChangeStage, false );
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
|
|
bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0;
|
|
if( m_pContentPanel->IsVertical() && nBars==g_Opus.BarCount() ||
|
|
!m_pContentPanel->IsVertical() && ( bDeletedMT || nMTCount!=g_aMidiTracks.size()) ){
|
|
m_pContentPanel->InitialVars();
|
|
}
|
|
|
|
// if( !m_pContentPanel->IsVertical() )
|
|
// GenerateCompose();
|
|
}
|
|
else if( iType==UNDO_TRKMID_DELALL ){
|
|
if( m_pContentPanel->IsVertical() ){
|
|
if( pLite->iCode==ST_MIDI )
|
|
m_pContentPanel->SetScrollMode( false );
|
|
}
|
|
TOpusStageList* lstStages = bUndo ? (TOpusStageList*)pLite->pBefore
|
|
: (TOpusStageList*)pLite->pAfter;
|
|
TMidiTrackList *lstTracks = bUndo ? (TMidiTrackList*)pLite->pExt1 : NULL;
|
|
UINT idLoc = bUndo ? pLite->iExt1 : pLite->iExt2,
|
|
idStyle = bUndo ? pLite->iBegin : pLite->iEnd;
|
|
|
|
ClearAllItems();
|
|
g_Midi.ClearMidiTracks();
|
|
|
|
if( lstTracks ){
|
|
for( int i=0; i<lstTracks->size(); i++ ){
|
|
TMidiTrack* pMT = new TMidiTrack((*lstTracks)[i]);
|
|
g_Midi.AddMidiTrack( pMT );
|
|
}
|
|
}
|
|
|
|
g_Opus.Set( idLoc, idStyle, *lstStages );
|
|
g_Midi.SortMidiTracks();
|
|
g_Opus.BuildStyleItem();
|
|
TStylePanel::SetStyleItem( g_pUseStyle );
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
m_pContentPanel->InitialVars();
|
|
GenerateCompose();
|
|
}
|
|
else if( g_iSegColorMode==1 ){
|
|
m_pContentPanel->InvalidateBars( 0, g_Opus.BarCount()-1, BAR_DATA );
|
|
}
|
|
|
|
if( g_iPreStage==0 ){
|
|
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
|
|
g_lstOpusStages );
|
|
}
|
|
}
|
|
else if( iType>=UNDO_MIDI_ADD && iType<=UNDO_MIDI_FONT || iType==UNDO_TRKMID_ADD || iType==UNDO_TRKMID_DEL ){
|
|
if( m_pContentPanel->IsVertical() ){
|
|
if( pLite->iCode==ST_MIDI )
|
|
m_pContentPanel->SetScrollMode( false );
|
|
else if( VIEW_STYLE!=g_iViewMode )
|
|
Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_STYLE, 0 );
|
|
}
|
|
|
|
vector<DWORD> *aAddStage = (vector<DWORD>*)( bUndo ? pLite->pExt1 : pLite->pExt2 ),
|
|
*aDelStage = (vector<DWORD>*)( bUndo ? pLite->pExt2 : pLite->pExt1 );
|
|
TTrack *aAddTrks = bUndo ? (TTrack*)pLite->pBefore : (TTrack*)pLite->pAfter;
|
|
|
|
int iSBar = pLite->iBegin,
|
|
iEBar = pLite->iEnd,
|
|
iBStage = iSBar<0 ? 0 : GetInsertStage( iSBar ),
|
|
infoAdd = bUndo ? pLite->iExt1 : pLite->iExt2,
|
|
infoDel = bUndo ? pLite->iExt2 : pLite->iExt1,
|
|
iAddMT = infoAdd==-1 ? -1 : (infoAdd & 0xFF),
|
|
iDelMT = infoDel==-1 ? -1 : (infoDel & 0xFF);
|
|
BYTE iAddMTState = infoAdd==-1 ? 0 : (infoAdd & 0xFF00)>>8,
|
|
iAddMTVol = infoAdd==-1 ? 0 : (infoAdd & 0xFF0000)>>16;
|
|
char iAddMTPan = infoAdd==-1 ? 0 : (infoAdd & 0xFF000000)>>24;
|
|
|
|
if( iEBar>=0 )
|
|
GetInsertStage( iEBar+1 );
|
|
|
|
TMidiTrack *pDelMT = NULL, *pAddMT = NULL;
|
|
if( iDelMT>=0 && iDelMT<g_aMidiTracks.size() )
|
|
pDelMT = g_aMidiTracks[iDelMT];
|
|
if( iAddMT>=0 && iAddMT<g_aMidiTracks.size() )
|
|
pAddMT = g_aMidiTracks[iAddMT];
|
|
|
|
vector<DWORD>::iterator itAdd = aAddStage->begin(),
|
|
itDel = aDelStage->begin();
|
|
int iAddStage(-1), iAddTrack(-1),
|
|
iDelStage(-1), iDelTrack(-1);
|
|
|
|
if( itAdd!=aAddStage->end() ){
|
|
int iFBar = (*itAdd) & 0xFFF,
|
|
iLBar = ((*itAdd) & 0xFFF000)>>12;
|
|
|
|
iAddTrack = ((*itAdd) & 0xFF000000)>>24;
|
|
iAddStage = GetInsertStage( iFBar );
|
|
GetInsertStage( iLBar+1 );
|
|
}
|
|
|
|
if( itDel!=aDelStage->end() ){
|
|
int iFBar = (*itDel) & 0xFFF,
|
|
iLBar = ((*itDel) & 0xFFF000)>>12;
|
|
|
|
iDelTrack = ((*itDel) & 0xFF000000)>>24;
|
|
iDelStage = GetInsertStage( iFBar );
|
|
GetInsertStage( iLBar+1 );
|
|
}
|
|
|
|
bool bAddedMT = false;
|
|
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
|
|
while( itAdd!=aAddStage->end() || itDel!=aDelStage->end() ){
|
|
if( iDelStage>=0 && (iAddStage<0 || iDelStage<iAddStage) ){
|
|
TOpusStage* pStage = g_lstOpusStages[iDelStage];
|
|
TTrack* pTrack = pStage->aTracks[iDelTrack];
|
|
|
|
if( !pDelMT || pDelMT->file!=pTrack->iFile || pDelMT->chno!=pTrack->iChanSpec ){
|
|
pDelMT = g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec );
|
|
}
|
|
|
|
delete pTrack;
|
|
pStage->aTracks.erase( pStage->aTracks.begin()+iDelTrack );
|
|
|
|
TSegmentItem* pSegment = (TSegmentItem*)pStyItem->aItems->Items[iDelStage];
|
|
TTrackItem* pTrkItem = (TTrackItem*)pSegment->aItems->Items[iDelTrack];
|
|
TStylePanel::DeleteItem( pTrkItem, -1 );
|
|
|
|
pDelMT->DelStage( iDelStage );
|
|
|
|
if( ++itDel!=aDelStage->end() ){
|
|
int iFBar = (*itDel) & 0xFFF,
|
|
iLBar = ((*itDel) & 0xFFF000)>>12;
|
|
|
|
iDelTrack = ((*itDel) & 0xFF000000)>>24;
|
|
iDelStage = GetInsertStage( iFBar );
|
|
GetInsertStage( iLBar+1 );
|
|
}
|
|
else{
|
|
iDelStage = -1;
|
|
iDelTrack = -1;
|
|
}
|
|
}
|
|
else if( iDelStage>=0 && iDelStage==iAddStage ){
|
|
TOpusStage* pStage = g_lstOpusStages[iDelStage];
|
|
TTrack *pTrack = pStage->aTracks[iDelTrack],
|
|
*pSubTrack = &aAddTrks[itAdd - aAddStage->begin()];
|
|
|
|
if( !pDelMT || pDelMT->file!=pTrack->iFile || pDelMT->chno!=pTrack->iChanSpec ){
|
|
pDelMT = g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec );
|
|
}
|
|
|
|
if( pSubTrack->iFile!=pDelMT->file || pSubTrack->iChanSpec!=pDelMT->chno ){
|
|
if( !pAddMT || pAddMT->file!=pSubTrack->iFile || pAddMT->chno!=pSubTrack->iChanSpec
|
|
|| pAddMT->prog!=pSubTrack->iProg
|
|
|| !( pAddMT=g_Midi.FindMidiTrack( pSubTrack->iFile, pSubTrack->iChanSpec )) ){
|
|
pAddMT = new TMidiTrack( pSubTrack->iBank, pSubTrack->iChanSpec, pSubTrack->iProg, pSubTrack->iFile );
|
|
pAddMT->state = iAddMTState;
|
|
pAddMT->volume = iAddMTVol;
|
|
pAddMT->pan = iAddMTPan;
|
|
g_Midi.AddMidiTrack( pAddMT, iAddMT );
|
|
|
|
bAddedMT = true;
|
|
}
|
|
|
|
pDelMT->DelStage( iDelStage );
|
|
pAddMT->AddStage( iAddStage );
|
|
}
|
|
else if( pAddMT==pDelMT && pSubTrack->iProg!=pAddMT->prog ){
|
|
pAddMT->prog = pSubTrack->iProg;
|
|
}
|
|
|
|
if( pTrack->iStyleLoc!=pSubTrack->iStyleLoc
|
|
|| pTrack->iStyleId!=pSubTrack->iStyleId ){
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[iDelStage];
|
|
TTrackItem* pTrkItem = (TTrackItem*)pSeg->aItems->Items[iDelTrack];
|
|
pTrkItem->pStyle = GetStyleInfo( pSubTrack->iStyleLoc, pSubTrack->iStyleId );
|
|
}
|
|
|
|
memcpy( pTrack, pSubTrack, sizeof(TTrack) );
|
|
|
|
if( ++itAdd!=aAddStage->end() ){
|
|
int iFBar = (*itAdd) & 0xFFF,
|
|
iLBar = ((*itAdd) & 0xFFF000)>>12;
|
|
|
|
iAddTrack = ((*itAdd) & 0xFF000000)>>24;
|
|
iAddStage = GetInsertStage( iFBar );
|
|
GetInsertStage( iLBar+1 );
|
|
}
|
|
else{
|
|
iAddStage = -1,
|
|
iAddTrack = -1;
|
|
}
|
|
|
|
if( ++itDel!=aDelStage->end() ){
|
|
int iFBar = (*itDel) & 0xFFF,
|
|
iLBar = ((*itDel) & 0xFFF000)>>12;
|
|
|
|
iDelTrack = ((*itDel) & 0xFF000000)>>24;
|
|
iDelStage = GetInsertStage( iFBar );
|
|
GetInsertStage( iLBar+1 );
|
|
}
|
|
else{
|
|
iDelStage = -1;
|
|
iDelTrack = -1;
|
|
}
|
|
}
|
|
else if( iAddStage>=0 && ( iDelStage<0 || iDelStage>iAddStage ) ){
|
|
TTrack* pTrack = new TTrack( &aAddTrks[itAdd - aAddStage->begin()] );
|
|
|
|
if( !pAddMT || pAddMT->file!=pTrack->iFile || pAddMT->chno!=pTrack->iChanSpec
|
|
|| !( pAddMT=g_Midi.FindMidiTrack( pTrack->iFile, pTrack->iChanSpec )) ){
|
|
pAddMT = new TMidiTrack( pTrack->iBank, pTrack->iChanSpec, pTrack->iProg, pTrack->iFile );
|
|
pAddMT->state = iAddMTState;
|
|
pAddMT->volume = iAddMTVol;
|
|
pAddMT->pan = iAddMTPan;
|
|
g_Midi.AddMidiTrack( pAddMT, iAddMT );
|
|
|
|
bAddedMT = true;
|
|
}
|
|
|
|
TOpusStage* pStage = g_lstOpusStages[iAddStage];
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[iAddStage];
|
|
|
|
pStage->aTracks.insert( pStage->aTracks.begin()+iAddTrack, pTrack );
|
|
AddTrack( pSeg, pTrack, iAddTrack );
|
|
pAddMT->AddStage( iAddStage );
|
|
|
|
if( ++itAdd!=aAddStage->end() ){
|
|
int iFBar = (*itAdd) & 0xFFF,
|
|
iLBar = ((*itAdd) & 0xFFF000)>>12;
|
|
|
|
iAddTrack = ((*itAdd) & 0xFF000000)>>24;
|
|
iAddStage = GetInsertStage( iFBar );
|
|
GetInsertStage( iLBar+1 );
|
|
}
|
|
else{
|
|
iAddStage = -1,
|
|
iAddTrack = -1;
|
|
}
|
|
}
|
|
}
|
|
|
|
IntegrateStages( iBStage, false );
|
|
|
|
ResetScrollBar();
|
|
Paint();
|
|
|
|
bool bDeletedMT = g_Midi.ClearEmptyTrack()>=0;
|
|
if( !m_pContentPanel->IsVertical() ){
|
|
if( bDeletedMT || bAddedMT ){
|
|
m_pContentPanel->InitialVars();
|
|
}
|
|
else{
|
|
if( iDelMT>=0 ){
|
|
int iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iDelMT );
|
|
if( iST>0 )
|
|
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_TRACK | iST );
|
|
}
|
|
}
|
|
|
|
if( iAddMT>=0 && !aAddStage->empty() || iDelMT>=0 && !bDeletedMT ){
|
|
if( VIEW_TRACK!=g_iViewMode )
|
|
Application->MainForm->Perform( UM_SETVIEWMODE, VIEW_TRACK, 0 );
|
|
|
|
if( iAddMT==iDelMT )
|
|
m_pContentPanel->SelectTrack( -1, -1, -1, false );
|
|
|
|
int iMT = iAddMT>=0 && !aAddStage->empty() ? iAddMT : iDelMT,
|
|
iST = m_pContentPanel->GetShowTrackId( ST_MIDI, iMT );
|
|
|
|
if( iST>0 ){
|
|
m_pContentPanel->SelectTrack( iST-1, -1, -1, false );
|
|
m_pContentPanel->SetSelectRange( iSBar, 0, iEBar, POINTS_PER_BAR-1, true );
|
|
}
|
|
}
|
|
|
|
GenerateCompose();
|
|
}
|
|
|
|
if( g_iSegColorMode==1 && iType!=UNDO_MIDI_FONT )
|
|
m_pContentPanel->InvalidateBars( iSBar, iEBar, BAR_DATA );
|
|
|
|
}
|
|
else if( iType==UNDO_OPUS_STYLE ){ //全曲风格替换
|
|
iMode = MODE_INIT;
|
|
|
|
TAudioTrackList* lstAudio = (TAudioTrackList*)pLite->pExt1;
|
|
TOpusStageList* lstStages = (TOpusStageList*)( bUndo ? pLite->pBefore
|
|
: pLite->pAfter );
|
|
if( lstAudio ){
|
|
f_MM_Undo( bUndo );
|
|
}
|
|
|
|
g_Audio.RestoreAudio( lstStages, lstAudio, bUndo );
|
|
|
|
g_Opus.Set( pLite->iBegin, pLite->iEnd, *lstStages );
|
|
g_Opus.BuildStyleItem();
|
|
g_Midi.ClearMidiTracks();
|
|
|
|
SetStyleItem( g_pUseStyle );
|
|
|
|
if( g_iPreStage==0 ){
|
|
g_Theme.Set( g_pUseStyle->pStyle->idLoc, g_pUseStyle->pStyle->idStyle,
|
|
g_lstOpusStages );
|
|
}
|
|
}
|
|
else if( iType==UNDO_STAGE_VOL || iType==UNDO_PROG_VOL ){
|
|
int iStage = GetInsertStage( pLite->iBegin ),
|
|
nStageLen = pLite->iEnd - pLite->iBegin;
|
|
|
|
TStyleItem* pStyItem = (TStyleItem*)m_aItems->First();
|
|
TSegmentItem* pTempSeg = (TSegmentItem*)pStyItem->aItems->Items[iStage];
|
|
|
|
if( pTempSeg->iSegType<SEGTYPE_FILL && pTempSeg->nBars>nStageLen )
|
|
GetInsertStage( pLite->iEnd );
|
|
|
|
TSegmentItem* pSegItem = (TSegmentItem*)pStyItem->aItems->Items[iStage];
|
|
|
|
int iSet = (int)(bUndo ? pLite->pBefore : pLite->pAfter ),
|
|
iOther = (int)(!bUndo ? pLite->pBefore : pLite->pAfter );
|
|
|
|
TCommonItem* pSetItem = NULL;
|
|
|
|
if( iType==UNDO_STAGE_VOL ){
|
|
SetSelectStage( iStage );
|
|
pSetItem = pSegItem;
|
|
}
|
|
else{
|
|
TTrack* pExt = (TTrack*)pLite->pExt1;
|
|
|
|
for( int i=0; i<pSegItem->aItems->Count; i++ ){
|
|
TTrackItem* pTrkItem = (TTrackItem*)pSegItem->aItems->Items[i];
|
|
TTrack* pTrack = pTrkItem->pTrack;
|
|
|
|
if( pTrack->iStyleLoc==pExt->iStyleLoc && pTrack->iStyleId==pExt->iStyleId
|
|
&& pTrack->iSegNo==pExt->iSegNo && pTrack->iBank==pExt->iBank
|
|
&& pTrack->iProg==pExt->iProg && pTrack->nVol==iOther ){
|
|
pSetItem = pTrkItem;
|
|
SetSelectTrack( pTrkItem );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
ChangeVolume( iStage, pSetItem, iSet, false );
|
|
|
|
if( iSet>=0 && iOther<0 || iSet<0 && iOther>=0 ){ //静音操作
|
|
DrawItem( m_pSelItem, m_iSelLine, COL_FOLD );
|
|
}
|
|
else{
|
|
DrawItem( m_pSelItem, m_iSelLine, COL_TEXT );
|
|
DoAdjustVolume( NULL );
|
|
}
|
|
}
|
|
|
|
if( iMode>=0 )
|
|
m_pContentPanel->OnStageChanged( iChangeStage, iMode );
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::SetSelectTrack( TTrackItem* pTrack )
|
|
{
|
|
TStyleItem* pStyle = (TStyleItem*)m_aItems->Items[0];
|
|
TSegmentItem* pSeg = (TSegmentItem*)pTrack->up;
|
|
|
|
if( !pStyle->IsUnfold() ){
|
|
SetFold( pStyle, 0 );
|
|
}
|
|
|
|
TCommonItem* pItem = GetNextItem( pStyle );
|
|
int iLine = 1;
|
|
while( pItem!=pSeg ){
|
|
pItem = GetNextItem( pItem );
|
|
iLine++;
|
|
}
|
|
|
|
if( !pSeg->IsUnfold() ){
|
|
SetFold( pSeg, iLine );
|
|
}
|
|
|
|
while( pItem!=pTrack ){
|
|
pItem = GetNextItem( pItem );
|
|
iLine++;
|
|
}
|
|
|
|
SetSelect( pTrack, iLine - m_iTopLine );
|
|
|
|
ShowSelItem();
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
bool __fastcall TUseStylePanel::GetPrebeat( BYTE* pData, int& nSize )
|
|
{
|
|
if( m_aItems->Count==0 )
|
|
return false;
|
|
|
|
TStyleItem* pStyItem = (TStyleItem*)m_aItems->Items[0];
|
|
TTrack* pDrumTrk = NULL;
|
|
|
|
for( int i=pStyItem->aItems->Count-1; !pDrumTrk && i>=0; i-- ){
|
|
TSegmentItem* pSeg = (TSegmentItem*)pStyItem->aItems->Items[i];
|
|
int stype = pSeg->GetSegType();
|
|
|
|
if( stype!=SEGTYPE_ENDING ){
|
|
for( int j=0; j<pSeg->aItems->Count; j++ ){
|
|
TTrack* pTrk = ((TTrackItem*)pSeg->aItems->Items[j])->pTrack;
|
|
|
|
if( pTrk->iChanNo==9 ){
|
|
pDrumTrk = pTrk;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( pDrumTrk ){
|
|
int nStageNum = 1;
|
|
TStage* aStages = new TStage[nStageNum];
|
|
aStages[0].iSegType = SEGTYPE_VAR;
|
|
aStages[0].iSegKey = 0;
|
|
aStages[0].nBarNum = 4;
|
|
aStages[0].aChords = new TBarChords[aStages[0].nBarNum];
|
|
for( int j=0; j<4; j++ ){
|
|
aStages[0].aChords[j].iKey[0]
|
|
= aStages[0].aChords[j].iKey[1]
|
|
= aStages[0].aChords[j].iKey[2]
|
|
= aStages[0].aChords[j].iKey[3] = 0;
|
|
aStages[0].aChords[j].iType[0]
|
|
= aStages[0].aChords[j].iType[1]
|
|
= aStages[0].aChords[j].iType[2]
|
|
= aStages[0].aChords[j].iType[3] = 0;
|
|
}
|
|
|
|
//tracks
|
|
aStages[0].nTrkNum = 1;
|
|
aStages[0].aTracks = new TComposeTrack[aStages[0].nTrkNum];
|
|
aStages[0].aTracks[0].iStyleLoc = pDrumTrk->iStyleLoc;
|
|
aStages[0].aTracks[0].iStyleId = pDrumTrk->iStyleId;
|
|
aStages[0].aTracks[0].iSegNo = pDrumTrk->iSegNo;
|
|
aStages[0].aTracks[0].iChanNo = pDrumTrk->iChanNo;
|
|
aStages[0].aTracks[0].iChanSpec = pDrumTrk->iChanSpec;
|
|
aStages[0].aTracks[0].iProg = pDrumTrk->iProg;
|
|
aStages[0].aTracks[0].nVol = 110;
|
|
|
|
int ret = f_CM_Compose( &nSize, pData, g_iMelodyTimeSignature, g_nMelodyTempo,
|
|
nStageNum, aStages, false, NULL, NULL );
|
|
|
|
if( ret==0 ){
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
// ---------------------------------------------------------------------------
|
|
|
|
void TUseStylePanel::SetBarsUndo( int iMode, int iStartBar, int nBars, int iMoveTo )
|
|
{
|
|
int iEndBar = iStartBar + nBars - 1;
|
|
|
|
TOpusStageList* lstStages = new TOpusStageList;
|
|
TAudioTrackList* lstAudio = new TAudioTrackList;
|
|
|
|
CopyUndoBars( iStartBar, iEndBar, lstStages, lstAudio );
|
|
|
|
void *pBefore = iMode==UNDO_BAR_INSERT ? NULL : (void*)lstStages,
|
|
*pAfter = iMode==UNDO_BAR_INSERT ? (void*)lstStages : NULL;
|
|
|
|
g_Undo.AddUndo( iMode, 0, iStartBar, iEndBar, pBefore, pAfter );
|
|
|
|
if( iMode==UNDO_BAR_MOVE && iMoveTo > iStartBar )
|
|
iMoveTo -= nBars;
|
|
|
|
g_Undo.SetUndoExtra( iMoveTo, 0, 0, (void*)lstAudio, NULL );
|
|
}
|
|
//---------------------------------------------------------------------------
|
|
|
|
|