juegos

Juegos de terminal de Pancho: Catan (TUI, GUI, web, servidor, PicoCalc), ajedrez, calculadora y minijuegos
git clone https://git.lu3dhn.xyz/juegos.git
Log | Files | Refs

README.md (4924B)


      1 # comun — base compartida de los juegos
      2 
      3 Todo lo que no es de un juego en particular: dibujo en pixeles, menús, terminal,
      4 ventana SDL, red, servidor de partidas y la PicoCalc. Lo usan `catan/` y
      5 `ajedrez-c/`. No sabe nada de ningún juego: cada juego lo configura con un
      6 `app_config.h` y le enchufa sus reglas.
      7 
      8 ```
      9 base/    C99 sin malloc ni stdio (compila igual para Linux y el RP2040)
     10          rng (PCG32), str (texto sin stdio), lang (g_lang es/en),
     11          input (teclas K_*, eventos, zonas clickeables, layouts), form (menús)
     12 gfx/     renderer de pixeles sobre una Surface abstracta: primitivas, texto,
     13          fuente bitmap (font.c, generada), menús en pixeles (gfx_form)
     14 linux/   paths (XDG + reloj), netline (cliente de líneas TCP + tokens guardados),
     15          tuikit (ncurses: colores opacos, cajas, lienzo de medios bloques, menús, input),
     16          guikit (ventana SDL3 con framebuffer escalado)
     17 server/  srv: servidor de partidas por turnos; el juego se enchufa con un GameModule
     18 pico/    hal.h (la interfaz de hardware) y sus dos implementaciones:
     19          hal_rp2040.c (PicoCalc real) y hal_sim.c (simulador SDL, cable por TCP);
     20          sdlog (SD: log y partida guardada), link (líneas con checksum por el cable),
     21          memmap_sdboot_200k.ld y comun_pico.cmake (arma el .uf2 y el .bin)
     22 deploy/  install-vps.sh: instala el servidor de un juego con systemd
     23 tools/   mkfont.py (fuente), patch_reset.py (parche del .bin), ansi2png.py (capturas de la TUI)
     24 ```
     25 
     26 ## Cómo lo usa un juego
     27 
     28 **`app_config.h`** en el include path del juego:
     29 
     30 ```c
     31 #define APP_NAME     "catan"          /* ~/.local/share/catan, ~/.config/catan */
     32 #define APP_TITLE    "Catan"          /* ventanas, arranque de la PicoCalc */
     33 #define APP_SD_LOG   "CATAN.LOG"      /* archivos pre-creados en la raíz de la SD */
     34 #define APP_SD_SAV   "CATAN.SAV"
     35 #define APP_SD_LOG83 "CATAN   LOG"    /* los mismos como entrada FAT 8+3 */
     36 #define APP_SD_SAV83 "CATAN   SAV"
     37 ```
     38 
     39 **Makefile**:
     40 
     41 ```make
     42 COMUN ?= ../comun
     43 include $(COMUN)/comun.mk
     44 CPPFLAGS += -I. $(COMUN_INC)
     45 # fuentes: $(COMUN_BASE) $(COMUN_GFX) $(COMUN_LINUX) $(COMUN_TUI) $(COMUN_GUI)
     46 #          $(COMUN_SERVER) $(COMUN_SIM)
     47 ```
     48 
     49 **PicoCalc** (`pico/CMakeLists.txt`, después de `pico_sdk_init()`):
     50 
     51 ```cmake
     52 include(${COMUN_DIR}/pico/comun_pico.cmake)
     53 comun_picocalc_app(mi_app NAME "MiApp" DESC "..." SOURCES ... INCLUDES ${ROOT})
     54 ```
     55 
     56 La app define `void app_main(void)` y usa solo `hal.h`, así el mismo código corre
     57 en la PicoCalc y en el simulador.
     58 
     59 **Servidor**: el juego implementa un `GameModule` (ver `server/srv.h`): crear
     60 partida, aplicar/reproducir movidas, redactar lo privado, cabecera, estado para
     61 "mis partidas", bots/relojes (`next_wake`/`wake`). El servidor pone conexiones,
     62 códigos de 6 letras, tokens por asiento, persistencia (meta + log) y reanuda las
     63 partidas al reiniciar. `srv_main()` es el `main` de un servidor dedicado.
     64 
     65 El servidor acepta en el mismo puerto clientes TCP y **WebSocket** (la versión web del
     66 juego en el navegador): si lo primero que llega es un pedido HTTP de upgrade (`GET `
     67 en vez de `HELLO`), `server/ws.c` hace el handshake y desenvuelve/envuelve los frames;
     68 el protocolo de líneas es el mismo. Todo el WebSocket vive en `ws.c` (sin sockets, se
     69 prueba sobre buffers) y `srv.c` lo llama en tres puntos; `-DSRV_NO_WS` lo saca. Como el
     70 navegador exige TLS, delante va Caddy o nginx haciendo `wss://` → `ws://127.0.0.1:puerto`.
     71 
     72 `AGAIN` arma otra partida como la actual (mismas opciones, la misma gente en los mismos
     73 asientos, otro reparto si el juego implementa `GameModule.again`).
     74 
     75 `ADMIN <secreto> RESET <código> <llave> <nombre>` cambia la llave de un asiento (para
     76 quien se olvidó la contraseña; el nombre va al final porque puede tener espacios); el secreto está en `<datos>/admin.key` (el servidor lo
     77 crea la primera vez). `deploy/admin.sh` (instalado como `<juego>-admin` por
     78 `install-vps.sh`) lo usa y además lista las partidas desde los `meta`.
     79 
     80 **Menús**: `gfx_form_backdrop` (pixeles) y `tk_form_logo` (terminal) son hooks
     81 para que cada juego ponga su fondo y su logo.
     82 
     83 ## Depuración sin mirar la pantalla
     84 
     85 `APP_SHOT=cuadro.ppm` vuelca cada cuadro de la GUI o del simulador a PPM, y
     86 `APP_KEYS="..."` alimenta el input (`~` Enter, `<` Esc, `>` Tab, `^ v { }` flechas,
     87 `.` pausa de 300 ms, `!` salir).
     88 
     89 ## PicoCalc: reglas de la casa
     90 
     91 - **La flash de la Pico no se escribe.** Todo lo persistente va a la SD, en
     92   archivos pre-creados que `sdlog.c` reescribe por dentro (nunca crea archivos ni
     93   toca la FAT). La partida usa dos mitades alternadas con checksum.
     94 - El cargador de la SD deja interrupciones armadas y el core 1 dibujando:
     95   `comun_early_reset` (instalado por `tools/patch_reset.py`) y
     96   `multicore_reset_core1()` lo resuelven.
     97 
     98 ## Separar en repos
     99 
    100 Si los juegos se publican por separado, `comun/` va a su propio repo y cada juego
    101 lo incluye con `git subtree` en `comun/` (y `COMUN=comun`).