CusPop TODO list

Discussions about all other tools (CusPop, SAV/HOF editors) and hex editing.
User avatar
Zaknafein
Sheikh
Sheikh
Posts: 48
Joined: May 1st, 2014, 11:40 pm
Location: Menorca

Re: CusPop TODO list

Post by Zaknafein »

Is there any way to make a mod/level/room/event which disables some key? For example, that disable shift that allow you to grab/walk, disable up/down/left/right key, etc. More restrictive levels will make you to think other ways to solve it.
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: CusPop TODO list

Post by David »

You need to hex-edit PRINCE.EXE. Codes are for v1.0.

Disabling a key in the whole game:

search for:
80 3E D4 28 00 : numpad 8 / up
80 3E D3 28 00 : numpad 7 / home (twice)
80 3E D5 28 00 : numpad 9 / page up (twice)
80 3E D8 28 00 : numpad 5 (down)
80 3E DC 28 00 : numpad 2 / down
80 3E D7 28 00 : numpad 4 / left
80 3E D9 28 00 : numpad 6 / right
replace -> 80 3E 8C 28 00

24 03 28 06 C6 4C : shift
replace 03 -> 00

Note: This is for keyboard control only. It does not disable anything about the joystick, and disabling shift does not affect cheats with shift.

About the "level/room/event" part...
Disabling a key if a condition is true:

search for:
80 3E A8 42 00 7C 1A : left
80 3E 88 40 00 7C 1A : right
80 3E 22 43 00 7C 1A : up
80 3E 9A 40 00 7C 1A : down
80 3E 06 46 00 7C 1A : shift (does not work)

replace -> 80 3E (variable) (constant) (condition) 1A
The key will be disabled if the values of the variable and the constant meet the condition.
Some possible values for (variable): 9E 0F = current level, 61 43 = kid's room, ...
(constant) is one byte, it's the value you want to compare with.
Some possible values for (condition): 74 = equal, 75 = not equal, 7C = var less than const, 7F = var greater than const, ...

Note: With this method, left/right/up can be disabled only for: turning, stepping, swordfighting, jumping up, run-jumping.
They remain enabled for: running, jumping, run-turning.
This is due to the way the game checks the keys.
(There are two sets of variables, and this hack prevents copying from one to another.)
User avatar
Zaknafein
Sheikh
Sheikh
Posts: 48
Joined: May 1st, 2014, 11:40 pm
Location: Menorca

Re: CusPop TODO list

Post by Zaknafein »

Thanks! This is very useful :)
I'm not familiar with hex editing, but i'll try to change some things. Just a question.

How do you do to find what code you have to change and for which one you have to replace it? Maybe do you have source code of PoP1 and making changes of that let you see what changes opening it with hex editing? Reverse engineering? :roll:
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: CusPop TODO list

Post by David »

David wrote:How do you do to find what code you have to change and for which one you have to replace it? [...] Reverse engineering?
Yes, I did some reverse engineering in the past years:
* I made a disassembly of PoP1. You can download it here: viewtopic.php?p=15321#p15321
* From the disassembly I made SDLPoP, an open-source version of PoP: viewtopic.php?f=69&t=3512
fatguard
Scholar Scribe
Scholar Scribe
Posts: 2
Joined: July 31st, 2013, 11:53 am

Re: CusPop TODO list

Post by fatguard »

Question. When you enter Jaffars room in the original game his musical theme plays and he stands there for a short time before raising his sword. I think this is triggered by leaving room 3 in Level 13 to the right as long as the Level door is not opened yet. (it even happens when there is no room to the right of room 3 and you die by moving there)
Can this Event be placed in a different Level? And can the direction of leaving the room for this to be triggered be changed?

And a general question. When a Level does not show its Level number, when you die you get sent back to the title screen after a while. Is it known why this happens? For example this happens in Level 14, but when showing its Level number is enabled you can die there and restart the Level normally without being sent back to the title screen after a while. Might this be related to copy protection in Level 15 (potions Level) because that doesn't also show its name and I think you are supposed to be sent back to the title if you die there?
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: CusPop TODO list

Post by David »

fatguard wrote: When you enter Jaffars room in the original game his musical theme plays and he stands there for a short time before raising his sword. I think this is triggered by leaving room 3 in Level 13 to the right as long as the Level door is not opened yet.
That is correct.
(We have a document about special events.)
fatguard wrote: Can this Event be placed in a different Level?
The relevant part in the disassembly:

Code: Select all

seg002:06AE                      ; void __pascal far meet_Jaffar()
seg002:06AE                      meet_Jaffar     proc far
seg002:06AE 83 3E 9E 0F 0D                       cmp     current_level, 13 ; Special event: play music
seg002:06B3 75 1D                                jnz     locret_3D52
seg002:06B5 83 3E 9C 40 00                       cmp     leveldoor_open?, 0
seg002:06BA 75 16                                jnz     locret_3D52
seg002:06BC 80 3E 2B 3D 03                       cmp     char_room, 3
seg002:06C1 75 0F                                jnz     locret_3D52
seg002:06C3 B8 1D 00                             mov     ax, sound_29_meet_Jaffar
seg002:06C6 50                                   push    ax              ; sound_id
seg002:06C7 9A C5 12 00 00                       call    play_sound
seg002:06CC C7 06 34 3D 1C 00                    mov     guard_notice_timer, 28 ; Special event: Jaffar waits a bit (28/12=2.33 seconds)
seg002:06D2                      locret_3D52:
seg002:06D2 CB                                   retf
seg002:06D2                      meet_Jaffar     endp
Search: 83 3E 9E 0F 0D 75 1D 83 3E 9C 40 00 75 16 80 3E 2B 3D 03
Replace: 0D with the level number, 03 with the room number.
fatguard wrote: And can the direction of leaving the room for this to be triggered be changed?
fatguard wrote: When a Level does not show its Level number, when you die you get sent back to the title screen after a while. Is it known why this happens? For example this happens in Level 14, but when showing its Level number is enabled you can die there and restart the Level normally without being sent back to the title screen after a while.
I tried this and it seems you're right.
I knew about the bug, but I didn't know it disappears if I change "First level that does not show its number" in CusPop.

When I restart after dying, space will not show the remaining time.
If I press Esc and then space, then the time will appear, and the game won't go to the title screen.

I think I figured out why does this happen.
(Variable and function names refer to the SDLPoP source.)
The game has two variables related to timing of status texts, called text_time_total and text_time_remaining.
text_time_remaining is decreased every frame if it is nonzero. (draw_game_frame())
If it reaches 1, then the text is cleared. If it's the "press button" message, then the game is restarted.
The game uses text_time_total to check what text is shown currently.
The "Press Button to Continue" sets them to 288.
When you restart the level, show_level() resets them to 24, but *only* if the level number is shown.
The variables are cleared by erase_bottom_text(1). It is called, among others, when you un-pause the game. (do_paused())
The remaining time can be shown only if text_time_remaining is 0. (show_time())
fatguard wrote: Might this be related to copy protection in Level 15 (potions Level) because that doesn't also show its name and I think you are supposed to be sent back to the title if you die there?
No, I think this is a bug. (On level 15, you can't restart the level, Ctrl-A is disabled.)
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: CusPop TODO list

Post by Norbert »

David wrote:Search: 83 3E 9E 0F 0D 75 1D 83 3E 9C 40 00 75 16 80 3E 2B 3D 03
Replace: 0D with the level number, 03 with the room number.
Using this as a test case for CusAsm.

Input, in the "Hex:" textarea (note the curly brackets):

83 3E 9E 0F {0D} 75 1D 83 3E 9C 40 00 75 16 80 3E 2B 3D {03}

Its XML output:

Code: Select all

<hack name="Hack name here">
	<offset file="p0" value="0x3f2e"/>
	<offset file="u0" value="0x55de"/>

	<check codes="83 3e 9e 0f"/>
	<read default="0d" name="name here" type=""/>
	<check codes="75 1d 83 3e 9c 40 00 75 16 80 3e 2b 3d"/>
	<read default="03" name="name here" type=""/>
</hack>
It seems it can only find offsets for the packed and unpacked 1.0 versions.
Still useful, but any thoughts on why the offsets for 1.3 and 1.4 do not show up?
I guess maybe those versions store/recall the level and room number differently.
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: CusPop TODO list

Post by David »

It works if I enter the corresponding disassembly:
(Copied from beye (formerly BIEW), with some manual tweaks.)

Code: Select all

000055DE 833E9E0F0D                     cmp (w)   [0F9E],0D
000055E3 751D                           jne       file:00005602
000055E5 833E9C4000                     cmp (w)   [409C],00
000055EA 7516                           jne       file:00005602
000055EC 803E2B3D03                     cmp       [3D2B],03
The hex output is:

Code: Select all

83 3e .. .. {0d} 75 1d 83 3e .. .. .. 75 16 80 3e .. .. {03}
Note that the memory addresses (like 0F9E) are replaced with ".. ..".
Norbert wrote: Still useful, but any thoughts on why the offsets for 1.3 and 1.4 do not show up?
I guess maybe those versions store/recall the level and room number differently.
It's because the addresses of global variables are different in each version.
See here and here.

There is some code in CusAsm that detects small differences like these, but it seems that it is used only with the Asm input.
(It's in GetOffsetProb(), called by FullSearch().)

Alternatively, if you don't want to paste an actual disassembly, you can fake it.
Paste this into the Asm input:

Code: Select all

0000 833E9E0F0D751D833E9C40007516803E2B3D03 dummy
Note that you need a dummy offset and a dummy opcode.
And there must be no spaces between the bytes.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: CusPop TODO list

Post by Norbert »

I found a tiny bug in CusPop.

CusPop currently says:
-----
Starting minutes left: 60
Starting seconds left: 59.92
-----

With the accompanying text:
-----
Remaining seconds to be added to the remaining minutes.
-----

Either 60 should be changed to 59 (and the underlying code should +1 the user input), or the accompanying text should say something like: "Starting seconds are what remains of the highest starting minute."

[Edit: Hm, the most user-friendly implementation might be to keep 60, and change 59.92 to 0. Then, change the underlying code to do magic. Complicated. Maybe just leave the whole thing alone.]
User avatar
doppelganger
Vizier
Vizier
Posts: 119
Joined: April 24th, 2015, 9:04 am
Location: India

Re: CusPop TODO list

Post by doppelganger »

It's funny. The original game gives you 61 minutes as opposed to 60 minutes.
I don't think it's CusPop's fault.
Doppelgänger
Hmm.. These mortals know about me.. :evil:

Download 'Hell of A Palace' now from Popot!
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: CusPop TODO list

Post by Norbert »

doppelganger wrote:It's funny. The original game gives you 61 minutes as opposed to 60 minutes.
I don't think it's CusPop's fault.
No, it doesn't, the game gives you 60 minutes. See my explanation in my previous post.
The seconds are the number of seconds that are left from the highest minute.
In other words, it starts with 60 minutes, and of minute 60 there are still 59.92 seconds left.
Those 59.92 seconds are: ((60 seconds x 12 ticks (fps)) - 1 tick) / 12 = 59.916666667 = about 59.92.
User avatar
doppelganger
Vizier
Vizier
Posts: 119
Joined: April 24th, 2015, 9:04 am
Location: India

Re: CusPop TODO list

Post by doppelganger »

Norbert wrote:
doppelganger wrote:It's funny. The original game gives you 61 minutes as opposed to 60 minutes.
I don't think it's CusPop's fault.
No, it doesn't, the game gives you 60 minutes. See my explanation in my previous post.
The seconds are the number of seconds that are left from the highest minute.
In other words, it starts with 60 minutes, and of minute 60 there are still 59.92 seconds left.
Those 59.92 seconds are: ((60 seconds x 12 ticks (fps)) - 1 tick) / 12 = 59.916666667 = about 59.92.
Oops.. I thought the game shows a '1 minute remaining' message and THEN start counting the seconds...
I checked it again. The game directly goes to counting the seconds after the '2 minutes remaining'.
My bad. I'm sorry. The game doesn't give you 61 minutes... I apologize.
Doppelgänger
Hmm.. These mortals know about me.. :evil:

Download 'Hell of A Palace' now from Popot!
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: CusPop TODO list

Post by Norbert »

Don't worry about it, doppelganger.
The game itself is a bit confusing when it comes to the remaining time, because it rounds up to full minutes.
I did the same check as you did, to check what happened between 2 minutes remaining and then the seconds showing up. :)
User avatar
doppelganger
Vizier
Vizier
Posts: 119
Joined: April 24th, 2015, 9:04 am
Location: India

Re: CusPop TODO list

Post by doppelganger »

I could swear I saw a '1 minute remaining' message somewhere... maybe in a port of the game?
Doppelgänger
Hmm.. These mortals know about me.. :evil:

Download 'Hell of A Palace' now from Popot!
Dark77
Wise Scribe
Wise Scribe
Posts: 296
Joined: October 26th, 2010, 7:10 pm
Location: Poland

Re: CusPop TODO list

Post by Dark77 »

The "level 1 crouching start" and "level 1 music" settings don't work for me. Unless I misunderstood the way they work. When I set any other level than level 1, it only eliminates the crouching start and music from level 1, but the music and the crouching don't appear in the level I set.
Post Reply