Page 1 of 2

Re: Unknowns in the level format

Posted: December 28th, 2012, 11:39 pm
by Norbert
It is very likely that Unknown IVa, IVb and IVc contain guard information.
(Because they are in between other guard data, about locations, directions, skills and colors.)
Each is a byte times 24, so it's also very likely the data is one byte per room.

The source code released by Jordan and the disassembly by David could be useful to find out more.
I'll try to look into it some more, maybe I'll figure out more.

Re: Unknowns in the level format

Posted: December 29th, 2012, 12:09 am
by Norbert
This is what the bytes of the Unknown blocks in the default LEVELS.DAT are like:
Spoiler: show
=== Level 1 ===
Unknown I:
24 16 16 17 12 15 15 13
14 18 10 14 11 255 13 10
11 13 255 11 12 14 10 12
255 15 16 16 17 15 16 16
16 16 17 17 16 255 17 16
15 15 255 17 16 15 15 15
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
Unknown II and III: (One byte less on the potions level.)
0 0 0 255
Unknown IVa:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVb:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVc:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVd:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255

=== Level 2 ===
Unknown I:
25 15 6 16 17 18 16 12
11 6 17 14 10 11 7 10
9 10 13 8 9 7 15 7
8 16 15 15 16 16 16 15
14 14 17 15 14 15 16 15
15 16 15 15 14 15 15 14
14 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
Unknown II and III: (One byte less on the potions level.)
0 0 0 0
Unknown IVa:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVb:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVc:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVd:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255

=== Level 3 ===
Unknown I:
24 15 16 15 16 14 14 17
15 18 18 19 19 20 20 21
22 21 21 16 15 16 17 255
255 15 15 16 16 15 16 15
18 16 15 15 16 16 15 14
14 16 15 18 17 17 16 255
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
Unknown II and III: (One byte less on the potions level.)
0 0 0 255
Unknown IVa:
255 255 170 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 156 255 255 255
Unknown IVb:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVc:
255 255 0 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 0 255 255 255
Unknown IVd:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255

=== Level 4 ===
Unknown I:
25 15 16 15 21 17 18 20
14 13 14 22 21 22 20 19
12 12 13 12 22 17 16 11
19 15 15 16 15 15 15 15
15 15 16 15 16 16 16 16
15 16 16 17 17 16 16 15
15 255 255 255 255 255 255 255
0 0 0 0 0 0 0 0
Unknown II and III: (One byte less on the potions level.)
0 0 0 0
Unknown IVa:
255 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 255 255 255 255 255 255 255
Unknown IVb:
255 255 255 255 255 255 255 255 255 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
Unknown IVc:
0 0 0 0 0 0 0 0 0 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVd:
255 255 255 255 255 255 255 255
255 0 0 0 0 0 0 0

=== Level 5 ===
Unknown I:
25 255 15 255 15 255 255 18
17 19 18 19 16 17 17 13
14 13 12 255 14 19 14 11
20 255 15 255 16 255 255 15
15 15 14 14 15 14 13 15
15 16 15 255 16 16 17 15
14 255 255 255 255 255 255 255
0 0 0 0 0 0 0 0
Unknown II and III: (One byte less on the potions level.)
0 0 0 0
Unknown IVa:
255 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 255 255 255 255 255 255 255
Unknown IVb:
255 255 255 255 255 255 255 255 255 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
Unknown IVc:
0 0 0 0 0 0 0 0 0 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVd:
255 255 255 255 255 255 255 255
255 0 0 0 0 0 0 0

=== Level 6 ===
Unknown I:
25 11 15 11 255 10 13 13
255 12 17 13 17 255 255 14
255 255 12 255 255 255 255 14
16 15 15 16 255 15 15 16
255 16 15 17 16 255 255 15
255 255 15 255 255 255 255 16
15 255 255 255 255 255 255 255
0 0 0 0 0 0 0 0
Unknown II and III: (One byte less on the potions level.)
0 0 0 0
Unknown IVa:
255 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 255 255 255 255 255 255 255
Unknown IVb:
255 255 255 255 255 255 255 255 255 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
Unknown IVc:
0 0 0 0 0 0 0 0 0 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVd:
255 255 255 255 255 255 255 255
255 0 0 0 0 0 0 0

=== Level 7 ===
Unknown I:
25 15 16 15 16 18 17 17
18 18 19 19 20 20 22 22
14 15 19 21 21 22 19 18
20 15 15 16 16 17 16 15
16 15 15 16 15 16 15 16
15 14 17 15 16 17 14 14
14 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0
Unknown II and III: (One byte less on the potions level.)
0 0 0 255
Unknown IVa:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVb:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVc:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVd:
0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255

=== Level 8 ===
Unknown I:
25 14 15 14 15 13 13 12
12 22 22 255 17 18 18 255
16 22 22 255 20 19 19 20
21 15 15 16 16 15 16 15
16 17 18 255 16 16 15 255
16 15 16 255 15 15 16 16
16 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0
Unknown II and III: (One byte less on the potions level.)
0 0 0 255
Unknown IVa:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVb:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVc:
28 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVd:
0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255

=== Level 9 ===
Unknown I:
25 14 16 16 16 17 13 13
17 17 14 18 18 18 19 19
19 17 18 16 20 15 15 15
14 15 15 14 16 15 13 14
14 16 13 16 14 15 16 15
14 13 13 13 14 14 13 15
14 255 255 255 255 255 255 255
0 0 0 0 0 0 0 0
Unknown II and III: (One byte less on the potions level.)
0 0 0 0
Unknown IVa:
255 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 255 255 255 255 255 255 255
Unknown IVb:
255 255 255 255 255 255 255 255 255 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0
Unknown IVc:
0 0 0 0 0 0 0 0 0 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVd:
255 255 255 255 255 255 255 255
255 0 0 0 0 0 0 0

=== Level 10 ===
Unknown I:
21 15 16 15 16 14 255 17
13 12 18 14 13 16 19 20
19 20 17 18 17 16 8 11
12 15 15 16 16 15 255 15
15 15 15 14 14 14 15 15
14 14 14 14 16 16 15 15
15 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
Unknown II and III: (One byte less on the potions level.)
0 0 0 255
Unknown IVa:
255 255 255 128 255 255 255 255 255 255 255 255
255 255 255 255 255 255 128 255 142 255 255 255
Unknown IVb:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVc:
255 255 255 0 255 255 255 255 255 255 255 255
255 255 255 255 255 255 0 255 0 255 255 255
Unknown IVd:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255

=== Level 11 ===
Unknown I:
25 15 17 15 17 20 14 17
15 14 14 21 13 22 16 16
21 13 255 18 19 18 19 15
20 15 15 16 16 16 15 14
14 14 16 16 14 15 14 15
15 15 255 15 14 16 15 17
15 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
Unknown II and III: (One byte less on the potions level.)
0 0 0 0
Unknown IVa:
255 86 255 72 255 255 86 255 255 255 114 255
255 255 72 255 255 255 255 255 255 255 255 72
Unknown IVb:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVc:
255 0 255 0 255 255 0 255 255 255 0 255
255 255 0 255 255 255 255 255 255 255 255 0
Unknown IVd:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255

=== Level 12 ===
Unknown I:
25 15 14 15 16 16 15 15
16 16 14 13 16 13 17 15
13 13 15 16 16 14 15 12
17 18 14 19 19 13 16 17
17 18 13 15 16 14 16 14
13 16 15 15 14 15 13 14
17 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0
Unknown II and III: (One byte less on the potions level.)
0 0 0 255
Unknown IVa:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVb:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVc:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVd:
0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255

=== Level 13 (12b) ===
Unknown I:
25 12 14 11 11 255 255 255
255 255 14 12 255 14 255 255
12 13 255 255 255 255 255 13
10 13 15 13 14 255 255 255
255 255 13 15 255 14 255 255
14 13 255 255 255 255 255 14
14 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0
Unknown II and III: (One byte less on the potions level.)
0 0 0 255
Unknown IVa:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVb:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVc:
0 255 0 255 0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255 0 255 0 255
Unknown IVd:
0 255 0 255 0 255 0 255
0 255 0 255 0 255 0 255

=== Princess level ===
Unknown I:
7 15 16 17 18 14 19 14
11 6 17 14 10 11 7 10
9 10 13 8 9 7 15 7
8 15 15 15 15 15 15 14
14 14 17 15 14 15 16 15
15 16 15 15 14 15 15 14
14 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
Unknown II and III: (One byte less on the potions level.)
0 0 0 0
Unknown IVa:
255 86 255 72 255 255 86 255 255 255 114 255
255 255 72 255 255 255 255 255 255 255 255 72
Unknown IVb:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVc:
255 0 255 0 255 255 0 255 255 255 0 255
255 255 0 255 255 255 255 255 255 255 255 0
Unknown IVd:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255

=== Potions level ===
Unknown I:
9 255 255 15 16 15 14 16
17 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0
255 255 255 16 16 17 16 17
16 0 255 0 255 0 255 0
126 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0
Unknown II and III: (One byte less on the potions level.)
0 0 0
Unknown IVa:
255 0 255 0 255 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0 255 0 255 0
Unknown IVb:
255 0 255 0 255 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0 255 0 255 0
Unknown IVc:
255 0 255 0 255 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0 255 0 255 0
Unknown IVd:
255 0 255 0 255 0 255 0
255 0 255 0 255 0 255 0

=== Demo level ===
Unknown I:
25 17 16 255 15 16 15 17
14 14 14 14 14 14 14 14
13 13 13 13 13 13 13 13
14 15 15 255 15 16 16 16
16 17 18 19 20 21 22 23
23 22 21 20 19 18 17 16
15 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255
Unknown II and III: (One byte less on the potions level.)
0 0 0 0
Unknown IVa:
255 255 255 72 255 255 86 255 255 255 114 255
255 255 72 255 255 255 255 255 255 255 255 72
Unknown IVb:
255 255 255 255 255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255 255 255 255 255
Unknown IVc:
255 255 255 0 255 255 0 255 255 255 0 255
255 255 0 255 255 255 255 255 255 255 255 0
Unknown IVd:
255 255 255 255 255 255 255 255
255 255 255 255 255 255 255 255

Re: Unknowns in the level format

Posted: January 8th, 2013, 12:53 pm
by David
Here is the relevant part from EQ.S: (// comments by me)

Code: Select all

 dum blueprnt

BLUETYPE ds 24*30 // tiles
BLUESPEC ds 24*30 // modifiers
LINKLOC ds 256 // door links 1
LINKMAP ds 256 // door links 2
MAP ds 24*4 // room links
INFO ds 256 // see below
And the INFO part detailed: (// comments by me)

Code: Select all

 dum INFO

 ds 64 // unknown I
KidStartScrn ds 1 // start room
KidStartBlock ds 1 // start tile
KidStartFace ds 1 // start direction
 ds 1 // unknown II
SwStartScrn ds 1 // maybe Sw means shadow?, these are not used anywhere
SwStartBlock ds 1
 ds 1 // unknown III
GdStartBlock ds 24 // guard tile
GdStartFace ds 24 // guard direction
GdStartX ds 24 // unknown IV (a)
GdStartSeqL ds 24 // unknown IV (b)
GdStartProg ds 24 // guard skill
GdStartSeqH ds 24 // unknown IV (c)
// guard color and unknown IV (d) are missing
GdStartX and GdStartSeqH are initialized when the level is loaded, so their initial values are not used:
SUBS.S:

Code: Select all

*-------------------------------
*
* Set initial guard posns for entire level (call once)
*
*-------------------------------
INITIALGUARDS
 ldy #24 ;screen #
:loop
 lda GdStartBlock-1,y
 cmp #30
 bcs :nogd
 jsr unindex ;A = blockx
 jsr getblockej
 clc
 adc #angle+7
 sta GdStartX-1,y
 lda #0
 sta GdStartSeqH-1,y

:nogd dey
 bne :loop
]rts rts
from COMMENTS.S: (// comments by me)

Code: Select all

*  INFO
*
*  Bytes 0-63: reserved for editor // unknown I
*
*  Bytes 64-255: Information about starting positions
*  of player & other characters on this level.
*  (See GAMEEQ for details.) // actually, it's EQ.S
from BUILDER.S (part of the level editor): (// comments by me)

Code: Select all

readblue lda MATX
 pha
 lda MATY
 pha

 lda INFO ;next available block #
 sta NUMNEXT

 ldx #1
 ldy #0

:loop jsr getinfo
 bmi :skip ;255 = nonexistent block
 jsr CALCMAT
 txa
 sta (ZTEMP),y

:skip inx
 cpx NUMNEXT
 bcc :loop

:done pla
 sta MATY
 pla
 sta MATX
 rts

getinfo lda INFO,x
 sta MATX
 lda INFO+MAXBLOX,x // MAXBLOX=24
 sta MATY
]rts rts
So, byte 0 stores the number of the first unused room. Bytes 1..24 store the X coordinates and bytes 25..48 store the Y coordinates.
Byte 0 is also used in the game:
from SUBS.S: (// comments by me)

Code: Select all

*-------------------------------
*
*  S E T  I N I T I A L S
*
*  Set initial states of gadgets
*
*-------------------------------
SETINITIALS
 lda INFO ;number of screens +1
 sec
 sbc #1
 sta SCRNUM

:loop jsr DoScrn ;for every screen

 dec SCRNUM
 bne :loop
 rts
*-------------------------------
DoScrn
 lda SCRNUM
 jsr calcblue

 ldy #29

:loop jsr getinitobj // for every tile in the room
 bcc :skip
 sta (BlueSpec),y

:skip dey
 bpl :loop

 rts
getinitobj from FRAMEADV.S: (// comments by me)

Code: Select all

*-------------------------------
*
*  Get initial state of object
*
*  In: BlueType, BlueSpec, Y
*
*  Return cs if it matters, else cc // cs=carry set, cc=carry clear
*
*-------------------------------
GETINITOBJ
 lda (BlueType),y
 and #idmask ;get objid // #idmask=0x1F

getinitobj1
 cmp #gate
 beq :okgate
 cmp #loose
 beq :okloose
 cmp #flask
 beq :okflask
 bne :skip ;if it isn't a gadget, leave it alone

:okgate lda (BlueSpec),y ;1=gate up, 2=gate down, etc.
 tax
 lda initsettings-1,x // see below
 sec
 rts

:okloose lda #0 ;loose floor
 rts

:okflask lda (BlueSpec),y
 asl
 asl
 asl
 asl
 asl ;5x
 sec
 rts

:skip clc
]rts rts
The referenced initsettings:

Code: Select all

initsettings
 db gmaxval,gminval
from BGDATA.S: (// comments by me)

Code: Select all

gmaxval = 47*4 // open gate
gminval = 0 // closed gate
The modifiers of certain objects are changed after the level is loaded.
Gate: on disk, 1=open, 2=closed. In memory, the modifier stores how much the gate is open, in 1/4 pixels. (Probably because when the gate is closing, it moves 1 pixel in 4 frames.)
Loose floor: the modifier is zeroed out. In memory, the modifier tells which frame to show.
Potion: the modifier is shifted 5 bits left, i.e. the bottom 3 bits become the top 3 bits, and the bottom 5 bits store which bubble image should be shown.

An interesting thing is that the unused rooms of level 14 contain parts of level 2, but the modifiers have these changed values.
For example the potions in room 8, 12, 13, 18 have modifier 32, in room 20 (big potion) modifier 64, in room 13 (hurt potion) modifier 160.
Room 13 also has an open door with modifier 188(=47*4).

Re: Unknowns in the level format

Posted: January 8th, 2013, 7:55 pm
by Norbert
Now someone needs to translate everything that David posted into whether the unknowns are now known, and if they do anything that's useful and should be added to level editors... :lol:
The assembly language is such a pain...

Re: Unknowns in the level format

Posted: January 18th, 2013, 10:32 am
by David
Norbert wrote:Now someone needs to translate everything that David posted
Yeah, I usually get carried away when writing about technical details... :)
Norbert wrote:if they do anything that's useful and should be added to level editors
The only thing that does something is the number of the first unused room. It's the first byte of unknown I.
The DOS version seems to interpret it as the number of the last used room, though.

Re: Unknowns in the level format

Posted: February 2nd, 2013, 8:34 pm
by Norbert
David wrote:The only thing that does something is the number of the first unused room. It's the first byte of unknown I.
The DOS version seems to interpret it as the number of the last used room, though.
In other words, I need to re-check all foreground+modifier combinations with that first byte of Unknown I on 0x00, and apoplexy should set it on 0x00 for all levels to make these new background+modifier combinations show up properly. Correct?

Re: Unknowns in the level format

Posted: February 8th, 2013, 12:53 pm
by David
programmer wrote:(and what was the II-nd one used for in RoomShaker)
If you place a Debug Start in RoomShaker, start_position will contain the location of the Debug Start, and unknown II will contain the location of the Player Start.
Norbert wrote:In other words, I need to re-check all foreground+modifier combinations with that first byte of Unknown I on 0x00, and apoplexy should set it on 0x00 for all levels to make these new background+modifier combinations show up properly. Correct?
You only need to re-check where the foreground is one of: 0x04 (Gate), 0x0A (Potion), 0x0B (Loose floor) and 0x14 (Wall). The wall was added to the list in the DOS version.

Re: Unknowns in the level format

Posted: September 12th, 2013, 4:46 pm
by Norbert
David wrote:
Norbert wrote:In other words, I need to re-check all foreground+modifier combinations with that first byte of Unknown I on 0x00, and apoplexy should set it on 0x00 for all levels to make these new background+modifier combinations show up properly. Correct?
You only need to re-check where the foreground is one of: 0x04 (Gate), 0x0A (Potion), 0x0B (Loose floor) and 0x14 (Wall). The wall was added to the list in the DOS version.
I don't understand this.
From what I understand, I need to set sUnknownI[0] to 0x18 (24) for all levels, to make sure all modifiers show up everywhere.
Seting sUnknownI[0] to 0x00 would tell the game that no rooms are in use, which means no modifiers would be shown/used at all.
So, how could setting sUnknownI[0] to 0x00 help me find possible new foreground+modifier combinations?
(Back in September 2012, I created/tested all those custom tiles in levels 1 (Unknown I[0] is 0x18 there) and 4 (Unknown I[0] is 0x19 there)...)

Re: Unknowns in the level format

Posted: September 13th, 2013, 10:15 am
by David
I think you misunderstood me.
That byte tells where to stop the remapping of modifiers, not the usage of modifiers.
You can see what happens in the converted room-drawing code: viewtopic.php?p=13927#p13927
In seg008.c search for seg008:1937 or alter_mods_allrm. That function is called after the level is loaded.
In turn, it calls load_alter_mod for each tile of each room, from room 1 to the room specified in sUnknownI[0]. (I called it level.used_rooms.)

Re: Unknowns in the level format

Posted: September 13th, 2013, 11:27 am
by Norbert
David wrote:I think you misunderstood me.
Yes. Thanks to your extra information, I get it now though. :)

Already checked the modifiers (shown below in decimals) for the potion:

0-31 = empty
32-63 = small red
64-95 = big red
96-127 = float
128-159 = reverse
160-191 = blue
192-223 = special blue
224-255 = small red, but doesn't heal(!)

I'll check the loose tiles, walls and gates later.

[Edit: Also added gates.]

Gates:

gate:
0-3 = 0px open
4-7 = 1px open
8-11 = 2px open
...
184-187 = 46px open
188-255 = 47px open

[Edit: Also added loose tiles.]

Loose tiles are very deserve.
Here's an image that explains everything:
http://i.imgur.com/LdOyqsS.png (mirror)
(Yes, you can walk over all of those, including the elements that don't look like tiles at all.)

[Edit: Also added walls.]

Walls: basically, in the palace environment 128 and up are without the wall stripe...
...and in the dungeon environment there are some block variations and lots of missing resources.

Re: Unknowns in the level format

Posted: September 15th, 2013, 11:53 am
by David
Loose floors:
There is a table that tells which image should be displayed for each modifier. (Search for data:2710 in the disassembly.)
Modifiers greater than 10 will index out of the arrays.
The table is followed by the similar tables for the chomper, spikes, gate top, gate slice, tapestry top, blue line; that's why those images appear.

Walls:
The lower 7 bits of the modifier mean whether there are walls on the left and/or the right side.
From the wall drawing algorithm by HTamas:

Code: Select all

#define WALL_MODIFIER_SWS     0
#define WALL_MODIFIER_SWW     1
#define WALL_MODIFIER_WWS     2
#define WALL_MODIFIER_WWW     3
(W=wall; S=space, or more precisely: not wall)
Again, there is a table for deciding which graphics to use, and modifiers greater than 3 will index out of the arrays.
(The table is at data:27A2)

Re: Unknowns in the level format

Posted: March 4th, 2017, 6:57 am
by agartha
Sorry for the revival of an ancient post, but I was wondering about the same thing, and tried to find some stuff out.

Unknown IVa = GdStartX = X-axis position (in the 140 pixel scale) of the guard. GdStartBlock basically has only three useful values to determine the row. If you specify the exact block in GdStartBlock, you will not notice any difference.

Unknown IVb and IVc (GdStartSeqL and H) form a 2-byte pointer to the sequence table to determine the CharSeq starting point (so, what's the guard doing initially). It's the one in SEQTABLE.S in the original source.

The first byte of Unknown 1 (last used room) was presumably used in the original editor to keep track of the last open room in the editor for that level, since the first 64 bytes of the INFO block are described as 'reserved for editor'.

Re: Unknowns in the level format

Posted: March 4th, 2017, 12:44 pm
by David
It looks like my previous post in this thread was before SDLPoP...
Much knowledge about the level format can be found in SDLPoP.
For example: https://github.com/NagyD/SDLPoP/blob/ma ... pes.h#L197
agartha wrote: Unknown IVa = GdStartX = X-axis position (in the 140 pixel scale) of the guard.
Correct.
agartha wrote: GdStartBlock basically has only three useful values to determine the row. If you specify the exact block in GdStartBlock, you will not notice any difference.
Did you edit the level in memory instead of in LEVELS.DAT?
When the level is loaded, GdStartX is initialized based on GdStartBlock.
Apple II: https://github.com/jmechner/Prince-of-P ... BS.S#L1684
SDLPoP: https://github.com/NagyD/SDLPoP/blob/ma ... 003.c#L580

So "the exact block in GdStartBlock" *is* meaningful, but only in LEVELS.DAT.
agartha wrote: Unknown IVb and IVc (GdStartSeqL and H) form a 2-byte pointer to the sequence table to determine the CharSeq starting point (so, what's the guard doing initially).
Right, except for the "initially" part.

GdStartSeqH is zeroed when the level is loaded.
Apple II: https://github.com/jmechner/Prince-of-P ... BS.S#L1686
SDLPoP: https://github.com/NagyD/SDLPoP/blob/ma ... 003.c#L581

And when you enter a room with GdStartSeqH=0, GdStartSeqH and L are initialized to some default values.
Apple II: https://github.com/jmechner/Prince-of-P ... TO.S#L1865
SDLPoP: https://github.com/NagyD/SDLPoP/blob/ma ... 002.c#L191

However, when you leave a room that has a guard, his current CharSeq is written here.
Apple II: https://github.com/jmechner/Prince-of-P ... TO.S#L1374
SDLPoP: https://github.com/NagyD/SDLPoP/blob/ma ... 002.c#L280

And when you re-enter the room, it is loaded back from here.
Apple II: https://github.com/jmechner/Prince-of-P ... TO.S#L1881
SDLPoP: https://github.com/NagyD/SDLPoP/blob/ma ... 002.c#L200

Re: Unknowns in the level format

Posted: September 15th, 2018, 10:50 am
by Norbert
[Edit: Edited multiple times for clarification.]

I'd like to make a proposal; for future use (e.g. SDLPoP).
If we can agree, I'll make sure apoplexy will be able to work with this.

Based on posts in this tread, Unknown I is truly unused, except for its first byte.
(Please triple-check this...)
Level editor apoplexy always sets Unknown I's first byte (#1) to 0x18 (24) to have remapped modifiers in all rooms.
This leaves us with 63 bytes of Unknown I.

I'd like to use the next byte (#2) to indicate whether it's a multiplayer level.
Default values in decimal are 11,12,14-17,255; so, 0x01 could mean it's multiplayer, and for backwards compatibility anything else single.

I'd like to use byte #3 to specify the number of players.
If the number of players is set to 0x01 through 0x08, the rest of Unknown I becomes relevant.

This leaves 61 bytes.
Each player will be described with 8 bytes.
At 8 players x 8 bytes, this would mean we are 64-61=3 bytes short.
However, the first (original) player already has 3 bytes in place.

Here's the proposed order of these 8 bytes per player:
1 0xFF (future use; e.g. hit points, has sword, whatever)
2 0xFF (future use)
3 0xFF (future use)
4 0xFF (future use)
5 color
6 room
7 tile
8 direction

In the file, the first 8 bytes will be for player 8, the next 8 bytes for player 7, and so on.
This means player 1's 3 bytes that are already in place (after Unknown I) will match up.

What do you think?

Re: Unknowns in the level format

Posted: January 2nd, 2019, 4:57 pm
by Norbert
Norbert wrote: September 15th, 2018, 10:50 amWhat do you think?
Bumpity-bump.