# ports_jetsetradio **Repository Path**: windstarry/ports_jetsetradio ## Basic Information - **Project Name**: ports_jetsetradio - **Description**: jetsetradio的移植 - **Primary Language**: Unknown - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-09-26 - **Last Updated**: 2026-09-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 街头涂鸦(Jet Set Radio)掌机通用移植 > **来源说明**:本工程将 SEGA 官方 Android 版 Jet Set Radio(1.07,`com.sega.jetsetradio`)经自研 Linux ARMHF 加载器移植到 PortMaster 通用掌机。游戏本体文件不随仓库分发。 > **项目定位**:PortMaster 通用版,适配 muOS / Knulli / dArkOS / ROCKNIX / EmuELEC 等,标准契约(`control.txt`、`device_info.txt`、`mod_${CFW_NAME}.txt`、`PORT_32BIT`)。 > **状态:WIP**。 仓库不包含 APK、OBB、`libjetsetradio.so` 与 `gamedata/` 游戏资源,需自行放置(见安装)。 ## 适配范围 - 目标架构:armhf 32 位(`ld-linux-armhf.so.3`) - 实测方向:开源掌机 - 复用机制:Bionic/JNI 兼容层、软浮点 ABI 转译、SDL2 图形/输入/音频、GLES2 渲染、内嵌 FFmpeg 6.1.2 播放 FMV ## 架构说明 游戏本体是无源码的 32 位 ARMv7 Android 库(`libjetsetradio.so`),由加载器 `jetsetradio.armhf` 直接 `dlopen` 并桥接: 1. **`jetsetradio.armhf`(armhf PIE)** —— 假 JNIEnv / Activity / Audio 回调,驱动 SEGA KATANA 框架; 2. **软浮点转译** —— `libjetsetradio.so` 为 softfp,GL 浮点入口经 `pcs("aapcs")` 桥接;`setjmp/longjmp` 使用 bionic 尺寸 `jmp_buf`; 3. **FMV** —— 内嵌最小 FFmpeg 6.1.2(LGPL),YUV420 → GLES2 shader,带字幕; 4. **数据** —— OBB/zip 按需解包到 `gamedata/`(`DATA/` + `CUSTOM/`),首次启动完成。 ## 功能特性 - 启动、涂鸦、比赛、存档(`gamedata/SAVE/`) - 原生手柄映射;Start+Select 长按退出(加载器内处理,先刷存档) - Select+L1 切换虚拟触摸光标 - `logs/files.log` 记录游戏打开的每个文件(OK/MISSING/NEW) - `logs/data_check.log` 校验 503 个数据文件名 ## 操作控制 | 动作 | 按键 | |---|---| | 移动 | 左摇杆 / 十字键 | | 视角 | 右摇杆 | | 跳跃 | A | | 返回 | B | | 涂鸦 | L1 / L2 / X | | 冲刺 | R1 / R2 / Y | | 暂停 | Start | | Android Back | Select | | 退出 | Start + Select 长按 | | 虚拟光标 | Select + L1 | | 跳过视频 | A / B / Start | 完整映射见 `portmaster/jetsetradio/controls.txt`。 ## 安装 1. 将 `portmaster/街头涂鸦.sh` 放到 `roms/ports/`(或前端对应的 ports 脚本目录); 2. 将 `portmaster/jetsetradio/` 放到 `roms/ports/jetsetradio/`; 3. 把合法获取的 SEGA 1.07 APK(`com.sega.jetsetradio`)放入 `roms/ports/jetsetradio/`; 4. 把数据(`main.*.com.sega.jetsetradio.obb` / `JetSetRadioData.zip` / 已解包 `files/`)放入同目录; 5. 通过 PortMaster 启动「街头涂鸦」。首次启动抽取 `libjetsetradio.so` 并解包数据。日志:`roms/ports/jetsetradio/log.txt`。 ## 构建 加载器在本地 Docker 镜像内交叉编译(armhf,hard-float,NEON): ```bash # 1) 构建派生镜像(国内源 + armhf FFmpeg/SDL2/zlib) docker build -t jetsetradio-builder:armhf runtime/docker # 2) 编译加载器 bash runtime/build-docker.sh ``` - 基础镜像:`portmaster-builder:aarch64-armhf-zen2`(entrypoint 为 `qemu-aarch64-static`,需显式传 `/usr/bin/bash`) - 工具链:`arm-linux-gnueabihf-gcc`(Ubuntu 9.4) - FFmpeg:Ubuntu focal armhf 动态库(4.2),已拷贝到 `portmaster/jetsetradio/libs.armhf/` - 产物 `runtime/out/jetsetradio.armhf`(ELF32 ARM,已用 `tools/assert_elf.ps1` 校验)→ 更新 `baseline/` 注意:`runtime/src/video.c` 含 FFmpeg 4.x/5+ 通道布局 API 兼容层。 ## 大体积产物不入库 `gamedata/`(约 1.2 GB)、`lib/libjetsetradio.so`、APK/OBB 不随源码提交,由用户自备或 `setup.ps1` 从 APK 抽取。 ## 运行库策略(ee47 实测) | 库 | 来源 | 说明 | |---|---|---| | `libSDL2-2.0.so.0` | `libs.armhf/` 随包 | ee47 系统 32 位 SDL2 为精简构建(kmsdrm 等后端缺失),必须自带 | | FFmpeg 4.x(`libav*.so`) | 系统 `/usr/lib32/` | ee47 已带完整 armhf FFmpeg,soname 兼容;**不要**捆绑 Ubuntu 版(会遮蔽系统库并拖入 `libgme` 等缺失依赖) | `ldd` 判据:设备上 `ld-linux-armhf.so.3 --list` 零 `not found` 即可。 ## 资产来源 | 文件 | 说明 | |---|---| | APK SEGA 1.07 | 包名 `com.sega.jetsetradio`,armeabi-v7a;`lib/armeabi-v7a/libjetsetradio.so` | | OBB `main.*.com.sega.jetsetradio.obb` | 或 `JetSetRadioData.zip` / 已解包 `files/` | | 加载器源码 | `jetsetradio_loader_src_v1.1`(本仓库 `runtime/`) | ## 致谢 - 移植方案参考 NFS Most Wanted / Galaxy on Fire 2 在掌机上的 PortMaster 做法 - FFmpeg 6.1.2(LGPL)—— 见 `portmaster/jetsetradio/licenses/` - 原始游戏:SEGA / Blit Software Jet Set Radio 是 SEGA 的商标。本项目为非官方的兼容性项目。