CusPop TODO list
Re: CusPop TODO list
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.
Re: CusPop TODO list
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.)
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.)
Re: CusPop TODO list
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?
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?
Re: CusPop TODO list
Yes, I did some reverse engineering in the past years: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?
* 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
Re: CusPop TODO list
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?
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?
Re: CusPop TODO list
That is correct.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.
(We have a document about special events.)
The relevant part in the disassembly:fatguard wrote: Can this Event be placed in a different Level?
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
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?
I tried this and it seems you're right.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 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())
No, I think this is a bug. (On level 15, you can't restart the level, Ctrl-A is disabled.)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?
Re: CusPop TODO list
Using this as a test case for CusAsm.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.
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>
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.
Re: CusPop TODO list
It works if I enter the corresponding disassembly:
(Copied from beye (formerly BIEW), with some manual tweaks.)
The hex output is:
Note that the memory addresses (like 0F9E) are replaced with ".. ..".
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:
Note that you need a dummy offset and a dummy opcode.
And there must be no spaces between the bytes.
(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
Code: Select all
83 3e .. .. {0d} 75 1d 83 3e .. .. .. 75 16 80 3e .. .. {03}
It's because the addresses of global variables are different in each version.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.
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
And there must be no spaces between the bytes.
Re: CusPop TODO list
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.]
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.]
- doppelganger
- Vizier
- Posts: 119
- Joined: April 24th, 2015, 9:04 am
- Location: India
Re: CusPop TODO list
It's funny. The original game gives you 61 minutes as opposed to 60 minutes.
I don't think it's CusPop's fault.
I don't think it's CusPop's fault.
Re: CusPop TODO list
No, it doesn't, the game gives you 60 minutes. See my explanation in my previous post.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.
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.
- doppelganger
- Vizier
- Posts: 119
- Joined: April 24th, 2015, 9:04 am
- Location: India
Re: CusPop TODO list
Oops.. I thought the game shows a '1 minute remaining' message and THEN start counting the seconds...Norbert wrote:No, it doesn't, the game gives you 60 minutes. See my explanation in my previous post.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.
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.
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.
Re: CusPop TODO list
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.
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.
- doppelganger
- Vizier
- Posts: 119
- Joined: April 24th, 2015, 9:04 am
- Location: India
Re: CusPop TODO list
I could swear I saw a '1 minute remaining' message somewhere... maybe in a port of the game?
Re: CusPop TODO list
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.