| 777 | } |
| 778 | |
| 779 | void CFamiTrackerDocIO::LoadPatterns(CFamiTrackerModule &modfile, int ver) { |
| 780 | fds_adjust_arps_ = ver < 5; // // // |
| 781 | bool compat200 = (file_.GetFileVersion() == 0x0200); // // // |
| 782 | |
| 783 | if (ver == 1) { |
| 784 | int PatternLen = AssertRange(file_.GetBlockInt(), 0, MAX_PATTERN_LENGTH, "Pattern data count"); |
| 785 | modfile.GetSong(0)->SetPatternLength(PatternLen); |
| 786 | } |
| 787 | |
| 788 | const CChannelOrder &order = modfile.GetChannelOrder(); // // // |
| 789 | |
| 790 | while (!file_.BlockDone()) { |
| 791 | unsigned Track = 0; |
| 792 | if (ver > 1) |
| 793 | Track = AssertRange(file_.GetBlockInt(), 0, static_cast<int>(MAX_TRACKS) - 1, "Pattern song index"); |
| 794 | |
| 795 | unsigned Channel = AssertRange((unsigned)file_.GetBlockInt(), 0u, CHANID_COUNT - 1, "Pattern track index"); |
| 796 | AssertRange<MODULE_ERROR_OFFICIAL>(Channel, 0u, MAX_CHANNELS - 1, "Pattern track index"); |
| 797 | unsigned Pattern = AssertRange(file_.GetBlockInt(), 0, MAX_PATTERN - 1, "Pattern index"); |
| 798 | unsigned Items = AssertRange(file_.GetBlockInt(), 0, MAX_PATTERN_LENGTH, "Pattern data count"); |
| 799 | stChannelID ch = order.TranslateChannel(Channel); |
| 800 | |
| 801 | auto *pSong = modfile.GetSong(Track); |
| 802 | |
| 803 | for (unsigned i = 0; i < Items; ++i) try { |
| 804 | unsigned Row; |
| 805 | if (compat200 || ver >= 6) |
| 806 | Row = static_cast<unsigned char>(file_.GetBlockChar()); |
| 807 | else |
| 808 | Row = AssertRange(file_.GetBlockInt(), 0, 0xFF, "Row index"); // // // |
| 809 | |
| 810 | try { |
| 811 | stChanNote Note; // // // |
| 812 | |
| 813 | Note.Note = enum_cast<note_t>(AssertRange<MODULE_ERROR_STRICT>( // // // |
| 814 | file_.GetBlockChar(), value_cast(note_t::none), value_cast(note_t::echo), "Note value")); |
| 815 | Note.Octave = AssertRange<MODULE_ERROR_STRICT>( |
| 816 | file_.GetBlockChar(), 0, OCTAVE_RANGE - 1, "Octave value"); |
| 817 | int Inst = static_cast<unsigned char>(file_.GetBlockChar()); |
| 818 | if (Inst != HOLD_INSTRUMENT) // // // 050B |
| 819 | AssertRange<MODULE_ERROR_STRICT>(Inst, 0, CInstrumentManager::MAX_INSTRUMENTS, "Instrument index"); |
| 820 | Note.Instrument = Inst; |
| 821 | Note.Vol = AssertRange<MODULE_ERROR_STRICT>( |
| 822 | file_.GetBlockChar(), 0, MAX_VOLUME, "Channel volume"); |
| 823 | |
| 824 | int FX = compat200 ? 1 : ver >= 6 ? MAX_EFFECT_COLUMNS : |
| 825 | pSong->GetEffectColumnCount(order.TranslateChannel(Channel)); // // // 050B |
| 826 | for (int n = 0; n < FX; ++n) try { |
| 827 | auto EffectNumber = (effect_t)file_.GetBlockChar(); |
| 828 | if (Note.Effects[n].fx = static_cast<effect_t>(EffectNumber); Note.Effects[n].fx != effect_t::none) { |
| 829 | AssertRange<MODULE_ERROR_STRICT>(value_cast(EffectNumber), value_cast(effect_t::none), value_cast(effect_t::max), "Effect index"); |
| 830 | unsigned char EffectParam = file_.GetBlockChar(); |
| 831 | if (ver < 3) { |
| 832 | if (EffectNumber == effect_t::PORTAOFF) { |
| 833 | EffectNumber = effect_t::PORTAMENTO; |
| 834 | EffectParam = 0; |
| 835 | } |
| 836 | else if (EffectNumber == effect_t::PORTAMENTO) { |
nothing calls this directly
no test coverage detected