--- a/ptplayer.asm +++ b/ptplayer.asm @@ -2495,6 +2495,10 @@ mt_arpeggio: ; cmd 0 x y (x = first arpeggio offset, y = second arpeggio offset) ; d4 = xy +; As Protracker 2.3: the period, wherever a slide has left it, is looked +; up in the channel's finetune row, and the note x or y above taken from +; there -- past B-3, from the next finetune's row, which the table runs on +; into. (Counting from n_noteoff instead kept the note from before a slide.) moveq #0,d0 move.b mt_Counter(a4),d0 @@ -2509,16 +2513,26 @@ ; step 2, arpeggio by right nibble .1: and.w #$000f,d4 - ; offset current note + ; find the period in the tuned table: 37 entries, as Protracker reads .2: add.w d4,d4 - add.w n_noteoff(a2),d4 - cmp.w #2*36,d4 + lea mt_PeriodTableEnd(pc),a1 + move.l n_pertab(a2),a0 + move.w n_period(a2),d1 + moveq #37-1,d0 +.3: cmp.l a1,a0 + bhs .5 + cmp.w (a0),d1 bhs .4 + addq.l #2,a0 + dbf d0,.3 + rts - ; set period with arpeggio offset from note table - move.l n_pertab(a2),a0 - move.w (a0,d4.w),AUDPER(a5) -.4: rts + ; set period with arpeggio offset, unless it runs off the table +.4: add.w d4,a0 + cmp.l a1,a0 + bhs .5 + move.w (a0),AUDPER(a5) +.5: rts arptab: dc.b 0,1,-1,0,1,-1,0,1,-1,0,1,-1,0,1,-1,0 @@ -2689,7 +2703,7 @@ ; cmd 5 x y (x = volume-up, y = volume-down) ; d4 = xy - pea mt_volumeslide(pc) + pea mt_volslide_noper(pc) bra mt_toneporta_nc @@ -2698,12 +2712,13 @@ ; d4 = xy move.w d4,d3 + moveq #0,d2 ; the depth indexes a table: no stale high byte move.b n_vibratoamp(a2),d2 move.b n_vibratospd(a2),d4 bsr mt_vibrato_nc move.w d3,d4 - bra mt_volumeslide + bra mt_volslide_noper mt_tremolo: @@ -2723,47 +2738,53 @@ bra .4 .3: move.b n_tremolospd(a2),d4 - ; calculate tremolo table offset: 64 * amplitude + (pos & 63) -.4: lsl.w #6,d2 - moveq #63,d0 - and.b n_tremolopos(a2),d0 - add.w d0,d2 - - ifne ENABLE_SAWRECT - ; select tremolo waveform + ; As Protracker 2.3: twice a vibrato's depth (the wave times y, over + ; 64), and the saw ramping as the channel's VIBRATO position says. +.4: moveq #31,d0 + and.b n_tremolopos(a2),d0 ; d0 = position in the wave's half moveq #3,d1 and.b n_tremoloctrl(a2),d1 beq .6 + + lsl.b #3,d0 ; saw and square: the ramp's step subq.b #1,d1 - beq .5 + bne .5 - ; ctrl 2 & 3 select a rectangle tremolo - lea mt_VibratoRectTable(pc),a0 + ; ctrl 1 selects a saw, falling in the vibrato's negative half + btst #5,n_vibratopos(a2) + beq .9 + not.b d0 ; 255 - ramp bra .9 - ; ctrl 1 selects a sawtooth tremolo -.5: lea mt_VibratoSawTable(pc),a0 + ; ctrl 2 & 3 select a square +.5: st d0 bra .9 - endc ; ENABLE_SAWRECT - ; ctrl 0 selects a sine tremolo -.6: lea mt_VibratoSineTable(pc),a0 + ; ctrl 0 selects a sine +.6: move.b mt_ProTrackerSine(pc,d0.w),d0 - ; add tremolo-offset to volume -.9: move.w n_volume(a2),d0 - add.b (a0,d2.w),d0 - bpl .10 - moveq #0,d0 -.10: cmp.w #64,d0 + ; scale by the depth, then add or subtract by the position's half +.9: and.w #$00ff,d0 + mulu d2,d0 + lsr.w #6,d0 + move.w n_volume(a2),d1 + btst #5,n_tremolopos(a2) + beq .10 + sub.w d0,d1 + bpl .11 + moveq #0,d1 + bra .11 +.10: add.w d0,d1 + cmp.w #64,d1 bls .11 - moveq #64,d0 + moveq #64,d1 .11: move.w n_period(a2),AUDPER(a5) ifeq MINIMAL move.l mt_MasterVolTab(a4),a0 - move.b (a0,d0.w),d0 - and.b n_enable(a2),d0 + move.b (a0,d1.w),d1 + and.b n_enable(a2),d1 endc - move.w d0,AUDVOL(a5) + move.w d1,AUDVOL(a5) ifd VOL0_UNLOOPS bne .12 move.b d7,n_looped(a2) @@ -2773,6 +2794,12 @@ .12: add.b d4,n_tremolopos(a2) rts +mt_ProTrackerSine: + ; Protracker's mt_VibratoTable: the first half of the sine + dc.b 0,24,49,74,97,120,141,161,180,197,212,224,235,244,250,253 + dc.b 255,253,250,244,235,224,212,197,180,161,141,120,97,74,49,24 + even + mt_volumeslide: ; cmd A x y (x = volume-up, y = volume-down) @@ -2815,6 +2842,34 @@ .1: rts +mt_volslide_noper: +; The volume slide of 5xy and 6xy, and EAx/EBx's: as mt_volumeslide but +; leaving Paula's period alone, as Protracker 2.3 does -- setting it back to +; n_period undid 6xy's vibrato, 5xy's glissando, and a tick of either. +; d4 = xy + + move.w n_volume(a2),d0 + moveq #$0f,d1 + and.b d4,d1 + lsr.b #4,d4 + beq vol_slide_down_np + + ; slide up, until 64 + add.b d4,d0 +vol_slide_up_np: + cmp.b #64,d0 + bls set_vol + moveq #64,d0 + bra set_vol + + ; slide down, until 0 +vol_slide_down_np: + sub.b d1,d0 + bpl set_vol + moveq #0,d0 + bra set_vol + + mt_posjump: ; cmd B x y (xy = new song position) ; d4 = xy @@ -3079,7 +3134,7 @@ rts .1: add.w n_volume(a2),d0 - bra vol_slide_up + bra vol_slide_up_np mt_volfinedn: @@ -3092,7 +3147,7 @@ .1: move.b d0,d1 move.w n_volume(a2),d0 - bra vol_slide_down + bra vol_slide_down_np mt_notecut: @@ -3448,6 +3503,7 @@ dc.w 862,814,768,725,684,646,610,575,543,513,484,457 dc.w 431,407,384,363,342,323,305,288,272,256,242,228 dc.w 216,203,192,181,171,161,152,144,136,128,121,114 +mt_PeriodTableEnd: ifeq MINIMAL MasterVolTab0: