Este projeto é um port Linux enxuto inspirado no modelo de containers do Winlator v11.1 para consoles dArkOS baseados em RK3326, como R36S, R36H e RX6H. Ele mantém containers separados, configuração por programa, limite de memória salvo por container, atalhos, biblioteca interna de jogos e acesso aos programas Windows armazenados no cartão SD.
O projeto não é um APK Android. A interface foi reimplementada em C++/SDL2 para Linux ARM64. O gerenciador grava os dados em arquivos de configuração dentro do cartão, o Box64 é compilado para AArch64 com dynarec e o launcher usa Wine como componente externo. Para o Mali-G31, o caminho principal é WineD3D/OpenGL/GLES com Panfrost; Vulkan e DXVK são opções experimentais e não são requisitos do pacote.
A interface SDL2 possui criação, duplicação e remoção de containers, memória por container, preset Box64, modo Wine, gráfico, áudio, driver SDL de vídeo, modo de entrada, perfil de desempenho, autostart, contador FPS, atalhos e biblioteca interna de jogos. O launcher foi compilado para host x86_64 e ARM64; ambos passaram pelo self-test sob execução nativa/QEMU AArch64. O runner passou por testes de PE32, PE32+, seleção automática de Wine, propagação de memória e opções avançadas, instalação DXVK em prefixo isolado e rejeição de executáveis fora de /roms/pc/.
A biblioteca interna procura recursivamente por .exe, .bat, .com e .msi em /roms/pc/. Ela mostra o caminho relativo e o container detectado para cada programa, sem exigir que o jogo seja iniciado pela lista normal de ROMs do EmulationStation. Ao abrir o Winlator diretamente, a tela inicial continua sendo a de containers; pressione P para entrar na tela de jogos. Ao selecionar um jogo e pressionar Enter, o launcher inicia o runner com o container associado. Se não houver associação, o container default é usado.
No laboratório, o C-Dogs SDL 2.3.0 win64 chegou ao menu principal usando Wine 11.15 WOW64, X11/Xvfb, OpenGL e o runner completo, desde que se use um prefixo Wine previamente inicializado. O teste visual está em tests/artifacts/runner-wow64/screen.png. A criação de um prefixo limpo travou no laboratório por falta de DRI3 e pela janela de instalação do Wine Mono; isso é um bloqueio de bootstrap da VM, não uma prova de incompatibilidade do jogo. No R36S ainda é necessário testar o kernel, a Mesa/Panfrost, a saída de áudio e a imagem dArkOS efetivamente usada pelo console.
A documentação oficial do Mesa registra para Mali-G31/Bifrost v7 OpenGL ES 3.1, OpenGL 3.1 e Vulkan 1.3, mas ressalva que a conformidade é garantida apenas para alguns modelos e que PanVK é não conformante fora do G610. Por isso, o port prioriza WineD3D/OpenGL/GLES. Esse caminho é adequado para jogos 2D, GDI, DirectDraw, SDL e parte dos jogos 3D antigos, embora o desempenho dependa de shaders, resolução e carga do Cortex-A35.
O modo vulkan somente seleciona o backend Vulkan. O modo dxvk prepara DLLs x64/x32 e overrides de Direct3D 8/9/10/11, mas exige que o usuário forneça runtime/dxvk/x64/ e runtime/dxvk/x32/ com as DLLs correspondentes e que vulkaninfo mostre um driver Mali/PanVK funcional no console. DXVK não é o padrão porque a existência de Vulkan no chip não garante conformidade ou compatibilidade suficiente para todos os jogos.
Sim, o port foi desenhado para iniciar jogos Windows: cada jogo pode apontar para um container, prefixo Wine, limite de memória, preset Box64, configuração gráfica, driver de vídeo, áudio, modo de entrada, perfil de desempenho e atalho próprios. O primeiro alvo realista são jogos Windows 2D pequenos, engines 2D, shareware antigo e jogos independentes simples que não usem DRM, anti-cheat, launcher online ou dependências pesadas.
Executáveis PE32 são detectados e direcionados para o caminho WOW64 quando wine_mode=auto. Executáveis PE32+ x86-64 seguem o Wine x86_64 sob Box64. A opção arm64-wow64 exige um Wine ARM64 WOW64 e runtime/bin/wowbox64.dll; box32 permanece experimental. Para máxima compatibilidade, a configuração recomendada é uma build Linux nativa de Wine x86_64 WOW64, pois ela cobre jogos Windows 32-bit e 64-bit sem exigir uma árvore Linux i386 completa.
Jogos com DirectX 8/9, OpenGL ou DirectDraw podem ser tentados depois da validação 2D, mas não há promessa de velocidade jogável para títulos 3D. O teste de Neverball 1.6.0 no laboratório ficou bloqueado por uma falha de página durante a inicialização do Wine, antes de ser possível classificar a compatibilidade do jogo. Jogos modernos, Vulkan, DXVK, .NET sem Wine Mono, DRM, anti-cheat e dependências proprietárias ficam condicionais ou fora da primeira versão.
Coloque os programas Windows em /roms/pc/. A biblioteca interna varre essa pasta e seus subdiretórios. O port cria containers em /roms/winlator/containers/, logs em /roms/winlator/logs/, caches em /roms/winlator/cache/ e backups de instalação em /roms/winlator/backups/. O runtime fica em /opt/winlator-rk3326/.
O launcher nunca trata /roms/pc/ como armazenamento privado do Android. Ele resolve o caminho real do executável, rejeita arquivos fora da raiz de jogos e não executa configuração usando eval. Caminhos de trabalho ficam limitados ao jogo ou ao diretório do container. Isso permite colocar o executável e os dados do jogo na partição acessível do cartão sem depender de /data/data/com.winlator.
Baixe winlator-rk3326-darkos-0.3.2.zip na página de releases do repositório e extraia no computador ou diretamente em uma pasta acessível do cartão. A pasta extraída contém install-darkos.sh, bin/, scripts/ e integration/ na raiz; não é necessário compilar no console. No dArkOS, confirme que /roms está montado e execute o instalador a partir da pasta extraída:
cd /roms/pc/winlator-rk3326-darkos-0.3.2
sudo sh ./install-darkos.shSe o pacote estiver em outra pasta, substitua o caminho do cd. O instalador salva uma cópia do XML atual do EmulationStation em /roms/winlator/backups/<data>/ antes de adicionar o sistema windows-rk3326. No dArkOS em execução, o alvo padrão é /etc/emulationstation/es_systems.cfg; a entrada usa /roms/pc/ e chama /opt/winlator-rk3326/bin/winlator.sh. A instalação é reversível e não remove ROMs, containers ou saves durante o rollback.
O ZIP contém o launcher, Box64 e wowbox64.dll, mas não contém uma distribuição Wine completa. Antes de iniciar jogos, coloque uma build Linux x86_64/WOW64 compatível em /opt/winlator-rk3326/wine/ ou configure wine_root/wine_binary no container. Sem Wine, a interface instala e abre, mas nenhum .exe poderá ser executado.
Para abrir a interface sem selecionar um executável, use o atalho Winlator-RK3326-UI.sh em Ports/Tools ou execute:
/opt/winlator-rk3326/bin/winlator-rk3326-uiNa tela de containers, use o direcional para selecionar um container. Enter confirma e inicia o programa associado; Esc sai; P abre a biblioteca interna; M alterna a memória; N cria um container; D duplica; R remove o container selecionado. Os botões equivalentes são A, B, X, Y, L, R e o botão configurado para remoção conforme a placa do controle.
Na biblioteca interna, o direcional seleciona os executáveis encontrados em /roms/pc/, Enter inicia o jogo, Esc retorna à tela de containers e P também permite voltar. O item selecionado mostra o caminho relativo, por exemplo meu-jogo/bin/game.exe, e o container detectado. O launcher grava ou reutiliza o atalho do programa no container correspondente. Containers novos recebem autostart=1, portanto o container é preparado automaticamente quando um jogo é selecionado; o valor também fica salvo no arquivo de configuração e pode ser ajustado manualmente para 0.
As teclas de configuração são as seguintes. B alterna o preset Box64 entre default, safe, fast e fastest. G alterna wined3d, opengl, vulkan e dxvk. V alterna o driver SDL entre auto, kmsdrm, fbcon, x11, wayland e dummy. I alterna o modo de controle entre auto, sdl e keyboard. A alterna ALSA/dummy. T alterna o perfil de desempenho entre auto, normal, battery e max. O alterna o FPS entre auto, on e off; on liga o overlay e off desliga o overlay. No controle, D-pad esquerdo executa T e D-pad direito executa O. O valor de memória zero significa sem limite rígido.
No perfil auto, o runner usa perfmax quando disponível e restaura perfnorm ao encerrar o jogo. normal não força governor, battery restaura o modo normal antes de iniciar e max força o governor de desempenho. Se o sistema não fornecer os comandos perfmax/perfnorm, o jogo continua sendo iniciado e o log registra que o governor não estava disponível.
O modo FPS auto ou on usa MangoHud, quando disponível, com apenas FPS, fonte pequena, posição no canto superior direito e fundo translúcido. A partir da release 0.3.1, os perfis opengl e wined3d definem SDL_RENDER_DRIVER=opengl por padrão, porque alguns jogos SDL escolhem o renderer software e, nesse caso, o overlay não recebe frames OpenGL. Para um jogo que precise de software, use WINLATOR_SDL_RENDER_DRIVER=software antes de iniciá-lo. Quando MangoHud não está instalado, o runner tenta o HUD fps do Mesa/Gallium em escala reduzida; esse fallback continua experimental em Wine. off não exporta nenhum overlay. O jogo não depende do contador para iniciar.
A partir desta atualização, input_mode=auto procura o banco SDL instalado em /opt/winlator-rk3326/share/gamecontrollerdb.txt ou, em uma instalação dArkOS existente, a cópia compatível do PPSSPP em /opt/ppsspp/assets/gamecontrollerdb.txt. O pacote inclui também share/darkos-r36.gptk. Quando gptokeyb está disponível em /opt/inttools/gptokeyb ou no runtime do Winlator, o runner inicia essa ponte com o nome do executável e o mapa .gptk; assim o controle interno GO-Super Gamepad é normalizado pelo mesmo GUID SDL usado pelo dArkOS e pelo PPSSPP. input_mode=sdl força esse caminho, enquanto input_mode=keyboard desativa o joystick e serve apenas para jogos que precisam de teclado.
O mapeamento público do dArkOS para o GO-Super Gamepad usa A=b1, B=b0, X=b2, Y=b3, D-pad nos botões b8–b11, L1/R1 nos botões b4/b5, L2/R2 nos botões b6/b7, Select/Start nos botões b12/b13, analógico esquerdo nos eixos a0/a1 e analógico direito nos eixos a2/a3. O .gptk converte esses controles em ações de teclado compatíveis com jogos Windows: D-pad e analógico esquerdo viram setas, A vira espaço, B backspace, X N, Y/L1 V, R1 espaço, L2 backspace e R2 N.
Se o log mostrar input_bridge=gptokeyb, a ponte foi iniciada. Se mostrar input_bridge=unavailable, o sistema não forneceu gptokeyb; nesse caso input_mode=auto não deve ser considerado controle físico validado. A VM de desenvolvimento não possui /dev/input nem o controle interno do R36S, portanto a fixture valida a seleção do GUID, exportação SDL, arquivo .gptk e ciclo de vida da ponte, mas a confirmação final de D-pad, analógico, L1/L2 e R1/R2 precisa ser feita no console físico.
Cada arquivo em shortcuts/ pode substituir as preferências do container para um jogo específico, incluindo memória, Box64, Wine, gráfico, áudio, driver SDL, controle, perfil de desempenho, autostart e FPS. Quando o runner encontra um atalho cujo executable corresponde ao caminho selecionado pelo EmulationStation, ele aplica apenas aquele atalho e mantém os demais jogos do container inalterados.
Quando um jogo é aberto diretamente pelo EmulationStation, winlator.sh procura primeiro um container cujo container.conf tenha executable igual ao caminho selecionado. Se nenhum container corresponder, ele usa default. A aplicação do perfil de desempenho ocorre uma única vez no runner, evitando governor duplicado entre a integração do EmulationStation e a biblioteca interna.
O campo sdl_video_driver é opcional e aceita auto, kmsdrm, fbcon, x11, wayland ou dummy. Em auto, o ambiente do dArkOS escolhe o driver. O runner exporta tanto SDL_VIDEODRIVER, usado pelo SDL2, quanto SDL_VIDEO_DRIVER, usado por versões mais novas da família SDL. No R36S, comece com auto; se a imagem dArkOS confirmar DRM/KMS funcional, teste kmsdrm; use x11 apenas quando houver um servidor X ativo.
O campo audio aceita alsa, dummy ou none. alsa é o caminho esperado para áudio no console. Se alsa for solicitado mas /dev/snd não existir, o runner usa dummy automaticamente e grava audio_requested=alsa e audio_fallback=1 no log; defina WINLATOR_AUDIO_STRICT=1 para transformar essa situação em uma escolha estrita do ambiente. dummy é útil para diagnosticar jogos que travam ao inicializar áudio ou para testes headless, mas não produz som.
memory_limit_mb fica salvo por container e é exportado para logs e jogos, mas o limite rígido via ulimit -v permanece desativado por padrão para não quebrar Wine/WOW64. Para ativá-lo conscientemente em um teste, use WINLATOR_APPLY_RLIMIT=1; o log informa memory_limit_applied=1 quando o kernel aceitou a proteção.
Antes de escolher Vulkan/DXVK, execute a sonda no aparelho:
sudo /opt/winlator-rk3326/bin/winlator-rk3326-gfx-probe.shO arquivo gerado em /roms/winlator/logs/ deve ser guardado junto com o log do jogo. Ele registra /dev/dri, driver do kernel, variáveis SDL, EGL, OpenGL e Vulkan. Não use o resultado do laboratório como substituto: a VM de testes só encontrou llvmpipe, que é renderização por CPU e não representa o Mali-G31.
Instale ou copie uma build Linux x86_64/WOW64 compatível para o runtime e defina wine_binary no container.conf, ou disponibilize wine/wine64 no PATH. O runner procura primeiro o caminho absoluto configurado, depois /opt/winlator-rk3326/wine/bin/<nome> e, por fim, o PATH.
A opção de preparo install-wine-mono-prefix.sh é instalada junto com o port. Ela deve ser usada somente quando o pacote Wine Mono correspondente estiver disponível no cartão ou no sistema, por exemplo:
WINE_ROOT=/opt/winlator-rk3326/wine \
WINEPREFIX=/roms/winlator/containers/default/prefix \
WINE_MONO_MSI=/caminho/wine-mono-10.1.0-x86.msi \
/opt/winlator-rk3326/bin/install-wine-mono-prefix.shO script não baixa nem executa arquivos da internet sozinho. Ele usa apenas o MSI indicado pelo usuário. Em alguns builds de Wine, o primeiro boot pode demorar ou exigir um ambiente gráfico funcional; se ocorrer prompt ou travamento, use a sonda gráfica e teste o prefixo em uma configuração SDL/X11/KMSDRM válida.
A documentação do Box64 explica que Wine x86_64 pode rodar sobre Box64 e que Wine x86_64 WOW64 executa programas Windows 32-bit e 64-bit sem uma árvore Linux de 32 bits. Box32 continua experimental. Hangover é uma alternativa futura para Wine ARM64, mas não faz parte do primeiro pacote.
O runner aplica um perfil conservador por padrão para o RK3326. O Box64 usa BOX64_DYNAREC_BIGBLOCK=3, recomendado pela própria documentação para programas Wine, BOX64_DYNAREC_STRONGMEM=0, BOX64_DYNAREC_WEAKBARRIER=1, BOX64_MMAP32=1 para o caminho WOW64, no máximo quatro CPUs expostas e cache dinâmico comprimido limitado a 256 MiB por container. O cache fica em /roms/winlator/containers/<id>/home/.cache/box64, evitando mistura entre jogos e permitindo limpeza individual.
No caminho wined3d/OpenGL, BOX64_NOVULKAN=1, BOX64_NOVULKANOVERLAY=1 e BOX64_WRAP_EGL=1 evitam carregar Vulkan experimental e priorizam EGL/GLES nativo/wrapped. Nos modos vulkan e dxvk, Vulkan é reabilitado explicitamente, mas continua experimental no Mali-G31. Como o port oferece somente ALSA/dummy/none, BOX64_NOPULSE=1 evita tentativas de carregar PulseAudio inexistente.
Containers e shortcuts antigos continuam funcionando porque os campos avançados são opcionais. Para um jogo específico, podem ser acrescentados box64_maxcpu, box64_dynarec_bigblock, box64_dynarec_strongmem, box64_dynarec_weakbarrier, box64_mmap32, box64_dynacache_limit_mb, box64_dynacache_compress, performance_profile, autostart e fps_overlay ao arquivo .shortcut. Os valores são validados pelo runner; o limite rígido de memória via WINLATOR_APPLY_RLIMIT=1 permanece separado e opt-in.
O rollback remove somente os binários em /opt/winlator-rk3326 e restaura o XML salvo no backup indicado. Os containers, jogos, logs e saves em /roms/winlator/ permanecem intactos:
sudo /opt/winlator-rk3326/rollback.sh YYYYMMDD-HHMMSSSubstitua o valor pelo diretório exibido pelo instalador ou registrado em /roms/winlator/last-backup.
Crédito do projeto e da adaptação: Instagram melo._.071.
A base de referência é o Winlator oficial v11.1. O emulador user-space é o Box64. A documentação de uso do Box64 com Wine está em docs/WINE.md. A alternativa de Wine ARM64 estudada foi o Hangover. A entrada de dArkOS foi modelada a partir do dArkOSRE-R36, incluindo o banco SDL do PPSSPP e o GO-Super Gamepad. A ponte de controle usa o gptokeyb do PortMaster, conforme o padrão de porting do PortMaster. A decisão gráfica usa a documentação oficial do Mesa/Panfrost, a referência de SDL KMSDRM e o DXVK.