sahlberg / pop-fe

Python script to automate the process of fetching boxart and installing PS1 games (onto your PSP/VITA/PS2/PS3)
135 stars 13 forks source link

Invalid number of discs (1) in multi-disc PBP file #7

Closed DamonHougland closed 2 years ago

DamonHougland commented 2 years ago

I tried using pop-fe.py in a Docker image on my Windows machine. I tried several different bin/cue combinations, and verified that I could use PSX2PSP to convert them appropriately to PBP files. I consistently get the same error in Duckstation when checking the PBP files: Invalid number of discs (1) in multi-disc PBP file. Note that I tried games with single bin/cue combinations as well as some with multiple bin tracks (to test binmerge). Always the same result.

Here is the verbose log from pop-fe: Processing /TEMP/Need for Speed - High Stakes (USA).zip ... This is a ZIP file. Uncompress the file. Extracting Need for Speed - High Stakes (USA).bin Extracting Need for Speed - High Stakes (USA).cue Found CUE file Need for Speed - High Stakes (USA).cue CUE Need for Speed - High Stakes (USA).cue Creating temporary CU2 file: TMP0.cu2 Convert CUE to a normal style ISO Convert CUE to a normal style ISO Cue: Need for Speed - High Stakes (USA).cue Read bin 0 Need for Speed - High Stakes (USA).bin Write track ISO0001.iso disc_ids ['SLUS00826'] Fetch cover for NEED FOR SPEED - HIGH STAKES get https://psxdatacenter.com/games/U/N/SLUS-00826.html get icon for SLUS00826 Fetch screenshot for NEED FOR SPEED - HIGH STAKES Add image text: title: NEED FOR SPEED - HIGH STAKES Id: SLUS00826 Title: NEED FOR SPEED - HIGH STAKES Cue Files ['Need for Speed - High Stakes (USA).cue'] Imb Files ['Need for Speed - High Stakes (USA).bin'] Disc IDs ['SLUS00826'] Create PBP file for NEED FOR SPEED - HIGH STAKES Need to create a TOC Add image Need for Speed - High Stakes (USA).bin Create PBP file at /TEMP/PBP/NEED FOR SPEED - HIGH STAKES.pbp Generating PARAM.SFO [NEED FOR SPEED - HIGH STAKES]... Writing header Writing PARAM.SFO at Writing ICON0.PNG at Writing PIC1.PNG Got a TOC Writing indexes Writing PSX CD Dump Writing compressed image Writing PSTITLEIMG.DAT Writing STARTDAT header Writing P.O.P.S standard logo Writing STARTDAT footer EBOOT.PBP Created Deleting temp file Need for Speed - High Stakes (USA).bin Deleting temp file Need for Speed - High Stakes (USA).cue Deleting temp file TMP0.cu2 Deleting temp file ISO0001.iso Deleting temp file ICON0.jpg

Here is the Log from Duckstation: [ 0.3014] I/SDLControllerInterface: Loading game controller mappings from 'C:\Users\damon\Desktop\Duckstation\database\gamecont rollerdb.txt' [ 0.8932] I/AutoUpdaterDialog: Current SHA: 50db81af16025583c68171c1fdaf921b6e655175 [ 0.8932] I/AutoUpdaterDialog: Latest SHA: 50db81af16025583c68171c1fdaf921b6e655175 [ 0.8932] I/AutoUpdaterDialog: Last Checked SHA: [ 0.8932] I/AutoUpdaterDialog: No update needed. [ 15.5418] I/HostInterface: Boot Filename: D:\TEMP\PBP\NEED FOR SPEED - HIGH STAKES.pbp [ 15.5844] I/D3D11HostDisplay: No adapter selected, using first. [ 15.6117] I/D3D11HostDisplay: D3D Adapter: Intel(R) UHD Graphics [ 15.6118] I/D3D11HostDisplay: Creating a 2400x1767 flip-discard windowed swap chain [ 15.6135] I/D3D11HostDisplay: Swap chain buffer size: 2400x1767 [ 15.6684] E(LoadTexture): Failed to open texture resource 'resources\logo.png' [ 15.6713] I/HostInterface: Creating 'Cubeb' audio stream, sample rate = 44100, channels = 2, buffer size = 2048 [ 16.3927] I/CubebAudioStream: Minimum latency in frames: 133 [ 16.4654] I/System: Loading CD image 'D:\TEMP\PBP\NEED FOR SPEED - HIGH STAKES.pbp'... [ 16.4656] E(Open): Invalid number of discs (1) in multi-disc PBP file [ 16.4656] E(ReportError): Failed to load CD image 'D:\TEMP\PBP\NEED FOR SPEED - HIGH STAKES.pbp': [ 18.5554] E(ReportError): System failed to boot. The log may contain more information.

sahlberg commented 2 years ago

This sounds like a bug in the EBOOT parsing in duckstation.

What pop-fe does is that it always creates a PSTITLEIMG section in the EBOOT.PBP. This is a data structure that contains a list of all the disks that the game consists of as well as some additional metadata. And following this structure there is one PSISOIMG section for each disk of the game.

Now, PSTITLEIMG is required if you have multiple disks as this is where the offsets to all the disks are stored. So the structure of the disks internally in the PBP will look something like

PSTITLEIMG section PSISOIMG section for the first disk and then additional PSISOIMG sections for consecutive disks.

And the difference between a single disk and multi disk PBP is just how many PSISOIMG sections there are. If there is one then it is a single disc game. If there are multiple, then it is a multidisc game.

As a convenience, there is a special case. IF there is only one disk then the EBOOT.PBP can optionally skip the PSTITLEIMG section and instead just pass in the PSISOIMG section.

What I think the bug is is that DuckStation assumes that single disk games MUST be in the second format without a PSTITLEIMG section and thus flags the error. This is a bug because it is perfectly allowed to have also a PSTITLEIMG section for single disk games and both PSP and PS3 accept this format. These formats are somewhat poorly understood and the reverse engineering of them is incomplete. What I think might have happened is that they might have looked at the sources of the old c-based popstation, like this one : https://github.com/moparisthebest/popstation because it does create EBOOT.PBP files without a PSTITLEIMG section for single disk games and then they might have assumed that this is a hard rule when it is not.

The reason I always insert the PSTITLEIMG section is because it makes the code simpler to just have one codepath and just generate one type of EBOOT.PBP structure instead of two.

I think it should be fairly trivial for the DuckStation forlks to fix this. Somewhere in the code there is likely some conditional that has

if has(PSTITLEIMG section) and number of disks == 1 then print error and abort

which is wrong and should be removed.

As a temporary workaround you could add a small iso as the second disk for your EBOOTS. If the they can not fix this in DuckStation then I could make a change to pop-fe to force creation of a EBOOT without the PSTITLEIMG section but I would like to avoid that if possible as it would make the code more complex.

sahlberg commented 2 years ago

Patch for duckstation to fix this issue https://github.com/sahlberg/duckstation/commit/449d5a30075395f1084254d8b1b892669f74c843

They don't allow unknown people (== me) to send pull requests to their repo so we need to figure out an alternative way to get it into duckstation.

jdgleaver commented 2 years ago

@sahlberg I took the liberty of applying your fix to RetroArch's Swanstation core: https://github.com/libretro/swanstation/pull/11

I just wanted to say thank you for this, and for your truly excellent pop-fe utility :)