Si vede che è arrivato il mese di agosto. Mark Russinovich, CTO di Microsoft Azure, creatore della suite Sysinternals e tra i massimi esperti del funzionamento interno di Windows, ha trovato il tempo per trasformare Paint in una sorta di display virtuale sul quale giocare a Doom. Non si tratta però dell’ennesimo port dello storico, indimenticabile e indimenticato titolo id Software: il motore gira all’esterno dell’applicazione, mentre ogni fotogramma passa attraverso la clipboard di Windows e finisce sul canvas come una normale operazione di incolla. Il risultato raggiunge fino a 35 fps, la stessa frequenza con cui il Doom originale aggiorna la logica di gioco.
Doom risale al 1993 e occupa una posizione particolare nella cultura informatica. Il codice sorgente del motore, pubblicato da id Software nel 1997, ha favorito porting su console, calcolatrici, fotocamere, lettori multimediali e dispositivi che difficilmente assoceremmo a un videogioco. Il DoomPaint di Russinovich (repository GitHub) segue la stessa tradizione, ma con una differenza importante: non porta il motore dentro Paint. Usa invece l’applicazione Microsoft come una sorta di monitor estremamente inefficiente, alimentato attraverso la clipboard di Windows.
Doom non gira dentro Paint: Paint mostra soltanto i fotogrammi
DoomPaint prende davvero le mosse dalla versione shareware del gioco, DOOM1.WAD, distribuita liberamente secondo i termini originali di id Software.
Il rendering e la simulazione spettano a ViZDoom, derivato da ZDoom e nato come piattaforma per addestrare agenti AI attraverso le immagini prodotte dal gioco. Paint riceve soltanto il risultato finale. Il motore, la logica, gli avversari, la fisica, la gestione delle mappe e la produzione delle immagini rimangono all’esterno: Paint non diventa quindi un ambiente di esecuzione per Doom, né interpreta il file WAD. Funziona come destinazione grafica di una serie di bitmap.
Sarebbe però comunque riduttivo descrivere DoomPaint come un semplice ciclo basato su CTRL+C e CTRL+V: mantenere stabile una sequenza di “incollaggi” al ritmo di decine di aggiornamenti al secondo richiede di gestire sincronizzazione, proprietà degli appunti, ritardi variabili dell’interfaccia, input da tastiera e selezioni mobili di Paint.
Gli appunti di Windows non rappresentano un canale video: sono nati per trasferimenti occasionali tra applicazioni. DoomPaint li forza a lavorare come un collegamento grafico sincronizzato, facendo attenzione a non sovrascrivere i dati mentre Paint li sta ancora leggendo.

Perché la prima soluzione basata sulla clipboard non funzionava
Un’implementazione ingenua potrebbe svuotare gli appunti, inserire una nuova bitmap, inviare CTRL+V a Paint e ricominciare. Nei test del progetto, però, tale metodo provocava errori intermittenti. Paint elabora l’operazione di incollaggio in modo asincrono: quando riceve il comando, può continuare a leggere l’immagine dalla clipboard per un intervallo non prevedibile.
Se il programma chiama EmptyClipboard e sostituisce i dati prima che Paint abbia concluso la lettura, l’applicazione perde il contenuto in uso e mostra l’errore “Impossibile completare l’operazione“. Un semplice ritardo fisso non risolve il problema, perché il tempo necessario cambia in base alla risoluzione, al carico del sistema e alla versione di Paint.
DoomPaint adotta quindi la clipboard OLE: il programma registra una sola volta un oggetto che implementa l’interfaccia IDataObject; invece di pubblicare continuamente nuovi handle, aggiorna i byte dell’immagine restituiti dall’oggetto quando Paint invoca GetData. Il conteggio dei riferimenti mantiene validi i dati durante una lettura già iniziata, anche se nel frattempo il motore prepara il fotogramma successivo.
La chiamata GetData svolge inoltre una seconda funzione: conferma che Paint ha “preso in carico” il frame. DoomPaint aspetta tale segnale prima di procedere, evitando di sommergere l’applicazione con richieste di incollaggio.
I 35 fps non sono un limite casuale
La cifra di 35 fps può sembrare modesta per un gioco moderno, ma corrisponde alla frequenza temporale storica di Doom: raggiungere 35 aggiornamenti al secondo significa quindi arrivare proprio alla velocità completa prevista dal motore classico.
La modalità video DOS usava un segnale a 70 Hz e una risoluzione di 320 x 200 pixel, ma il gioco non aggiornava la propria logica 70 volte al secondo. I moderni source port possono disaccoppiare rendering e simulazione, interpolando le immagini per offrire animazioni a 60, 120 fps o più.
Paint tratta ogni immagine incollata come una selezione mobile. Quando arriva il fotogramma successivo, l’incollaggio precedente viene consolidato implicitamente e compare nella cronologia delle modifiche. Ne deriva uno degli effetti più curiosi del progetto: premendo CTRL+Z si può tornare ai fotogrammi precedenti.
La tastiera deve controllare Doom senza modificare l’immagine
Un problema meno evidente riguarda l’input. La finestra attiva rimane Paint, quindi i tasti freccia, CTRL, Barra spaziatrice e le lettere destinate a Doom rischiano di spostare la selezione, aprire menu o attivare comandi dell’applicazione.
Il folle progetto sviluppato da Russinovich installa perciò un hook di tastiera a basso livello tramite WH_KEYBOARD_LL. Quando Paint è in primo piano, DoomPaint intercetta i tasti di gioco e impedisce che raggiungano l’applicazione. W e S controllano l’avanzamento, A e D la rotazione, Q ed E lo spostamento laterale, mentre CTRL o F permettono di sparare. Spazio apre porte e attiva interruttori; MAIUSC abilita la corsa.
L’uso di F come comando alternativo non è casuale. PowerToys, software di accessibilità, ambienti remoti e macchine virtuali possono intercettare Ctrl prima che arrivi al gioco. DoomPaint tenta di acquisire il tasto con il proprio hook, ma conserva F come soluzione di riserva.
Come provare DoomPaint sul proprio PC
Per provare DoomPaint serve un PC Windows con Python installato e richiamabile dal prompt dei comandi.
Basta scaricare il repository da GitHub, tramite Code, Download ZIP oppure con il comando git clone https://github.com/markrussinovich/DoomPaint.git, estrarre i file e avviare run.bat.
Al primo avvio lo script crea automaticamente un ambiente virtuale, installa ViZDoom e le altre dipendenze Python, sostituisce la libreria OpenAL inclusa con la versione fornita dal progetto e apre Paint; durante la partita occorre lasciare la sua finestra in primo piano.
Per privilegiare la fluidità si può aprire un terminale nella cartella di DoomPaint ed eseguire run.bat --res 320x200: è la risoluzione nativa del gioco e può portare la frequenza fino ai 35 fps.
La modalità predefinita usa invece 640 x 400 pixel; run.bat --res 320x240 offre proporzioni 4:3 più fedeli alla resa dei vecchi monitor CRT. Il file shareware DOOM1.WAD è già incluso, quindi non occorre possedere una copia commerciale di Doom per iniziare.
DoomPaint non si limita alle immagini. ViZDoom riproduce gli effetti attraverso OpenAL: collegando una cuffia durante la partita, gli spari possono quindi seguire il nuovo dispositivo senza restare associati agli altoparlanti usati all’avvio.
Una demo giocosa, ma anche una lezione sulle API di Windows
Un’obiezione valida potrebbe essere la seguente: se ogni frame è già pronto, perché scegliere proprio Paint come destinazione? Tecnicamente potrebbe riceverlo qualunque applicazione capace di accettare immagini dagli appunti. La risposta sta nella natura della dimostrazione: Paint rende immediatamente visibile il comportamento della clipboard, conserva ogni incollaggio nella cronologia e permette di salvare il risultato come un normale immagine.
La firma di Russinovich rende l’esperimento ancora più interessante. Prima di assumere ruoli dirigenziali in Microsoft, l’ingegnere ha creato con Bryce Cogswell la suite Sysinternals e ha approfondito per decenni il funzionamento interno di Windows. DoomPaint appare quindi come un esercizio deliberatamente ironico sulle API Win32 e OLE, più che come il tentativo di dimostrare una reale capacità di Paint.
Il lavoro svolto dimostra quanto sia possibile piegare componenti molto vecchi di Windows a usi mai previsti. La clipboard diventa un canale video; la cronologia di annullamento si trasforma in una memoria dei fotogrammi; il canvas assume il ruolo di display.