Class Vaadoom
- All Implemented Interfaces:
com.vaadin.flow.component.AttachNotifier, com.vaadin.flow.component.DetachNotifier, com.vaadin.flow.component.HasElement, com.vaadin.flow.component.HasSize, com.vaadin.flow.component.HasStyle, Serializable
DOOM runs inside a NOMMU Linux which itself runs on Adrian Cable's single-instruction
SUBLEQ virtual machine, compiled to WebAssembly and driven from a Web Worker. The
worker paints the emulated framebuffer onto an OffscreenCanvas inside the
<vaadoom-viewport> custom element.
The IWAD
The game data comes from a WAD the browser fetches at start-up:add(new Vaadoom(Vaadoom.SHAREWARE_WAD));
SHAREWARE_WAD is id Software's freely redistributable shareware
doom1.wad (episode 1, "Knee-Deep in the Dead"). Any other IWAD works too:
the engine reads the lump directory and presents the file to DOOM under the name
that selects the matching game mode (doom2.wad, doomu.wad,
doom.wad, doom1.wad), so the full games play as they should.
Where those full IWADs come from is up to you. The commercial WADs are not
freely redistributable and this add-on deliberately ships no links to copies of
them — if you own DOOM, The Ultimate DOOM, DOOM II or Final DOOM, put the
.wad from your own copy on your own server and pass that URL. Serving it
from your own Vaadin application needs no CORS setup at all; a cross-origin URL
must send Access-Control-Allow-Origin, since the worker uses fetch().
The WAD is handed to the guest through a host-file device: the bytes stay in the host's memory and are copied straight into guest RAM on demand, so the (slow) emulated CPU never moves the file itself. If the fetch fails, DOOM falls back to the shareware WAD contained in the boot image.
Playing
The DOOM framebuffer is 800×512. By default the component is sized to those pixels; useHasSize.setWidth(String) /
HasSize.setHeight(String) (from HasSize) to scale the viewport.
The engine boots a NOMMU Linux and launches fbdoom; first paint takes ~15 seconds (a
loading overlay is shown meanwhile). It is playable: when the component has
focus it forwards keyboard input to DOOM (arrows move, Ctrl fires, Space uses, Alt
strafes, 1–7 select weapons). Disable input with setPlayable(boolean).
Sound effects are played through the Web Audio API (see setSound(boolean));
the browser only starts them once the user has interacted with the page.
Needs a browser with OffscreenCanvas, WebAssembly and
DecompressionStream; no cross-origin-isolation (COOP/COEP) headers are
required (input is delivered between VM slices, without SharedArrayBuffer).
- See Also:
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intNative height, in pixels, of the DOOM framebuffer.static final intNative width, in pixels, of the DOOM framebuffer.static final Stringid Software's sharewaredoom1.wad(v1.9, 4,196,020 bytes) on the Internet Archive, served with CORS headers. -
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionbooleanbooleanbooleanisSound()voidsetAutostart(boolean autostart) Whether the emulator starts automatically when the component is attached.voidsetPlayable(boolean playable) Whether keyboard input is enabled (the viewport becomes focusable and forwards key events to DOOM).voidsetSound(boolean sound) Whether DOOM's sound effects are played.voidSets the URL of the WAD to fetch and play.Methods inherited from class com.vaadin.flow.component.Component
addListener, bindVisible, findAncestor, fireEvent, from, get, getChildren, getElement, getEventBus, getId, getListeners, getLocale, getParent, getTestId, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getTranslation, getUI, hasListener, isAttached, isTemplateMapped, isVisible, onAttach, onDetach, onEnabledStateChanged, removeFromParent, scrollIntoView, scrollIntoView, set, setElement, setId, setTestId, setVisibleMethods inherited from class Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface com.vaadin.flow.component.AttachNotifier
addAttachListenerMethods inherited from interface com.vaadin.flow.component.DetachNotifier
addDetachListenerMethods inherited from interface com.vaadin.flow.component.HasSize
bindHeight, bindWidth, getHeight, getHeightUnit, getMaxHeight, getMaxWidth, getMinHeight, getMinWidth, getWidth, getWidthUnit, setHeight, setHeight, setHeightFull, setMaxHeight, setMaxHeight, setMaxWidth, setMaxWidth, setMinHeight, setMinHeight, setMinWidth, setMinWidth, setSizeFull, setSizeUndefined, setWidth, setWidth, setWidthFullMethods inherited from interface com.vaadin.flow.component.HasStyle
addClassName, addClassNames, bindClassName, bindClassNames, getClassName, getClassNames, getStyle, hasClassName, removeClassName, removeClassNames, setClassName, setClassName
-
Field Details
-
FB_WIDTH
public static final int FB_WIDTHNative width, in pixels, of the DOOM framebuffer.- See Also:
-
FB_HEIGHT
public static final int FB_HEIGHTNative height, in pixels, of the DOOM framebuffer.- See Also:
-
SHAREWARE_WAD
id Software's sharewaredoom1.wad(v1.9, 4,196,020 bytes) on the Internet Archive, served with CORS headers. This is the episode id Software released for free distribution, so it is the one this add-on points at.- See Also:
-
-
Constructor Details
-
Vaadoom
Creates a Vaadoom viewport that plays the WAD at the given URL, sized to the native DOOM framebuffer (800×512).- Parameters:
wadUrl- URL of the IWAD to play, e.g.SHAREWARE_WAD, or a WAD you host yourself;nullto use the shareware WAD bundled in the boot image. Cross-origin URLs must allow CORS.
-
Vaadoom
public Vaadoom()Creates a Vaadoom viewport that plays the shareware WAD bundled in the boot image (no download). Equivalent tonew Vaadoom(null).
-
-
Method Details
-
setWadUrl
Sets the URL of the WAD to fetch and play. Takes effect on the next attach.- Parameters:
wadUrl- URL of the IWAD, ornullfor the bundled shareware WAD
-
getWadUrl
- Returns:
- the WAD URL, or
nullif the bundled shareware WAD is used
-
setAutostart
public void setAutostart(boolean autostart) Whether the emulator starts automatically when the component is attached. Defaults totrue.- Parameters:
autostart-trueto start on attach
-
isAutostart
public boolean isAutostart()- Returns:
- whether the emulator starts automatically on attach
-
setPlayable
public void setPlayable(boolean playable) Whether keyboard input is enabled (the viewport becomes focusable and forwards key events to DOOM). Defaults totrue. Input works without any cross-origin-isolation headers.- Parameters:
playable-trueto enable keyboard control
-
isPlayable
public boolean isPlayable()- Returns:
- whether keyboard input is enabled
-
setSound
public void setSound(boolean sound) Whether DOOM's sound effects are played. Defaults totrue. The guest produces PCM frames which the VM's sound card hands to the page'sAudioContext; browsers keep that context suspended until the user interacts with the page, so the first sounds arrive after the first click.- Parameters:
sound-trueto play sound effects
-
isSound
public boolean isSound()- Returns:
- whether sound effects are played
-