PoP1 SEGA Genesis format documentation

Discuss other PoP1 related things here.

Moderator: English Moderator Team

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » November 25th, 2016, 10:10 pm

David, do you have any thoughts on saving object customizations? In particular, the original ROMs do not seem to have any free space after the object groups. There are some areas with consecutive 00's, but not many and most are sprinkled with other values. For the EU version, the guards end at 0x3030, level doors at 0x4854, gates at 0x6720, and so on, and, for example, the space between level doors and gates appears to be occupied. The solution I have in mind is to disallow additional objects if their maximum has been reached. This would mean for, for example, gates, that their overall usage limit is 105. If 105 gates are used in the first level, all other levels can have 0 gates. I think this is a fairly good - especially safe - solution, but maybe you have a better alternative. I don't want to scour through the entire ROM to locate areas that could provide a handful of extra bytes. Also, I don't think there are any. There are places with dozens of 00's (similarly for FF's), but most are sprinkled with other bytes. Maybe (near) the very end of the ROM. I think limiting objects might be good, it might breed creativity and - perhaps more importantly - prevent modders from creating huge levels.

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » November 26th, 2016, 4:48 pm

Speaking of names of levels, the four extra levels of the EU version, how will we name them? (For the 12a and 12b combination of tower and jaffar, I'm simply using "twr+jaf" and similar things.) As David mentioned, screenshots of the levels can be found here.

My thoughts:

Level 6
-----
The player moves through the level using an S path, meeting the level exit door early on. It also forces the prince to close two gates. It has lots of gates-stuff in general. But "gates" wouldn't be suitable, it might be misleading, as another extra level (#12) has a section with lots of gates. Neither would "snake" as a reference to the level shape, because the player might think of the (PoP2) animal. So, maybe "back", as in, the player has to find a way back to the level door after completing the S path?

Level 7
-----
This has the potion that freezes (stops) time. I was thinking "freeze" for this one. The guards are frozen, the hazards are, and so on.

Level 12
-----
This has the potion that shakes the screen. I was thinking either "shake" or "rumble".

Level 15
-----
This level has lots of spikes. Also several chompers and deadly pits. Drop buttons that need to be avoided. Maybe "pits" for his one? Or "hazards" or "spikes". The level itself is shaped like a gun, kind of, but I asked in #guns and from what I could tell they didn't think it resembles any known gun.

David
The Prince of Persia
The Prince of Persia
Posts: 1493
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PoP1 SEGA Genesis format documentation

Post by David » November 26th, 2016, 8:42 pm

Norbert wrote:There are several other interesting differences I noticed. One is that after obtaining the LP in level 4, the prince cannot go back via the top rooms. He has to first kill the guard in the lower room, then obtain the LP, and then take the path to where the guard used to be. I didn't look into why the original path isn't possible, but I think the reason is that the dropped loose tile, that should keep open more than one gate, only keeps open the gate next to the LP. This could mean - again, just speculating - that the game only keeps the first gate open if a loose tile drops on a raise button.
I made a map of level 4 that shows the numbers of gates and buttons' event links:
level_4_triggers.png
It seems like the (leftmost) button that opens the gate to the LP (gate[0]) is just not linked to any other gate.
And so there is no way to keep gate[1] open.

I also found out that the button that opens the exit on level 4 is linked to *two* things.
The first link is 0xFFFF, which means the exit door.
The second link is 0xFFFE. It might be related to the mirror's appearance.

David
The Prince of Persia
The Prince of Persia
Posts: 1493
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PoP1 SEGA Genesis format documentation

Post by David » November 26th, 2016, 8:58 pm

I figured out where is the prince's starting position stored.
I added it to the docs: http://www.princed.org/wiki/SEGA_Genesis_format

Here is how I found it, to show a concrete example of how I find out things:
Spoiler: show
Where is the kid's starting position stored?
It can't come from the position of the level door, because level 1 and 7 have no level door at the starting place.

I've already found the coordinates of the starting room.
Is the position relative to that?

I changed level 1 to start in the top-left room.
Then, the display starts in the top-left room, but then it moves to the prince's room, moving one room at a time.
So the kid's starting position is absolute. Not relative to the starting room.

(By the way, the coordinates of the starting room don't have to be multiples of the room size.
You could play the existing levels with the room bounds at different places. Weird.)

What values should I look for?
start X = 0x07C0 = 1984 (assuming tile boundary)
start Y = 0x007F = 127 (assuming bottom)
(These values are for the USA version. The Europe version has a falling start on level 1.)

So let's search for 00 7F 07 C0.
(I put the Y value before X, because the other tables also do that.)
There is only one result:

Code: Select all

00020140: 007F 07C0 0800
00020146: 01FF 0F60 0000
0002014C: 023F 05A0 0800
00020152: 007F 05E0 0800
00020158: 023F 0800 0000
0002015E: 007F 06A0 0800
00020164: 00DE 0180 0000
0002016A: 007F 0380 0000
00020170: 02BF 06E0 0000
00020176: 013F 0300 0000
0002017C: 013F 00E0 0800
00020182: 053F 06E0 0800
00020188: 007F 0440 0800
I think I found it.
The three fields are Y, X, and direction.

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » November 26th, 2016, 11:02 pm

Now that you write about those directions, those are a giveaway.
Even guards have 0x0000 and 0x0800 values. :)
Are you also creating an editor of sorts?

[Edit: By the way, I think what you wrote about the gates (coordinate left edge, displayed right edge) also goes for guards and the prince?]

salvadorc17
Calif
Calif
Posts: 521
Joined: August 27th, 2011, 2:04 am

Re: PoP1 SEGA Genesis format documentation

Post by salvadorc17 » November 28th, 2016, 10:01 pm

David wrote: I made a map of level 4 that shows the numbers of gates and buttons' event links:

It seems like the (leftmost) button that opens the gate to the LP (gate[0]) is just not linked to any other gate.
And so there is no way to keep gate[1] open.

I also found out that the button that opens the exit on level 4 is linked to *two* things.
The first link is 0xFFFF, which means the exit door.
The second link is 0xFFFE. It might be related to the mirror's appearance.
The map is really tiny, havent played so much Sega version, but does levels are smaller than Dos/Snes versions??

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » November 29th, 2016, 2:31 am

salvadorc17 wrote:The map is really tiny, havent played so much Sega version, but does levels are smaller than Dos/Snes versions??
The image only shows part of the level.

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » November 30th, 2016, 12:13 am

Here is a bit more information about the format:

Code: Select all

               US               EU
Starting Level 0x1DFA7 (00..0C) 0x4E2A7 (00..10)
Starting HP    0x1DFAF          0x4E2C1
Starting Time  0x1DF9D/0x1DF9E  0x4E29D/0x4E29E
The bytes for the starting time are 03 4B for US, and 02 BF for EU.

First I came up with:
- US: number of times (1093/60) minutes left + number of times (1/14) minutes left
- EU: number of times (1322.5/60) minutes left + number of times (1/12) minutes left

Then I realized the US (NTSC) framerate 59.9227510135505 is a higher value than the EU (PAL) framerate 49.7014601199484.
And 703 (02 BF) x 1.205653735 = 847.574575705, which is indeed close to 843 (03 4B)
Probably some rounding happening there.

Close, but now I'm tired of looking into it.
At least I've helped a little. :)

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » December 2nd, 2016, 4:11 pm

Tested with the EU version, time values above 809 show letters for the minutes left instead of numbers.

...|66|67|68|69|Mi|nu|te| R|em|ai|ni|ng| M|in|ut|es| R|em|ai|ni|ng|...

This seems to indicate the time value is a pointer to a location with strings or images.

David
The Prince of Persia
The Prince of Persia
Posts: 1493
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PoP1 SEGA Genesis format documentation

Post by David » December 3rd, 2016, 10:34 am

Norbert wrote:Tested with the EU version, time values above 809 show letters for the minutes left instead of numbers.

...|66|67|68|69|Mi|nu|te| R|em|ai|ni|ng| M|in|ut|es| R|em|ai|ni|ng|...

This seems to indicate the time value is a pointer to a location with strings or images.
I made a small program that can export texts from the game.
pop_genesis_texts.zip
(492 Bytes) Downloaded 7 times
The part with the time messages is:

Code: Select all

US: 0x00026BDE:  1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960Minute Remaining Minutes RemainingLevel1 2 3 4 5 6 7 8 9 1011121314151617181920Password
EU: 0x000573B4:  1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869Minute Remaining Minutes RemainingLevel1 2 3 4 5 6 7 8 9 1011121314151617181920Password
Looks like the programmers were lazy to write a generic integer-to-string conversion routine? :)
Not just that, but there are separate tables for minutes (right-aligned) and levels (left-aligned).
And it seems they were planning for 20 levels?
Norbert wrote: Starting Time 0x1DF9D/0x1DF9E 0x4E29D/0x4E29E
The bytes for the starting time are 03 4B for US, and 02 BF for EU.
It makes a lot more sense if you look at the whole 32-bit numbers:
US: 0x0001DF9C: 0x00034BBF = 215999 = 60*60*60 - 1
EU: 0x0004E29C: 0x0002BF1F = 179999 = 60*60*50 - 1
The first 60 is the number of minutes at start, the second 60 is the number of seconds in a minute, and the last 50 or 60 is the framerate.
So you were right that it's bound to the framerate.

How did you find these offsets, by the way?

Here is the disassembly of that area:

Code: Select all

(US version)
0001DF92   33fc 0000 00ff 1d92              MOVE.W    #0x0000    , A_00ff1d92 ; ???
0001DF9A   23fc 0003 4bbf 00ff 0d5c         MOVE      #0x00034bbf, A_00ff0d5c ; Time
0001DFA4   33fc 0000 00ff 0f48              MOVE.W    #0x0000    , A_00ff0f48 ; Level
0001DFAC   33fc 0003 00ff 1eb0              MOVE.W    #0x0003    , A_00ff1eb0 ; HP
0001DFB4   4e75                             RTS

(EU version)
0004E292   33fc 0000 00ff 1e2c              MOVE.W    #0x0000    , A_00ff1e2c ; ???
0004E29A   23fc 0002 bf1f 00ff 0d5c         MOVE      #0x0002bf1f, A_00ff0d5c ; Time
0004E2A4   33fc 0000 00ff 0fe0              MOVE.W    #0x0000    , A_00ff0fe0 ; Level
0004E2AC   33f9 00ff 0fe0 00ff 0fe2         MOVE.W    A_00ff0fe0 , A_00ff0fe2 ; Level is copied (why?)
0004E2B6   33fc 003e 00ff 3eae              MOVE.W    #0x003e    , A_00ff3eae ; ???
0004E2BE   33fc 0003 00ff 1f66              MOVE.W    #0x0003    , A_00ff1f66 ; HP
0004E2C6   4e75                             RTS
Looks like there are some other settings around there as well.
That 0x003e seems to be related to how long is the level number shown.
And if I change the first 0x0000 then the game will hang when I start the first level. The pause menu will still work, though.

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » December 3rd, 2016, 3:04 pm

David wrote:I made a small program that can export texts from the game.
It's unfortunate you used variable names such as $a, $p, $f, $x, $sa, $ea and $la.
In pseudo-code, it's doing something with 0x7A1 and a static string?
David wrote:It makes a lot more sense if you look at the whole 32-bit numbers: [...]
Okay.
David wrote:How did you find these offsets, by the way?
Changed random bytes, and when I'd found the byte to modify hit points I changed some more random bytes in its vicinity.
Norbert wrote:[...], the original ROMs do not seem to have any free space [...] The solution I have in mind is to disallow additional objects if their maximum has been reached. This would mean for, for example, gates, that their overall usage limit is 105.
This is indeed what I'm going to do, for both the rooms (object/graphics combinations) and the guard/object attributes.
I'm adding a screen that shows usage numbers and totals, that'll show up if save is requested but one or more totals exceed available space.

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » December 3rd, 2016, 6:28 pm

David wrote:US: 0x0001DF9C: 0x00034BBF = 215999 = 60*60*60 - 1
EU: 0x0004E29C: 0x0002BF1F = 179999 = 60*60*50 - 1
The first 60 is the number of minutes at start, the second 60 is the number of seconds in a minute, and the last 50 or 60 is the framerate.
Even more accurate:
US: 0x0001DF9C: 0x00034BBF = 215999 = 3600*60 - 1
EU: 0x0004E29C: 0x0002BF1F = 179999 = 3600*50 - 1
The 3600 is the number of seconds at start, and the last 50 or 60 is the framerate.
Since it's not storing a multiplication of the number of minutes at the start times the - theoretically variable/modifiable - number of seconds in a minute. I know you understand (and meant) that, but just for people who're interested in the material and are reading along.

David
The Prince of Persia
The Prince of Persia
Posts: 1493
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PoP1 SEGA Genesis format documentation

Post by David » December 4th, 2016, 3:42 pm

Norbert wrote:
David wrote:I made a small program that can export texts from the game.
It's unfortunate you used variable names such as $a, $p, $f, $x, $sa, $ea and $la.
In pseudo-code, it's doing something with 0x7A1 and a static string?
It goes through the whole ROM image, reading it as a sequence of 2-byte integers.
If the current 2-byte integer is between 0x7A1 and 0x7A1+strlen($abc) then it can be the tile index of a character, and the program outputs that character.

The "static string" ($abc) is the list of characters in the game's font, and 0x7A1 is the tile index of the first character.
That is, 0x7A1=" ", 0x7A2="0", 0x7A3="1", and so on.

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » December 4th, 2016, 9:45 pm

While working on the level editor, I'm frequently playtesting. The starting animation, in the EU version, of the prince rolling downhill, I pass that quickly by holding down the backquote key. It's funny, because of the sped up sound it appears as if the prince is rolling down some kind of amusement park attraction, expression enjoyment by exclaiming "Whee!". :)

User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 3139
Joined: April 9th, 2009, 10:58 pm
Contact:

Re: PoP1 SEGA Genesis format documentation

Post by Norbert » December 5th, 2016, 1:12 am

Norbert wrote:[Edit: By the way, I think what you wrote about the gates (coordinate left edge, displayed right edge) also goes for guards and the prince?]
[I've edited this post a bunch of times.]
It does not, my bad.
There are two exceptions though, namely the X-coordinate of the prince in level 1(EU only) and the Y-coordinate of the prince in level 7(US)/9(EU). The game moves the prince (an additional) respectively +12 (in level 1) and +31 (level 7/9) pixels.
Last edited by Norbert on December 6th, 2016, 9:24 pm, edited 2 times in total.

Post Reply