7.6 KiB
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,
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.
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
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
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:
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 i modelu, których repozytorium nie dostarcza.
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
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:
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.