dressupgeekout / lunapurpura

Reimplementation of Purple Moon's games from the 1990s (WIP) - NOTE: ScummVM port in progress
https://dressupgeekout.github.io/lunapurpura/
BSD 2-Clause "Simplified" License
8 stars 1 forks source link

[Secret Invitation] "Phantom" Members in IDL Archives #28

Closed AlanisSmithee closed 4 years ago

AlanisSmithee commented 4 years ago

Three character IDL archives appear to have "phantom" members when you list them with the prx tool, and give a "permission denied" error when you extract them. Bo and Chaz have two (Internal IDs 117/118 and 122/123, respectively). Whitney has a startling four. (160 to 163). Whitney's archive also appears to have two members with an internal ID of 163. (One is a phantom, the other is a valid file: WHIT_hair1.xmv) All of them occur at the bottom of the list and give no file name, no file type, no resource ID, and a file size of 0. All of the other files in the archives will extract normally.

157   WHIT_hair3        XMV   47855   1624
158   WHIT_hair2        XMV   47844   1176
163   WHIT_hair1        XMV   47843   1176
160                           0       0
161                           0       0
162                           0       0
163                           0       0
AlanisSmithee commented 4 years ago

First Dance: Six character archives have the phantom member problem: Arnold (which doesn't give an error when extracting), Bo, Chaz, Stephanie, Teachers, and Whitney. Some are also skipping member numbers and have "duplicates".

Arnold:

127   ARN_LAGOOPSTER    Aif   48073   85121
128   ARN_SANDWICH      XMV   30504   1144
130   ARN_SANDWICH      Aif   30504   220622
130                           0       0

Bo:

116   BO_circuit        XMV   30602   1624
117   BO_circuit        Aif   30602   266176
120   BO_GRAFFITI       Aif   45847   68467
119                           0       0
120                           0       0

Chaz:

124   CHA_TROPHY        XMV   30658   1896
125   CHA_trophy        Aif   30658   264706
128   CHA_MUMMY_V3      Aif   47962   50150
127                           0       0
128                           0       0

Stephanie:

133   STE_DRYER         Aif   31355   220710
139   STE_TIGER_V2      Aif   43041   70680
135                           0       0
136                           0       0
137                           0       0
138                           0       0
139                           0       0

Teacher

386   CHE_laptop        Aif   50951   176482
387   PIL_BALLET        XMV   37035   1944
391   PIL_BALLET        Aif   37035   264706
389                           0       0
390                           0       0
391                           0       0

Whitney

163   WHI_BERRET        XMV   47872   792
164   WHI_BERRET        Aif   47872   66252
167   WHI_shellmirror   Aif   31468   132382
166                           0       0
167                           0       0

These may be tied in with the other various bugs going on with the PRX tool and Dance. Some of the other archives might have the same problem as Arnold's. I haven't looked deeply into it yet.

dressupgeekout commented 4 years ago

Thanks for the report. I'm able to reproduce. I'm labelling it as a bug for now, because it certainly doesn't look right.

I have a few ideas why this might be happening. In particular, there's one major assumption currently in use in the PRX unarchiver code, which I think could be related.

dressupgeekout commented 4 years ago

Yup, taking a closer look at a variety of PRXes in Secret Invitation... there's definitely a characteristic of PRX archives which the PRX reader is currently ignoring. I can confirm that the aforementioned "major assumption" is at play. From prx/prx.c, line 40:

40  /* 128 + 10 - 1, I guess -- all zeroes */
41  fseek(fp, 137L, SEEK_CUR);
42
43  ReadUint16LE(fp, 1, &prx->n_entries);
44  fseek(fp, 4L, SEEK_CUR); /* Number of entries, again? */

The "number of entries, again?" is NOT true in the troublesome PRX archives (Whitney, Arnold, etc.). We always skip a "phantom member" (or "dummy entry") which seems to always be the first member, but today we've learned that that some archives have empty members at the end of the list, too.

Here's the bug: whether or not there are "phantom" members at the end of a PRX's table of contents is actually encoded into PRX files, but we've been ignoring it because we skip over that information in line 44 (above).

dressupgeekout commented 4 years ago

Candidate fix in branch 'phantom_members' https://github.com/dressupgeekout/lunapurpura/commit/4ff4d18fb4d1fd41347caf2850c70bda2aee1a56

dressupgeekout commented 4 years ago

Put up a pull request: https://github.com/dressupgeekout/lunapurpura/pull/32