tools/voci.mjs (make voci) genera un mp3 per ogni battuta con la voce del personaggio scelta in tools/voci.json, solo per i testi nuovi o cambiati; tools/voci_xtts.py divide le frasi e toglie punti finali e caporali, che XTTS in italiano leggeva («Buongiorno, punto»). Nel gioco il fumetto dura quanto la voce, la musica si abbassa mentre si parla, il muto spegne anche le voci. Il leone ora parla e i personaggi parlano dalla posizione che la scena dichiara (speakers), che prima era ignorata. Tutte le voci verificate con Whisper; test: ogni battuta ha la sua voce, il fumetto non finisce prima della voce, la musica si abbassa (provati con errori iniettati). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UdeKd62opy9PKgpQXtVctF
117 lines
4.6 KiB
Makefile
117 lines
4.6 KiB
Makefile
# LA LEGGENDA DEL REGOLO — comandi di sviluppo, verifica, grafica e Docker.
|
|
# `make` o `make help` elenca i target.
|
|
|
|
SHELL := /bin/bash
|
|
.DEFAULT_GOAL := help
|
|
|
|
PORT ?= 8000
|
|
DOCKER_PORT ?= 8080
|
|
IMAGE ?= leggenda-regolo
|
|
TAG ?= latest
|
|
COMPOSE ?= DOCKER_PORT=$(DOCKER_PORT) docker compose
|
|
PYTHON ?= python3
|
|
NODE ?= node
|
|
# Personaggio da ritagliare: make character NAME=andrea (foglio in assets/raw/$(NAME)-sheet.png, 4x2)
|
|
NAME ?= andrea
|
|
SHEET ?= assets/raw/$(NAME)-sheet.png
|
|
HEIGHT ?= 120
|
|
FRAMES ?= walk_1,walk_2,walk_3,walk_4,stand,talk,take,back
|
|
REF ?= stand
|
|
# Sfondo da preparare: make background SRC=assets/generated/pieve-dalla-salita.png (CROP=x,y,w,h facoltativo)
|
|
SRC ?=
|
|
DST ?= assets/scenes/$(notdir $(SRC))
|
|
CROP ?=
|
|
COLORS ?= 64
|
|
|
|
.PHONY: help serve open test browser verify voci voci-elenco sfondi sfondi-genera sfondi-confronto background character \
|
|
build up down restart logs ps shell image-size clean distclean
|
|
|
|
## ------------------------------------------------------------ sviluppo
|
|
|
|
help: ## Mostra questo aiuto
|
|
@echo "LA LEGGENDA DEL REGOLO — target disponibili:"; echo
|
|
@grep -hE '^[a-zA-Z0-9_-]+:.*?## ' $(MAKEFILE_LIST) | \
|
|
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-16s\033[0m %s\n", $$1, $$2}'
|
|
@echo; echo "Variabili: PORT=$(PORT) DOCKER_PORT=$(DOCKER_PORT) IMAGE=$(IMAGE):$(TAG)"
|
|
|
|
serve: ## Avvia il server statico locale (PORT=8000)
|
|
@echo "→ http://localhost:$(PORT)"
|
|
$(PYTHON) -m http.server $(PORT) --bind 0.0.0.0
|
|
|
|
open: ## Apre il gioco nel browser predefinito (serve già avviato)
|
|
@xdg-open "http://localhost:$(PORT)" >/dev/null 2>&1 || open "http://localhost:$(PORT)"
|
|
|
|
## ------------------------------------------------------------ verifica
|
|
|
|
test: ## Test della logica, della storia, della soluzione completa e del generatore
|
|
$(NODE) --test tests/*.test.mjs
|
|
$(PYTHON) -m unittest discover -s tests -p "test_*.py" -q
|
|
|
|
browser: ## Partita completa nel browser con Playwright
|
|
$(NODE) tests/browser.mjs
|
|
|
|
verify: test browser ## Tutti i controlli
|
|
|
|
## ------------------------------------------------------------ grafica
|
|
|
|
voci: ## Voci dei personaggi con XTTS sulla GPU: solo le battute nuove o cambiate (RIFAI='testo' per ritentarne una)
|
|
$(NODE) tools/voci.mjs $(if $(RIFAI),--rifai "$(RIFAI)")
|
|
|
|
voci-elenco: ## Quali battute mancano di voce, senza generare niente
|
|
$(NODE) tools/voci.mjs --dry
|
|
|
|
sfondi: ## Prova a secco del generatore: quali foto di assets/raw/foto/ genererebbe (nessuna API)
|
|
$(PYTHON) tools/genera.py --dry-run
|
|
|
|
sfondi-genera: ## Genera davvero gli sfondi con l'API (serve OPENAI_API_KEY; ogni immagine si paga)
|
|
@test -n "$$OPENAI_API_KEY" || { echo "manca OPENAI_API_KEY nell'ambiente"; exit 2; }
|
|
$(PYTHON) tools/genera.py
|
|
|
|
sfondi-confronto: ## Rifà il confronto foto/immagini in assets/generated/index.html e lo apre
|
|
$(PYTHON) tools/genera.py --gallery-only
|
|
@xdg-open assets/generated/index.html >/dev/null 2>&1 || open assets/generated/index.html
|
|
|
|
background: ## Porta uno sfondo a 640x360 nel gioco (SRC=..., DST=..., CROP=x,y,w,h, COLORS=64)
|
|
@test -n "$(SRC)" || { echo "uso: make background SRC=assets/generated/nome.png [CROP=x,y,w,h]"; exit 2; }
|
|
$(PYTHON) tools/prepare_background.py $(SRC) $(DST) $(if $(CROP),--crop $(CROP)) --colors $(COLORS)
|
|
|
|
character: ## Ritaglia un foglio sprite 4x2 e prepara il personaggio (NAME=andrea, SHEET=..., HEIGHT=120, FRAMES=..., REF=stand)
|
|
$(PYTHON) tools/slice_sprites.py --sheet $(SHEET) --out /tmp/regolo-$(NAME) --cols 4 --rows 2 \
|
|
--despill --names $(FRAMES) --prefix $(NAME)_
|
|
$(PYTHON) tools/prepare_character.py /tmp/regolo-$(NAME) $(NAME) assets/characters --height $(HEIGHT) \
|
|
--frames $(FRAMES) --ref $(REF)
|
|
|
|
## ------------------------------------------------------------ docker
|
|
|
|
build: ## Costruisce l'immagine Docker
|
|
docker build -t $(IMAGE):$(TAG) .
|
|
|
|
up: ## Avvia il container (DOCKER_PORT=8080)
|
|
$(COMPOSE) up -d --build
|
|
@echo "→ http://localhost:$(DOCKER_PORT)"
|
|
|
|
down: ## Ferma e rimuove il container
|
|
$(COMPOSE) down
|
|
|
|
restart: down up ## Riavvia il container
|
|
|
|
logs: ## Segue i log del container
|
|
$(COMPOSE) logs -f
|
|
|
|
ps: ## Stato del container
|
|
$(COMPOSE) ps
|
|
|
|
shell: ## Shell dentro il container
|
|
$(COMPOSE) exec leggenda-regolo sh
|
|
|
|
image-size: ## Dimensione dell'immagine
|
|
@docker image ls $(IMAGE):$(TAG) --format '{{.Repository}}:{{.Tag}} {{.Size}}'
|
|
|
|
## ------------------------------------------------------------ pulizia
|
|
|
|
clean: ## Rimuove file temporanei
|
|
find . -name '__pycache__' -type d -prune -exec rm -rf {} +
|
|
|
|
distclean: clean down ## clean + container + immagine Docker
|
|
-docker image rm $(IMAGE):$(TAG)
|