-
Posts
5,111 -
Joined
-
Last visited
Everything posted by IRF
-
But if I'm running game files on an emulator, with no loader, how does it know to start at #8400?
-
Richard, Sorry to be a pain, but I don't think your latest iteration of the 'Through the Wall' entry in your Manic Miner disassembly is quite accurate yet: http://skoolkit.ca/disassemblies/manic_miner/reference/bugs.html#throughTheWall "This happens because the section of code at 35600 - which is executed during jumping animation step 16, after Willy's y-coordinate has been updated so that he's exactly one cell height above the place he jumped from, but before his x-coordinate has been updated - checks whether there are any nasty tiles in the cells below Willy's sprite. If there are (as is the case here), the code jumps forward to 35665, which makes Willy proceed to the next jumping animation step (as if the bricks were not there), instead of landing on the bricks." Regarding the text highlighted in bold, if you look at the illustration for Jumping Animation Step 16, you will see that there aren't any Fire cells under Willy's sprite (there are actually two 'brick' Earth cells). Part of the confusion relates to the text highlighted in the quote above in italics. In fact, if you consider a jump from start to finish, it's actually the other way round - Willy's x-coordinate is updated before his sprite is drawn to the screen, but his y-coordinate is updated after his sprite is drawn. (More comments on that later*.) Now, during a jump the check for Fire cells (to determine whether to jump forward to 35665) can only be determined when the Jumping Animation Counter has reached a value of 16 (or 13). However, this takes place after the Jumping Animation Counter has been incremented by the command at 36355. But the Jumping Animation Counter is used to calculate Willy's current y-coordinate at 36330 i.e. before the Jumping Animation Counter is incremented. As a result, as far as your illustrations are concerned, the pertinent check for Fire cells is taking place at Step 15. At that point, Willy's 'physical presence' is cell-row-aligned, with his back foot directly above the left-most Fire cell (and his front foot above the adjacent 'brick' Earth cell). However, because the y-coordinate of his sprite hasn't been updated yet, there appears to be a vertical gap (of three pixels) between Willy's back foot and the Fire cell. In contrast, at the point in time represented by the illustration for Step 16, Willy's 'physical presence' is four pixels lower than where his sprite is drawn, so he is not cell-row-aligned. By now, the Jumping Animation Counter has reached a value of 17, so the checks for Fire cells beneath him are not reached (but in any case he has moved past the cell-column boundary, so he is no longer straddling a Fire cell). * As for the order in which Willy's x- and y- coordinates are updated, this is counter-intuitive because the code that progresses Willy's y-coordinate in a jump is at Move Willy (1) i.e. before the code at Move Willy (3), which moves him sideways and causes him to pass from one cell-column to the next. [The 'Draw Willy' routine of course comes after the 'Move Willy' routine in the Main Loop.] However, because the check for Jump keys (which initiates the jumping sequence) is in Move Willy (2), each incrementation of the jump is drawn with the adjustment of the y-coordinate lagging behind that of the x-coordinate. i.e. What you see on the screen is a 'snapshot' taken after Willy's x-coordinate has been moved on, but before his y-coordinate is updated. You can see evidence of this at the end of the jump. It's the reason why he appears to drop from 4 pixels up, to his final landing position, without his frame of animation being updated (it's 'left-facing frame 2' in both cases; see your illustrations for Jumping Animation Step 17 and 18 - both of which actually represent Jumping Animation Counter values of 18, for the reason discussed earlier). In the last time-frame of his jump, his sprite is drawn before his y-coordinate is updated. Then the next time the program passes through the Main Loop, his sprite's position is updated to reflect his true y-coordinate. (I haven't checked this yet, but if either a 'Left' or 'Right' movement key were kept depressed throughout the jump, then the illustration for 'Step 18' may not be as shown - he would either have moved on to 'left-facing frame 1', or else turned around to be in 'right-facing frame 2'.) You can also witness the 'lag' of the y-coordinate behind the x-coordinate if you study the very beginning of the jump, when Willy appears to walk forward by one frame of animation before starting to ascend. Which doesn't make sense if he's jumping from a position at the edge of a precipice - his sprite appears to walk off the edge (with no supporting structure beneath him) before the jump commences. But again, it's because in the first time-frame of his jump, his x-coordinate is updated before his sprite is drawn, but his y-coordinate isn't. ************ Apologies if all that was a bit long-winded, but if I were to try and summarise it: The current illustrations in the MM disassembly represent 'snapshots' taken before Willy's vertical pixel coordinate has been updated, and before the Jumping Animation Counter has been incremented. Unlike your previous set of illustrations, the latest ones reflect exactly what is seen on the screen. However, the previous snapshots showed where Willy is located immediately prior to the check for Fire cells underneath him (and the current value of the Jumping Animation Counter at that point), and so they did actually provide a better representation of what is occurring with this quirky aspect of the game engine!
-
It's clear that #8000 is the start of the uncontended (higher) memory. But I'm still none the wiser as to why the program starts running at #8400?! Is it hard-wired into the processor? i.e. do all Spectrum games have that starting point?
-
But 32768 (in binary) equates to #8000, not #8400? So somehow the machine is starting off at a point that is 1 KB further on than the beginning of the Higher Memory Area?
-
How does the Spectrum/machine/emulator know that it should commence interpreting code at the address #8400?
-
Update: Not only does the above optimisation work fine (saving two bytes), there is also another three-byte optimisation to be found. Currently, the 'new' section of code (called from the main 'Draw the Guardians' routine) is as follows: 7e e6 38 c2 f2 91 dd 7e 01 e6 0f c6 38 e6 47 4f 7e e6 38 c3 fb 91 It can be shortened to this: 7e e6 38 c2 f2 91 4f dd 7e 01 e6 0f c6 38 e6 47 c3 fb 91 You can see that the '4f' instruction (LD C, A) has been moved back in the code, and two commands (of total length three bytes) '7e e6 38' have been removed. Those two commands: LD A, (HL) AND #38 assign the Paper colour of the guardian's background cells to Bits 3-5 of A. But that had already been achieved by the first three bytes in the new code, so by copying that across to the C register, before the Ink colour and Brightness of the guardian are attributed to the A register, the same thing is achieved more efficiently. Instead of doing the calculation XOR [Guardian Ink/Brightness], the code would then be doing [Guardian Ink/Brightness] XOR . Which is the same thing, as the XOR command is a commutative function i.e. A XOR B = B XOR A.
-
Regarding the above I've just noticed that, whilst it wasn't mentioned in the latest Changelog, Richard has added a note to that effect in the relevant page of his disassembly (and also towards the end of the preceding page): http://skoolkid.github.io/jetsetwilly/asm/8141.html http://skoolkid.github.io/jetsetwilly/asm/8100.html Thanks Richard! :)
-
I've just had a thought - if we were to try to come up with a 'fix' for the above, we'd have to be careful not to implement it in such a way that prevents Willy from walking down the ramp into The Swimming Pool (i.e. through the Water cells - which in this case really do justify that name!) Or for that matter, walking down the Ramp from West Wing Roof to West Wing.
-
Danny, did you pick up the document I forwarded via a PM (it fell at the end of a 'page' of messages so you may have missed it). If so, did it help you to formulate the appropriate words for your readme?
-
To answer my own question, I think it could just cause more problems than it solves! If the check for Fire cells was applied to the Empty Room Attribute Buffer, then it should still correctly pick up Fire cells within the room, but if Willy's sprite occupied the bottom two cell-rows (i.e. as he's falling off the bottom of the screen), then the check for Fire cells underneath him will probably wrap beyond the bottom of the screen to the Screen Buffer (for an occupied room) at #6000 (which contains the pixel patterns of all the room elements and all the entities within the room). Therefore the check for Fire cells will probably pick up the top pixel-row of the cell that lies in the uppermost cell-row directly above Willy. So if that cell happens to contain something (not necessarily a Fire cell!) whose first graphics byte (i.e. top row of pixels) matches the attribute byte for the Fire cells in that room, then the program will interpret that as if Willy has landed on a Fire cell, and kill him! Any room element (Earth/Water/Ramp cells) at the top of the screen could potentially cause such a match, giving rise to a 'misdiagnosis' that Willy has stood on a Fire cell! It could even occur if an (uncollected) item lies at the top of the screen, whose first pixel-row matches the colour-attribute of the Fire cells. (N.B. such a match does actually exist in Tree Root, although the items aren't at the top of that screen.) Or if a horizontal guardian happened to pass along the top of the screen, through the pertinent cell, such that the top pixel pattern of the portion of the guardian that instantaneously occupies that cell, matches the Fire cells' colour-attribute at the precise moment just before Willy drops off the bottom of the screen, then it could also trigger a positive check for a Fire cell 'beneath' him and kill him!
-
Oops, typo corrected! (I was getting ahead of myself, with a half-formed answer to my own question in my own head as I typed - on which more later!)
-
I notice that in his disassembly, Richard has managed to identify the precise cause of the bug (or quirky feature?) whereby a Fire cell at the top of the screen can kill Willy if he drops off the bottom directly underneath: http://skoolkit.ca/disassemblies/jet_set_willy/reference/bugs.html#longDistanceNasties I had got as far as surmising that it's something to do with the check for Fire cells, underneath the 2x2 square of cells occupied by Willy, somehow wrapping around from the bottom of the screen to the top. However, the 'missing link' in terms of the explanation is that the Attribute Buffer for the occupied room (i.e. occupied by guardians, items and Willy) at #5C00, is immediately followed in the code by the Attribute Buffer for the empty room (i.e. the room without guardians, items or Willy - but, crucially, WITH the Fire cells) at #5E00. Whilst it can be quite a useful bug in terms of preventing Infinite Death Scenarios, I wonder if hypothetically this could be fixed by pointing the check for Fire cells to the Empty Room Attribute Buffer at #5E00 instead of the Empty Room Screen Buffer Occupied Room Attribute Buffer at #5C00? Any thoughts?
-
Another suggestion for the disassembly: The POKE that fixes the 'uncollectable item' in Conservatory Roof (the rightmost item) does not fix the fact that Willy has to sacrifice a life in order to collect the leftmost item in that room. A simple single-POKE fix for this is to extend the green platform to the left of the conveyor by one cell leftwards: POKE 60269, 1 EDIT: Sorry, having playtested this you would also have to 'delay' the Red guardian by shifting its starting position rightwards by one cell, otherwise Willy couldn't jump over it in time without hitting a fire cell: POKE 60401, 21 Still, it only takes two POKES (on top of the Software Projects one that removes the rightmost fire cell) to make this screen completable without loss of life. However, see the following link for a more satisfactory visual fix which, by shifting all the fire cells and items along to the left by one cell (and rejigging a couple of platforms), manages to keep them all paired up (as per the original screen), whilst ensuring that all four items can be collected without losing a life: http://jswmm.co.uk/topic/65-conservatory-roof-changes/?p=4310 That would take quite a few POKES, although it should be within Richard's ten-POKE limit: four to shift the items individually, three to move the fire cells (room cell attributes are grouped in blocks of four per byte) and three to rearrange the water cells near the bottom (ditto). EDIT: Let's see, these should do it: POKE 42421, 30 POKE 42422, 24 POKE 42423, 27 POKE 42424, 21 POKE 60229, 195 POKE 60230, 12 POKE 60231, 48 POKE 60269, 4 POKE 60270, 16 POKE 60285, 1
-
Richard, I notice you've picked up the point about the Nightmare Room conveyor having its attribute and graphic data placed incorrectly in the code. The solution to which is to shift bytes 56780-56788 forward by one byte to 56781-56789. However, perhaps you could also make the point that if the byte that 'falls off the end' (from 56789) is rotated back to occupy 56780, then it also fixes the visual appearance of the ramp cells (filling in the 'air gap' at bottom of the ramp)?
-
In the original set-up, each note in the tune is played twice, but because the tune begins at a 'Music Note Index' value of 1, rather than Zero, the first note is heard at the very beginning, but for only half the duration - if you see what I mean? i.e. one instance of the first note at #865F, followed by two instances of the second note at #8660, two instances of the third note at #8661, etc. [Once the tune rendition has finished, the first note will play twice as the tune wraps round, so this 'glitch' will only affect the very start of the game.] However, if you've changed the code (as previously discussed) so that the tune plays at double the normal speed (i.e. the first note of the game is played when the Music Note Index is at a value of 1, the second note when the Music Note Index is at 2, etc), then I think the first actual note in the code ('Note Zero' as it were; the note represented by byte #865F) will be missed out entirely at the start of the game - unless you've initialised the Music Note Index to FF (in which case the M.N.I. is incremented by #8B43 to a value of 00 prior to a note being played). I hope that makes sense?
-
I believe that everything from #840C to #841E is redundant code.
-
Something's just occurred to me - because of the INC A instruction at #8B43, the first note of the in-game tune may be skipped at the very start of the game. This is something I've often wondered about, but I wasn't sure if it was my ears deceiving me! To prevent it from occurring, the Music Note Index at #85E1 could be initialised to FF instead of 00. Then on the first pass through the Main Loop, it will be incremented to zero, so the first note of the tune (or should we call it the '0th note'?) will be selected in the first instance.
-
Following on from my previous post, see the attached test file. There is one item in the game to collect (Bathroom tap). If you leave the tap, walk left to Top Landing and lose some lives by hitting the Swiss Army Knife, you'll notice that the tune pitch deterioration appears to be disabled. But if you collect the tap, then proceed to the Master Bed, then let Willy run to the toilet, you'll notice that at each stage (change of Game Mode), the pitch deteriorates! The command at #8B51 which loads up the number of lives remaining from #85CC to the A register, is instead picking up the Game Mode Indicator (#85DF). I've also removed the SUB and NEG commands, and added a couple more RLCA instructions (four in total now), as suggested in the previous post. Fewer RLCA's will yield a more subtle deterioration of the tune. If you wanted a more extreme deterioration, add more RLCA's. (EDIT: Actually, on that latter point, to be more byte-efficient I believe you could replace the RLCA's with RRCA's and have fewer than four. i.e. rotate the bits of A along in the opposite direction. 3xRRCA achieves the same thing as 5xRLCA, 2xRRCA is equivalent to 6xRLCA, etc.) pitchbygamemode.z80
-
I like the Cross Item you came up with, keeping the item near its original location. :)
-
It's a long-standing problem. Even the 'official' POKE released by Software Projects was a bit of a fudge, I think.
-
I've come up with the attached alternative layout for Conservatory Roof. It keeps the Fire cells and Items all paired up, retains four of each in more or less the original location to the original (under the 'glass roof), and all four Items can be collected without loss of life. (One requires a 'standing jump' on the Conveyor to avoid hitting a Fire cell.) I've also checked that there is no 'short-cut' enabled by jumping through the ramp, which would otherwise mean the player could avoid having to climb the Banyan Tree. Finally, Willy can drop down to The Orangery safely to either side of the lowest Water cell, without entering into an IDS. To be implemented in the Bug Fix 2016/17 Edition perhaps? (when we assemble all the other bug fixes that we've come up with over the last six months) The visual appearance of the Conservatory Roof Conveyor could also do with improvement, but I think layout-wise I've nailed it, in terms of being as true as possible to Matt Smith's original vision! Only 32 years after the game's release, as well!
-
I spotted the Earth cells 'behind' the conveyor in Esmeralda as I was studying the raw data for the room layout in the disassembly! (Whilst trying to figure out a POKE to add an extra Earth cell below the conveyor.)
-
Curiously, the order in which ramp and conveyor attributes are laid out is the opposite to the way in which their pixel patterns are drawn, meaning that if a ramp intersects a conveyor, the cell where they cross has the same pixel pattern (with animation) as the conveyor, but the colour-attribute of the ramp (and so the same underfoot behaviour as a ramp). EDIT: The above refers to what you see 'in-game'. In JSWED, the ramp pixel pattern (unanimated) is drawn, rather than the conveyor pixels. (Sorry Richard, I think I've veered off-topic!)
-
P.P.S. Another thought that was sparked by the previous one: The cells in Rescue Esmerelda containing ramps have byte value suggesting they are occupied by Water cells. Which of course, they are. This screen and others (most notably Out on a Limb) have multiple Water-Ramps, achieved by matching the attributes for Water and Ramp cells. This is something that the JSW disassembly doesn't mention. There is an entry covering Conveyor-Ramps aka Escalators (e.g. The Chapel - see 'Slippery Slopes' in the Trivia section), but no mention of the Water-Ramps as far as I am aware?
-
P.S. When coming up with the above POKE I noticed that, based on the value of the bytes for the appropriate point on the screen, the conveyor in Rescue Esmeralda seems to be overlaying Earth cells (i.e. 52774 has a value of 170, or 10101010 in binary,not just zero as is the case for most conveyors). So presumably Willy can't jump up through that conveyor - perhaps this gives the player a bit of protection against accidentally 'overshooting' and hitting Esmeralda when trying to collect the 'gate' items? I'd never noticed this before! (the conveyor pixel pattern and colour overrides the Earth cell graphics, so they aren't visible). Matthew Smith's original game can still throw up a few surprises!! Scrap that, the routine at 36203 is ordered such that conveyor attributes (and then ramp attributes) overwrite all the attributes that were previously laid out on the screen buffer, so Willy can jump through the conveyor in Rescue Esmeralda! (i.e. it doesn't display Earth cell-like properties, despite the above).