Files
deadinsideandClaude Opus 5.5 9f74a6035d Tidy the repository for publishing: layout, README (EN/RU), license, launcher save folder
- Layout: src/ (loader, runtime), scripts/ (image preparation, patch compiler),
  tests/, tools/ (developer tools, fetch_fsr4_assets.sh, bridge helper,
  diagnostics), docs/history/ (dated reports); build.sh, run.sh, CMake,
  packaging, tools and tests follow the new paths. Raw run log removed.
- Submodules: FSR-Vulkan points at upstream c64f093 and build.sh applies
  gpu/patches/fsr-vulkan to its working tree; LibAtrac9 registered in
  .gitmodules; build.sh initializes missing submodules.
- No absolute home paths in scripts; the desktop entry is a template
  installed by launcher/install-desktop.sh.
- Launcher: the save folder is chosen with a folder dialog (default shown,
  reset, open in the file manager), status icons that exist in Adwaita,
  upscaler asset status for FSR 4 / 4.1.1.
- README.md / README.ru.md: what it is, status, highlights, differences from
  shadPS4, build/run, assets, layout, roadmap, credits. LICENSE: GPL-2.0.
- tests/test_probe.py: expectations updated to the loader's current messages.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-01 08:42:38 +03:00

27 lines
1.3 KiB
Python

"""Prepare explicit offline AppContent metadata; SKU is a probe setting, not a license check."""
import argparse
import json
import struct
from pathlib import Path
from prepare import sfo
def prepare(game, out, sku='full'):
values=sfo((game/'sce_sys/param.sfo').read_bytes())
params=[values.get(f'USER_DEFINED_PARAM_{i}',0) for i in range(1,5)]
if any(type(v) is not int or not 0<=v<=0xffffffff for v in params):
raise ValueError('invalid user-defined parameter')
profile=dict(title_id=values.get('TITLE_ID'),sku=sku,sku_source='explicit probe setting',
user_params=params, mounted_addons=[],boot_attr=0)
out.mkdir(parents=True,exist_ok=True)
(out/'content.bin').write_bytes(struct.pack('<8s5I',b'BBCONT01',{'full':3,'trial':1}[sku],*params))
(out/'content-profile.json').write_text(json.dumps(profile,indent=2)+'\n')
print(f'AppContent profile: SKU={sku} (probe setting), user params={params}, mounted add-ons=0')
if __name__=='__main__':
p=argparse.ArgumentParser(description=__doc__)
p.add_argument('game',type=Path)
p.add_argument('--out',type=Path,default=Path(__file__).resolve().parent.parent/'out')
p.add_argument('--sku',choices=['full','trial'],default='full')
a=p.parse_args();prepare(a.game,a.out,a.sku)