현재 버전 v1.3.0-ko.1

릴리즈 노트

CrossPoint Reader 한국어 펌웨어 버전별 변경사항

v1.2.0-ko.14

1.2.0-ko.142026년 4월 29일
GitHub

새 기능 — 책별 독서 타이머 (Reading Timer)

이번 릴리스는 책마다 누적 독서 시간을 자동으로 기록하는 독서 타이머 기능을 도입합니다.

핵심

  • EPUB과 TXT 두 리더 모두에서 책을 펼치는 순간부터 독서 시간이 자동 누적됩니다.
  • 누적 시간은 책의 캐시 디렉터리(.crosspoint//reading_stats.bin)에 16바이트 바이너리로 저장되어, 책을 닫고 다시 열어도 이어서 계산됩니다.
  • 리더 메뉴 상단 진행률 라인 우측에 누적 시간 칩이 표시됩니다 (Reading Time: 1h 23m).
  • 메뉴에 독서 타이머 초기화 / Reset Reading Timer 항목이 추가되었습니다 — 두 단계 확인 후에만 누적 값이 0으로 리셋됩니다.

동작 디테일

상황동작
사용자가 페이지를 넘기거나 메뉴에서 돌아옴누적 진행
자동 페이지 넘김 활성 중누적 진행 (장시간 무인 읽기에서도 끊기지 않음)
5분 동안 입력 없음일시 정지 (다음 입력 시 재개)
메뉴/서브 액티비티 진입그동안의 시간은 누적되지 않음 (메뉴 시간 제외)
30초 미만 짧은 세션저장 생략 (SD 카드 마모 방지)
활성 독서 5분마다자동 중간 저장
리더 종료 시잔여 시간 드레인 후 최종 저장

기술 내용

  • 신규 모듈: src/util/ReadingStats.{h,cpp}, src/util/ReadingTimer.{h,cpp}
  • 저장 포맷: 16바이트 (magic 'TIME', version=1, totalSeconds u32, sessionCount u32, little-endian)
  • 시간 누적은 millis() 기반이며 49.7일 롤오버에 안전한 uint32_t 차감을 사용합니다.
  • 단일 tick이 2초를 초과하면 서브 액티비티/슬립 갭으로 간주하여 누적에서 제외합니다.
  • uint32 초 단위 카운터로 약 136년치 시간을 다룰 수 있습니다.

i18n

  • STR_READING_TIME — 독서 시간 / Reading Time
  • STR_RESET_READING_TIMER — 독서 타이머 초기화 / Reset Reading Timer
  • STR_RESET_READING_TIMER_PROMPT — 이 책의 독서 시간을 초기화할까요? / Reset this book's reading time?

호환성

  • 기존 progress.bin, book.bin, section.bin 캐시 포맷에는 영향 없음.
  • reading_stats.bin은 책당 새로 생성되는 파일이며, 없으면 0초로 시작합니다.
  • 기존에 읽던 책의 누적 시간은 이 빌드를 처음 켠 시점부터 0초로 시작합니다.

빌드 정보

  • 환경: ESP32-C3 (Xteink X4)
  • Flash 사용량: ~99.7%
  • DRAM 사용량: ~51.2%

변경 파일

  • src/util/ReadingStats.{h,cpp} (신규)
  • src/util/ReadingTimer.{h,cpp} (신규)
  • src/activities/reader/{Epub,Txt}Reader{,Menu}Activity.{h,cpp}
  • lib/I18n/translations/{english,korean}.yaml
  • platformio.ini (버전 범프)

1.2.0-ko.13

1.2.0-ko.132026년 4월 27일
GitHub

TXT 리더 옵션 적용 + 설정 변경 시 첫 페이지 회귀 버그 수정

개선 사항

TXT 리더에 누락되어 있던 옵션 두 가지 적용

  • 추가 단락 간격 (extraParagraphSpacing) — 단락 사이에 약 반 줄 높이의 여백을 추가합니다. 페이지의 첫 단락 앞에는 적용되지 않아 위쪽 여백이 어색하게 늘어나지 않습니다.
  • 단락 들여쓰기 (paragraphIndent) — 각 단락의 첫 줄에 1em 만큼 들여쓰기를 적용합니다.

페이지 분할 방식 개선

기존엔 linesPerPage = viewportHeight / lineHeight 로 고정된 줄 수만큼 채웠습니다. 단락 간격이 들어가면 마지막 줄이 viewport 밖으로 잘리는 문제가 생기므로, 누적 y 좌표 기반의 동적 페이지네이션으로 교체했습니다. 단락 간격이 켜져 있어도 잘림 없이 정확히 화면에 들어가는 양만큼만 한 페이지로 묶습니다.

정렬 동작 개선

center / justify 정렬이 들여쓰기된 콘텐츠 박스를 기준으로 동작하도록 보정했습니다. 단락 첫 줄과 wrap된 다음 줄의 정렬 기준이 일관됩니다.

버그 수정

설정 변경 시 첫 페이지로 돌아가는 문제 ([현상 #1])

읽고 있는 도중에 폰트, 여백, 정렬, 줄간격 등을 바꾸면 책의 첫 페이지로 회귀하는 문제가 있었습니다.
원인: 설정 변경 감지 시 initialized = false로 다시 초기화 → loadProgress()가 다시 호출 → 진입 시 currentOffset = 0으로 리셋 후 저장된 layout과 현재 layout 비교 검증에서 한 항목이라도 다르면 그대로 0이 유지되는 문제
수정:
  • initializeReader()recomputeLayout() (레이아웃 재계산)과 진행률 로드로 분리
  • progressLoaded 플래그를 추가하여 진행률은 파일을 열 때 한 번만 로드
  • 설정 변경 분기에서는 recomputeLayout()만 호출, currentOffset은 유지하고 라인 경계로 스냅
  • loadProgress()의 layout 검증 제거 — byte offset은 layout-독립적이라 폰트/여백을 바꿔도 그대로 유효

진행률 파일 포맷 변경

progress.bin 포맷이 v1 → v2로 올라갔습니다 (extraParagraphSpacing, paragraphIndent 두 필드 추가).
기존 진행률 파일은 한 번 무효화되어 처음부터 시작합니다. 이후엔 설정 변경에도 위치가 보존됩니다.

적용 옵션 현황

옵션적용
줄간격적용됨
화면 여백적용됨
단락 정렬적용됨
추가 단락 간격이번 릴리즈부터 적용
단락 들여쓰기이번 릴리즈부터 적용
글자단위 줄바꿈적용됨

1.2.0-ko.12

1.2.0-ko.122026년 4월 24일
GitHub
Xteink X4와 동일한 펌웨어가 이제 Xteink X3에서도 동작합니다. 하드웨어 감지는 런타임에 자동으로 이루어지며, 각 기종 고유 기능은 해당 기기에서만 노출됩니다.

새 기능 (X3 전용)

조작 옵션

  • 기울여 페이지 넘기기 (Controls 카테고리) — QMI8658 IMU로 기기 기울임을 감지해 페이지를 넘깁니다.
    • 옵션: 꺼짐 / 정방향 / 역방향
    • 방향 감지는 현재 화면 회전(세로/가로/반전)에 맞춰 자동 보정됩니다.

리더 옵션 (상태 표시줄 설정)

  • 상태바 시계 (Customise Status Bar) — DS3231 RTC 기반의 HH:MM 표시.
    • NTP 자동 동기화: Wi-Fi 네트워크에 연결되는 순간 자동으로 시각을 맞춥니다 (별도 메뉴 없음).
    • UTC 오프셋을 30분 단위로 조정 가능 (UTC-12:00 ~ UTC+14:00). 참고 한국 표준시 UTC+09:00

X4 사용자를 위한 변경

  • 위 두 기능은 X4에서 설정 메뉴에 표시되지 않습니다halTiltSensor.isAvailable() / halClock.isAvailable()가 X4에서 false이므로 작동하지 않는 옵션

내부 변경

  • lib/hal/HalTiltSensor.{h,cpp}, lib/hal/HalClock.{h,cpp} 추가 (upstream juicecultus PR #1636, #1612 cherry-pick)
  • 설정 리스트와 상태바 커스터마이즈 액티비티가 런타임 하드웨어 감지에 따라 메뉴 항목을 동적으로 필터링
  • 기울기 극성(polarity) 옵션을 위한 전용 번역 키 STR_TILT_NORMAL / STR_TILT_INVERTED 추가 — 기존 STR_NORMAL("정방향") / STR_INVERTED("역방향")가 줄 간격·화면 방향 등 다른 맥락에서도 쓰이기 때문
  • 개발용 default 빌드의 LOG_LEVEL을 2 → 1로 낮춤 (X3 기능 추가 후 DEBUG 레벨에서 플래시 오버플로 방지). 실제 OTA/릴리즈 펌웨어는 기존과 동일한 INFO 레벨

검증

  • pio run (default): Flash 99.6%, 여유 26,803 B
  • pio run -e gh_release: Flash 99.6%, 여유 27,905 B
  • pio check --fail-on-defect low --fail-on-defect medium --fail-on-defect high: PASSED
  • bin/clang-format-fix (llvm@21): idempotent
30개의 릴리즈 중 10-12