Add claude docs
This commit is contained in:
@@ -0,0 +1,200 @@
|
||||
# Platform -- Sony PSP
|
||||
|
||||
`DUSK_TARGET_SYSTEM`: `psp`
|
||||
Source layer: `src/duskpsp/`
|
||||
Renderer: OpenGL ES (legacy, via PSPGL/SDL2)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The PSP is a 32 MB MIPS-based handheld console running at up to 333 MHz.
|
||||
It uses SDL2 (ported to PSP) for windowing and OpenGL in legacy/fixed-
|
||||
function mode. The game binary and all assets are packaged together inside
|
||||
a `.pbp` file -- the PSP's native executable format.
|
||||
|
||||
---
|
||||
|
||||
## Hardware
|
||||
|
||||
| Attribute | Value |
|
||||
|-----------|-------|
|
||||
| CPU | MIPS R4000 (Allegrex), up to 333 MHz |
|
||||
| RAM | 32 MB (4 MB reserved for OS) |
|
||||
| Display | 480x272, 16/32-bit colour |
|
||||
| Storage | Memory Stick (UMD for retail; MS for homebrew) |
|
||||
| Endian | Little-endian |
|
||||
|
||||
---
|
||||
|
||||
## Compile-time macros
|
||||
|
||||
| Macro | Set |
|
||||
|-------|-----|
|
||||
| `DUSK_PSP` | yes |
|
||||
| `DUSK_SDL2` | yes |
|
||||
| `DUSK_OPENGL` | yes |
|
||||
| `DUSK_OPENGL_LEGACY` | yes |
|
||||
| `DUSK_INPUT_GAMEPAD` | yes |
|
||||
| `DUSK_PLATFORM_ENDIAN_LITTLE` | yes |
|
||||
| `DUSK_DISPLAY_WIDTH` | 480 |
|
||||
| `DUSK_DISPLAY_HEIGHT` | 272 |
|
||||
| `DUSK_THREAD_PTHREAD` | yes |
|
||||
|
||||
No `DUSK_DISPLAY_SIZE_DYNAMIC` -- the resolution is fixed.
|
||||
No `DUSK_INPUT_KEYBOARD`, no `DUSK_INPUT_POINTER`.
|
||||
|
||||
---
|
||||
|
||||
## Display
|
||||
|
||||
- Fixed 480x272 resolution.
|
||||
- OpenGL legacy (fixed-function pipeline, `DUSK_OPENGL_LEGACY`).
|
||||
- Texture dimensions **must** be powers of two (use `mathNextPowTwo`).
|
||||
- VFPU (4-wide float SIMD) is available -- use it for matrix/vector hot
|
||||
paths under `#ifdef DUSK_PSP`.
|
||||
|
||||
---
|
||||
|
||||
## Asset loading
|
||||
|
||||
Assets are packed into the **PSAR** section of the `.pbp` file by the
|
||||
post-build `create_pbp_file()` CMake command. At runtime,
|
||||
`assetInitPBP()` locates and opens the PSAR from the running executable's
|
||||
path.
|
||||
|
||||
The PBP format header:
|
||||
```c
|
||||
typedef struct {
|
||||
char_t signature[4]; // "\0PBP"
|
||||
uint32_t version;
|
||||
uint32_t sfoOffset;
|
||||
uint32_t icon0Offset;
|
||||
uint32_t icon1Offset;
|
||||
uint32_t pic0Offset;
|
||||
uint32_t pic1Offset;
|
||||
uint32_t snd0Offset;
|
||||
uint32_t pspOffset;
|
||||
uint32_t psarOffset; // dusk.dsk starts here
|
||||
} assetpbpheader_t;
|
||||
```
|
||||
|
||||
`assetpbp_t` holds the open file handle and parsed header. Asset paths
|
||||
inside the PSAR are ZIP paths within `dusk.dsk`.
|
||||
|
||||
---
|
||||
|
||||
## Input
|
||||
|
||||
Layered on SDL2. `inputInitPSP()` maps PSP physical buttons to SDL2
|
||||
`SDL_CONTROLLER_BUTTON_*` constants:
|
||||
|
||||
| PSP button | Action |
|
||||
|------------|--------|
|
||||
| Cross | Accept |
|
||||
| Circle | Cancel |
|
||||
| Triangle | - |
|
||||
| Square | - |
|
||||
| L / R | Shoulder buttons |
|
||||
| D-pad | Directional |
|
||||
| L-Stick | Analog axes |
|
||||
|
||||
No keyboard or pointer input available. Attempting to use
|
||||
`INPUT_BUTTON_TYPE_KEYBOARD` on PSP is undefined behaviour.
|
||||
|
||||
The PSP system setting `PSP_UTILITY_ACCEPT_CROSS` / `ACCEPT_CIRCLE`
|
||||
swaps the Cross and Circle button roles in OS dialogs -- read this via
|
||||
`systemPSPGetCrossButtonSetting()` if you need to match the system
|
||||
convention.
|
||||
|
||||
---
|
||||
|
||||
## Save system
|
||||
|
||||
- Path: `ms0:/PSP/SAVEDATA/<TITLE_ID><slot>/save.dat`
|
||||
(default title ID `DUSK00001`, configurable via `SAVE_PSP_TITLE_ID`).
|
||||
- Uses `sceIo` for file I/O -- no extra dialog required for raw reads.
|
||||
- PSP OS-level save/load dialogs (via `sceUtility`) are separate and
|
||||
block the main loop when open (`systemGetActiveDialogType()` returns
|
||||
`SYSTEM_DIALOG_TYPE_TICK_BLOCKING`).
|
||||
- Do not call save functions directly from game code during a dialog.
|
||||
|
||||
---
|
||||
|
||||
## Network
|
||||
|
||||
Connection requires an explicit user Wi-Fi selection step via the PSP
|
||||
system network dialog (`sceUtilityNetconfInitStart`).
|
||||
|
||||
```
|
||||
networkRequestConnection(onConnected, onFailed, onDisconnect, user);
|
||||
// -> shows PSP Wi-Fi selection dialog (blocking dialog type)
|
||||
// -> calls onConnected or onFailed when the dialog closes
|
||||
```
|
||||
|
||||
HTTP and SSL modules (`psphttp`, `pspssl`, `pspnet_resolver`) are
|
||||
linked in `psp.cmake` but the HTTP implementation code is commented out.
|
||||
The infrastructure exists for future use.
|
||||
|
||||
---
|
||||
|
||||
## Time
|
||||
|
||||
- Tick source: `SDL_GetTicks64()`.
|
||||
- Real time: `sceRtcGetCurrentTick()` (returns microseconds).
|
||||
- Dynamic timestep is **not** enabled (`DUSK_TIME_DYNAMIC` not set).
|
||||
Every tick is a fixed 16 ms step.
|
||||
|
||||
---
|
||||
|
||||
## System dialogs
|
||||
|
||||
PSP shows OS-level dialogs for:
|
||||
- Wi-Fi configuration (`networkRequestConnection`)
|
||||
- Save management (if using `sceUtility` save dialogs)
|
||||
|
||||
Check `systemGetActiveDialogTypePSP()` to know whether the main loop
|
||||
should skip rendering or ticking.
|
||||
|
||||
---
|
||||
|
||||
## Build and toolchain
|
||||
|
||||
Requires the [PSPDEV toolchain](https://github.com/pspdev/pspdev).
|
||||
Set `PSPDEV` in your environment before configuring.
|
||||
|
||||
```sh
|
||||
cmake -B build \
|
||||
-DDUSK_TARGET_SYSTEM=psp \
|
||||
-DCMAKE_TOOLCHAIN_FILE=${PSPDEV}/lib/cmake/psp.cmake \
|
||||
-DCMAKE_BUILD_TYPE=Release
|
||||
cmake --build build
|
||||
```
|
||||
|
||||
Post-build output: `Dusk.pbp` (executable + assets combined).
|
||||
|
||||
Dependencies: SDL2-PSP, OpenGL-PSP, pspgu, pspctrl, pspdisplay,
|
||||
pspaudio, pspaudiolib, psputility, pspvfpu, pspvram, pspnet,
|
||||
pspnet_inet, pspnet_apctl, psphttp, pspssl, pspdebug, psphprm,
|
||||
mbedtls, mbedcrypto, lzma, zip, bz2, z.
|
||||
|
||||
---
|
||||
|
||||
## Endianness
|
||||
|
||||
Little-endian. `DUSK_PLATFORM_ENDIAN_LITTLE` is set at compile time.
|
||||
No runtime endian check is needed.
|
||||
|
||||
---
|
||||
|
||||
## Gotchas
|
||||
|
||||
- The PSP has only 28 MB of usable RAM after the OS. Keep asset budgets
|
||||
tight -- see `.claude/optimization.md`.
|
||||
- VFPU instructions are not valid on threads other than the main thread
|
||||
on some firmware versions. Use `assertIsMainThread` on any code that
|
||||
calls VFPU intrinsics.
|
||||
- OpenGL legacy mode means no vertex/fragment shaders; rendering uses
|
||||
the fixed-function pipeline via `pspgl`.
|
||||
- `DUSK_TIME_DYNAMIC` is absent -- physics always runs at exactly the
|
||||
fixed step rate.
|
||||
Reference in New Issue
Block a user