Upper 3 bits of the "curr_tile"

Windows and Linux editor of PoP1 (for DOS and SNES) and PoP2 (for DOS).
Post Reply
dmitry_s
Developer
Developer
Posts: 148
Joined: July 27th, 2021, 7:22 am

Upper 3 bits of the "curr_tile"

Post by dmitry_s »

Currently each tile is represented by 2 bytes, or more specifically 5 bits of the tile byte and the modifier byte. The only exception (from what I know) is the loose tile which uses tile bit #6 to indicate whether it is a stuck loose or a regular loose tile.

The code that determines the tile byte value and the modifier value in SDLPoP looks like this.

Code: Select all

curr_modifier = curr_room_modif[tilepos];
curr_tile = curr_room_tiles[tilepos] & 0x1F /* masks the first 5 bits */;
Currently Apoplexy separates bit #6 into the "mod" value. The other 2 bits can be set by using a "random" 0-3 value. I think it would make more sense to have a single 0-7 "mod" value for the upper 3 bits of the tile byte. This is purely a UI thing but it would make it easier to think about/document tile customizations.

The existing stuck loose tile logic would still work the same by using 1 for that mod value. And most people just choose the stuck tile with a mouse/controller instead of changing those values.

I have a couple of ideas that can be easily implemented using that mod value. Those tiles are already extensively using the modifier byte so it would require some ugly bit manipulation to use that byte.

1. Totally loose tiles (as in PoP2 ruins or in my mod on level 11) by setting bit #7. It would only work for tiles that have bit #6 set to 0 (non-stuck).

2. Loud gates (can be heard from other rooms). Currently the room and the gate position is hard-coded and it only applies to the first gate on level 3.

Looking at the gates in Apoplexy I have found an inconsistency. It looks like all the gates in the original LEVELS.DAT file have the bit #6 (mod) set to 1. But when you add a new gate through Apoplexy it sets it to 0. It does not affect the game play as that bit is not used. But it would require using bit #7 for loud gates to avoid inconsistencies in mods.

Skeleton tiles can also be modified that way to have skeletons rise on skeleton levels. It can have 2 values - when the level door is open or at any time.
Last edited by David on January 22nd, 2022, 5:25 pm, edited 1 time in total.
Reason: Changed "byte" to "bit" where appropriate.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: Upper 3 bytes of the "curr_tile"

Post by Norbert »

I will react to your ideas in the New tile ideas thread.
As for the rest...
dmitry_s wrote: December 29th, 2021, 11:05 pmCurrently Apoplexy separates bit #6 into the "mod" value. The other 2 bytes can be set by using a "random" 0-4 value.
0-3 (00=0, 01=1, 10=2, 11=3)
But, yes.
dmitry_s wrote: December 29th, 2021, 11:05 pmIt looks like all the gates in the original LEVELS.DAT file have the bit #6 (mod) set to 1. But when you add a new gate through Apoplexy it sets it to 0.
Yes, so does RoomShaker.
In the apoplexy source code, it even says:

Code: Select all

/*** 0 = default for level editors, 2 = default of the game ***/
Also mentioned in the gate section of the "Legacy combos" wiki page.

Both are remnants of the past. As the Specifications of File Formats says:
- (page 11) "A tile in the pop1 foretable part has 8 bits in this format rrmccccc, where rr are random bits and can be ignored. m is a modifier of the tile."
- (page 13) "gate 0x00 Closed" and "gate 0x01 Open"

I agree that when thinking about/documenting tile customizations, we should ignore the old-fashioned rrm separation. I think we have too, since - as you wrote - m never did much (just 'stuck') anyway.
dmitry_s
Developer
Developer
Posts: 148
Joined: July 27th, 2021, 7:22 am

Re: Upper 3 bytes of the "curr_tile"

Post by dmitry_s »

Norbert wrote: December 30th, 2021, 12:15 am
of the past. As the Specifications of File Formats says:
- (page 11) "A tile in the pop1 foretable part has 8 bits in this format rrmccccc, where rr are random bits and can be ignored. m is a modifier of the tile."
- (page 13) "gate 0x00 Closed" and "gate 0x01 Open"
But Apoplexy shows a tile with a question mark if random bits are set to anything other than 0.

As for the gates, the mod bit is set to Y for closed and opened in the original game. It is not clear on that wiki page which values correspond to the modifier byte vs the mod bit in the tile byte. For the gate, modifier byte values are much higher and proportional how much the gate is open, and 255 = stuck open.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: Upper 3 bytes of the "curr_tile"

Post by Norbert »

dmitry_s wrote: December 30th, 2021, 1:32 amBut Apoplexy shows a tile with a question mark if random bits are set to anything other than 0.
I meant to explain where the rr-m split comes from, other than the obvious stuck loose. The 'random bits can be ignored' I've always interpreted as: we ignore them and (therefore) only use/expect 0. Not: whatever value they are, always show/use this tile. Because the overall value is simply not the same, which indicates someone did not ignore these bits, which is something that should be indicated to the user, with e.g. a question mark.
dmitry_s wrote: December 30th, 2021, 1:32 amAs for the gates, the mod bit is set to Y for closed and opened in the original game. It is not clear on that wiki page which values correspond to the modifier byte vs the mod bit in the tile byte. For the gate, modifier byte values are much higher and proportional how much the gate is open, and 255 = stuck open.
We can designate a gate (group 0x04) with variant (modifier) e.g. 0x12 to be a fully closed (or fully open) gate with certain new properties. As soon as it's in place, SDLPoP can start using the variant value to reflect its 'actual' openness during gameplay. Also, if we'd want partially open gates as new native tiles, we'd only need 3 or so variants for whatever openness makes sense gameplay-wise, such as ~1/8 open to allow climbing in from the bottom but not jumping in from the gate-row. Similar to the aforementioned reasoning, apoplexy completely ignores whatever changes happen to the rrm bits during gameplay, nor does it detect custom tiles that imitate these gameplay states. As for the mod bit, with the exception of the TODO-sentence and "(Bit set means it is stuck.)", the "Legacy combos" wiki page contains no information about it.
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Upper 3 bytes of the "curr_tile"

Post by David »

Norbert wrote: December 30th, 2021, 12:15 am
dmitry_s wrote: December 29th, 2021, 11:05 pmIt looks like all the gates in the original LEVELS.DAT file have the bit #6 (mod) set to 1. But when you add a new gate through Apoplexy it sets it to 0.
Yes, so does RoomShaker.
In the apoplexy source code, it even says:

Code: Select all

/*** 0 = default for level editors, 2 = default of the game ***/
Also mentioned in the gate section of the "Legacy combos" wiki page.
I think there is some confusion here: Dmitry wrote about bit #6 of the tile byte, while Norbert wrote about the modifier byte.
dmitry_s
Developer
Developer
Posts: 148
Joined: July 27th, 2021, 7:22 am

Re: Upper 3 bytes of the "curr_tile"

Post by dmitry_s »

Exactly. The only place in the game where that bit is being used is for the stuck loose tile. But for some reason it is also set in the original levels for the gates.

It should probably be mentioned on https://www.princed.org/wiki/Legacy_combos that normal/stuck tile value refers to the bit 6 of the tile while the rest of the values are for the modifier byte.
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Upper 3 bytes of the "curr_tile"

Post by David »

dmitry_s wrote: January 1st, 2022, 11:11 pm Exactly. The only place in the game where that bit is being used is for the stuck loose tile. But for some reason it is also set in the original levels for the gates.
FYI, on the original levels, bit #6 of the tile byte is set if the tile below needs to have floor above it.
This was added for the convenience of Mechner's own editor.

I have posted about this earlier here:
viewtopic.php?p=20148#p20148
viewtopic.php?p=18193#p18193

In the Apple II source, there is the linklist array which tells whether a tile needs floor above it, and other things as well.
https://github.com/jmechner/Prince-of-P ... .S#L27-L28

linklist is indexed by tile type ID.
The possible values are:
* The ID of another tile, if this tile is only half of an object. The value of the item is the ID of its pair. (Examples: big pillars, level doors, balconies, large arches)
* 0xFE, if a floor is needed above this tile.
* 0xFF, if no floor is needed above this tile.

Here is the meaning of values in the array:

Code: Select all

linklist[0x00] = 0xFF // empty -> no
linklist[0x01] = 0xFF // floor -> no
linklist[0x02] = 0xFF // spikes -> no
linklist[0x03] = 0xFE // pillar -> floor needed above
linklist[0x04] = 0xFF // gate -> no
linklist[0x05] = 0x00 // stuck floor -> ???
linklist[0x06] = 0xFF // drop button -> no
linklist[0x07] = 0xFE // doortop with floor -> floor needed above
linklist[0x08] = 0x09 // big pillar bottom half -> paired with big pillar top half
linklist[0x09] = 0xFE // big pillar top half -> floor needed above
linklist[0x0A] = 0xFF // potion -> no
linklist[0x0B] = 0xFF // loose floor -> no
linklist[0x0C] = 0xFE // doortop -> floor needed above
linklist[0x0D] = 0xFE // mirror -> floor needed above
linklist[0x0E] = 0xFF // broken floor -> no
linklist[0x0F] = 0xFF // raise button -> no
linklist[0x10] = 0x11 // level door left half -> paired with level door right half
linklist[0x11] = 0xFF // level door right half -> no
linklist[0x12] = 0xFE // chomper -> floor needed above
linklist[0x13] = 0xFF // torch -> no
linklist[0x14] = 0xFE // wall -> floor needed above
linklist[0x15] = 0xFF // skeleton -> no
linklist[0x16] = 0xFF // sword -> no
linklist[0x17] = 0x18 // balcony left half -> paired with balcony right half
linklist[0x18] = 0xFF // balcony right half -> no
linklist[0x19] = 0xFF // lattice pillar -> no
linklist[0x1A] = 0xFF // lattice down -> no
linklist[0x1B] = 0xFF // lattice small arch -> no
linklist[0x1C] = 0x1D // lattice large arch left half -> paired with lattice large arch right half
linklist[0x1D] = 0xFF // lattice large arch right half -> no
These mostly match what you'd expect, except no floor is required above gates and lattice pieces.

The array is used here:
https://github.com/jmechner/Prince-of-P ... OR.S#L1038

The mask for bit #6 is here:
https://github.com/jmechner/Prince-of-P ... /EQ.S#L485

bit #6 of loose floors is checked here:
https://github.com/jmechner/Prince-of-P ... VER.S#L396
dmitry_s
Developer
Developer
Posts: 148
Joined: July 27th, 2021, 7:22 am

Re: Upper 3 bits of the "curr_tile"

Post by dmitry_s »

That is good to know. I can see that some other tiles like the pillars have the bit 6 set as well on the original levels which makes sense.

That would make Apoplexy/Roomshaker not fully compatible with Mechner's editor which does not really matter but a fun fact to know.

Maybe it would make sense to rename "random bits" to something like a flag/attribute and retain the original tile picture despite of the 0-3 value of tile bits 7 and 8. Bit 6 is cannot be relied on for anything other than loose tiles since editors treat it differently than how it is set on the original levels.
Last edited by David on January 22nd, 2022, 5:28 pm, edited 1 time in total.
Reason: Changed "byte" to "bit" where appropriate.
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Upper 3 bytes of the "curr_tile"

Post by David »

I just realized that "byte(s)" should be "bit(s)" in the title and elsewhere.
Please let me know if I can fix this.
User avatar
Norbert
The Prince of Persia
The Prince of Persia
Posts: 5743
Joined: April 9th, 2009, 10:58 pm

Re: Upper 3 bytes of the "curr_tile"

Post by Norbert »

David wrote: January 16th, 2022, 3:11 pmI just realized that "byte(s)" should be "bit(s)" in the title and elsewhere.
Maybe that resulted in the confusion:
David wrote: January 1st, 2022, 3:08 pmI think there is some confusion here: Dmitry wrote about bit #6 of the tile byte, while Norbert wrote about the modifier byte.
As for...
David wrote: January 16th, 2022, 3:11 pmPlease let me know if I can fix this.
Fine with me, the more accurate the better.
dmitry_s
Developer
Developer
Posts: 148
Joined: July 27th, 2021, 7:22 am

Re: Upper 3 bytes of the "curr_tile"

Post by dmitry_s »

Feel free to change it. I obviously meant bits.
David
The Prince of Persia
The Prince of Persia
Posts: 2846
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: Upper 3 bits of the "curr_tile"

Post by David »

dmitry_s wrote: January 17th, 2022, 9:33 am Feel free to change it. I obviously meant bits.
Done.
Post Reply