MCPcopy Create free account
hub / github.com/OpenNFS/OpenNFS / ParseMAP

Method ParseMAP

src/Loaders/music_loader.cpp:326–396  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

324}
325
326void MusicLoader::ParseMAP(const std::string &map_path, const std::string &mus_path) {
327 FILE *pcm_file = fopen("stereo.pcm", "wb");
328
329 std::cout << "- Parsing MAP File " << std::endl;
330 ifstream map(map_path, ios::in | ios::binary);
331
332 // Read the MAP file header
333 MAPHeader *mapHeader = static_cast<MAPHeader *>(calloc(1, sizeof(MAPHeader)));
334 map.read((char *) mapHeader, sizeof(MAPHeader));
335 std::cout << (int) mapHeader->bNumSections << " Sections" << std::endl;
336
337 MAPSectionDef *sectionDefTable = static_cast<MAPSectionDef *>(calloc(mapHeader->bNumSections,
338 sizeof(MAPSectionDef)));
339 map.read((char *) sectionDefTable, mapHeader->bNumSections * sizeof(MAPSectionDef));
340
341 // Skip over seemlingly useless records
342 map.seekg(mapHeader->bNumRecords * 0x10, ios_base::cur); // bRecordSize may be incorrect, use 0x10 to be safe
343
344 uint32_t *startingPositions = static_cast<uint32_t *>(calloc(mapHeader->bNumSections, sizeof(long)));
345
346 for (int startPos_Idx = 0; startPos_Idx < mapHeader->bNumSections; ++startPos_Idx) {
347 uint32_t startingPosition;
348 map.read((char *) &startingPosition, sizeof(uint32_t));
349 startingPositions[startPos_Idx] = SWAPuint32_t(startingPosition);
350 }
351
352 std::cout << "MAP File successfully parsed. Playing back MUS file." << std::endl;
353
354 FILE *mus_file = fopen(mus_path.c_str(), "rb");
355
356 // Get starting position of first section
357 uint8_t section_Idx = mapHeader->bFirstSection;
358
359 // TODO: Linear playthrough until I work out the looping malarkey
360 for (auto lol = 0; lol < mapHeader->bNumSections; ++lol)
361 {
362 if (!ReadSCHl(mus_file, startingPositions[lol], pcm_file)) { //
363 std::cout << "Error reading SCHl block, POS: " << (int)lol << " Offset: " << startingPositions[lol] << std::endl;
364 break;
365 }
366 }
367
368 // Out of spec: Track number of times played section, use to set next section
369 auto playedSections = std::map<uint8_t, int8_t>();
370
371
372 while (sectionDefTable[section_Idx].bNumRecords > 0 && section_Idx < mapHeader->bNumSections) {
373 // Starting positions are raw offsets into MUS file
374 // Read the SCH1 header and further blocks in MUS to play the section
375 if (!ReadSCHl(mus_file, startingPositions[section_Idx], pcm_file)) { //
376 std::cout << "Error reading SCHl block, POS: " << (int) section_Idx << " Offset: " << startingPositions[section_Idx] << std::endl;
377 break;
378 }
379
380 // Check if we've already played this section before. If we have, drop record number, else set to highest record index
381 playedSections[section_Idx] = playedSections.count(section_Idx) ? playedSections[section_Idx]-1 : sectionDefTable[section_Idx].bNumRecords - 1;
382
383 // If played all next records, quit playback? TODO: Implies that Track data must correlate to MAP derived loops

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected