The way this plays music bears little resemblance to the way Matthew played music. His was just an incremented pointer, playing at a fixed rate. Code wise :-
35648 LD A,(34273) Increment the in-game music note index at 34273
35651 INC A
35652 LD (34273),A
35655 AND 126 Point HL at the appropriate entry in the tune data table at 34399
35657 RRCA
35658 LD E,A
35659 LD D,0
35661 LD HL,34399
35664 ADD HL,DE
at this point (hl) holds the note data
"BC" will be set with a fixed value of 3
and my code --- minus most of the comments and data
; this plays variable length and variable note repeat and even mutes the music if needed
the call to STEP_INDEX- this adds "A" to "HL" and returns the contents of "(HL)" : A=(A+HL)
The routine below plays the in game music, changed from just being a variable delay.
snail_run:
ld hl,var_flag ; this is the speed factor
LD a,(MUSIC) ; the music flag (on/off)
bit 1,a
ld a,(hl)
LD D,0
jr Nz,set1_version
add a,4
LD D,#18
set1_version:
or a
ret z
; this loop is repeated less than 20 times at maximum slow down
;(the speed to execute this code compared to the delay this is calculating, means it is insignificant)
; on a flat out game (music off and fastest speed) this code is not executed.
ld e,a
ld bc,$190 ; a delay value
ld hl,0
sgk:
add hl,bc
dec a
jr nz,sgk
ld c,l
ld b,h
ld hl,repeating_note ; table of Blip values (how many times the note will blip)
ld a,e
call STEP_INDEX
LD E,A
S_M_C_RECHARGE: EQU $+1
ld a,2
dec a
jr nz,se1_note
inc (hl)
ld a,E
se1_note:
ld (S_M_C_RECHARGE),a
ld a,(hl)
and 63
LD HL,Music_data ; table of note data
CALL STEP_INDEX
ld e,a
E= note
BC= duration
L= mic toggle
D=mic toggle (the routine uses "L", so this must be copied, somewhere)
Note standard in all my code. if something starts with S_M_C_ it is indicating the value or variable is part of inline code that will be modified e.g. Self Modifying Code
;--------------------------------------------
The game notes are still played as designated minimum of two blips per note, However on the first pass the blip count is set to two and is similar to the problem in the original JSW. This is decremented and the first blip is played. This is one blip before the note index is moved to the next note.
On first game start up the speed index is set to very fast and in this instance the number of blips is set to 5 for all the subsequent notes and the blip counter should be set at 5 (or even 6) . Not as stated above at 2.
Playing one blip is equivalent at the game start to playing 1/5 of a note, Which is more noticeable than the equivalent problem in the original. All the changes in speed reset the blip count after each note. The routine has no external counters and does not get updated outside of the music/delay routine. The note index is reset on each game.
The technical problem is the blip count, which was not reset and due historically to this being a two blip game was left as 2 (which would have still omitted the first half of the note, even if the game was started at the slowest speed). I thought it would take too much code to actually adjust the blip counter at reset to the required value on a game reset (I knew it was a problem- just was not bothered, to actually fix it--- this does have a great big banner on it saying DEMO of speed)
addendum to the paragraph above......( on subsequent slow speed game, playing, with 2 blips per note) Not resetting the blip count can make it either skip one blip on subsequent game resets or skip the whole note. The chances are 50-50
I have now fixed this problem and inserted a blip reset, and changed the note index to the last note. This ensures on the first pass the blip count is reset to the correct value for its speed, and the note is stepped to the next note, which will be the first note. This was done by changing the data in a data reset list from (NOTE_INDEX ,0) to (NOTE_INDEX ,63) and inserting 2 more values (S_M_C_RECHARGE , 1). The modification was far easier than I thought at the time of writing the original.
-------------------------
As I mentioned before I do not listen to the music, it is turned off. If the game had crashed or started playing very obvious long note sequences.I might have checked it a bit more or at least bothered to investigate how I could reset the data. It played and it was not the focus of what I was doing.
Edited by Norman Sword, 26 January 2019 - 07:55 AM.