Toggle menu
Toggle preferences menu
Toggle personal menu
Not logged in
Your IP address will be publicly visible if you make any edits.

3DSlibris: Difference between revisions

From GameBrew
No edit summary
No edit summary
Line 4: Line 4:
|description=eBook Reader. Port of dslibris.
|description=eBook Reader. Port of dslibris.
|author=Rigle
|author=Rigle
|lastupdated=2026/04/16
|lastupdated=2026/04/24
|type=Utilities
|type=Utilities
|version=2.3.0
|version=2.5.0
|license=GPL-2.0
|license=GPL-2.0
|download=https://github.com/RigleGit/3dslibris/releases
|download=https://github.com/RigleGit/3dslibris/releases
Line 89: Line 89:
** EPUB2 + EPUB3 content parsing with NAV and NCX table-of-contents support, plus fallback chapter labels when source metadata is incomplete
** EPUB2 + EPUB3 content parsing with NAV and NCX table-of-contents support, plus fallback chapter labels when source metadata is incomplete
** Persistent page cache keyed by layout inputs, so repeated opens can reuse compatible pagination instead of rebuilding every page
** Persistent page cache keyed by layout inputs, so repeated opens can reuse compatible pagination instead of rebuilding every page
** Configurable serif, sans, and monospace font families; <code>pre</code> / <code>code</code> blocks now reflow and measure with the active monospace face
** Configurable serif, sans, and monospace font families; <code>pre</code> / <code>code</code> blocks now reflow and measure with the active monospace face
** Monospace regular, bold, italic, and bold-italic variants are preserved when matching fonts are available
** Monospace regular, bold, italic, and bold-italic variants are preserved when matching fonts are available
** Inline formatting support includes bold, italic, underline, strikethrough, overline, superscript, subscript, and CSS-driven dotted/dashed/wavy underline markers
** Inline formatting support includes bold, italic, underline, strikethrough, overline, superscript, subscript, and CSS-driven dotted/dashed/wavy underline markers
** Block formatting covers headings, paragraphs, lists, nested ordered lists, blockquotes, asides, figures, captions, definition lists, and horizontal rules
** Block formatting covers headings, paragraphs, lists, nested ordered lists, blockquotes, asides, figures, captions, definition lists, and horizontal rules
** Tables are linearized into readable label/value blocks for the 3DS screen instead of trying to preserve wide desktop table layout
** Tables are linearized into readable label/value blocks for the 3DS screen instead of trying to preserve wide desktop table layout
** Common hidden accessibility/helper text is ignored when marked with <code>hidden</code>, <code>aria-hidden</code>, <code>display:none</code>, <code>visibility:hidden</code>, or <code>visually-hidden</code>-style classes
** Common hidden accessibility/helper text is ignored when marked with <code>hidden</code>, <code>aria-hidden</code>, <code>display:none</code>, <code>visibility:hidden</code>, or <code>visually-hidden</code>-style classes
** Cosmetic EPUB print-page markers such as hidden <code>epub:type=&quot;pagebreak&quot;</code> / <code>role=&quot;doc-pagebreak&quot;</code> spans are ignored instead of forcing bogus page breaks in the reflowed text
** Cosmetic EPUB print-page markers such as hidden <code>epub:type=&quot;pagebreak&quot;</code> / <code>role=&quot;doc-pagebreak&quot;</code> spans are ignored instead of forcing bogus page breaks in the reflowed text
** CSS list marker suppression is honored for reflowed lists, including class-driven rules such as <code>list-style-type: none</code>
** CSS list marker suppression is honored for reflowed lists, including class-driven rules such as <code>list-style-type: none</code>
** Switching from one already-open book to another from the library no longer reuses stale reader state or leaves the app stuck on the opening screen after a failed open
** Switching from one already-open book to another from the library no longer reuses stale reader state or leaves the app stuck on the opening screen after a failed open
** Punctuation handling keeps Spanish opening/closing punctuation attached across inline style boundaries in common cases
** Punctuation handling keeps Spanish opening/closing punctuation attached across inline style boundaries in common cases
Line 184: Line 184:


== Changelog ==
== Changelog ==
'''v2.5.0'''
* Highlights
** '''Text alignment support''': <code>text-align: center</code> and <code>text-align: right</code> are now honoured in EPUB reflow. Each paragraph emits an alignment token that the draw routine uses to compute per-line offset, so wrapped lines stay correctly aligned across the whole paragraph.
** '''Performance improvements''': EPUB CSS scanning now reads only the <code>&lt;head&gt;</code> section of each spine document, reducing zip I/O on large books (~1 second less loading time). A single zip handle is recycled across all spine CSS scans (~20% less loading time). Plain text pagination eliminates per-line heap allocation. First-time EPUB cover extraction is ~3× faster on old 3DS via MuPDF subsampled thumbnail decode.
* Included fixes and behavior changes
** '''Browser return and suspend handling stabilized''': returning from the reader to the library now correctly resumes browser jobs and handles applet suspend/resume, avoiding tearing down in-flight async opens during HOME suspension.
** '''Gallery covers clipped correctly''': cover thumbnails in gallery view are clipped to the rounded frame, preventing image pixels from bleeding outside the card border.
** '''PDF HOME button crash fixed''': PDF file parsing is now split into independently cancellable steps, each with an APT yield point, so pressing HOME during PDF loading is handled cleanly instead of causing a console restart.
** '''Large EPUB page limit raised''': the maximum pages in memory raised from 5,000 to 25,000 (cache guard to 50,000), fixing books that stopped loading halfway through.
** '''HR overflow tracking fixed''': parser and renderer now agree on vertical position after <code>&lt;hr&gt;</code> rules, preventing text overlap after horizontal rules.
** '''PagedListMenu overflow fixed''': pagination indices changed from <code>u8</code> to <code>u16</code> so menus with more than 255 entries no longer wrap and corrupt the page list.
** '''SDMC zip trimmed''': <code>3dslibris-sdmc.zip</code> now contains only SD card runtime files; the <code>.3dsx</code> builds are separate release assets instead of being duplicated inside the zip.
'''v2.4.2'''
* Highlights
** '''Stability and crash-fix release''': addresses several null dereference, divide-by-zero, out-of-bounds, and infinite-loop issues identified on real hardware.
* Included fixes and behavior changes
** '''FontManager null dereference crash fixed''': <code>GetFace()</code> now uses <code>find()</code> and returns <code>NULL</code> for missing style keys instead of silently inserting a null entry via <code>operator[]</code>; all callers guard against <code>NULL</code> before dereferencing.
** '''Division by zero in browser marquee fixed''': the background color averaging loop now guards against zero-dimension covers before dividing.
** '''Degenerate layout when font height is zero fixed''': a <code>line_height</code> floor of 10 pixels is enforced so menus do not collapse to unreadable or non-interactive rows when no valid face is loaded.
** '''Out-of-bounds touch in empty list menus fixed''': <code>PagedListMenu::HandleTouchInput()</code> now returns early when the button vector is empty, avoiding an out-of-bounds read.
** '''Infinite loop in text wrapping fixed''': <code>WrapTextToLines()</code> now forces a minimum advance of 1 byte so the loop always makes progress on zero-width or unrecognised code points.
'''v2.4.1'''
* Highlights
** '''Crash-at-boot fix''': <code>FontMenu</code> is constructed during <code>App::App()</code> before fonts are loaded. Calling <code>GetHeight()</code> and <code>GetAdvance()</code> through the null font manager cascaded into a heap Data Abort immediately at startup. Both methods now return safe defaults until the font manager is initialised.
'''v2.4.0'''
* Highlights
** '''Six-color theme system''': the app now supports six palette-based color themes (light, sepia, dark, and three more), each controlling text, background, UI chrome, and cover overlays consistently across all views.
** '''Dark/light splash screen variants''': the startup splash now uses a dark or light version that matches the active color mode.
** '''Cycle themes with X in the browser''': press <code>X</code> in the library view to cycle through color modes without opening the settings menu.
** '''Gradient backgrounds in reader mode''': the top and bottom strips of the reading view now use a smooth gradient instead of a flat color.
** '''Improved bookmark menu''': entries now show a preview of the page text alongside the bookmark position.
** '''Improved chapter menu''': chapter titles wrap to up to three lines so long titles are no longer truncated.
** '''Dynamic row heights in PagedListMenu''': the shared paged-list component now sizes rows dynamically per page so entries always fit the available screen space.
** '''Browser warmup re-enabled''': cover extraction now runs incrementally on idle frames (3 ms budget), so covers populate without stalling the UI.
* Included fixes and behavior changes
** '''EPUB NAV spine ordering fixed''': chapter detection now correctly follows the <code>&lt;spine&gt;</code> order from the OPF manifest rather than assuming document order.
** '''Marquee background color fixed''': the browser grid marquee now correctly tracks the active dark theme background instead of always using the light color.
** '''Long font filenames wrap in FontMenu''': font file paths too long for a single line now wrap cleanly instead of being clipped.
'''v2.3.2'''
* Highlights
** '''MOBI structured TOC restored''': the HTML-to-text position map is now built during safe-extractor parsing, so structured TOC entries are resolved to accurate page numbers instead of falling back to linear estimation.
** '''MOBI inline images restored''': images embedded in MOBI HTML are now registered and rendered in the reading view; previously the safe extractor wired up no callbacks and all inline images were silently dropped.
** '''MOBI page cache re-enabled''': the second open of a large MOBI now loads from cache in roughly 3.7 s instead of re-parsing for roughly 9 s.
** '''Browser grid covers load on view toggle''': switching from list to grid view now immediately loads covers for the visible page instead of showing empty slots until the next navigation event.
** '''EPUB large PNG covers decode via libpng''': covers larger than 4 MB now use a direct libpng thumbnail path that scales to 85×115 px while keeping peak memory low.
** '''EPUB SVG covers rendered via MuPDF''': SVG cover images are rasterized at thumbnail size using the MuPDF fitz renderer instead of being skipped or incorrectly decoded.
'''v2.3.1'''
* Highlights
** '''All background workers disabled for this release''': fixed-layout rendering (PDF, CBZ), MOBI finalization, and browser warmup all run synchronously on the main thread, trading some speed for confirmed reliability on real hardware.
** '''Reading direction toggle for fixed-layout documents''': PDF, CBZ, and XPS now have a per-book <code>reading direction</code> toggle in <code>BOOK</code> settings. Switch between <code>Left to right</code> (default, western) and <code>Right to left</code> (manga, Arabic, Hebrew).
** '''Book opening and switching are much harder to break''': stale open sessions are gated more carefully, browser-side background work is paused at the right time, and the transition between books no longer relies on timing-sensitive state.
** '''PDF and CBZ now render at zoom-correct resolution''': in synchronous mode the interactive tile is rendered immediately after the preview, so zoomed-in content is sharp rather than upscaled from the preview bitmap.
** '''MOBI crash on reopen is fixed''': a large contiguous heap reservation during text merging could <code>std::terminate</code> on a fragmented 3DS heap after a prior book close; the reservation is removed and the string now grows incrementally.
* Included fixes and behavior changes
** '''EPUB inline image metadata retried on zip open failure''': if <code>unzOpen</code> fails due to transient memory pressure, <code>metadata_probed</code> is left false so the next frame retries instead of permanently marking the image as unloadable.
** '''Book vector capacity released on close''': <code>pages</code> and <code>chapters</code> vectors now swap with an empty vector on <code>Book::Close()</code>, actually freeing capacity rather than just clearing size.
** '''Opening a book is cancellable and session-safe''': an in-progress open can now be cancelled with <code>B</code>, <code>Start</code>, or <code>Select</code>, and switching books no longer depends on stale callbacks or unfinished work from the previous session.
'''v2.3.0'''
'''v2.3.0'''
* Highlights
* Highlights

Revision as of 04:48, 26 April 2026

3DSlibris
General
AuthorRigle
TypeUtilities
Version2.5.0
LicenseGPL-2.0
Last Updated2026/04/24
Links
Download
Website
Source

Nintendo 3DS homebrew ebook reader based on the original Nintendo DS project dslibris.

3dslibris ports the original architecture to libctru, keeps the fast text-first reading model, and adds practical 3DS UX improvements (grid library, cover thumbs, indexed navigation, procedural UI skin, orientation-aware touch, etc.).

The current .cia packaging flow is based on the same makerom/bannertool process used by Universal-Updater, adapted to this project's assets and release layout.

Features

  • Custom fonts.
  • Bookmarks.
  • Table of contents/index support.
  • Left- and right-handed layouts.
  • Three color modes: Daylight, Night, and Book.
  • Strong EPUB support.
  • Good FB2, TXT, RTF and ODT support.
  • Experimental MOBI support.
  • PDF, CBZ, and XPS viewing (MuPDF-backed).

Installation

Recommended install:

  • Download 3dslibris-sdmc.zip from GitHub Releases.
  • Extract that zip into the root of your SD card, so it expands into sdmc:/.
  • Put your books in sdmc:/3ds/3dslibris/book/.
  • Launch sdmc:/3ds/3dslibris/3dslibris.3dsx from Homebrew Launcher.

Alternative install:

  • Install 3dslibris.cia.
  • Launch the installed title once so it creates sdmc:/3ds/3dslibris/ if needed.
  • Put your books in sdmc:/3ds/3dslibris/book/.
  • Launch the installed title.

Important:

  • The .cia bundles the default font/ and resources/ runtime assets inside RomFS, so it can boot without manually extracting 3dslibris-sdmc.zip.
  • Books are discovered from sdmc:/3ds/3dslibris/book/ and romfs:/3ds/3dslibris/book/.
  • If the same filename exists in both places, SD takes priority.
  • 3dslibris-sdmc.zip is still the recommended install for .3dsx, and it remains useful if you want the same runtime files laid out explicitly on SD.
  • 3dslibris-debug.3dsx uses the same SD layout and writes verbose diagnostics to sdmc:/3ds/3dslibris/3dslibris.log.
  • The .cia build uses the Universal-Updater-style packaging flow and now also validates the bundled RomFS path in GitHub Actions.

Generated install package targets:

  • make package-sdmc stages dist/sdmc/... with 3dslibris.3dsx included
  • make zip-sdmc creates dist/3dslibris-sdmc.zip
  • make cia creates 3dslibris.cia
  • make source-release creates dist/3dslibris-source.tar.gz
  • GitHub Releases: pushing a tag like v2.0.4 triggers .github/workflows/release.yml and attaches 3dslibris.cia, 3dslibris.3dsx, 3dslibris-debug.3dsx, dist/3dslibris-sdmc.zip, and dist/3dslibris-source.tar.gz to the release

Bundled runtime files:

  • sdmc/3ds/3dslibris/resources/splash.jpg
  • sdmc/3ds/3dslibris/resources/ui/icons/png/*.png
  • sdmc/3ds/3dslibris/book/README.md
  • sdmc/3ds/3dslibris/font/README.md
  • sdmc/3ds/3dslibris/font/Liberation*.ttf
  • sdmc/3ds/3dslibris/font/OFL-1.1.txt

Notes:

  • Homebrew Launcher path: keep the app at sdmc:/3ds/3dslibris/3dslibris.3dsx
  • Debug build path: keep 3dslibris-debug.3dsx in the same sdmc:/3ds/3dslibris/ folder if you want verbose logs
  • Default Liberation fonts are bundled in the SD package for .3dsx, and inside RomFS for .cia
  • You can replace them with other .ttf, .otf, or .ttc fonts if you want to customize the reading/UI typefaces
  • Runtime files such as 3dslibris.xml, 3dslibris.log, and cache/* are created by the app on first run
sdmc:/3ds/3dslibris/3dslibris.3dsx
sdmc:/3ds/3dslibris/book/*.epub|*.fb2|*.txt|*.rtf|*.odt|*.mobi
sdmc:/3ds/3dslibris/font/*.ttf
sdmc:/3ds/3dslibris/resources/splash.jpg
sdmc:/3ds/3dslibris/resources/ui/icons/png/{back,gear,home,next,prev}.png

Supported formats

Strong support

  • EPUB
    • EPUB2 + EPUB3 content parsing with NAV and NCX table-of-contents support, plus fallback chapter labels when source metadata is incomplete
    • Persistent page cache keyed by layout inputs, so repeated opens can reuse compatible pagination instead of rebuilding every page
    • Configurable serif, sans, and monospace font families; pre / code blocks now reflow and measure with the active monospace face
    • Monospace regular, bold, italic, and bold-italic variants are preserved when matching fonts are available
    • Inline formatting support includes bold, italic, underline, strikethrough, overline, superscript, subscript, and CSS-driven dotted/dashed/wavy underline markers
    • Block formatting covers headings, paragraphs, lists, nested ordered lists, blockquotes, asides, figures, captions, definition lists, and horizontal rules
    • Tables are linearized into readable label/value blocks for the 3DS screen instead of trying to preserve wide desktop table layout
    • Common hidden accessibility/helper text is ignored when marked with hidden, aria-hidden, display:none, visibility:hidden, or visually-hidden-style classes
    • Cosmetic EPUB print-page markers such as hidden epub:type="pagebreak" / role="doc-pagebreak" spans are ignored instead of forcing bogus page breaks in the reflowed text
    • CSS list marker suppression is honored for reflowed lists, including class-driven rules such as list-style-type: none
    • Switching from one already-open book to another from the library no longer reuses stale reader state or leaves the app stuck on the opening screen after a failed open
    • Punctuation handling keeps Spanish opening/closing punctuation attached across inline style boundaries in common cases
    • Inline SVG image wrappers are detected and resolved when they point to supported raster image assets

Good support (text-oriented)

  • FB2
  • TXT
  • RTF
  • ODT

Experimental / best-effort

  • MOBI
    • First open can be slow on large books (decompress + parse + pagination)
    • Subsequent opens are accelerated by persistent page cache
    • TOC quality is heuristic for many files (can be approximate)
    • Inline MOBI images now reuse the same smart inline / band / page layout pipeline used by EPUB/FB2, with better caption flow on mixed photo spreads
    • Includes an optional per-book line wrap fix for badly converted files that hard-wrap prose line by line, while preserving embedded image markers during cleanup
    • Empty or corrupt books are reported with a readable error instead of a raw numeric code
  • PDF
    • Viewer-only path with MuPDF-backed rendering
    • Top screen shows a zoomed page region; bottom screen shows the full-page preview and viewport box
    • Uses the shared fixed-layout reader controls documented below
    • PDF-enabled builds in this branch are distributed with AGPL-driven notice and source-release requirements; see the license section below
  • CBZ
    • Viewer-only path with MuPDF-backed image-page rendering
    • Uses the shared fixed-layout reader controls documented below
  • XPS
    • Viewer-only path with MuPDF-backed rendering
    • Uses the shared fixed-layout reader controls documented below

Known limitations

  • Some EPUB files have malformed anchors; index jumps can be approximate when source metadata is broken.
  • MOBI TOC extraction depends on file structure and may omit or merge entries in some books.
  • MOBI inline images depend on recoverable image references in the source markup, including the zero-padded recindex values commonly found in Kindle-generated books; malformed files can still miss some images.
  • Some malformed MOBI sources still contain encoding or OCR artifacts that cannot be repaired reliably on the reader side.
  • After changing font size, paragraph spacing, orientation, reading fonts, or the per-book MOBI line wrap fix, reopen the current book to apply the new layout.
  • Reading position and existing bookmarks are remapped approximately after that reopen and can shift a few pages from their original location.
  • No DRM support.

Controls

Library controls

D-Pad - Move the current selection around the library grid

A - Open the selected book

L / R - Jump to the previous or next library page

Touch - Tap a book to select it, tap it again to open it

Y / Select - Open settings

Default reading controls

A/B/L/R - Turn pages

D-Pad Left/Right - Jump between bookmarks

Y - Toggle bookmark

X - Change background color

Select - Settings

Start - Return to library

Touch UI for library, settings, index, bookmarks, font menus...

PDF / CBZ / XPS controls

A - Zoom in

B - Zoom out

Left/Right - Previous or next page

Up/Down - Next or previous chapter when the document exposes an outline; otherwise previous or next page

Touch - Move the viewport by tapping or dragging on the page preview

Select - Open settings

Start - Return to library

Screenshots

3dslibris2.png

3dslibris3.png

Changelog

v2.5.0

  • Highlights
    • Text alignment support: text-align: center and text-align: right are now honoured in EPUB reflow. Each paragraph emits an alignment token that the draw routine uses to compute per-line offset, so wrapped lines stay correctly aligned across the whole paragraph.
    • Performance improvements: EPUB CSS scanning now reads only the <head> section of each spine document, reducing zip I/O on large books (~1 second less loading time). A single zip handle is recycled across all spine CSS scans (~20% less loading time). Plain text pagination eliminates per-line heap allocation. First-time EPUB cover extraction is ~3× faster on old 3DS via MuPDF subsampled thumbnail decode.
  • Included fixes and behavior changes
    • Browser return and suspend handling stabilized: returning from the reader to the library now correctly resumes browser jobs and handles applet suspend/resume, avoiding tearing down in-flight async opens during HOME suspension.
    • Gallery covers clipped correctly: cover thumbnails in gallery view are clipped to the rounded frame, preventing image pixels from bleeding outside the card border.
    • PDF HOME button crash fixed: PDF file parsing is now split into independently cancellable steps, each with an APT yield point, so pressing HOME during PDF loading is handled cleanly instead of causing a console restart.
    • Large EPUB page limit raised: the maximum pages in memory raised from 5,000 to 25,000 (cache guard to 50,000), fixing books that stopped loading halfway through.
    • HR overflow tracking fixed: parser and renderer now agree on vertical position after <hr> rules, preventing text overlap after horizontal rules.
    • PagedListMenu overflow fixed: pagination indices changed from u8 to u16 so menus with more than 255 entries no longer wrap and corrupt the page list.
    • SDMC zip trimmed: 3dslibris-sdmc.zip now contains only SD card runtime files; the .3dsx builds are separate release assets instead of being duplicated inside the zip.

v2.4.2

  • Highlights
    • Stability and crash-fix release: addresses several null dereference, divide-by-zero, out-of-bounds, and infinite-loop issues identified on real hardware.
  • Included fixes and behavior changes
    • FontManager null dereference crash fixed: GetFace() now uses find() and returns NULL for missing style keys instead of silently inserting a null entry via operator[]; all callers guard against NULL before dereferencing.
    • Division by zero in browser marquee fixed: the background color averaging loop now guards against zero-dimension covers before dividing.
    • Degenerate layout when font height is zero fixed: a line_height floor of 10 pixels is enforced so menus do not collapse to unreadable or non-interactive rows when no valid face is loaded.
    • Out-of-bounds touch in empty list menus fixed: PagedListMenu::HandleTouchInput() now returns early when the button vector is empty, avoiding an out-of-bounds read.
    • Infinite loop in text wrapping fixed: WrapTextToLines() now forces a minimum advance of 1 byte so the loop always makes progress on zero-width or unrecognised code points.

v2.4.1

  • Highlights
    • Crash-at-boot fix: FontMenu is constructed during App::App() before fonts are loaded. Calling GetHeight() and GetAdvance() through the null font manager cascaded into a heap Data Abort immediately at startup. Both methods now return safe defaults until the font manager is initialised.

v2.4.0

  • Highlights
    • Six-color theme system: the app now supports six palette-based color themes (light, sepia, dark, and three more), each controlling text, background, UI chrome, and cover overlays consistently across all views.
    • Dark/light splash screen variants: the startup splash now uses a dark or light version that matches the active color mode.
    • Cycle themes with X in the browser: press X in the library view to cycle through color modes without opening the settings menu.
    • Gradient backgrounds in reader mode: the top and bottom strips of the reading view now use a smooth gradient instead of a flat color.
    • Improved bookmark menu: entries now show a preview of the page text alongside the bookmark position.
    • Improved chapter menu: chapter titles wrap to up to three lines so long titles are no longer truncated.
    • Dynamic row heights in PagedListMenu: the shared paged-list component now sizes rows dynamically per page so entries always fit the available screen space.
    • Browser warmup re-enabled: cover extraction now runs incrementally on idle frames (3 ms budget), so covers populate without stalling the UI.
  • Included fixes and behavior changes
    • EPUB NAV spine ordering fixed: chapter detection now correctly follows the <spine> order from the OPF manifest rather than assuming document order.
    • Marquee background color fixed: the browser grid marquee now correctly tracks the active dark theme background instead of always using the light color.
    • Long font filenames wrap in FontMenu: font file paths too long for a single line now wrap cleanly instead of being clipped.

v2.3.2

  • Highlights
    • MOBI structured TOC restored: the HTML-to-text position map is now built during safe-extractor parsing, so structured TOC entries are resolved to accurate page numbers instead of falling back to linear estimation.
    • MOBI inline images restored: images embedded in MOBI HTML are now registered and rendered in the reading view; previously the safe extractor wired up no callbacks and all inline images were silently dropped.
    • MOBI page cache re-enabled: the second open of a large MOBI now loads from cache in roughly 3.7 s instead of re-parsing for roughly 9 s.
    • Browser grid covers load on view toggle: switching from list to grid view now immediately loads covers for the visible page instead of showing empty slots until the next navigation event.
    • EPUB large PNG covers decode via libpng: covers larger than 4 MB now use a direct libpng thumbnail path that scales to 85×115 px while keeping peak memory low.
    • EPUB SVG covers rendered via MuPDF: SVG cover images are rasterized at thumbnail size using the MuPDF fitz renderer instead of being skipped or incorrectly decoded.

v2.3.1

  • Highlights
    • All background workers disabled for this release: fixed-layout rendering (PDF, CBZ), MOBI finalization, and browser warmup all run synchronously on the main thread, trading some speed for confirmed reliability on real hardware.
    • Reading direction toggle for fixed-layout documents: PDF, CBZ, and XPS now have a per-book reading direction toggle in BOOK settings. Switch between Left to right (default, western) and Right to left (manga, Arabic, Hebrew).
    • Book opening and switching are much harder to break: stale open sessions are gated more carefully, browser-side background work is paused at the right time, and the transition between books no longer relies on timing-sensitive state.
    • PDF and CBZ now render at zoom-correct resolution: in synchronous mode the interactive tile is rendered immediately after the preview, so zoomed-in content is sharp rather than upscaled from the preview bitmap.
    • MOBI crash on reopen is fixed: a large contiguous heap reservation during text merging could std::terminate on a fragmented 3DS heap after a prior book close; the reservation is removed and the string now grows incrementally.
  • Included fixes and behavior changes
    • EPUB inline image metadata retried on zip open failure: if unzOpen fails due to transient memory pressure, metadata_probed is left false so the next frame retries instead of permanently marking the image as unloadable.
    • Book vector capacity released on close: pages and chapters vectors now swap with an empty vector on Book::Close(), actually freeing capacity rather than just clearing size.
    • Opening a book is cancellable and session-safe: an in-progress open can now be cancelled with B, Start, or Select, and switching books no longer depends on stale callbacks or unfinished work from the previous session.

v2.3.0

  • Highlights
    • GENERAL and BOOK settings are now separated cleanly: global preferences stay in the library settings menu, while book-specific actions appear only when you open settings during reading.
    • New go to page slider popup: books now expose a dedicated page-jump control from BOOK settings, with visible page number feedback and both touch and button-based adjustment.
  • Included fixes and behavior changes
    • The in-book settings menu is more coherent: global options such as clock formatcolor mode, and library view no longer appear mixed into the per-book menu.
    • go to page is tuned for 3DS controls: touch chooses the page directly, Left/Right moves by one page, Up/Down and L/R move in larger jumps, A confirms, and B / Select / Start cancel.
    • Left-handed orientation remains supported: the new slider and the updated settings separation continue to use the existing orientation-aware input mapping.
    • Recent EPUB compatibility fixes remain included: cosmetic hidden pagebreak spans are ignored, and CSS list marker suppression such as list-style-type: none is still honored.

v2.2.2

  • Highlights
    • Cosmetic EPUB pagebreak markers no longer disturb pagination: hidden epub:type="pagebreak" / role="doc-pagebreak" spans are now ignored when they are purely decorative, so they no longer create bogus breaks in the reflowed text.
    • CSS-hidden list markers are now respected: lists styled with list-style-type: none or list-style: none no longer show bullets or numbers in 3dslibris when those rules come from EPUB CSS.
  • Included fixes and behavior changes
    • EPUB parser hidden-content handling is more robust: the parser now distinguishes between useful structural content and hidden print-parity markers that should not affect reading flow.
    • List marker suppression now works from class-based CSS too: this is no longer limited to inline styles or a few hardcoded class names.
    • The EPUB rendering fixture was updated: the test book now includes a non-hardcoded ornamentless list case so the behavior can be validated in both automated tests and on hardware.

v2.2.1

  • Highlights
    • Optional library list view: settings now let you switch the browser between the existing cover gallery and a DSLibris-style list view that loads only titles, starts faster, and is easier to navigate on large libraries.
    • List view is fully integrated: the new mode is saved in the XML preferences, works even with no book currently open, supports vertical navigation, and keeps the existing browser flow intact.
    • Long titles are handled better in the list: list rows now use the dedicated presentation path introduced for this feature, with clearer rendering and spacing for long display names.
    • Debug and release CIA builds can coexist3dslibris-debug.cia now uses its own Title ID/Product Code so it installs separately instead of overwriting the release build.
  • Included fixes and behavior changes
    • Browser presentation is split cleanly by mode: grid and list rendering now live in separate presentation files while app_browser.cpp remains the coordinator for shared navigation and actions.
    • Preformatted host wrapping stays correct: the host-side regression fix for hard wrapping in preformatted text is included in this release train.
    • Release automation still publishes the full artifact set: the release workflow continues to generate and attach both CIA variants, both 3DSX variants, the SD package, and the source tarball.

v2.1.0

  • Highlights
    • Configurable EPUB monospace flow restored and expanded: pre / code now reflow with the active monospace font instead of measuring with the serif text face, preserving readable code blocks while keeping the new configurable mono font path.
    • Monospace variants now render correctly: EPUB content can distinguish regular, bold, italic, and bold-italic monospace text instead of collapsing everything to one mono style.
    • More EPUB block semantics are supported: lists, nested ordered lists, blockquoteasidecaptionfiguredl / dd, and basic table linearization now render as readable reflow blocks instead of collapsing into generic paragraph flow.
    • EPUB inline formatting support is broader: underline, strikethrough, overline, superscript, subscript, dotted/dashed/wavy underline styles, and common CSS-driven emphasis patterns are now recognized more consistently.
    • Hidden EPUB accessibility text is ignored: common hidden-text patterns such as visually-hiddenaria-hidden, and equivalent inline CSS are no longer shown as visible body text.
    • Styled punctuation stays attached to the surrounding text: closing ! / ? and opening ¡ / ¿ are handled more safely across inline style boundaries, avoiding the worst split cases in Spanish text.
    • EPUB index labels are cleaner: chapter menus now prefer simpler labels instead of concatenating multiple headings into one noisy entry.
    • EPUB page cache writes are safer: page cache files now save with the actual layout parameters used for pagination instead of stale zeroed values, avoiding invalid cache entries after fresh opens.
    • Bundled quickstart and SD docs are clearer about where books go: the release package now makes the sdmc:/3ds/3dslibris/book/ path more explicit, since this is still the most common user setup question.
    • Book view renderer recovery is more defensive: entering or reopening a book now resets the text renderer state more aggressively, which should reduce rare cases where visible glyphs disappear until the app is restarted.

v2.0.4

  • Highlights
    • Bookmarks and last-read page persistence fixed: prefs XML writing now escapes attribute values correctly and sanitizes invalid control characters, so filenames like ... & ... no longer break 3dslibris.xml parsing on startup.
    • CIA library source handling improved: the app now discovers books from both sdmc:/3ds/3dslibris/book and romfs:/3ds/3dslibris/book, with SD entries taking priority when names overlap.
    • Left-handed page screen order corrected: reflow reading now inverts first and second reading screens correctly in left-handed orientation.
    • Orientation-relative library D-Pad navigation: grid navigation now follows console orientation in both modes so directional input matches visual movement in right-handed and left-handed layouts.
    • Startup diagnostics improved: prefs load failures are now logged with an explicit warning instead of failing silently.
    • EPUB emphasis compatibility improved: the parser now recognizes bold/italic expressed via common style and class CSS patterns, not only semantic tags.
    • Release pipeline stability improved: debug MOBI builds now include the correct reporter definitions so debug-3dsx compiles reliably in CI/release workflows.

v2.0.3

  • Highlights
    • Fixed bundled RomFS for .cia builds — the installable build now actually includes its bundled fonts and UI resources, instead of staging them locally but omitting them from the final CIA package.
    • Fixed the CIA-only startup crash — a null cache entry in the text/font teardown path could trigger an ARM11 data abort during early startup failure; font initialization and cache cleanup are now hardened.
    • Better runtime asset fallback — bundled fonts and resources are resolved safely between SD and RomFS, so .cia installs no longer depend on a manual font/ or resources/ copy to boot.
    • Stable fatal boot screens — missing-book and startup error screens no longer flicker between old and new frames while waiting for Start.
    • Clearer first-run behavior — if no books are present, the app now shows a stable message telling you to copy your EPUB, FB2, TXT, RTF, or ODT files into sdmc:/3ds/3dslibris/book.
    • CIA build validation added to CI — GitHub Actions now builds and verifies the .cia path as well, including checks that the staged RomFS contains the bundled runtime files.
  • Included reader functionality
    • MuPDF-backed PDF, CBZ, and XPS support
    • Progressive fixed-layout rendering
    • Asynchronous/deferred MOBI open on New 3DS
    • Generated library cover thumbnails
    • Bundled runtime assets for .cia installs

v2.0.2

  • Highlights
    • Fixed CIA startup on hardware and Azahar: the packaged NCCH code is now emitted without compression, avoiding the startup crash seen in previous 2.0.1 CIA builds.
    • No change to reader features: this is a packaging-focused release intended to restore a working installable build.
    • Clean CIA build path: the local CIA build also includes the small book_io.cpp declaration fix required for a clean rebuild.

v2.0.1

  • Highlights
    • Full branch catch-up release: v2.0.1 includes the missing commits that were finished after the original v2.0.0 tag, so the public release now matches the maintained main line.
    • Centralized runtime paths: SD, cache, and related filesystem paths now live in a shared path layer instead of being duplicated across subsystems.
    • Cleaner repo structure: shared helpers were reorganized, legacy duplicate files were removed after the move, and bundled expat sources now live under third_party/.
    • MOBI cache code split out cleanly: page-cache serialization and invalidation logic now live in a dedicated MOBI cache module instead of being embedded in the larger common book I/O unit.
    • Improved native test ergonomics: the text-layout and Unicode tests now reuse a shared native build helper instead of each script compiling the same dependency objects manually.
    • Expanded technical documentation: the repository now includes architecture notes plus local NDS/3DS hardware reference material derived from GBATek for future maintenance work.
  • Included reader functionality (from the v2.0.0 line)
    • MuPDF-backed PDF, CBZ, and XPS support
    • Progressive fixed-layout rendering with preview-first display
    • Asynchronous/deferred MOBI open on New 3DS
    • Generated library cover thumbnails for EPUB, FB2, MOBI, PDF, and CBZ
    • Bundled runtime assets for .cia installs

v2.0.0

  • Highlights
    • PDF, CBZ, and XPS reading: open PDF documents, comic books (CBZ), and XPS files with zoom, full-page preview on the bottom screen, and outline navigation when available.
    • Progressive page loading: a preview of the page is shown immediately, then it refines to full quality in the background.
    • Faster on New 3DS: page rendering for PDF and CBZ runs on a separate processor core, keeping the UI responsive. Old 3DS still works with automatic fallback.
    • MOBI books open without freezing the UI on New 3DS thanks to asynchronous processing: you can start reading while the rest of the book finishes loading in the background.
    • Library covers now work for every format: EPUB, FB2, MOBI, PDF, and CBZ all show actual page thumbnails instead of placeholders.
    • All 1.1.x improvements included: inline images in MOBI and EPUB, faster image-heavy books, better text rendering, and more accurate MOBI table of contents.
    • No more manual SD card setup for .cia installs: fonts and UI resources are built in.
    • More stable startup: problematic MOBI files no longer cause crashes, and the app stays on a clear error screen instead of flickering between states when something goes wrong.

v1.1.0

  • Highlights
    • Library navigation: you can now move the selection around the book grid with the D-Pad and press A to open.
    • Images inside EPUB and MOBI books now display correctly: small icons, wide separators, and full-size figures no longer take up the entire screen or disappear.
    • EPUB books with lots of images open noticeably faster thanks to internal optimizations in how images are loaded from the archive.
    • Library cover thumbnails for MOBI books generate faster on subsequent visits since cover data is now remembered between sessions.
    • No more manual SD card setup for .cia installs: the .cia now includes all required fonts and UI resources, so a plain install from the Homebrew Menu is enough.
    • Better text rendering across all formats: improved line breaking, proper handling of special characters, and font sizes that can no longer be set to values that break pagination.
    • Code blocks and <code></code> <pre></pre> sections in EPUBs now wrap properly instead of running off the edge of the screen.
    • MOBI books benefit from multiple fixes: more accurate table of contents, better plain-text wrapping that matches how real books read, and support for HUFF/CDIC compressed files.

v1.0.3

  • Highlights
    • Pressing right on settings rows such as font size and paragraph spacing now increases the value.
    • Pressing left now decreases the value, matching the on-screen arrows and touch layout.
    • Horizontal navigation inside the settings list is aligned with the same left/right direction.
    • The main browser splash now shows the app version centered at the bottom of the left screen.
    • Changing font size, paragraph spacing, orientation, or reading fonts no longer tries to repaginate the book inside the settings menu.
    • When layout-related settings change, the app shows a warning and applies the new layout after reopening the current book.
    • MOBI parsing is more resilient against empty or corrupt files and now shows a readable error instead of a raw numeric failure.
    • MOBI books now have an optional per-book line wrap fix for badly converted files that hard-wrap normal prose into many short blocks.
    • The .cia packaging flow was rebuilt around the same makerom/bannertool process used by Universal-Updater.
    • Previous 1.0.3 test .cia builds could install but fail to boot because the packaged exheader ended up with an invalid main-thread priority.
    • The generated .cia now boots correctly on original hardware and in Azahar.
  • Known bug
    • When a book is reopened after a layout change, or after toggling the per-book MOBI line wrap fix, reading position and existing bookmarks are remapped approximately and may land a few pages away from their original location.
    • Some malformed MOBI files still contain source encoding or OCR artifacts that cannot be repaired fully by the reader.

v1.0.2

  • Highlights
    • Startup now stops with clear install guidance if required runtime files are missing from the SD card.
    • The error message tells users to download and extract 3dslibris-sdmc.zip and shows the expected sdmc:/3ds/3dslibris/ layout.
    • The README now explains installation step by step for the .3dsx + SD package flow.

v1.0.1

  • Highlights
    • EPUB cold opens are now much faster on large books by indexing ZIP entries before spine parsing.
    • In real tests with Don Quijote, cold open time dropped from about 50.5s to about 7.2s, roughly a 7x improvement.
    • Releases now include 3dslibris-debug.3dsx, which enables verbose diagnostic logging in 3dslibris.log.
  • Notes
    • The debug build is intended for troubleshooting and performance investigation.
    • EPUB TOC resolution remains separate from the main open path and was not the main cause of the previous cold-open slowdown.

v1.0.0

  • First release.

Credits

  • Original dslibris: Ray Haleblian
  • 3DS port and maintenance: Rigle

External links

Advertising: