Hacking the SNES ROM

Discuss PoP1 for SNES here.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5746
Joined: April 9th, 2009, 10:58 pm

Re: Hacking the SNES ROM

Post by Norbert »

Attached is a document I've created that lists all ASCII texts and their offsets.
Attachments
2018-06-24_PoP1_SNES_text_offsets.txt
(7.21 KiB) Downloaded 98 times
User avatar
Shauing
Calif
Calif
Posts: 432
Joined: April 5th, 2018, 10:38 pm
Contact:

Re: Hacking the SNES ROM

Post by Shauing »

Norbert wrote: June 24th, 2018, 1:43 pm Attached is a document I've created that lists all ASCII texts and their offsets.
I have a question here. Yesterday, I did a modification on the ''Best Time'' menu to only show 10 levels.
Test000.png
Test000.png (9.23 KiB) Viewed 2612 times
But when completing a level, the time appears instead on the place it was before.
Test001.png
Test001.png (9.27 KiB) Viewed 2612 times
I am probably missing something to make the times appear on the new position. Is it possible to do this?
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: 5746
Joined: April 9th, 2009, 10:58 pm

Re: Hacking the SNES ROM

Post by Norbert »

Shauing wrote: June 25th, 2018, 6:21 amI am probably missing something to make the times appear on the new position. Is it possible to do this?
Should be possible by changing one of the bytes (x-coordinate); David may know how...
However, maybe an easier solution is to switch the "LEVEL" and "TIME" columns? :)
User avatar
Shauing
Calif
Calif
Posts: 432
Joined: April 5th, 2018, 10:38 pm
Contact:

Re: Hacking the SNES ROM

Post by Shauing »

Norbert wrote: June 25th, 2018, 7:10 am
Should be possible by changing one of the bytes (x-coordinate); David may know how...
However, maybe an easier solution is to switch the "LEVEL" and "TIME" columns? :)
I will consider it as the alternative if modifying the positions isn't possible. Thank you for suggesting it!
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: 5746
Joined: April 9th, 2009, 10:58 pm

Re: Hacking the SNES ROM

Post by Norbert »

Norbert wrote: June 24th, 2018, 1:43 pm Attached is a document I've created that lists all ASCII texts and their offsets.
Some small corrections of offsets:
" BEST TIME" 0x1117 -> 0x1116
" PASSWORD " 0x1124 -> 0x1123
" GAME END " 0x1131 -> 0x1130
" OPTION " 0x113E -> 0x113D
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5746
Joined: April 9th, 2009, 10:58 pm

Re: Hacking the SNES ROM

Post by Norbert »

The new apoplexy v3.4 (apoplexy.org) can modify these texts. Even modders who prefer to use Pr1SnesLevEd can use this by temporarily moving their mod into apoplexy's snes/ directory, then making the changes (F3 on main screen), and then moving their mod back.

-----

The SNES mods with modified texts:
- The Quiet Levels by Kaslghnoon: Intro (partial), Outro(*), Continue (partial)
- SmallDungMod (SNES) by 2233: Intro (partial)
- The Lost Bottle (Chapter 1) by spartacus735: Intro (partial), Menus (2 entries), Various (3 entries)
- Time Only Knows by NITM-T(**): Intro, Outro
- The Kingdom of the Dead by NITM-T(**): Intro (partial), Outro, Menus (partial), Various (1 entry)
- The Two Princesses by NITM-T(**): Intro, Credits (I) (1 entry), Menus (partial), Various (2 entries)
- Shadow's Story by NITM-T: Intro (partial), Outro, Credits (I) (1 entry), Menus (partial), Various (partial)
- Sword of Gold by juliano_did: Intro, Outro, Menus (1 entry), Cheat (1 entry)
- Twin Brother by NITM-T: Intro (partial), Credits (I) (1 entry), Menus (2 entries), Various (2 entries)

(*) The end of this outro is displayed incorrectly by apoplexy. I'll have to look into this. Maybe Kaslghnoon changed more than just text?
(**) The Portuguese characters aren't displayed properly by apoplexy. Not a big deal.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5746
Joined: April 9th, 2009, 10:58 pm

Re: Hacking the SNES ROM

Post by Norbert »

Norbert wrote: June 27th, 2018, 5:03 pm(*) The end of this outro is displayed incorrectly by apoplexy. I'll have to look into this. Maybe Kaslghnoon changed more than just text?
He did.
He moved the line endings, as can be seen in the attached images of the original game and his modification.
Attachments
quiet.png
pop1.png
David
The Prince of Persia
The Prince of Persia
Posts: 2850
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Norbert wrote: June 24th, 2018, 10:27 am Maybe this has already been discussed somewhere, but where are the "MINUTES LEFT" and "SECONDS LEFT" (and "THE END") texts?
(This question seems familiar, but I can't find anything in the forum.)

This is the font used by PoP1 SNES:
SNES_font.png
SNES_font.png (4.02 KiB) Viewed 2562 times
As you can see, there are three texts made from custom tiles instead of the regular letters.

The "MINUTES LEFT" text is at 0xCA0E, as hex 80 81 82 83 84 85 86 87 88 89 8A (00).
The "SECONDS LEFT" text is at 0xCA1A, as hex 90 91 92 93 94 95 96 97 98 99 9A 9B (00).
These are just before the "TIME UP" and "TRAINING !!" texts.
You can change these bytes to regular letters.
The "PUSH START BUTTON" text is not used.

There are a few more texts missing from your list:
"BTL3GY7Q9CVM4HZ8R+DWN5J12S!FXP6K" 0x15C38 -- The password alphabet, never displayed.
"BRNGBB9" 0x15DF2 -- The default password.
"A" "B" "X" "Y" "L" "R 345678901234 789012" 0x161F1-0x1621B -- The names of the buttons, just after "OPTION". The digits are overwritten by other texts.

By the way, many of the texts are joined together.
For example, the OPTION screen is one big text that starts at 0x161DD and ends at 0x16254.
Every time you find a 0x01 byte, it means that the next two bytes tell the column and row position of the following text. (Set cursor position.)
A 0x00 byte marks the end of the text. (But only if it's not one of the two bytes of the cursor position.)

About "THE END": If you mean the end of the credits, it's stored as hex 84 20 1E 1F at 0x1BC01.
The font used for the credits also contains a few special "characters", as you can see here:
SNES_font_credits.png
SNES_font_credits.png (4.47 KiB) Viewed 2562 times
David
The Prince of Persia
The Prince of Persia
Posts: 2850
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Norbert wrote: June 24th, 2018, 10:27 am pirate.png
It's JaffAAAARRRRrrrr! :lol:

Yeah, that area (around 0x74D40) contains lots of bytes that are repeated four times.
That's because this area contains the Japanese font, which is drawn with color 15 on a color 0 background.
Because 15=1111, 0=0000 in binary, this means that every tile has the same bytes in all the four bitplanes.
And since the corresponding bytes of the bitplanes are stored next to each other, this results in the repetition that you see.

I wonder why didn't the compression replace the sequences of four identical bytes with a single byte.
That would have reduced the number of times users got an error message saying "Last resource doesn't fit into its place" from Pr1SnesLevEd...

(By the way, there is a (DOS) mod where Jaffar is a pirate: https://www.popot.org/custom_levels.php?mod=0000047 )
David
The Prince of Persia
The Prince of Persia
Posts: 2850
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Norbert wrote: June 27th, 2018, 5:03 pm - Time Only Knows by NITM-T(**): Intro, Outro
- The Kingdom of the Dead by NITM-T(**): Intro (partial), Outro, Menus (partial), Various (1 entry)
- The Two Princesses by NITM-T(**): Intro, Credits (I) (1 entry), Menus (partial), Various (2 entries)
[...]
(**) The Portuguese characters aren't displayed properly by apoplexy. Not a big deal.
Do you mean these?
from Prince of Persia The Two Princesses
from Prince of Persia The Two Princesses
snes_text_pt.png (1.14 KiB) Viewed 2562 times
The "Ì" characters are byte 0xCC. In the game these appear as spaces. I don't know why did NITM-T use these, though.
The box characters are byte 0x0D, that is, newline.
David
The Prince of Persia
The Prince of Persia
Posts: 2850
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Norbert wrote: June 25th, 2018, 7:10 am
Shauing wrote: June 25th, 2018, 6:21 amI am probably missing something to make the times appear on the new position. Is it possible to do this?
Should be possible by changing one of the bytes (x-coordinate); David may know how...

Code: Select all

02:D652: a3 01       LDA $01,S
02:D654: c9 0a       CMP #$0a ; 10 levels in left column
02:D656: b0 04       BCS $d65c
02:D658: a9 03       LDA #$03 ; left column
02:D65A: 80 02       BRA $d65e
02:D65C: a9 0d       LDA #$0d ; right column
02:D65E: 95 01       STA $01,X ; column
Search: B0 04 A9 03
Change: 03 to the column position you need.
In your case I think it's 0B.
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: June 30th, 2018, 4:35 pm

Code: Select all

02:D652: a3 01       LDA $01,S
02:D654: c9 0a       CMP #$0a ; 10 levels in left column
02:D656: b0 04       BCS $d65c
02:D658: a9 03       LDA #$03 ; left column
02:D65A: 80 02       BRA $d65e
02:D65C: a9 0d       LDA #$0d ; right column
02:D65E: 95 01       STA $01,X ; column
Search: B0 04 A9 03
Change: 03 to the column position you need.
In your case I think it's 0B.
Thank you, David!

By the way, have you find if its possible to alter the "Training (1, 2, 3, 4 and 5)" texts individually so that on each one can describe what the training is about (i.e. "Loose Tiles"?

Also, is it possible to reduce the time limit to 60, 75 or 90 minutes? I feel one of these will be just right for the mod.
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: 2850
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: June 30th, 2018, 5:34 pm Also, is it possible to reduce the time limit to 60, 75 or 90 minutes? I feel one of these will be just right for the mod.
Part 1: Displayed minutes:

Code: Select all

01:E95D: ad 27 05    LDA $0527 ; remaining min
01:E960: a2 78       LDX #$78
01:E962: 20 99 e9    JSR $e999 ; subtract and to BCD?
01:E965: 8d 27 05    STA $0527 ; remaining min
Search: A2 78 20 99 E9
Change: 78 to the number of minutes you want (in hex).

Part 2: The point when time expires:

Code: Select all

01:E93D: ac 2d 05    LDY $052d ; elapsed time 1 L
01:E940: c0 38 c7    CPY #$c738
01:E943: b0 2f       BCS $e974

02:D876: ad 4b 05    LDA $054b ; elapsed time on this level L
02:D879: c9 38 c7    CMP #$c738
02:D87C: b0 10       BCS $d88e ; don't store

02:DCA7: ad 4b 05    LDA $054b ; elapsed time on this level L
02:DCAA: c9 38 c7    CMP #$c738
02:DCAD: b0 0a       BCS $dcb9
Search: 38 C7 B0
There should be 3 results.
(In case this has too much results, search instead for AC 2D 05 C0 38 C7 (one result) and AD 4B 05 C9 38 C7 (two results).)
In all results, change 38 C7 to the result of the following: multiply the minutes by 425, convert it to hex, then swap the two halves (bytes) of the result.
(The original value is 120 * 425 = 51000 = 0xC738, when swapped it becomes 38 C7.)

Part 3: When the game shows time by itself:

Code: Select all

times when time is shown:
01:EA11: WORD $0000,$084d,$109a,$18e7,$2134,$2981,$31ce,$3a1b,$4268,$4ab5,$5302,$5b4f,$639c,$6be9,$7436,$7c83,$84d0,$8d1d,$956a,$9db7,$a604,$ae51,$b69e,$beeb,$c094,$c23d,$c3e6,$c590,$c73d,$ffff
Err, I'm not sure if I want to go into this...
This table basically says that the time is shown every 5 minutes (5*425=$084D) until there are only 5 minutes left (115*425=$BEEB), then every minute, then about one second after time is up ($C73D).
The problem is that since time expires much before the elapsed time counter reaches the original 120 minutes, these values are all off, and the player won't get the warnings in every minute before the time expires.
I don't know if this would be a problem for you.
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: June 30th, 2018, 7:13 pm
Part 1: Displayed minutes:

Code: Select all

01:E95D: ad 27 05    LDA $0527 ; remaining min
01:E960: a2 78       LDX #$78
01:E962: 20 99 e9    JSR $e999 ; subtract and to BCD?
01:E965: 8d 27 05    STA $0527 ; remaining min
Search: A2 78 20 99 E9
Change: 78 to the number of minutes you want (in hex).

Part 2: The point when time expires:

Code: Select all

01:E93D: ac 2d 05    LDY $052d ; elapsed time 1 L
01:E940: c0 38 c7    CPY #$c738
01:E943: b0 2f       BCS $e974

02:D876: ad 4b 05    LDA $054b ; elapsed time on this level L
02:D879: c9 38 c7    CMP #$c738
02:D87C: b0 10       BCS $d88e ; don't store

02:DCA7: ad 4b 05    LDA $054b ; elapsed time on this level L
02:DCAA: c9 38 c7    CMP #$c738
02:DCAD: b0 0a       BCS $dcb9
Search: 38 C7 B0
There should be 3 results.
(In case this has too much results, search instead for AC 2D 05 C0 38 C7 (one result) and AD 4B 05 C9 38 C7 (two results).)
In all results, change 38 C7 to the result of the following: multiply the minutes by 425, convert it to hex, then swap the two halves (bytes) of the result.
(The original value is 120 * 425 = 51000 = 0xC738, when swapped it becomes 38 C7.)
Ok, I think I get it.
David wrote: June 30th, 2018, 7:13 pm Part 3: When the game shows time by itself:

Code: Select all

times when time is shown:
01:EA11: WORD $0000,$084d,$109a,$18e7,$2134,$2981,$31ce,$3a1b,$4268,$4ab5,$5302,$5b4f,$639c,$6be9,$7436,$7c83,$84d0,$8d1d,$956a,$9db7,$a604,$ae51,$b69e,$beeb,$c094,$c23d,$c3e6,$c590,$c73d,$ffff
Err, I'm not sure if I want to go into this...
This table basically says that the time is shown every 5 minutes (5*425=$084D) until there are only 5 minutes left (115*425=$BEEB), then every minute, then about one second after time is up ($C73D).
The problem is that since time expires much before the elapsed time counter reaches the original 120 minutes, these values are all off, and the player won't get the warnings in every minute before the time expires.
I don't know if this would be a problem for you.
So, all those values need to be altered as well if I want every warning to be displayed correctly? If so, how do I alter them correctly?

It's okay if it is a long process to do. I have been working on the mod (on and off) for four months and I have learned pretty much about modding and hacking a ROM by doing it, and it has been a fun ride.
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: 2850
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Hacking the SNES ROM

Post by David »

Shauing wrote: June 30th, 2018, 5:34 pm By the way, have you find if its possible to alter the "Training (1, 2, 3, 4 and 5)" texts individually so that on each one can describe what the training is about (i.e. "Loose Tiles"?
At 0xCA9B write: AD 79 05 E9 15 08 C2 20 29 FF 00 0A 0A 0A 0A 0A 69 00 FF 48 F4 56 08 20 A0 CB 68 68 28 4C 36 CB
At 0xFF00 write the text for training 1.
At 0xFF20 write the text for training 2.
At 0xFF40 write the text for training 3.
At 0xFF60 write the text for training 4.
At 0xFF80 write the text for training 5.
There must be a 00 byte after the end of each text.
The maximum length of each text is 31 characters (32 with the closing 00 byte). I hope this is enough.
(The width of the SNES screen is 32 characters, but two columns are occupied by the black margins, and two more by the border around the text.)
(The border around the text will be cropped for 28-character or longer texts.)

The meaning of that long byte sequence, if someone is interested:
Spoiler: show

Code: Select all

AD 79 05  LDA $0579 ; current level
E9 15     SBC #$15 ; number of first training level
08        PHP
C2 20     REP #$20 ; 16-bit accumulator
29 FF 00  AND #$00FF
0A        ASL ;*2
0A        ASL ;*4
0A        ASL ;*8
0A        ASL ;*16
0A        ASL ;*32
69 00 FF  ADC #$FF00 ; address of first text
48        PHA
F4 56 08  PEA $0856 ; buffer for strings
20 A0 CB  JSR $CBA0 ; copy string
68        PLA
68        PLA
28        PLP
4C 36 CB  JMP $CB36 ; show status text
Post Reply