3652 |
UpdateVelocityTable(); |
UpdateVelocityTable(); |
3653 |
} |
} |
3654 |
|
|
3655 |
|
/** @brief Change type of an existing dimension. |
3656 |
|
* |
3657 |
|
* Alters the dimension type of a dimension already existing on this |
3658 |
|
* region. If there is currently no dimension on this Region with type |
3659 |
|
* @a oldType, then this call with throw an Exception. Likewise there are |
3660 |
|
* cases where the requested dimension type cannot be performed. For example |
3661 |
|
* if the new dimension type shall be gig::dimension_samplechannel, and the |
3662 |
|
* current dimension has more than 2 zones. In such cases an Exception is |
3663 |
|
* thrown as well. |
3664 |
|
* |
3665 |
|
* @param oldType - identifies the existing dimension to be changed |
3666 |
|
* @param newType - to which dimension type it should be changed to |
3667 |
|
* @throws gig::Exception if requested change cannot be performed |
3668 |
|
*/ |
3669 |
|
void Region::SetDimensionType(dimension_t oldType, dimension_t newType) { |
3670 |
|
if (oldType == newType) return; |
3671 |
|
dimension_def_t* def = GetDimensionDefinition(oldType); |
3672 |
|
if (!def) |
3673 |
|
throw gig::Exception("No dimension with provided old dimension type exists on this region"); |
3674 |
|
if (newType == dimension_samplechannel && def->zones != 2) |
3675 |
|
throw gig::Exception("Cannot change to dimension type 'sample channel', because existing dimension does not have 2 zones"); |
3676 |
|
if (GetDimensionDefinition(newType)) |
3677 |
|
throw gig::Exception("There is already a dimension with requested new dimension type on this region"); |
3678 |
|
def->dimension = newType; |
3679 |
|
def->split_type = __resolveSplitType(newType); |
3680 |
|
} |
3681 |
|
|
3682 |
DimensionRegion* Region::GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase) { |
DimensionRegion* Region::GetDimensionRegionByBit(const std::map<dimension_t,int>& DimCase) { |
3683 |
uint8_t bits[8] = {}; |
uint8_t bits[8] = {}; |
3684 |
for (std::map<dimension_t,int>::const_iterator it = DimCase.begin(); |
for (std::map<dimension_t,int>::const_iterator it = DimCase.begin(); |
4121 |
for (int i = 0; i < nameSize; ++i) |
for (int i = 0; i < nameSize; ++i) |
4122 |
Name[i] = ckScri->ReadUint8(); |
Name[i] = ckScri->ReadUint8(); |
4123 |
// to handle potential future extensions of the header |
// to handle potential future extensions of the header |
4124 |
ckScri->SetPos(headerSize - 6*sizeof(int32_t) + nameSize, RIFF::stream_curpos); |
ckScri->SetPos(sizeof(int32_t) + headerSize); |
4125 |
// read actual script data |
// read actual script data |
4126 |
uint32_t scriptSize = ckScri->GetSize() - ckScri->GetPos(); |
uint32_t scriptSize = ckScri->GetSize() - ckScri->GetPos(); |
4127 |
data.resize(scriptSize); |
data.resize(scriptSize); |
4425 |
if (lst3LS) { |
if (lst3LS) { |
4426 |
RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL); |
RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL); |
4427 |
if (ckSCSL) { |
if (ckSCSL) { |
4428 |
int slotCount = ckSCSL->ReadUint32(); |
int headerSize = ckSCSL->ReadUint32(); |
4429 |
int slotSize = ckSCSL->ReadUint32(); |
int slotCount = ckSCSL->ReadUint32(); |
4430 |
int unknownSpace = slotSize - 2*sizeof(uint32_t); // in case of future extensions |
if (slotCount) { |
4431 |
for (int i = 0; i < slotCount; ++i) { |
int slotSize = ckSCSL->ReadUint32(); |
4432 |
_ScriptPooolEntry e; |
ckSCSL->SetPos(headerSize); // in case of future header extensions |
4433 |
e.fileOffset = ckSCSL->ReadUint32(); |
int unknownSpace = slotSize - 2*sizeof(uint32_t); // in case of future slot extensions |
4434 |
e.bypass = ckSCSL->ReadUint32() & 1; |
for (int i = 0; i < slotCount; ++i) { |
4435 |
if (unknownSpace) ckSCSL->SetPos(unknownSpace, RIFF::stream_curpos); // in case of future extensions |
_ScriptPooolEntry e; |
4436 |
scriptPoolFileOffsets.push_back(e); |
e.fileOffset = ckSCSL->ReadUint32(); |
4437 |
|
e.bypass = ckSCSL->ReadUint32() & 1; |
4438 |
|
if (unknownSpace) ckSCSL->SetPos(unknownSpace, RIFF::stream_curpos); // in case of future extensions |
4439 |
|
scriptPoolFileOffsets.push_back(e); |
4440 |
|
} |
4441 |
} |
} |
4442 |
} |
} |
4443 |
} |
} |
4520 |
} |
} |
4521 |
|
|
4522 |
// own gig format extensions |
// own gig format extensions |
4523 |
if (pScriptRefs) { |
if (ScriptSlotCount()) { |
4524 |
|
// make sure we have converted the original loaded script file |
4525 |
|
// offsets into valid Script object pointers |
4526 |
|
LoadScripts(); |
4527 |
|
|
4528 |
RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS); |
RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS); |
4529 |
if (!lst3LS) lst3LS = pCkInstrument->AddSubList(LIST_TYPE_3LS); |
if (!lst3LS) lst3LS = pCkInstrument->AddSubList(LIST_TYPE_3LS); |
4530 |
const int totalSize = pScriptRefs->size() * 2*sizeof(uint32_t); |
const int slotCount = pScriptRefs->size(); |
4531 |
|
const int headerSize = 3 * sizeof(uint32_t); |
4532 |
|
const int slotSize = 2 * sizeof(uint32_t); |
4533 |
|
const int totalChunkSize = headerSize + slotCount * slotSize; |
4534 |
RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL); |
RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL); |
4535 |
if (!ckSCSL) ckSCSL = lst3LS->AddSubChunk(CHUNK_ID_SCSL, totalSize); |
if (!ckSCSL) ckSCSL = lst3LS->AddSubChunk(CHUNK_ID_SCSL, totalChunkSize); |
4536 |
else ckSCSL->Resize(totalSize); |
else ckSCSL->Resize(totalChunkSize); |
4537 |
uint8_t* pData = (uint8_t*) ckSCSL->LoadChunkData(); |
uint8_t* pData = (uint8_t*) ckSCSL->LoadChunkData(); |
4538 |
for (int i = 0, pos = 0; i < pScriptRefs->size(); ++i) { |
int pos = 0; |
4539 |
int fileOffset = |
store32(&pData[pos], headerSize); |
4540 |
(*pScriptRefs)[i].script->pChunk->GetFilePos() - |
pos += sizeof(uint32_t); |
4541 |
(*pScriptRefs)[i].script->pChunk->GetPos() - |
store32(&pData[pos], slotCount); |
4542 |
CHUNK_HEADER_SIZE; |
pos += sizeof(uint32_t); |
4543 |
store32(&pData[pos], fileOffset); |
store32(&pData[pos], slotSize); |
4544 |
|
pos += sizeof(uint32_t); |
4545 |
|
for (int i = 0; i < slotCount; ++i) { |
4546 |
|
// arbitrary value, the actual file offset will be updated in |
4547 |
|
// UpdateScriptFileOffsets() after the file has been resized |
4548 |
|
int bogusFileOffset = 0; |
4549 |
|
store32(&pData[pos], bogusFileOffset); |
4550 |
pos += sizeof(uint32_t); |
pos += sizeof(uint32_t); |
4551 |
store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0); |
store32(&pData[pos], (*pScriptRefs)[i].bypass ? 1 : 0); |
4552 |
pos += sizeof(uint32_t); |
pos += sizeof(uint32_t); |
4553 |
} |
} |
4554 |
|
} else { |
4555 |
|
// no script slots, so get rid of any LS custom RIFF chunks (if any) |
4556 |
|
RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS); |
4557 |
|
if (lst3LS) pCkInstrument->DeleteSubChunk(lst3LS); |
4558 |
} |
} |
4559 |
} |
} |
4560 |
|
|
4561 |
|
void Instrument::UpdateScriptFileOffsets() { |
4562 |
|
// own gig format extensions |
4563 |
|
if (pScriptRefs) { |
4564 |
|
RIFF::List* lst3LS = pCkInstrument->GetSubList(LIST_TYPE_3LS); |
4565 |
|
RIFF::Chunk* ckSCSL = lst3LS->GetSubChunk(CHUNK_ID_SCSL); |
4566 |
|
const int slotCount = pScriptRefs->size(); |
4567 |
|
const int headerSize = 3 * sizeof(uint32_t); |
4568 |
|
ckSCSL->SetPos(headerSize); |
4569 |
|
for (int i = 0; i < slotCount; ++i) { |
4570 |
|
uint32_t fileOffset = |
4571 |
|
(*pScriptRefs)[i].script->pChunk->GetFilePos() - |
4572 |
|
(*pScriptRefs)[i].script->pChunk->GetPos() - |
4573 |
|
CHUNK_HEADER_SIZE; |
4574 |
|
ckSCSL->WriteUint32(&fileOffset); |
4575 |
|
// jump over flags entry (containing the bypass flag) |
4576 |
|
ckSCSL->SetPos(sizeof(uint32_t), RIFF::stream_curpos); |
4577 |
|
} |
4578 |
|
} |
4579 |
|
} |
4580 |
|
|
4581 |
/** |
/** |
4582 |
* Returns the appropriate Region for a triggered note. |
* Returns the appropriate Region for a triggered note. |
4583 |
* |
* |
4713 |
if (scriptPoolFileOffsets.empty()) return; |
if (scriptPoolFileOffsets.empty()) return; |
4714 |
File* pFile = (File*) GetParent(); |
File* pFile = (File*) GetParent(); |
4715 |
for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) { |
for (uint k = 0; k < scriptPoolFileOffsets.size(); ++k) { |
4716 |
uint32_t offset = scriptPoolFileOffsets[k].fileOffset; |
uint32_t soughtOffset = scriptPoolFileOffsets[k].fileOffset; |
4717 |
for (uint i = 0; pFile->GetScriptGroup(i); ++i) { |
for (uint i = 0; pFile->GetScriptGroup(i); ++i) { |
4718 |
ScriptGroup* group = pFile->GetScriptGroup(i); |
ScriptGroup* group = pFile->GetScriptGroup(i); |
4719 |
for (uint s = 0; group->GetScript(s); ++s) { |
for (uint s = 0; group->GetScript(s); ++s) { |
4720 |
Script* script = group->GetScript(s); |
Script* script = group->GetScript(s); |
4721 |
if (script->pChunk) { |
if (script->pChunk) { |
4722 |
script->pChunk->SetPos(0); |
uint32_t offset = script->pChunk->GetFilePos() - |
4723 |
if (script->pChunk->GetFilePos() - |
script->pChunk->GetPos() - |
4724 |
script->pChunk->GetPos() - |
CHUNK_HEADER_SIZE; |
4725 |
CHUNK_HEADER_SIZE == offset) |
if (offset == soughtOffset) |
4726 |
{ |
{ |
4727 |
_ScriptPooolRef ref; |
_ScriptPooolRef ref; |
4728 |
ref.script = script; |
ref.script = script; |
5981 |
if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf); |
if (einf && pVersion && pVersion->major == 3) pRIFF->MoveSubChunk(_3crc, einf); |
5982 |
} |
} |
5983 |
} |
} |
5984 |
|
|
5985 |
|
void File::UpdateFileOffsets() { |
5986 |
|
DLS::File::UpdateFileOffsets(); |
5987 |
|
|
5988 |
|
for (Instrument* instrument = GetFirstInstrument(); instrument; |
5989 |
|
instrument = GetNextInstrument()) |
5990 |
|
{ |
5991 |
|
instrument->UpdateScriptFileOffsets(); |
5992 |
|
} |
5993 |
|
} |
5994 |
|
|
5995 |
/** |
/** |
5996 |
* Enable / disable automatic loading. By default this properyt is |
* Enable / disable automatic loading. By default this properyt is |