Skip to content

Repository files navigation

PSP-BookReader

Turn a Sony PSP into a dedicated EPUB reader.

PSP-BookReader is a C++/SDL2 homebrew app for reading EPUB books on real PSP hardware, with cover art, persistent progress, theme controls, TATE rotation, and careful optimization for the PSP's memory and battery limits.

PSP-BookReader Library View

Features

  • Interface: Library view with cover art support and system status overlays.
  • Orientation: Supporting vertical (TATE) mode for a 9:16 reading aspect ratio.
  • Typography: TrueType font rendering with character cache.
  • Navigation: Chapter-based navigation and persistent page tracking.
  • Library Management: Metadata extraction and persistent caching for library indexing.
  • Resource Efficiency: LRU texture caching and incremental background layout.
  • Customization: User-selectable themes (Night, Sepia, Light), font scale, and margin adjustments.
  • System Integration: Real-time clock and battery percentage monitoring.
  • Wide Character Support: Conditional font switching for CJK (Chinese, Japanese, Korean) and Latin/Cyrillic scripts.
  • Power Management: Dynamic frequency scaling and inactivity-based frame throttling.

Why It Stands Out

  • Built for real PSP constraints: Designed around 32MB RAM limits, texture caps, and Memory Stick I/O bottlenecks.
  • Actually pleasant to read on: Themes, font scaling, margin controls, chapter navigation, and progress persistence make it feel like a reader instead of a tech demo.
  • Hardware-aware battery savings: Dynamic CPU scaling and idle throttling reduce power draw during long reading sessions.
  • Unusual but useful device reuse: It gives old PSP hardware a calm, practical second life as a pocket ebook reader.

Quick Start

  1. Download the latest packaged release from the GitHub Releases page, or build it yourself with the PSP toolchain.
  2. Copy the app folder containing EBOOT.PBP to PSP/GAME/ on your Memory Stick.
  3. Keep the bundled fonts/ assets alongside the app files.
  4. Place your .epub files where the app can index them.
  5. Launch the app from the PSP Game menu.

Controls

Button Action
Cross (X) Select Book / Open Menu Item
Circle (O) Rotate Screen (TATE Mode)
Triangle Open/Close Chapter Menu
Start Return to Library (from Reader) / Exit App (from Library)
Select Open Settings Menu
L / R Triggers Fast Scroll (Library) / Page Turn (Reader)
D-Pad Up/Down Navigate Menu / Font Size Adjustment
D-Pad Left/Right Navigate Library / Adjust Settings

Build Instructions

Dependencies

The project requires the following libraries in the PSP toolchain:

  • SDL2: System abstraction and rendering.
  • SDL2_ttf: FreeType-based font rendering.
  • SDL2_image: Image decoding (PNG/JPG).
  • pugixml: XML parsing for metadata and navigation.
  • miniz: ZIP extraction for EPUB data.

Building

  1. Configure the PSPdev toolchain.
  2. Install dependencies via the toolchain package manager (e.g., psp-pacman).
  3. Execute make in the repository root.

The resulting EBOOT.PBP will be located in the root directory.

Technical Implementation Details ("Development Hacks")

Developing a modern reader for hardware with 32MB of RAM required several specific architectural optimizations and workarounds.

1. Dynamic Power Management (DFS)

To maximize battery life, the application implements event-driven frequency scaling:

  • Automated Scaling: The CPU drops to 66MHz after 2 seconds of inactivity, scaling back to 222MHz for UI interaction and 333MHz for intensive tasks like library scanning.
  • Frame Throttling: The main loop reduces poll frequency when idle, significantly lowering CPU utilization during passive reading.

2. The CJK Tokenizer Hack

Without a heavy dictionary-based tokenizer, supporting CJK line-breaking is difficult.

  • Byte-Level Detection: The extractor identifies 3-byte UTF-8 sequences (typical for CJK ideographs) and treats each as a standalone "word."
  • Arithmetic Wrapping: This allows the standard whitespace-based layout engine to wrap CJK text correctly without dedicated script-aware logic.

3. Adaptive Incremental Layout

To prevent UI stutter upon loading large book chapters, we avoid blocking the main thread.

  • Frame Throttling: The layout engine processes 500 words per frame. This budget is dynamically doubled if the user is actively waiting (e.g., pressing "Next Page").
  • Position Anchors: Reading positions are tracked via word indices. When the user changes font size or rotates the screen, the engine reflows the text and instantly scrolls to maintain the exact word position.

4. Hardware-Specific Memory Guards

On the PSP-1000, 32MB of RAM is extremely restrictive.

  • Cover Guard: Uncompressed images are limited to 2MB. Larger covers are rejected to prevent OOM (Out of Memory) crashes.
  • GE Texture Limit: The PSP Graphics Engine has a 512x512 texture size limit. The app detects oversized covers and re-samples them locally to stay within hardware bounds.

5. Disk I/O & Serialization Hacks

  • RWops Buffering: Data is decompressed via miniz directly to memory and fed to SDL via SDL_RWFromMem. This bypasses the slow Memory Stick I/O for all image decoding.
  • Zero-Overhead Serialization: App settings and reading progress are stored as a raw binary dump of the struct (config.bin). This is significantly faster than JSON/XML parsing on handheld hardware.
  • Metadata Caching: A library.cache file stores book info, avoiding expensive ZIP/XML parsing on every launch.

6. Optimized Font Pipeline

  • Dual-Tier Caching: Uses a combined hardware texture cache and a theoretical metrics cache (FNV-1a hashed) to make layout an O(N) arithmetic task.
  • Zero-Check Font Switching: Detects book language from OPF metadata and locks the renderer to a specific font (Droid Sans Fallback vs Inter) to avoid per-character Unicode checks during the render loop.

7. TATE Coordinate Engine

  • Input Remapping: While SDL_RenderCopyEx handles the visual 90-degree rotation, the input handler uses a specialized remap matrix for the D-Pad and Analog axes to keep navigation intuitive.
  • Event Latching: Atomic state transitions in the input handler prevent "double-triggering" across multiple logical states in a single frame.

Promotion Notes

This project tends to resonate with:

  • PSP homebrew and retro handheld communities
  • EPUB and ebook tooling communities
  • People who enjoy repurposing older hardware
  • Developers interested in optimization on constrained devices

If you share it publicly, lead with the core hook: a real EPUB reader running on original PSP hardware, not just an emulator demo.

For launch copy and channel planning, see LAUNCH_COPY.md and PROMOTION_PLAN.md.

Contribution

Technical contributions are welcome via Pull Requests.

License

This project is open source.

About

Turn a Sony PSP into a dedicated EPUB reader.

Topics

Resources

Stars

8 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages