It looks like the code on jeskola.net was old so it didn't have the latest features like pitch bend record. It's updated now and I think you might be able to automatically merge it with your new code. There are some other important changes like UpdateWaveReferences (template paste). Here's the whole diff:
Code: Select all
diff old/ActionStack.cpp new/ActionStack.cpp
21c21
< int oldsize = pdata->size();
---
> int oldsize = (int)pdata->size();
83a84
> s.scrollpos = pew->pe.GetScrollPos();
101a103
> pew->pe.ScrollTo(ps->scrollpos);
diff old/ActionStack.h new/ActionStack.h
13a14
> CPoint scrollpos;
diff old/App.cpp new/App.cpp
62a63,64
> //afxAmbientActCtx = FALSE;
>
diff old/EditorWnd.cpp new/EditorWnd.cpp
318,320c318
< MACHINE_LOCK;
< pPattern->EnableColumns(dlg.enabledColumns, pCB);
< pPattern->SetRowsPerBeat(dlg.m_RPBValue);
---
> pPattern->EnableColumns(dlg.enabledColumns, pCB, 1, dlg.m_RPBValue);
diff old/MachinePattern.h new/MachinePattern.h
2a3
> #include <functional>
172c173
< modulators = shared_ptr<CModulators>(new CModulators());
---
> modulators = make_shared<CModulators>();
201c202
< enum State { note_on_pending, playing, note_off_pending, recording };
---
> enum State { note_on_pending, playing, note_off_pending, recording, pw_or_cc };
208a210,211
> int pw;
> int cc;
381a385,393
> int GetValueClamp(int row, int mini, int maxi) const
> {
> MapIntToValue::const_iterator i = events.find(row);
> if (i == events.end())
> return GetNoValue();
> else
> return min(max((*i).second, mini), maxi);
> }
>
597a610
> MapIntToValue::const_iterator EventsBeginAt(int offset) const { return events.lower_bound(offset); }
630a644,645
> bool IsMidiPW() const { return paramIndex == MidiPitchWheel; }
> bool IsMidiCC() const { return paramIndex == MidiCC; }
633c648
< int GetDigitCount()
---
> int GetDigitCount() const
639c654
< case pt_byte: return 2;
---
> case pt_byte: return IsAscii() ? 1 : 2;
646c661
< int GetWidth()
---
> int GetWidth() const
651c666
< return GetDigitCount() + 1;
---
> return GetDigitCount() + (IsTiedToNext() ? 0 : 1);
654c669
< bool IsNormalValue(int value)
---
> bool IsNormalValue(int value) const
677a693,694
> int GetIndex() const { return paramIndex; }
>
742,743c759,761
< if (GetParamType() == pt_note)
< value = EncodeNote(modulators->DiatonicTransposition(DecodeNote(value)));
---
> if (GetParamType() == pt_note && IsNormalValue(value))
> value = EncodeNote(min(max(modulators->DiatonicTransposition(DecodeNote(value)), 0), 9 * 12 + 11));
>
770a789
> if (modulators) n.note = min(max(modulators->DiatonicTransposition(n.note), 0), 9 * 12 + 11);
773a793
> n.pw = n.cc = -1;
796a817,850
> else if (ip == MidiPitchWheel)
> {
> auto n = gdata.activeMidiNotes.find(MacIntPair(pMachine, paramTrack));
> if (n == gdata.activeMidiNotes.end())
> {
> gdata.activeMidiNotes[MacIntPair(pMachine, paramTrack)] = ActiveMidiNote();
> n = gdata.activeMidiNotes.find(MacIntPair(pMachine, paramTrack));
> (*n).second.state = ActiveMidiNote::pw_or_cc;
> (*n).second.cc = -1;
> (*n).second.delaytime = 0;
> (*n).second.cuttime = 0x7fffffff;
> }
>
> (*n).second.rowInBeat = gdata.currentRowInBeat;
> (*n).second.RPB = gdata.currentRPB;
> (*n).second.pw = (*i).second;
> }
> else if (ip == MidiCC)
> {
> auto n = gdata.activeMidiNotes.find(MacIntPair(pMachine, paramTrack));
> if (n == gdata.activeMidiNotes.end())
> {
> gdata.activeMidiNotes[MacIntPair(pMachine, paramTrack)] = ActiveMidiNote();
> n = gdata.activeMidiNotes.find(MacIntPair(pMachine, paramTrack));
> (*n).second.state = ActiveMidiNote::pw_or_cc;
> (*n).second.pw = -1;
> (*n).second.delaytime = 0;
> (*n).second.cuttime = 0x7fffffff;
> }
>
> (*n).second.rowInBeat = gdata.currentRowInBeat;
> (*n).second.RPB = gdata.currentRPB;
> (*n).second.cc = (*i).second;
> }
802c856
< if ((*n).second.state == ActiveMidiNote::note_on_pending)
---
> if ((*n).second.state == ActiveMidiNote::note_on_pending || (*n).second.pw >= 0 || (*n).second.cc >= 0)
823c877
< (*sptv)[tid] = shared_ptr<CSubPatternControl>(new CSubPatternControl((*i).second, paramTrack));
---
> (*sptv)[tid] = make_shared<CSubPatternControl>((*i).second, paramTrack);
887a942,971
> bool IsTiedToNext() const
> {
> assert(pParam != NULL);
> return (pParam->Flags & MPF_TIE_TO_NEXT) != 0;
> }
>
> bool IsAscii() const
> {
> assert(pParam != NULL);
> return (pParam->Flags & MPF_ASCII) != 0;
> }
>
> char const *GetName() const
> {
> assert(pParam != NULL);
> return pParam->Name;
> }
>
> bool NameEqualsIgnoreCase(char const *str) const
> {
> assert(pParam != NULL);
> return ::_stricmp(pParam->Name, str) == 0;
> }
>
> bool NameStartsWithIgnoreCase(char const *str) const
> {
> assert(pParam != NULL);
> return ::_strnicmp(pParam->Name, str, strlen(str)) == 0;
> }
>
893a978
>
922a1008,1020
> void UpdateWaveReferences(byte const *remap)
> {
> if (!IsWaveParameter()) return;
>
> for (MapIntToValue::iterator i = events.begin(); i != events.end(); i++)
> {
> int wr = (*i).second;
> if (wr >= WAVE_MIN && wr <= WAVE_MAX && remap[wr] >= WAVE_MIN && remap[wr] <= WAVE_MAX)
> (*i).second = remap[wr];
> }
>
> }
>
982c1080
< columns.push_back(shared_ptr<CColumn>(new CColumn((*i).get(), copydata)));
---
> columns.push_back(make_shared<CColumn>((*i).get(), copydata));
1030c1128
< CColumn *pc = new CColumn();
---
> auto pc = make_shared<CColumn>();
1032c1130
< columns.push_back(shared_ptr<CColumn>(pc));
---
> columns.push_back(pc);
1180c1278
< shared_ptr<CColumn> pc = shared_ptr<CColumn>(new CColumn(columns[lastcoli+i].get(), false, true));
---
> shared_ptr<CColumn> pc = make_shared<CColumn>(columns[lastcoli+i].get(), false, true);
1184,1185c1282,1283
< // int nmt = pcb->GetNumTracks(pmac);
< // if (nmt < tc + 1)
---
> int nmt = pcb->GetNumTracks(pmac);
> if (nmt < tc + 1)
1218a1317,1325
> shared_ptr<CColumn> GetColumn(function<bool (shared_ptr<CColumn> const &)> match) const
> {
> for (auto i = columns.begin(); i != columns.end(); i++)
> if (match(*i))
> return (*i);
>
> return shared_ptr<CColumn>();
> }
>
1241c1348
< return shared_ptr<CColumn>(new CColumn(pcb, mpp, track));
---
> return make_shared<CColumn>(pcb, mpp, track);
1244c1351
< void EnableColumns(MacParamPairVector const &_ec, CMICallbacks *pcb, int mintracks = 1)
---
> void EnableColumns(MacParamPairVector const &_ec, CMICallbacks *pCB, int mintracks = 1, int rpb = -1)
1253c1360
< if (IsGlobalParameter(*i, pcb))
---
> if (IsGlobalParameter(*i, pCB))
1262c1369
< if (!c) c = CreateColumn(*i, 0, pcb);
---
> if (!c) c = CreateColumn(*i, 0, pCB);
1266d1372
<
1271a1378
> maxtracks = max(maxtracks, GetTrackCount((*i).first));
1289c1396
< cv.push_back(shared_ptr<CColumn>(CreateColumn(MacIntPair(*(i + c)), t, pcb)));
---
> cv.push_back(shared_ptr<CColumn>(CreateColumn(MacIntPair(*(i + c)), t, pCB)));
1295a1403
> MACHINE_LOCK;
1296a1405,1408
>
> if (rpb > 0)
> SetRowsPerBeat(rpb);
>
1404a1517,1525
> void UpdateWaveReferences(byte const *remap)
> {
> for (ColumnVector::iterator i = columns.begin(); i != columns.end(); i++)
> (*i)->UpdateWaveReferences(remap);
>
> for (ColumnVector::iterator i = deletedColumns.begin(); i != deletedColumns.end(); i++)
> (*i)->UpdateWaveReferences(remap);
> }
>
1415a1537,1541
> auto pwcol = GetColumn(MacIntPair(pmac, MidiPitchWheel), t).get();
> if (pwcol != NULL && pwcol->HasValue(row)) continue;
> auto cccol = GetColumn(MacIntPair(pmac, MidiCC), t).get();
> if (cccol != NULL && cccol->HasValue(row)) continue;
>
1533a1660,1732
> int AllocateMidiCCTrack(CMachine *pmac, int row, int delay, MapMacAndTrackToActiveMidiNote ¬es, int tc)
> {
> for (int t = 0; t < tc; t++)
> {
> MapMacAndTrackToActiveMidiNote::iterator i;
>
> for (i = notes.begin(); i != notes.end(); i++)
> if ((*i).first.second == t) break;
>
> if (i == notes.end())
> {
> auto notecol = GetColumn(MacIntPair(pmac, MidiNote), t).get();
> auto pwcol = GetColumn(MacIntPair(pmac, MidiPitchWheel), t).get();
> auto cccol = GetColumn(MacIntPair(pmac, MidiCC), t).get();
> auto delaycol = GetColumn(MacIntPair(pmac, MidiNoteDelay), t).get();
> auto cutcol = GetColumn(MacIntPair(pmac, MidiNoteCut), t).get();
>
> bool gotstuff = notecol != NULL && notecol->HasValue(row);
> gotstuff |= pwcol != NULL && pwcol->HasValue(row);
> gotstuff |= cccol != NULL && cccol->HasValue(row);
> gotstuff |= cutcol != NULL && cutcol->HasValue(row);
>
> if (!gotstuff) return t;
> }
> }
>
> return tc > 0 ? 0 : -1;
> }
>
> void RecordMidiCCs(int row, CRecQueue::Event const &e, CGlobalData &gdata)
> {
> int tc = GetTrackCount(e.pmac);
> if (tc < 1) return;
>
> if (e.param == 255)
> {
> if (!HasMidiPWColumn()) return;
> }
> else if (e.param >= 0 && e.param <= 127)
> {
> if (!HasMidiCCColumn()) return;
> }
> else
> {
> return;
> }
>
>
> auto range = GetRowSubtickRange(row % gdata.currentRPB, gdata.currentRPB, gdata.subticksPerTick);
> int delay = min(max((gdata.currentSubtick - range.first) * 96 / (range.second - range.first), 0), 95);
>
> int rectrack = AllocateMidiCCTrack(e.pmac, row, delay, gdata.recordingMidiNotes, tc);
> if (rectrack < 0) return;
>
> if (e.param == 255)
> {
> auto pwcol = GetColumn(MacIntPair(e.pmac, MidiPitchWheel), rectrack).get();
> if (pwcol == NULL) return;
> pwcol->SetValue(row, e.value);
> }
> else
> {
> auto cccol = GetColumn(MacIntPair(e.pmac, MidiCC), rectrack).get();
> if (cccol == NULL) return;
> cccol->SetValue(row, (e.param << 8) | e.value);
> }
>
> auto delaycol = GetColumn(MacIntPair(e.pmac, MidiNoteDelay), rectrack).get();
> if (delaycol != NULL && delay != 0) delaycol->SetValue(row, delay);
>
>
> }
>
1546c1745,1751
< if (e.group < 0 && e.value > 0) RecordMidiNoteOns(row, e, gdata);
---
> if (e.group == -1 && e.value > 0) RecordMidiNoteOns(row, e, gdata);
> }
>
> for (int ei = 0; ei < (int)ev.size(); ei++)
> {
> CRecQueue::Event const &e = ev[ei];
> if (e.group == -1 && e.value == 0) RecordMidiNoteOffs(row, e, gdata);
1552c1757
< if (e.group < 0 && e.value == 0) RecordMidiNoteOffs(row, e, gdata);
---
> if (e.group == -2) RecordMidiCCs(row, e, gdata);
1588a1794,1816
> bool HasMidiPWColumn() const
> {
> for (auto i = columns.begin(); i != columns.end(); i++)
> if ((*i)->IsMidiPW())
> return true;
>
> return false;
> }
>
> bool HasMidiCCColumn() const
> {
> for (auto i = columns.begin(); i != columns.end(); i++)
> if ((*i)->IsMidiCC())
> return true;
>
> return false;
> }
>
> int ScaleToMidiTime(int row, int delay, int range) const
> {
> return (range * row + delay) * 960 * BUZZ_TICKS_PER_BEAT / (range * rowsPerBeat);
> }
>
1591d1818
< if (!HasMidiNoteColumn()) return false;
1604a1832,1840
> if (notecol[i] == NULL)
> {
> notecol[i] = GetColumn([=] (shared_ptr<CColumn> const &c)
> {
> return c->GetParamType() == pt_note && c->IsTrackParam() && c->GetTrack() == i && c->NameEqualsIgnoreCase("note");
> }).get();
> if (notecol[i] == NULL) return false;
> }
>
1605a1842,1849
> if (velcol[i] == NULL)
> {
> velcol[i] = GetColumn([=] (shared_ptr<CColumn> const &c)
> {
> return c->GetParamType() == pt_byte && c->IsTrackParam() && c->GetTrack() == i && (c->NameEqualsIgnoreCase("note velocity") || c->NameEqualsIgnoreCase("velocity"));
> }).get();
> }
>
1606a1851,1858
> if (delaycol[i] == NULL)
> {
> delaycol[i] = GetColumn([=] (shared_ptr<CColumn> const &c)
> {
> return c->GetParamType() == pt_byte && c->IsTrackParam() && c->GetTrack() == i && c->NameEqualsIgnoreCase("note delay");
> }).get();
> }
>
1607a1860,1866
> if (cutcol[i] == NULL)
> {
> cutcol[i] = GetColumn([=] (shared_ptr<CColumn> const &c)
> {
> return c->GetParamType() == pt_byte && c->IsTrackParam() && c->GetTrack() == i && c->NameEqualsIgnoreCase("note cut");
> }).get();
> }
1615a1875,1877
> int const delayrange = (delaycol[t] != NULL) ? (delaycol[t]->GetMaxValue() + 1) : 96;
> int const cutrange = (cutcol[t] != NULL) ? (cutcol[t]->GetMaxValue() + 1) : 96;
>
1619c1881
< int cut = 96;
---
> int cut = cutrange;
1622c1884
< if (velcol[t] != NULL && velcol[t]->HasValue(row)) velocity = velcol[t]->GetValue(row);
---
> if (velcol[t] != NULL && velcol[t]->HasValue(row)) velocity = velcol[t]->GetValueClamp(row, 1, 127);
1634c1896
< (96 * row + delay) * 10 * BUZZ_TICKS_PER_BEAT / rowsPerBeat,
---
> ScaleToMidiTime(row, delay, delayrange),
1641c1903
< (96 * row + delay) * 10 * BUZZ_TICKS_PER_BEAT / rowsPerBeat,
---
> ScaleToMidiTime(row, delay, delayrange),
1646c1908
< if (cut < 96)
---
> if (cut < cutrange)
1650c1912
< (96 * row + cut) * 10 * BUZZ_TICKS_PER_BEAT / rowsPerBeat,
---
> ScaleToMidiTime(row, cut, cutrange),
1658c1920
< (96 * row + min(delay, cut)) * 10 * BUZZ_TICKS_PER_BEAT / rowsPerBeat,
---
> ScaleToMidiTime(row, min(delay, cut), delayrange),
1952c2214
< shared_ptr<CPlayingPattern> p = shared_ptr<CPlayingPattern>(new CPlayingPattern(gdata.patternList[spi], NULL, -1, tofs, (*i).second->modulators));
---
> auto p = make_shared<CPlayingPattern>(gdata.patternList[spi], nullptr, -1, tofs, (*i).second->modulators);
diff old/PatEd.cpp new/PatEd.cpp
42a43
> ON_WM_CHAR()
217,218d217
< MapIntToValue::const_iterator ei = pc->EventsBegin();
<
219a219
> MapIntToValue::const_iterator ei = pc->EventsBeginAt(firstrow);
222,223d221
< while(ei != pc->EventsEnd() && (*ei).first < firstrow) ei++;
<
246c244
< static void FieldToText(char *txt, CMPType type, bool hasval, void *fdata)
---
> static void FieldToText(char *txt, CMPType type, bool ascii, bool hasval, void *fdata)
282c280
< if (!hasval)
---
> if (ascii)
284,285c282,287
< txt[0] = '.';
< txt[1] = '.';
---
> if (!hasval)
> txt[0] = '.';
> else
> txt[0] = b;
>
> txt[1] = 0;
289,290c291,301
< txt[0] = NibbleToHexText[b >> 4];
< txt[1] = NibbleToHexText[b & 15];
---
> if (!hasval)
> {
> txt[0] = '.';
> txt[1] = '.';
> }
> else
> {
> txt[0] = NibbleToHexText[b >> 4];
> txt[1] = NibbleToHexText[b & 15];
> }
> txt[2] = 0;
292d302
< txt[2] = 0;
336a347,389
> static CString FieldToLongText(CMPType type, bool hasval, int v)
> {
> CString s;
>
> switch(type)
> {
> case pt_note:
> {
> if (!hasval)
> {
> }
> else if (v == NOTE_OFF)
> {
> s = "note off";
> }
> else
> {
> int octave = v >> 4;
> int note = (v & 15) -1;
>
> s = NoteToText[note*2+0];
> s += NoteToText[note*2+1];
> s += (char)(octave + '0');
> }
> }
> break;
> default:
> if (v != -1)
> {
> if (v > 255)
> s.Format("%04X (%d)", v, v);
> else
> s.Format("%02X (%d)", v, v);
> }
>
> break;
>
>
> }
>
> return s;
> }
>
340a394,402
> int bar = 4;
>
> if (ppat->numBeats % 13 == 0) bar = 13;
> else if (ppat->numBeats % 11 == 0) bar = 11;
> else if (ppat->numBeats % 9 == 0) bar = 9;
> else if (ppat->numBeats % 7 == 0) bar = 7;
> else if (ppat->numBeats % 5 == 0) bar = 5;
> else if (ppat->numBeats % 3 == 0) bar = 3;
>
345c407
< else if ((row % (4 * ppat->rowsPerBeat)) == 0)
---
> else if ((row % (bar * ppat->rowsPerBeat)) == 0)
377c439
< FieldToText(txt, pc->GetParamType(), hasvalue, (void *)&data);
---
> FieldToText(txt, pc->GetParamType(), pc->IsAscii(), hasvalue, (void *)&data);
379c441
< int len = strlen(txt);
---
> int len = (int)strlen(txt);
479c541
< if (x < colx - pew->fontSize.cx)
---
> if (x < colx - (ppat->columns[col]->IsTiedToNext() ? 0 : pew->fontSize.cx))
561c623
< r.right = r.left + GetColumnWidth(column) - pew->fontSize.cx;
---
> r.right = r.left + GetColumnWidth(column); // - pew->fontSize.cx;
882a945,959
> void CPatEd::EditAscii(char val)
> {
> CMachinePattern *ppat = pew->pPattern;
> CColumn *pc = ppat->columns[cursor.column].get();
>
> ppat->actions.BeginAction(pew, "Edit ASCII");
> {
> MACHINE_LOCK;
> pc->SetValue(cursor.row, val);
> }
>
> InvalidateField(cursor.row, cursor.column);
> MoveCursorDelta(0, cursorStep);
> }
>
1088,1095c1165,1175
< if (nChar >= '0' && nChar <= '9')
< EditByte(nChar - '0');
< else if (nChar == 'A') EditByte(0xA);
< else if (nChar == 'B') EditByte(0xB);
< else if (nChar == 'C') EditByte(0xC);
< else if (nChar == 'D') EditByte(0xD);
< else if (nChar == 'E') EditByte(0xE);
< else if (nChar == 'F') EditByte(0xF);
---
> if (!pc->IsAscii())
> {
> if (nChar >= '0' && nChar <= '9')
> EditByte(nChar - '0');
> else if (nChar == 'A') EditByte(0xA);
> else if (nChar == 'B') EditByte(0xB);
> else if (nChar == 'C') EditByte(0xC);
> else if (nChar == 'D') EditByte(0xD);
> else if (nChar == 'E') EditByte(0xE);
> else if (nChar == 'F') EditByte(0xF);
> }
1121a1202,1239
> void CPatEd::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
> {
> CMachinePattern *ppat = pew->pPattern;
> if (ppat == NULL || ppat->columns.size() == 0)
> return;
>
> CColumn *pc = ppat->columns[cursor.column].get();
>
> if (pc->GetParamType() == pt_byte && pc->IsAscii())
> {
> if (nChar != '.')
> {
> char ch = (char)nChar;
> bool valid = pCB->IsValidAsciiChar(pc->GetMachine(), pc->GetIndex(), ch);
>
> if (!valid && nChar >= 'a' && nChar <= 'z')
> {
> ch += 'A' - 'a';
> valid = pCB->IsValidAsciiChar(pc->GetMachine(), pc->GetIndex(), ch);
> }
> else if (!valid && nChar >= 'A' && nChar <= 'Z')
> {
> ch += 'a' - 'A';
> valid = pCB->IsValidAsciiChar(pc->GetMachine(), pc->GetIndex(), ch);
> }
>
> if (ch < pc->GetMinValue() || ch > pc->GetMaxValue())
> valid = false;
>
> if (valid)
> EditAscii(ch);
> }
> }
>
> CWnd::OnChar(nChar, nRepCnt, nFlags);
> }
>
>
1279,1280d1396
< char txt[6];
< FieldToText(txt, pc->GetParamType(), pc->HasValue(cursor.row), (void *)&value);
1284c1400
< char const *desc = pc->DescribeValue(value, pCB);
---
> s = FieldToLongText(pc->GetParamType(), pc->HasValue(cursor.row), value);
1286c1402,1403
< s = txt;
---
> char const *desc = pc->DescribeValue(value, pCB);
>
1288c1405
< s += (CString)" (" + desc + ")";
---
> s += (CString)" " + desc;
1372a1490,1491
> CColumn *pc = ppat->columns[cursor.column].get();
>
1379a1499,1500
> CCursorPos oldpos = cursor;
>
1388a1510,1540
> if (cursor == oldpos)
> {
> switch(selMode)
> {
> case column: selMode = track; break;
> case track: if (pc->IsTrackParam()) selMode = group; else selMode = all; break;
> case group: selMode = all; break;
> case all: selMode = column; break;
> }
>
> switch(selMode)
> {
> case column:
> selStart.x = selEnd.x = cursor.column;
> break;
> case track:
> selStart.x = ppat->GetFirstColumnOfTrackByColumn(cursor.column);
> selEnd.x = selStart.x + ppat->GetGroupColumnCount(cursor.column) - 1;
> break;
> case group:
> selStart.x = ppat->GetFirstColumnOfTrackByColumn(cursor.column) - pc->GetTrack() * ppat->GetGroupColumnCount(cursor.column);
> selEnd.x = selStart.x + ppat->GetGroupColumnCount(cursor.column) * ppat->GetTrackCount(pc->GetMachine()) - 1;
> break;
> case all:
> selStart.x = 0;
> selEnd.x = (int)ppat->columns.size() - 1;
> break;
> }
>
> }
>
1763,1764c1915,1916
< int vel = lParam;
< int n = wParam - pew->pCB->GetBaseOctave() * 12;
---
> int vel = (int)lParam;
> int n = (int)wParam - pew->pCB->GetBaseOctave() * 12;
diff old/PatEd.h new/PatEd.h
69a70
> void EditAscii(char n);
131a133
> afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
diff old/PatternXP.cpp new/PatternXP.cpp
92a93
> virtual void UpdateWaveReferences(CPattern *p, byte const *remap);
448a450,453
> void miex::UpdateWaveReferences(CPattern *p, byte const *remap)
> {
> pmi->patterns[p]->UpdateWaveReferences(remap);
> }
508a514,519
> if (pmi->pCB->GetStateFlags() & SF_RECORDING)
> {
> pmi->recQueue.Push(CRecQueue::Event(pmac, -2, channel, ctrl, value));
> pmi->patEd->pe.InvalidateInTimer();
> }
>
696a708,719
> if ((*i).second.pw >= 0 && cst >= dtime)
> {
> pCB->SendMidiControlChange((*i).first.first, 255, 0, (*i).second.pw);
> (*i).second.pw = -1;
> }
>
> if ((*i).second.cc >= 0 && cst >= dtime)
> {
> pCB->SendMidiControlChange((*i).first.first, ((*i).second.cc >> 8) & 0x7f, 0, (*i).second.cc & 0x7f);
> (*i).second.cc = -1;
> }
>
701a725,729
> else if ((*i).second.state == ActiveMidiNote::pw_or_cc && (*i).second.pw < 0 && (*i).second.cc < 0)
> {
> globalData.activeMidiNotes.erase(i);
> }
>
diff old/ScrollWnd.cpp new/ScrollWnd.cpp
44,45c44,48
< canvasSize = s;
< ScrollTo(CPoint(0, 0));
---
> if (canvasSize != s)
> {
> canvasSize = s;
> ScrollTo(GetScrollPos());
> }
diff old/ScrollWnd.h new/ScrollWnd.h
50a51
> void ScrollTo(CPoint pos);
58d58
< void ScrollTo(CPoint pos);
diff old/stdafx.h new/stdafx.h
14a15,24
> #define NOMINMAX
>
> #ifndef max
> #define max(a,b) (((a) > (b)) ? (a) : (b))
> #endif
>
> #ifndef min
> #define min(a,b) (((a) < (b)) ? (a) : (b))
> #endif
>
53a64,65
>
> //#define MI_DEBUG_LOCKS
68a81
>