This is a formal specification for a common format for storing resources associated with an interactive fiction game file. Resources are data which the game can invoke, such as sounds and pictures. In addition, the executable game file may itself be a resource in a resource file. This is a convenient way to package a game and all its resources together in one file.
Blorb was originally designed solely for the Z-machine, which is capable of playing sounds (Z-machine versions 3 and up) and showing images (the V6 Z-machine). However, it has been extended for use with other IF systems. The Glk portable I/O library uses Blorb as a resource format, and therefore so does the Glulx virtual machine. (See http://eblong.com/zarf/glk/ and http://eblong.com/zarf/glulx/.) ADRIFT 5 (see http://www.adrift.org.uk/) also uses Blorb, albeit with an extended format list.
This format is named "Blorb" because it wraps your possessions up in a box, and because the common save file format was at one point named "Gnusto". That has been changed to "Quetzal", but I'm not going to let that stop me.
This proposal is longer than I would have liked. However, a large percentage of it is optional stuff -- optional for either the interpreter writer, the game author, or both. That may make you feel better. I've also put in lots of examples, explication, and self-justification.
The overall format will be a new IFF type. The FORM type is 'IFRS'.
The first chunk in the FORM must be a resource index (chunk type 'RIdx'.) This lists all the resources stored in the IFRS FORM. There must be exactly one resource index chunk.
The resources are stored in the FORM as chunks; each resource is one chunk. They do not need to be in any particular order, since the resource index contains all the information necessary to find a particular resource.
There are several optional chunks which may appear in the file: the release number (chunk type 'RelN'), the game identifier (chunk type 'IFhd'), and others defined hereafter. They may occur anywhere in the file after the resource index.
Several optional chunks may also appear by convention in any IFF FORM: '(c) ', 'AUTH', and 'ANNO'. These may also appear anywhere in the file after the resource index.
4 bytes 'RIdx' chunk ID 4 bytes n chunk length (4 + num*12) 4 bytes num number of resources num*12 bytes ... index entries
There is one index entry for each resource. (But not for the optional chunks.) Each index entry is 12 bytes long:
4 bytes usage resource usage 4 bytes number number of resource 4 bytes start starting position of resource
The index entries should be in the same order as the resource chunks in the file.
The usage field tells what kind of resource is being described. There are currently four values defined:
The number field tells which resource is being described, from the game's point of view. For example, when a Z-code game calls @draw_picture with an argument of 3, the interpreter would find the index entry whose usage is 'Pict' and whose number is 3. For code chunks (usage 'Exec'), the number should contain 0.
The start field tells where the resource chunk begins. This value is an offset, in bytes, from the start of the IFRS FORM (that is, from the start of the resource file.)
Note that the start field must refer to the beginning of a chunk. It is not strictly required for each resource to refer to a different chunk.
Each picture is stored as one chunk, whose content is a PNG file, a JPEG (JFIF) file, or a placeholder rectangle. (Note that these are various possible formats for a single resource. It is not possible to have a PNG image and a JPEG image with the same image resource number.)
A PNG resource has a chunk type of 'PNG '.
PNG is a lossless image compression format. The PNG file format is available at
http://www.libpng.org/pub/png/
A JPEG resource has a chunk type of 'JPEG'.
JPEG is a lossy image compression format, developed for photograph-like images. For information on JPEG, see
http://www.jpeg.org/jpeg/
A third form of picture resource is a placeholder rectangle. A rectangle has only size, but no contents. This format exists to describe the legacy behavior of some V6 Infocom games (Zork Zero, Shogun, and Arthur). Its support in interpreters is optional, and its use is strongly discouraged for any purpose other than conversions of Infocom graphics.
4 bytes 'Rect' chunk ID 4 bytes 8 chunk length 4 bytes width rectangle width 4 bytes height rectangle height
Either or both of the width and height may be zero.
In a Z-code game, a rectangle exists for the purposes of @picture_data and @erase_picture, but its use in @draw_picture or @picture_table is an error. The behavior of rectangles in Glulx and other game files is not defined.
[Thanks to Kevin Bracey for this extension.]
Each sound is stored as one chunk, whose content is either an AIFF file, an Ogg file, a MOD file, or a song file. (Note that these are various possible formats for a single resource. It is not possible to have an AIFF sound and a MOD sound with the same sound resource number.)
On the Z-machine, we must consider the problems of how the game knows the interpreter can play music, and how sampled sounds are played over music. See the section "Z-Machine Compatibility Issues" later in this document. (These issues are not relevant to Glk and Glulx.)
An AIFF (Audio IFF) file has chunk type 'FORM', and formtype 'AIFF'. AIFF is an uncompressed digital-sample format developed in the late 1980s. The AIFF format is available at these locations:
http://www.digitalpreservation.gov/formats/fdd/fdd000005.shtml http://eblong.com/zarf/ftp/aiff-c.9.26.91.ps
An Ogg Vorbis file has chunk type 'OGGV'. This is a high-quality (but lossy) audio compression format, comparable to MP3 (but without the patent concerns that encumber MP3). The Ogg format is available at:
http://www.vorbis.com/
MOD is an Amiga-originated format for music synthesized from note samples. Over the years, other formats of this type -- generally called "tracker" or "module music" formats -- have arisen. Blorb supports four: original ".MOD" files, ImpulseTracker (".IT"), FastTracker 2 Extended (".XM"), and ScreamTracker 3 (".S3M").
Because tracker-playing libraries typically handle many formats, it is most practical for Blorb to lump them all together. Regardless of which tracker format is used, the chunk type will be 'MOD '.
The formats are described here:
http://www.digitalpreservation.gov/formats/fdd/fdd000126.shtml
This spec does not attempt to distinguish variations within the four supported formats. (".MOD" is particularly ill-defined, although I have saved comments on the original MOD format at http://eblong.com/zarf/blorb/mod-spec.txt.) Instead, we recommend that C implementations embed libmodplug, a public-domain tracker-playing library. Its home page is:
http://modplug-xmms.sourceforge.net/
However, some bug fixes are included in the version packaged with Windows Glk:
http://ifarchive.org/if-archive/programming/glk/implementations/
(Note that it may be safer to compile libmodplug with the MODPLUG_BASIC_SUPPORT option, which eliminates many obscure tracker formats that Blorb does not support.)
Where libmodplug is not practical, implementations should use whatever tracker-playing library claims to support the four formats in question. We trust, perhaps beyond reason, that implementation differences will not lead game creators to their doom.
The song file format is deprecated, as of Blorb 2.0. It is complicated, non-standard, and hard to use. Its support in interpreters should be considered optional. However, it will continue to be documented here.
A song file has chunk type 'SONG'. This is similar to a MOD file, but with no built-in sample data. The samples are instead taken from AIFF sounds in the resource file. For each sample, the 22-byte sample-name field in the song should contain the string "SND1" to refer to sound resource 1, "SND953" to refer to sound resource 953, and so on. Any sound so referred to must be an AIFF, not a MOD or song. (You can experiment with fractal recursive music on your own time.)
Each sample record in a MOD or song contains six fields: sample name, sample length, finetune value, volume, repeat start, repeat length. In a MOD file, the sample name is ignored by Blorb (it is traditionally used to store a banner or comments from the author.) In a song file, the sample name contains a resource reference as described above; but the sample length, repeat start, and repeat length fields are ignored. These values are inferred from the AIFF resource. (The repeat start and repeat length are taken from the sustainLoop of the AIFF's instrument chunk. If there is no instrument chunk, or if sustainLoop.playMode is NoLooping, there is no repeat; the repeat start and length values are then considered zero.)
Note that an AIFF need not contain 8-bit sound samples, as a sound built into a MOD would. A clever sound engine may take advantage of this to generate higher-quality music. An unclever one can trim (or pad) the AIFF's data to 8 bits before playing the song. In the worst case, it is always possible to trim the AIFF data to 8 bits, append it to the song data, fill in the song's sample records (with the appropriate lengths, etc, from the AIFF data); the result is a complete MOD file, which can then be played by a standard MOD engine.
The intent of allowing song files is both to allow higher quality, and to save space. Note samples are the largest part of a MOD file, and if the samples are stored in resources, they can be shared between songs. (Typically note samples will be given high resource numbers, so that they do not conflict with sounds used directly by the game. However, it is legal for the game to use a note sample as a sampled-sound effect, if it wants.)
Each data file is stored as one chunk, with chunk type 'TEXT' or 'BINA' (denoting text or binary data). The format and contents are up to the game to interpret.
This feature was designed to support Glulx, but data resources can be accessed by any game format if the interpreter supports them.
For Glulx games (and any other game format which uses the Glk API), the data format must follow the conventions described in the Glk spec. (http://eblong.com/zarf/glk/, "Resource Streams".)
[To summarize: if the data file is opened via glk_stream_open_resource(), then it will be read as a stream of bytes; text will be assumed to be encoded as Latin-1. If it is opened via glk_stream_open_resource_uni(), then a 'TEXT' chunk will be assumed to be a stream of characters encoded as UTF-8; 'BINA' will be assumed to be a stream of big-endian four-byte integers. If read by lines (glk_get_line_stream(), etc), resource text should use Unix line breaks in all cases.]
There should at most one chunk with usage 'Exec'. [But see below.] If present, its number must be zero. Its content is a VM or game executable. Its chunk type describes its format:
[This list of formats is taken from the Babel format agreement. See http://babel.ifarchive.org/ for more information. Most of these development systems do not support Blorb at the present time; the list is available for future use. Other executable formats may also be added in the future. As a convention, the chunk types should be taken from the Babel format name, converted to upper case and padded (if necessary) with spaces.]
[The EXEC (native) chunk type is not likely to be useful, because it is underspecified. Nothing (beyond the chunk data itself) indicates what CPU or operating system the executable is intended for. Again, it is defined here following the Babel format list.]
A resource file which contains an executable chunk contains everything needed to run the executable. An interpreter can begin interpreting when handed such a resource file; it sees that there is an executable chunk, loads it, and runs it.
A resource file which does not contain an executable chunk can only be used in tandem with an executable file. The interpreter must be handed both the resource file and the executable file in order to begin interpreting.
If an interpreter is handed inconsistent arguments -- that is, a resource file with no executable chunk, or a resource file with an executable chunk plus an executable file -- it should complain righteously to the user.
As of this spec, no IF system puts more than one 'Exec' chunk in a Blorb file, or has any need to. However, this could change in the future.
One possible use (noted as a comment in earlier versions of this spec) is to support several loadable libraries or game segments. In such a case, chunk zero should contain the code to execute first, or at the top level.
Another possibility is to distribute several versions of a game in one Blorb package. IF platforms are famed for the fragility of their save files; a player who downloads an updated game file is likely to find that it no longer loads her old saved games. This could be avoided if the updated Blorb actually contained multiple game files, one per 'Exec' chunk. Chunk zero would be the preferred (most recent) game version, but when loading a save file, the interpreter would select whichever game version was compatible with it.
This identifies which game the resources are associated with. The chunk type is 'IFhd'.
This chunk is optional; at most one should appear. If it is present, and the interpreter is given a game file along with a resource file, the interpreter can check that the game matches the IFhd chunk. If they don't, the interpreter should display an error. The interpreter may want to provide a way for the user to ignore or skip this error (for example, if the user is a game author testing changes to the game file.)
If the resource file contains an executable chunk, there is little reason to have an IFhd chunk. It is legal, however, as long as the identifier matches the executable.
For Z-code, the contents of the game identifier chunk are defined in the common save file format specification, section 5. This spec can be found at
http://ifarchive.org/if-archive/infocom/interpreters/specification/savefile_14.txt
The "Initial PC" field of the IFhd chunk (bytes 10 through 12) has no meaning for resource files. It should be set to zero.
For Glulx, the contents of the game identifier chunk are defined in the Glulx specification. This can be found at http://eblong.com/zarf/glulx/.
This contains information about which colors are used by picture resources in the file. The chunk type is 'Plte'. It is optional, and should not appear if there are no 'Pict' resources in the file. At most one color palette chunk should appear.
The format is:
4 bytes 'Plte' chunk ID 4 bytes n chunk length n bytes ... color data
There are two possibilities for the color data format. The first is an explicit list of colors. In this case, the data consists of 1 to 256 color entries. Each entry is three bytes, of the form:
1 byte red value (0 = black, 255 = red) 1 byte green value (0 = black, 255 = green) 1 byte blue value (0 = black, 255 = blue)
The second case is a single byte, which may have either the value 16 or 32 (decimal). 16 indicates that the picture resources are best displayed on a direct-color display which has 16 or more bits per pixel (5 or more bits per color component.) 32 indicates that the resources are best displayed with 32 or more bits per pixel (8 or more bits per color component.)
The two cases are differentiated by checking the chunk length (n). If n is 1, it's a direct color value; if it's a positive multiple of 3, it's a color list, and the number of entries is the length divided by 3. Any other length is illegal.
This chunk is only a hint; there is no guarantee about what the interpreter will do with it. A color list will most likely be useful if the interpreter's display can only display a limited number of colors (for example, an 8-bit indexed color device). The interpreter may set the display to the colors listed in the palette. Or it may set the display to just some of the colors listed (for example, if it wishes to reserve some colors for text display, or if it just doesn't have enough colors available.) Or the interpreter may ignore the palette chunk, or do something else.
Similarly, if the interpreter finds a "16" or "32" value, it may set the display to the appropriate bit depth. Or it may set the display to an 8-bit color cube, and dither the images for display. Or, again, it may ignore the palette chunk entirely, or do something else.
It is not required that the palette chunk list every color used in the 'Pict' resources. It is not required that the colors in the palette all be different, or that they all are actually used by 'Pict' resources. It is not required that the palette have anything to do with the game art at all. Of course, if you give the interpreter misleading hints, you deserve whatever you get.
The Blorb format generally does not specify how images are loaded and displayed; that is the province of the game file format. However, it may be desirable to associate a single image with the game. The image would serve as a frontispiece, or "cover art".
The exact use of a frontispiece image is left open to invention. An interpreter may display it before starting a game. Or it might display frontispieces while the player is choosing a game to play (as an aid to locating a particular game). An index of games might extract the frontispieces and use them as catalog illustrations.
If present, the frontispiece is simply an ordinary picture resource. It is singled out as a frontispiece by a chunk with type 'Fspc'; this contains its image resource number. There may not be more than one 'Fspc' chunk.
The frontispiece image may be of any legal Blorb type (except a placeholder rectangle). The image may be of any size, but is preferred to be square or approximately so. This allows interpreters to display frontispieces in a systematic way, scaling them to fit a layout, without wasting screen space.
(Since the frontispiece image is not loaded by the game file, it may be used even with game files that do not support graphics, such as the V5 Z-machine. In a graphics-capable game file, it is legal for the frontispiece image to also be loaded by the game file in the usual way.)
4 bytes 'Fspc' chunk ID 4 bytes 4 chunk length 4 bytes number number of a Pict resource
For a game to be fully accessible to visually impaired users, it should provide textual descriptions to be displayed as alternatives to images. Similarly, audio resources should have textual descriptions as alternatives for hearing-impaired users.
The resource description chunk allows the Blorb file to offer this information.
4 bytes 'RDes' chunk ID 4 bytes len chunk length 4 bytes num number of entries ... entries
The entries are variable-length, and look like:
4 bytes usage resource usage 4 bytes number number of resource 4 bytes length length of text (bytes) length bytes text textual description (UTF-8, not null-terminated)
There should be at most one entry for each resource -- that is, each (usage, number) pair.
Resource descriptions are not required, but they are recommended for significant sounds and images. (Images used for decoration, such as window borders or text dividers, may not need textual descriptions.) Data and executable chunks do not need descriptions; if they appear in this chunk, the interpreter can ignore them.
[An interpreter with a web interface would apply the textual description of an image as an "alt" attribute on the <img> tag.]
Metadata is a contentious topic, with which the Blorb spec is not entirely unentangled. (The game identifier and frontispiece chunks are answers to small parts of the IF metadata problem.)
Rather than entangle ourselves further, we will merely say that metadata will be stored as XML, in a chunk of type 'IFmd'. The XML structure is documented in the Babel format agreement; see http://babel.ifarchive.org/.
4 bytes 'IFmd' chunk ID 4 bytes n chunk length n bytes ... XML document (UTF-8 encoding)
The handling of metadata chunks will not be defined here. In particular, the behavior of an interpreter which finds more than one metadata chunk is undefined. It is likely to be a good idea to have at most one.
The Z-machine's graphics and sound capabilities were added late in Infocom's history, but early in the history of data format standardization. As a result, the Z-machine's audio and image models are both too rigid and too flexible to work well with modern file formats.
To compensate for this, we add additional information to the Blorb file. Interpreters can use these hints to display the resource information correctly.
Some of these hints are needed only to handle legacy Infocom games and their resources. Others will be useful for the creation of new Z-code games.
Each of these chunks is optional; no more than one of each should appear.
This chunk is used to tell the interpreter the release number of the resource file. It is meaningful only in Z-code resource files.
The interpreter passes this information to the game when the @picture_data opcode is executed with an argument of 0. The release number is a 16-bit value. The chunk format is:
4 bytes 'RelN' chunk ID 4 bytes 2 chunk length 2 bytes num release number
This chunk is optional. If it is not present, the interpreter should assume a release number of 0.
This chunk contains information used to scale images. The chunk type is 'Reso'. It is optional. This chunk is meaningful only in Z-code resource files.
A scalable image is one which the author says should be larger when more space is available, and smaller when less space is available. (Note that the Z-code game does not directly control the scaling of images. The interpreter controls the scaling of images, in response to the information in the resolution chunk. The interpreter then provides the scaled size in response to @picture_data queries, and the game draws its display based on those queries.)
It is also possible to create images that have a fixed scaling ratio; they are always scaled up or down by a particular amount, regardless of window size.
Not all images have to be scalable. Unless the resolution chunk gives scaling data for an image, that image is assumed to be non-scalable. Non-scalable images are always displayed at their actual size. (One image pixel per screen pixel.)
This chunk is optional; if it is not present, then all of the images in this file are non-scalable.
4 bytes 'Reso' chunk ID 4 bytes num*28+24 chunk length 4 bytes px standard window width 4 bytes py standard window height 4 bytes minx minimum window width 4 bytes miny minimum window height 4 bytes maxx maximum window width 4 bytes maxy maximum window height num*28 bytes ... image resolution entries
The "standard window size" is the normal size, the author's original chosen size, for the Z-machine window. It is not the only possible size; a good V6 game should be prepared for any window the interpreter chooses to create. The idea is that when the Z-machine window is exactly the standard size, scalable images are presented at their original size. When the Z-machine window is larger than the standard size, scalable images are scaled up; when it is smaller, scalable images are scaled down.
The minimum and maximum window sizes are provided as a hint to the interpreter, when it is choosing a window size. It may also use the standard window size as a hint for this purpose. (If the interpreter lacks the ability to choose its own window size, of course, it will ignore these hints.) The idea is that the minimum and maximum sizes define the range in which the game can draw itself successfully.
Any or all of minx, miny, maxx, maxy can indicate "no limit in this direction" by containing a value of zero. However, px and py must contain non-zero values. Unless the min or max values are zero, it must be true that minx <= px <= maxx, miny <= py <= maxy.
Important note: The standard, minimum, and maximum window size values are measured in screen pixels. Furthermore, unscaled pictures should be drawn in screen pixels -- one image pixel per screen pixel. (This may seem dumb as rocks, and maybe it is, but my rationale is presented at the end of this document.)
Also note that I have not mentioned Z-pixels. This standard does not concern itself with Z-pixels.
On with the show.
The standard, minimum, and maximum window sizes are followed by a set of image entries, one for each scalable image. (Non-scalable images do not have an entry in this table; that's how they are declared to be non-scalable.) Each image entry is 28 bytes, of the form:
4 bytes number image resource number 4 bytes ratnum numerator of standard ratio 4 bytes ratden denominator of standard ratio 4 bytes minnum numerator of minimum ratio 4 bytes minden denominator of minimum ratio 4 bytes maxnum numerator of maximum ratio 4 bytes maxden denominator of maximum ratio
The number is the picture number; in other words, this entry applies to the resource whose usage is 'Pict' and whose number matches this value.
The entry then contains a standard, minimum, and maximum image scaling ratio. Each ratio is a real number, represented by two integers:
Minratio can indicate zero ("no minimum limit") by having both minnum and minden equal to zero. Similarly, maxratio can indicate infinity ("no maximum limit") by having maxnum and maxden equal to zero. It is illegal to have only half of a fraction be zero.
To compute the actual scaling ratio for this image, the interpreter must first compute the overall game scaling ratio, or Elbow Room Factor (ERF). If the actual game window size is (wx,wy), and the standard window size is (px,py), then
(Note that if the game's window is exactly its standard size, ERF = 1.0. If the window is twice the standard size, ERF = 2.0. If the window is three times the standard width and four times the standard height, then ERF = 3.0, because there's really only enough room for the game's standard layout to be tripled before it overflows horizontally.)
The scaling ratio R for this image is then determined:
If minratio and maxratio are the same value, then R will always be this value; ERF and stdratio are ignored in this case. (This indicates a scalable image with a fixed scaling ratio.)
The interpreter then knows that this image should be drawn at a scale of R screen pixels per image pixel, both vertically and horizontally. The interpreter should report this scaled size to the game if queried with @picture_data (as opposed to the original image size).
Yes, this is an ornate system. The author is free to ignore it by not including a resolution chunk. If the author wants scaled images, or variably-scalable images, this system should suffice.
Here are some examples. They're not necessarily examples of good art design, but they do demonstrate how a given set of desires translate into images and resolution values. All are for a game with a standard size of (600,400).
The game wishes a title image that covers the entire window, and all the resolution should be visible at the standard size. (So if the window is twice the standard size, the image will be stretched and coarse-looking; if the window is half the standard size, the image will be squashed and lose detail.)
The game has a background image of a cave, made from a scanned photograph. At standard window size, this should cover the entire window, but not all the detail needs to be visible. If the window is larger, the image should still cover the entire window; more detail will be visible, up to twice the standard size (at which point all the resolution should be visible.) If the window is larger than twice the standard size, the image should not be stretched farther; instead the game will center it and have blank space around the edges.
The game has small monochrome icons indicating different magical perceptions, which it will draw interspersed with the text. The icons should always be drawn at double size, two screen pixels per image pixel, regardless of the window size.
The game has a graphical compass rose which it will draw in the top left corner. This should be 1/4 of the window size in the standard case, and shrink proportionally if the window is smaller. However, if the window is larger than standard, the rose should not grow; all the extra space can be allotted for text. All detail (image pixels) should be visible in the standard case.
The same compass rose, still to be 1/4 of the window size -- but this time it is critical that all the image detail be visible when the window is as small as half-standard (that is, when the rose is 75 by 50 pixels). At standard scale (150 by 100), it will therefore appear stretched and coarse. If the window is smaller than half the standard size, the rose should not shrink beyond 75x50, so that pixels are never lost.
End of verbose examples.
This chunk contains a list of pictures that change their colors according to the pictures plotted before. The chunk type is 'APal'. It is optional. This chunk is meaningful only in Z-code resource files.
This format exists to describe the legacy behavior of some V6 Infocom games (Zork Zero and Arthur). Its support in interpreters is optional, and its use is strongly discouraged for any purpose other than conversions of Infocom graphics.
4 bytes 'APal' chunk ID 4 bytes num*4 chunk length num*4 bytes ... adaptive palette entriesEach entry is 4 bytes, of the form:
4 bytes number picture resource number
If this chunk is present:
However, the following rules still apply from the PNG standard:
These restrictions, though intricate, serve to make the interpreter's life easier at the expense of constraining the creator. The constraints are natural given the form of the original Infocom graphics.
The interpreter should keep track of the "Current Palette". This will be a 14-entry table, covering color indices 2-16. For ease of implementation, this will probably be a 16-entry table, whose first two entries are not significant.
Whenever a picture not listed in the APal chunk is plotted, its palette (as derived from its PLTE, gAMA, cHRM and sRGB/iCCP chunks) should be copied into the Current Palette. If its palette has fewer than 16 entries, then only those entries of the Current Palette are changed. (Possible interpreter implementation: transform the PNG's PLTE chunk according to the gAMA, cHRM, sRGB chunks, then copy it into your Current Palette which is always in the screen color-space. With libpng, use png_get_PLTE, after calling png_update_info).
Whenever a picture listed in the APal chunk is plotted, its palette should be ignored, and it should be plotted with the Current Palette. (Possible interpreter implementation: strip out the PLTE, gAMA, cHRM and sRGB/iCCP chunks from the PNG, and insert the Current Palette as its PLTE. Or with libpng, use png_set_PLTE before reading the data).
The behavior is undefined if any adaptive-palette pictures are plotted before a non-adaptive picture has been plotted.
If picture caching (through @picture_data or otherwise) is implemented, special attention may need to be paid to ensure that adaptive images that are cached are still appropriate for the Current Palette when plotted. It would appear that the Zork Zero does reset the cache after a palette change, but this has not been exhaustively investigated.
Alternatively, for the full retro-gaming experience, the pictures can be handled in the same way as the Amiga and IBM MCGA interpreters, as follows: Use a 16-color screen mode. Copy non-adaptive pictures' palette (apart from the first two entries) into the screen palette when plotted. Use color indices 0 and 1 for the window background and text respectively. This mimics the IBM MGA and Amiga display, where drawing a picture can change the colors of graphics already on the screen, but it is not the preferred rendering.
Shogun and Journey do not use any adaptive-palette images, but on some platforms the effect of pictures already on the screen changing color is visible. To give an interpreter the ability to do this if desired, and to signal that optimizations may be possible because of the limited nature of the graphics, the Blorb files for Shogun and Journey contain an empty APal chunk.
[Thanks to Kevin Bracey for this extension.]
This chunk contains information about which sounds are looped, in a V3 Z-machine game. The chunk type is 'Loop'. It is optional.
Note that in V5 and later, the @sound_effect opcode determines whether a sound loops. The looping chunk is ignored. Therefore, this chunk should not be used at all in Blorb files intended for games which are not V3 Z-machine games.
The format is:
4 bytes 'Loop' chunk ID 4 bytes num*8 chunk length num*8 bytes ... sound looping entries
Each entry is 8 bytes, of the form:
4 bytes number sound resource number 4 bytes value repeats
The repeats flag is one if the sound is to be played once; it is zero if the sound is to repeat indefinitely (until it is stopped or another sound started.) If there is no entry for a particular sound resource, or if the looping chunk is absent, the V3 interpreter should assume the flag is one, and play the sound exactly once.
A resource file can contain extra user-level information in 'AUTH', '(c) ', and 'ANNO' chunks. These are all optional. An interpreter should not do anything with these other than ignore them or (optionally) display them.
These chunks all contain simple ASCII text (all characters in the range 0x20 to 0x7E). The only indication of the length of this text is the chunk length (there is no zero byte termination as in C, for example).
The 'AUTH' chunk, if present, contains the name of the author or creator of the file. This could be a login name on multi-user systems, for example. There should only be one such chunk per file.
The '(c) ' chunk contains the copyright message (date and holder, without the actual copyright symbol). There should only be one such chunk per file.
The 'ANNO' chunk contains any textual annotation that the user or writing program sees fit to include.
Some older Z-code Blorb files contain an 'SNam' (story name) chunk, which contains the game's title. The format of this chunk is Unicode UTF-16, with the 16-bit values stored big-endian. Modern Blorb files should not have an 'SNam' chunk; this information should be stored in the metadata chunk instead.
Previous versions of the Blorb spec did not discuss file naming. However, with the relapse of MacOS into filename suffix semantics, it is impossible for us to pretend that the issue is an implementation detail.
It is always legal for a Blorb file to have a ".blorb" filename suffix. However, interpreters have a natural interest in locating their sort of Blorb files -- Z-code, Glulx, or so on -- and it is generally easier for them to do this by filename suffix, rather than by opening each Blorb and looking at its resource index. Therefore, ".zblorb" and ".gblorb" should be used to designate Blorb files containing Z-code and Glulx games, respectively.
On platforms which limit filename suffixes to three characters, the suffixes ".blb", ".zlb", and ".glb" may be used instead. But this practice, at least, I can deprecate without qualm. I hope.
Historically, Blorb files have been associated with the MIME type application/x-blorb
.
We can use the profile feature of MIME to differentiate the contents: application/x-blorb;profile="zcode"
and application/x-blorb;profile="glulx"
for the common virtual machines.
(Previous versions of this spec suggested application/x-blorb-zmachine
and application/x-blorb-glulx
. These are now deprecated.)
The image system presented in this document is fully backwards-compatible with Infocom's interpreters. Infocom V6 games, such as Arthur, Journey, and Zork Zero, contain only non-scalable image resources. The game files are written to deal with both variations in window size and variations in image size (since the interpreters for different platforms had different window sizes and different art.) Therefore, if you construct a Blorb file containing the images from a particular platform (say, the Mac) and give it the suggested window size of the Infocom Mac interpreter, the game file will deal with it correctly.
The image system is also sort of forwards-compatible, in the following sense. If you take a Blorb file whose standard (intended) window size is the same as the Infocom interpreter's, and break it out into Infocom image files, the Infocom interpreter should display it correctly. The interpreter will not scale images, but since the window size is equal to the standard size, the Blorb rules require the images to be displayed unscaled anyway.
Also, of course, if you take a Blorb file which contains only non-scalable images, an Infocom interpreter will act correctly, since it will not scale the images regardless of the standard size.
The sound system is slightly more problematic. A game file can announce that it uses sound, by setting a header bit; the interpreter can announce that it does not support sound, by clearing that bit. But there is no way to distinguish a game that uses sampled sound only, from one that uses sampled sound and music. (And similarly for the interpreter's support of samples versus music.) This may be addressed in a future revision of the Z-machine. In the meantime, games should set that header bit if any kind of sound is used (samples or music or both.) And interpreters should clear that bit only if no sound support is available. If the interpreter supports sampled sound but not music, it should leave the header bit set, announcing that it does "support sound." It should then ignore any request to play a music resource.
There is also the question of overlapping sounds. The Z-Spec (9.4.2) says that starting a new sound effect automatically stops any current one. But it is not desirable that a sound effect such as footsteps should interrupt the playing of background music. Therefore, the interpreter should amend this rule, and consider sampled sounds and music to be in seperate "channels". Samples interrupt samples, and music interrupts music, but one form of sound does not interrupt the other.
This is an actual variance in the behavior of the Z-machine, and worse, a variance which depends on data format. (One sound will either stop another, or not, depending on whether the sound is stored in AIFF (sampled) or Ogg/MOD (music) format.) We apologize for the ugliness.
Again, future versions of the Z-machine may address this issue, and allow a more general system where any sound can be overlaid on any other sound, or interrupt it, as the game desires and regardless of storage format. (After all, there can be background sounds as well as background music.) Such a system would also allow the interpreter to announce its limitations and capabilities -- whether it can play music, whether it can play two pieces of music at once, how many sampled sounds it can play at once, etc.
A final, ah, note: The remark at the end of Z-Spec chapter 9, about sequencing sound effects to simulate the slow Amiga version of "The Lurking Horror", should not be applied to music sounds. New music should interrupt old music immediately, regardless of whether keyboard input has occurred since the old music started.
The Glk I/O library was designed with portable resources in mind, so there should be no incompatibility.
Remember that the resolution and scaling data is not used by Glk. That chunk is ignored by Blorb-capable Glk libraries.
ADRIFT supports more media formats than Blorb, but has adopted Blorb as a packaging format. To permit this, the following chunk types may be used in ADRIFT blorbs:
For images: 'GIF '.
For sounds: 'WAV ', 'MIDI', 'MP3 '.
ADRIFT Blorb files should use MIME type application/x-blorb;profile="adrift"
. The filename suffix should be ".blorb" or ".adriftblorb". ["A" or "AD" is unfortunately not a unique prefix when it comes to IF systems!]
A description of the IFF format can be found at
http://eblong.com/zarf/blorb/iff.html
In the interests of simplicity, this proposal does not use IFF LISTs or CATs, even though its purpose is to contain concatenated lists of data. Therefore, the format can be quickly described as follows:
4 bytes 'FORM' Magic number indicating IFF 4 bytes n FORM length (file length - 8) 4 bytes 'IFRS' FORM type n-4 bytes ... The chunks, concatenated
Each chunk has the following format:
4 bytes id Chunk type 4 bytes m Chunk data length m bytes ... Chunk data
Remember that the chunk length never includes the eight-byte header (the type and length). This is true for the top-level FORM and internal FORMs as well.
If a chunk has an odd length, it must be followed by a single padding byte whose value is zero. (This padding byte is not included in the chunk length m.) This allows all chunks to be aligned on even byte boundaries.
All numbers are two-byte or four-byte unsigned integers, stored big-endian (most significant byte first.) Character constants such as 'FORM' are stored as four ASCII bytes, in order from left to right.
When reading an IFF file, a program should always ignore any chunk it doesn't understand.
It may be convenient for an interpreter to be able to access resources in formats other than a resource file. In particular, when developing a game, an author will want to load images and sounds from individual files, rather than having to re-package all the resources whenever any one of them changes.
Such resource arrangements are platform-specific, and the details are left to the interpreter. However, one suggestion is to have a single directory which contains all the resources as files, with one file per resource. (PNG files for images, and so on. The contents of each file would be exactly the same as the contents of the equivalent chunk, minus the initial eight bytes of type/length information.) Files would be named something like "PIC1", "PIC2"..., "SND1", "SND2"..., "DATA1", "DATA2"..., and so on. An executable game file (if present) would be named "STORY". Other chunks would be named as follows:
(Naturally, file suffixes would be added in platforms that require them.) The interpreter would be started up and handed the entire directory as an argument; or possibly the directory along with a separate Z-code file.
It is of course possible to break a Blorb file down into a directory in this format. When doing this, one must remember that AIFF (and no other chunk type) uses an IFF form as its single-file representation. Therefore, the SND... file representing an AIFF will begin "FORM<length>AIFF", followed by the chunk data. All other chunk types would be turned into files simply by extracting the chunk data.
- Why have a common resource collection format?
Infocom chose not to standardize their resource formats; they had a different picture format for each platform. This was a reasonable choice for them, since they were writing all the games, all the art, and all the interpreters. They therefore had the capacity to translate the art into platform-specific formats for all the platforms they supported.
In the modern age, an IF author does not have access to all the platforms his game will be played on. It is therefore reasonable to distribute art in a single format, and leave interpreter writers the job of supporting that format.
- Why an IFF-based format?
IFF does what we want; it's a known, very simple way to concatenate chunks of data together.
Also, the common save-file format is IFF-based. This allows interpreters to use the same code for reading both save files and resource files.
- Why not compress data as well as archiving it? Why just concatenate everything together as chunks?
Any reasonable sound or image format already incorporates compression.
- Why is there a "number" field in the entries in the resource index chunk? Why not just assume chunks are numbered consecutively?
On the Z-machine, pictures are not necessarily numbered contiguously (Z-Spec <IP_ADDRESS>.) Sounds are numbered consecutively, but sounds 1 and 2 are bleeps, so the game-specific sound resources start at 3. (Z-Spec 9.2.) In Glk, resources need not be contiguous at all. Rather than jigger the numbering or require place-holder chunks, I decided there should be an index which maps resource numbers to chunks.
- Why only two image formats? Why not allow any image format?
The whole point of this exercise is to assure the author that the player can view his art. If we allow lots of different formats, we can't possibly insist that every interpreter must display all the formats. This leaves us just about back where we started. Individual game authors would be negotiating with individual interpreter authors to support particular formats, and it would just be icky.
Therefore, we do insist that every interpreter be able to display all the formats listed in this standard. That means a small number of formats. See the next two questions.
It is very strongly suggested that an interpreter use standard open-source libraries for interpreting sound and image resources. To rely on OS services, while tempting, is a road paved with incompatibility problems.
- Okay, then, why three sound formats?
Because a sampled-sound format (like AIFF) can reproduce anything, and a compressed digital format (like Ogg) can reproduce large sounds efficiently.
MOD can reproduce music even more efficiently, but it's really retained in the spec more for backwards compatibility than for any technical reason. Existing games use it, and while it's not very well standardized, it seems to work.
(The "song" format was never widely used, which is both the qualification and the justification for deprecating it.)
- Why PNG and JPEG for images?
The PNG format is not burdened with patent restrictions; it is free; it's not lossy; and it can efficiently store many types of images, from 1-bit (monochrome) images up to 48-bit color images. JPEG is lossy and not optimal for images other than photographs, but compresses photographs well. Earlier versions of Blorb specified only PNG, but JPEG was a popular request, and the two formats should complement each other.
As to other possibilities: GIF is a popular format, but was previously owned by twits who restricted its use. (Life has improved, but we have PNG now and we will stick with it.) TIFF has been suggested, but it seems to be overly baroque. Blorb is likely to stay with PNG and JPEG for the foreseeable future.
- So why does ADRIFT get a bye on these format decisions?
Game authors and interpreters need to agree on what formats they will use. Z-code had no cross-platform agreement when Blorb was invented, and Glulx was created to use Blorb, so Blorb's role for them is normative. GIF and MP3 are not going to become standard Blorb format types.
ADRIFT, in contrast, already had cross-platform interpreters when it adopted Blorb. Blorb can therefore be valuable to ADRIFT as a packaging and metadata format, while taking a descriptive role on media formats. (The alternative would be to disallow ADRIFT Blorb files, which seems silly.)
[It is worth noting, however, that IF interpreters are often ported by adapting existing IF display code. IF interpreter ports can also be based on Glk libraries and the Glk API. Both routes entail the Blorb standard media format list, to some extent. Therefore, game authors have some reason to consider sticking to those formats.]
- What is the Blorb Policy on Color Depth?
The idea is that each author can decide what kind of color requirements his game will have.
The alternative (which we did not choose) would be to mandate a fixed set of color requirements for all graphical games -- for example, an 8-bit color display set to a color-cube set of colors.  Any fixed set of requirements is going to be impossible for some machines and standard equipment on others, and both these sets will change over time. The requirements would quickly become obsolete.
Instead, we choose to allow any kind of art in graphical games. If the author includes only monochrome images, the game will run anywhere. If the author includes full-color 32-bit images, he is creating a game which wants a powerful graphics machine to display itself on. That's the author's choice. If the player's machine only allows 8-bit color, his interpreter will have to dither or otherwise reduce the color information of the game art. The player can accept this, buy a more powerful computer, or throw away the game. There's no way around that. The problem can only be avoided by outlawing 32-bit color images, which we do not wish to do.
- What's the idea of the palette chunk?
The palette chunk itself is provided for the benefit of interpreters which can control their display palettes or color depth. The palette declares the minimum set of colors (or direct-color depth) which the author wants you to have in order for the game to "look okay." It may be a good idea to switch palettes in order to play a particular game; the palette chunk tells the interpreter this advice.
Now, the interpreter is not required to follow this advice. This is for the player's benefit; if the player has a monochrome machine, or just doesn't like changing palettes, he is not denied the opportunity to play the game. He'll just get reduced-quality art. That's his choice. As stated above, he can accept it, upgrade, or throw the game away.
- What is the Blorb Policy on Pixel Size?
We make a couple of assumptions.
Assumption one: Image pixels are square. Your images should have the correct aspect ratio when drawn with square pixels -- that is, when the number of image-pixels-per-inch is the same vertically and horizontally. If your art program doesn't understand square pixels, get a real art program. There. That's resolved.
(This means that if an image is 400 pixels wide and 200 pixels high, the interpreter should draw it on the screen with a physical width twice its physical height. Anything else will look distorted.)
(It has been noted that this does not exactly apply to Infocom's V6 games; their art was probably designed for an era of computers that did not have exactly square pixels (IBM EGA, Apple II machines displaying on television screens, and other such barbarisms.) However, this does not seem to have concerned them. Infocom interpreters which are running on modern machines, with square-pixel displays, display their art with square pixels. We will do the same.)
Assumption two: It is always okay to draw images at their "actual size" -- one image pixel per screen pixel.
Now you think I'm crazy. It is true that many modern screens can be adjusted to different pixel sizes. However, I declare this to be an illusion. If a user sets his monitor to smaller pixels, it's because he wants a given image to be smaller. So he can fit more of them on screen. He also wants his text to be smaller, and his windows. That's the way web browsers work, that's the way Adobe Photoshop works, and that's damn well good enough for the Z-machine.
Perhaps in the future there will be monitors that break this rule -- much smaller pixels, 300 or 600 pixels per inch, for example. At that time there will be some consensus on how to display images. (Frankly, I expect it will be "draw them at 55, 72, or 88 pixels per inch, depending on the user's previous preference." Or some such set of standard options.) Z-machine interpreters can follow that plan when it emerges.
Until then, the right size for a non-scaled picture is one image pixel per screen pixel. If an image is to be scaled by a ratio of 2.0, then the right size for it is one image pixel per two screen pixels (vertically and horizontally). And so on.
- Where do Z-pixels come into all this?
The definition of Z-pixels is entirely up to the interpreter. This standard says nothing on the subject, and does not care.
It is true that the interpreter must tell the game what the window size and image sizes are, as measured in Z-pixels. That's the interpreter's job. The interpreter knows how big its window is, in screen pixels; it translates that into Z-pixels -- using whatever definition it has -- and reports it to the game. Then, the scaling rules of this spec define what the display sizes of the images will be, as measured in screen pixels. The interpreter translates these sizes into Z-pixels -- using the same definition -- and reports them to the game. All consistent and well-defined.
- What is the Blorb Policy on Interpreters that do Funky Stuff?
The interpreter is Allowed. It's okay to be ugly.
For example, someone may (in a fit of insanity) write a Blorb-compliant interpreter for the Apple II. The Apple II had non-square pixels. But (assume) it doesn't have the processing power to scale all its images by a factor of 1.2 (or whatever) to adjust for this. Well, it's legal to write an interpreter that draws art at one image pixel per (non-square) screen pixel. The art will look distorted; the user can like it or play on a different machine.
For another example, someone may want their entire game display doubled in size. All the art twice as large (in screen pixels) as this spec says it should be. An interpreter which has this option is legal. It's the moral equivalent of mounting a magnifying glass on your monitor -- that certainly doesn't violate any software standards.
- What about playing Blorb-packaged games on original Infocom interpreters?
It's possible. You'll have to unpack the PNG art and translate it into the format that Infocom used. Since the Infocom interpreters had a hard-wired screen size, you can precompute all the scaling factors, and do any necessary scaling in the translation process. 32-bit color images will have to be color-reduced; that's the way it goes. But the result should be fully playable on Infocom's interpreters.
- Have you considered --
Yes.


Aston Martin Shows Awesome Aviation-Inspired Special Editions
And more are coming.
by Jared RosenholtzAston Martin is a company with a rich connection to aviation. Three of its four UK manufacturing sites are located on former Royal Air Force bases and the company's logo is made up of a pair of wings. Hence why Aston's Q Division has released a series of special edition cars with RAF-inspired themes. One example was the V8 Vantage S Blades Edition, which was named after a British aerobatics team. Only five copies were built.
The V12 Vantage S Spitfire 80 was another great example, of which just 80 were built. If you bought one of the 80 cars, you also received a Spitfire 80 Irvin jacket, flying helmet, and goggles. To celebrate its connection with the RAF, the company has brought together all of its "Aston Martin Wings" vehicles for an impressive photoshoot.
Along with the two RAF-inspired Vantage models, Aston Martin also gathered up examples of the Vanquish S Red Arrows Edition. Only 10 of these cars were built with just nine making it into customer's hands. The 10th car was auctioned off for charity, raising £1.46 million ($1.87 million) for the RAF Benevolent Fund.
Judging by the photo of nine red cars with a corresponding number of Red Arrows Hawk airplanes flying above them, Aston was able to gather all of the cars for this historic photoshoot. The Red Arrows Edition Vanquish even uses switchgear made from the undercarriage leg of the airplane from which it gets its name.
You Might Also Like
Aston Martin President and Group CEO, Andy Palmer, is even an Honorary Group Captain in the 601st Squadron of the Royal Air Force. "Aston Martin will always be synonymous with aviation, from our wings logo to the heritage of our manufacturing sites across the UK," Palmer said. "The Vanquish S Red Arrows edition was a great success for everyone concerned and I look forward to seeing our future aviation-related special editions."


"Walser Lawn Care did a beautiful job with our garden! Now I love taking my guests through my backyard when I'm hosting events and I am always getting compliments. They were very effecient and very professional, I could not have asked for a better job!" - Judy Castle, March 14, 2021
"I use Walser's mowing and weed-eating service, and I'm never going to use any other service. They are always right on time, every two weeks, and my yard is always pristine. I would definitely reccomend this business." -Robert Miller,
April 6, 2021
"My sprinkler system was installed by Walser lawn care. My grass is always well watered and I never have to worry about it turning brown again. One of my kids messed up a sprinkler head playing in the yard, and with my warranty, Walser came and fixed it for free." -William McQueen, September 13, 2020


title=The ServerSide Java Symposium 2010 Recap date=2010-03-20 type=post tags=blog status=published ~~~~~~
I'm in my hotel room thinking about the last 3 days here at The ServerSide Java Symposium. I've had a fantastic time. I gave and/or participated in two talks: one was a talk on jBPM and Spring, the other was participation (representing Spring Integration) in a panel with Jeff Genender (representing ServiceMix) and Ross Mason (representing Mule) on ESBs. I enjoyed that process and enjoyed talking to Jeff and Ross gentlemen to the last. The 400+ people in the audience were invigorating too. Im pretty sure anybody would tell you this year was a welcome, marked improvement over previous years, especially in attendance numbers. It also heralded the introduction of a new editorial lineup, with Cameron Mckenzie taking the lead-editors position. Hes got his work cut out for him, but Im confident hes up to the task.
Rod Johnson gave a "zepo" (zero-powerpoint) Spring / Roo keynote, which was very impressive until it seemed to have failed him at the end. A post mortem revealed that the demo was fine, just a simple error. It was interesting to note that he misplaced his wedding ring and still gave a 99% performance without slides in front of 400+ people! Well done! Spring Roo seemed to garner a lot of attention from the audience and the Twitterati. Matt Raible and James Wards talk on Flex vs. GWT was fun, as expected. Jeff Genender and Keath Hesler both turned in good talks on ServiceMix. Ted Neward and Scott Davis gave their talks to great reception, as usual. Finally, my old friends Reza Rahman, Kito Mann, etc., did very well too. I missed some of the JBoss crowd (Emmanuel Bernard and Dan Allen, notably) this year, however.
It was nice meeting James Gosling, too. Can't help but feel a little in-awe. The final treat was partaking in the festivities, libations, etc., with my colleagues at Shopzilla. Tim Morrow, Senior Architect at Shopzilla, gave a very well received talk about the scale story at Shopzilla.


 I pity your dread and dismay
For not diving into the waters
Of a persons soul
Deeper


Bitwise operators treat their operands as a sequence of 32 bits (zeroes and ones), rather than as decimal, hexadecimal, or octal numbers
. For example, the decimal number nine has a binary representation of 1001. Bitwise operators perform their operations on such binary representations, but they return standard JavaScript numerical values.
The following table summarizes JavaScript's bitwise operators:
The operands of all bitwise operators are converted to signed 32-bit integers in two's complement format. Two's complement format means that a number's negative counterpart (e.g. 5 vs. -5) is all the number's bits inverted (bitwise NOT of the number, a.k.a. ones' complement of the number) plus one. For example, the following encodes the integer 314:
00000000000000000000000100111010
The following encodes ~314
, i.e. the ones' complement of 314
:
11111111111111111111111011000101
Finally, the following encodes -314,
i.e. the two's complement of 314
:
11111111111111111111111011000110
The two's complement guarantees that the left-most bit is 0 when the number is positive and 1 when the number is negative. Thus, it is called the sign bit.
The number 0
is the integer that is composed completely of 0 bits.
0 (base 10) =<PHONE_NUMBER>0000000000000000000000 (base 2)
The number -1
is the integer that is composed completely of 1 bits.
-1 (base 10) =<PHONE_NUMBER>1111111111111111111111 (base 2)
The number -2147483648
(hexadecimal representation: -0x80000000
) is the integer that is composed completely of 0 bits except the first (left-most) one.
-2147483648 (base 10) =<PHONE_NUMBER>0000000000000000000000 (base 2)
The number<PHONE_NUMBER>
(hexadecimal representation: 0x7fffffff
) is the integer that is composed completely of 1 bits except the first (left-most) one.
2147483647 (base 10) =<PHONE_NUMBER>1111111111111111111111 (base 2)
The numbers -2147483648
and<PHONE_NUMBER>
are the minimum and the maximum integers representable through a 32bit signed number.
Conceptually, the bitwise logical operators work as follows:
Performs the AND operation on each pair of bits. a
AND b
yields 1 only if both a
and b
are 1. The truth table for the AND operation is:
. 9 (base 10) =<PHONE_NUMBER>0000000000000000001001 (base 2) 14 (base 10) =<PHONE_NUMBER>0000000000000000001110 (base 2) -------------------------------- 14 & 9 (base 10) =<PHONE_NUMBER>0000000000000000001000 (base 2) = 8 (base 10)
Bitwise ANDing any number x with 0 yields 0. Bitwise ANDing any number x with -1 yields x.
Performs the OR operation on each pair of bits. a
OR b
yields 1 if either a
or b
is 1. The truth table for the OR operation is:
. 9 (base 10) =<PHONE_NUMBER>0000000000000000001001 (base 2) 14 (base 10) =<PHONE_NUMBER>0000000000000000001110 (base 2) -------------------------------- 14 | 9 (base 10) =<PHONE_NUMBER>0000000000000000001111 (base 2) = 15 (base 10)
Bitwise ORing any number x with 0 yields x. Bitwise ORing any number x with -1 yields -1.
Performs the XOR operation on each pair of bits. a
XOR b
yields 1 if a
and b
are different. The truth table for the XOR operation is:
. 9 (base 10) =<PHONE_NUMBER>0000000000000000001001 (base 2) 14 (base 10) =<PHONE_NUMBER>0000000000000000001110 (base 2) -------------------------------- 14 ^ 9 (base 10) =<PHONE_NUMBER>0000000000000000000111 (base 2) = 7 (base 10)
Bitwise XORing any number x with 0 yields x. Bitwise XORing any number x with -1 yields ~x.
Performs the NOT operator on each bit. NOT a
yields the inverted value (a.k.a. one's complement) of a
. The truth table for the NOT operation is:
9 (base 10) =<PHONE_NUMBER>0000000000000000001001 (base 2) -------------------------------- ~9 (base 10) =<PHONE_NUMBER>1111111111111111110110 (base 2) = -10 (base 10)
Bitwise NOTing any number x yields -(x + 1). For example, ~5 yields -6.
Example with indexOf:
var str = 'rawr'; var searchFor = 'a'; // this is alternative way of typing if (-1*str.indexOf('a') <= -1) if (~str.indexOf(searchFor)) { // searchFor is in the string } else { // searchFor is not in the string } // here are the values returned by (~str.indexOf(searchFor)) // r == -1 // a == -2 // w == -3
The bitwise shift operators take two operands: the first is a quantity to be shifted, and the second specifies the number of bit positions by which the first operand is to be shifted. The direction of the shift operation is controlled by the operator used.
Shift operators convert their operands to 32-bit integers in big-endian order and return a result of the same type as the left operand. The right operand should be less than 32, but if not only the low five bits will be used.
This operator shifts the first operand the specified number of bits to the left. Excess bits shifted off to the left are discarded. Zero bits are shifted in from the right.
For example, 9 << 2
yields 36:
. 9 (base 10):<PHONE_NUMBER>0000000000000000001001 (base 2) -------------------------------- 9 << 2 (base 10):<PHONE_NUMBER>0000000000000000100100 (base 2) = 36 (base 10)
Bitwise shifting any number x to the left by y bits yields x * 2^y.
This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Copies of the leftmost bit are shifted in from the left. Since the new leftmost bit has the same value as the previous leftmost bit, the sign bit (the leftmost bit) does not change. Hence the name "sign-propagating".
For example, 9 >> 2
yields 2:
. 9 (base 10):<PHONE_NUMBER>0000000000000000001001 (base 2) -------------------------------- 9 >> 2 (base 10):<PHONE_NUMBER>0000000000000000000010 (base 2) = 2 (base 10)
Likewise, -9 >> 2
yields -3, because the sign is preserved:
. -9 (base 10):<PHONE_NUMBER>1111111111111111110111 (base 2) -------------------------------- -9 >> 2 (base 10):<PHONE_NUMBER>1111111111111111111101 (base 2) = -3 (base 10)
This operator shifts the first operand the specified number of bits to the right. Excess bits shifted off to the right are discarded. Zero bits are shifted in from the left. The sign bit becomes 0, so the result is always non-negative.
For non-negative numbers, zero-fill right shift and sign-propagating right shift yield the same result. For example, 9 >>> 2
yields 2, the same as 9 >> 2
:
. 9 (base 10):<PHONE_NUMBER>0000000000000000001001 (base 2) -------------------------------- 9 >>> 2 (base 10):<PHONE_NUMBER>0000000000000000000010 (base 2) = 2 (base 10)
However, this is not the case for negative numbers. For example, -9 >>> 2
yields<PHONE_NUMBER>, which is different than -9 >> 2
(which yields -3):
. -9 (base 10):<PHONE_NUMBER>1111111111111111110111 (base 2) -------------------------------- -9 >>> 2 (base 10):<PHONE_NUMBER>1111111111111111111101 (base 2) =<PHONE_NUMBER> (base 10)
The bitwise logical operators are often used to create, manipulate, and read sequences of flags, which are like binary variables. Variables could be used instead of these sequences, but binary flags take much less memory (by a factor of 32).
Suppose there are 4 flags:
These flags are represented by a sequence of bits: DCBA. When a flag is set, it has a value of 1. When a flag is cleared, it has a value of 0. Suppose a variable flags
has the binary value 0101:
var flags = 5; // binary 0101
This value indicates:
Since bitwise operators are 32-bit, 0101 is actually<PHONE_NUMBER>0000000000000000000101, but the preceding zeroes can be neglected since they contain no meaningful information.
A bitmask is a sequence of bits that can manipulate and/or read flags. Typically, a "primitive" bitmask for each flag is defined:
var FLAG_A = 1; // 0001 var FLAG_B = 2; // 0010 var FLAG_C = 4; // 0100 var FLAG_D = 8; // 1000
New bitmasks can be created by using the bitwise logical operators on these primitive bitmasks. For example, the bitmask 1011 can be created by ORing FLAG_A, FLAG_B, and FLAG_D:
var mask = FLAG_A | FLAG_B | FLAG_D; // 0001 | 0010 | 1000 => 1011
Individual flag values can be extracted by ANDing them with a bitmask, where each bit with the value of one will "extract" the corresponding flag. The bitmask masks out the non-relevant flags by ANDing with zeroes (hence the term "bitmask"). For example, the bitmask 0101 can be used to see if flag C is set:
// if we own a cat if (flags & FLAG_C) { // 0101 & 0100 => 0100 => true // do stuff }
A bitmask with multiple set flags acts like an "either/or". For example, the following two are equivalent:
// if we own a bat or we own a cat // (0101 & 0010) || (0101 & 0100) => 0000 || 0100 => true if ((flags & FLAG_B) || (flags & FLAG_C)) { // do stuff }
// if we own a bat or cat var mask = FLAG_B | FLAG_C; // 0010 | 0100 => 0110 if (flags & mask) { // 0101 & 0110 => 0100 => true // do stuff }
Flags can be set by ORing them with a bitmask, where each bit with the value one will set the corresponding flag, if that flag isn't already set. For example, the bitmask 1100 can be used to set flags C and D:
// yes, we own a cat and a duck var mask = FLAG_C | FLAG_D; // 0100 | 1000 => 1100 flags |= mask; // 0101 | 1100 => 1101
Flags can be cleared by ANDing them with a bitmask, where each bit with the value zero will clear the corresponding flag, if it isn't already cleared. This bitmask can be created by NOTing primitive bitmasks. For example, the bitmask 1010 can be used to clear flags A and C:
// no, we don't have an ant problem or own a cat var mask = ~(FLAG_A | FLAG_C); // ~0101 => 1010 flags &= mask; // 1101 & 1010 => 1000
The mask could also have been created with ~FLAG_A & ~FLAG_C
(De Morgan's law):
// no, we don't have an ant problem, and we don't own a cat var mask = ~FLAG_A & ~FLAG_C; flags &= mask; // 1101 & 1010 => 1000
Flags can be toggled by XORing them with a bitmask, where each bit with the value one will toggle the corresponding flag. For example, the bitmask 0110 can be used to toggle flags B and C:
// if we didn't have a bat, we have one now, // and if we did have one, bye-bye bat // same thing for cats var mask = FLAG_B | FLAG_C; flags = flags ^ mask; // 1100 ^ 0110 => 1010
Finally, the flags can all be flipped with the NOT operator:
// entering parallel universe... flags = ~flags; // ~1010 => 0101
Convert a binary String
to a decimal Number
:
var sBinString = "1011"; var nMyNumber = parseInt(sBinString, 2); alert(nMyNumber); // prints 11, i.e. 1011
Convert a decimal Number
to a binary String
:
var nMyNumber = 11; var sBinString = nMyNumber.toString(2); alert(sBinString); // prints 1011, i.e. 11
If you have to create many masks from some Boolean
values, you can automatize the process:
function createMask () { var nMask = 0, nFlag = 0, nLen = arguments.length > 32 ? 32 : arguments.length; for (nFlag; nFlag < nLen; nMask |= arguments[nFlag] << nFlag++); return nMask; } var mask1 = createMask(true, true, false, true); // 11, i.e.: 1011 var mask2 = createMask(false, false, true); // 4, i.e.: 0100 var mask3 = createMask(true); // 1, i.e.: 0001 // etc. alert(mask1); // prints 11, i.e.: 1011
If you want to create an Array
of Booleans
from a mask you can use this code:
function arrayFromMask (nMask) { // nMask must be between -2147483648 and<PHONE_NUMBER> if (nMask > 0x7fffffff || nMask < -0x80000000) { throw new TypeError("arrayFromMask - out of range"); } for (var nShifted = nMask, aFromMask = []; nShifted; aFromMask.push(Boolean(nShifted & 1)), nShifted >>>= 1); return aFromMask; } var array1 = arrayFromMask(11); var array2 = arrayFromMask(4); var array3 = arrayFromMask(1); alert("[" + array1.join(", ") + "]"); // prints "[true, true, false, true]", i.e.: 11, i.e.: 1011
You can test both algorithms at the same time…
var nTest = 19; // our custom mask var nResult = createMask.apply(this, arrayFromMask(nTest)); alert(nResult); // 19
For didactic purpose only (since there is the Number.toString(2)
method), we show how it is possible to modify the arrayFromMask
algorithm in order to create a String
containing the binary representation of a Number
, rather than an Array
of Booleans
:
function createBinaryString (nMask) { // nMask must be between -2147483648 and<PHONE_NUMBER> for (var nFlag = 0, nShifted = nMask, sMask = ""; nFlag < 32; nFlag++, sMask += String(nShifted >>> 31), nShifted <<= 1); return sMask; } var string1 = createBinaryString(11); var string2 = createBinaryString(4); var string3 = createBinaryString(1); alert(string1); // prints<PHONE_NUMBER>0000000000000000001011, i.e. 11
Created by Mozilla Contributors, license: CC-BY-SA 2.5


|
Panda3D
|
This is a structure representing a single input device. More...
Classes | |
| class | AxisState |
| class | BatteryData |
| class | ButtonState |
Public Types | |
| enum | Axis { none = 0, x = 1, y = 2, z = 3, yaw = 4, pitch = 5, roll = 6, left_x = 7, left_y = 8, left_trigger = 9, right_x = 10, right_y = 11, right_trigger = 12, throttle = 13, rudder = 14, wheel = 15, accelerator = 16, brake = 17, pressure = 18 } |
| enum | DeviceClass { unknown = 0, virtual_device = 1, keyboard = 2, mouse = 3, touch = 4, gamepad = 5, flight_stick = 6, steering_wheel = 7, dance_pad = 8, hmd = 9, spatial_mouse = 10, digitizer = 11 } |
| enum | Feature { pointer = 0, keyboard = 2, tracker = 2, vibration = 3, battery = 4 } |
| enum | State { S_unknown = 0, S_up = 1, S_down = 2 } |
Public Member Functions | |
| disablePointerEvents () | |
| Disables the generation of mouse-movement events. More... | |
| enablePointerEvents () | |
| Enables the generation of mouse-movement events. More... | |
| InputDevice::AxisState | findAxis (InputDevice::Axis axis) |
| Returns the first AnalogAxis found with the given axis, or throw an assert if the axis was not found in the list. More... | |
| InputDevice::ButtonState | findButton (ButtonHandle handle) |
| Returns the first ButtonState found with the given axis, or throw an assert if the button handle was not found in the list. More... | |
| ButtonEventList | getButtonEvents () |
| Returns the list of recently-generated ButtonEvents. More... | |
| PointerEventList | getPointerEvents () |
| Returns a PointerEventList containing all the recent pointer events. More... | |
| bool | hasButtonEvent () |
| Returns true if this device has a pending button event (a mouse button or keyboard button down/up), false otherwise. More... | |
| bool | hasFeature (InputDevice::Feature feature) |
| Returns true if the device supports the indicated feature. More... | |
| bool | hasPointerEvent () |
| Returns true if this device has a pending pointer event (a mouse movement), or false otherwise. More... | |
| mapAxis (int index, InputDevice::Axis axis) | |
| Associates the indicated Axis with the axis of the indicated index number. More... | |
| mapButton (int index, ButtonHandle handle) | |
| Associates the indicated ButtonHandle with the button of the indicated index number. More... | |
| output (Ostream out) | |
| Writes a one-line string describing the device. More... | |
| poll () | |
| Polls the input device for new activity, to ensure it contains the latest events. More... | |
| setVibration (double strong, double weak) | |
| Sets the strength of the vibration effect, if supported. More... | |
| Public Member Functions inherited from TypedObject | |
| TypeHandle | getType () |
| int | getTypeIndex () |
| Returns the internal index number associated with this object's TypeHandle, a unique number for each different type. More... | |
| bool | isExactType (TypeHandle handle) |
| Returns true if the current object is the indicated type exactly. More... | |
| bool | isOfType (TypeHandle handle) |
| Returns true if the current object is or derives from the indicated type. More... | |
| Public Member Functions inherited from ReferenceCount | |
| int | getRefCount () |
| Returns the current reference count. More... | |
| ref () | |
| Explicitly increments the reference count. More... | |
| bool | testRefCountIntegrity () |
| Does some easy checks to make sure that the reference count isn't completely bogus. More... | |
| bool | testRefCountNonzero () |
| Does some easy checks to make sure that the reference count isn't zero, or completely bogus. More... | |
| bool | unref () |
| Explicitly decrements the reference count. More... | |
Static Public Member Functions | |
| static TypeHandle | getClassType () |
| Static Public Member Functions inherited from TypedReferenceCount | |
| static TypeHandle | getClassType () |
| Static Public Member Functions inherited from TypedObject | |
| static TypeHandle | getClassType () |
| Static Public Member Functions inherited from ReferenceCount | |
| static TypeHandle | getClassType () |
Public Attributes | |
| InputDevice::Axes | _axes |
| InputDevice::BatteryData | _battery_data |
| InputDevice::Buttons | _buttons |
| PointerData | _pointer_data |
| TrackerData | _tracker_data |
| InputDevice::AxisState | axes [] |
| Returns the axis state that is set at the given index, or throw an assert if the index was not found in the list. More... | |
| InputDevice::BatteryData | battery |
| Returns a rough indication of the battery level, ranging from 0 (completely empty battery) to the indicated max_level value. More... | |
| InputDevice::ButtonState | buttons [] |
| Make device buttons and axes iterable. More... | |
| bool | connected |
| This is false if we know that the device is not currently connected. May report false positives if we can't know this with certainty. More... | |
| InputDevice::DeviceClass | device_class |
| This contains an identification of the general type of device. If this could not be determined, it is set to DC_unknown. More... | |
| String | manufacturer |
| The device's manufacturer, or the empty string if not known. More... | |
| String | name |
| The human-readable name of this input device. More... | |
| unsigned short int | product_id |
| USB product ID of the device, or 0 if not known. More... | |
| String | serial_number |
| The device's serial number, or the empty string if not known. More... | |
| TrackerData | tracker |
| Getters for the various types of device data. More... | |
| unsigned short int | vendor_id |
| USB vendor ID of the device, or 0 if not known. More... | |
| Public Attributes inherited from TypedObject | |
| TypeHandle | type |
| Returns the TypeHandle representing this object's type. More... | |
| Public Attributes inherited from ReferenceCount | |
| int | ref_count |
| The current reference count. More... | |
This is a structure representing a single input device.
Input devices may have zero or more buttons, pointers, or axes associated with them, and optionally a motion tracker.
These devices are brought under a common interface because there is such a large range of devices out there that may support any number of these types of axes, we couldn't even begin to cover them with type-specific subclasses.
Use the various has_() and get_num_() methods to determine information about the device capabilities. For instance, has_keyboard() will give an indication that you can receive keystroke events from this device, and get_num_buttons() will tell you that the device may send button events.
There is the DeviceType enumeration, however, which will (if known) contain identification of the general category of devices this fits in, such as keyboard, mouse, gamepad, or flight stick.
| enum Axis |
| enum DeviceClass |
| enum Feature |
| enum State |
| disablePointerEvents | ( | ) |
Disables the generation of mouse-movement events.
| enablePointerEvents | ( | ) |
Enables the generation of mouse-movement events.
| InputDevice::AxisState findAxis | ( | InputDevice::Axis | axis | ) |
Returns the first AnalogAxis found with the given axis, or throw an assert if the axis was not found in the list.
| InputDevice::ButtonState findButton | ( | ButtonHandle | handle | ) |
Returns the first ButtonState found with the given axis, or throw an assert if the button handle was not found in the list.
| ButtonEventList getButtonEvents | ( | ) |
Returns the list of recently-generated ButtonEvents.
The list is also cleared.
|
static |
| PointerEventList getPointerEvents | ( | ) |
Returns a PointerEventList containing all the recent pointer events.
Clears the list.
| bool hasButtonEvent | ( | ) |
Returns true if this device has a pending button event (a mouse button or keyboard button down/up), false otherwise.
If this returns true, the particular event may be extracted via get_button_event().
| bool hasFeature | ( | InputDevice::Feature | feature | ) |
Returns true if the device supports the indicated feature.
| bool hasPointerEvent | ( | ) |
Returns true if this device has a pending pointer event (a mouse movement), or false otherwise.
If this returns true, the particular event may be extracted via get_pointer_event().
| mapAxis | ( | int | index, |
| InputDevice::Axis | axis | ||
| ) |
Associates the indicated Axis with the axis of the indicated index number.
Pass Axis::none to turn off any association.
It is not necessary to call this if you simply want to query the state of the various axes by index number.
| mapButton | ( | int | index, |
| ButtonHandle | handle | ||
| ) |
Associates the indicated ButtonHandle with the button of the indicated index number.
When the given button index changes state, a corresponding ButtonEvent will be generated with the given ButtonHandle. Pass ButtonHandle::none() to turn off any association.
It is not necessary to call this if you simply want to query the state of the various buttons by index number; this is only necessary in order to generate ButtonEvents when the buttons change state.
| output | ( | Ostream | out | ) |
Writes a one-line string describing the device.
| poll | ( | ) |
Polls the input device for new activity, to ensure it contains the latest events.
This will only have any effect for some types of input devices; others may be updated automatically, and this method will be a no-op.
| setVibration | ( | double | strong, |
| double | weak | ||
| ) |
Sets the strength of the vibration effect, if supported.
The values are clamped to 0-1 range. The first value axes the low-frequency rumble motor, whereas the second axes the high-frequency motor, if present.
| InputDevice::Axes _axes |
| InputDevice::BatteryData _battery_data |
| InputDevice::Buttons _buttons |
| PointerData _pointer_data |
| TrackerData _tracker_data |
| InputDevice::AxisState axes[] |
Returns the axis state that is set at the given index, or throw an assert if the index was not found in the list.
| InputDevice::BatteryData battery |
Returns a rough indication of the battery level, ranging from 0 (completely empty battery) to the indicated max_level value.
| InputDevice::ButtonState buttons[] |
Make device buttons and axes iterable.
| bool connected |
This is false if we know that the device is not currently connected. May report false positives if we can't know this with certainty.
| InputDevice::DeviceClass device_class |
This contains an identification of the general type of device. If this could not be determined, it is set to DC_unknown.
| String manufacturer |
The device's manufacturer, or the empty string if not known.
| String name |
The human-readable name of this input device.
| unsigned short int product_id |
USB product ID of the device, or 0 if not known.
| String serial_number |
The device's serial number, or the empty string if not known.
| TrackerData tracker |
Getters for the various types of device data.
| unsigned short int vendor_id |
USB vendor ID of the device, or 0 if not known.


Organizing your model into steps allows you build sequential instructions like Lego’s.
| Activating Step Display | |
| Click the Steps button at the top of the viewing window. Then you can click though each step of your model and watch it build up. |
Sometimes, you may find that you need to show the underside of your model, such as when putting wheels on the bottom of a car chassis. Or perhaps you need to rotate it to see the other side. You can do this with the Step Rotation settings.
There are several different ways to enter a step rotation. Ultimately they all do the same thing: rotate your model. But some types of rotations are easier to accomplish in one mode than in another.
| Step Rotation Modes | ||
| Rotation Type | Best Used For | Description |
|---|---|---|
| None specified | Steps that don’t need to begin a special rotation | Steps with no specified rotation are drawn with the rotation of the previous step, or with the default viewing angle if there was no previous rotation. Most of your model’s steps will use this setting. |
| Relative to default view | Most rotation situations | The step’s viewing angle is computed by starting with the default 3D perspective angle, then adding the value you specify. This setting is ideal for most normal step-rotation operations, such as flipping upside-down or looking at the left or right side of the model. |
| Absolute | Head-on views like Front or Top | Whatever you type in, that’s what the camera angle is. This is perfect for setting a view like Top, but otherwise it should be avoided in favor of Relative rotation. While it may be tempting to use Absolute rotation for everything, your instructions will look better (and more consistent) if you always base your rotation on the default viewing angle like relative mode does. |
| Additive | When you liked the last step’s view and want to tweak it without doing math | Additive rotations accumulate from step to step. Four y=90° additive step rotations would show all four sides of the model in order. In contrast, each Relative rotation starts over with the default view as its base, so they cannot accumulate. |
| End rotations | Restoring the view to its default angle | Cancels the effect of all step rotations and restores the viewing angle to the default 3D Perspective angle. |


类 StdAudio
- java.lang.Object
-
- edu.princeton.cs.algs4.StdAudio
-
public final class StdAudio extends java.lang.Object
Standard audio. This class provides a basic capability for creating, reading, and saving audio.The audio format uses a sampling rate of 44,100 (CD quality audio), 16-bit, monaural.
For additional documentation, see Section 1.5 of Computer Science: An Interdisciplinary Approach by Robert Sedgewick and Kevin Wayne.
-
-
字段概要
字段 修饰符和类型 字段 说明 static int
SAMPLE_RATE
The sample rate - 44,100 Hz for CD quality audio.
-
方法概要
所有方法 静态方法 具体方法 修饰符和类型 方法 说明 static void
close()
Closes standard audio.static void
loop(java.lang.String filename)
Loops an audio file (in .wav, .mid, or .au format) in a background thread.static void
main(java.lang.String[] args)
Test client - play an A major scale to standard audio.static void
play(double sample)
Writes one sample (between -1.0 and +1.0) to standard audio.static void
play(double[] samples)
Writes the array of samples (between -1.0 and +1.0) to standard audio.static void
play(java.lang.String filename)
Plays an audio file (in .wav, .mid, or .au format) in a background thread.static double[]
read(java.lang.String filename)
Reads audio samples from a file (in .wav or .au format) and returns them as a double array with values between -1.0 and +1.0.static void
save(java.lang.String filename, double[] samples)
Saves the double array as an audio file (using .wav or .au format).
-
-
-
字段详细资料
-
SAMPLE_RATE
public static final int SAMPLE_RATE
The sample rate - 44,100 Hz for CD quality audio.- 另请参阅:
- 常量字段值
-
-
方法详细资料
-
close
public static void close()
Closes standard audio.
-
loop
public static void loop(java.lang.String filename)
Loops an audio file (in .wav, .mid, or .au format) in a background thread.- 参数:
filename
- the name of the audio file- 抛出:
java.lang.IllegalArgumentException
- iffilename
isnull
-
main
public static void main(java.lang.String[] args)
Test client - play an A major scale to standard audio.- 参数:
args
- the command-line arguments
-
play
public static void play(double sample)
Writes one sample (between -1.0 and +1.0) to standard audio. If the sample is outside the range, it will be clipped.- 参数:
sample
- the sample to play- 抛出:
java.lang.IllegalArgumentException
- if the sample isDouble.NaN
-
play
public static void play(double[] samples)
Writes the array of samples (between -1.0 and +1.0) to standard audio. If a sample is outside the range, it will be clipped.- 参数:
samples
- the array of samples to play- 抛出:
java.lang.IllegalArgumentException
- if any sample isDouble.NaN
java.lang.IllegalArgumentException
- ifsamples
isnull
-
play
public static void play(java.lang.String filename)
Plays an audio file (in .wav, .mid, or .au format) in a background thread.- 参数:
filename
- the name of the audio file- 抛出:
java.lang.IllegalArgumentException
- if unable to playfilename
java.lang.IllegalArgumentException
- iffilename
isnull
-
read
public static double[] read(java.lang.String filename)
Reads audio samples from a file (in .wav or .au format) and returns them as a double array with values between -1.0 and +1.0.- 参数:
filename
- the name of the audio file- 返回:
- the array of samples
-
save
public static void save(java.lang.String filename, double[] samples)
Saves the double array as an audio file (using .wav or .au format).- 参数:
filename
- the name of the audio filesamples
- the array of samples- 抛出:
java.lang.IllegalArgumentException
- if unable to savefilename
java.lang.IllegalArgumentException
- ifsamples
isnull
-
-


| About Dailyrotten |
|
Feedback
If you like this page, hate it, or would like to suggest changes,
<EMAIL_ADDRESS>is listening. This page
is experimental and somewhat different from what we usually offer, so please
do send your feedback.
Adding Stories
If you are a rotten newshound and you would like to suggest a story,
visit our submit page to
send us the URL. Stories that are accepted will have your name credited.
Posting Comments
In order to post comments to stories, you will have to
create an account.
Accounts will generally be validated within 24 hours, and of
course will be disabled if there is abuse.
Viewership
On the first full day this page went live, 100,000 people visited this Rotten
News page. Of course that was the day after the WTC attacks, so that number is
somewhat distorted. Right now this page gets between 50,000 and 75,000 people
every day.
Linking
We encourage everyone to link to this page; if you like it, others probably
will as well.
Other Rotten
Rotten
Gaping Maw
Celebrity Morgue
Mugshots
Rotten Store
Rate My Poo
Rate My Kitten
Rate My Finger
Penny Postcards
Phallic
Boners
Home
Make Dailyrotten your start page
|
|
|
April 15, 2002
Boy raised by chimps
News Corporation | Submitted by: mark knipe
"When he was first brought in, Bello, who is about the size and weight
of a four-year-old, walked in a chimpanzee-like fashion, moving on his hind
legs but dragging his arms on the ground... Still today he leaps, chimpanzee
like, and claps his hands over his head repeatedly, cupping his hands, as
monkeys do, and does not speak but makes chimpanzee-like noises."
|
|
Read article...
|
|
Fatties have new hope
New Scientist | Submitted by: Polymorf
This isn't from a tabloid, but an established science magazine:
"Scientists have found an enzyme in muscle that, when activated, can
mimic the effects of exercise. The discovery could one day lead to
'exercise in a bottle' pills but this will not be for many years, as the
experiments have so far only been done in mice."
|
|
Read article...
|
|
Girl pimps too young to be charged
Canoe | Submitted by: egoman
"For six months Constable Tim Korchinski and the Saskatoon vice unit heard
stories about an 11-year-old girl running a prostitution ring. The four
person unit spent hours compiling information from tips and other sources.
"This girl was actually successful in doing this through other people," Korchinski said. "She was very manipulative. She was a bit of a bully too..."
|
|
Read article...
|
|
Excessive Reading A Disease
ABC News | Submitted by: f00f
"When Jimmy suddenly started to read as a toddler still in diapers, his parents were shocked. [...] Their dazzling ability to read is in fact a rare syndrome called hyperlexia, which means excessive reading. The illness, which affects mostly boys, is so unusual no one is sure how many kids it affects. It is accompanied by significant delays in language, and an inability to interact normally with others."
|
|
Read article...
|
|
$100,000 speeding ticket
Canoe | Submitted by: anonymous
Anssi Vanjoki drove 46.5 mph in a 30 mph zone and for that, he recieved
a ticket for $103,000 based on his annual income, or $6200 for every mile
over the speed limit. Vanjoki is an executive at Nokia, at a trade fair
he demonstrated their new ringtones: the phone "emits the roar of a
motorbike followed by police sirens."
|
|
Read article...
|
|
Sewage truck explodes
Otago Daily Times | Submitted by: Melisande
"Inner city traffic was showered with effluent [the polite word for
mostly fecal matter] and hydrogen peroxide after the back end of a
septic tank vacuum truck exploded in Dunedin yesterday.
The explosion, which could heard and felt several blocks away, blew
out a window at the nearby Leviathan Hotel and sent a metal sluice valve
flying about 15m into the windscreen of a parked car." Fantastic
picture of the brown aftermath.
|
|
Read article...
|
|
Picture of the day
News of the World | Submitted by: Wessoman
This article isn't all that interesting or unusual. But in the upper right
is a picture of a little girl: "A protestor at an anti-Israeli demo in Berlin
resses his daughter up as a suicide bomber - her tiny body strapped with
sticks of pretend TNT..."
|
|
Read article...
|
|
|
|
|


WITNESS LIST Urban Affairs Committee October 9, 2000-10:00A TX Dept. of Housing & Comm Affairs On: Cedillo, Ruth (TX Dept. of Housing & Community Affairs) Volunteer Fire Fighters For: Ivie Miller, Lisa (State Firemen's & Fire Marshal's Assn. of TX)


trim
(PHP 4, PHP 5, PHP 7)
trim — 去除字符串首尾处的空白字符（或者其他字符）
说明
string trim ( string $str [, string $charlist = " \t\n\r\0\x0B" ] )
此函数返回字符串 str 去除首尾空白字符后的结果。如果不指定第二个参数，trim() 将
去除这些字符：
• " " (ASCII 32 (0x20))，普通空格符。
• "\t" (ASCII 9 (0x09))，制表符。
• "\n" (ASCII 10 (0x0A))，换行符。
• "\r" (ASCII 13 (0x0D))，回车符。
• "\0" (ASCII 0 (0x00))，空字节符。
• "\x0B" (ASCII 11 (0x0B))，垂直制表符。
参数
str
待处理的字符串。
charlist
可选参数，过滤字符也可由 charlist 参数指定。一般要列出所有希望过滤的字符，
也可以使用 “..” 列出一个字符范围。
返回值
过滤后的字符串。
更新日志
版本 说明
4.1.0 新增可选的 charlist 参数。

string(24) "These are a few words :)"
string(5) "o Wor"
string(14) "Example string"
Example #2 使用 trim() 清理数组值
以上例程会输出：
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(7) "banana "
[2]=>
string(11) " cranberry "
}
array(3) {
[0]=>
string(5) "apple"
[1]=>
string(6) "banana"
[2]=>
string(9) "cranberry"
}
注释
Note: Possible gotcha: removing middle characters
Because trim() trims characters from the beginning and end of a string, it
may be confusing when characters are (or are not) removed from the middle.
trim('abc', 'bad') removes both 'a' and 'b' because it trims 'a' thus
moving 'b' to the beginning to also be trimmed. So, this is why it "works"
whereas trim('abc', 'b') seemingly does not.
参见
• ltrim() - 删除字符串开头的空白字符（或其他字符）
• rtrim() - 删除字符串末端的空白字符（或者其他字符）
• str_replace() - 子字符串替换
User Contributed Notes 15 notes
===============================================================================
Non-breaking spaces can be troublesome with trim:
>
// UTF encodes it as chr(0xC2).chr(0xA0)
$converted = trim($converted,chr(0xC2).chr(0xA0)); // should work
// PS: Thanks to John for saving my sanity!
?>
===============================================================================
It may be useful to know that trim() returns an empty string when the argument
is an unset/null variable.
===============================================================================
To remove multiple occurences of whitespace characters in a string an convert
them all into single spaces, use this:
$text = preg_replace('/\s+/', ' ', $text);
?>
------------
JUBI
http://www.jubi.buum.pl
===============================================================================
Another way to trim all the elements of an array
===============================================================================
Trim full width space will return mess character, when target string starts
with '《'
@example
echo trim("《", " ");
@return
�
php version 5.4.27
[EDIT by cmb AT php DOT net: it is not necessarily safe to use trim with
multibyte character encodings. The given example is equivalent to echo trim("\
xe3\80\8a", "\xe3\x80\x80").]
===============================================================================
Just for reference, using trim on a string which only contains blank characters
returns an empty string, not ' '.
i.e. strlen(trim(' ')) is 0
===============================================================================
This function trims regular expressions from strings.
The following example outputs "Hello, world":
===============================================================================
Windows uses two characters for definining newlines, namely ASCII 13 (carriage
return, "\r") and ASCII 10 (line feed, "\n") aka CRLF. So if you have a string
with CRLF's, trim() won't recognize them as being one newline. To solve this
you can use str_replace() to replace the CRLF's with with a space or something.
===============================================================================
To show off the empty positions in a string by means of trim():
";
echo "
".$rightt = strlen(ltrim($string)) - strlen(trim($string))."
empty position(s) from right.";
echo "
".$leftt = strlen(rtrim($string)) - strlen(trim($string))."
empty position(s) from left.
";
$length = strlen($string);
for($x = 0; $x < $length; $x++){
$letter = substr($string, $x, 1);
if($letter <> " ")
echo "
Position $x ===> ".substr(
$string, $x, 1);
else
echo "
Position $x ===> Empty";
}
?>
the output is:
Hello World! Has : 19 letter(s). One by one according to the following:
3 empty position(s) from right.
4 empty position(s) from left.
Position 0 ===> Empty
Position 1 ===> Empty
Position 2 ===> Empty
Position 3 ===> Empty
Position 4 ===> H
Position 5 ===> e
Position 6 ===> l
Position 7 ===> l
Position 8 ===> o
Position 9 ===> Empty
Position 10 ===> W
Position 11 ===> o
Position 12 ===> r
Position 13 ===> l
Position 14 ===> d
Position 15 ===> !
Position 16 ===> Empty
Position 17 ===> Empty
Position 18 ===> Empty
===============================================================================
A simple function to clear extra white spaces along a string.
[EDIT BY danbrown AT php DOT net: Contains a fix provided by (info AT deep-soft
DOT com) to address the issue where "it deletes the first char after spaces
(because of while)."]
===============================================================================
If you want to check whether something ONLY has whitespaces, use the following:
===============================================================================
On my application I had several users submit what to me appeared as "empty
strings", whereas in fact they were submitting the character.
Trim, by default, does not strip this character (Though arguably it should).
The following code strips this character from your input:
Gerard
===============================================================================
You can combine character ranges and individual characters in trim()'s second
argument (ditto for ltrim and rtrim). All of the specified characters and
ranges will be used concurrently (i.e., if a character on either end of the
string matches any of the specified charaters or character ranges, it will be
trimmed). The characters and character ranges can be in any order (except of
course that the character ranges need to be specified in increasing order) and
may overlap.
E.g., trim any nongraphical non-ASCII character:
trim($text,"\x7f..\xff\x0..\x1f");
===============================================================================
I think this is my implementation of trim...
===============================================================================
Trim will generate a warning is you try to trim an empty string if this is a
problem for you can test with is_string