@@ -93,28 +93,28 @@ type |
| 93 |
//https://github.com/stoneface86/libtrackerboy/blob/bf4993d53bc34691ca75819a96d3d00b3b699dea/src/trackerboy/data.nim#L111 |
93 |
//https://github.com/stoneface86/libtrackerboy/blob/bf4993d53bc34691ca75819a96d3d00b3b699dea/src/trackerboy/data.nim#L111 |
| 94 |
TTBMEffectType = ( |
94 |
TTBMEffectType = ( |
| 95 |
etNoEffect = 0, // No effect, this effect column is unset. |
95 |
etNoEffect = 0, // No effect, this effect column is unset. |
| 96 |
etPatternGoto, // `Bxx` begin playing given pattern immediately |
96 |
etPatternGoto = 1, // `Bxx` begin playing given pattern immediately |
| 97 |
etPatternHalt, // `C00` stop playing |
97 |
etPatternHalt = 2, // `C00` stop playing |
| 98 |
etPatternSkip, // `D00` begin playing next pattern immediately |
98 |
etPatternSkip = 3, // `D00` begin playing next pattern immediately |
| 99 |
etSetTempo, // `Fxx` set the tempo |
99 |
etSetTempo = 4, // `Fxx` set the tempo |
| 100 |
etSfx, // `Txx` play sound effect |
100 |
etSfx = 5, // `Txx` play sound effect |
| 101 |
etSetEnvelope, // `Exx` set the persistent envelope/wave id setting |
101 |
etSetEnvelope = 6, // `Exx` set the persistent envelope/wave id setting |
| 102 |
etSetTimbre, // `Vxx` set persistent duty/wave volume setting |
102 |
etSetTimbre = 7, // `Vxx` set persistent duty/wave volume setting |
| 103 |
etSetPanning, // `Ixy` set channel panning setting |
103 |
etSetPanning = 8, // `Ixy` set channel panning setting |
| 104 |
etSetSweep, // `Hxx` set the persistent sweep setting (CH1 only) |
104 |
etSetSweep = 9, // `Hxx` set the persistent sweep setting (CH1 only) |
| 105 |
etDelayedCut, // `Sxx` note cut delayed by xx frames |
105 |
etDelayedCut = 10, // `Sxx` note cut delayed by xx frames |
| 106 |
etDelayedNote, // `Gxx` note trigger delayed by xx frames |
106 |
etDelayedNote = 11, // `Gxx` note trigger delayed by xx frames |
| 107 |
etLock, // `L00` (lock) stop the sound effect on the current channel |
107 |
etLock = 12, // `L00` (lock) stop the sound effect on the current channel |
| 108 |
etArpeggio, // `0xy` arpeggio with semi tones x and y |
108 |
etArpeggio = 13, // `0xy` arpeggio with semi tones x and y |
| 109 |
etPitchUp, // `1xx` pitch slide up |
109 |
etPitchUp = 14, // `1xx` pitch slide up |
| 110 |
etPitchDown, // `2xx` pitch slide down |
110 |
etPitchDown = 15, // `2xx` pitch slide down |
| 111 |
etAutoPortamento, // `3xx` automatic portamento |
111 |
etAutoPortamento = 16, // `3xx` automatic portamento |
| 112 |
etVibrato, // `4xy` vibrato |
112 |
etVibrato = 17, // `4xy` vibrato |
| 113 |
etVibratoDelay, // `5xx` delay vibrato xx frames on note trigger |
113 |
etVibratoDelay = 18, // `5xx` delay vibrato xx frames on note trigger |
| 114 |
etTuning, // `Pxx` fine tuning |
114 |
etTuning = 19, // `Pxx` fine tuning |
| 115 |
etNoteSlideUp, // `Qxy` note slide up |
115 |
etNoteSlideUp = 20, // `Qxy` note slide up |
| 116 |
etNoteSlideDown, // `Rxy` note slide down |
116 |
etNoteSlideDown = 21, // `Rxy` note slide down |
| 117 |
etSetGlobalVolume // `Jxy` set global volume scale |
117 |
etSetGlobalVolume = 22 // `Jxy` set global volume scale |
| 118 |
); |
118 |
); |
| 119 |
|
119 |
|
| 120 |
function TStreamHelper.ReadLString: String; |
120 |
function TStreamHelper.ReadLString: String; |
@@ -131,13 +131,12 @@ end; |
| 131 |
procedure ConvertEffect(Code, Params: Byte; Channel: TInstrumentType; |
131 |
procedure ConvertEffect(Code, Params: Byte; Channel: TInstrumentType; |
| 132 |
out OutCode: Integer; out OutParams: TEffectParams); |
132 |
out OutCode: Integer; out OutParams: TEffectParams); |
| 133 |
var |
133 |
var |
| 134 |
FXType: TTBMEffectType absolute Code; |
|
|
| 135 |
EP: TEffectParams absolute Params; |
134 |
EP: TEffectParams absolute Params; |
| 136 |
begin |
135 |
begin |
| 137 |
OutCode := 0; |
136 |
OutCode := 0; |
| 138 |
OutParams.Value := 0; |
137 |
OutParams.Value := 0; |
| 139 |
|
138 |
|
| 140 |
case FXType of |
139 |
case TTBMEffectType(Code) of |
| 141 |
etNoEffect: begin |
140 |
etNoEffect: begin |
| 142 |
// no op |
141 |
// no op |
| 143 |
end; |
142 |
end; |
@@ -282,7 +281,7 @@ var |
| 282 |
CurNote: Integer = NO_NOTE; |
281 |
CurNote: Integer = NO_NOTE; |
| 283 |
begin |
282 |
begin |
| 284 |
for I := Low(TPattern) to High(TPattern) do begin |
283 |
for I := Low(TPattern) to High(TPattern) do begin |
| 285 |
if not InstMap.TryGetData(Pat^[I].Instrument, Pat^[I].Instrument) then |
284 |
if not InstMap.TryGetData(Pat^[I].Instrument-1, Pat^[I].Instrument) then |
| 286 |
Pat^[I].Instrument := 0; |
285 |
Pat^[I].Instrument := 0; |
| 287 |
|
286 |
|
| 288 |
if Pat^[I].Note <> NO_NOTE then |
287 |
if Pat^[I].Note <> NO_NOTE then |
@@ -322,6 +321,7 @@ var |
| 322 |
SquareMap, WaveMap, NoiseMap: TTBMInstrumentMap; |
321 |
SquareMap, WaveMap, NoiseMap: TTBMInstrumentMap; |
| 323 |
SeenSquare, SeenWave, SeenNoise: Integer; |
322 |
SeenSquare, SeenWave, SeenNoise: Integer; |
| 324 |
NewInstId: Integer; |
323 |
NewInstId: Integer; |
|
|
324 |
TracksForCleanup: array of TTBMTrackFormat; |
| 325 |
begin |
325 |
begin |
| 326 |
InitializeSong(Result); |
326 |
InitializeSong(Result); |
| 327 |
|
327 |
|
@@ -352,8 +352,10 @@ begin |
| 352 |
Result.OrderMatrix[3, I] := 400 + Stream.ReadByte; |
352 |
Result.OrderMatrix[3, I] := 400 + Stream.ReadByte; |
| 353 |
end; |
353 |
end; |
| 354 |
|
354 |
|
|
|
355 |
SetLength(TracksForCleanup, SongFormat.NumberOfTracks); |
| 355 |
for I := 0 to SongFormat.NumberOfTracks-1 do begin |
356 |
for I := 0 to SongFormat.NumberOfTracks-1 do begin |
| 356 |
Stream.ReadBuffer(TrackFormat, SizeOf(TTBMTrackFormat)); |
357 |
Stream.ReadBuffer(TrackFormat, SizeOf(TTBMTrackFormat)); |
|
|
358 |
TracksForCleanup[I] := TrackFormat; |
| 357 |
|
359 |
|
| 358 |
case TrackFormat.Channel of |
360 |
case TrackFormat.Channel of |
| 359 |
0, 1: InsType := itSquare; |
361 |
0, 1: InsType := itSquare; |
@@ -369,7 +371,6 @@ begin |
| 369 |
end; |
371 |
end; |
| 370 |
|
372 |
|
| 371 |
// INST block |
373 |
// INST block |
| 372 |
|
|
|
| 373 |
SquareMap := TTBMInstrumentMap.Create; |
374 |
SquareMap := TTBMInstrumentMap.Create; |
| 374 |
WaveMap := TTBMInstrumentMap.Create; |
375 |
WaveMap := TTBMInstrumentMap.Create; |
| 375 |
NoiseMap := TTBMInstrumentMap.Create; |
376 |
NoiseMap := TTBMInstrumentMap.Create; |
@@ -467,14 +468,15 @@ begin |
| 467 |
end; |
468 |
end; |
| 468 |
|
469 |
|
| 469 |
// Cleanup patterns |
470 |
// Cleanup patterns |
| 470 |
for I := Low(Result.OrderMatrix[0]) to High(Result.OrderMatrix[0])-1 do |
471 |
for TrackFormat in TracksForCleanup do begin |
| 471 |
CleanupPattern(Result.Patterns.KeyData[Result.OrderMatrix[0, I]], SquareMap); |
472 |
Pat := Result.Patterns.GetOrCreateNew(((TrackFormat.Channel+1)*100) + TrackFormat.TrackId); |
| 472 |
for I := Low(Result.OrderMatrix[1]) to High(Result.OrderMatrix[1])-1 do |
473 |
|
| 473 |
CleanupPattern(Result.Patterns.KeyData[Result.OrderMatrix[1, I]], SquareMap); |
474 |
case TrackFormat.Channel of |
| 474 |
for I := Low(Result.OrderMatrix[2]) to High(Result.OrderMatrix[2])-1 do |
475 |
0, 1: CleanupPattern(Pat, SquareMap); |
| 475 |
CleanupPattern(Result.Patterns.KeyData[Result.OrderMatrix[2, I]], WaveMap); |
476 |
2: CleanupPattern(Pat, WaveMap); |
| 476 |
for I := Low(Result.OrderMatrix[3]) to High(Result.OrderMatrix[3])-1 do |
477 |
3: CleanupPattern(Pat, NoiseMap); |
| 477 |
CleanupPattern(Result.Patterns.KeyData[Result.OrderMatrix[3, I]], NoiseMap); |
478 |
end; |
|
|
479 |
end; |
| 478 |
end; |
480 |
end; |
| 479 |
|
481 |
|
| 480 |
end. |
482 |
end. |