Jump to content


Photo

[File] JSW jagged finger effect (demo)


  • Please log in to reply
49 replies to this topic

#21 IRF

IRF

    Advanced Member

  • Contributor
  • 4,309 posts

Posted 03 April 2017 - 10:56 AM

Another thing that I meant to point out last night, but forgot: the only moving elements that aren’t prone to the ‘Delayed Attribute Effect’ are Ropes, because they don’t update the colour-attribute of the cells through which they pass (they are always rendered in the pre-defined INK colour of their host cells).

 

******

 

Anyway, here’s one more example of the ‘Delayed Attribute Update’ effect – please see the attached screenshot, taken just after Willy has dropped into ‘Entrance to Hades’.  (This one didn’t require any messing around with the room’s Air attributes to illustrate the point – it is a very prominent effect in the original JSW, based on the original settings for this room.)

 

Once the graphic bytes representing Willy’s legs have been drawn to the screen file - at a point in time when he has just fallen past a cell-row boundary - there is a relatively long delay before his legs are rendered in the customary White.  That is because the program has to draw the rest of the graphic bytes for the upper half of the playing area, and then the graphic bytes for the entire lower half of the playing area, before the Main Loop starts the task of refreshing the attribute file row-by-row.

 

The cumulative effect of that long delay, and the visually-striking contrast between the three colours involved (Green/Yellow/White), means that the ‘Green Legs’ effect is very pronounced.  Although I think it becomes less pronounced, the further Willy falls down the screen.

 

(Actually, typing this out has got me thinking that perhaps the Green INK for the Air cells in ‘Entrance to Hades’ was deliberately chosen, in order to prevent part of the ‘Demon Head’ guardian from briefly ‘disappearing’ as it moves up and down across cell-row boundaries?  That is a less-noticeable element of the ‘Delayed Attribute Effect’ in rooms where the Air INK and PAPER settings are the same – the leading pixels are rendered ‘invisibly’ for a brief moment as an entity advances into the next cell, before the attributes are refreshed - perhaps this is more noticeable on a non-Black screen?)

Attached Thumbnails

  • Hades.png

Edited by IRF, 03 April 2017 - 12:44 PM.


#22 IRF

IRF

    Advanced Member

  • Contributor
  • 4,309 posts

Posted 03 April 2017 - 05:06 PM

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!)

 

I think the above can be done in 26 29 bytes. That should nicely leave exactly three spare bytes, which would be best left in situ prior to the start of Norman's code (to allow a CALL to elsewhere to reinstate the Screen Flash routine - otherwise the Screen Flash effect wouldn't be able to influence the screen's PAPER colour - or alternatively to add a CALL to the Main Loop Patch Vector sub-routine).

I haven't tried this out yet, but here's my first stab on the basis of studying the code (I prefer to work in hexadecimal):

org #89F5

89F5 Three spare bytes

Then First comes most of Norman's code, highlighted in bold:

89F5   LD HL, #8200
89F8   LD E, (HL)       Start of LOOP, each iteration of which copies 32 graphic bytes across a single pixel-row (raster line) of the                                                           screen
89F9   INC L
89FA   PUSH HL
89FB   LD D, (HL)
89FC   LD L, E
89FD   LD H, D
89FE   RES 5, D
8A00   LD BC, #0020
8A03   LDIR
8A05   POP HL
8A06   INC L

8A07   LD A, L
8A08   AND #0F           Check if L is now exactly divisible by #10
8A0A   JR NZ, LOOP   If not, then we haven't yet drawn all eight pixel-rows of the current character-row to the screen, so jump back to                                                                  LOOP to draw the next pixel-row
8A0C   PUSH HL

8A0D   LD A, L

8A0E   SUB A, #10

8A10   LD L, A

8A11   LD H, #5C

8A12   OR A                 Reset the Carry Flag in preparation for the next command (N.B. This may not be necessary?)

8A13   SLA L                This sets the Carry Flag if (and only if) we are now considering a character-row in the bottom half of the playing area
8A15   LD E, L
8A16   JR NC, #01       This jump only occurs if we are in the bottom half of the playing area
8A18   INC H                Point H at the bottom half of the playing area; HL now points at the left-hand end of the appropriate character-row in                                                          the attribute buffer
8A19   LD D, H
8A1A   RES 2, D           DE now points at the left-hand end of the appropriate character-row in the screen's attribute file
8A1C   LD BC, #0020   There are 32 bytes to copy
8A1F   LDIR                 Copy the attributes along the current character-row
8A21   POP HL
8A22   LD A, L
8A23   OR A                 Check if we have finished copying the whole of the playing area (i.e. the graphic bytes and attributes for all sixteen                                                              character-rows)

8A24   JR NZ, LOOP   If not, then jump back to LOOP to consider the next character-row This command marks the end of Norman's code

That would then be followed by the original code which makes Willy run at double-speed during the Toilet Dash (which fortuitously fits exactly into the space where the original attribute-copying code was located):

8A26   LD A, (#85DF)
8A29   AND #02
8A2B   RRCA
8A2C   LD HL, #85D2
8A2F   OR (HL)
8A30   LD A, (HL)

Finally, the original Main Loop routine resumes at #8A31 (starting with the code which prints the current time, then the number of items collected, etc).

Let's just hope it works!! :P


Edited by IRF, 04 April 2017 - 12:18 AM.


#23 jetsetdanny

jetsetdanny

    Advanced Member

  • Contributor
  • 2,169 posts

Posted 03 April 2017 - 08:27 PM

I'm unable to follow the details of this, but your effort looks impressive, Ian! It's interesting how Norman Sword will react to it  :) .


  • IRF likes this

#24 IRF

IRF

    Advanced Member

  • Contributor
  • 4,309 posts

Posted 03 April 2017 - 08:30 PM

I just tried it out and it crashed the emulator, with random coloured squares everywhere!! Either my idea is completely off, or I've made a tiny mistake that may take ages to track down - or possibly some scenario in between!!

EDIT: At first glance, I think it's something to do with the way in which I've incorrectly used the PUSH and POP commands, causing a stack overload.

UPDATE: Yes, that was the problem, a PUSH in the wrong place. I've swapped the code around slightly and it works fine now. I'll edit the previous post accordingly (DONE).

Please see the latest test file attached to this post. The 'Delayed Attribute Update' effect is still present, but it is much less prominent than it was before.

EDIT: I've also reattached the earlier test file here (renamed slightly for clarity), which displayed the bugs prominently and has the same starting position (the Swimming Pool, with Red Air INK, Cyan Air PAPER and eight arrows at various heights), so that the 'Before' and 'After' can be compared and contrasted.

 

FURTHER UPDATE: I've removed the files temporarily, as I want to work a bit more on the code to increase its effectiveness and efficiency.


Edited by IRF, 04 April 2017 - 09:40 AM.


#25 IRF

IRF

    Advanced Member

  • Contributor
  • 4,309 posts

Posted 03 April 2017 - 08:53 PM

Please see the latest test file, attached here.  The 'Delayed Attribute Update' effect is still present, but less prominent than it was before, I feel.

 

If you compare the effect in the Swimming Pool between the two snapshot files (the earlier one and the 'fixed' one), there is definitely less of a pronounced 'leading edge' to Willy as he walks/jumps/falls across cell boundaries.

 

The effect is still quite prominent for the two arrows at the top of the screen (UPDATE: not any more!), but less so for the lower arrows.  Since arrows move horizontally one cell at a time, I would expect the effect's prominence to be most acute for arrows.

 

However, I would have expected the delay between the arrow being pixel-drawn and attribute-rendered to be greater for the first arrow from the top (which occupies the second pixel-row of the top cell-row), compared with the delay for the second arrow down (which occupies the seventh pixel-row of the top cell-row).  So I am a bit surprised that the effect seems to have roughly equal prominence for those top two arrows(?)  UPDATE: I had made a small error when writing my patch, which I have now fixed.

 

Still, my latest code changes seem to have improved the situation for most UPDATE: ALL of the arrows in the test file.  :)

 

EDIT: And the 'Green Legs' effect when Willy falls into 'Entrance to Hades' is greatly reduced in the latest file (although you'll have to navigate over there yourself to see that).


Edited by IRF, 04 April 2017 - 12:20 AM.


#26 IRF

IRF

    Advanced Member

  • Contributor
  • 4,309 posts

Posted 03 April 2017 - 11:19 PM

I don't think I've quite got the attribute part of the loop working properly.  I think each cell-row is having its attributes drawn before the graphic bytes for that cell-row, but the first cell-row isn't getting coloured in until the very end of the loop (after the rest of the screen has been drawn).  That's why the top two arrows haven't been 'fixed' to the same extent as the others.  A further tweak is required...

 

EDIT: I''ve cracked it!  In the end I needed to use the three spare bytes which I thought I had left over, as well as an OR A which I had previously indicated would reset the Carry Flag, but which on reflection wasn't necessary for the patch to function properly.  I think the improvement is now very noticeable from the 'Before' to the 'After' scenario.  B)

 

I've swapped the file which I'd previously uploaded for the 'properly fixed' version (I don't think anyone had downloaded it before I swapped it?), and I've also updated/corrected the disassembly which I provided in post no. 22 of this thread.

 

Thanks again to Norman for his part in this fix - I was able to 'piggy-back' onto his code, in order to implement my more comprehensive patch for both the 'Jagged Finger' AND the 'Delayed Attribute Update' bugs.


Edited by IRF, 04 April 2017 - 12:25 AM.


#27 IRF

IRF

    Advanced Member

  • Contributor
  • 4,309 posts

Posted 04 April 2017 - 07:07 AM

I'm unable to follow the details of this, but your effort looks impressive, Ian! It's interesting how Norman Sword will react to it  :) .


Hopefully you won't need to be able to follow the details to appreciate the qualitative difference between the Before and After scenarios?

 

The improvement in terms of the 'Delayed Attributes' is easily seen in the starting room (Swimming Pool), and it you wander left and then up the long staircase as far as Conservatory Roof, you can hopefully see the improvement in terms of the 'Jagged Finger' - watch Willy's sprite as he goes up the ramp (particularly as he passes from bottom to top half of the playing area), and the horizontal guardians in Conservatory Roof.

 

EDIT: Other places to watch/compare/contrast:

 

- watch Willy jump and fall in Front Door (highly noticeable improvement in there because the Air INK is Black against Cyan PAPER, both of which contrast well with Willy's customary White);

- drop him down into Entrance to Hades;

- observe the fast-moving vertical guardians in 'I'm sure I've seen this before', and 'Rescue Esmerelda'; also the beak of the horizontal Bird in both rooms, and the Arrows in the former.


Edited by IRF, 04 April 2017 - 08:30 AM.


#28 jetsetdanny

jetsetdanny

    Advanced Member

  • Contributor
  • 2,169 posts

Posted 04 April 2017 - 07:23 AM

Congratulations, Ian! So I was right in believing your effort was impressive ;).

I can't download the the files right now, I'll have a look at them later :).

#29 IRF

IRF

    Advanced Member

  • Contributor
  • 4,309 posts

Posted 04 April 2017 - 07:28 AM

Maybe it ended up impressive once I'd resolved a couple of silly mistakes! I'm still not convinced it's as byte-efficient as it could be though?


Edited by IRF, 04 April 2017 - 08:30 AM.


#30 IRF

IRF

    Advanced Member

  • Contributor
  • 4,309 posts

Posted 04 April 2017 - 08:20 AM

I don't think I've quite got the attribute part of the loop working properly.  I think each cell-row is having its attributes drawn before the graphic bytes for that cell-row, but the first cell-row isn't getting coloured in until the very end of the loop (after the rest of the screen has been drawn).  That's why the top two arrows haven't been 'fixed' to the same extent as the others.  A further tweak is required...

 

That's exactly what was happening during my previous 'semi-successful' attempt to fix the 'Delayed Attributes' bug.  In fact, some of the arrows actually had red 'trailing edges' instead of red 'leading edges', particularly where an arrow occupied a pixel-row towards the bottom of its cell-row - the white attribute was being advanced ahead of the arrow's graphical bytes.  A kind of 'Premature Attribute Update' effect, so to speak.

 

I suppose the optimum fix would be, for each cell-row, to draw the top four pixel-rows, copy the attributes for that cell-row, and then draw the bottom four pixel-rows.  That would balance out/minimise the 'delays' between any particular graphic byte and its associated attribute being distributed across the whole screen.  It might further complicate the code though!






0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users