Jump to content


IRF

Member Since 23 Aug 2015
Offline Last Active May 29 2020 08:41 PM
-----

#11979 Playing around.

Posted by IRF on 21 May 2020 - 07:58 AM

I did download the file last week and played all the introductory screens and up until the end of the Central Cavern, but didn't get chance to post yet due to 'real life' work pressures.

Anyway, what I saw was excellent, and I'm intrigued by the one cavern in the first post's screenshots which I didn't manage to reach yet - the kind of Spiral Staircase affair.

Thanks for posting this project, NS, and for the detailed description of the collision logic as well. I have a question:

I notice that not all of the master pixel buffer is copied to the working pixel buffer during each pass through the main loop - instead, only those elements of the screen that have had their pixels changed since the previous pass are updated. I presume this is primarily to speed up the game.

My question is: could the same logic not be applied to the attributes (admittedly for a more marginal improvement in speed)? i.e. Instead of copying all of the master attribute buffer to the working attribute buffer during each loop-pass, just update those parts of the screen where Willy or a guardian's attributes have changed things since the previous pass?


#11964 Pokes for Fixing the Cell Graphics Bug in JSW

Posted by IRF on 10 May 2020 - 01:59 PM

I'd forgotten about The Final Barrier, it's actually a good example of what I was talking about. Some of the cells in the upper half of the cavern are drawn using data that is supposed to represent Willy's start position, movement flags, fall counter, etc for the top seven pixel-rows, and the conveyor direction byte for the bottom pixel-row of the cell.

In other cases, the Cell Graphics Bug causes 'classic' corruption of cells in the upper half of The Final Barrier - like you see in several rooms in JSW - where the defined attribute value inadvertently matches with a graphical byte value (one of the defined cell bitmaps).

But of course, none of this is ever seen in The Final Barrier - it happens 'behind the scenes' in the pixel-buffer, but is then overwritten by the graphic from the title screen before gameplay commences.

 


If the CPIR steps past the last known graphic, and onto stair data etc. Then it indicates that the loop should be shortened to stop on the last known graphic,

 

I don't think the search will ever go beyond the address #8068 that immediately follows on after the end of the cell graphics table, where HL is left pointing if the CPIR loop comes to an end without a match.  So there's no danger of a scan through the whole of memory (unless a patch has been applied that is based on an unbounded search, as per Skoolkid's or J.G.Harston's methods).

 

But I agree that it would be good to reduce the length of the CPIR loop by 9 (i.e. reduce the value assigned to BC by 09, prior to the CPIR being executed), so that the 'default' graphic for a 'none of the above' cell type can be defined and controlled, rather than the program picking up unassociated data for the purpose.

 

That would also have the benefit that you would be able to have different coloured switches within a single Kong cavern.  (The switch graphic definition uses the last slot in the table of cell graphics, and collision-detection between Willy and a switch isn't attribute-based.)


  • zub likes this


#11962 Pokes for Fixing the Cell Graphics Bug in JSW

Posted by IRF on 10 May 2020 - 12:05 PM

Incidentally, you can see the effect of a bounded search in action in Manic Miner (albeit that the data picked up falls beyond the intended range of the bounded search, if you insert* an attribute value into a cavern layout which doesn't match with any of the attribute or graphical bytes in the cavern's cell definitions.

(*e.g. Manually via the Hex Editor, not in JSWED's GUI.)

What happens is that when the CPIR loop comes to an end having failed to find a match after searching through the range of addresses #8020-#8067, HL is left pointing at the next address in the cavern buffer: #8068. The next eight bytes - #8068-#806E (various parameters which define Willy's state upon entry to the cavern) and #806F (which defines the conveyor direction for the cavern) are then interpreted as graphical bytes to draw the pixel pattern of the errant cell.


#11959 Pokes for Fixing the Cell Graphics Bug in JSW

Posted by IRF on 10 May 2020 - 10:54 AM

For reference, Norman Sword's fix for the CGB (as part of a more fundamental rewrite/optimisation of the Room Expansion routine) is listed here:

http://jswmm.co.uk/t...or-jsw/?p=11166

It involves a bounded search.

(P.S. My tablet attempted to autocorrect that to "a bouncer search", which sounds like a plotline from Neighbours during the 1980's.)
  • zub likes this


#11957 Pokes for Fixing the Cell Graphics Bug in JSW

Posted by IRF on 09 May 2020 - 08:07 PM

Also J.G.Harston's 'JSW Extensions' page was updated in 2017, which seems to be when he added the CGB fix.

So Stuart (Zub)'s fix on this forum seems to have been the first to be 'published' (unless you count Skoolkid's Github entry, prior to it being transposed to a disassembly update).


#11956 Pokes for Fixing the Cell Graphics Bug in JSW

Posted by IRF on 09 May 2020 - 07:57 PM

Okay, so it turns out that SkoolKid committed his fix in the SkoolKit disassembly about a month before I posted my fix! I’m not sure this would have been published immediately, though, so it’s possible that I couldn’t be blamed for missing it at the time (assuming that it had been pushed at that point). :-)


The update on Github wasn't transferred to a disassembly update until the following January:
https://skoolkid.git...g.html#20160117


#11951 Portal Change Idea

Posted by IRF on 09 May 2020 - 03:38 PM

Did you mean if he uses the Portal to hide ? :) In theory he could be walking left with jump enabled under the earth cell so should jump the gap and not touch the Portal.

As otherwise he'd only enter it when it was flashing at cavern completion ? :unsure:


Can't do that in Manic Miner. If you try to jump over the portal when traversing at the lower level, then Willy doesn't land on the far side, but drops into the portal, and you have to jump back out again. (Except with your modification, he would die!)

You could perform such a jump in JSW, but only when jumping from right to left, not vice versa.


#11946 Portal Change Idea

Posted by IRF on 08 May 2020 - 08:24 PM

I think the check for whether Willy has entered a portal comes before the test for a standonable (or jumpoffable) platform underneath Willy.

Otherwise, Willy wouldn't be able to survive falling into the portal in Return of Kong...


#11935 Title-screen tunes for Andrew Broad's JSW->MM and MM->JSW convers...

Posted by IRF on 30 April 2020 - 08:40 AM

For 'compare and contrast' purposes, Dr Broad's original versions of the JSW->MM and MM->JSW conversions are available within this Zip folder:

https://jswcentral.o...party_willy.zip


#11912 JSW As Manufacturer (probably) intended .. kind of...

Posted by IRF on 23 April 2020 - 09:42 AM

UPDATE: It's just occurred to me that if you were to implement the above, and then instigate the toilet run in The Nightmare Room, the pig sprite would run with its little legs without flapping its wings!

If you load up the 'Proper Toilet Run' test file which I attached four posts above this one, start the game & navigate to The Nightmare Room (preferably the left-hand side of that room to see the effect in full), and then apply Mickey's POKE 34271,2 then you can see what I mean.

From that position, you should be able to complete the game too (possibly with some judicious use of the 'P' key to dodge the Nightmare Room guardians), as once you leave that room and revert back to the Willy sprite, there's just a straight run up the full length of the ramp in First Landing and on to The Bathroom!

 

Further to the above, I've made a short recording (see attached) to demonstrate a 'proper toilet run' incorporating The Nightmare Room.  Look at his little trotters go!

 

As it turned out, no use of the 'P' key bug to pause* Willy in order to avoid guardians was actually necessary - though it was a close-run thing with the red Maria!  That's just as well, because in the test file that I previously prepared to demonstrate the alternative toilet run - upon which I based the recording - I had 'fixed' the 'P' key bug so it no longer functions to pause the toilet run.  (Incidentally, I also fixed the 'jagged finger' visual flaw identified by Norman Sword, since it was particularly prominent during the toilet dash what with the sprite moving so fast.)

 

In the recording I also started off the toilet run in The Banyan Tree, to extend the run as much as possible, and as an added bonus I hit the Jump and Right keys just before applying the POKE to commence the sequence, so that it starts off with a nice 'Superjump' over the yellow saw guardian.  B)

 

 

(* 'P' for 'Pause'? Hmmm..... maybe it was a feature not a bug all along!?)

Attached Files




#11911 JSW As Manufacturer (probably) intended .. kind of...

Posted by IRF on 23 April 2020 - 08:36 AM

I believe the way to get [Willy to run to the toilet properly] would be to relocate #8A00-#8A0A to sit in between the commands at #89D6 and #89D9 in the Main Loop. i.e. after Willy has been moved, but before he is drawn.


UPDATE: It's just occurred to me that if you were to implement the above, and then instigate the toilet run in The Nightmare Room, the pig sprite would run with its little legs without flapping its wings!

If you load up the 'Proper Toilet Run' test file which I attached four posts above this one, start the game & navigate to The Nightmare Room (preferably the left-hand side of that room to see the effect in full), and then apply Mickey's POKE 34271,2 then you can see what I mean.

From that position, you should be able to complete the game too (possibly with some judicious use of the 'P' key to dodge the Nightmare Room guardians), as once you leave that room and revert back to the Willy sprite, there's just a straight run up the full length of the ramp in First Landing and on to The Bathroom!




#11910 Title-screen tunes for Andrew Broad's JSW->MM and MM->JSW convers...

Posted by IRF on 21 April 2020 - 12:46 PM


#40 and #80 [pair of pitch values]

 

So the note that is played has a pitch of #80, corresponding to the lower of the two pitches represented by the note data (i.e. the numerically higher of the two pitch values, since a smaller number yields a higher pitch).

 

 

P.S. If you wanted a pure tone of #40, then you would need to use a pair of pitch values #40 and #20.  (I don't think it would matter in which order the two values are stored in the data, as long as one is half the value of t'other.)

 

In terms of Andrew's original JSW->MM conversion, the upshot is that the pure tone version of 'Moonlight Sonata' plays the lower pitched half of each note (as if the doubling of pitch that you get in the JSW engine was applied immediately, instead of halfway through each note).  Rather than only playing the higher pitched half of each note (which is what you get if you just NOP out the RL E command from #96BC in the JSW game engine).




#11909 Title-screen tunes for Andrew Broad's JSW->MM and MM->JSW convers...

Posted by IRF on 21 April 2020 - 12:32 PM


Andrew's JSW->MM conversion plays a pure tone version of JSW's title tune 'Moonlight Sonata'.  It achieves this by making each pair of notes consist of one value (x) followed by a note with exactly double the pitch value (2x).  This seems to turn off** the 'dischordancy' feature of the tune that you normally hear. i.e. when 'The Blue Danube' is playing in the original MM.

 

[** Incidentally, looking at the Manic Miner title tune-playing routine, I can see why that would have the effect of generating pure tones, although I can't recall this ever being discussed - either here or on the Yahoo! Group - as an available technique to employ when creating MM title-screen tunes?]

 

Explanation for the above: say you had a set of three pitch values for a MM title tune note of #32 [the duration], #40 and #80 [pair of pitch values].  Those values are assigned to the C, D and E registers respectively.  The inner note playing loop decrements D and E once for each pass through the loop, and when either of those reaches zero then an XOR #18 command is executed - meaning that the speaker state will be toggled at the start of the next pass through the inner loop - before D or E is reset back to its original value for this note.  (The inner loop is controlled by the B register, which is set to #00 at the start, and that effectively means #100 iterations since B is decremented to #FF before a check for a zero value is made.  The outer loop decrements C to repeat all of the above C times, meaning that the duration of the note is C x #100 iterations of the inner loop [#3200 iterations in the above example].)

 

But if you have two pitch values which are exactly separated by a factor of 2, as in the above example, then the following happens:

 

On the #40th iteration of the inner loop, D has reached zero so an XOR #18 activates the speaker.

On the #80th iteration of the inner loop, D and E both reach zero so XOR #18 is executes twice; those operations cancel each other out*, so the speaker is not activated.

On the #C0th iteration, D has reached zero again so XOR #18 activates the speaker.

On the #100th iteration, D and E both reach zero so XOR #18 is executes twice; those operations cancel each other out, so the speaker is not activated.  B has now reached zero which brings an end to the inner loop for now.

 

Then C is decremented and the whole of the above is repeated, until C reaches zero, bringing the outer loop to an end.  (Then there is a check for whether the ENTER key is being pressed to start the game - if not, then the next note will be played [next set of three note definition bytes will be considered].)

 

If you look at the above pattern, you can see that - except for in the very first instance at the start of the first outer loop - the speaker diaphragm is only actually activated once every #80 passes through the inner loop.  So the note that is played has a pitch of #80, corresponding to the lower of the two pitches represented by the note data (i.e. the numerically higher of the two pitch values, since a smaller number yields a higher pitch and vice versa).

 

 

(* Applying XOR #18 to the A register, and then applying another XOR #18 to A, is effectively the same as applying XOR #00, which has no effect on the value in the Accumulator.)




#11878 Manic Miner in 48k with 40 rooms

Posted by IRF on 14 April 2020 - 12:24 PM

The routine is still playing a linear keyboard. The only changes are the compression of the data, the redrawing of the keyboard, the full key light up and removal of the silent keyboard light ups.

Long time since I looked at the routine. A quick glance does indicate I could change to a key reference lookup quite easily. E.g. permit each note to designate a value for its true key position. Not something I would bother to do.

 

If there was space in memory for it, then the following code could be adapted for the purpose. (It's something which I came up with for Daniel Gromann's recent 48K conversion of Fabian Alvarez Lopez's 128K JSW game 'Madam Blavskja's Carnival Macabre'.)

 

At #C040 - #C05F, a lookup table of 'Pitch versus attributes' is stored. The first half of that table (#C040 - #C04F) contains pitch values used by the notes of the title-screen tune. The second half of the table (#C050 - #C05F) contains attribute values corresponding with each note, which will be used as the INK colour for the game's title printed at the top of the title screen.

 

The following subroutine is called from the 'Play the title tune' routine, immediately after the check for a #FF Terminator byte but before the note is actually played.  Going into the subroutine, HL points at the pitch value of the note which is about to be played.

 

LD A,(HL)          pick up the pitch value of the note which is about to be played, and store it in A
PUSH HL          save HL (which points at the current note) onto the stack
LD HL,#C040    point HL at the start of the lookup table at #C040
LD BC,#0010    we will search through #10 pairs of entries (16 in decimal)
CPIR                 do the search – the CPIR loop stops when it reaches a value from the first half of the table which matches the pitch of the current note
LD BC,#000F    then we need to consult the second half of the table to find the corresponding attribute value
ADD HL,BC      adding #0F (15 in decimal) because the last iteration of the CPIR loop incremented HL once more after a match had been found
LD A,(HL)         pick up the attribute value to be used to colour the game title, and store it in A
LD HL,#5800    point HL at the first character of the title screen to be coloured
LD (HL),A         colour it using the attribute value picked up from the table

LD DE,#5801   point DE at the second byte to be modified
LD BC,#007F   128 bytes will be modified
LDIR                 modify them

POP HL            restore the pitch value of the note which is about to be played to HL

RET                  return back to the main 'Play the title-screen/Came Completed screen tune' routine to play the note

 

In this case, the second half of the table wouldn't contain different attribute values for each note (rendering the same element of the screen in different colours according to the note being played), but instead would need to hold values for the low byte of the attribute address corresponding to the appropriate piano key for each note played (which would thus be coloured in with a fixed attribute value, and then reverted back to white after the note has finished being played).

 

Of course the table could be stored anywhere convenient in memory; it wouldn't have to be at #C040-5F.  And the size of the table should be adjusted as appropriate to accommodate the number of different pitch values in the tune (with BC assigned a value equal to the number of different pitch values in the first instance, and then the number of different pitch values minus one in the second instance that BC is defined).




#11872 Manic Miner in 48k with 40 rooms

Posted by IRF on 13 April 2020 - 11:11 AM

Norman, am I right in thinking that the piano keys on the title screen now light up 'correctly'? i.e. they accurately represent the notes which are being played at the time, so that if you were to reproduce the visual pattern on a real piano then you would end up playing the tune faithfully?

 

And assuming that is the case, then I have a follow-up query: are the appropriate attribute addresses on the screen worked out in your rewritten version of the title-tune routine, using a logarithmic calculation method (as opposed to the linear method in the original MM, which leads to incorrect keys being highlighted)?

 

Or alternatively, does your rewritten routine use a look-up table to determine which piano keys (i.e. which attribute addresses on the screen) to highlight, based on what note (i.e. which pitch value) is being played?