169 lines
7.6 KiB
Markdown
169 lines
7.6 KiB
Markdown
# rex-catalog
|
|
|
|
Katalog kolekcji gier Aidem Media — serii *Reksio* i *Poznaj Mity*. Indeksuje obrazy płyt,
|
|
zagląda do środka i pozwala je przeglądać: odszyfrowane skrypty, odtwarzalne kwestie
|
|
mówione, podgląd grafiki i animacji oraz powiązania między nimi.
|
|
|
|
Powstał do celów archiwizacyjnych i testów emulatora. Niczego nie modyfikuje w kolekcji —
|
|
obrazy płyt otwiera wyłącznie do odczytu, a wszystko, co wytworzy, ląduje w osobnym
|
|
katalogu `data/`.
|
|
|
|
## Skąd bierze wiedzę o formatach
|
|
|
|
Formaty Aidem — zaszyfrowane skrypty CNV, obrazy `PIK\0`, animacje `NVP\0`, kompresje
|
|
CLZW i CRLE — czyta przez `:core` z [Rex-EMoolatora](https://github.com/patryk025/Rex-EMoolator),
|
|
podpiętego jako **composite build**, a nie fork. Emulator jest przypięty submodułem na
|
|
konkretnym tagu (`gradle.properties` → `coreVersion`), a zadanie `verifyCoreVersion`
|
|
pilnuje, żeby tag i submoduł się nie rozjechały.
|
|
|
|
Dzięki temu wiedza o formatach ma jedno źródło. Tam, gdzie katalog musiał napisać własny
|
|
parser, jest to powiedziane wprost w komentarzu razem z powodem — najczęściej dlatego,
|
|
że loader z `:core` buduje tekstury OpenGL-a i w procesie bez okna nie da się go użyć.
|
|
|
|
## Jak to jest poukładane
|
|
|
|
**Trzy poziomy tożsamości.** `title` (dzieło) → `edition` (wydanie) → `copy` (konkretny
|
|
plik na dysku). Między wydaniem a kopią stoi jeszcze `game_root`, bo jedna płyta bywa
|
|
dwupackiem z dwiema grami, każdą z własnym silnikiem.
|
|
|
|
**Plik osobno, treść osobno.** `file` mówi, gdzie coś leży, `blob` — czym jest. Porównanie
|
|
dwóch wydań jest więc operacją na zbiorach odcisków, a wszystko, co wytworzone
|
|
(odszyfrowany skrypt, miniatura), kluczuje się treścią: ten sam plik na trzech płytach
|
|
przerabiamy raz.
|
|
|
|
**Fakty z dowodem.** Detektory nie nadpisują pól, tylko dopisują wiersze do `detection`
|
|
z wartością, pewnością i dowodem. Poprawki człowieka siedzą osobno, w polach `*_override`,
|
|
i nigdy nie są nadpisywane przez kolejny przebieg.
|
|
|
|
**Nic nie wypakowujemy.** Dźwięk i klatki animacji czytamy z obrazu płyty na żądanie,
|
|
sięgając od razu na właściwą pozycję. W `data/` zostaje tylko to, co drogo policzyć:
|
|
odszyfrowane skrypty i miniatury.
|
|
|
|
## Uruchomienie
|
|
|
|
Potrzebne: **JDK 21** i submoduł z emulatorem.
|
|
|
|
```bash
|
|
git submodule update --init --recursive
|
|
./gradlew installDist
|
|
```
|
|
|
|
Dalej wygodnie przez launcher (`build/install/rex-catalog/bin/rex-catalog`) albo
|
|
`./gradlew run --args="..."`. Katalog bazy wskazuje `-Dcatalog.data` (domyślnie `./data`).
|
|
|
|
### Potok
|
|
|
|
```bash
|
|
rex-catalog ingest /ścieżka/do/kolekcji # indeksuje obrazy, katalogi gier i całe kolekcje
|
|
rex-catalog decode # odszyfrowuje skrypty do cache'u i indeksu FTS5
|
|
rex-catalog probe # dźwięk, grafika, dialogi, powiązania
|
|
rex-catalog analyze # metadane z application.def i install.ini
|
|
rex-catalog promote # tworzy tytuły i wydania z wykrytych faktów
|
|
```
|
|
|
|
Każdy krok jest **przyrostowy** — dołożenie nowej płyty przerabia tylko ją. Ponowne
|
|
uruchomienie bez `--force` nie robi nic, jeśli nic się nie zmieniło.
|
|
|
|
`ingest` przyjmuje obraz `.iso` (ISO 9660, Joliet i UDF), archiwum `.zip`, katalog
|
|
rozpakowanej gry albo katalog z całą kolekcją.
|
|
|
|
### Przeglądanie
|
|
|
|
```bash
|
|
rex-catalog serve # front i MCP na http://127.0.0.1:8765
|
|
rex-catalog find CANVAS_OBSERVER # przeszukanie skryptów (składnia FTS5)
|
|
rex-catalog cat arcade.cnv # odszyfrowany skrypt na wyjście
|
|
rex-catalog titles # lista wydań z metadanymi
|
|
```
|
|
|
|
Front otwiera się na widoku **Zasoby** — paginowanej galerii obrazów, animacji i nagrań,
|
|
filtrowanej po grze, rodzaju i nazwie. Zaznaczenie otwiera inspektor z pełnym podglądem,
|
|
parametrami i miejscami użycia. Animacje można odtwarzać w tempie zapisanym w ANN — jako
|
|
wszystkie obrazy albo konkretne nazwane zdarzenie, np. `BEZRUCH` czy `GADA_1`, razem z jego
|
|
właściwą kolejnością klatek i zakresem pętli. Dalej są **Skrypty** (wyszukiwanie
|
|
pełnotekstowe i podgląd z listą użytych zasobów), **Dźwięk** (wyszukiwanie nagrań,
|
|
odtwarzacz, transkrypcja), **Kolekcja** (tytuły, wydania, kopie, pliki) i **Statystyki**.
|
|
|
|
Pod `/mcp` stoi serwer MCP (Streamable HTTP, tylko do odczytu) z dziewięcioma narzędziami —
|
|
od `list_titles` i `search_scripts` po `get_script_assets`, które pokazuje, co dany skrypt
|
|
odtwarza, kto to mówi i jak długo trwa.
|
|
|
|
### Metadane ręczne
|
|
|
|
Tego, czego nie da się wykryć, nie zgadujemy:
|
|
|
|
```bash
|
|
rex-catalog set copy "Wojna Troj" source_kind=wlasny_zgraj rip_tool=dd
|
|
rex-catalog set edition 3 distributor="Aidem Media" release_date_override=2003-11-18
|
|
rex-catalog lang add 3 cs audio
|
|
```
|
|
|
|
## Transkrypcja mowy
|
|
|
|
Opcjonalna i uruchamiana świadomie — wymaga [whisper.cpp](https://github.com/ggerganov/whisper.cpp)
|
|
i modelu, których repozytorium nie dostarcza.
|
|
|
|
```bash
|
|
brew install whisper-cpp # albo dowolna inna instalacja
|
|
rex-catalog transcribe --limit 100 # -Dcatalog.whisper.model=ścieżka/do/ggml-medium.bin
|
|
```
|
|
|
|
Da się też wyklikać z zakładki **Dźwięk** — z paskiem postępu i zatrzymaniem, które nie
|
|
gubi tego, co już policzone.
|
|
|
|
Kwestie są sklejane po kilka w trzydziestosekundowe okna z sekundą ciszy między nimi,
|
|
a wynik rozcinany z powrotem po znacznikach czasu. Whisper koduje zawsze pełne okno,
|
|
więc podawanie mu czterosekundowych kwestii po jednej marnuje większość pracy.
|
|
|
|
Transkrypt jest **wygenerowany, nie odczytany z płyty**. Siedzi w osobnej tabeli razem
|
|
z nazwą modelu i narzędzia, a interfejs oznacza go jako maszynowy. Zdania, które model
|
|
dopisuje z siebie na ciszy — podpisy ekip od napisów — są odsiewane.
|
|
|
|
## Docker
|
|
|
|
```bash
|
|
COLLECTION=/ścieżka/do/kolekcji docker compose up -d
|
|
docker compose exec katalog /app/entrypoint.sh ingest /media
|
|
```
|
|
|
|
Kolekcja montuje się tylko do odczytu, baza i cache lądują w wolumenie. Obraz niesie
|
|
whisper.cpp i ffmpeg, ale **nie model** — ten podmontuj pod `/models` i wskaż zmienną
|
|
`WHISPER_MODEL`.
|
|
|
|
`Dockerfile.cuda` buduje wariant z akceleracją NVIDII (domyślnie pod compute capability
|
|
8.6, czyli GeForce RTX 30). Na macOS akceleracja w kontenerze nie działa — tam transkrypcję
|
|
uruchamiaj na hoście, gdzie whisper.cpp sam korzysta z Metala.
|
|
|
|
## Przenoszenie między maszynami
|
|
|
|
Baza zapisuje bezwzględne ścieżki do obrazów płyt, bo czyta z nich dźwięk i grafikę.
|
|
Po skopiowaniu `data/` na inną maszynę trzeba ją przypiąć do kolekcji:
|
|
|
|
```bash
|
|
rex-catalog relocate D:\Reksio --dry-run # najpierw pokaż, co zrobisz
|
|
rex-catalog relocate D:\Reksio
|
|
```
|
|
|
|
Dopasowuje po nazwie i sprawdza rozmiar (`--verify` dokłada SHA-256), a nazwy porównuje po
|
|
normalizacji Unicode — bez tego kolekcja z macOS nie dogaduje się z tą samą kolekcją na
|
|
Windowsie, bo `ń` jest tam zapisane inaczej.
|
|
|
|
## Co siedzi w bazie
|
|
|
|
SQLite, jeden plik obok cache'u, więc przeniesienie katalogu to skopiowanie `data/`.
|
|
|
|
| tabela | co trzyma |
|
|
|---|---|
|
|
| `title`, `edition`, `copy`, `game_root` | tożsamość: dzieło, wydanie, nośnik, korzeń gry |
|
|
| `file`, `blob` | gdzie plik leży i czym jest |
|
|
| `detection` | fakty detektorów z dowodem i pewnością |
|
|
| `artifact` | wytworzone: odszyfrowane skrypty, miniatury |
|
|
| `media` | fakty o zasobie: długość, wymiary, klatki, kodek |
|
|
| `archive_entry` | zawartość archiwów `.snd` — kwestie spakowane w jeden plik |
|
|
| `script_ref` | odwołania skryptów do zasobów |
|
|
| `dialogue_line`, `anim_event` | mówca i zdarzenie kwestii, nazwane sekwencje animacji |
|
|
| `transcript` | rozpoznana mowa, osobno od reszty |
|
|
| `script_fts`, `transcript_fts` | indeksy pełnotekstowe |
|
|
|
|
`rex-catalog stats` pokazuje, co w danej chwili jest w środku.
|