PoP1 Game Boy (Color) format documentation

Discuss other PoP1 related things here.
Post Reply
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

PoP1 Game Boy (Color) format documentation

Post by David »

Here is what I could figure out about the formats so far: http://www.princed.org/wiki/Game_Boy_format
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: PoP1 Game Boy (Color) format documentation

Post by Norbert »

Thanks for creating that article.
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PoP1 Game Boy (Color) format documentation

Post by David »

http://www.princed.org/wiki/Game_Boy_format wrote: There is an unused sprite group with map offset = 0x3B444, tiles offset = 0x3B523. It seems to show a pile of bones becoming a guard!?
Here is the picture:
skeleton_guard.png
skeleton_guard.png (790 Bytes) Viewed 6292 times
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: PoP1 Game Boy (Color) format documentation

Post by Norbert »

It also has a loose floor (with mod 1) that does not shake, which is used for the training, in room 7 only, which is the same in both training levels. On the tiles screen of legbop it's the loose floor with the "TR" marking on it. (For 'training'. The next release will instead mark it "NO SHAKE".) I've added the mod 1 to the wiki page.

Any chance a hex edit can make all mirrors jump-through-able?
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PoP1 Game Boy (Color) format documentation

Post by David »

Norbert wrote: December 3rd, 2022, 12:26 pm Any chance a hex edit can make all mirrors jump-through-able?
Unfortunately GBC PoP hardcodes a lot more things than DOS PoP.

So far I have come up with hacks which change which single mirror can the player jump through.

Rows are numbered from 0 to 2: 0=top, 1=middle, 2=bottom.
Columns are numbered from 0 (leftmost) to 9 (rightmost).
Rooms are numbered from 1 to 24.
Levels are numbered as they are displayed.

The spoilers contain the relevant parts of the disassembly.

Checking for the mirror

At 0x0EA4 write the room number.
At 0x0EA5 write the level number.
At 0x0ECB write (2 bytes, little-endian!) the result of 0xC0A0 + (row + 1) * 11 + (column + 1)
A simpler calculation with the same result: 0xC0AC + row * 11 + column.
At 0x0EEA write (column number + 1) * 2.
At 0x0EF3 write (column number + 1) * 2.

If row is not 0 (the top row):
At 0x0EC1 write: CD 40 3B 00
At 0x3B40 write: FA 12 C1 FE rr C9, where rr is the row. (0=top, 1=middle, 2=bottom)

Spoiler: show

Code: Select all

check level 4 room 4 (mirror):
**:0EA3: 01 04 04   LD BC,0404h
**:0EA6: CD 2E 3A   CALL 3A2Eh ; check level B room C
**:0EA9: C2 42 0F   JP NZ,0F42h ; not mirror
[...]
**:0EC1: FA 12 C1   LD A,(C112h) ; kid top row
**:0EC4: A7         AND A,A
**:0EC5: 20 7B      JR NZ,0F42h ; not mirror
**:0EC7: EA 1D C1   LD (C11Dh),A ; guard top row
**:0ECA: FA AF C0   LD A,(C0AFh) ; tile in current room, row=0,col=3
**:0ECD: FE 0D      CP A,0Dh ; mirror
**:0ECF: 20 71      JR NZ,0F42h ; not mirror
[...]
**:0EE6: FA 11 C1   LD A,(C111h) ; kid left col * 2
**:0EE9: D6 08      SUB A,08h ; column 4 (*2), calculate distance from the mirror
**:0EEB: FE 04      CP A,04h ; the mirror image appears if the kid is at most 2 (*2) tiles away from the mirror
**:0EED: 30 0D      JR NC,0EFCh ; ???
**:0EEF: EE FF      XOR A,FFh ; negate the distance from the mirror
**:0EF1: 3C         INC A
**:0EF2: C6 08      ADD A,08h
**:0EF4: 91         SUB A,C
**:0EF5: EA 1C C1   LD (C11Ch),A ; guard left col * 2 ; column position of mirror image

Breaking the mirror

At 0x0F12 write (column number + 2) * 2.

At 0x0F17 write (column number + 1) * 2.

At 0x0F22 write the tile position (row * 10 + column).
At 0x0F23 write the room number - 1.

At 0x0F2A write the tile position - 1.
At 0x0F2B write the room number - 1.

Spoiler: show

Code: Select all

**:0F0E: FA 11 C1   LD A,(C111h) ; kid left col * 2
**:0F11: FE 0A      CP A,0Ah
**:0F13: C2 D3 10   JP NZ,10D3h ; ???
jumped through mirror:
**:0F16: 3E 08      LD A,08h
**:0F18: EA 1C C1   LD (C11Ch),A ; guard left col * 2
**:0F1B: 21 01 40   LD HL,4001h
**:0F1E: CD 46 3A   CALL 3A46h ; set shadow sequence from HL and play anim?
room 4 tile 3 = put broken mirror:
**:0F21: 01 03 03   LD BC,0303h
**:0F24: 1E 05      LD E,05h ; broken mirror
**:0F26: CD BC 2E   CALL 2EBCh ; put tile type E at room B+1 tilepos C
room 4 tile 2 = erase mirror left:
**:0F29: 01 02 03   LD BC,0302h
**:0F2C: 1E 00      LD E,00h ; empty
**:0F2E: CD BC 2E   CALL 2EBCh ; put tile type E at room B+1 tilepos C

Adding the mirror when the exit opens

At 0x095A write the room from which the player enters the room of the mirror.
The mirror appears when the player leaves that room to the left, i.e. enters the mirror room from the right.
At 0x095B write the the level number.
At 0x096C write the tile position.
At 0x096D write the room number - 1.
At 0x0974 write the tile position - 1.
At 0x0975 write the room number - 1.

At 0x0962 write the room number - 1 of the exit door.
At 0x0963 write the tile position of the exit door.

Spoiler: show

Code: Select all

check level 4 room 11 (to the left is the mirror):
**:0959: 01 0B 04   LD BC,040Bh
**:095C: CD 2E 3A   CALL 3A2Eh ; check level B room C
**:095F: 20 1A      JR NZ,097Bh ; don't put mirror
room 24 tile 12 = the exit door:
**:0961: 01 0C 17   LD BC,170Ch
**:0964: CD 10 2F   CALL 2F10h ; get tile modifier at room B+1 tilepos C into A
**:0967: FE 40      CP A,40h ; modifier of closed exit
**:0969: 28 10      JR Z,097Bh ; don't put mirror
room 4 tile 3 = place the mirror:
**:096B: 01 03 03   LD BC,0303h
**:096E: 1E 0D      LD E,0Dh ; mirror
**:0970: CD BC 2E   CALL 2EBCh ; put tile type E at room B+1 tilepos C
room 4 tile 2 = place 'mirror left':
**:0973: 01 02 03   LD BC,0302h
**:0976: 1E 17      LD E,17h ; mirror left
**:0978: CD BC 2E   CALL 2EBCh ; put tile type E at room B+1 tilepos C
don't put mirror:
**:097B: CD CF 36   CALL 36CFh ; play kid anim?

Check with unknown purpose

At 0x28A8 write the room number.
At 0x28A9 write the level number.

If row is not 0 (the top row):
At 0x28AF write: CD 40 3B 00
At 0x3B40 write: FA 12 C1 FE rr C9, where rr is the row. (0=top, 1=middle, 2=bottom) (Same as one of the earlier hacks.)

Spoiler: show

Code: Select all

check level 4 room 4 (mirror):
**:28A7: 01 04 04   LD BC,0404h
**:28AA: CD 2E 3A   CALL 3A2Eh ; check level B room C
**:28AD: 20 0A      JR NZ,28B9h ; ???
**:28AF: FA 12 C1   LD A,(C112h) ; kid top row
**:28B2: A7         AND A,A
**:28B3: 20 04      JR NZ,28B9h ; ???

Known problems

If you change the row or the column, then the shadow appears just like the prince (or his mirror image), not as an outline.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: PoP1 Game Boy (Color) format documentation

Post by Norbert »

David wrote: December 23rd, 2022, 2:02 pm
Norbert wrote: December 3rd, 2022, 12:26 pm Any chance a hex edit can make all mirrors jump-through-able?
Unfortunately GBC PoP hardcodes a lot more things than DOS PoP.

So far I have come up with hacks which change which single mirror can the player jump through.

[...]
Wow, that is really complex.
Thanks for the feedback.
Post Reply