Um... by "Apple", did you mean Apple II or Macintosh?David wrote:Amiga graphics is identical to the DOS, so why?segra wrote:- Apple / Amiga data support?
Apple: It makes sense, but is it worth?
SDLPoP; David's open-source port of PoP
Re: SDLPoP; David's open-source port of PoP (pre-release)
Apple 2, I havn't seen the Mac version... come to think of it though, SNES graphics would be pretty cool tho

Re: SDLPoP; David's open-source port of PoP (pre-release)
Have you tested the game yet?David wrote: So is it time to release 1.15 officially?
Maybe I play it through to see if there are no showstopper bugs like that one with the exit door on level 4.
I did a playthrough and had no problems.
The way the quicksave system handles the remaining time is one remaining issue though, that we will probably want to fix in 1.16.
Simply restoring the quicksaved time when quickloading is not ideal, because getting the best possible time then becomes very reliant on overuse of the quicksave system (this is probably not a lot of fun).
A flat penalty for quickloading might be a solution: i.e. quickloading always jumps to, for example, one minute later than the quicksaved time. (Except perhaps when the remaining time is already very low (say, below 5 minutes or so) because then the penalty becomes rather harsh; and speedrunners are unlikely to ever reach such a threshold anyway.)
The sequence table deobfuscation is over halfway done now. It may be good to have a human readable seqtable to it will be easier to fix some annoyances (like the quirk that makes trick 25 necessary). Sadly, inserting new stuff into the seqtable might get a bit tricky, because the table offsets will get messed up by doing this. Some C macros may be of some help, although this will probably not be as convenient as the original assembler code.
Edit: I finished the deobfuscation of the sequence table. I moved it into its own file because it became quite large (see attachment).
Here is the pull request on GitHub.
- Attachments
-
- seqtbl.c
- (51.38 KiB) Downloaded 263 times
Re: SDLPoP; David's open-source port of PoP (pre-release)
I added some optional fixes for a couple of gameplay quirks (pull request):
Fix for falling off the ledge when turning around and jumping up after climbing two floors:
See Trick 25. With this fix the kid automatically moves one pixel backward before jumping up (only when the kid is exactly three pixels from the edge). The trick still works but it is unnecessary now.
In seg005.c, jump_up():
Fix "teleporting" four pixels further than necessary when climbing up from firm ground while not in front of a wall
Removes an edge distance check. The game checks whether the distance to the nearest edge below is <4 pixels, but this is only relevant if there's a wall right in front of the kid (because the kid might bump into the wall then) and the game already checks for the presence of a wall: edge_type != 1
In seg005.c, grab_up_with_floor_behind():
Fix being able to survive lethal falls by jumping on top of a guard
See Trick 11.
In seg003.c, bump_into_opponent():
Fix triggering loose floors by bumping into the wall above
See Trick 18. The fix modifies the sequence table: in the "bumpwall" sequence, I changed actions_5_bumped to actions_3_in_midair.
Fix for falling off the ledge when turning around and jumping up after climbing two floors:
See Trick 25. With this fix the kid automatically moves one pixel backward before jumping up (only when the kid is exactly three pixels from the edge). The trick still works but it is unnecessary now.
In seg005.c, jump_up():
Code: Select all
distance = get_edge_distance();
if (distance < 4 && edge_type == 1) {
Char.x = char_dx_forward(distance - 3);
}
#ifdef FIX_JUMP_DISTANCE_AT_EDGE
// When climbing up two floors, turning around and jumping upward, the kid falls down.
// This fix makes the workaround of Trick 25 unnecessary.
if (distance == 3 && edge_type == 0) {
Char.x = char_dx_forward(-1);
}
#endif
Removes an edge distance check. The game checks whether the distance to the nearest edge below is <4 pixels, but this is only relevant if there's a wall right in front of the kid (because the kid might bump into the wall then) and the game already checks for the presence of a wall: edge_type != 1
In seg005.c, grab_up_with_floor_behind():
Code: Select all
distance = distance_to_edge_weight();
#ifdef FIX_EDGE_DISTANCE_CHECK_WHEN_CLIMBING
// When climbing to a higher floor, the game unnecessarily checks how far away the edge below is;
// This contributes to sometimes "teleporting" considerable distances when climbing from firm ground
#define JUMP_STRAIGHT_CONDITION distance < 4 /* && get_edge_distance() < 4 */ && edge_type != 1
#else
#define JUMP_STRAIGHT_CONDITION distance < 4 && get_edge_distance() < 4 && edge_type != 1
#endif
if (JUMP_STRAIGHT_CONDITION) {
Char.x = char_dx_forward(distance);
seqtbl_offset_char(seq_8_jump_up_and_grab_straight); // jump up and grab (when?)
} else {
Char.x = char_dx_forward(distance - 4);
seqtbl_offset_char(seq_24_jump_up_and_grab_forward); // jump up and grab (with floor behind)
}
See Trick 11.
In seg003.c, bump_into_opponent():
Code: Select all
if (ABS(distance) <= 15) {
#ifdef FIX_PAINLESS_FALL_ON_GUARD
if (Char.fall_y >= 33) return; // don't bump; dead
else if (Char.fall_y >= 22) { // medium land
take_hp(1);
play_sound(sound_16_medium_land);
}
#endif
Char.y = y_land[Char.curr_row + 1];
Char.fall_y = 0;
seqtbl_offset_char(seq_47_bump); // bump into opponent
play_seq();
}
See Trick 18. The fix modifies the sequence table: in the "bumpwall" sequence, I changed actions_5_bumped to actions_3_in_midair.
Re: SDLPoP; David's open-source port of PoP (pre-release)
Man, you've really been an active contributor to the SDLPoP project, Falcury. Nice.
Funny how you suddenly appeared with contributions, even though you already had a forum account.
Funny how you suddenly appeared with contributions, even though you already had a forum account.

Re: SDLPoP; David's open-source port of PoP (pre-release)
I also played it through and found no problems either.Falcury wrote: Have you tested the game yet?
I did a playthrough and had no problems.
Ideally, seqtbl[] (and jump commands) would contain pointers into seqtbl_offsets[].Falcury wrote: Sadly, inserting new stuff into the seqtable might get a bit tricky, because the table offsets will get messed up by doing this. Some C macros may be of some help, although this will probably not be as convenient as the original assembler code.
But I'm afraid that requires assembly, or dirty macro tricks. (*)
(I wonder how was this solved in the DOS port?)
By the way, seqtbl_offsets[] in seg005.c should also be moved to the new file.
(*) A dirty macro trick would be to cut seqtbl[] where you would put a label, like this:
(I did not try this yet!)
Code: Select all
#define LABEL(label) }; const byte label[] = {
#define OFFSET(label) (&label-&seqtbl+SEQTBL_BASE) // or: (&label-SEQTBL_0)
const word seqtbl_offsets[] = {
0x0000, OFFSET(startrun), OFFSET(stand), ......
......
const byte seqtbl[] = {
LABEL(running)
SEQ_ACTION, actions_1_run_jump, SEQ_JMP, DW(OFFSET(running_frame_7)), // goto running: frame 7
LABEL(startrun)
SEQ_ACTION, actions_1_run_jump, frame_1_start_run,
......
And then hope that the parts remain in order after compiling and linking.

Although that might not even be required if every label is preceded by a jump.
(But that's not the case with "goto running: frame 7", and there are more!)
Thank you!Falcury wrote: Edit: I finished the deobfuscation of the sequence table.
Re: SDLPoP; David's open-source port of PoP (pre-release)
Thanks! Well, I only recently developed my coding skills to the extent where I could do something useful... It also helps that I finally have some free time to spare lately. It's a very nice project to work on (so many ideas!)Norbert wrote:Man, you've really been an active contributor to the SDLPoP project, Falcury. Nice.
Funny how you suddenly appeared with contributions, even though you already had a forum account.
Yes, that makes sense!David wrote:By the way, seqtbl_offsets[] in seg005.c should also be moved to the new file.
That is absolutely brilliant. I shall try this out!David wrote:A dirty macro trick would be to cut seqtbl[] where you would put a label, like this:Code: Select all
#define LABEL(label) }; const byte label[] = {
Edit:
Apparently, the gcc compiler adds some padding bytes between subsequent declarations. However, forcing the compiler to use an alignment of 1 byte seems to work for me:
Code: Select all
#define LABEL(label) }; const byte label[] __attribute__ ((aligned(1))) = {
Progress so far (pull request):
We could perhaps leave the enum in place for global access to the values, but in seqtbl.c add macros without the "SEQ_" prefix that take parameters.David wrote:(And maybe change the SEQ_JMP, SEQ_ACTION etc. macros to take parameters? But we need the values in play_seq().)
Re: SDLPoP; David's open-source port of PoP (pre-release)
Yes, I get errors like this:Falcury wrote: The eventual memory addresses are only available at runtime, and C won't let me do something like the offsetof(type, member) macro because apparently that only works for structs...
Code: Select all
pointer_into_array.c:18: error: initializer element is not computable at load time
If I put only seqptr inside a function, then that part compiles, but jumps still can't be used in seqtbl.
Interestingly, something similar works with labels: https://gcc.gnu.org/onlinedocs/gcc/Labe ... alues.html (the last example)
Re: SDLPoP; David's open-source port of PoP (pre-release)
I gave up on the seqtbl labels... couldn't get it to work. Ended up doing a gaint macro chain, so inserting and deleting is at least possible now (are there better solutions?)gameplay fixes:
Temporarily standing on thin air when standing up on a falling loose tile:
Added a check in check_action() (seg006.c) whether the kid is actually standing on a floor tile during the standing up animation. Side effect: it became easier to fall off ledges by standing up. I think this is because the kid gets moved a little bit forward (and then back again) during the animation - after reducing this by one pixel in the sequence table however, it is much less an issue.
Being able to press buttons through closed gates (Trick 1):
Adds a call to determine_col() in check_press() (seg006.c) to check that the kid is actually on the tile's column (and not bumped backward!) before the tile is pressed.
Being able to grab ledges two stories down by bumping into a wall first:
Reduces the max falling speed cutoff for grabbing to <30 in check_grab() (seg006.c).
The trick can be done with a standing jump slightly more than two tiles from a wall. The kid can than grab the ledge with a Char.fall_y of 30 (the game's original cutoff is <32; but under normal conditions the falling speed for "legal" grabs always seems to be 27 or less).
Blood appearing on chompers when a skeleton is chomped:
Before adding blood, check that the victim is not a skeleton in chomped() (seg004.c)
Controls not being released during the drinking animation, causing unintended movement:
During the drinking animation, use release_arrows() in control() (seg005.c).
Add a way to crouch after climbing up (instead of climbing down again) by pressing down + forward:
It's annoying not to be able to crouch-hop under gates that are near ledges (because when you are too close to a gate and forward is pressed, you will safe_step() instead of run + slide).
To execute this maneuver, press down and forward at exactly the same time.
Here is an experimental build. Hopefully this does not introduce too many strange new bugs.
Edit: I added some new Temporarily standing on thin air when standing up on a falling loose tile:
Added a check in check_action() (seg006.c) whether the kid is actually standing on a floor tile during the standing up animation. Side effect: it became easier to fall off ledges by standing up. I think this is because the kid gets moved a little bit forward (and then back again) during the animation - after reducing this by one pixel in the sequence table however, it is much less an issue.
Being able to press buttons through closed gates (Trick 1):
Adds a call to determine_col() in check_press() (seg006.c) to check that the kid is actually on the tile's column (and not bumped backward!) before the tile is pressed.
Being able to grab ledges two stories down by bumping into a wall first:
Reduces the max falling speed cutoff for grabbing to <30 in check_grab() (seg006.c).
The trick can be done with a standing jump slightly more than two tiles from a wall. The kid can than grab the ledge with a Char.fall_y of 30 (the game's original cutoff is <32; but under normal conditions the falling speed for "legal" grabs always seems to be 27 or less).
Blood appearing on chompers when a skeleton is chomped:
Before adding blood, check that the victim is not a skeleton in chomped() (seg004.c)
Controls not being released during the drinking animation, causing unintended movement:
During the drinking animation, use release_arrows() in control() (seg005.c).
Add a way to crouch after climbing up (instead of climbing down again) by pressing down + forward:
It's annoying not to be able to crouch-hop under gates that are near ledges (because when you are too close to a gate and forward is pressed, you will safe_step() instead of run + slide).
To execute this maneuver, press down and forward at exactly the same time.
Here is an experimental build. Hopefully this does not introduce too many strange new bugs.
- Attachments
-
- SDLPoP_v1.16b1.zip
- (4.72 MiB) Downloaded 272 times
Re: SDLPoP; David's open-source port of PoP (pre-release)
David, will you create a 1.15 package?
Re: SDLPoP; David's open-source port of PoP (pre-release)
I finally managed to finish my mod: see here. Phew.
Well... actually it's only eight levels. Oh well.
It requires SDLPoP; I diverged a bit from the main branch to add some "special events" and the like.
It may be good to have some sort of "customization" API or "scripting framework" for modders in the future? Of course I do not want to not want to "pollute" the original code just for the sake of my own levelset...
Well... actually it's only eight levels. Oh well.
It requires SDLPoP; I diverged a bit from the main branch to add some "special events" and the like.
It may be good to have some sort of "customization" API or "scripting framework" for modders in the future? Of course I do not want to not want to "pollute" the original code just for the sake of my own levelset...
Re: SDLPoP; David's open-source port of PoP (pre-release)
Umm... I should have already made it earlier.Norbert wrote:David, will you create a 1.15 package?
Now the ChangeLog needs updating.
I also merged the new pull requests.
I looked at those series of #defines.Falcury wrote:Ended up doing a gaint macro chain, so inserting and deleting is at least possible now
I tried replacing it with const, but it won't work.
A smaller example:
This code results in the error "initializer element is not constant".
Code: Select all
const int i=1;
const int j=i+1;
It seems C and C++ have different ideas about what is a constant.
Re: SDLPoP; David's open-source port of PoP (pre-release)
Done.David wrote:Now the ChangeLog needs updating.
Can I make a ZIP now, or does someone have more additions?

Re: SDLPoP; David's open-source port of PoP (pre-release)
There are some additions that I haven't made pull requests for yet. Do you want me to do that now, or do you want to wait for the next update?
Edit: pull requests submitted.
Edit: pull requests submitted.
Re: SDLPoP; David's open-source port of PoP (pre-release)
From https://github.com/NagyD/SDLPoP/pull/20
I'm trying to figure out why.
Update: I just figured it out: An else was missing in redraw_needed().
Looks like I overlooked a jmp in the disassembly. (Even though it's followed by a separator line as wide as the screen.)
Who would have thunk there were still some of these?...
From https://github.com/NagyD/SDLPoP/pull/21/files
I'm not sure what FIX_GUARD_FOLLOWING_THROUGH_CLOSED_GATES does.
Also, that "Kid.curr_row * 10 + 9" looks strange. get_tile() expects a column there, so it should be just 9?
Interestingly, the bug disappears in the original game in exactly that case.Falcury wrote:A drawing bug occurs when a loose tile is placed to the left of a potion.
[...]
Unfortunately, the bug still occurs when the loose tile wobbles.
I'm trying to figure out why.
Update: I just figured it out: An else was missing in redraw_needed().
Looks like I overlooked a jmp in the disassembly. (Even though it's followed by a separator line as wide as the screen.)
Who would have thunk there were still some of these?...

From https://github.com/NagyD/SDLPoP/pull/21/files
I'm not sure what FIX_GUARD_FOLLOWING_THROUGH_CLOSED_GATES does.
Also, that "Kid.curr_row * 10 + 9" looks strange. get_tile() expects a column there, so it should be just 9?