--- libgig/trunk/src/gig.cpp 2019/12/14 17:04:28 3656 +++ libgig/trunk/src/gig.cpp 2020/01/10 11:21:59 3709 @@ -3412,7 +3412,7 @@ } File* pFile = (File*) GetParent()->GetParent(); - bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2; + const bool versiongt2 = pFile->pVersion && pFile->pVersion->major > 2; const int iMaxDimensions = versiongt2 ? 8 : 5; const int iMaxDimensionRegions = versiongt2 ? 256 : 32; @@ -3459,6 +3459,32 @@ } store32(&pData[iWavePoolOffset + i * 4], iWaveIndex); } + + if (versiongt2) { + // add 3dnm list which always seems to be empty + RIFF::List* _3dnm = pCkRegion->GetSubList(LIST_TYPE_3DNM); + if (!_3dnm) _3dnm = pCkRegion->AddSubList(LIST_TYPE_3DNM); + + // add 3ddp chunk which always seems to have 16 bytes of 0xFF + RIFF::Chunk* _3ddp = pCkRegion->GetSubChunk(CHUNK_ID_3DDP); + if (!_3ddp) _3ddp = pCkRegion->AddSubChunk(CHUNK_ID_3DDP, 16); + uint8_t* pData = (uint8_t*) _3ddp->LoadChunkData(); + for (int i = 0; i < 16; i += 4) { + store32(&pData[i], 0xFFFFFFFF); + } + + // move 3dnm and 3ddp to the end of the region list + pCkRegion->MoveSubChunk(pCkRegion->GetSubList(LIST_TYPE_3DNM), (RIFF::Chunk*)NULL); + pCkRegion->MoveSubChunk(pCkRegion->GetSubChunk(CHUNK_ID_3DDP), (RIFF::Chunk*)NULL); + } else { + // this is intended for the user switching from GSt >= 3 version + // back to an older format version, delete GSt3 chunks ... + RIFF::List* _3dnm = pCkRegion->GetSubList(LIST_TYPE_3DNM); + if (_3dnm) pCkRegion->DeleteSubChunk(_3dnm); + + RIFF::Chunk* _3ddp = pCkRegion->GetSubChunk(CHUNK_ID_3DDP); + if (_3ddp) pCkRegion->DeleteSubChunk(_3ddp); + } } void Region::LoadDimensionRegions(RIFF::List* rgn) { @@ -3997,9 +4023,23 @@ // now tempRegion's dimensions and DimensionRegions basically reflect // what we wanted to get for this actual Region here, so we now just // delete and recreate the dimension in question with the new amount - // zones and then copy back from tempRegion - DeleteDimension(oldDef); - AddDimension(&newDef); + // zones and then copy back from tempRegion. we're actually deleting and + // recreating all dimensions here, to avoid altering the precise order + // of the dimensions (which would not be an error per so, but it would + // cause usability issues with instrument editors) + { + std::vector oldDefs; + for (int i = 0; i < Dimensions; ++i) + oldDefs.push_back(pDimensionDefinitions[i]); // copy, don't reference + for (int i = Dimensions - 1; i >= 0; --i) + DeleteDimension(&pDimensionDefinitions[i]); + for (int i = 0; i < oldDefs.size(); ++i) { + dimension_def_t& def = oldDefs[i]; + AddDimension( + (def.dimension == newDef.dimension) ? &newDef : &def + ); + } + } for (int iSrc = 0; iSrc < 256; ++iSrc) { DimensionRegion* srcDimRgn = tempRgn->pDimensionRegions[iSrc]; if (!srcDimRgn) continue;