bool NamcoSnesInstrSet::GetInstrPointers() { uint8_t maxSampCount = 0x80; if (spcDirAddr < addrTuningTable) { uint16_t sampCountCandidate = (addrTuningTable - spcDirAddr) / 4; if (sampCountCandidate < maxSampCount) { maxSampCount = (uint8_t)sampCountCandidate; } } usedSRCNs.clear(); for (uint8_t srcn = 0; srcn < maxSampCount; srcn++) { uint32_t addrDIRentry = spcDirAddr + (srcn * 4); if (!SNESSampColl::IsValidSampleDir(rawfile, addrDIRentry, true)) { continue; } uint16_t addrSampStart = GetShort(addrDIRentry); if (addrSampStart < spcDirAddr) { continue; } uint32_t ofsTuningEntry; ofsTuningEntry = addrTuningTable + (srcn * 2); if (ofsTuningEntry + 2 > 0x10000) { break; } uint16_t sampleRate = GetShort(ofsTuningEntry); if (sampleRate == 0 || sampleRate == 0xffff) { continue; } usedSRCNs.push_back(srcn); std::wostringstream instrName; instrName << L"Instrument " << srcn; NamcoSnesInstr * newInstr = new NamcoSnesInstr(this, version, srcn, spcDirAddr, ofsTuningEntry, instrName.str()); aInstrs.push_back(newInstr); } if (aInstrs.size() == 0) { return false; } std::sort(usedSRCNs.begin(), usedSRCNs.end()); SNESSampColl * newSampColl = new SNESSampColl(NamcoSnesFormat::name, this->rawfile, spcDirAddr, usedSRCNs); if (!newSampColl->LoadVGMFile()) { delete newSampColl; return false; } return true; }
bool HudsonSnesInstrSet::GetInstrPointers() { usedSRCNs.clear(); for (uint8_t instrNum = 0; instrNum < unLength / 4; instrNum++) { uint32_t ofsInstrEntry = dwOffset + (instrNum * 4); if (ofsInstrEntry + 4 > 0x10000) { break; } uint8_t srcn = GetByte(ofsInstrEntry); uint32_t addrDIRentry = spcDirAddr + (srcn * 4); if (!SNESSampColl::IsValidSampleDir(rawfile, addrDIRentry, true)) { continue; } uint32_t ofsTuningEnt = addrSampTuningTable + srcn * 4; if (ofsTuningEnt + 4 > 0x10000) { continue; } usedSRCNs.push_back(srcn); std::wostringstream instrName; instrName << L"Instrument " << instrNum; HudsonSnesInstr *newInstr = new HudsonSnesInstr(this, version, ofsInstrEntry, instrNum, spcDirAddr, addrSampTuningTable, instrName.str()); aInstrs.push_back(newInstr); } if (aInstrs.size() == 0) { return false; } std::sort(usedSRCNs.begin(), usedSRCNs.end()); SNESSampColl *newSampColl = new SNESSampColl(HudsonSnesFormat::name, this->rawfile, spcDirAddr, usedSRCNs); if (!newSampColl->LoadVGMFile()) { delete newSampColl; return false; } return true; }
void RareSnesScanner::SearchForRareSnesFromARAM(RawFile *file) { RareSnesVersion version = RARESNES_NONE; uint32_t ofsSongLoadASM; uint32_t ofsVCmdExecASM; uint32_t addrSeqHeader; uint32_t addrVCmdTable; wstring name = file->tag.HasTitle() ? file->tag.title : RawFile::removeExtFromPath(file->GetFileName()); // find a sequence if (file->SearchBytePattern(ptnSongLoadDKC2, ofsSongLoadASM)) { addrSeqHeader = file->GetShort(file->GetByte(ofsSongLoadASM + 8)); } else if (file->SearchBytePattern(ptnSongLoadDKC, ofsSongLoadASM) && file->GetShort(ofsSongLoadASM + 13) == file->GetShort(ofsSongLoadASM + 8) + 1) { addrSeqHeader = file->GetShort(ofsSongLoadASM + 8); } else { return; } // guess engine version if (file->SearchBytePattern(ptnVCmdExecDKC2, ofsVCmdExecASM)) { addrVCmdTable = file->GetShort(ofsVCmdExecASM + 10); if (file->GetShort(addrVCmdTable + (0x0c * 2)) != 0) { if (file->GetShort(addrVCmdTable + (0x11 * 2)) != 0) { version = RARESNES_WNRN; } else { version = RARESNES_DKC2; } } else { version = RARESNES_KI; } } else if (file->SearchBytePattern(ptnVCmdExecDKC, ofsVCmdExecASM)) { addrVCmdTable = file->GetShort(ofsVCmdExecASM + 12); version = RARESNES_DKC; } else { return; } // load sequence RareSnesSeq *newSeq = new RareSnesSeq(file, version, addrSeqHeader, name); if (!newSeq->LoadVGMFile()) { delete newSeq; return; } // Rare engine has a instrument # <--> SRCN # table, find it uint32_t ofsReadSRCNASM; if (!file->SearchBytePattern(ptnReadSRCNTable, ofsReadSRCNASM)) { return; } uint32_t addrSRCNTable = file->GetShort(ofsReadSRCNASM + 5); if (addrSRCNTable + 0x100 > 0x10000) { return; } // find DIR address uint32_t ofsSetDIRASM; if (!file->SearchBytePattern(ptnLoadDIR, ofsSetDIRASM)) { return; } uint32_t spcDirAddr = file->GetByte(ofsSetDIRASM + 4) << 8; // scan SRCN table RareSnesInstrSet *newInstrSet = new RareSnesInstrSet(file, addrSRCNTable, spcDirAddr, newSeq->instrUnityKeyHints, newSeq->instrPitchHints, newSeq->instrADSRHints); if (!newInstrSet->LoadVGMFile()) { delete newInstrSet; return; } // get SRCN # range uint8_t maxSRCN = 0; std::vector<uint8_t> usedSRCNs; const std::vector<uint8_t> &availInstruments = newInstrSet->GetAvailableInstruments(); for (std::vector<uint8_t>::const_iterator itr = availInstruments.begin(); itr != availInstruments.end(); ++itr) { uint8_t inst = (*itr); uint8_t srcn = file->GetByte(addrSRCNTable + inst); if (maxSRCN < srcn) { maxSRCN = srcn; } std::vector<uint8_t>::iterator itrSRCN = find(usedSRCNs.begin(), usedSRCNs.end(), srcn); if (itrSRCN == usedSRCNs.end()) { usedSRCNs.push_back(srcn); } } std::sort(usedSRCNs.begin(), usedSRCNs.end()); // load BRR samples SNESSampColl *newSampColl = new SNESSampColl(RareSnesFormat::name, file, spcDirAddr, usedSRCNs); if (!newSampColl->LoadVGMFile()) { delete newSampColl; return; } }