Hacking the SNES ROM

Discuss PoP1 for SNES here.
David
The Prince of Persia
The Prince of Persia
Posts: 2852
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: April 18th, 2020, 10:18 am Another thing; while making attempts on adding a new sample, for some reason new sequence I added to the area at ECDE6-ECE96, so that the list of sound effects expand from 45 to 46 doesn't register/play. It only plays if I replace an existing sequence. Why this happens?
When the game wants to play a sound, it checks whether the sound ID falls into the correct range.
If it doesn't then nothing is played.

Code: Select all

play sound A on channel X:
02:9320: 8b          PHB
02:9321: 08          PHP
02:9322: e2 30       SEP #$30
02:9324: c9 2e       CMP #$2e ; <-- here
02:9326: 90 09       BCC $9331 ; sound ID in range
The byte at offset 0x11325 contains the last allowed ID plus one.
You need to change it from 0x2E (46) to 0x2F (47).

By the way, sound 0x2E exists but it cannot be played by default, because the check above only allows those sounds whose ID is *less than* 0x2E. (off-by one error)
Its command string is "T64V10O1@21A7R1A7" at 0xED390 (referred by the bytes 01 A8 05 at 0xECE8C-0xECE8E, 0xECDE8+0x5A8=0xED390), so if you want to add a sound effect with number 46 then you need to overwrite that part.
If, instead, you want to add a new sound effect after that then it will have number 47 (0x2F), you need to add the pointer at 0xECE8F-0xECE91, and increase the byte at 0x11325 further (to 0x30).
David
The Prince of Persia
The Prince of Persia
Posts: 2852
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: April 18th, 2020, 10:18 am Any findings on the multiple exits idea?
For now I've looked into this one:
Shauing wrote: March 8th, 2020, 2:45 am 1. Can levels have multiple exits that lead to different levels via a level end door? (e.g., on Level 1 one exit lead to Level 2, and another on the same level to Level 4).
(By the way, this is not for the SNES remake of the DOS version, right?)

We need to alter the part which sets next level = current level + 1.

Code: Select all

01:9F01: AD 79 05    LDA $0579 ; current level
01:9F04: 1A          INC
01:9F05: 8D 44 05    STA $0544 ; next level
At 0x9F01 write: 20 00 FD EA
At 0xFD00 write: AD 79 05 AE 06 05 [ C9 LL D0 07 E0 RR D0 03 A9 NN 60 ] 1A 60
Where:
* LL is the level where the exit door is. (As usual, 00=level 1, 01=level 2, etc.)
* RR is the room of the exit door. (I'm assuming you would put the two exits into different rooms.)
* NN is the level where this exit door should lead.
* [ ] means you can repeat the enclosed part as many times as needed, with different values of LL,RR,NN.

You only need to include the cases where the exit door doesn't lead to the next level.
So in your example, you only need to add the exit door which leads from level 1 to level 4.


The meaning of the written code is:

Code: Select all

At 0x9F01 write:
20 00 FD  JSR 0xFD00
EA        NOP

At 0xFD00 write:
AD 79 05  LDA $0579 ; current level
AE 06 05  LDX $0506 ; shown room ; VisScrn
          [[[ repeat as needed
C9 LL     CMP #$LL ; current level
D0 07     BNE :1
E0 RR     CPX #$RR ; room
D0 03     BNE :1
A9 NN     LDA #$NN ; next level
60        RTS
          :1
          ]]] end repeat
1A        INC
60        RTS
User avatar
Shauing
Calif
Calif
Posts: 432
Joined: April 5th, 2018, 10:38 pm
Contact:

Re: Hacking the SNES ROM

Post by Shauing »

David wrote: April 18th, 2020, 1:37 pm
Spoiler: show
When the game wants to play a sound, it checks whether the sound ID falls into the correct range.
If it doesn't then nothing is played.

Code: Select all

play sound A on channel X:
02:9320: 8b          PHB
02:9321: 08          PHP
02:9322: e2 30       SEP #$30
02:9324: c9 2e       CMP #$2e ; <-- here
02:9326: 90 09       BCC $9331 ; sound ID in range
The byte at offset 0x11325 contains the last allowed ID plus one.
You need to change it from 0x2E (46) to 0x2F (47).

By the way, sound 0x2E exists but it cannot be played by default, because the check above only allows those sounds whose ID is *less than* 0x2E. (off-by one error)
Its command string is "T64V10O1@21A7R1A7" at 0xED390 (referred by the bytes 01 A8 05 at 0xECE8C-0xECE8E, 0xECDE8+0x5A8=0xED390), so if you want to add a sound effect with number 46 then you need to overwrite that part.
If, instead, you want to add a new sound effect after that then it will have number 47 (0x2F), you need to add the pointer at 0xECE8F-0xECE91, and increase the byte at 0x11325 further (to 0x30).
Ah ha! I was suspecting something was missing that indicated how many samples could play. Thank you.
A bit related with the samples insertion: Do you know why the game hangs if the sample length indicated at E8073-E80C3 is bigger than approximately 8448-8528 bytes (21 50 in hex)? I discovered this while attempting to insert a sample of around 9982 bytes of length. I haven't figured what is the exact limit, but at 8448 bytes the game could still run.
EDIT: 8541 bytes (21 5D in hex) is the limit; if I try to run the game with the sample length being 8550 bytes long (21 66 in hex) it will hang at very beginning without displaying the Konami screen.
EDIT 2: Using values above approximately 2142 bytes and below 8541 bytes however causes some audio glitching/corruption when the Konami jingle notes and the first note of the intro music play (though in the sound test they play fine), and the new added sample's playback will be truncated and loop wrong/won't loop at all.
David wrote: April 18th, 2020, 9:35 pm
Shauing wrote: April 18th, 2020, 10:18 am Any findings on the multiple exits idea?
For now I've looked into this one:
Shauing wrote: March 8th, 2020, 2:45 am 1. Can levels have multiple exits that lead to different levels via a level end door? (e.g., on Level 1 one exit lead to Level 2, and another on the same level to Level 4).
(By the way, this is not for the SNES remake of the DOS version, right?)
Right, this is for a third mod I'm planning to do sometime afterwards, probably the last if I can bring all the ideas I have into it.
David wrote: April 18th, 2020, 9:35 pm
Spoiler: show
We need to alter the part which sets next level = current level + 1.

Code: Select all

01:9F01: AD 79 05    LDA $0579 ; current level
01:9F04: 1A          INC
01:9F05: 8D 44 05    STA $0544 ; next level
At 0x9F01 write: 20 00 FD EA
At 0xFD00 write: AD 79 05 AE 06 05 [ C9 LL D0 07 E0 RR D0 03 A9 NN 60 ] 1A 60
Where:
* LL is the level where the exit door is. (As usual, 00=level 1, 01=level 2, etc.)
* RR is the room of the exit door. (I'm assuming you would put the two exits into different rooms.)
* NN is the level where this exit door should lead.
* [ ] means you can repeat the enclosed part as many times as needed, with different values of LL,RR,NN.

You only need to include the cases where the exit door doesn't lead to the next level.
So in your example, you only need to add the exit door which leads from level 1 to level 4.


The meaning of the written code is:

Code: Select all

At 0x9F01 write:
20 00 FD  JSR 0xFD00
EA        NOP

At 0xFD00 write:
AD 79 05  LDA $0579 ; current level
AE 06 05  LDX $0506 ; shown room ; VisScrn
          [[[ repeat as needed
C9 LL     CMP #$LL ; current level
D0 07     BNE :1
E0 RR     CPX #$RR ; room
D0 03     BNE :1
A9 NN     LDA #$NN ; next level
60        RTS
          :1
          ]]] end repeat
1A        INC
60        RTS
Niiice. And yes, though different rooms for the door exits were my intention, it makes me wonder how it would work with multiple exit doors on the same room.

This first hack leads me to something probably unlikely but will ask it anyway. If multiple levels have an exit door that lead to one same level (for example, Levels 4 and 6 have an exit door that can lead to Level 10), can the Prince start in different parts of the level depending of which level's exit door was taken?
Can this apply to special exits as well?
(I imagine it might need a check for this first hack, and see if the Prince can start in different parts of the level like if they were checkpoints. And if the Prince dies, he should be restored to this new start instead of the default level start point (like a checkpoint); passwords could use that unused feature where it would check for the checkpoint and restore you there.

I hope more than 6 special exits and in all four directions are possible as well. As I recall, right or up special exits do not exist in the original game.
NEW UPDATE! Prince Of Persia: 30th Anniversary Port v1.1.5. Download it today!: viewtopic.php?p=29053#p29053
NEW UPDATE! Prince Of Persia: The Queen Of Light v2.6. Download it today! viewtopic.php?p=33174#p33174
User avatar
Shauing
Calif
Calif
Posts: 432
Joined: April 5th, 2018, 10:38 pm
Contact:

Re: Hacking the SNES ROM

Post by Shauing »

These are the last hacks for the 30th Anniversary Port I can think I need.
1. During the Jaffar fight, if the time runs out, the game sends you to the game over cutscene, instead of waiting for the Prince to kill Jaffar or die at Jaffar's hands like in the DOS version. Can this be fixed?
2. On the staff roll screen, can it display the title screen background instead? On DOS, the title screen background is displayed during the epilogue. Also can the animation (of the stars and water) be displayed as well?
3. On the best time window, can Levels 13 & 14 not display the time and instead add it to Level 12? If not, can a total time like in DOS can be displayed replacing the Level 20 space (Levels 15-19 will be erased from here so that they don't appear)?
4. Still haven't done the demo gameplay but if I recall correctly, there's two different demos that play on the DOS version, can this be done?
5. Can the HP of the demo be modified? The Prince has 4 HP.
NEW UPDATE! Prince Of Persia: 30th Anniversary Port v1.1.5. Download it today!: viewtopic.php?p=29053#p29053
NEW UPDATE! Prince Of Persia: The Queen Of Light v2.6. Download it today! viewtopic.php?p=33174#p33174
User avatar
Shauing
Calif
Calif
Posts: 432
Joined: April 5th, 2018, 10:38 pm
Contact:

Re: Hacking the SNES ROM

Post by Shauing »

EDIT for 4. I see that the demo has multiple variants of either the Prince winning or the Prince losing. I will try to recreate it as closer as I can and see if somehow I can manage to trigger multiple results like the DOS demo.
Adding a small bug for on Level 13. When using the SPCCMD! password, if for some reason you kill the hidden skeletons that trigger the falling tiles with the 'kill' button, the screen will flash and timer will stop as if Jaffar was killed, but he's still waiting above. It seems the ''timer stops when Jaffar is killed and screen flash'' hack doesn't specifically look for Jaffar but any enemy.
Spoiler: show
Also, for some odd reason, the falling tiles do not hurt the Prince when he's running, only when he doesn't move.
Also I noticed that the Shadow on Level 4 doesn't stop and turn back after being released from the mirror. Can he just keep running?
EDIT: Figured this one via disassembly and guessing I should modify the Shadow moves at 01:8000.
This makes me wonder if in the cutscenes there is something that manipulates how long each frame of animation will play. For example, in DOS the Princess stands for 16 seconds before turning to see Jaffar. On SNES, she only stands for around two seconds. Is there something similar to this? Couldn't find it in the disassembly. This is what I have been asking by ''timing'' of each cutscene, but couldn't word it properly.
EDIT: I think I found them at 02:CC1D. I'm not sure of the coding language, but it seems that either A9 XX and A2 XX, modify the timing between one set of sprite animations and the next one. I don't know the timing measure but I think it's probably frames.
NEW UPDATE! Prince Of Persia: 30th Anniversary Port v1.1.5. Download it today!: viewtopic.php?p=29053#p29053
NEW UPDATE! Prince Of Persia: The Queen Of Light v2.6. Download it today! viewtopic.php?p=33174#p33174
David
The Prince of Persia
The Prince of Persia
Posts: 2852
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: April 28th, 2020, 11:40 am 5. Can the HP of the demo be modified? The Prince has 4 HP.
We need to change this part:

Code: Select all

3 hp: (CHECKED: level 1, demo AND training):
01:ED4A: a9 03       LDA #$03
01:ED4C: 8d 1d 05    STA $051d ; HP at beginning of level ; checkpoint max HP
At 0xED4C write: 20 F0 FD
At 0xFDF0 write: AE 79 05 E0 15 D0 02 A9 04 8D 1D 05 60

The meaning of the new code:

Code: Select all

At 0xED4C write:
20 F0 FD  JSR $FDF0

At 0xFDF0 write:
AE 79 05  LDX $0579 ; current level
E0 15     CPX #$15 ; demo level
D0 02     BNE :1
A9 04     LDA #$04 ; HP on demo level
          :1
8D 1D 05  STA $051D ; HP at beginning of level
60        RTS
Shauing wrote: May 1st, 2020, 8:03 pm Also I noticed that the Shadow on Level 4 doesn't stop and turn back after being released from the mirror. Can he just keep running?
EDIT: Figured this one via disassembly and guessing I should modify the Shadow moves at 01:8000.
You're right.

Here's what the bytes there mean.
The first number of each pair is the time (number of frames after the moves started), and the second number is the action.
$00,$00, -- stop
$01,$01, -- run
$05,$00, -- stop
$14,$02, -- turn around
$19,$00, -- stop
$3c,$02, -- turn around
$41,$00, -- stop
$46,$01, -- run
$ff,$fe -- end

At 0x8004 write: FF FE
This overwrites the second "stop" with an "end" (at frame 255), so the shadow will keep running until he exits the room.

Shauing wrote: May 1st, 2020, 8:03 pm This makes me wonder if in the cutscenes there is something that manipulates how long each frame of animation will play. For example, in DOS the Princess stands for 16 seconds before turning to see Jaffar. On SNES, she only stands for around two seconds. Is there something similar to this? Couldn't find it in the disassembly. This is what I have been asking by ''timing'' of each cutscene, but couldn't word it properly.
EDIT: I think I found them at 02:CC1D. I'm not sure of the coding language, but it seems that either A9 XX and A2 XX, modify the timing between one set of sprite animations and the next one. I don't know the timing measure but I think it's probably frames.
You're correct about the offset, the lengths are indeed after A9 and A2, and they are in frames.

There are actually three delays before the Princess turns around. (See the disassembly below.)
You could change the length of any of them. (At 0x14C1E, 0x14C23, 0x14C28.)
The difference between the delays is whether the animations of the characters are paused or played during the delay.
But since these three delays are before any animation, there is no difference between the two.

Code: Select all

02:CC1D: a9 04       LDA #$04 ; <-- here
02:CC1F: 20 5e cd    JSR $cd5e ; play A frames from cutscene (play animations)
02:CC22: a2 08       LDX #$08 ; <-- here
02:CC24: 20 55 cd    JSR $cd55 ; play X frames from cutscene (pause animations)
02:CC27: a9 05       LDA #$05 ; <-- here
02:CC29: 20 5e cd    JSR $cd5e ; play A frames from cutscene (play animations)
02:CC2C: a9 62       LDA #$62 ; sequence ID: Princess turns around
02:CC2E: 20 61 c9    JSR $c961 ; shadow jump to sequence
02:CC31: a9 09       LDA #$09 ; length of turn around animation
02:CC33: 20 5e cd    JSR $cd5e ; play A frames from cutscene (play animations)
Shauing wrote: May 1st, 2020, 8:03 pm Also, for some odd reason, the falling tiles do not hurt the Prince when he's running, only when he doesn't move.
Yes, there is a special event in the DOS version to specifically make the falling floors hurt the Prince when he's running, only on level 13.
(First mentioned in this post.)
(In SDLPoP: https://github.com/NagyD/SDLPoP/blob/ma ... 07.c#L1209 )

The SNES version doesn't have this, here is how to add it:

At 0xDC3E write: 20 E0 FD
At 0xFDE0 write: AD 79 05 C9 0C D0 03 4C 8D DC 4C 82 DC

Here is the existing code:

Code: Select all

01:DC3E: 20 82 dc    JSR $dc82 ; fell_on_your_head

fell_on_your_head:
01:DC82: ad 57 04    LDA $0457 ; Char ; Char.frame ; CharPosn
01:DC85: c9 05       CMP #$05
01:DC87: 90 04       BCC $dc8d
01:DC89: c9 0f       CMP #$0f
01:DC8B: 90 4d       BCC $dcda ; return

01:DC8D: ad 5d 04    LDA $045d ; Char.action
01:DC90: c9 02       CMP #$02
01:DC92: 90 04       BCC $dc98
01:DC94: c9 07       CMP #$07
01:DC96: d0 42       BNE $dcda ; return

01:DC98: ae 5c 04    LDX $045c ; Char.row ; CharBlockY
01:DC9B: e8          INX
01:DC9C: bd fe ec    LDA $ecfe,X ; y_land ; FloorY
The meaning of the new code:

Code: Select all

At 0xDC3E write:
20 E0 FD  JSR $FDE0

At 0xFDE0 write:
AD 79 05  LDA $0579 ; current level
C9 0C     CMP #$0C ; level 13
D0 03     BNE :1
4C 8D DC  JMP $DC8D ; fell_on_your_head, but skip the Char.frame checks
          :1
4C 82 DC  JMP $DC82 ; fell_on_your_head
User avatar
Shauing
Calif
Calif
Posts: 432
Joined: April 5th, 2018, 10:38 pm
Contact:

Re: Hacking the SNES ROM

Post by Shauing »

David wrote: May 2nd, 2020, 6:39 pm
Spoiler: show
Shauing wrote: April 28th, 2020, 11:40 am 5. Can the HP of the demo be modified? The Prince has 4 HP.
We need to change this part:

Code: Select all

3 hp: (CHECKED: level 1, demo AND training):
01:ED4A: a9 03       LDA #$03
01:ED4C: 8d 1d 05    STA $051d ; HP at beginning of level ; checkpoint max HP
At 0xED4C write: 20 F0 FD
At 0xFDF0 write: AE 79 05 E0 15 D0 02 A9 04 8D 1D 05 60

The meaning of the new code:

Code: Select all

At 0xED4C write:
20 F0 FD  JSR $FDF0

At 0xFDF0 write:
AE 79 05  LDX $0579 ; current level
E0 15     CPX #$15 ; demo level
D0 02     BNE :1
A9 04     LDA #$04 ; HP on demo level
          :1
8D 1D 05  STA $051D ; HP at beginning of level
60        RTS
I noticed that the guard for this demo also has 4 HP, and the one other guard that share the skill with, the fat, has 5 HP. I don't have any more skill guards available, so how can this guard have 4 HP as well?
EDIT: I made a list of all the guard skills, and turns out I do have one more slot. The Shadow and Dead Purple Guard have the same skills, but I wrote each of their skills to their own guard type instead of sharing the same skill, so I can change one of these to match the demo guard skills, which are the same as the fat minus 1 health point.
David wrote: May 2nd, 2020, 6:39 pm
Spoiler: show
Shauing wrote: May 1st, 2020, 8:03 pm Also I noticed that the Shadow on Level 4 doesn't stop and turn back after being released from the mirror. Can he just keep running?
EDIT: Figured this one via disassembly and guessing I should modify the Shadow moves at 01:8000.
You're right.

Here's what the bytes there mean.
The first number of each pair is the time (number of frames after the moves started), and the second number is the action.
$00,$00, -- stop
$01,$01, -- run
$05,$00, -- stop
$14,$02, -- turn around
$19,$00, -- stop
$3c,$02, -- turn around
$41,$00, -- stop
$46,$01, -- run
$ff,$fe -- end

At 0x8004 write: FF FE
This overwrites the second "stop" with an "end" (at frame 255), so the shadow will keep running until he exits the room.
Oh, so it is similar to the Prince demo movement.
David wrote: May 2nd, 2020, 6:39 pm
Spoiler: show

You're correct about the offset, the lengths are indeed after A9 and A2, and they are in frames.

There are actually three delays before the Princess turns around. (See the disassembly below.)
You could change the length of any of them. (At 0x14C1E, 0x14C23, 0x14C28.)
The difference between the delays is whether the animations of the characters are paused or played during the delay.
But since these three delays are before any animation, there is no difference between the two.

Code: Select all

02:CC1D: a9 04       LDA #$04 ; <-- here
02:CC1F: 20 5e cd    JSR $cd5e ; play A frames from cutscene (play animations)
02:CC22: a2 08       LDX #$08 ; <-- here
02:CC24: 20 55 cd    JSR $cd55 ; play X frames from cutscene (pause animations)
02:CC27: a9 05       LDA #$05 ; <-- here
02:CC29: 20 5e cd    JSR $cd5e ; play A frames from cutscene (play animations)
02:CC2C: a9 62       LDA #$62 ; sequence ID: Princess turns around
02:CC2E: 20 61 c9    JSR $c961 ; shadow jump to sequence
02:CC31: a9 09       LDA #$09 ; length of turn around animation
02:CC33: 20 5e cd    JSR $cd5e ; play A frames from cutscene (play animations)
Ah, I'm happy I got it right. And that explains why a few of these seemingly do nothing (like the first one).
David wrote: May 2nd, 2020, 6:39 pm
Spoiler: show
Shauing wrote: May 1st, 2020, 8:03 pm Also, for some odd reason, the falling tiles do not hurt the Prince when he's running, only when he doesn't move.
Yes, there is a special event in the DOS version to specifically make the falling floors hurt the Prince when he's running, only on level 13.
(First mentioned in this post.)
(In SDLPoP: https://github.com/NagyD/SDLPoP/blob/ma ... 07.c#L1209 )

The SNES version doesn't have this, here is how to add it:

At 0xDC3E write: 20 E0 FD
At 0xFDE0 write: AD 79 05 C9 0C D0 03 4C 8D DC 4C 82 DC

Here is the existing code:

Code: Select all

01:DC3E: 20 82 dc    JSR $dc82 ; fell_on_your_head

fell_on_your_head:
01:DC82: ad 57 04    LDA $0457 ; Char ; Char.frame ; CharPosn
01:DC85: c9 05       CMP #$05
01:DC87: 90 04       BCC $dc8d
01:DC89: c9 0f       CMP #$0f
01:DC8B: 90 4d       BCC $dcda ; return

01:DC8D: ad 5d 04    LDA $045d ; Char.action
01:DC90: c9 02       CMP #$02
01:DC92: 90 04       BCC $dc98
01:DC94: c9 07       CMP #$07
01:DC96: d0 42       BNE $dcda ; return

01:DC98: ae 5c 04    LDX $045c ; Char.row ; CharBlockY
01:DC9B: e8          INX
01:DC9C: bd fe ec    LDA $ecfe,X ; y_land ; FloorY
The meaning of the new code:

Code: Select all

At 0xDC3E write:
20 E0 FD  JSR $FDE0

At 0xFDE0 write:
AD 79 05  LDA $0579 ; current level
C9 0C     CMP #$0C ; level 13
D0 03     BNE :1
4C 8D DC  JMP $DC8D ; fell_on_your_head, but skip the Char.frame checks
          :1
4C 82 DC  JMP $DC82 ; fell_on_your_head
Oh, so it is a special case and not something that normally can occur in the game. Very interesting!
Last edited by Shauing on May 3rd, 2020, 10:24 pm, edited 1 time in total.
NEW UPDATE! Prince Of Persia: 30th Anniversary Port v1.1.5. Download it today!: viewtopic.php?p=29053#p29053
NEW UPDATE! Prince Of Persia: The Queen Of Light v2.6. Download it today! viewtopic.php?p=33174#p33174
David
The Prince of Persia
The Prince of Persia
Posts: 2852
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: May 1st, 2020, 8:03 pm Adding a small bug for on Level 13. When using the SPCCMD! password, if for some reason you kill the hidden skeletons that trigger the falling tiles with the 'kill' button, the screen will flash and timer will stop as if Jaffar was killed, but he's still waiting above. It seems the ''timer stops when Jaffar is killed and screen flash'' hack doesn't specifically look for Jaffar but any enemy.
Yeah, the game checks the level number, but it should check the guard type.

This overwrites part of a previous hack. This is intentional.
The instruction we overwrite at 0xFFC6 (AD 79 05 = LDA $0579) is originally at 0xE199, but that previous hack moved it to 0xFFC6.

At 0xFFC6 write: AD 2B 06
At 0xE19C write: C9 10

Code: Select all

At 0xFFC6 write:
AD 2B 06  LDA $062B ; guard type

At 0xE19C write:
C9 10     CMP #$10 ; Jaffar
Shauing wrote: April 28th, 2020, 11:40 am 1. During the Jaffar fight, if the time runs out, the game sends you to the game over cutscene, instead of waiting for the Prince to kill Jaffar or die at Jaffar's hands like in the DOS version. Can this be fixed?
Part 1: Don't show bad ending if time expires on level 13.

Like the previous one, this hack overwrites a previous hack.

At 0xFF50 write: AD 79 05 C9 0C 90 01 60 A9 FE 8D 79 05 4C D3 F3

Code: Select all

At 0xFF50 write:
AD 79 05  LDA $0579 ; current level
C9 0C     CMP #$0C ; level 13
90 01     BCC :1
60        RTS
          :1
A9 FE     LDA #$FE
8D 79 05  STA $0579 ; current level
4C D3 F3  JMP $F3D3 ; show ending

Part 2: If the prince dies on level 13, then show the bad ending.

First, disable the disappearing of the prince after death in a different way than previously.
That hack disabled counting frames after death, to indirectly disable disappearing of the prince.
But we need that counting.

At 0xF381 write: 24 (restore the original value)
At 0xF579 write: 80

Then, if a certain time has elapsed since the prince died, and the time has expired, then show the bad ending.

At 0xF384 write: 20 D0 FD
At 0xFDD0 write: EE 66 04 C9 07 D0 08 AD 27 05 D0 03 4C 58 FF 60

Code: Select all

At 0xF384 write:
20 D0 FD  JSR $FDD0

At 0xFDD0 write:
EE 66 04  INC $0466 ; Char.alive? ; CharLife
C9 07     CMP #$07 ; frames since death
D0 08     BNE :1
AD 27 05  LDA $0527 ; remaining min
D0 03     BNE :1
4C 58 FF  JMP $FF58 ; this jumps into part 1
          :1
60        RTS

Problem: If you beat Jaffar after the time has expired, then when you enter the princess's room, you'll get the bad ending.

Solution:
At 0xF3DC write: EA EA
At 0xFF5D write: 4C EA F3
User avatar
Shauing
Calif
Calif
Posts: 432
Joined: April 5th, 2018, 10:38 pm
Contact:

Re: Hacking the SNES ROM

Post by Shauing »

Reposting the remaining things on the list above plus a few bugs/small details I found to see if they can be fixed/added:
1. On the game over cutscene, after the music is over and the ''game over'' prompt appears you can press any button to end the cutscene and go back to the menu. But if you press start, after the fade-out the game ''pauses'' making reappear the cutscene with some glitchy appearance and the pause sound plays as if the game was still paused. I did sort of a workaround by writing A9 72 at 02:CB6C and write 4C 51 CD at 02:CB78, so that the cutscene ends just before the music decays completely so that you don't have a chance to press start. Even though this is pretty much what the DOS does (there's no ''Game Over'' display), the issues with this ''fix'' is that the music doesn't completely decay and a brief flashing glance of the cutscene and the pause sound effect still occurs (this glance lasts longer if killed by Jaffar and it doesn't need a button press).
2. If possible, when the Prince dies on Level 12b when time has run out, can the jump to the game over cutscene wait until the death music stops playing? It just starts to play and then its abruptly cut by the cutscene.
3. On DOS, when either the Prince or a guard has one hitpoint left, it flashes. Can this be implemented?
4. I also see that on DOS each guard has a different hitpoint palette as well (I think it matches the turban colors), and on SNES all of them they share a green color. Can this be implemented somehow?
5. Can the demo choose between two autoplay sequences? I couldn't manage to have at least one variant where the Prince could lose.
6. Can the player have the option to skip the title screen like on the Japanese version? As the title screen appearance takes a few seconds long, and it might be a bother to players. Also/or, can the water/stars animation play while waiting for the title screen to appear? It kind of looks like the game is frozen.
7. Hopefully a way to display the title screen background on the staff roll with the animation. I tried to do it myself but didn't find success.
8. Hopefully, best time does not display time for Levels 13 & 14, and just add a total time on the Level 20 slot, as I think it will be a pain to add a ''name input'' for it.

I will release the trailer between today and Sunday, and pin the release date between May 15th-June 3rd depending if any or all of the things above can be fulfilled. Those are the only things remaining; everything else has been implemented now (as much as I could; unfortunately there were space and palette limitations that prevented some screens and sprites to look like on the DOS, or appealing on the SNES).
Last edited by Shauing on May 9th, 2020, 7:11 am, edited 3 times in total.
NEW UPDATE! Prince Of Persia: 30th Anniversary Port v1.1.5. Download it today!: viewtopic.php?p=29053#p29053
NEW UPDATE! Prince Of Persia: The Queen Of Light v2.6. Download it today! viewtopic.php?p=33174#p33174
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5749
Joined: April 9th, 2009, 10:58 pm

Re: Hacking the SNES ROM

Post by Norbert »

Shauing wrote: May 8th, 2020, 9:35 pmI will release the trailer between today and Sunday, and pin the release date between May 15th-June 3rd depending [...]
Getting closer. :)
David
The Prince of Persia
The Prince of Persia
Posts: 2852
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: May 8th, 2020, 9:35 pm 2. If possible, when the Prince dies on Level 12b when time has run out, can the jump to the game over cutscene wait until the death music stops playing? It just starts to play and then its abruptly cut by the cutscene.
At 0xF384 write: 20 C0 FD
At 0xFDC0 write: AD 41 05 D0 12 EE 66 04 AD 66 04 C9 07 D0 08 AD 27 05 D0 03 4C 58 FF 60

This replaces and overwrites "Part 2" of the hack in my previous post.

Disassembly of the new code:

Code: Select all

At 0xF384 write:
20 C0 FD  JSR $FDC0

At 0xFDC0 write:
AD 41 05  LDA $0541 ; SongCue
D0 12     BNE :1
EE 66 04  INC $0466 ; Char.alive? ; CharLife
AD 66 04  LDA $0466 ; Char.alive? ; CharLife
C9 07     CMP #$07
D0 08     BNE :1
AD 27 05  LDA $0527 ; remaining min
D0 03     BNE :1
4C 58 FF  JMP $FF58
          :1
60        RTS
User avatar
Shauing
Calif
Calif
Posts: 432
Joined: April 5th, 2018, 10:38 pm
Contact:

Re: Hacking the SNES ROM

Post by Shauing »

David wrote: May 9th, 2020, 9:29 pm
Spoiler: show
Shauing wrote: May 8th, 2020, 9:35 pm 2. If possible, when the Prince dies on Level 12b when time has run out, can the jump to the game over cutscene wait until the death music stops playing? It just starts to play and then its abruptly cut by the cutscene.
At 0xF384 write: 20 C0 FD
At 0xFDC0 write: AD 41 05 D0 12 EE 66 04 AD 66 04 C9 07 D0 08 AD 27 05 D0 03 4C 58 FF 60

This replaces and overwrites "Part 2" of the hack in my previous post.

Disassembly of the new code:

Code: Select all

At 0xF384 write:
20 C0 FD  JSR $FDC0

At 0xFDC0 write:
AD 41 05  LDA $0541 ; SongCue
D0 12     BNE :1
EE 66 04  INC $0466 ; Char.alive? ; CharLife
AD 66 04  LDA $0466 ; Char.alive? ; CharLife
C9 07     CMP #$07
D0 08     BNE :1
AD 27 05  LDA $0527 ; remaining min
D0 03     BNE :1
4C 58 FF  JMP $FF58
          :1
60        RTS
All right, though because the prompt ''Press a button to continue'' appears for a brief moment, the player can actually manage to continue if it mashes the button fast enough.
NEW UPDATE! Prince Of Persia: 30th Anniversary Port v1.1.5. Download it today!: viewtopic.php?p=29053#p29053
NEW UPDATE! Prince Of Persia: The Queen Of Light v2.6. Download it today! viewtopic.php?p=33174#p33174
David
The Prince of Persia
The Prince of Persia
Posts: 2852
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: May 9th, 2020, 10:12 pm All right, though because the prompt ''Press a button to continue'' appears for a brief moment, the player can actually manage to continue if it mashes the button fast enough.
Here is the fix.
It replaces and overwrites the previous version of the hack. (Again!)

At 0xF384 write back the original bytes: EE 66 04
(You can also fill 0xFDC0-0xFDDF with zeroes before you write the following codes.)

At 0xF648 write: 4C D0 FD
At 0xFDD0 write: AD 27 05 D0 03 4C 58 FF 4C FD CA

Code: Select all

The original code which we overwrite:
01:F648: 4C FD CA    JMP $CAFD ; show "press button"

Disassembly of the new code:

At 0xF648 write:
4C D0 FD  JMP $FDD0

At 0xFDD0 write:
AD 27 05  LDA $0527 ; remaining min
D0 03     BNE :1
4C 58 FF  JMP $FF58 ; time expired
          :1
4C FD CA  JMP $CAFD ; show "press button"
David
The Prince of Persia
The Prince of Persia
Posts: 2852
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: May 8th, 2020, 9:35 pm 7. Hopefully a way to display the title screen background on the staff roll with the animation. I tried to do it myself but didn't find success.
At 0x1B3E6 write: A9 05 -- load hidden second background needed for the animations
At 0x1B3F2 write: A9 04 -- load sky+moon background
At 0x1B406 write: A2 08 -- load palette for the sky+moon background
At 0x1B440 write: 80 12 -- disable transparency effects
At 0x1B667 write: EA EA EA -- remove elephant
At 0x1B695 write: EA EA EA -- remove wave animation
At 0x1B454 write: EA EA EA -- don't even apply a stopped wave to the screen

I also tried to add the animations of the title screen to the ending screen, but everything I tried so far has locked up the game.
Details:
Spoiler: show
At 0x1B695 I tried to write the following: 20 2E 81, or 20 49 81, or 20 83 81, or 20 9E 80.
These would call one out of the following codes:

Code: Select all

03:809E: a9 02       LDA #$02
03:80A0: a2 10       LDX #$10
03:80A2: 20 2e 81    JSR $812e ; sky+moon: wait frames
03:80A5: 60          RTS

sky+moon: wait frames:
03:812E: 48          PHA
03:812F: da          PHX
03:8130: da          PHX
03:8131: 20 49 81    JSR $8149 ; animate stars
03:8134: 20 83 81    JSR $8183 ; animate reflection of moon
03:8137: 20 0d 82    JSR $820d ; update screen
David
The Prince of Persia
The Prince of Persia
Posts: 2852
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: May 8th, 2020, 9:35 pm 3. On DOS, when either the Prince or a guard has one hitpoint left, it flashes. Can this be implemented?
At 0x50E8 write: 20 80 FF
At 0x5133 write: 20 80 FF
At 0x7F80 write: 29 FF 00 C9 01 00 D0 03 2D 2F 05 60

Note: My first try had "2D 2D 05" instead of "2D 2F 05". That will make the flash slower than in the DOS version.
I mention it here in case someone wants that.

Details:

Code: Select all

The hit points are loaded here for the purpose of drawing the bottles:

00:D0E4: af 08 05 00 LDA $00:0508 ; kid current HP ; KidStrength
00:D0E8: 29 ff 00    AND #$00ff

00:D12F: af 0b 05 00 LDA $00:050b ; guard current HP ; OppStrength
00:D133: 29 ff 00    AND #$00ff

New code:

At 0x50E8 write:
20 80 FF  JSR $FF80

At 0x5133 write:
20 80 FF  JSR $FF80

At 0x7F80 write:
29 FF 00  AND #$00FF
C9 01 00  CMP #$0001 ; If we would draw 1 HP:
D0 03     BNE :1
2D 2F 05  AND $052F ; Do a bitwise and between that 1 and the low bit of the elapsed time (which is toggled in every frame).
                    ; The result is either 0 or 1.
          :1
60        RTS

The alternate version with slower flash contains this instead of "2D 2F 05":
2D 2D 05  AND $052D ; elapsed time 1 L ; FrameCount
Post Reply