Jump to content
Jet Set Willy & Manic Miner Community

[File] JSW jagged finger effect (demo)


Norman Sword

Recommended Posts

One thing to also bear in mind is that most emulators allow you to disable memory contention (or not) which can result in slightly different effects.

 

This 'memory contention' is why things like loaders do not work properly in the lower ram and why most games tend to use the upper memory for the 'main loops' and lower memory

Link to comment
Share on other sites

  I will agree with your sprite drawing layout. (hence the title I used Jagged finger look)

 

Below is a quick mock up of the effect. On the left the red square is moving to be in the position of the black underlying square.  During screen refresh the screen is being updated from displaying the red square and now needs to display the black square. During the screen refresh the raster overtakes the block move LDIR and we end up with the composite of the red plus the black square- the jagged finger outline on the right. This effect will change from frame to frame and position to position. This is the flicker that follows the sprites around. (depending on how fast they move and in what direction and where the raster is when it is overtaken) 

 

I was surprised that Matthew implemented a "Y-table" of offsets then chose to ignore the table when it came to the task of screen copying. The overhead (speed reduction) is very, very  small.  

post-125-0-16686400-1491163312.jpg

Link to comment
Share on other sites

Is that example drawing pairs of graphic bytes, vertically-paired? If so, I don't think that's what happens? Except (sort of) during the transition from the top half of the playing area to the bottom half - the bottom pixel-row of character-row 7 is drawn immediately before the top pixel-row of character-row 8.

 

When I said "pairs of graphic bytes", I was referring to a byte from the left half of Willy's sprite, followed by the adjacent byte from his right half.

Link to comment
Share on other sites

And with the above comment, I will no longer elaborate. because your statement is so very wrong.  

 

starting at the top the screen updates -- Physical scan line update

 

 

raster line 00 - screen char 0 line 0  an ldir will update 0

raster line 01 - screen char 0 line 1                                8

raster line 02 - screen char 0 line 2                                   16

raster line 03 - screen char 0 line 3                                     24

raster line 04,- screen char 0 line 4                                      32

raster line 05 - screen char 0 line 5                                        40

raster line 06 - screen char 0 line 6                                          48

raster line 07 - screen char 0 line 7                                           56

raster line 08 - screen char 1 line 0                              1

raster line 09,- screen char 1 line 1                                9

raster line 10 - screen char 1 line 2                                 17

raster line 11 - screen char 1 line 3                                  25

raster line 12 - screen char 1 line 4                                   33

raster line 13 - screen char 1 line 5                                     41

raster line 14,- screen char 1 line 6                                       49

raster line 15 - screen char 1 line 7                                        57

raster line 16 - screen char 2 line 0                              2 

raster line 17 - screen char 2 line 1                               10

raster line 18 - screen char 2 line 2                                  18

raster line 19,- screen char 2 line 3                                     26

etc

 

The above is not the layout as it crosses the 1/3 boundaries

 

 

 

the raster refresh can/does/will be overtaken by  the LDIR.. This is basic in the principle of screen updates. 

Edited by Norman Sword
Link to comment
Share on other sites

I have noticed the separate issue whereby the screen's display file is updated slightly before the attribute file.  This is most noticeable in rooms where the background's INK and PAPER settings are different, and fast-moving elements traverse the screen. e.g. arrows in a room with a rope, where it manifests itself in the arrows flickering in a different colour to the usual white (in that example, the arrows would be seen for the briefest of moments in the same colour as the rope).

 

I have thought some more about the above, and carried out some investigations.  It seems to be a related phenomenon to the one which Norman has identified.

 

PREAMBLE: For my investigations, I inserted several arrows of the same 'Guardian Class' into a room, in which I had assigned differing values for the Air's INK and PAPER settings.  (Red INK on Cyan PAPER - both of which contrast well with each other, and also with the White colour of the arrows.)

 

The effect described above was clearly visible, whereby an arrow's graphic bytes are drawn to the next cell along the arrow's path, in advance of that cell's INK setting being updated in the attribute file.  This causes the arrow to flicker for the briefest of moments in red (the background's INK setting).

 

Furthermore, the effect was much more pronounced for an arrow that fired along the top of the screen, than for one which traversed along the bottom of the screen.  For two arrows which occupy the same cell-row, but different pixel-rows, the effect was more pronounced in the arrow that passed along the upper pixel-row.  But within the same vertical half of the screen, an arrow in the top pixel-row of a cell-row at the bottom of the screen (row 15) displayed the effect more prominently than an arrow in the bottom pixel-row of a cell-row higher up the screen (row 8).

 

This pattern is not surprising, bearing in mind the previous discussion about how the screen is drawn in JSW.  The prominence of the effect is proportionate to the time delay between the arrow being drawn, and the colour-attribute of its host cell being updated.

 

(With Norman's alternative screen-drawing routine in place, I suspect that the prominence of the effect would follow a simple linear progression down the screen, although I haven't checked that.)

 

******

 

This gives rise to the possibility of coming up with a further rearrangement of the code to diminish this effect, building on Norman's methodology.  Could Norman's new code be modified so that the attributes along each cell-row are updated from the attribute buffer immediately after all eight pixel-rows for that cell-row have been copied from the display buffer?

 

i.e. Pixel-rows 0-7 of cell-row 0 are drawn, and then the updated attributes are inserted across cell-row 0, before cell-row 1 is considered?

 

EDIT: If such an approach were to be implemented and if you wanted to use the unused 'Screen Flash' routine [a relic from Manic Miner, where it is enacted once an extra life is gained] within a project, then the Screen Flash part would need to be reinserted in the Main Loop (to overwrite the PAPER colour of every screen cell in the secondary attribute buffer) before any of the screen (graphic bytes or attribute bytes) is updated during the Main Loop.

 

******

 

Incidentally, I gave the example of arrows because the effect (which we should probably think of a suitable name for) is most noticeable, since arrows are so fast-moving.  But you can also observe it with guardians (especially fast-moving vertical ones) in rooms with non matching INK and PAPER settings for the background.  See the Cyan Security Guard in the blue rooftop room 'I'm sure I've seen this before' - the top of the guard's helmet or its feet, at the point when those elements cross into a new cell-row - or the horizontal Green Bird in same room - watch its beak as it flies into a new cell-column.

 

You can also observe the effect quite prominently when Willy falls through 'Entrance to Hades' (where the background has Green INK on Yellow PAPER).  It isn't generally as noticeable with Willy whilst he is walking, because his sprite is quite narrow, and so his colour-attribute actually moves forward in advance of the inked-in part of his sprite.  (That's why he can perch on the edge of a block when it appears there is nothing underneath him supporting him.)  But in 'The Nightmare Room', where Willy is in Flying Pig mode, his sprite is quite a bit wider than usual, so if you POKE the Air INK in there from the default Black to Magenta, then as it walks around you can sometimes catch the pig's snout turning pink (appropriately enough!)

Edited by IRF
Link to comment
Share on other sites

And with the above comment, I will no longer elaborate. because your statement is so very wrong.  

 

starting at the top the screen updates -- Physical scan line update

 

 

raster line 00 - screen char 0 line 0  an ldir will update 0

raster line 01 - screen char 0 line 1                                8

raster line 02 - screen char 0 line 2                                   16

raster line 03 - screen char 0 line 3                                     24

raster line 04,- screen char 0 line 4                                      32

raster line 05 - screen char 0 line 5                                        40

raster line 06 - screen char 0 line 6                                          48

raster line 07 - screen char 0 line 7                                           56

raster line 08 - screen char 1 line 0                              1

raster line 09,- screen char 1 line 1                                9

raster line 10 - screen char 1 line 2                                 17

raster line 11 - screen char 1 line 3                                  25

raster line 12 - screen char 1 line 4                                   33

raster line 13 - screen char 1 line 5                                     41

raster line 14,- screen char 1 line 6                                       49

raster line 15 - screen char 1 line 7                                        57

raster line 16 - screen char 2 line 0                              2 

raster line 17 - screen char 2 line 1                               10

raster line 18 - screen char 2 line 2                                  18

raster line 19,- screen char 2 line 3                                     26

etc

 

The above is not the layout as it crosses the 1/3 boundaries

 

 

 

the raster refresh can/does/will be overtaken by  the LDIR.. This is basic in the principle of screen updates. 

 

I appreciate the order in which the screen lines are updated (thanks to explanations given in the past on this very forum by Dr Andrew Broad).

 

I think where I failed was in my interpretation of what your previous diagram (the one with the red and black squares) was trying to represent.  And possibly in my lack of knowledge of computer terminology.  (I thought 'raster' was something to do with Bob Marley before I Googled it!  :D )

 

EDIT: I think I've grasped what your diagram is showing now (having looked at the diagram on a bigger screen - I was on my tablet earlier).  Please excuse my general ignorance!  I'm just a humble EHO, dabbling in a bit of coding in my spare time!

Edited by IRF
Link to comment
Share on other sites

This gives rise to the possibility of coming up with a further rearrangement of the code to diminish this effect, building on Norman's methodology.  Could Norman's new code be modified so that the attributes along each cell-row are updated from the attribute buffer immediately after all eight pixel-rows for that cell-row have been copied from the display buffer?

 

i.e. Pixel-rows 0-7 of cell-row 0 are drawn, and then the updated attributes are inserted across cell-row 0, before cell-row 1 is considered?

 

Having thought a bit about the above, perhaps another check could be inserted just prior to the JR NZ, LOOP command:

 

Copy L into A, apply an AND #0F, and if that sets the Zero Flag, then it's time to update the attributes for the cell-row under consideration.  (N.B. the code to achieve that should be bookended by PUSH HL and then POP HL, to preserve the pointer to the lookup table at #8200).

 

I'm not sure whether it would fit into those spare 16 bytes which Norman identified?  (Which could be 18 bytes if you didn't need the JR 35366 / #8A26 at the end of the code which makes Willy run double-quick during the toilet dash.)

 

EDIT: Actually, there would be another 11 bytes to play with (so 29 in all), since the function of the code at #8A26-#8A30 would have been performed instead by the new intervention.

 

So it should be doable within the available space in the Main Loop - I might have a go at it when I get a moment.  It would kill two birds with one stone - eliminate the 'Jagged Finger Effect' AND the 'Delayed Attribute Update Effect' (I'm still open to suggestions on the name for that one!)

Edited by IRF
Link to comment
Share on other sites

One other point which I forgot to mention last night: both the Jagged Finger and Delayed Attribute Effects can be clearly seen if you are playing on an emulator and you pause the game using the emulator's pause function. That way, you can capture a 'moment in time'.

 

However, if you pause 'in-game' by using one of JSW's defined pause keys (A-G), then you won't capture either effect, because the Main Loop only checks for pause keys being pressed after it has finished copying to both the Display File and the Attribute File.

Link to comment
Share on other sites

Something else I've just thought of: the three images that Norman attached in the third post of this thread, were taken in the First Landing where the Air's INK and PAPER are both set to black. I believe that both phenomena would have been visible if the Air INK had been set to another colour.

(N.B. It might be worth pointing out that the first of those three images was captured at the point when Willy is passing from the top third to the middle third of the screen. i.e. from the top half of the playing area to the bottom half).

 

 

EDIT: I've just captured a screenshot, using my emulator's pause function.  Please see the attached image, and in particular the Monk guardian.

 

Hopefully you can see that I have replicated what Norman's previous images showed, in terms of the 'Jagger Finger' effect. i.e. the top part of the Monk's head and the upper part of his body have been moved on to the next animation frame, but his jaw and his legs haven't yet been updated (as per the previous discussion).  Thus capturing a moment midway through the implementation of the LDIR loop which copies the graphic bytes from the Display Buffer to the actual screen.

 

But because I have changed the Air INK to Red in First Landing, you can also see that the foremost pixels of the Monk (the tip of his long nose and the front of his belly) are drawn in Red INK.  That's because he has just crossed a cell-column boundary, and the screen attributes haven't yet been updated to ensure that the cells into which the Monk is advancing is rendered with his Yellow INK.

post-63-0-34882300-1491208643_thumb.png

Edited by IRF
Link to comment
Share on other sites

Please find attached a snapshot (Z80) file and a screenshot, taken in the Swimming Pool where I've set the background to Cyan PAPER and Red INK, and added eight arrows (of the same class) at various heights on the screen.

 

If you open up the snapshot file, you can watch the way in which the y-coordinate of an arrow determines how prominent the 'Delayed Attribute Update' effect is.  There's a general pattern of the higher arrows' graphic bytes being more visibly 'detached' from their attributes than is the case for the lower arrows, but it isn't a linear effect (see previous discussion).

 

In the screenshot, you can also - in the topmost arrow - observe the 'Jagged Finger' effect.  The top two pixel-rows of the arrow have moved on into the next cell (which still has Red INK), whilst the bottom pixel-row of that arrow hasn't been updated yet and has been left behind in the previous column (where it is still rendered in White INK).

 

This is a strong indication that the two effects are linked, and I intend to come up with a comprehensive fix for both, using Norman's code as a starting point (and thank you for that code Norman, which not only brought attention to the 'Jagged Finger' phenomenon that I wasn't previously aware of, but also provides the basis for a fix for the 'Delayed Attribute' phenomenon which I was previously aware of!)

 

EDIT: It won't be possible to fix the 'Delayed Attribute Update' phenomenon entirely, but if you watch the bottom arrow in flight in the attached Z80 snapshot file, that one shows the effect least prominiently, because the arrow occupies one of the last pixel-rows to be drawn to the screen, and so the time delay before the associated attributes for that cell-row are updated is minimised.  That should be possible to achieve for all cell-rows, by modifying Norman's approach as I suggested in post number 17 on this thread.  I will try to do that later this week (unless someone beats me to it!)  :ph34r:

Jagged Finger & Delayed Attributes.z80

post-63-0-21514900-1491209915_thumb.png

Edited by IRF
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...

Important Information

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