About DrawSprocket
DrawSprocket provides an application interface that lets your game easily access and manipulate system display resources. The features supported by DrawSprocket include the following:
When your game uses DrawSprocket, it becomes the "owner" of the system display resources. All video devices in the system are hidden, and you can freely change pixel depths, color palettes, and screen resolutions at will.
- Display configuration: convenient, optimized selection of display devices and resolution and pixel depth
- Blanking window: a convenient way to hide and show the desktop, menu bar, and other system tools such as the control strip
- Double- or triple-buffered drawing: page flipping when supported by the video hardware or software buffering when page flipping is not available
- Display fading: sophisticated gamma fading capability
- Overlays and underlays: creation of foreground and background images
- Back buffer scaling: support for pixel scaling with optional bilinear interpolation
- Color-table management: easy retrieval and modification of entries in color lookup tables
- Frame skipping: support for evening the frame display rate across your game
- Debugging support: access to the screen and system resources at all times, even when the screen is blanked and faded
Display Configuration
An individual Macintosh computer can simultaneously support more than one monitor, and many monitors can support several different combinations of resolution (horizontal and vertical timing of a display mode) and pixel depth (number of bits per pixel). In DrawSprocket, each combination of resolution and pixel depth is known as a context. At any one time, a given system may allow one or more graphics devices, each with its associated contexts, as well as other characteristics such as color support, hardware acceleration, and display buffering.Your game, on the other hand, has its own display requirements and preferences, and also may want to take advantage of special display features when they are available. An important aspect of DrawSprocket is that it coordinates your game's needs with the currently supported display characteristics and features of the user's system.
The key to this selection system is the context attributes structure, a structure that both your game and DrawSprocket use to pass information to each other. You use certain fields of the context attributes structure to request a context of a given size (width and height, in pixels), pixel depth, color capabilities, and so on. DrawSprocket then finds the closest match to your requests using the
DSPFindBestContext
function. Alternatively, you can use other routines to let the user or the game determine which context to use. Once a context is identified, you refer to it with theDSpContextReference
type.See "Context Attributes Structure" (page 2-27) for descriptions of the structure's fields. See "Choosing a Context" (page 2-12) for examples of its use.
Contexts and the Play State
After you find a context that best suits your needs, you must reserve it before using it. Reserving a context for a display device tells that device to use a particular display depth and resolution. Once a context is reserved, all other contexts for the device become unavailable. When you are finished using a context you release it, making all contexts associated with the display available again.When you reserve a context, its play state is initially inactive. In that play state, the context has no effect on the screen display. However, as soon as you make the play state active, the context's resolution, pixel depth, and other characteristics take effect. At that point, DrawSprocket also covers the entire display with a blanking window, which completely hides the desktop, menu bar, and other system adornments to provide a uniform background color for your game to draw over.
When your game is finished using a display, you can make the context's play state inactive. In that state, DrawSprocket removes the blanking window and restores the user's original display characteristics. See "Play State" (page 2-25) for descriptions of a context's play states.
A context reference is not consistent across executions of your game. This means that every time your game executes you must relocate the best context for your game. DrawSprocket does provide calls to enable you to save a particular context description to disk and then attempt to restore it later. Restoration may fail if the user reconfigured the displays in the system. See the
DSpContext_Flatten
function (page 2-39) for more information.Page Flipping and Software Buffering
During execution your game does all its drawing to a back buffer, an offscreen buffer DrawSprocket draws into while another image buffer is being displayed. DrawSprocket transfers the completed offscreen images to the display in response to aDSpContext_SwapBuffers
call. DrawSprocket supports page flipping, in which the back buffer DrawSprocket provides is a video page located in VRAM that can be displayed by the video controller in rotation with other VRAM pages. Page flipping is a very fast way change an entire graphics display without tearing artifacts, because the game only needs to tell the video controller to begin displaying the new page--the actual page data (which can be very large) does not need to be copied.If page flipping is not available, or you have told DrawSprocket that you prefer not to use page flipping, the back buffer is located in DRAM. When the game tells DrawSprocket to make the buffer visible to the user, DrawSprocket copies it using a highly optimized blitter that is customized to your game's needs.
For both page flipping and software buffering, you can tell DrawSprocket to use double buffering or triple buffering during the execution of your game. With double buffering you have two buffers--one that is displayed and one that is hidden (used for rendering). With triple buffering you have three buffers--one that is displayed, and two that are hidden. Requests for page flipping and double or triple buffering are made in the context attributes structure passed in when you reserve a context for play.
How Triple Buffering Works
When the game is using double buffering and tells DrawSprocket to make the back buffer visible, you may want the game to begin drawing the next frame right away. If the game is fast enough, it could even be rendering while DrawSprocket is moving the back buffer to the display. But when DrawSprocket is drawing to the display, the back buffer is busy, so the game has to wait, wasting precious CPU cycles. You can request that, if DrawSprocket detects this occurring, it will throw another buffer into the available buffer queue, so that the game may begin rendering into it while the first back buffer is in use. This is called triple buffering.The flip side of triple buffering is that the game may retrieve a back buffer (buffer #1), tell DrawSprocket to show it, retrieve a new back buffer (buffer #2), and then tell DrawSprocket to show buffer #2 before buffer #1 has been displayed. In this case, the game is rendering too fast for its own good and can introduce video lag. DrawSprocket can detect such a situation and will queue the buffer swap and drop the game back to double buffering. The next time the game retrieves the back buffer, all the buffers may be busy and the call may block (avoid blocking by using
DSpContext_IsBusy
before retrieving the back buffer).A possible scenario is a game riding the edge between the need for double and triple buffering, which causes DrawSprocket to alternate between the two buffering methods. There is no performance penalty for this condition, and the transitions will not affect game performance. The net effect is that the game will always be triple buffered, because it will always be using the next available back buffer.
A side effect of running your game faster than the achievable display frame rate (and hence, faster than can be triple buffered) is that your game will always run two frames behind what the user sees. Consider what happens when you have two buffers queued for a display swap: a frame is currently visible on the display, the first queued buffer will be displayed at the next (first) VBL, and the second queued buffer will be displayed at the second VBL.
Gamma Fading
When a monitor switches resolution modes, there is typically a visible flash or flicker that can be annoying to the user. When your game starts it usually switches resolution modes, and when it quits it switches back. Depending on its features, your game might also switch modes during execution.To hide the flicker, you can fade the display to black, make the switch, and then bring the display back to full intensity. A typical procedure for fading out is called indexed fading, in which you repeatedly draw the screen with all colors at proportionally lesser and lesser RGB intensities, reaching zero intensity over the course of a second or so. You then wait about half a second for the mode switch to take effect on the monitor, and fade the intensity back in.
DrawSprocket provides a facility to achieve a superior, more convenient, and more flexible fading process. Using the DrawSprocket functions, you can fade out one or all displays in the system and achieve a variety of interesting effects at the same time. The three functions--
DSpContext_FadeGamma
,DSpContext_FadeGammaIn
, andDSpContext_FadeGammaOut
--perform a gamma fade. A gamma fade is a fade based on a gamma table, which accounts for nonlinearities in the display's color response. With a gamma fade, bright colors won't remain visible after the darker colors have already disappeared, as can happen with indexed fading.Because of its flexibility, you might want to use DrawSprocket's gamma fading for other transitions besides switches in resolution mode. The DrawSprocket gamma fade functions provides these advantages:
See the description of the
- You can fade direct devices as well as indexed devices.
- You can fade all the graphics devices in your system at once, or one at a time.
- When fading out, you don't have to fade to black. You can define any RGB color as the "zero intensity" color.
- You can overdrive the gamma table by specifying an intensity greater than 100 percent. This feature is good for those blinding flashes that occur when a rocket detonates in the player's face.
- You can automatically fade smoothly and gradually to zero intensity with a single call to
DSpContext_FadeGammaOut
, and fade smoothly back in with a second call toDSpContext_FadeGammaIn
.- For more direct control over the fading process, you can make repeated calls to
DSpContext_FadeGamma
and manually control the amount of fade for each step.- By combining manual control with manipulation of the zero-intensity color, you can achieve special effects. For example, you could fade halfway to red and then the rest of the way to black.
DSpContext_FadeGamma
function (page 2-45) for more information.Underlays, Overlays, and Transparency Masks
An underlay is an image that is used as a background for the back buffer and is restored automatically whenever the back buffer is returned fromDSpContext_GetBackBuffer
. Typically, you use an underlay where you have a static background (or a background that may stay static for at least a few frames), such as in a sprite-based game, or in a scroller game where the background only moves when the player crosses a threshold near the edge of the screen.An overlay is an image that is superimposed on the back buffer before it is displayed. This occurs during the call to
DSpContext_SwapBuffers
. You can use an overlay as a control panel type of image, such as that of an airplane cockpit or a radar screen, or decorative scenery such as a border around the active playing area. An overlay must have transparent areas, known as a transparency mask, in order for the back buffer to show through. For more information on how underlays and overlays work see "Creating Underlays and Overlays" (page 2-16).Pixel Scaling
Your game may scale the back buffer. With scaling, the resolution of the underlay, overlay, and display all remain the same, but the area of the back buffer that is used is reduced. For example, with a 2x scaling factor, DrawSprocket uses only the upper-left quadrant of the back buffer when it composites the image and displays it. However, that quadrant is doubled horizontally and vertically to fill the entire display.You have the option of using bilinear interpolation with pixel scaling. Bilinear interpolation averages the pixels and determines a pixel value that falls between the two original pixels. This results in smoother images, but as scaling is increased images begin to look out of focus (but at least they won't look chunky). For each scaling factor that DrawSprocket provides, there is an identical factor with bilinear interpolation enabled. For more information see "Pixel Scaling" (page 2-25) and the DSpContext_SetScale function on (page 2-58).
Other Features
DrawSprocket allows you set a maximum frame-refresh rate for your game, so that it will not appear to run at uneven speeds, slowing down in portions that require complex rendering and speeding up during simpler drawing. By using theDSpContext_SetMaxFrameRate
function (page 2-55), you can give yourself enough time to render each frame before the screen is refreshed.You can easily manipulate the colors in a color lookup table with a DrawSprocket convenience function. See the DSpContext_SetCLUTEntries function (page 2-70) for more information.
Finally, DrawSprocket provides two utility functions. The special function
DSpSetDebugMode
(page 2-73) helps you when debugging. When you use this function, the display screen and system resources remain visible at all times, even behind the blanking window and even if your code has performed a fade to zero intensity. This feature exists to give you access to the debugger screen at all times. TheDSpContext_SetVBLProc
function (page 2-74) allows you to piggyback your own VBL tasks to a particular context.Video Driver Support
DrawSprocket never communicates directly with the Macintosh video hardware. Instead, it relies on standard Macintosh video drivers to provide access to any special hardware features. Video drivers that do not currently support page flipping must be revised so that video games that use DrawSprocket can have access to this capability when it is present in the hardware.The Apple Computer video drivers are being revised, and third-party card and driver developers are strongly encouraged to follow suit. Documentation on how driver developers can best support DrawSprocket is in preparation.
If you are developing a driver to work with DrawSprocket, make sure that, if your video hardware does not support a feature, your driver does not emulate that feature in software. DrawSprocket itself provides highly optimized emulations of hardware capabilities. For example, if page-flipping is not supported by the hardware, your video driver should not attempt to simulate it. If page-flipping is not present, DrawSprocket manages the transition of the background page to the display in as efficient a manner as possible, and the game need not be aware of how the transition occurs.