Skip to content

Commit 259e50e

Browse files
committed
nullsound: retrigger FX
Also add the missing nsstool features for the cut and delay refactoring from the previous commit
1 parent 043e72b commit 259e50e

File tree

5 files changed

+110
-32
lines changed

5 files changed

+110
-32
lines changed

nullsound/fx-trigger.s

+66-24
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ trigger_delay_init::
4141
inc hl
4242

4343
;; configure trigger FX for delay
44-
ld TRIGGER_DELAY(ix), a
44+
ld TRIGGER_CUR(ix), a
4545
xor a
4646
set BIT_TRIGGER_ACTION_DELAY, a
4747
ld TRIGGER_ACTION(ix), a
@@ -62,8 +62,8 @@ trigger_cut_init::
6262
inc a
6363
inc hl
6464

65-
;; configure trigger FX for delay
66-
ld TRIGGER_CUT(ix), a
65+
;; configure trigger FX for cut
66+
ld TRIGGER_CUR(ix), a
6767
xor a
6868
set BIT_TRIGGER_ACTION_CUT, a
6969
ld TRIGGER_ACTION(ix), a
@@ -72,6 +72,27 @@ trigger_cut_init::
7272
ret
7373

7474

75+
;;; Enable another note trigger after a defined number of steps
76+
;;; ------
77+
;;; ix : state for channel
78+
;;; [ hl ]: delay
79+
;;; [ hl modified ]
80+
trigger_retrigger_init::
81+
;; a: delay
82+
ld a, (hl)
83+
inc hl
84+
85+
;; configure trigger FX for retrigger
86+
ld TRIGGER_ARG(ix), a
87+
ld TRIGGER_CUR(ix), a
88+
xor a
89+
set BIT_TRIGGER_ACTION_RETRIGGER, a
90+
ld TRIGGER_ACTION(ix), a
91+
set BIT_FX_TRIGGER, FX(ix)
92+
93+
ret
94+
95+
7596
;;; Call an function from the action lookup table
7697
;;; ------
7798
;;; hl: function lookup table
@@ -103,26 +124,42 @@ _trigger_post_action:
103124
;;; hl: function lookup table for the current channel
104125
;;; [hl, bc, de modified]
105126
eval_trigger_step::
106-
;; is the trigger a delay?
107-
bit BIT_TRIGGER_ACTION_DELAY, TRIGGER_ACTION(ix)
108-
jr z, _trigger_post_delay
109-
;; check whether delay is reached
110-
dec TRIGGER_DELAY(ix)
127+
;; if this is a retrigger, check whether we reached the last tick
128+
;; for this row, and stop it after this eval
129+
bit BIT_TRIGGER_ACTION_RETRIGGER, TRIGGER_ACTION(ix)
130+
jr z, _trigger_post_retrigger_check
131+
ld a, (state_timer_ticks_per_row)
132+
ld b, a
133+
ld a, (state_timer_ticks_count)
134+
inc a
135+
sub b
136+
jr c, _trigger_post_retrigger_check
137+
res BIT_FX_TRIGGER, FX(ix)
138+
_trigger_post_retrigger_check:
139+
140+
;; check whether delay is reached for trigger action
141+
dec TRIGGER_CUR(ix)
111142
jr nz, _trigger_end
143+
;; if so, run the configured action
144+
bit BIT_TRIGGER_ACTION_DELAY, TRIGGER_ACTION(ix)
145+
jr z, _trigger_not_a_delay
112146
jr _trigger_load_and_clear
113-
_trigger_post_delay:
114-
115-
;; is the trigger a cut?
147+
_trigger_not_a_delay:
116148
bit BIT_TRIGGER_ACTION_CUT, TRIGGER_ACTION(ix)
117-
jr z, _trigger_post_cut
118-
;; check whether delay is reached
119-
dec TRIGGER_CUT(ix)
120-
jr nz, _trigger_end
149+
jr z, _trigger_not_a_cut
121150
jr _trigger_cut_note
122-
_trigger_post_cut:
151+
_trigger_not_a_cut:
152+
;; is the trigger a cut?
153+
bit BIT_TRIGGER_ACTION_RETRIGGER, TRIGGER_ACTION(ix)
154+
jr z, _trigger_not_a_retrigger
155+
jr _trigger_retrigger_note
156+
_trigger_not_a_retrigger:
157+
123158
_trigger_end:
124159
ret
125160

161+
162+
;;; trigger: load delayed note/vol
126163
_trigger_load_and_clear:
127164
;; load new note?
128165
bit BIT_TRIGGER_LOAD_NOTE, TRIGGER_ACTION(ix)
@@ -131,28 +168,33 @@ _trigger_load_and_clear:
131168
ld bc, #TRIGGER_LOAD_NOTE_FUNC
132169
call trigger_action_function
133170
_trigger_post_load_note:
134-
135171
;; load new vol?
136172
bit BIT_TRIGGER_LOAD_VOL, TRIGGER_ACTION(ix)
137173
jr z, _trigger_post_load_vol
138174
ld a, TRIGGER_VOL(ix)
139175
ld bc, #TRIGGER_LOAD_VOL_FUNC
140176
call trigger_action_function
141177
_trigger_post_load_vol:
142-
143-
;; trigger is finished
144-
xor a
145-
ld TRIGGER_ACTION(ix), a
178+
res BIT_TRIGGER_ACTION_DELAY, TRIGGER_ACTION(ix)
146179
res BIT_FX_TRIGGER, FX(ix)
147-
148180
ret
149181

182+
183+
;;; trigger: cut current note
150184
_trigger_cut_note:
151185
ld bc, #TRIGGER_STOP_NOTE_FUNC
152186
call trigger_action_function
153-
xor a
154-
ld TRIGGER_ACTION(ix), a
187+
res BIT_TRIGGER_ACTION_DELAY, TRIGGER_ACTION(ix)
155188
res BIT_FX_TRIGGER, FX(ix)
189+
ret
190+
156191

192+
;;; trigger: restart current note
193+
_trigger_retrigger_note:
194+
ld bc, #TRIGGER_LOAD_NOTE_FUNC
195+
call trigger_action_function
196+
;; rearm trigger for the next step
197+
ld a, TRIGGER_ARG(ix)
198+
ld TRIGGER_CUR(ix), a
157199
ret
158200

nullsound/nss-adpcm-a.s

+11
Original file line numberDiff line numberDiff line change
@@ -605,3 +605,14 @@ adpcm_a_cut::
605605

606606
ld a, #1
607607
ret
608+
609+
610+
;;; ADPCM_A_RETRIGGER
611+
;;; Enable another trigger of the current note after a number of steps
612+
;;; ------
613+
;;; [ hl ]: delay
614+
adpcm_a_retrigger::
615+
call trigger_retrigger_init
616+
617+
ld a, #1
618+
ret

nullsound/stream.s

+1
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,7 @@ nss_opcodes:
525525
.nss_op adpcm_a_cut
526526
.nss_op adpcm_b_cut
527527
.nss_op adpcm_b_delay
528+
.nss_op adpcm_a_retrigger
528529

529530

530531

nullsound/struct-fx.inc

+9-8
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
.area struct
2828

2929
.local pipeline, fx_fx, fx_trigger, fx_vol_slide, fx_slide, fx_vibrato
30-
.local _trigger_action, _trigger_note, _trigger_vol, _trigger_cut, _trigger_delay, _trigger_size
30+
.local _trigger_action, _trigger_note, _trigger_vol, _trigger_arg, _trigger_cur, _trigger_size
3131
.local _vol_slide_inc16, _vol_slide_pos16, _vol_slide_end, _vol_slide_size
3232
.local _slide_speed, _slide_depth, _slide_inc16, _slide_pos16, _slide_portamento, _slide_end, _slide_size
3333
.local _vibrato_speed, _vibrato_depth, _vibrato_pos, _vibrato_pos16, _vibrato_size
@@ -37,11 +37,11 @@ pipeline: .blkb 1
3737
;;; enabled FX. This must be the second field of a channel's state
3838
fx_fx: .blkb 1
3939
fx_trigger:
40-
_trigger_action: .blkb 1
41-
_trigger_note: .blkb 1
42-
_trigger_vol: .blkb 1
43-
_trigger_cut: .blkb 1
44-
_trigger_delay: .blkb 1
40+
_trigger_action: .blkb 1 ; trigger action (cut, delay, retrigger)
41+
_trigger_note: .blkb 1 ; trigger delayed note
42+
_trigger_vol: .blkb 1 ; trigger delayed volume
43+
_trigger_arg: .blkb 1 ; per-action argument
44+
_trigger_cur: .blkb 1 ; per-action current accumulator
4545
_trigger_size:
4646
;;; FX: volume slide
4747
fx_vol_slide:
@@ -75,8 +75,8 @@ _vibrato_size:
7575
.lclequ TRIGGER_ACTION, (_trigger_action - pipeline)
7676
.lclequ TRIGGER_NOTE, (_trigger_note - pipeline)
7777
.lclequ TRIGGER_VOL, (_trigger_vol - pipeline)
78-
.lclequ TRIGGER_CUT, (_trigger_cut - pipeline)
79-
.lclequ TRIGGER_DELAY, (_trigger_delay - pipeline)
78+
.lclequ TRIGGER_ARG, (_trigger_arg - pipeline)
79+
.lclequ TRIGGER_CUR, (_trigger_cur - pipeline)
8080
.lclequ TRIGGER_SIZE, (_trigger_size - fx_trigger)
8181
.lclequ VOL_SLIDE, (fx_vol_slide - pipeline)
8282
.lclequ VOL_SLIDE_INC16, (_vol_slide_inc16 - pipeline)
@@ -109,5 +109,6 @@ _vibrato_size:
109109

110110
.lclequ BIT_TRIGGER_ACTION_DELAY, 0
111111
.lclequ BIT_TRIGGER_ACTION_CUT, 1
112+
.lclequ BIT_TRIGGER_ACTION_RETRIGGER, 2
112113
.lclequ BIT_TRIGGER_LOAD_NOTE, 4
113114
.lclequ BIT_TRIGGER_LOAD_VOL, 5

tools/nsstool.py

+23
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,13 @@ def register_nss_ops():
282282
("b_porta", ["speed"]),
283283
("s_pitch_slide_d", ["speed"]),
284284
("s_porta", ["speed"]),
285+
("fm_cut", ["delay"]),
286+
("s_cut", ["delay"]),
287+
("a_cut", ["delay"]),
288+
# 0x60
289+
("b_cut", ["delay"]),
290+
("b_delay", ["delay"]),
291+
("a_retrigger", ["delay"]),
285292
# reserved opcodes
286293
("nss_label", ["pat"])
287294
)
@@ -371,6 +378,8 @@ def convert_fm_row(row, channel):
371378
opcodes.append(fm_pitch_slide_u(fxval))
372379
elif fx == 0x03: # portamento
373380
opcodes.append(fm_porta(fxval))
381+
elif fx == 0xec: # cut
382+
opcodes.append(fm_cut(fxval))
374383
else:
375384
add_unknown_fx('FM', fx)
376385

@@ -457,6 +466,8 @@ def convert_s_row(row, channel):
457466
opcodes.append(s_pitch_slide_d(fxval))
458467
elif fx == 0x03: # pitch slide down
459468
opcodes.append(s_porta(fxval))
469+
elif fx == 0xec: # cut
470+
opcodes.append(s_cut(fxval))
460471
else:
461472
add_unknown_fx('SSG', fx)
462473

@@ -498,8 +509,12 @@ def convert_a_row(row, channel):
498509
jmp_to_order = 256
499510
elif fx == 0xff: # Stop song
500511
jmp_to_order = 257
512+
elif fx == 0x0c: # retrigger
513+
opcodes.append(a_retrigger(fxval))
501514
elif fx == 0x0f: # Speed
502515
opcodes.append(speed(fxval))
516+
elif fx == 0xec: # cut
517+
opcodes.append(a_cut(fxval))
503518
else:
504519
add_unknown_fx('ADPCM-A', fx)
505520

@@ -516,6 +531,10 @@ def convert_b_row(row, channel):
516531
jmp_to_order = -1
517532
opcodes = []
518533
if not is_empty(row):
534+
# pre note/vol/instrument effects
535+
for fx, fxval in row.fx:
536+
if fx == 0xed: # note delay
537+
opcodes.append(b_delay(fxval))
519538
# instrument
520539
if row.ins != -1:
521540
opcodes.append(b_instr(row.ins))
@@ -526,6 +545,8 @@ def convert_b_row(row, channel):
526545
for fx, fxval in row.fx:
527546
if fx == -1: # empty fx
528547
pass
548+
elif fx in [0xed]: # pre-instrument FX
549+
pass
529550
elif fx == 0x0b: # Jump to order
530551
jmp_to_order = fxval
531552
elif fx == 0x0d: # Jump to next order
@@ -540,6 +561,8 @@ def convert_b_row(row, channel):
540561
opcodes.append(b_pitch_slide_u(fxval))
541562
elif fx == 0x03: # portamento
542563
opcodes.append(b_porta(fxval))
564+
elif fx == 0xec: # cut
565+
opcodes.append(b_cut(fxval))
543566
else:
544567
add_unknown_fx('ADPCM-B', fx)
545568

0 commit comments

Comments
 (0)