home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection 1998 Fall: Game Toolkit / Disc.iso / Samples / SprocketExamples / SprocketInvaders / Source / Graphics.c < prev    next >
Encoding:
Text File  |  1998-07-14  |  10.8 KB  |  405 lines  |  [TEXT/CWIE]

  1. //•    ------------------------------------------------------------------------------------------    •
  2. //•
  3. //•    Copyright © 1996 Apple Computer, Inc., All Rights Reserved
  4. //•
  5. //•
  6. //•        You may incorporate this sample code into your applications without
  7. //•        restriction, though the sample code has been provided "AS IS" and the
  8. //•        responsibility for its operation is 100% yours.  However, what you are
  9. //•        not permitted to do is to redistribute the source as "DSC Sample Code"
  10. //•        after having made changes. If you're going to re-distribute the source,
  11. //•        we require that you make it clear in the source that the code was
  12. //•        descended from Apple Sample Code, but that you've made changes.
  13. //•
  14. //•        Authors:
  15. //•            Chris De Salvo
  16. //•
  17. //•    ------------------------------------------------------------------------------------------    •
  18.  
  19. //•    ------------------------------    Includes
  20.  
  21. #include <Types.h>
  22. #include <Resources.h>
  23.  
  24. #include <string.h>
  25.  
  26. #include "DrawSprocket.h"
  27. #include "ErrorHandler.h"
  28. #include "Graphics.h"
  29. #include "MemoryHandler.h"
  30. #include "SIResources.h"
  31. #include "Sprite.h"
  32.  
  33. //•    ------------------------------    Private Definitions
  34.  
  35. #define kFirstIconColor                1
  36. #define kLastIconColor                33
  37.  
  38. #define kFirstBGColor                34
  39. #define kLastBGColor                183
  40.  
  41. #define kFirstSpriteColor            184
  42. #define kLastSpriteColor            254
  43.  
  44. //•    ------------------------------    Private Types
  45. //•    ------------------------------    Private Variables
  46.  
  47. static DSpAltBufferReference        gUnderlay;
  48. static CTabHandle                    gGameCLUT;
  49.  
  50. //•    ------------------------------    Private Functions
  51.  
  52. static void GraphicsUpdateScreenPalette(UInt16 inFirstColor, UInt16 inLastColor);
  53. static void GraphicsCreateUnderlay(void);
  54. static void GraphicsSelectContext(SInt16 modifiers);
  55. static void GraphicsInitAttributes(DSpContextAttributes *inAttributes);
  56.  
  57. //•    ------------------------------    Public Variables
  58.  
  59. DSpContextReference        gDisplayContext;
  60. DSpContextAttributes    gDisplayAttributes;
  61. GDHandle                gGameGDH;
  62.  
  63. const RGBColor    rgbBlack    = { 0x0000, 0x0000, 0x0000 };
  64. const RGBColor    rgbWhite    = { 0xFFFF, 0xFFFF, 0xFFFF };
  65. const RGBColor    rgbRed        = { 0xFFFF, 0x0000, 0x0000 };
  66. const RGBColor    rgbBlue        = { 0x0000, 0x0000, 0xFFFF };
  67. const RGBColor    rgbYellow    = { 0xFFFF, 0xFFFF, 0x0000 };
  68. const RGBColor    rgbGreen    = { 0x0000, 0xFFFF, 0x0000 };
  69.  
  70. #pragma mark —————  Startup/Shutdown  —————
  71.  
  72. //•    --------------------    GraphicsInit
  73.  
  74. void
  75. GraphicsInit(SInt16 modifiers)
  76. {
  77. CGrafPtr    backBuffer;
  78. OSErr        theErr;
  79. Rect        r = { 40, 40, 100, 100 };
  80.  
  81.     theErr = DSpStartup();
  82.     if (theErr)
  83.         FatalError("GraphicsInit: DSpStartup() failed!!!!");
  84.  
  85.     //•    CLUT 8 is the standard 8-bit color system color table and is
  86.     //•    always present
  87.     gGameCLUT = GetCTable(8);
  88.     DetachResource((Handle) gGameCLUT);
  89.     
  90.     //•    Define and create our drawing context
  91.     GraphicsSelectContext(modifiers);
  92.  
  93.     //•    Add our various colors to the color table
  94.     GraphicsMergeCLUT(128, kFirstIconColor, kLastIconColor);
  95.     GraphicsMergeCLUT(kPICTGasCloud, kFirstBGColor, kLastBGColor);
  96.     GraphicsMergeCLUT(kCLUTSprites, kFirstSpriteColor, kLastSpriteColor);
  97.  
  98.     //•    Create our underlay and load a picture into it
  99.     GraphicsCreateUnderlay();
  100.     GraphicsLoadBackground(kPICTGasCloud);
  101.  
  102.     //•    Swap the buffers once to get the underlay image on the screen
  103.     DSpContext_GetBackBuffer(gDisplayContext, kDSpBufferKind_Normal, &backBuffer);
  104.     DSpContext_InvalBackBufferRect(gDisplayContext, &backBuffer->portRect);
  105.     GraphicsUpdateScreen();
  106.  
  107.     //•    Fade up from black and then put the context in the paused state
  108.     //•    so that the user has access to the menu bar.
  109.     DSpContext_FadeGammaIn(nil, nil);
  110.     GraphicsPaused();
  111. }
  112.  
  113. //•    --------------------    GraphicsReset
  114.  
  115. void
  116. GraphicsReset(void)
  117. {
  118.     DSpContext_FadeGammaOut(nil, nil);
  119.     GraphicsInactive();
  120.     DSpContext_FadeGammaIn(nil, nil);
  121.  
  122.     DSpContext_Release(gDisplayContext);
  123.     DSpShutdown();
  124. }
  125.  
  126. #pragma mark —————  Context Management  —————
  127.  
  128. //•    --------------------    GraphicsSelectContext
  129.  
  130. static void
  131. GraphicsSelectContext(SInt16 modifiers)
  132. {
  133. OSStatus        theError;
  134. DisplayIDType    displayID;
  135.     
  136.     //•    Initialize our context description
  137.     GraphicsInitAttributes(&gDisplayAttributes);
  138.  
  139.     //•    Tell DrawSprocket the exact needs we have for our game
  140.     gDisplayAttributes.displayWidth            = 640;
  141.     gDisplayAttributes.displayHeight        = 480;
  142.     gDisplayAttributes.colorNeeds            = kDSpColorNeeds_Require;
  143.     gDisplayAttributes.backBufferDepthMask    = kDSpDepthMask_8;
  144.     gDisplayAttributes.displayDepthMask        = kDSpDepthMask_8;
  145.     gDisplayAttributes.backBufferBestDepth    = 8;
  146.     gDisplayAttributes.displayBestDepth        = 8;
  147.     gDisplayAttributes.pageCount            = 2;
  148.     gDisplayAttributes.colorTable            = gGameCLUT;
  149.  
  150.     //•    Find the best context for these attributes
  151.     //•    This call will check to see if multiple monitors can handle the request
  152.     //•    If there is more than one valid device it will put up the selection interface
  153.     theError = DSpUserSelectContext(&gDisplayAttributes, 0L, nil, &gDisplayContext);
  154.  
  155.     if (theError)
  156.         FatalError("A suitable display context could not be found.");
  157.  
  158.     if (modifiers & optionKey)
  159.         gDisplayAttributes.contextOptions |= kDSpContextOption_DontSyncVBL;
  160.  
  161. //    gDisplayAttributes.contextOptions |= kDSpContextOption_PageFlip;
  162.  
  163.     //•    Set the blanking color to black
  164.     DSpSetBlankingColor(&rgbBlack);
  165.  
  166.     //•    Find the DisplayID for this draw context and then find the GDevice
  167.     //•    that goes along with it.  We need this because if we need to perform
  168.     //•    QuickDraw operations in a context that isn't on the main monitor then
  169.     //•    we need to have the proper GDevice set or QuickDraw loses its mind.
  170.     theError =  DSpContext_GetDisplayID(gDisplayContext, &displayID);
  171.     if (theError)
  172.         FatalError("DSpContext_GetDisplayID() had an error.");
  173.  
  174.     theError = DMGetGDeviceByDisplayID(displayID, &gGameGDH, false);
  175.     if (theError)
  176.         FatalError("DMGetGDeviceByDisplayID() had an error.");
  177.  
  178.     //•    Reserve the draw context so that we get the attributes we want
  179.     theError = DSpContext_Reserve(gDisplayContext, &gDisplayAttributes);
  180.     if (theError)
  181.         FatalError("Could not reserve display context.");
  182.  
  183.     //•    Fade the screen to black and make our context active
  184.     DSpContext_FadeGammaOut(nil, nil);
  185.     GraphicsActive();
  186. }
  187.  
  188. //•    --------------------    GraphicsInitAttributes
  189.  
  190. static void
  191. GraphicsInitAttributes(DSpContextAttributes *inAttributes)
  192. {
  193.     if (! inAttributes)
  194.         FatalError("Nil context passed to MyInitAttributes().");
  195.  
  196.     memset(inAttributes, 0, sizeof (DSpContextAttributes));
  197. }
  198.  
  199. //•    --------------------    GraphicaCreateUnderlay
  200.  
  201. static void
  202. GraphicsCreateUnderlay(void)
  203. {
  204. OSStatus    theError;
  205.  
  206.     //•    Create a new alt buffer which mimics the onscreen display
  207.     theError = DSpAltBuffer_New(gDisplayContext, true, 0L, &gUnderlay);
  208.     if (theError)
  209.         FatalError("Could not create underlay buffer.");
  210.         
  211.     //•    Make it the active underlay
  212.     theError = DSpContext_SetUnderlayAltBuffer(gDisplayContext, gUnderlay);
  213.     if (theError)
  214.         FatalError("Could not set underlay buffer.");
  215. }
  216.  
  217. //•    --------------------    GraphicsGetUnderlayGrafPort
  218.  
  219. void
  220. GraphicsGetUnderlayGrafPort(CGrafPtr *underlay, GDHandle *device)
  221. {
  222.     DSpAltBuffer_GetCGrafPtr(gUnderlay, kDSpBufferKind_Normal, underlay, device);
  223. }
  224.  
  225. #pragma mark —————  Image Management  —————
  226.  
  227. //•    --------------------    GraphicsLoadBackground
  228.  
  229. void
  230. GraphicsLoadBackground(SInt16 whichBG)
  231. {
  232. GrafPtr        oldPort;
  233. GDHandle    oldDevice;
  234. GDHandle    underlayDevice;
  235. PicHandle    thePict;
  236. CGrafPtr    backBuff;
  237. Rect        r;
  238.  
  239.     thePict = GetPicture(whichBG);
  240.     if (! thePict)
  241.         FatalError("Could not load background.");
  242.  
  243.     //•    Get a CGrafPtr reference to the underlay graphics buffer
  244.     DSpAltBuffer_GetCGrafPtr(gUnderlay, kDSpBufferKind_Normal, &backBuff, &underlayDevice);
  245.     
  246.     GetPort(&oldPort);
  247.     oldDevice = GetGDevice();
  248.     
  249.     SetPort((GrafPtr) backBuff);
  250.     SetGDevice(underlayDevice);
  251.  
  252.     RGBForeColor(&rgbBlack);
  253.     RGBBackColor(&rgbWhite);
  254.     
  255.     //•    Fill the background with black
  256.     PaintRect(&backBuff->portRect);
  257.  
  258.     HLock((Handle) thePict);
  259.  
  260.     SetRect(&r, 0, 0, 640, 440);
  261.     DrawPicture(thePict, &r);
  262.     KillPictureZ(&thePict);
  263.  
  264.     //•    Invalidate the entire underlay so that all other back buffers
  265.     //•    get the new image copied up to them.
  266.     DSpAltBuffer_InvalRect(gUnderlay, &backBuff->portRect);
  267.  
  268.     SetPort(oldPort);
  269.     SetGDevice(oldDevice);
  270. }
  271.  
  272. //•    --------------------    GraphicsMergeCLUT
  273.  
  274. void
  275. GraphicsMergeCLUT(SInt16 clutID, UInt16 firstColor, UInt16 lastColor)
  276. {
  277. CTabHandle    ct;
  278. UInt32        i;
  279.  
  280.      //•    Load the appropritate 'CLUT' resource
  281.      ct = GetCTable(clutID);
  282.     if (! ct)
  283.         FatalError("Could not load color table for merge.");
  284.         
  285.     HLock((Handle) ct);
  286.     
  287.     //•    Copy colors from it to our game color table
  288.     for (i = firstColor; i <= lastColor; i++)
  289.     {
  290.         (**gGameCLUT).ctTable[i].rgb.red = (**ct).ctTable[i].rgb.red;
  291.         (**gGameCLUT).ctTable[i].rgb.green = (**ct).ctTable[i].rgb.green;
  292.         (**gGameCLUT).ctTable[i].rgb.blue = (**ct).ctTable[i].rgb.blue;
  293.     }
  294.     
  295.     HUnlock((Handle) ct);
  296.     ReleaseResource((Handle) ct);
  297.  
  298.     //•    Make the new game color table the active color environment
  299.     GraphicsUpdateScreenPalette(firstColor, lastColor);
  300. }
  301.  
  302. //•    --------------------    GraphicsUpdateScreenPalette
  303.  
  304. static void
  305. GraphicsUpdateScreenPalette(UInt16 inFirstColor, UInt16 inLastColor)
  306. {
  307. OSStatus    theError;
  308.     
  309.     //•    Copy our game color table to our DrawSprocket context.  This also
  310.     //•    updates the color environment of any buffers that we've allocated with
  311.     //•    DrawSprocket.
  312.     theError = DSpContext_SetCLUTEntries(gDisplayContext, (**gGameCLUT).ctTable, inFirstColor, inLastColor - inFirstColor);
  313.     if( theError )
  314.         DebugStr("\p error from CLUT ");
  315. }
  316.  
  317. //•    --------------------    GraphicsSetRectDirty
  318.  
  319. void
  320. GraphicsSetRectDirty(RectPtr r)
  321. {
  322.     DSpContext_InvalBackBufferRect(gDisplayContext, r);
  323. }
  324.  
  325. //•    --------------------    GraphicsSetUnderlayRectDirty
  326.  
  327. void
  328. GraphicsSetUnderlayRectDirty(RectPtr r)
  329. {
  330.     DSpAltBuffer_InvalRect(gUnderlay, r);
  331. }
  332.  
  333. //•    --------------------    GraphicsUpdateScreen
  334.  
  335. void
  336. GraphicsUpdateScreen(void)
  337. {
  338.     DSpContext_SwapBuffers(gDisplayContext, nil, nil);
  339. }
  340.  
  341. #pragma mark —————  Context State  —————
  342.  
  343. //•    --------------------    GraphicsActive
  344.  
  345. void
  346. GraphicsActive(void)
  347. {
  348. OSStatus    theErr;
  349.  
  350.     HideCursor();
  351.  
  352.     theErr = DSpContext_SetState(gDisplayContext, kDSpContextState_Active);
  353.     if (theErr)
  354.         DebugStr("\pSetState active failed in GraphicsActive().");
  355. }
  356.  
  357. //•    --------------------    GraphicsPaused
  358.  
  359. void
  360. GraphicsPaused(void)
  361. {
  362.     DSpContext_SetState(gDisplayContext, kDSpContextState_Paused);
  363.     ShowCursor();
  364.     DrawMenuBar();
  365. }
  366.  
  367. //•    --------------------    GraphicsInactive
  368.  
  369. void
  370. GraphicsInactive(void)
  371. {
  372.     DSpContext_SetState(gDisplayContext, kDSpContextState_Inactive);
  373.     ShowCursor();
  374. }
  375.  
  376. //•    --------------------    GraphicsDoUpdateEvent
  377.  
  378. void
  379. GraphicsDoUpdateEvent(void)
  380. {
  381. GrafPtr        savePort;
  382. GDHandle    saveGDH;
  383.  
  384. CGrafPtr    backBuffer;
  385. CGrafPtr    frontBuffer;
  386.  
  387.     DSpContext_GetFrontBuffer(gDisplayContext, &frontBuffer);
  388.     DSpContext_GetBackBuffer(gDisplayContext, kDSpBufferKind_Normal, &backBuffer);
  389.  
  390.     GetPort(&savePort);
  391.     saveGDH = GetGDevice();
  392.     
  393.     SetPort((GrafPtr) frontBuffer);
  394.     SetGDevice(gGameGDH);
  395.  
  396.     ForeColor(blackColor);
  397.     BackColor(whiteColor);
  398.  
  399.     CopyBits((BitMapPtr) *backBuffer->portPixMap, (BitMapPtr) *frontBuffer->portPixMap,
  400.         &backBuffer->portRect, &frontBuffer->portRect, srcCopy, nil);
  401.  
  402.     SetPort(savePort);
  403.     SetGDevice(saveGDH);
  404. }
  405.