102 lines
5.6 KiB
Markdown
102 lines
5.6 KiB
Markdown
# Decisiones de diseño de FnixLib
|
|
|
|
Registro de las decisiones técnicas tomadas en la versión 0.1.0, con su motivo y
|
|
lo que costaría revertirlas. Es un documento nuevo; no sustituye a ningún otro.
|
|
|
|
## Convenciones
|
|
|
|
- **Lenguaje:** C17 estricto (`-std=c17`, sin extensiones de GNU).
|
|
- **Nombres:** funciones `fnix_modulo_accion`, tipos `FnixTipo`, constantes y
|
|
macros `FNIX_NOMBRE`. Los identificadores van en inglés; los comentarios y los
|
|
mensajes de error, en español.
|
|
- **Errores:** las funciones que crean objetos devuelven `NULL` si fallan; las de
|
|
consulta no fallan (devuelven 0/false ante argumentos inválidos). El motivo se
|
|
guarda por hilo y se lee con `fnix_last_error_code()` / `fnix_last_error()`.
|
|
Un éxito no borra el último error (como `errno`).
|
|
- **Objetos opacos:** `FnixWindow` y `FnixCanvas` solo se manejan por puntero, de
|
|
modo que su contenido puede cambiar sin romper la API.
|
|
|
|
## Decisiones
|
|
|
|
### D1. Xlib (libX11) como interfaz con el sistema gráfico de Linux
|
|
Se trata como interfaz nativa del sistema, igual que Win32 en Windows. Alternativas
|
|
descartadas por ahora: hablar el protocolo X11 a mano sobre un socket (mucho trabajo
|
|
sin beneficio en 0.1.0) y Wayland nativo (exige además implementar el protocolo y
|
|
buscar una forma de dibujar). Los ejecutables se verifican bajo X11; en sesiones
|
|
Wayland deberían funcionar mediante XWayland, pero **no está verificado**.
|
|
*Reversible:* todo lo específico de X11 está en `src/platform/linux/` detrás de
|
|
`src/platform/platform.h`.
|
|
|
|
### D2. Renderizador 2D por software y presentación con `XPutImage`
|
|
Es la forma más sencilla de validar la arquitectura sin depender de la GPU. Coste:
|
|
no hay aceleración ni sincronización vertical. El backend de GPU (OpenGL) queda para
|
|
la fase 4 y se añadirá detrás de la misma API de dibujo.
|
|
|
|
### D3. Formato de píxel `0x00RRGGBB` y requisitos de pantalla
|
|
El lienzo guarda `uint32_t 0x00RRGGBB`. Es lo que acepta X11 sin conversión en el
|
|
caso habitual. Si el servidor no ofrece un visual TrueColor de 24/32 bits con esas
|
|
máscaras y el mismo orden de bytes que la CPU, `fnix_window_create` falla con
|
|
`FNIX_ERROR_UNSUPPORTED` y un mensaje explicativo (no se intenta convertir).
|
|
|
|
### D4. Destino de dibujo implícito, por hilo
|
|
`fnix_draw_*` dibuja sobre el lienzo fijado con `fnix_set_target()`;
|
|
`fnix_begin_frame()` fija el de la ventana. Mantiene la API corta
|
|
(`fnix_draw_circle(x, y, r, color)`) y permite pruebas sin ventana usando
|
|
`fnix_canvas_create()`. Coste: estado oculto por hilo.
|
|
|
|
### D5. Ventana de tamaño fijo
|
|
Se indica con los *hints* de tamaño mínimo = máximo. Redimensionar exigiría decidir
|
|
qué ocurre con el lienzo y no aporta a la primera versión.
|
|
|
|
### D6. Entrada: estado por fotograma + cola de eventos
|
|
`fnix_begin_frame()` borra los *pressed/released* y la rueda, procesa los eventos del
|
|
sistema y los aplica a una máquina de estados (`input.c`), que es lo que consultan
|
|
`fnix_key_down`, `fnix_key_pressed`, etc. Además cada evento se guarda en una cola
|
|
de 256 entradas (se descarta lo más antiguo) para quien prefiera
|
|
`fnix_window_poll_event`. Detalles:
|
|
- El autorepeat no vuelve a activar *pressed* (`XkbSetDetectableAutoRepeat`).
|
|
- Al perder el foco, lo pulsado pasa a soltado: evita teclas pegadas.
|
|
- Las teclas se identifican por el KeySym sin modificadores (índice 0) de la
|
|
distribución activa; con distribuciones no QWERTY la tecla física puede cambiar de
|
|
identificador. Alternativa (códigos físicos/scancodes) pospuesta.
|
|
|
|
### D7. Tiempo entre fotogramas y límite de FPS
|
|
El *delta time* se mide de `begin_frame` a `begin_frame` (0 en el primero). El límite
|
|
de FPS (60 por defecto) duerme en `end_frame` hasta una fecha límite que avanza un
|
|
periodo por fotograma, de modo que el promedio a largo plazo es exacto. Si se va más
|
|
de un fotograma tarde, se reajusta en lugar de recuperar con una ráfaga.
|
|
|
|
### D8. Geometría y recorte
|
|
- Entradas limitadas a `[-2^28, 2^28]`; fuera de ese rango no se dibuja y se
|
|
registra un error. Con ese límite los cálculos en `int64_t` no desbordan.
|
|
- Todo se recorta antes de recorrer píxeles: el coste depende del lienzo, no del
|
|
tamaño de la figura (una línea de millones de píxeles fuera de pantalla es barata).
|
|
- Cada primitiva escribe cada píxel como máximo una vez, para que la mezcla con alfa
|
|
no se aplique dos veces.
|
|
- Líneas: Bresenham con aritmética entera; los empates se redondean hacia arriba, por
|
|
lo que una línea y su inversa pueden diferir en algún píxel intermedio.
|
|
- Círculos: un píxel pertenece al disco si `dx² + dy² <= r² + r`; el contorno es el
|
|
disco de radio `r` menos el de `r - 1`.
|
|
|
|
### D9. Mezcla alfa
|
|
"Source-over" con alfa recto y redondeo al entero más cercano; alfa 255 reemplaza y
|
|
alfa 0 no dibuja. `fnix_clear` ignora el alfa.
|
|
|
|
### D10. CMake
|
|
Biblioteca estática por defecto (`BUILD_SHARED_LIBS` la cambia, **sin verificar**),
|
|
tipo *Release* si no se indica otro, opciones `FNIX_BUILD_EXAMPLES`,
|
|
`FNIX_BUILD_TESTS`, `FNIX_WARNINGS_AS_ERRORS` y `FNIX_SANITIZE`. En sistemas que no
|
|
son Linux la configuración falla con un mensaje claro en vez de compilar a medias.
|
|
|
|
### D11. Pruebas
|
|
Tres ejecutables sin pantalla (núcleo, dibujo, entrada) y una prueba de integración
|
|
que usa un servidor X real: una segunda conexión inyecta eventos con `XSendEvent` y
|
|
lee los píxeles de la ventana con `XGetImage`. Sin `DISPLAY` termina con código 77 y
|
|
`ctest` la marca como omitida.
|
|
|
|
## Pendiente (no implementado)
|
|
- `cmake --install`, `find_package(FnixLib CONFIG)` y empaquetado.
|
|
- Windows, y compilación cruzada desde Linux.
|
|
- Imágenes y texturas, fuentes y texto, audio, matemáticas, colisiones, 3D.
|
|
- Licencia: el repositorio no incluye `LICENSE`; debe elegirla el autor.
|