npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

sdlterm

v1.8.0

Published

Another kind of SDL bindings

Downloads

6

Readme

This program is for use of SDL with Node.js even though I did not write it
as a Node.js addon because I found that too confusing. Therefore it is a C
code that you must compile and then call it externally (which this package
will do for you). Currently it is only working on Linux with X window
system (due to the way the SDL event system works, it can't mix them with
standard I/O, so instead it sends a X "client message" event when it need
to control the SDL).

It is similar to a terminal in a way which is why it can called SDLTERM. A
few functions such as joysticks are untested because I do not have the way
to test it.

The export is a function (normally called SDL). The arguments are:
- Width of screen
- Height of screen
- Depth of screen (8, 15, 16, 24, or 32)
- Title (if omitted, it is "SDLTERM")
- Mode (default "S_" for software rendering and no async blitting)

The first character of the mode is "S" for software or "H" for hardware,
and the second character can be "_" normally or "A" for async blitting.

If the SDL function is called as a constructor then it creates the object,
and the property called "ready" is a promise which will be resolved when
when it is ready. If not called as a constructor, it returns a function,
which takes as an argument a callback function, that will be called with
two arguments the first being the error (if any) and the second being the
SDL object that it created.

There is also OpenGL mode. If the depth of the screen is "G" then OpenGL
mode is activated. Functions marked ^ below are only for OpenGL, and those
marked ! are not supported in OpenGL mode (but in future some may be
supported even in OpenGL mode).

Various objects are created by these functions. None of them can be shared
between different screens! Surfaces, displays, shared memory views, sound
effects, etc must be used only on the screen they are created with.

Static (non-instance) properties of the SDL function itself are:

SDL.ALT
  Mask of alt keys.

SDL.CAPSLOCK
  Mask of caps lock keys.

SDL.CTRL
  Mask of control keys.

SDL.Icon *
  A symbol. However, you may set this to a string instead if you wish. It
  is used with the SDL.Surface.prototype.drawBobs() function.

SDL.Key
  An object with name of SDL keys, without "SDLK_" at front. The value of
  these properties are the number. The first argument to keyDown and keyUp
  methods will be one of these key codes.

SDL.META
  Mask of meta keys.

SDL.NUMLOCK
  Mask of num lock keys.

SDL.SHIFT
  Mask of shift keys.

The SDL instance object has properties (* = writable):

._mem
  The internally mapped memory share buffer. It is best you do not touch
  this directly.

._send(buf)
  Used to send a command to the SDL instance. Normally you should not call
  this function yourself because it is used internally instead. The
  internal format of the commands to send may also differ between
  different implementations anyways, or different versions too possibly,
  so there is not really the guarantee that this will help.

.clear([color])
  Clear the screen, using specified colour. If not specified, colour 0 is
  used by default.

.clip(x,y,w,h)
  Set the clip rectangle for blits having the screen as destination.

.commonTexture(unit,func,...) ^
  Create a texture, like .createTexture() or .createTexture2D(), but this
  new texture is read-only once created. The data is automatically filled
  in, given the function name (one of the properties of SDL.Common), and
  further arguments which are all 8-bit numbers, and their meaning depends
  on which function is chosen. See a section below about SDL.Common.

.createDisplay() ^
  Create a new display. Once the display, commands are put in then you can
  call .display() in order to display it.

.createDrawing()
  Create an empty drawing for this screen. Once the drawing commands are
  put in, then .draw() can be called in order to draw it.

.createGeometryList(offset,count,kind,vfunc,cfunc) ^
  Create a new geometry list, which can then be drawn in a display using
  the .geometry() function in the display. The first argument is the
  offset into the vertex array set by setAddress(). The second argument is
  the number of total number of records it can contain. The third argument
  gives the kind of shapes to draw, which can have the same values as the
  .shapes() function in a display can have. The fourth argument is an
  array of functions to produce vertex outputs, and the fifth argument is
  a single function to produce the colour output. These functions can take
  arbitrary inputs (as long as all of them take the same number of
  arguments), and the vertex functions must output an array of four
  numbers (the X, Y, Z, and W coordinates of the vertex), while the colour
  function must output an array of four numbers. You must call setAddress
  before calling this function.

.createSurface(width,height,depth,pitch,[data])
  Create a off-screen surface. You are limited to 32 off-screen surfaces.
  Set the width, height, depth, and pitch. The depth can be 8 for a
  paletted picture, or can be 15 or 16 or 24 or 32 for true colours. The
  pitch is the number of bytes per scanline; if omitted or zero it will
  automatically calculate. The data is any typed array, which must be of
  the correct size, to initialize the contents of the surface. If the
  data is omitted, it will create a blank one of the correct size. The
  return value is the off-screen surface instance object (see below).

.createTexture(unit,width,height,format,[data]) ^
  Create a texture, and returns an object that can be used in a display in
  order to select or upload to the texture. The unit is the texture unit
  number; the first unit is zero and the maximum range depends on the
  system, but is probably at least 7. The format is one of the constants
  from the SDL.GL object (described elsewhere in this document): RED, RG,
  RGB, BGR, RGBA, or BGRA. The data is optional and is a Uint8Array that
  contains the pixel data; if not provided, it is blank.

.createTexture2D(unit,size,format,mode,data) ^
  Similar to .createTexture() but the size must be a power of two and the
  texture is square. The texture becomes immutable. The size parameter is
  the base 2 logarithm of the width or height. The mode is 0 for clamp to
  edge or 1 for repeating. Other parameters have the   same meaning as
  above. This function uses the RECTANGLE target while the above function
  uses the 2D target.

.cursor(shape)
  Set the mouse cursor shape. Valid numbers are 0 to 76 and 255. These are
  the standard X11 cursor shapes (converted into SDL format so that it is
  compatible with other computers too), but the number here is half of
  what Xlib expects. If you specify 255 then the cursor is hidden. The
  object SDL.Cursor maps these cursor names (without XC_ at front) to the
  numbers to be given to this.

.depth
  The depth of the screen.

.display(display) ^
  Execute a display, and flip the screen afterward.

.draw(drawing,[flip])
  Draw the drawing on this screen. If flip is true then also update the
  picture on the screen so that the drawing is visible. If used with
  OpenGL, the drawing must start with a .dest() command to set the
  destination to a surface other than the screen; you can't draw on the
  screen with this function in OpenGL mode.

.exposed() *
  Normally does nothing. If you write to it, it may be called when the
  window is exposed and needs to be redrawn.

.filterRect(x1,y1,x2,y2)
  Disable mouseMove events and enables a filter rectangle. When the mouse
  moves out of the filter rectangle, a mouseOut event is generated and
  then the filter rectangle is cancelled.

.flip()
  Call to ensure the picture on the screen is updated. You should call it
  after doing drawing on the screen, to ensure it is visible.

.height
  The height of the drawable area of the screen in pixels.

.joyEvent(id,itemKind,itemNumber,value1,value2) *
  This event has a default function which converts joystick events into
  keyboard events (this implementation is subject to be changed). If you
  override it then it won't do that conversion. Called when a joystick
  event occurs, where id is the number of the joystick, itemKind is the
  kind of control on the joystick which has been touched, itemNumber
  specifies which control of that kind, and value1 and value2 are the
  value that it has been set to.
  - Button (type 0): Value1 is one if pushed or zero if not pushed. Value2
  is not used.
  - Axis (type 1): Value1 is the value of the axis as a signed 16-bit
  number. Normally, itemNumber 0 is the X axis and 1 is the Y axis. Value2
  is not used.
  - Ball (type 2): Value1 is the relative X motion of the ball and value2
  is the relative Y motion of the ball, both signed 16-bits.
  - Hat (type 3): Value1 is a bit field, where bit0 means up, bit1 means
  right, bit2 means down, and bit3 means left; more than one bit may be
  set in case of diagonals. Value2 is not used.

.joyReady(id,axes,buttons,hats,balls) *
  Normally does nothing. If you select a joystick with joySelect then this
  function will be called afterward if it successfully selected it. It
  reports the ID number, as well as how many axes, buttons, hats, balls.

.joySelect(id)
  Attempt to initialize joysticks and to enable events for the specified
  joystick ID. Which ID numbers are available is system-dependent, and how
  the controls are mapped to numbers is also system-dependent. It is
  recommended that your program allows the user to change which button has
  which function in your program. For menus, you should support the X and
  Y axis as well as the hat (if any) since different devices may map them
  differently. I do not know if Wii remotes will work or what will happen
  if one is connected, but it probably depends on the operating system
  (Windows will treat it differently from Linux).

.keyDown(keyCode,modifier,character) *
  Normally does nothing. Called when a key is pushed, with the keycode (a
  number), the modifier codes (a number; use & with the masks to test if
  the modifier is pushed), and the character if applicable. The character
  is a string containing a single ASCII character, or an empty string if
  the key has no ASCII character code.

.keyUp(keyCode,modifier) *
  Similar to keyDown but when the key is released, and no character is
  reported.

.loadFragmentProgram(text) ^
  Load a fragment program. A preprocessor is applied to allow writing
  fractions with a slash and to allow hex numbers with 0x at first. It
  returns the ID number of the program, for use in a display. The fragment
  program is used to determine the colour and depth of each pixel that is
  part of a triangle or rectangle being drawn on the screen, based on
  inputs that come from the vertex program or from the geometry.

.loadSound(id,data,[loop])
  Load a wave sound effect. (If a wave sound effect is currently playing,
  it will stop.) The data is a Int16Array, and is played back at 44100 Hz
  when you use the sound() function to tell it to play back. The id is a
  number in the range 0 to 32767. The loop number tells the index into the
  data to loop from; it is used only for music and not for sound effect.

.loadVertexProgram(text) ^
  Load a vertex program. A preprocessor is applied to allow writing
  fractions with a slash and to allow hex numbers with 0x at first. It
  returns the ID number of the program in order to use in a display. The
  vertex program is used to transform coordinates of shapes being drawn
  into normalized device coordinates.

.mouseDown(button,x,y) *
  Called when mouse button is pushed. The button number is 1 for left
  button, 2 for middle button, and 3 for right button.

.mouseMove(state,x,y) *
  Normally does nothing. If mouse movement events are enabled, it is
  called when the mouse is moved.

.mouseOff()
  Disable mouse movement events (also cancel filter rectangle).

.mouseOn()
  Enable mouse movement events (also cancel filter rectangle).

.mouseOut() *
  Normally do nothing. Called once when the mouse pointer leaves the
  filter rectangle.

.mouseUp(button,x,y) *
  Called when mouse button is released.

.music(samples,program,pc,[nonshift])
  Load and play music, where samples is an array with a list of sound
  numbers to map to samples for the music (you are allowed to repeat
  sounds in this list), program is a Buffer or Uint8Array containing the
  program to load, and pc is the initial value of the program counter. It
  will normally shift the length of the sounds, although if nonshift is
  specified and is true then it will not do this.

.musicControl(address,value)
  Set a register for the music playback. The address ranges from 0 to 255
  and the value ranges from 0 to 65535.

.musicVolume(value)
  Set music volume. Range is from 0 to 32767. The useful range depends on
  the music being played back and on the sound effects and MML volume; if
  set too high it may clip.

.onQuit([error]) *
  Normally displays an error message if an erro occurred and otherwise
  does nothing. You can override it and it will be called when the
  program is quit, possibly including the error object (if any).

.palette(list,[start]) !
  Set up the palette (only suitable if depth is 8). The start is the first
  palette index to write to (default 0), and the palette entries are
  numbers like "0xRRGGBB" where the R, G, B represent the red, green, blue
  components and each range from 0x00 to 0xFF.

.pause()
  Pause audio playback.

.play()
  Start or resume audio playback.

.playCD([track])
  Play a audio CD. If the track number is out of range or is omitted, then
  it will stop the playback instead.

.playMML(str,interrupt)
  Play a MML string. It is not a standard MML but uses the same format
  used in MegaZeux instead. If interrupt is false then it will not play if
  a sound effect is already playing; if true then it interrupts the sound
  effect that is already playing.

.quit()
  Cause SDL to quit.

.repeat(on)
  Set key repeating. Can be true or false.

.rgb(red,green,blue)
  Return the pixel value needed for the specified colour, where the red,
  green, blue components range from 0 to 255. This function does nothing
  if the depth is set to 8. For OpenGL, the format is the same as that
  specified for the palette.

.screenInfo !
  A Node.js buffer containing info for the screen format. Use this to
  help to create off-screen true colour surfaces.
  [0] Bytes per scanline (16-bits small-endian)
  [2] Bits per pixel
  [3] Bytes per pixel
  [4] Red channel shift amount
  [5] Green channel shift amount
  [6] Blue channel shift amount
  [12] Red channel mask
  [13] Green channel mask
  [14] Blue channel mask

.scroll(amount,[color]) !
  Scroll the area of the screen by the clip rectangle (the entire screen
  if no clip rectangle is set). The amount can be positive or negative,
  and is the number of pixels to scroll vertically. You can optionally
  specify the new background colour of the scrolled in part.

.setAddress(vertex_size,vertex_addr,color_size,color_addr) ^
  Set the vertex pointer and colour pointer for drawing shapes with
  OpenGL. These can be either numbers or Float32Array instances that have
  been returned from .viewShare() on this screen. The first and third
  arguments are the number of components, which can be 2 or 3 or 4 for the
  vertex list, and can be 3 or 4 for the colour list. If used with a
  geometry list then the vertex_size and color_size have to both be 4.

.setCaption(text)
  Set the window title. (Note that the title is not necessarily visible.
  It depends on the window manager in use (if any).)

.setMapping([id])
  Set the input mapping mode (can be used to distinguish text input, game
  input, touch-screen, etc; the valid ID numbers depend on your program).
  This function currently does nothing, and you need not worry about it.
  Other libraries implementing the same API may use it.

.share(length)
  Create a shared memory between the client and server. Can be used to
  upload OpenGL textures and vertex arrays. Should be called no more than
  once, and must be called before .viewShare() is usable. (The "mmap.js"
  dependency must be present for this function to work. It is now an
  optional dependency, so it is not necessarily present.)

.shot(command)
  Take a screen shot and write it as input to the specified shell command
  in farbfeld format. You should then redirect output to a file, because
  if it writes anything to stdout that is not redirected then it will
  cause various problems. (Writing to stderr is OK.) (Note for OpenGL:
  The picture is upsidedown when OpenGL is in use. Use another program
  such as "ff-turn 1" to turn it back right-side up.)

.sound(id,interrupt)
  Play a wave sound. You can tell it to interrupt or not like with MML
  sounds. Wave sounds and MML sounds can't play simultaneously, although
  either of them can be played together with background music. There is no
  volume control (load a quieter sound if you want it quieter).

.sync(function)
  Calls the specified function asynchronously, with no arguments. It will
  not be called until all previous requests are complete. It also will not
  be called if SDLTERM fails before then. This function is used when
  synchronization with external events is needed.

.text(x,y,color,text) !
  Draw text at position. Uses PC character set. This is a convenience to
  use rather than the general drawing functions.

.unclip()
  Unset the clip rectangle.

.unloadMusic()
  Stop and unload background music.

.unloadSound()
  All loaded wave sounds are unloaded from memory.

.viewShare(constructor,offset,length)
  Returns a typed array that views part of the shared memory space. The
  first argument is any typed array constructor or DataView; the others
  are the offset into the shared memory and the length of the view.

.volume(value)
  Set the MML volume. Range is from 0 to 32767. Does not control volume of
  wave souds (to do that, you must reduce the amplitude of the data before
  loading the sound) or music (use .musicVolume() to set that).

.warp(x,y)
  Set the position of the mouse cursor, generating a mouse motion event.
  It is recommended that this should be done only in response to keyboard
  input, and only if keyboard commands can care about mouse position.

.width
  The width of the drawable area of the screen in pixels.

A off-screen surface object instance has properties:

.clip(x,y,w,h)
  Set the clip rectangle for blits having this surface as destination.

.colorKey([color])
  If the color is null or omitted, blitting is opaque. Otherwise, pixels
  with the specified value are transparent for blitting.

.depth
  The depth of this surface.

.drawBobs(list) !
  Draw several bobs on the screen, using this surface as source. The size
  of the bobs is set by the surface's clip rectangle; it also sets the
  position of the top-left corner of icon 0 in the surface. The list is a
  list of objects, each having properties "x", "y", and SDL.Icon (normally
  a symbol, but you may change this). The icons in the surface are then
  starting there and going right, reaching the next row when there is no
  more left on this row.

.free()
  Free the off-screen buffer. Now it is no longer usable. Do not call any
  further functions on the surface after that or pass the surface to any
  other function after that.

.height
  The height of this surface.

.origin(x,y)
  Set the origin of bobs drawn from this surface. The default is 0, which
  means the top left corner of each bob.

.palette(list,[start])
  Same as the palette method for the screen object (see above), but set
  the palette for the surface. If the screen and surface both have depth 8
  then the palette must be set to the same as the palette of the screen,
  but if the screen's palette is already set before the surface is created
  then it will automatically be set.

.pitch
  The pitch (bytes per scanline) of this surface.

.render()
  Render this picture onto the screen, using the clip rectangle of the
  screen to determine the position to write to, and the clip rectangle of
  this surface to determine the part to write. If OpenGL mode is used, the
  depth has to be 8 and the alpha and colour key are ignored.

.screen
  The screen that this surface belongs to. You cannot share surfaces
  between multiple screens.

.setMode(rle,[alpha])
  Set the mode, where rle is boolean and if true it enables RLE
  accelerated blitting. If the alpha value is null or omitted then there
  is no alpha transparency for blitting from this surface, otherwise it
  will use alpha transparency, where 0 is transparent and 255 is opaque.
  The recommended alpha value is 128 because it is optimized.

.unclip()
  Unset the clip rectangle.

.width
  The width of this surface.

.write(data,[x,y,w,h])
  Replace part or all of the picture with the data in the specified buffer
  (can be a Node.js buffer or a typed array). You can specify the area of
  the rectangle to write into, or else it replaces the entire picture.

A drawing object has methods to add shapes to the drawing (which will not
be immediately visible on screen). After the function name lists L or U,
where L means it can only be used if the screen is locked and U means it
can only be used if the screen is unlocked; also the screen has to end up
unlocked at the end of the drawing. Some functions return other functions
(indicated by F); calling those functions will update the parameter of the
command with the new value in this drawing. Also, the values of various
registers are retained, with the exception of the source and destination
surfaces, so drawing another drawing afterward will use the values that
those registers ended up with if not overridden in the new drawing (but
some operations will clobber the "at" and/or "from" registers). Some
commands care about clipping rectangle; these are marked by C.

.advanceH()
  Move the current position right by the current width. After a text
  operation the current width will be equal to the width of the text.

.advanceV()
  Move the current position down by the current height.

.at([x],[y],[w],[h]) F
  Set the position to draw at, as well as the width and height for the
  commands that use them. Omitted values are treated as zero. All values
  must be nonnegative.

.back(color) F
  Set the background colour (used for text, reset, and rectPat). The depth
  of the current destination is considered when coding this command.

.blit() U C
  Copy the from rectangle area from the source surface onto the
  destination surface. The transparency settings of the source surface
  are used.

.blitPat() L
  Copy the from rectangle area from the source surface onto the
  destination surface. Both surfaces need to have depth 8 for this
  function to work properly. The current mode, pattern, and plane mask are
  used to copy it but the transparency settings of the source aren't used.
  Only where the pattern and plane mask have bits set are copied.

.circle(radius) L F
  Draw a circle with the specified radius.

.clone()
  Makes a copy of the current drawing and returns the copy. Changes and
  additions to the original will not affect the copy, and vice versa.

.color(color) F
  Set the foreground colour. The depth of the current destination is
  considered when coding this command, so you can only set a 8-bit colour
  if the destination's depth is 8; this applies to the returned function
  as well.

.dest([surface]) U
  Set the destination surface (normally the screen). Omitting the
  parameter or specifying null sets the destination to the screen. This is
  used for all drawing.

.from([x],[y],[w],[h]) F
  Set the source rectangle for blitting.

.keyName(keyCode) F
  Draw text (like the .text method) but the text drawn is the SDL name of
  the key with the specified keycode. Name is written in lowercase.

.lineRel(x,y) L F
  Draw a line to the specified relative position from the cursor and moves
  the cursor to the new position.

.lineTo(x,y) L F
  Draw a line to the specified absolute position from the cursor and moves
  the cursor to the new position.

.lineToN(x,y) L F
  Draw a line to the specified absolute position from the cursor, but does
  not move the cursor.

.lock() U
  Lock the surface. Needed for some operations.

.mode(mode) F
  Set the drawing mode for blitPat and rectPat. Mode 0 is normal drawing.
  Mode 1 is XOR mode. Mode 2 is OR mode. Mode 3 is AND NOT mode.

.opaque()
  Enable background opacity (currently used only for text and rectPat).

.pattern(value) F
  Set the current pattern for blitPat and rectPat. It is a 8x4 pattern
  where the low bit is in the top-left corner and then follow to right.

.planeMask(mask) F
  Set the plane mask, which is a 8-bit number. The blitPat and rectPat
  functions will overwrite only the bits of the destination pixel which
  are also set in this plane mask. Set to 255 if you want to overwrite
  all bits of the destination pixel.

.rect() C
  Draw a filled rectangle with the current top, left, width, and height.

.rectPat() L
  Draw a filled rectangle with the current top, left, width, and height.
  Requires the depth of the surface to be 8 for it to work properly. This
  function uses the current mode, pattern, and plane mask; it also uses
  the opacity setting. For opaque drawing, unset bits in the pattern are
  drawn using the background colour. For transparent drawing, unset bits
  in the pattern are not drawn at all.

.reset(x,y) L F
  Draw a pixel with the background colour. Does not move cursor.

.set(x,y) L F
  Draw a pixel with the foreground colour. Does not move cursor.

.setAt(x,y,[w],[h]) L F
  Combines set() with at().

.source([surface])
  Set the source surface for blitting from (normally the screen). Omitting
  or specifying null means use the screen as the source.

.text(str) L F
  Draw the text (which uses the PC character set; only the low 8-bits of
  each character are used). The current width is set to the width of the
  text, although the cursor does not move (use advanceH to move). Also, if
  the returned function is called, any text will be truncated to the
  length of the string initially specified if the new string is longer.

.transparent()
  Disable background opacity; background colour is not drawn and instead
  those pixels retain the old value.

.unlock() L
  Unlock the surface. Needed for some operations, and make sure that the
  surface is unlocked when the drawing is finished, otherwise you may get
  an incorrect result.

A display object contains a list of commands like a drawing object does,
but is specific to OpenGL (the ^ is not specified since it is implied for
all commands). There are beginBlock and endBlock; the commands that are
not allowed inside of such a block are marked by X.

.beginBlock() X
  Begin a block. The block executes commands normally, but may save memory
  and/or improve speed if the same block is executed many times. The block
  is internally implemented using glNewList(). You shouldn't begin a block
  while any display on this screen has an unfinished block.

.blend(src,dst,eq)
  Set the source and destination blend mode. Each can be 0 or 1, or can be
  one of the SDL.GL constants: SRC, MINUS_SRC, ALPHA, MINUS_ALPHA, DST, or
  MINUS_DST. The third argument is one of the SDL.GL constants: MIN, MAX,
  ADD, SUBTRACT, or RSUBTRACT. Specify (ALPHA,MINUS_ALPHA,ADD) to
  implement alpha transparency. (Note that it will not draw at all if the
  depth test is failing, so if you want to blend then you may want to set
  the depth mode also, but the blending can also be used in order to cause
  the fragment program to draw into the depth buffer only.)

.clear()
  Clear the screen (including depth buffer). The colour to use is
  determined by the last .clear() function of the screen; it is not saved
  in the display.

.depthMode(mode)
  Set the depth test mode. It is a bit field, where bit0 means to succeed
  if the new value is less, bit1 means to succeed if the new value is
  equal, and bit2 means to succeed if the new value is greater. The
  fragment program outputs a depth, and if this comparison succeeds then
  the pixel is drawn and the depth value at that point is updated;
  otherwise the pixel is not drawn and the depth value is not updated.

.endBlock()
  Ends a block; must be inside of a block to end it, and then it is no
  longer inside of a block. You cannot execute a display that contains an
  unfinished block; it may cause incorrect results if you do it anyways.

.fragmentEnv(index,address) X
  Set an environment parameter for fragment programs. The address is a
  number or a Float64Array returned by the .viewShare() of the screen;
  it should contain four elements which form the vector value. The index
  is a number 0 to 7.

.fragmentProgram([id])
  Set the active fragment program. If id is null or omitted, disables the
  fragment program. The id can also be a string, in which case it loads a
  new fragment program (you should not do this if you intend to use the
  same fragment program several times in the same display or use it in
  multiple displays).

.geometry(obj) X
  Execute a geometry list.

.program(id)
  Execute a fragment program (from ID number or string) across the entire
  screen (taking into account the scissor box if it is enabled); the
  vertex program and geometry list are disabled. This is a convenience
  rather than using fragmentProgram and rect together.

.rect(x1,y1,x2,y2)
  Draw a rectangle. Uses standard SDLTERM coordinates unless a vertex
  program is active, in which case the vertex program interprets the
  coordinates instead. The fragment program then determines the contents
  of the rectangle.

.repeatBlock(id)
  Repeat a block. The id is the return value from a .beginBlock(). The
  block to repeat has to belong to the same screen as this display, but it
  does not necessarily have to belong to the same display.

.scissor(x,y,w,h)
  Set the scissor rectangle. Coordinates are relative to top-left like in
  most other functions of SDLTERM, rather than bottom-left like OpenGL.

.setTexture(texture)
  Select a texture. If there are multiple textures using the same texture
  unit number, then this command specifies which texture is active in that
  texture unit.

.shapes(kind,start,count) X
  Draw shapes of the specified kind, read from the shared memory that has
  been configured by the screen's .setAddress() call. You can specify an
  offset into the vertex list to start at. The kind is one of the SDL.GL
  constants: POINTS, LINES, LINE_LOOP, LINE_STRIP, TRIANGLES,
  TRIANGLE_STRIP, or TRIANGLE_FAN. (If you want to draw other shapes (such
  as rectangles), make them by the combinations of triangles.)

.unblend()
  Cancel the blending mode.

.unscissor()
  Turn off the scissor rectangle.

.update(texture,addr) X
  Update a texture (created with .createTexture(), not .createTexture2D())
  from the shared memory at the specified address. If there are multiple
  textures sharing the texture unit number with that one, then the texture
  must be set first by .setTexture().

.vertexEnv(index,address) X
  Similar to .fragmentEnv() but for vertex programs.

.vertexProgram([id])
  Set the active vertex program. If id is null or omitted, disables the
  vertex program. Can also be a string, like with fragmentProgram().

A geometry list object (for use with OpenGL only) has the following
properties (where * indicates read/write):

.add(...)
  Add a record to the geometry list. The arguments needed are defined by
  the user when createGeometryList is called.

.begin()
  Set length to zero and prepare to add records.

.end()
  End the list of records. Must be called after adding records or after
  setting the length, before it can be displayed properly.

.length *
  The number of entries it currently includes.

.maxLength
  The maximum length allowed.

.set(index,...)
  Set one entry of the geometry list by index. Does not touch the length,
  which you must touch yourself if you want to change it.

For use with OpenGL, there is a SDL.GL object with the following
constants defined: RED, RG, RGB, BGR, RGBA, BGRA, SRC, MINUS_SRC, ALPHA,
MINUS_ALPHA, DST, MINUS_DST, POINTS, LINES, LINE_LOOP, LINE_STRIP,
TRIANGLES, TRIANGLE_STRIP, TRIANGLE_FAN, MIN, MAX, ADD, SUBTRACT,
RSUBTRACT.

For use with .commonTexture(), there is a SDL.Common object with the
constants defined listed below. The arguments it uses are also listed.
Next to to the name is also whether the target is RECT or 2D.

.PC (dir,fg_r,fg_g,fg_b,fg_a,bg_r,bg_g,bg_g,bg_a) RECT
  The texture contains the graphics of the 8x8 PC character set, in a
  vertical strip. The first argument is the direction which is 0 if the
  first scanline of each character is the top or 1 if it is the bottom;
  it always includes character 0 at the beginning of the data though.
  The next four arguments are the foreground colour, and the next four
  after that are the background colour. (The colour components are divided
  by 255 when being read by the fragment program.)

Environment variables (must be set before SDL() is called; in most cases
these should be set only by the user though rather than by the program):

AUDIODEV = Set the audio device to use.

SDLTERM_BUFFER = If set, overrides the buffer size for audio. The default
setting is 2048. On some computers the default setting may be unsuitable.
Larger numbers may cause the audio to lag more, while smaller numbers may
result in underflow.

SDLTERM_CD = Allow to select which drive to use to play CDs. The default
value is zero, which is the default CD-ROM drive for the operating system.

SDLTERM_DITHER = If set, enables dithering in OpenGL.

SDLTERM_EVENTEXEC = Replaces the X event sending program with a different
one. See the "events.c" source code to see what it is supposed to do.

SDLTERM_EVENTSLEEP = Number of microseconds to sleep between requests; the
default is 1 microsecond. Somehow this is needed to prevent protocol
sequence errors.

SDLTERM_EXEC = Allows using valgrind or something else to debug the
program. You can specify arguments separated by spaces.

SDLTERM_FULLSCREEN = Enable full screen mode. Please the program should
never specify this option unless the user specifies full screen mode.

SDLTERM_GAMMA = If the depth of the screen is 8, all colours in the
palette are raised to this exponent. If the depth of the screen is not 8,
then this environment variable does nothing.

SDLTERM_GLTIME = Show time for executing a OpenGL display. Updates the
window caption whenever a OpenGL display is executed.

SDLTERM_KRD * = Set key repeat delay. If not set, uses default setting of
SDL. Key repeat is still disabled unless the program enables it.

SDLTERM_KRI * = Set key repeat interval. If not set, uses default setting
of SDL instead.

SDLTERM_MODE = Overrides the mode for initializing SDL. The format is the
same as passed for the mode parameter of the SDL() function.

SDLTERM_NODBLBUF = If set, disables OpenGL double buffering. Only suitable
if OpenGL is in use.

SDLTERM_NOMOUSE = If set, disable mouse input events, as well as mouse
warping. (Does not currently disable changing cursor shapes, although this
may change in future. If mouse grabbing is ever implemented in future, it
will disable mouse grabbing too.)

SDLTERM_NOSOUND * = If set, disable sound output.

SDLTERM_NOSTICK = If set, disable joysticks.

SDLTERM_NOWARP = If set, disable mouse warping. The program should never
clear this setting; if the user does not want mouse warping, then it
should remain disabled.

SDLTERM_SHARE = If shared memory functions are implemented, this should be
a prefix for a filename for shared memory. Should be a RAM disk.

SDLTERM_TITLE = If set, uses this window caption instead of allowing it to
be changed.

SDL_AUDIODRIVER = Specify the audio driver to use. If set to "disk" then
the audio output is written to a file.

SDL_DEBUG = Enable SDL debugging messages.

SDL_DISKAUDIOFILE = When "disk" audio driver is selected, specifies the
filename for the audio output.

SDL_DSP_NOSELECT = Causes some audio drivers to avoid use of select(). In
some cases this might fix some problems, but it may also cause additional
problems in some cases.

SDL_JOYSTICK_DEVICE = You can tell it the device name for the joystick, to
use in addition to the defaults.

SDL_LINUX_JOYSTICK = On Linux system, enter a name (possibly with single
quotes), number of axes, number of hats, and number of balls; use spaces
in between. This overrides the auto-detection of these characteristics.

SDL_NOMOUSE * = Supposed to disable mouse, but does not usually work. You
can set SDLTERM_NOMOUSE instead.

SDL_NO_LOCK_KEYS * = Disable SDL's special function of caps lock and num
lock keys. If 1, affects both. If 2, affects caps lock only. If 3, affects
num lock only.

SDL_VIDEODRIVER = Currently, this program only supports the "x11" video
driver (it requires the use of X11 WM events). You can contribute support
for others if you wanted to.

SDL_VIDEO_CENTERED = For some systems, make the window in the center of
the screen. On some systems there is no window, some always center the
window, some can't control centering of window, and some can use this.

SDL_VIDEO_GL_DRIVER = If set and OpenGL mode is in use, then this can be
used to specify the driver file for OpenGL.

SDL_VIDEO_X11_NODIRECTCOLOR = If set, disables use of DirectColor visuals
on X11.

SDL_VIDEO_X11_VISUALID = If set, you can specify the visual to use,
instead of being selected automatically. Can be decimal or can have 0x at
first to be hex.

SDL_WINDOWID = Use an existing window to display the picture instead of
creating a new window.

Normally, the program should never set any of these environment variables
except the ones with asterisks, and even then, should not set them if the
user has already set them.

External resources:

- https://raw.githubusercontent.com/infertux/SDL-1.2.7/master/include/SDL_keysym.h
  List of SDL keycodes

- http://www.libsdl.org/release/SDL-1.2.15/docs/html/
  SDL library documentation (it might not necessarily be very useful to
  you if you are using this JavaScript library, but maybe it is useful)

- http://oss.sgi.com/projects/ogl-sample/registry/ARB/vertex_program.txt
  Description of the programming language used to write vertex programs.

- http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_program.txt
  Description of the programming language used to write fragment programs.


=== Music VM format ===

This documents the music VM.

Registers (c=channel 0 to 7):

00-7F = General use (also used for stack)

80+c = Oscillator 1 frequency

88+c = Oscillator 1 sample

90+c = Oscillator 1 volume

98+c = Oscillator 1 offset

A0+c = Oscillator 2 frequency

A8+c = Oscillator 2 sample

B0+c = Oscillator 2 volume

B8+c = Oscillator 2 offset

C0+c = Oscillator 3 frequency

C8+c = Oscillator 3 sample

D0+c = Oscillator 3 volume

D8+c = Oscillator 3 offset

E0+c = Channel filter

E8+c = Channel mode

F0+c = Old channel value

F8 = Interpretive lookup table address

F9 = Interpretive pointer

FA = Compare value

FB = Accumulator

FC = Frame counter (in units of 1/44100 second)

FD = Index register

FE = Stack pointer

FF = Program counter

All registers store unsigned 16-bit numbers. All are initialized to zero,
except the stack pointer is 128 and the sample numbers are 65535.

The music ROM stores unsigned 8-bit numbers.

Instruction opcodes have the following format:

bit7-bit5 = Addressing mode

bit5 = Direction (0=read 1=write)

bit5-bit0 = Opcode number

Addressing modes are:

000 = Register

001 = Register

010 = Register indexed

011 = Register indexed

100 = Immediate (16-bits small-endian)

101 = Accumulator

110 = Read ROM at address from register

111 = Program counter

Instructions are:

00 = HLT
  Write value to frame counter register and halt.

01 = PSH
  Push to stack.

02 = JMP
  Write value to program counter.

03 = LDA
  Write value to accumulator.

04 = LDX
  Write value to index register.

05 = JSR
  Push program counter to stack and write value to program counter.

06 = ADD
  Add to accumulator.

07 = SUB
  Subtract from accumulator.

08 = ADX
  Add to index register.

09 = SBX
  Subtract from index register.

0A = MUL
  Multiply accumulator by value.

0B = DIV
  Divide accumulator by value.

0C = MOD
  Modulo accumulator by value.

0D = AND
  Bitwise AND accumulator by value.

0E = IOR
  Bitwise OR accumulator by value.

0F = XOR
  Bitwise XOR accumulator by value.

10 = LSH
  Left shift accumulator by value.

11 = RSH
  Right shift accumulator by value.

12 = TAR
  Low 8-bits of value is a register number; write accumulator value to
  that register.

13 = CMP
  Write value to comparison register.

14 = BEQ
  Write to program counter if accumulator equals compare value.

15 = BNE
  Write to program counter if accumulator not equals compare value.

16 = BGT
  Write to program counter if accumulator greater than compare value.

17 = BLT
  Write to program counter if accumulator less than compare value.

18 = BGE
  Write to program counter if accumulator greater or equal compare value.

19 = BLE
  Write to program counter if accumulator less or equal compare value.

1A = SMU
  Shifted multiply accumulator by value.

1B = RAD
  Read from ROM by address by register and advance register. The register
  to access is by low 8-bits of value. Bit15 is set for 16-bit values
  instead of 8-bit values. Bit14-bit8 means how much advancing. The value
  read is written to accumulator.

1C = LUP
  Increment index register, and then if new value is not equal to compare
  value, write the operand value to program counter.

1D = LDN
  If index register is nonzero, decrement it and write operand value to
  the program counter.

1E = BZE
  Write to program counter if accumulator is zero.

1F = BNZ
  Write to program counter if accumulator is not zero.

20 = POP
  Pop from stack.

21 = STA
  Write value of accumulator.

22 = STX
  Write value of index register.

23 = STZ
  Write zero.

24 = FRQ
  Write value looked up in frequency table.

25 = NXT
  Write value of index register plus one.

26 = BRO
  Get 8-bit number from ROM.

27 = WRO
  Get 16-bit small-endian number from ROM.

28 = XCP
  Copy accumulator to compare value. Write old compare value.

29 = XIN
  Copy accumulator to index. Write old index.

2A = INC
  Write value of accumulator plus one.

2B = BAR
  Get 8-bit number from ROM and advance.

2C = WAR
  Get 16-bit small-endian number from ROM and advance.

2D = DEC
  Write value of accumulator minus one.

2E = PRV
  Write value of index register minus one.

2F = INT
  Read one byte from ROM at interpretive pointer and advance interpretive
  pointer, and then look up 16-bit small-endian number using that byte as
  the input inside of the interpretive lookup table, and write that value.

30 = RIP
  Get previous byte from interpretive pointer.

31 = BIP
  Get byte from interpretive pointer and advance.

32 = WIP
  Get 16-bit small endian number from interpretive pointer and advance.

33 = XIP
  Copy accumulator to interpretive pointer. Write old interpret pointer.

34 = STI
  Write value of interpretive pointer.

The channel filter register is used for filtering the output of the
channel (it is a low pass filter); if zero then no filter is done, and
65535 causes the channel to always output the old value.

Sample number for each oscillator can be 65535 for no oscillator.

The channel mode register is defined as follows:

bit10 = Oscillator 1 output

bit9 = Oscillator 2 output

bit8 = Oscillator 3 output

bit5 = Modulation is relative to frequency

bit4 = Oscillator 1 modulates oscillator 3

bit3 = Oscillator 2 modulates oscillator 3

bit2 = Oscillator 1 modulates oscillator 2

bit1 = Multiply output by oscillator 1

bit0 = Hard sync oscillator 3 by oscillator 2

Other bits are reserved and should never be set. (Later versions of
SDLTERM might define their meaning, and if those bits remain clear then
their meaning will be the same as the current meaning.)