Jump to content
Jet Set Willy & Manic Miner Community

IRF

Contributor
  • Posts

    5,095
  • Joined

  • Last visited

Reputation Activity

  1. Haha
    IRF got a reaction from Norman Sword in Playing around with the in-game tune in JSW   
    Actually Andy, you might need to think again there. Did you actually try that out? Because looking at it again, E isn't actually updated when the tune note index is increased, so when DE is added to HL (the second definition of HL) at #8B50, it won't pick up the new note during the current pass through the Main Loop.
    So you would need to use that spare, NOPped out byte at #8B4C for a LD E, A instruction.
    Edit: Thinking about it, the effect of E not being updated straight away probably just means that the tune will be playing 'one note behind'. It should play at the right speed. But the first note (first pitch value) will only play half as long as it should when you start playing the game. (And the normal fix for that - setting the music note index to #FF during game initialisation - won't work this time; I think that would cause the last note of the tune to be played during the first pass through the Main Loop.)
  2. Wow
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    Actually Andy, you might need to think again there. Did you actually try that out? Because looking at it again, E isn't actually updated when the tune note index is increased, so when DE is added to HL (the second definition of HL) at #8B50, it won't pick up the new note during the current pass through the Main Loop.
    So you would need to use that spare, NOPped out byte at #8B4C for a LD E, A instruction.
    Edit: Thinking about it, the effect of E not being updated straight away probably just means that the tune will be playing 'one note behind'. It should play at the right speed. But the first note (first pitch value) will only play half as long as it should when you start playing the game. (And the normal fix for that - setting the music note index to #FF during game initialisation - won't work this time; I think that would cause the last note of the tune to be played during the first pass through the Main Loop.)
  3. Wow
    IRF got a reaction from Spider in Playing around with the in-game tune in JSW   
    Actually Andy, you might need to think again there. Did you actually try that out? Because looking at it again, E isn't actually updated when the tune note index is increased, so when DE is added to HL (the second definition of HL) at #8B50, it won't pick up the new note during the current pass through the Main Loop.
    So you would need to use that spare, NOPped out byte at #8B4C for a LD E, A instruction.
    Edit: Thinking about it, the effect of E not being updated straight away probably just means that the tune will be playing 'one note behind'. It should play at the right speed. But the first note (first pitch value) will only play half as long as it should when you start playing the game. (And the normal fix for that - setting the music note index to #FF during game initialisation - won't work this time; I think that would cause the last note of the tune to be played during the first pass through the Main Loop.)
  4. Like
    IRF reacted to jetsetdanny in Playing around with the in-game tune in JSW   
    Actually, I need to correct both yourself, Ian, and myself! (I let myself be carried by your erroneous and, in fact, slightly blasphemous suggestion! 🤪)
    Each of the 20 in-game tunes in "Manic Person" is 128 bytes long. If they were 'only' 64 bytes long, there would be enough spare space also for a custom font (1280 spare bytes versus 768 needed for a full font).
  5. Like
    IRF reacted to Spider in Playing around with the in-game tune in JSW   
    Yes , it assumes that A is still set to zero as a result of the command at #8B3C
  6. Like
    IRF reacted to jetsetdanny in Playing around with the in-game tune in JSW   
    Ian, I never thanked you for answering my request and for all the information and code solutions you have provided! Thank you so much, it is all greatly appreciated! 🙂 👍
    I remember once in the past I did have a look at the Jet Set Mini code, but couldn't make enough sense of it to be sure what you had done there. I probably didn't try hard enough (I didn't need a 256-byte-long tune 'seriously', I was only toying with some ideas). In any case, it's great to have everything explained plainly in this thread! So thanks again 🙂.
  7. Like
    IRF reacted to jetsetdanny in Playing around with the in-game tune in JSW   
    Exactly. Even with 64-byte-long tunes there was no room left for any extras. A suggestion was made after the game was released that it could do with a non-standard font. It was a very good suggestion, but unfortunately impossible to apply without far-reaching changes to the game engine that would optimise the code 'a la Norman Sword' and free up enough space to implement a new font.
  8. Like
    IRF got a reaction from Spider in Playing around with the in-game tune in JSW   
    I should add that your more efficient solution wouldn't work in Manic Miner (if you were using the air supply variable #80BD to keep track of when to advance through the tune), because bit 2 of #80BD acts as the game clock, not bit 0. You would have to rotate the bits of A (twice) after the AND #04, eliminating the byte saving.
  9. Like
    IRF got a reaction from Spider in Playing around with the in-game tune in JSW   
    That's similar to my solution, but not identical. You seem to have a spare byte in there, so you could afford to retain the original two-byte LD D, #00 command, instead of the single-byte LD D, A. That would mean the patch isn't reliant on A having been reset to zero beforehand. (Since a lot of game designers ditch the preceding inactivity code which sets A=0.)
  10. Like
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    Indeed! Only 64 bytes per tune though. If you had 20 tunes of 256 bytes each, that wouldn't leave much room for anything else! 
  11. Like
    IRF reacted to jetsetdanny in Playing around with the in-game tune in JSW   
    That's exactly what happens in "Manic Person"!
  12. Like
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    I should add that your more efficient solution wouldn't work in Manic Miner (if you were using the air supply variable #80BD to keep track of when to advance through the tune), because bit 2 of #80BD acts as the game clock, not bit 0. You would have to rotate the bits of A (twice) after the AND #04, eliminating the byte saving.
  13. Like
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    That's similar to my solution, but not identical. You seem to have a spare byte in there, so you could afford to retain the original two-byte LD D, #00 command, instead of the single-byte LD D, A. That would mean the patch isn't reliant on A having been reset to zero beforehand. (Since a lot of game designers ditch the preceding inactivity code which sets A=0.)
  14. Like
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    Overnight, a couple of other things have occurred to me in relation to the above patches.
    In relation to the JSW patch, there's no need to use the trick of initialising the music note index to #FF at the start of the game - that might actually cause the game to begin by playing the last note of the tune first! (if the conditionality of the relative jump is such that the note index isn't incremented during the first pass through the Main Loop). 
    And for the MM patch, because of the fact that the initial air supply differs between caverns (some start off holding an even number of units of air; others start off with an odd number), that patch will mean that in some caverns the first note will be played shorter than usual. That can be fixed by ensuring that all caverns start off with either an even or an odd number of air units (bearing in mind that a single air decrement is a value of 4). 
    EDIT: D'oh! Sorry, that second point isn't an issue unless your game initialises the music note index at the start of each cavern. Which doesn't happen in the original Manic Miner - ITHOTMK just carries on where it left off after you go through a portal to the next cavern. But I suppose it might be the case if someone were to devise a game with a different tune for each cavern, and they wanted each tune to begin playing with its first note as the player encounters them.
     
  15. Thanks
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    Okay, with a bit more rearrangement, this should work to enable a 256-byte in-game tune for the Manic Miner game engine - insert the following at addresses #883A to #8851:
    LD A, ($80BD) - lower byte of the air supply
    AND #04 - test bit 2
    LD HL, #845B - point HL at the music_note_index variable; NB this doesn't affect the Zero Flag
    JR Z, #8845 (or JR NZ, whichever polarity doesn't cause the first note to be missed or curtailed upon game startup) - conditional relative jump past the next single-byte command
    INC (HL) - the conditional jump prior to this command will ensure that the code which increments the music note index is only executed when the game tick counter holds either an odd or an even value, thereby slowing down the rendition of the tune.
    LD E, (HL) - pass the value of the music note index to E
    LD BC, #0003 - this command was previously at #884F
    LD D, B - resets D to zero in a single byte
    LD HL, #858C - point HL at the table of tune data
    ADD HL, DE - adjust HL to find the current note
    LD E, (HL) - pick up the note pitch value
    LD A, (#8073) - pick up the current cavern border colour
    Then #8852 onwards is as normal.
  16. Wow
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    P.S. If you have already recycled the 'inactivity code' (#8B3C-3F), then you'll need to find an extra byte from somewhere else (two bytes to define LD D, #00 but you won't need the earlier single-byte LD D, A command).
    EDIT: In fact, if you're trying to apply this to a Manic Miner game then you'll have to find an additional byte from somewhere anyway, as the inactivity code doesn't exist in that game engine.
    FURTHER EDIT: Actually, you would have bigger fish to fry if you're trying to implement this in a Manic Miner game. The code in my previous post relies upon the minute/tick counter (#85CB in JSW) to decide when to increment the music note index. But there is no similar minute counter in the MM game engine. So you would have to introduce one (it wouldn't need a whole byte; just a single bit which acts as a flag and toggles between set & reset (probably via a XOR) every time that the Main Loop is executed.
    I suppose you could use the lower byte of the air supply variable (#80BD) for this purpose - it is decremented by a value of 4 each time, so you would have to test bit 2 (AND #04) for the purpose of playing the music at the regular speed. Or you could test bit 3 (AND #08) for an even slower rendition. But then you might have an odd effect in the solar cavern whereby the music either occasionally plays faster, or else gets stuck on the same note, whenever Willy is inside the solar beam? But then I suppose that could be quite a fun, quirky effect!!
  17. Like
    IRF reacted to Spider in Playing around with the in-game tune in JSW   
    Nopping out #8B47 and #8B49 would do but its too fast then. So...

    XOR A                            ;8B3C      ;                  clear the inactivity timer at L85E0      LD (inactivity),A            ;8B3D      ;L85E0     LD D,A                           ;8B40      ;                   initialise the mSB     LD a,(game ticker)       ;8B41      ;L85CB        the game ticker at 85CB     AND 1                            ;8B44      ;                   issolate odd or even game ticker bit     LD HL,(ingame_music) ;8B46      ;L865F        set HL to the music offset pointer     LD E,(HL)                       ;8B49      ;                   get the present offset     ADD A,E                        ;8B4A      ;                   add the ticker (odd/even) value     LD (HL),A                      ;8B4B      ;                   store the updated offset    NOP                              ; 8b4C      ; back to the original code    LD HL,ingame_music    ;8B4D     ;L865F    ADD HL,DE                    ; 8B50    ; >>> HL IS POINTING AT THE NOTE value
  18. Like
    IRF got a reaction from Spider in Playing around with the in-game tune in JSW   
    Overnight, a couple of other things have occurred to me in relation to the above patches.
    In relation to the JSW patch, there's no need to use the trick of initialising the music note index to #FF at the start of the game - that might actually cause the game to begin by playing the last note of the tune first! (if the conditionality of the relative jump is such that the note index isn't incremented during the first pass through the Main Loop). 
    And for the MM patch, because of the fact that the initial air supply differs between caverns (some start off holding an even number of units of air; others start off with an odd number), that patch will mean that in some caverns the first note will be played shorter than usual. That can be fixed by ensuring that all caverns start off with either an even or an odd number of air units (bearing in mind that a single air decrement is a value of 4). 
    EDIT: D'oh! Sorry, that second point isn't an issue unless your game initialises the music note index at the start of each cavern. Which doesn't happen in the original Manic Miner - ITHOTMK just carries on where it left off after you go through a portal to the next cavern. But I suppose it might be the case if someone were to devise a game with a different tune for each cavern, and they wanted each tune to begin playing with its first note as the player encounters them.
     
  19. Thanks
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    The simplest way to have a 256 byte in-game tune is this:
    Extend your tune data to 256 bytes.
    Then just NOP out the commands at #8B47 and #8B49.
    ****
    However, that by itself will cause the tune to play too fast (as the note counter will be incremented during every pass through the Main Loop). To slow it down to the regular speed, a bit more editing is needed. Insert this into the range of addresses #8B40-#8B4C:
    LD D, A (for the addition later on - N.B. this assumes that A is still set to zero as a result of the command at #8B3C)
    LD A, ($85CB) (game_tick_counter variable)
    AND #01 (test bit 0 of the game tick counter)
    LD HL, #85E1 (point HL at the music_note_index variable; NB this doesn't affect the Zero Flag)
    JR Z, #8B4C (or JR NZ, whichever polarity doesn't cause the first note to be missed or curtailed upon game startup) - conditional relative jump past the next single-byte command
    INC (HL) - The conditional jump prior to this command will ensure that the code which increments the music note index is only executed when the game tick counter holds either an odd or an even value, thereby slowing down the rendition of the tune.
    LD E, (HL) - the conditional jump above jumps to here if the condition is met
    Then #8B4D onwards is as normal.
    P.S. You could check that part of the Main Loop in the Jet Set Mini code to see the above in situ.
  20. Like
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    First paragraph - that's how I feel whenever I hear the short, 64-byte version of the Radetzky March in-game tune, after having implemented a 256-byte version (score courtesy of Richard Hallas) in Jet Set Mini.
    How to achieve a 256-byte tune? I'll get back to you - although the answer may be in an earlier post of this thread? 
  21. Thanks
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    If I Were A Rich Man.
    And ITHOTMK = In The Hall Of The Mountain King.
  22. Like
    IRF reacted to jetsetdanny in Playing around with the in-game tune in JSW   
    In the projects I've been involved in, this mechanism (turning the tune on at a specific moment even if the player was playing with the music off) has only been used for the game's completion, when a new - 'victory' - tune kicks in upon reaching the toilet. I believe you actually provided the code to enforce this, Ian - for which I continue to be grateful! 🙂
  23. Like
    IRF reacted to jetsetdanny in Playing around with the in-game tune in JSW   
    Thanks, Ian! I must say that now when I listen to the original 64-byte-long version of "If I Were a Rich Man" in other games (for example when recording their RZX walkthroughs), it seems very incomplete...
    Ian, in one of your projects, you applied a 256-byte-long in-game tune. Could you explain how you did it (from the technical point of view)?
  24. Like
    IRF reacted to jetsetdanny in Playing around with the in-game tune in JSW   
    Great minds... 😁
    What's "IIWARM"?
    IIRC in my setup the note index is set to #FF when the tune is supposed to start from the first note, so that when the in-game music note index is incremented on the first pass through the code *before* the first note is played, it is incremented from #FF to 0 and so the first note is not missed.
  25. Like
    IRF got a reaction from jetsetdanny in Playing around with the in-game tune in JSW   
    In the case of 'In the Hall of the Mountain King', I believe I did that classical piece of music justice in 'Manic Mixup' - implementing a quite faithful 128-byte loop during gameplay (which doubles in speed of play when the air supply in each cavern reaches the 'red zone' - replicating the way that ITHOTMK gains pace towards the end), and a coda that is played during the 'cavern completion' sequence (when Willy goes into a flashing portal), which matches the finale of Greg's original composition. 😎
    I look forward to hearing what you've done with it, and also your extended rendition of 'If I Were A Rich Man'. 😊
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.