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;
}
Beispiel #2
0
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;
}
Beispiel #3
0
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;
  }
}