1 puntos por GN⁺ 5 일 전 | 1 comentarios | Compartir por WhatsApp
  • Se añadió a SDL un port para DOS basado en DJGPP y se integró en main con un estado bastante completo, incluyendo video, audio, entrada, hilos, temporizadores, sistema de archivos y cadena de compilación
  • Incluye implementaciones adaptadas al entorno DOS para video VGA y VESA 1.2+, reproducción de audio de la familia Sound Blaster, teclado y mouse PS/2, joystick basado en BIOS, hilos cooperativos y temporizador PIT
  • El problema de seek/read de DJGPP se sorteó vaciando y restaurando el búfer al hacer seek, eliminando lecturas incorrectas y retrasos de varios segundos en SDL_LoadWAV; la ruta de audio también se ajustó para reducir la reentrada de IRQ y el stutter
  • La pantalla negra en fullscreen estaba vinculada a la selección del modo INDEX8; en vez de agregar un hint exclusivo para DOS, se ajustó el orden de los modos de forma lógica, y un commit adicional corrigió también el problema de transparencia del cursor
  • Las pruebas en hardware real fueron limitadas y faltan algunas funciones como grabación de audio, SDL_LoadObject y una implementación específica de DOS para SDL_TIME, pero se integró tras pasar 46 checks y quedó registrado como una función de la versión 3.6.0

Alcance del soporte de la plataforma DOS

  • Se añadió a SDL un port a DOS, que con base en DJGPP alcanzó un estado relativamente maduro
    • El trabajo se repartió entre varias personas, y en la etapa final se sumaron correcciones de estabilidad y funciones faltantes
    • Se probó ampliamente DevilutionX en DOSBox, pero no hubo pruebas en hardware real
    • Algunas funciones se excluyeron deliberadamente porque no había una forma adecuada de probarlas
  • Las funciones compatibles están detalladas con claridad
    • El video incluye framebuffer VGA y VESA 1.2+, color RGB y de índice de 8 bits, programación de la paleta VGA DAC, vsync y page flipping por hardware, además de guardado y restauración del estado VBE al salir
    • El audio es compatible con Sound Blaster 16, Sound Blaster Pro y Sound Blaster 2.0/1.x, usando DMA basada en IRQ y ruta auto-init con doble búfer
    • La entrada incluye teclado PS/2 con códigos de escaneo extendidos, mouse INT 33h y joystick de gameport basado en BIOS INT 15h
    • Los hilos usan un planificador cooperativo basado en setjmp/longjmp y parchado de pila, además de los fallbacks generales para mutex, semaphore, TLS y condition variable
    • Se añadieron puntos de yield en el bombeo de eventos y en la función de delay para mantener la capacidad de respuesta del audio y de otros hilos
    • Los temporizadores usan una implementación basada en PIT con uclock() de DJGPP, con resolución aproximada de 1.19 MHz
    • El sistema de archivos resuelve GetBasePath y GetPrefPath con searchpath() de DJGPP e incluye fallback para operaciones de sistema de archivos POSIX
    • La compilación incluye archivo de toolchain para cross-compiling con CMake, job de CI para DJGPP y preseed cache para una configuración rápida
  • También se indican con claridad las funciones no incluidas
    • Falta la grabación de audio y solo se admite reproducción
    • No hay una implementación nativa de SDL_TIME; se reutiliza gettimeofday de Unix a través de la capa POSIX de DJGPP
    • No se admite la carga de bibliotecas compartidas, por lo que no existe SDL_LoadObject

Proceso de implementación y cambios clave

  • El port a DOS se fue armando a lo largo de varios commits, añadiendo de forma gradual video, audio, entrada, temporizadores, hilos y cadena de compilación
    • Tras el trabajo inicial se fueron incorporando en orden el buffering de stdio, la implementación de audio, el subsistema de video, el sistema de archivos, el mouse, el teclado, la CI y la detección de plataforma
  • En stdio y acceso a archivos se sorteó el problema particular de seek/read en DJGPP
    • Hubo un intento de desactivar el búfer de los SDL_IOStreams de stdio, pero después se cambió por una solución que vacía y restaura el búfer al hacer seek
    • Este cambio fue mucho más rápido que desactivar el búfer por completo y además evitó lecturas incorrectas después de fseek
    • Desapareció el problema de que SDL_LoadWAV tardara varios segundos al leer test/sample.wav, y los datos pasaron a cargarse correctamente
  • El procesamiento de audio también se fue ajustando con foco en la estabilidad
    • Se comenzó con una implementación para Sound Blaster 16, y luego se añadió compatibilidad con mono de 8 bits pre-SB16 y estéreo SB Pro
    • La mezcla de audio pasó de ejecutarse directamente en el manejador de IRQ, a pasar por el loop principal, y luego volvió al hilo de audio de SDL
    • Se cambió de enfoque para evitar problemas de reentrada dentro de la IRQ, y durante la carga se silenció la mitad vieja del búfer DMA para reducir el stutter
    • También se organizaron el ajuste de sample rate, el polling del estado del DSP, el fundamento para la asignación de memoria DMA y la liberación del wrapper de IRET tras restaurar el vector de interrupción
  • El video también amplió funciones según las limitaciones del entorno DOS
    • Se añadió una implementación inicial que funciona con el renderizador por software a través de la interfaz VESA
    • Después se sumaron soporte de paleta de 8 bits, page flipping VBE, restauración de estado, vsync en modo de un solo búfer y modo framebuffer bancarizado de VESA
    • Cuando no hay LFB en VBE 1.2+, el framebuffer se copia mediante bank switching, y en ese modo se desactiva el page flipping
    • Al iniciar y cerrar video, se guarda y restaura el estado completo de VBE para manejar limpiamente el cambio de modo
  • La entrada y el manejo de interrupciones también se pulieron hasta un nivel de uso real
    • El teclado maneja códigos de escaneo extendidos e incluso la tecla Pause, y usa un ring buffer simple para almacenar eventos
    • El mouse consulta la sensibilidad mediante la función 0x1B de INT 33h
    • Para el joystick, el polling de ejes se limita a unos 60 Hz para reducir el costo del timing loop de BIOS, mientras que los botones se siguen consultando siempre de forma directa para mantener la respuesta
    • Se bloquean el código y los datos del ISR para evitar page faults durante interrupciones
  • También se corrigieron problemas de compilación y detección de plataforma
    • Se añadió un job de CI para DJGPP y se incorporó detección de plataforma DOS en CMake
    • SDL_PLATFORM_DOS se agregó a la lista de exclusión de SDL_RunApp() para evitar conflictos con el launcher específico de DOS
    • Aunque DJGPP define __unix__, DOS no tiene GTK ni display server, así que SDL_Gtk_Quit() se excluyó en DOS para evitar errores de enlace
    • También se tuvo en cuenta que algunas toolchains de DJGPP usan el prefijo i386-pc-msdosdjgpp-gcc

Estado de pruebas y limitaciones pendientes

  • Las pruebas automatizadas no terminaron todas de forma completamente fluida, pero llegaron a un punto suficiente para completarse con parches
    • Algunas funciones estándar de formatting impidieron que las pruebas automatizadas llegaran hasta el final, y se usó un parche para sortearlo y completar la ejecución
    • Seguían quedando casos fallidos, pero no se incluyeron porque no había certeza sobre la forma correcta de corregir esas funciones de formatting
    • Se resumió que la mayoría de los demos funcionaban en un nivel razonablemente esperable
  • También se añadieron resultados de uso real
    • En DOSBox y en DOS 6.22 sobre una placa Vortex86, la ventana sin fullscreen funcionó bien tanto con los programas de prueba como con código de usuarios
    • Sin embargo, en fullscreen en ese momento aparecía una pantalla negra vacía en ejemplos como draw.exe --fullscreen
    • El rendimiento se describió como lento, pero utilizable
  • También se identificaron problemas en algunos programas de prueba
    • sprite.exe se cerraba de inmediato en DOSBox
    • wm.exe y draw.exe no renderizaban, aunque sí terminaban al presionar ESC
    • testpalette provocaba un segfault

Problema de selección de profundidad de color en fullscreen y ajustes

  • La causa directa de la pantalla negra en fullscreen era el comportamiento de SDL_GetClosestFullscreenDisplayMode() al caer en un modo INDEX8
    • Si la aplicación no podía manejar renderizado INDEX8, la pantalla quedaba negra
    • En la implementación interna, INDEX8 se consideraba solo si el usuario ya había configurado un modo fullscreen INDEX8
  • Al principio se añadió en DOS una respuesta que ocultaba los modos INDEX8 detrás del SDL_HINT_DOS_ALLOW_INDEX8_MODES
    • La idea era que las aplicaciones hicieran opt-in explícito solo si podían manejarlos correctamente
  • Pero en la rama principal ya se había incorporado un cambio para elegir la mayor profundidad de bits en vez de la menor, y se siguió la línea de comprobar si eso resolvía el problema
    • Ese cambio resolvía el problema de bpp, pero introducía otro nuevo: al pedir un best fit de 640x480 se elegía 1024x768
    • Finalmente ese cambio se revirtió y se decidió tratar una corrección mejor en un PR aparte
  • Al final se eliminó el hint exclusivo para DOS y se pasó a ordenar los modos de manera lógica
    • Se añadió el commit Remove SDL_HINT_DOS_ALLOW_INDEX8_MODES and order modes logically
    • Se indicó que, si se fusiona #15442, la selección automática de modo podría funcionar correctamente incluso en apps que no configuran paleta o no eligen directamente el modo fullscreen
    • También se marcó un límite: no se iba a seguir profundizando indefinidamente en otros problemas previos de SDL dentro de este mismo PR

Correcciones de renderizado en demos y del cursor

  • El problema de los demos que se veían en negro no dependía solo de este PR, sino también del estado de integración de #15442
    • Mientras SDL_GetClosestFullscreenDisplayMode() siguiera prefiriendo la menor profundidad de color, este port elegía INDEX8 y, si la app no configuraba la paleta, la pantalla quedaba negra
    • Se confirmó que, al fusionar localmente ese PR, todos los casos de prueba funcionaban
  • El problema visual restante era la transparencia del cursor
    • Tras la verificación local se descubrió además que solo el cursor no era transparente
    • Para corregirlo se añadió el commit Don't convert cursor if dest is not INDEX8
    • Después de la corrección, en modo RGB se usa una versión no optimizada, pero el funcionamiento quedó correcto tanto en RGB como en INDEX8
    • Queda algo de margen para mejorar rendimiento en XRGB1555 y RGB565, pero se consideró de baja prioridad

Revisión y decisión de integración

  • Se consideró que el PR era adecuado para squash merge
    • Como GitHub mantiene la referencia al PR en el commit resultante, se entendió que el proceso de trabajo también quedaba rastreable
    • También se propuso añadir menciones de crédito extra en el commit final
    • Incluso se incluyó el texto concreto para agregar dos Co-authored-by y un Tested-by
  • El revisor comentó que, después de integrar, reescribiría con más limpieza parte de la expresión en algunos scripts de compilación
  • Justo antes de la integración final, se definió avanzar fusionando también otros PR relacionados y luego el PR de DOS
    • Tras “Last call on DOS pull request!”, se confirmó el estado de integración de PR relacionados
    • Después se integró en main con 46 checks passed
  • También quedó claramente delimitado el alcance para la versión
    • Este cambio se considera una función de la 3.6.0
    • No se hará cherry-pick a 3.4.x

      • Al día siguiente de la integración se eliminó la rama de trabajo de DOS

Tareas posteriores y problemas de hardware pendientes

  • También se planteó un problema con la implementación de 4f07(SetDisplayStart) en algunas GPU Nvidia
    • Junto con el enlace al hilo de VOGONS, se indicó que, aunque aparezcan como compatibles en reportes, hay GPU en las que en la práctica no funciona
    • Se menciona que el alcance podría ir desde GeForce 9300 hasta 3060, aunque no es un rango completo sino basado en el hardware disponible
    • En las pruebas del proyecto también se observó el mismo problema de visualización
  • No se consideró deseable que SDL desactive funciones según el fabricante de GPU, y por eso también se mencionó la posibilidad de un hint de control para el usuario
    • Se planteó que un nuevo hint para que el usuario controle directamente page_flip_available podría ser una mejor solución
    • El tema se cerró dejando abierta la posibilidad de añadirlo más adelante, sin tratarlo de inmediato
  • Tras la integración también se mencionó un hint para uso directo del framebuffer
    • Se indicó que, al activar SDL_HINT_DOS_ALLOW_DIRECT_FRAMEBUFFER, el problema anterior con SetDisplayStart podría dejar de ser tan importante

1 comentarios

 
GN⁺ 5 일 전
Comentarios de Hacker News
  • Ahora, con solo tener SDL para UEFI, ya se pueden ejecutar juegos incluso en un entorno previo al arranque del SO

    • Me pregunto si Intel Management Engine / Minix, que corre en todos los chipsets de Intel, sigue igual hoy en día
      También me pregunto si la seguridad se endureció más o si sigue siendo accesible https://www.zdnet.com/article/minix-intels-hidden-in-chip-operating-system/
    • En realidad no parece que fuera tan difícil
      Pero según entiendo, UEFI no tiene drivers de audio, y hoy en día incluso los chips de códec de audio solo tienen datasheets bajo NDA, así que escribirlos a mano también es complicado
      Lo más absurdo es que el graphics output protocol no tiene información de vsync, así que no se puede hacer blitting sin tearing, y eso literalmente es peor que VGA
    • UEFI se siente un poco como un DOS moderno
    • Siendo sincero, es una imagen increíblemente genial
      Pensar en arrancar con un menú tipo grub y que aparezca toda una lista de juegos clásicos emociona bastante
    • En una palabra, es SDL para bare metal
  • Lo especialmente gracioso de esta captura es que DosBOX en sí está hecho sobre SDL

    • Entonces ahora hace falta un dosbox corriendo dentro de DOS
    • Es SDLception en estado puro
  • Esto usa DJGPP, así que cambia la CPU a modo de 32 bits con DPMI
    Por eso no se siente esa vibra realmente old-school de memoria segmentada, near pointer y toda clase de límites de 64 KB por todas partes

  • Qué bueno
    Me da curiosidad qué pasaría si se usa junto con los ejecutables de MS-DOS para 386+ de FreeBASIC, que soporta bindings de SDL
    [1] - https://github.com/freebasic/fbc

    • Pienso probarlo yo mismo
      Llevo años pensando que debería volver a portar OHRRPGCE, que originalmente venía de DOS, otra vez a DOS
      Y considerando que SDL eliminó agresivamente casi todos los ports y el soporte de SO que tenía en la época de SDL 1.2, es bastante sorprendente que SDL3 haya recuperado soporte para DOS
  • Perfecto
    Esta mañana estaba desarrollando en Turbo C dentro de DOSBox-X dentro de Debian GNU/Linux dentro de VMware Fusion dentro de macOS, así que esta noticia me cae justo a tiempo

    • Necesito saber si era broma o lo decía en serio
    • Me pregunto si había alguna variante de turboc para Linux
      Me queda un recuerdo muy vago de haber trabajado con turboc hace décadas
    • Entonces seguro también disfrutarías la película Inception :)
  • Estrictamente hablando, esto ya era posible con HXDOS
    Porque emulaba DirectDraw lo bastante bien como para que SDL pudiera usarlo

    • Espera, ¿qué?
      Entonces me pregunto con qué target de SDL se compila
      Si es fullscreen exclusivo de Win32, o si es alguna resolución VESA como 640x480
  • En un proyecto open source como SDL, que entre este tipo de soporte normalmente depende de qué tan intrusivos sean los cambios y de si quien contribuye realmente va a seguir manteniéndolo
    Cada proyecto tiene políticas distintas y no sé cuál sea la de SDL, pero como ya tienen muchos ports, supongo que saben bien en qué se están metiendo

    • El soporte para este tipo de arquitecturas raras casi siempre se sostiene gracias a una sola persona con un sueño, y a un héroe que de verdad lo construye y lo mantiene
      Mi ejemplo favorito es openbsd luna88k https://www.openbsd.org/luna88k.html
      No tengo idea de cuántos usuarios reales hay. Creo que era una máquina bastante rara que solo salió en Japón, y si hay usuarios probablemente la mayoría estén allá, fuera de mi radar, así que desde mi perspectiva da la impresión de que el único usuario es quien la porta
      Y aun así, en cada release, unas semanas después de la fecha oficial, aparece de la nada para subir los archivos y paquetes de luna88k, como si saliera del bosque
      Imagino que tarda porque compila en una luna88k real, y de cualquier modo eso basta para que siga siendo una plataforma oficial de hardware de OpenBSD
      Yo no es que quiera una luna88k, pero de verdad admiro a esa persona que hace que siga funcionando
  • Se siente como si SDL estuviera volviendo a sus raíces de la era de Loki

  • Está genial
    ¿Por qué? No sé, pero si está genial, ya es suficiente

    • Porque ahora podemos correr Dota 2 en DOS
    • El DOSBox basado en navegador funciona tan fácil y tan rápido que DOS se vuelve un target muy portable para juegos pequeños y también para juegos bastante serios
      Como se puede ver en Internet Archive, con solo teclado y mouse se puede ejecutar prácticamente en cualquier lado hasta una complejidad AAA de mediados de los 90
      Juegos como Tomb Raider, Command & Conquer y Quake son así, y si lo que quieres es una plataforma que simplemente funcione, resulta bastante atractiva
      Si además le sumas SDL, se vuelve mucho más fácil
    • FreeDOS es, técnicamente hablando, un DOS moderno que todavía recibe soporte activo
    • SDL es una biblioteca multimedia multiplataforma, y DOS también es una plataforma
  • Me da muchísima alegría
    Esto me hace muy feliz