Jump to content
Jet Set Willy & Manic Miner Community

IRF

Contributor
  • Posts

    5,105
  • Joined

  • Last visited

Everything posted by IRF

  1. No I haven't tried it out yet, and yes I think you might be right about me being one Willy out. The problem would become evident immediately upon testing of course. I was going to do a DEC A before the RLCA, but forgot, and in any case using ADD #9E would be more byte-efficient.
  2. The above intervention in the 'Lose a life' routine is actually one byte longer than the code which it makes redundant at #8958-64. However, replacing the LD C, #00 with a LD C,E command (E is defined as zero by the previous LD DE) will make the change 'globally byte-neutral'.
  3. In between the commands that are currently at #8C3B and #8C3C, do: RLCA ADD A, #A0 #9E LD L, A LD H, #50 LD DE, #9800 [points DE at 32 contiguous NOPPED out bytes] LD C, #00 CALL #9456 Then there is no need to wipe the bottom third of the screen at room refresh (i.e. you may delete #8958-#8964 entirely). Nor is there a need to print the Items/Time character row at each room refresh, as long as that is done once at the start of the game (i.e. the code currently at #8971-#897C can be cut and pasted somewhere after #88FC but before #8912). N.B. If the standard 'Infinite Lives' POKE is applied (#8C3B, #00 or POKE 35899,0 in decimal), then I suspect that when Willy is killed, the right-hand life on the status bar might disappear briefly and then reappear - as if that life is magically regenerated! Which might be quite a nice effect!
  4. That alternative approach should save a few bytes as well. (#857C-84.)
  5. Actually, instead of the clock update code editing the ASCII values at addresses #857F-84, and then the contents of those addresses being printed to the display file (to overwrite the zeroes in the 32-byte message that is printed separately from #8554-8573) - couldn't the clock update code just edit the ASCII values of the addresses #856D-72, which are embedded within the 32-byte message? Ditto with the item count update code - instead of editing the addresses #857C-E (which are then copied over to the display file separately, again to overwrite zeroes), the routine at #93D1 could just work directly on #8564-66. With the game initialisation code setting both the start time and item count directly within the 32-byte message as well. Then when the Room setup routine printed that character line, it would be writing the correct values instead of zeros. It would make things a lot simpler! (Unless there's some reason that I haven't thought of which would preclude this approach?)
  6. Yes, I'm getting the hang of your 'modus operandi' now!
  7. Actually - note to self - the code at #88FC-#8906 really belongs at the start of the 'Display the title screen and play the theme tune' routine (next to the code which initialises the item count to zero).
  8. The other day, following your previous comments on the matter, I was thinking about ways that would allow for the clock and item count to be printed only at the point when those elements actually need to be updated. If the text of the pertinent character line wasn't printed (with default '0's for the time and item count - see #8971-897C) each time the room is refreshed, then you wouldn't have to regularly overwrite the '0's. That character line could be printed once, at the start of the game (after #88FC, but prior to the 'Room setup' entry point at #8912). You would also need to print the initial values for the time and number of items at that point. But there is also a bit of code which wipes all the pixels from the bottom third of the screen whenever the room is refreshed (see #8958-8964). I tried removing that completely from the 'Room setup' routine, which only had one drawback - it meant that when Willy loses a life, the remaining lives carry on dancing, but the expired life was still shown (unanimated) on the status bar*. I thought that could be quite a cool effect, to distinguish the static, expired lives from the living, dancing ones - except that of course none of the lives dance if the in-game music isn't playing. So I'm considering a couple of options: - Enforce the animation of the remaining lives even if the music isn't playing (by tying the animation to the 'game clock' variable #85CB, instead of the 'music note index' at #85E1); - Every time Willy loses a life, erase the four character squares corresponding to the life that has just been lost (via an intervention at #8C3B). [*N.B. In Manic Miner, there may also be an issue with the air supply bar - if the program doesn't wipe the entire bottom screen-third, then the full length of the air supply character-row may need to be erased at 'cavern refresh', before the appropriate amount of air for the current cavern is drawn in.]
  9. I was thinking that in the routine which animates the conveyor, maybe the code at #9507-#950B should come before the code from #94F9 to #9506? Otherwise, in rooms that have no conveyor, the program needlessly calculates the pixel-buffer addresses for the start of a non-existent conveyor. I'm not sure whether swapping the code round as suggested above would cause a perceptible increase in execution speed (in conveyor-less rooms), but as you say, slowdown is accumulative.
  10. Don't worry, it's here on record now. Thank you for the clarification (and for the original optimisation!)
  11. That looks like it only rotates the pertinent pair of graphic bytes once per time-frame? Meaning that the Master Bed would visible animate? (Whereas it doesn't in the original game, because the pixel pattern is such that two rotations, in either direction, leave the value of the bytes unchanged.) Talking of making tweaks to the original arrangement, adjusting the number of INC H commands will allow a different pixel-row of the conveyor, at an arbitrary depth beneath the top pixel-row, to act as the counter-rotating element of the conveyor.
  12. Yes, that's what I meant. (Draw the arrow shaft first before reacting to the Zero Flag.) In relation to the byte count, I merely meant to point out that you did yourself a disservice!
  13. Error in Norman Sword's post about the conveyor animation?: http://jswmm.co.uk/topic/185-free-space-and-code-optimisation-in-jsw/page-8?do=findComment&comment=6105 Shouldn't that be a LD A,(DE) in the context of the revised logic?
  14. I believe that the running total of saved bytes at that point should be 10, rather than 9? I think it could also be done without using B (the net byte-saving would be the same). From #928E (rejigged code shown in bold): LD A,(IX+$06) LD (HL),A INC H INC H LD (HL),A DEC H LD A,(HL) AND C JP NZ,#90B7 ;>>>>> kill Willy LD (HL),#FF JP #93B3 The above arrangement would also mean that the arrow is drawn in its entirety at the moment when it hits Willy (whereas in the original code, only the top pixel-row is drawn at the point of death).
  15. The above approach should also allow the code which draws Willy and the Toilet to be optimised, by simply setting the appropriate variables and then jumping to the routine at #9456.
  16. In original JSW, at the instant when Willy collides with a guardian, that guardian is only drawn as far the graphical byte which collided with Willy. Furthermore, all guardians that appear subsequently in the current room's guardian list are not drawn at all in that moment. (That latter point means that composite guardians - for example the three-part Evil Priest Head or the Attic Centipede - are rendered incompletely at the time of Willy's collision with one component part of them*.) In the attached file, all the guardians (and arrows and ropes) in the current room are drawn in their entirety at the moment when Willy is killed by colliding with one of them. Note that in the attached file, the room still appears as 'empty' - without guardians, items or Willy - whenever Willy hits a Fire cell or falls a fatal distance. EDIT: * Unless it is the last component part to be drawn which is the one that Willy collides with. Complete Guardians.z80
  17. The following sequence in the arrow-drawing code, at #927D, is used to detect a cell containing white INK: AND #07 CP #07 JR NZ... In Geoff Mode this is replaced with the following sequence, providing a saving of one byte (it is in a slightly different location in Geoff Mode, at #9271): INC A AND #07 JR NZ... This trick could be repeated at #93ED, in the item-drawing code, which also seeks out white INK cells.
  18. Norman's latest contribution looks ingenious! I haven't fully got my head around it yet, but the basic principle is that, in his previous incarnation, only the lower nybble of the rope data table were used, so now he's merged pairs of entries so that it takes up half the space!
  19. Two bytes - one per set of five colours, there being ten coloured number buttons (five BRIGHT and five non-BRIGHT). But I haven't checked whether, in the context, DE (and BC) are being used in a loop to keep track of something else - if so, then having to PUSH and then POP would negate the saving!
  20. Danny, if the BC or DE register-pair weren't being used at the time, then maybe you could have done for example a LD DE, #0101 and then four ADD HL,DE commands (7 bytes in total), replacing four INC H and INC L (8 bytes)?
  21. I have resisted recent attempts by my laptop to install the latest upgrade of W10, mainly for reasons of laziness (not wanting to hang around and wait while it does it). In light of this news, I will probably resist the upgrade even more vehemently! I'm sorry that doesn't really help with your predicament!
  22. Nice one Norman! I came up with an optimisation which placed the INC, AND and OR in a subroutine, that is then CALLed eight times - but it only yielded a net saving of about ten bytes or so.
  23. The LD BC command at #8C8E only actually needs to be a LD C (one byte shorter), since the B register is redefined after that before B is used. **** In the 'Lose a life' routine, at #8C19, there is the sequence: LD C,E RRC C RRC C RRC C It occurred to me that this can be replaced by the following, which saves two bytes (net): LD A,E RRCA RRCA RRCA LD C,A After I came up with the above, something else then occurred to me. Immediately afterwards, at #8C20, there is an OR #10 command which SkoolKid identifies as (currently) being redundant (since it is immediately followed by an XOR A, which resets A to zero). However, if the above approach is used, then perhaps the intention of the OR #10 in Matthew's original code might be fulfilled (note that the OR gate has to be placed before A is loaded into C): LD A,E RRCA RRCA RRCA OR #10 LD C,A This has the effect of slightly lengthening the sound effect when Willy is killed, and the sound has a little more 'depth' to it. It is an extremely subtle effect - only really noticeable if you play modified and unmodified files in tandem, killing Willy in each file in turn. However, if you study the possible values that are held by the C register as the 'death sneeze' progresses, I am convinced that this was the original purpose of that OR #10 command! To recap: the 'death' sound effect loop is repeated eight times, as A descends through consecutive values from #47 (01000111b) to #40 (01000000b). Each time, the duration of the note is assigned to the C register (copied from A, via E) using the above operations. This yields the following values of C: #E8 (11101000b) #C8 (11001000b) #A8 (10101000b) #88 (10001000b) #68 (01101000b) #48 (01001000b) #28 (00101000b) #08 (00001000b) Note how Bit 4 of C always holds zero for each possible value of C. The OR #10 command sets Bit 4 of A, which would slot in perfectly in between the highest three bits and the always-set Bit 3. If this was the intention, then Matthew may have made the mistake of assuming that OR #10 would set Bit 4 of C in that context - something which can be achieved by my suggested tweaks to the code. (Although doing so will negate the two-byte saving that was my original aim when I started playing around with this part of the code!)
  24. This is the simplest layout change that will prevent an IDS jump off the top of Dr Jones to 'Quirkafleeg' - see the attached screenshot. The only room cell change is the addition of a single Fire block (the one directly underneath the square blue JSWED cursor). Oh, and I removed a pixel from the top-right corner of the Fire cells, to reduce the 'unicorn factor'. (Then again, if Dr Jones wouldn't believe it anyway, then there's no harm in making the creature as fantastical as possible!)
  25. Good stuff. It's probably always a good idea, when performing rotate operations, to hand over to the Accumulator wherever possible, instead of rotating one of the other registers (and especially avoid rotating an indexed offset byte). Using A is more efficient both in terms of saving bytes (because there's no need to use shift opcodes) but also in terms of reducing the number of T-states that the operations take to perform. (Incidentally, doesn't AND #7F do exactly the same thing as RES 7,A - but requires fewer T-states? ;) EDIT: It's small beer in the scheme of things, mind.)
×
×
  • Create New...

Important Information

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