SDLPoP; David's open-source port of PoP

Open-source port of PoP that runs natively on Windows, Linux, etc.
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: SDLPoP; David's open-source port of PoP

Post by David »

(I wanted to post this a week ago, but the forum kept timing out then...)
Norbert wrote: November 26th, 2022, 12:13 pm As an example, the documentation says, "T: Toggle display of timer".
To me, "T" is a capital t, which makes me do Shift+t, which increases hit points.
[Edit: Maybe it is just me and my programmer mind. That nobody else is confused by the documentation.]
Dunno, GIMP for example shows letter keys with capital letters, whether they need Shift or not...
GIMP en.png
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: SDLPoP; David's open-source port of PoP

Post by Norbert »

David wrote: January 8th, 2023, 4:25 pmDunno, GIMP for example shows letter keys with capital letters, whether they need Shift or not...
Yeah, it's fine as is, I just need to get used to it.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: SDLPoP; David's open-source port of PoP

Post by Norbert »

Can anyone tell me how the program knows that PRINCE/ has a collection of res151-173.png images that are part of a certain chtab that goes from 0-22 (and not e.g. 23)?
Time and time again, I try to modify SDLPoP to create custom stuff, but I simply cannot grasp how everything works. It's too complex for me. Every time I see a function, e.g. load_sprites_from_file(), it uses another function, e.g. load_from_opendats_alloc(), that uses another function, e.g. load_from_opendats_metadata(), and then I just lose track of things, and feel sad about how powerless I am when it comes to tweaking things.
Sometimes I then try to work around everything, by using my own image loading function and then drawing stuff to the screen, but the game loop is so intricate and tight that there's no way I can just dump something in there and have it show up in-game.
Damn. :(
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: SDLPoP; David's open-source port of PoP

Post by David »

Norbert wrote: January 8th, 2023, 10:18 pm Can anyone tell me how the program knows that PRINCE/ has a collection of res151-173.png images that are part of a certain chtab that goes from 0-22 (and not e.g. 23)?
The number of images is in the first byte of the palette, res150.pal in your example.
0x17 = 23 means that image IDs go from 150+1 = 151 to 150+23 = 173.

This code tells which set is loaded into which chtab:
(seg000.c)

Code: Select all

	dathandle = open_dat("PRINCE.DAT", 'G');
[...]
	// PRINCE.DAT: sword
	chtab_addrs[id_chtab_0_sword] = load_sprites_from_file(700, 1<<2, 1);
	// PRINCE.DAT: flame, sword on floor, potion
	chtab_addrs[id_chtab_1_flameswordpotion] = load_sprites_from_file(150, 1<<3, 1);
The original PoP has this weird system for loading resources, where the function which loads a resource doesn't have a DAT file name parameter, it just scans through whatever DAT files are open at the moment.

This code loads the palette, which also contains the number of images:
(seg009.c)

Code: Select all

	dat_shpl_type* shpl = (dat_shpl_type*) load_from_opendats_alloc(resource, "pal", NULL, NULL);
[...]
	int n_images = shpl->n_images;
[...]
	for (int i = 1; i <= n_images; i++) {
		SDL_Surface* image = load_image(resource + i, pal_ptr);
[...]
		chtab->images[i-1] = image;
	}
And here is the top-level structure of *.pal files:
(types.h)

Code: Select all

typedef struct dat_shpl_type {
	byte n_images;
	dat_pal_type palette;
} dat_shpl_type;
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: SDLPoP; David's open-source port of PoP

Post by Norbert »

David wrote: January 14th, 2023, 1:13 pmThe number of images is in the first byte of the palette, [...] [...]
All right, I'll get cracking again soon then.
Let's see what I can make.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: SDLPoP; David's open-source port of PoP

Post by Norbert »

Norbert wrote: January 14th, 2023, 5:35 pm
David wrote: January 14th, 2023, 1:13 pmThe number of images is in the first byte of the palette, [...] [...]
All right, I'll get cracking again soon then.
Let's see what I can make.
My plan was to add collectable rotating coins, using floors with modifier 0x04, for a coins-mod. I tried that for 1 day (14th), then gave up and converted the plan into this basic tile idea instead. Next, I created Puny Prince from scratch, and included the previously planned coins-mod in it as "Coins of Persia".
FluffyQuack
Vizier
Vizier
Posts: 80
Joined: June 6th, 2004, 7:05 pm

Re: SDLPoP; David's open-source port of PoP

Post by FluffyQuack »

I wanted to fully understand how the check_collisions() function works, and as a test I disabled the comparison against collision from previous gameplay tick to understand how it's necessary. The test ended up being pretty amusing:
FluffyQuack
Vizier
Vizier
Posts: 80
Joined: June 6th, 2004, 7:05 pm

Re: SDLPoP; David's open-source port of PoP

Post by FluffyQuack »

I have one question about a piece of code in the function jump_up():

Code: Select all

	#ifdef USE_SUPER_HIGH_JUMP
	// kid should be able to grab 2 tiles above from an edge of a floor tile
	if (is_feather_fall && !tile_is_floor(get_tile_above_char()) && curr_tile2 != tiles_20_wall) {
		delta_x = Char.direction == dir_FF_left ? 1 : 3;
	} else {
		delta_x = 0;
	}
	int char_col = get_tile_div_mod(back_delta_x(delta_x) + dx_weight() - 6);
	get_tile(Char.room, char_col, Char.curr_row - 1);
	if (curr_tile2 != tiles_20_wall && !tile_is_floor(curr_tile2)) {
		if (fixes->enable_super_high_jump && is_feather_fall) { // super high jump can only happen in feather mode
			if (curr_room == 0 && Char.curr_row == 0) { // there is no room above
				seqtbl_offset_char(seq_14_jump_up_into_ceiling);
			} else {
				get_tile(Char.room, char_col, Char.curr_row - 2); // the target top tile
				bool is_top_floor = tile_is_floor(curr_tile2) || curr_tile2 == tiles_20_wall;
				if (is_top_floor && curr_tile2 == tiles_11_loose && (curr_room_tiles[curr_tilepos] & 0x20) == 0) {
					is_top_floor = false; // a regular loose floor above should not be treated as a floor
				}
				// kid should jump slightly higher if the top tile is not a floor
				super_jump_timer = is_top_floor ? 22 : 24;
				super_jump_room = curr_room;
				super_jump_col = tile_col;
				super_jump_row = tile_row;
				seqtbl_offset_char(seq_48_super_high_jump); // jump up 2 rows with nothing above
			}
		} else {
			seqtbl_offset_char(seq_28_jump_up_with_nothing_above); // jump up with nothing above
		}
	} else {
		seqtbl_offset_char(seq_14_jump_up_into_ceiling); // jump up with wall or floor above
	}
	#else
	get_tile(Char.room, get_tile_div_mod(back_delta_x(0) + dx_weight() - 6), Char.curr_row - 1);
	if (curr_tile2 != tiles_20_wall && ! tile_is_floor(curr_tile2)) {
		seqtbl_offset_char(seq_28_jump_up_with_nothing_above); // jump up with nothing above
	} else {
		seqtbl_offset_char(seq_14_jump_up_into_ceiling); // jump up with wall or floor above
	}
	#endif
If you compile with USE_SUPER_HIGH_JUMP, then the player's column position is calculated with an offset to the exact player position if feather_fall is true, even if fixes->enable_super_high_jump is false.

If you don't compile with USE_SUPER_HIGH_JUMP, then that offset is always 0, no matter what the feather_fall value is set to.

Is this intended? Seems odd to me that there's potentially a small difference in gameplay if you compile with USE_SUPER_HIGH_JUMP even with fixes->enable_super_high_jump set to false.
Post Reply