Patryk GenschandClaude Opus 5 c2036e1f72 Add a README
Everything so far lived in code comments and CLI help, which works while writing
the thing and not at all when coming back to it after a month. Covers what the
catalogue is, where its knowledge of the Aidem formats comes from (:core through
a composite build, never a fork), how the data is shaped, and how to run it —
pipeline, browsing, transcription, Docker, and moving the database between
machines.

Written against the actual state rather than memory: the command list is what the
binary prints, the table list is what the schema holds, and the submodule URL is
the one in .gitmodules. Volatile figures are left out, with a pointer to
`rex-catalog stats` instead, so the file does not rot on the next ingest.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-21 20:53:04 +02:00
2026-08-20 21:40:10 +02:00
2026-08-20 21:40:10 +02:00
2026-08-21 20:53:04 +02:00

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.propertiescoreVersion), 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 ma cztery widoki: Katalog (tytuły, wydania, kopie, pliki), Skrypty (wyszukiwanie pełnotekstowe i podgląd z listą użytych zasobów), Dźwięk (wyszukiwanie nagrań, odtwarzacz, transkrypcja) i Formaty (rozkład zawartości kolekcji).

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.

S
Description
A utility app for organizing Aidem Media games and making it easier to analyze them
Readme
286 KiB
Languages
Java 86%
HTML 13%
Dockerfile 0.8%
Shell 0.2%