1 pontos por GN⁺ 5 일 전 | 1 comentários | Compartilhar no WhatsApp
  • Foi adicionado ao SDL um port para DOS baseado em DJGPP, e ele foi mesclado ao main já com um conjunto amplo de recursos, incluindo vídeo, áudio, entrada, threading, temporizadores, sistema de arquivos e cadeia de build
  • Foram implementados recursos voltados ao ambiente DOS, como vídeo VGA e VESA 1.2+, reprodução de áudio da família Sound Blaster, teclado e mouse PS/2, joystick baseado em BIOS, threading cooperativo e temporizador PIT
  • Os problemas de seek/read do DJGPP foram contornados despejando e restaurando o buffer ao fazer seek, eliminando leituras incorretas e atrasos de vários segundos em SDL_LoadWAV; o caminho de áudio também foi refinado para reduzir reentrada de IRQ e stutter
  • A tela preta em fullscreen estava ligada à seleção do modo INDEX8; em vez de manter uma hint específica para DOS, o ajuste seguiu para uma ordenação lógica dos modos, e um commit adicional também corrigiu o problema de transparência do cursor
  • Os testes em hardware real foram limitados, e ainda faltam alguns recursos, como gravação de áudio, SDL_LoadObject e uma implementação específica de DOS para SDL_TIME, mas o merge foi concluído após passar em 46 checks e foi classificado como recurso da versão 3.6.0

Escopo do suporte à plataforma DOS

  • Foi adicionado ao SDL um port para DOS, que alcançou um nível relativamente maduro com base em DJGPP
    • O trabalho foi dividido entre várias pessoas, e na etapa final foram acrescentadas correções de estabilidade e complementos para recursos faltantes
    • O DevilutionX foi extensivamente testado no DOSBox, mas não houve testes em hardware real
    • Alguns recursos também foram deliberadamente deixados de fora por falta de uma forma adequada de testá-los
  • Os recursos suportados estão descritos de forma detalhada
    • O vídeo inclui framebuffer VGA e VESA 1.2+, cores RGB e indexadas em 8 bits, programação da paleta VGA DAC, vsync e page flipping por hardware, além de salvamento e restauração do estado VBE ao sair
    • O áudio oferece suporte a Sound Blaster 16, Sound Blaster Pro e Sound Blaster 2.0/1.x, usando DMA baseada em IRQ e caminho auto-init com buffer duplo
    • A entrada inclui teclado PS/2 com scancodes estendidos, mouse via INT 33h e joystick de gameport baseado em BIOS INT 15h
    • O threading usa um escalonador cooperativo com setjmp/longjmp e patching de stack, além dos fallbacks genéricos para mutex, semaphore, TLS e condition variable
    • O pump de eventos e a função de delay incluem pontos de yield para manter a responsividade do áudio e de outras threads
    • Os temporizadores usam uma implementação baseada em PIT com uclock() do DJGPP, com resolução de cerca de 1,19 MHz
    • O sistema de arquivos trata GetBasePath e GetPrefPath com searchpath() do DJGPP e também inclui fallback para operações de sistema de arquivos POSIX
    • O build inclui arquivo de toolchain para cross-compilation com CMake, job de CI para DJGPP e cache preseed para configuração mais rápida
  • Também foi deixado claro o que não está incluído
    • Gravação de áudio não está presente; apenas reprodução é suportada
    • Não há implementação nativa de SDL_TIME; é reutilizado o gettimeofday Unix por meio da camada POSIX do DJGPP
    • Carregamento de bibliotecas compartilhadas não é suportado, portanto não há SDL_LoadObject

Processo de implementação e mudanças principais

  • O port para DOS foi evoluindo ao longo de vários commits, com adição gradual de vídeo, áudio, entrada, temporizadores, threading e cadeia de build
    • Depois do trabalho inicial, foram sendo complementados em sequência o buffering de stdio, implementação de áudio, subsistema de vídeo, sistema de arquivos, mouse, teclado, CI e detecção de plataforma
  • Em stdio e acesso a arquivos, foi contornado um problema característico de seek/read do DJGPP
    • Houve uma tentativa de desativar o buffer dos SDL_IOStreams de stdio, mas depois isso foi substituído por um método de despejar e restaurar o buffer ao fazer seek
    • Essa mudança é muito mais rápida do que desativar completamente o buffer, e também evita leituras incorretas após fseek
    • Com isso, SDL_LoadWAV deixou de levar vários segundos para ler test/sample.wav e passou a retornar os dados corretos
  • O processamento de áudio também foi ajustado repetidamente com foco em estabilidade
    • A implementação começou com Sound Blaster 16, e depois ganhou suporte a mono 8 bits pré-SB16 e estéreo SB Pro
    • A mixagem de áudio saiu de uma execução direta no handler de IRQ para o loop principal e depois voltou para a thread de áudio do SDL
    • A direção foi alterada para evitar problemas de reentrada dentro da IRQ, e durante carregamento a metade antiga do buffer DMA passou a ser preenchida com silêncio para reduzir stutter
    • Também foram organizados os ajustes de sample rate, polling do estado do DSP, justificativa para alocação de memória DMA e remoção do wrapper de IRET após restaurar o vetor de interrupção
  • O vídeo também teve recursos ampliados para atender às limitações do ambiente DOS
    • Foi adicionada uma implementação inicial baseada na interface VESA funcionando com o renderizador de software
    • Depois vieram suporte a paleta de 8 bits, page flipping VBE, restauração de estado, vsync em modo single-buffer e modo framebuffer VESA banked
    • Em VBE 1.2+ sem LFB, a cópia para o framebuffer é feita via bank switching, e nesse modo o page flipping é desativado
    • O estado completo do VBE é salvo e restaurado na inicialização e no encerramento do vídeo para que a troca de modo seja limpa
  • O tratamento de entrada e interrupções também foi refinado até um nível utilizável na prática
    • O teclado lida com scancodes estendidos e até com a tecla Pause, usando um ring buffer simples para armazenar eventos
    • O mouse usa a function 0x1B da INT 33h para consultar e usar a sensibilidade
    • No joystick, o polling dos eixos foi limitado a cerca de 60 Hz para reduzir o custo do loop de temporização da BIOS, enquanto os botões seguem em polling direto para manter a responsividade
    • Código e dados de ISR são travados na memória para evitar page faults durante interrupções
  • Problemas de build e detecção de plataforma também foram corrigidos
    • Foi adicionado um job de CI para DJGPP, além da detecção de plataforma DOS no CMake
    • SDL_PLATFORM_DOS foi incluído na lista de exclusão de SDL_RunApp() para evitar conflito com o launcher específico de DOS
    • Como o DJGPP define __unix__, mas o DOS não tem GTK nem display server, SDL_Gtk_Quit() foi excluído no DOS para evitar erro de linkedição
    • Também foi considerado o fato de alguns toolchains DJGPP usarem o prefixo i386-pc-msdosdjgpp-gcc

Estado dos testes e limitações restantes

  • Os testes automatizados não terminaram todos de forma totalmente suave, mas chegaram a um ponto em que era possível concluir com patches
    • Alguns problemas em funções padrão de formatação impediram que os testes automatizados fossem até o fim, e isso foi contornado com patches para permitir a execução
    • Ainda restavam casos com falha, mas eles não foram incluídos porque não havia confiança sobre qual seria a correção correta dessas funções de formatação
    • No geral, foi resumido que a maioria dos demos funciona em um nível razoavelmente esperado
  • Também foram adicionados resultados de uso real
    • No DOSBox e em DOS 6.22 em uma placa Vortex86, a janela não fullscreen funcionou bem tanto nos programas de teste quanto no código de usuário
    • Já o fullscreen, naquele momento, exibia uma tela preta vazia em exemplos como draw.exe --fullscreen
    • O desempenho foi descrito como lento, mas utilizável
  • Alguns problemas em programas de teste também foram identificados
    • sprite.exe encerra imediatamente no DOSBox
    • wm.exe e draw.exe não renderizam, mas encerram ao pressionar ESC
    • testpalette gera segfault

Problema de seleção de profundidade de cor em fullscreen e ajuste

  • A causa direta da tela preta em fullscreen era o comportamento em que SDL_GetClosestFullscreenDisplayMode() caía em um modo INDEX8
    • Se a aplicação não consegue lidar com renderização INDEX8, a tela fica preta
    • Na implementação interna, o INDEX8 passou a ser considerado apenas quando o usuário já tiver configurado explicitamente um modo fullscreen INDEX8
  • Inicialmente, foi adicionada uma solução para DOS que escondia modos INDEX8 atrás de SDL_HINT_DOS_ALLOW_INDEX8_MODES
    • A ideia era exigir opt-in explícito apenas quando a aplicação pudesse lidar corretamente com eles
  • Porém, na branch principal já havia entrado uma mudança para escolher a maior profundidade de bits em vez da menor, e seguiu-se um fluxo para verificar se isso resolveria o problema
    • Essa mudança resolveu a questão do bpp, mas criou outro problema: uma solicitação de best fit para 640x480 acabava escolhendo 1024x768
    • No fim, essa alteração foi revertida, e a direção ficou em tratar uma correção melhor em um PR separado
  • No resultado final, a hint específica de DOS foi removida e substituída por uma ordenação lógica dos modos
    • Foi adicionado o commit Remove SDL_HINT_DOS_ALLOW_INDEX8_MODES and order modes logically
    • Quando #15442 for mesclado, também deve passar a funcionar corretamente a seleção automática de modo para apps que não definem paleta nem escolhem diretamente o modo fullscreen
    • Também ficou claro que a intenção não era continuar expandindo indefinidamente esse PR para cobrir outros problemas antigos do SDL

Renderização dos demos e correção do cursor

  • O problema de demos aparecendo em preto não dependia apenas deste PR, mas também do estado de merge de #15442
    • Enquanto SDL_GetClosestFullscreenDisplayMode() continuar preferindo a menor profundidade de cor, este port escolhe INDEX8, e se o app não definir a paleta a tela fica preta
    • Foi confirmado que, ao mesclar esse PR localmente, todos os casos testados passaram a funcionar
  • O problema visual restante era a transparência do cursor
    • Após verificação local, descobriu-se adicionalmente que apenas o cursor não estava transparente
    • Para corrigir isso, foi adicionado o commit Don't convert cursor if dest is not INDEX8
    • Depois da correção, em modo RGB passa-se a usar uma versão não otimizada, mas o comportamento fica correto tanto em RGB quanto em INDEX8
    • Ainda existe margem para desempenho um pouco melhor em XRGB1555 e RGB565, mas isso foi tratado como baixa prioridade

Revisão e decisão de merge

  • Foi considerado que o PR era adequado para squash merge
    • Como o GitHub mantém a referência ao PR no commit resultante, entendeu-se que o histórico do trabalho continuaria rastreável
    • Também foi sugerido adicionar créditos extras no commit final
    • O texto incluía formulações concretas para acrescentar dois Co-authored-by e um Tested-by
  • O revisor comentou que, após o merge, ainda reescreveria algumas expressões dos scripts de build de forma mais limpa
  • Pouco antes do merge final, a direção foi consolidada como mesclar também outros PRs relacionados e então seguir com o PR de DOS
    • Após “Last call on DOS pull request!”, foi confirmado o estado de merge dos PRs relacionados
    • Em seguida, ele foi mesclado ao main com 46 checks passed
  • Depois do merge, o escopo de release também foi claramente definido
    • Essa mudança é tratada como recurso da versão 3.6.0
    • Não será feito cherry-pick para a 3.4.x

      • No dia seguinte ao merge, a branch de trabalho do DOS foi removida

Tarefas futuras e problemas de hardware restantes

  • Também foi levantado um problema em que a implementação de 4f07(SetDisplayStart) de algumas GPUs Nvidia não funciona corretamente
    • Foi incluído um link para a thread no VOGONS, com a observação de que algumas GPUs aparecem como suportadas nos relatórios, mas na prática não funcionam
    • Foi mencionado que a faixa de testes pode ser mais ampla, de GeForce 9300 até 3060, mas isso não representa uma cobertura completa, e sim o conjunto de hardware disponível
    • O mesmo problema de exibição também foi observado nos testes do projeto
  • Não foi considerado desejável que o SDL desative recursos com base no fabricante da GPU, e por isso também foi levantada a possibilidade de uma hint de controle pelo usuário
    • Surgiu a ideia de que uma nova hint para controlar page_flip_available diretamente pelo usuário poderia ser melhor
    • O tema foi encerrado com a perspectiva de que isso poderia ser adicionado depois, sem tratamento imediato
  • Após o merge, também foi mencionada uma hint para uso direto do framebuffer
    • Foi observado que, ao ativar SDL_HINT_DOS_ALLOW_DIRECT_FRAMEBUFFER, o problema citado com SetDisplayStart pode deixar de ser tão importante

1 comentários

 
GN⁺ 5 일 전
Comentários do Hacker News
  • Agora, basta existir um SDL para UEFI para que seja possível rodar jogos até no ambiente pré-boot do SO

    • Fico curioso se o Intel Management Engine / Minix, que roda em todos os chipsets Intel, ainda continua do mesmo jeito hoje em dia
      Também queria saber se a segurança ficou mais robusta ou se ainda continua acessível https://www.zdnet.com/article/minix-intels-hidden-in-chip-operating-system/
    • Na verdade, isso provavelmente não seria tão difícil assim
      Só que, pelo que eu saiba, a UEFI não tem driver de som, e hoje em dia até chips de codec de áudio só têm datasheets sob NDA, então escrever isso na mão também é complicado
      O mais absurdo é que o graphics output protocol não tem informação de vsync, então não dá para fazer blitting sem tearing, e isso é literalmente pior do que VGA
    • A UEFI parece um tipo de DOS moderno
    • Sinceramente, é uma imagem muito legal
      Só de imaginar dar boot por um menu tipo grub e aparecer uma lista inteira de jogos clássicos já dá uma empolgação
    • Em resumo, é um SDL para bare metal
  • O que torna esse screenshot especialmente engraçado é que o próprio DosBOX foi feito em cima do SDL

    • Então agora precisamos de um dosbox rodando dentro do DOS
    • É SDLception em estado puro
  • Isso usa DJGPP, então troca a CPU para modo 32 bits via DPMI
    Por isso acaba não passando aquela sensação realmente old school de segmented memory, near pointer e todo tipo de limite de 64 KB aparecendo por toda parte

  • Legal
    Fiquei curioso para saber como isso ficaria junto com executáveis MS-DOS para 386+ do FreeBASIC, que suporta bindings de SDL
    [1] - https://github.com/freebasic/fbc

    • Vou testar eu mesmo
      Já faz anos que penso em portar de volta para DOS o OHRRPGCE, que originalmente era do DOS
      E, considerando como o SDL eliminou agressivamente quase todos os ports e suportes a SO que existiam na era do SDL 1.2, é bem surpreendente que o SDL3 tenha recuperado suporte a DOS
  • Perfeito
    Hoje de manhã eu estava desenvolvendo no Turbo C dentro do DOSBox-X dentro do Debian GNU/Linux dentro do VMware Fusion no macOS, então essa notícia veio na hora certa

    • Eu realmente queria saber se isso foi piada ou sério
    • Fiquei pensando se existia alguma variante de turboc para Linux
      Tenho uma lembrança vaga de ter trabalhado com turboc décadas atrás
    • Nesse caso, você provavelmente também vai gostar do filme Inception :)
  • Tecnicamente, isso já era possível com HXDOS
    Porque ele emulava DirectDraw bem o bastante para o SDL conseguir usar

    • Espera, o quê?
      Então fiquei curioso para saber para qual alvo de SDL isso é compilado
      Se é fullscreen exclusivo de Win32, ou alguma resolução VESA tipo 640x480
  • Em projetos open source como o SDL, esse tipo de suporte normalmente depende de quão intrusivas são as mudanças e se o contribuinte realmente vai continuar fazendo manutenção
    Cada projeto tem sua própria política, e eu não conheço a do SDL, mas como já existem tantos ports, imagino que eles saibam bem no que estão se metendo

    • Suporte a esse tipo de arquitetura rara quase sempre é sustentado por uma única pessoa sonhadora, um herói que de fato constrói e mantém aquilo
      Meu exemplo favorito é o openbsd luna88k https://www.openbsd.org/luna88k.html
      Não faço ideia de quantos usuários reais isso tem. Acho que era uma máquina bem rara, lançada provavelmente só no Japão, e se houver usuários, a maioria deve estar por lá, fora do meu campo de visão, então na prática parece que o único usuário é o portador
      Mesmo assim, a cada release, algumas semanas depois da data oficial, surgem do nada os arquivos e pacotes do luna88k como se tivessem saído da floresta
      Imagino que seja porque compilar num luna88k real demora bastante, e, de qualquer forma, isso por si só já basta para manter a plataforma como hardware oficialmente suportado pelo OpenBSD
      Eu mesmo não quero ter um luna88k, mas respeito muito a pessoa que faz isso continuar funcionando
  • Dá a sensação de que o SDL está voltando às suas raízes da era Loki

  • Legal
    Por quê? Não sei, mas se é legal, já basta

    • Agora dá para rodar Dota 2 no DOS
    • Como o DOSBox no navegador roda de forma tão fácil e rápida, o DOS vira um alvo portátil que consegue receber desde joguinhos até jogos bem mais sérios
      Como dá para ver no Internet Archive, com só teclado e mouse já é possível rodar praticamente em qualquer lugar algo com a complexidade de um AAA de meados dos anos 90
      Jogos como Tomb Raider, Command & Conquer e Quake entram nisso, e, se você quer uma plataforma que simplesmente funciona, é algo bem atraente
      Com SDL, isso fica muito mais fácil
    • O FreeDOS é, tecnicamente, um DOS moderno que ainda recebe suporte ativo
    • SDL é uma biblioteca multimídia multiplataforma, e DOS também é uma plataforma
  • Fico muito feliz
    Isso me deixa genuinamente contente