5.6 KiB
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, tiposFnixTipo, constantes y macrosFNIX_NOMBRE. Los identificadores van en inglés; los comentarios y los mensajes de error, en español. - Errores: las funciones que crean objetos devuelven
NULLsi fallan; las de consulta no fallan (devuelven 0/false ante argumentos inválidos). El motivo se guarda por hilo y se lee confnix_last_error_code()/fnix_last_error(). Un éxito no borra el último error (comoerrno). - Objetos opacos:
FnixWindowyFnixCanvassolo 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 enint64_tno 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 radiormenos el der - 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.