home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / C++ / Snippets / Pict File Reader 1.0 / Main.c++ next >
Encoding:
C/C++ Source or Header  |  1993-12-31  |  7.6 KB  |  224 lines  |  [TEXT/KAHL]

  1.  
  2. // PROGRAM: Pict File Reader Demo
  3. // VERSION: 1.0
  4. // AUTHOR : Hiep Dam, 3G Software
  5. // STATUS : Public domain, may be freely distributed
  6. // DATE   : December 28, 1993
  7.  
  8. // -------------------------------------------------------------------
  9.  
  10. // PURPOSE:
  11. // This is a very simple program that demonstrates how to draw a picture
  12. // from a picture data file. Most of the time, you would usually just read
  13. // in a picture as a "PICT" resource in a file's resource fork, via
  14. // _GetResource('PICT', picID).
  15.  
  16. // However, there may be a time when you would want to read in a picture
  17. // from a pict file. It's relatively easy and hassle-free to do so, BUT
  18. // it's not obvious at first. There are some small little points here and
  19. // there when reading in a pict file (such as it's header data).
  20.  
  21. // I didn't know how to do this at first, but after a little rummaging around
  22. // I found an article in a *very* old issue of MacTutor describing Pict files
  23. // and such. This was where I discovered how to read in pict files correctly.
  24. // If you're interested, the reference is:
  25. // Joel West, "Comments About Picts", MacTutor June 1988 Vol 4, No 6
  26. // (See, I told you it was an old article...)
  27.  
  28. // This code should be System 6.0.x and System 7.x compatible, though I
  29. // wrote it on System 7.1 and haven't tested it anywhere else.
  30. // This code was written in Symantec C++ 6.0 (wonderful!), but you
  31. // should be able to modify it to work with THINK C 6.0.
  32.  
  33. // Hope you find this code useful. Drop me a line anytime—I design games
  34. // in my spare time, if you're interested.
  35. // America Online:    StarLabs
  36. // Snail-mail:        Hiep Dam
  37. //                    2226 Parkside Ave #302
  38. //                    Los Angeles,  CA  90031
  39.  
  40. // Enjoy!
  41.  
  42.  
  43. // -------------------------------------------------------------------
  44. // -------------------------------------------------------------------
  45.  
  46. // A cheap inline that just waits for the user to click the mouse...
  47. inline void WaitMousey() { while (!Button()) {} }
  48.  
  49. // -------------------------------------------------------------------
  50.  
  51. // Some prototypes...
  52. PicHandle GetPictFile(Rect& picRect);
  53. void CenterRect(Rect& insideR, const Rect& outsideR);
  54.  
  55. // -------------------------------------------------------------------
  56.  
  57. void main() {
  58.     // Doo dah, initialize the program. Too bad there isn't an option
  59.     // in Symantec C++ to automatically intialize the ToolBox upon
  60.     // startup, much like Think Pascal 4.0 (are they ever going to
  61.     // upgrade that program?!?)
  62.     InitGraf(&thePort);
  63.     InitFonts();
  64.     FlushEvents(everyEvent,0);
  65.     InitWindows();
  66.     InitMenus();
  67.     TEInit();
  68.     InitDialogs(0L);
  69.     InitCursor();
  70.  
  71.     // -----------------------------------
  72.     
  73.     WindowPtr bkgndWind = NewWindow(nil, &screenBits.bounds, nil, true, plainDBox, (WindowPtr)-1, false, 0);
  74.     Rect picR;
  75.     PicHandle thePic;
  76.     do {
  77.         // Get rid of that distracting desktop!!
  78.         SetPort(bkgndWind);
  79.         FillRect(&screenBits.bounds, gray);
  80.  
  81.         // Call the actual function that reads in the pict file...
  82.         thePic = GetPictFile(picR);
  83.         if (thePic == nil) {
  84.             // The function returns nil either if the file was too large
  85.             // and it was unable to allocate enough heap space to read in
  86.             // the file, OR the user clicked "Cancel" in the SFGetFile dialog.
  87.             // So exit either way...
  88.             ExitToShell();
  89.         }
  90.  
  91.         // Okay, pict file was successfully read in, so center
  92.         // the picture on the screen...
  93.         CenterRect(picR, screenBits.bounds);
  94.         
  95.         // Get rid of that distracting desktop!!
  96.         SetPort(bkgndWind);
  97.         FillRect(&screenBits.bounds, gray);
  98.  
  99.         // Create our window to hold the picture...
  100.         WindowPtr mainWindow = NewWindow(nil, &picR, nil, true, plainDBox, (WindowPtr)-1, false, 0);
  101.         SetPort(mainWindow);
  102.         
  103.         // Get the picture's frame rect
  104.         picR = (**thePic).picFrame;
  105.         // Alright, draw it!
  106.         DrawPicture(thePic, &picR);
  107.  
  108.         // Dispose of our picture (since GetPictFile created a handle
  109.         // from which to load in the pict file data)
  110.         DisposeHandle(Handle(thePic));
  111.         
  112.         // Allow the user to look at the picture, and wait until
  113.         // they click the mouse...
  114.         WaitMousey();
  115.         
  116.         // Get rid of the window...
  117.         DisposeWindow(mainWindow);
  118.         
  119.         // Flush everything, so mouse click doesn't register
  120.         FlushEvents(everyEvent, 0);
  121.     } while (1);    // Loop forever, admittedly a lazy programming technique!  :)
  122. }
  123.  
  124. // -------------------------------------------------------------------
  125.  
  126. void CenterRect(Rect& insideR, const Rect& outsideR) {
  127.     // Basically just centers the rect insideR within rect outsideR.
  128.     short insideWidth = insideR.right - insideR.left;
  129.     short insideHeight = insideR.bottom - insideR.top;
  130.     short hDiff = ((outsideR.right - outsideR.left) - (insideWidth))/2;
  131.     short vDiff = ((outsideR.bottom - outsideR.top) - (insideHeight))/2;
  132.     insideR.left = outsideR.left + hDiff;
  133.     insideR.right = insideR.left + insideWidth;
  134.     insideR.top = outsideR.top + vDiff;
  135.     insideR.bottom = insideR.top + insideHeight;
  136. } // END CenterRect
  137.  
  138. // -------------------------------------------------------------------
  139.  
  140. // Alright, this is where the action is!
  141. // GetPictFile loads in a user-specified PICT file and returns the data
  142. // in that file as a standard PicHandle picture. It's the same as any
  143. // picture: you can _DrawPicture it, etc.
  144.  
  145. // A PICT file is identical to a pict resource except that it lies in the
  146. // data fork of a file. There's one additional difference: the first
  147. // 512 bytes of the file contains "header" data; we don't need the header,
  148. // so the header is skipped over. I wouldn't call this information common
  149. // knowledge (hey, I didn't know about it, either!)
  150.  
  151. // Note that this function reads in the pict file in one single gulp; there
  152. // could be problems if the user specifies a really BIG pict file and there
  153. // isn't enough memory (in which case the function beeps and returns nil).
  154.  
  155. PicHandle GetPictFile(Rect& picRect) {
  156.     const short kPictHeaderSize = 512;    // Size of header, in bytes
  157.  
  158.     PicHandle thePic = nil;        // Handle to a picture (which we're going to load in)
  159.     long pictFileLen;            // Length of the pict file
  160.     short pictFileRef;            // File reference of the pict file
  161.     SFReply    tr;
  162.     short rc;                    // Error return code
  163.     Point where;
  164.     where.h=100; where.v=50;
  165.     SFTypeList typeList;
  166.     typeList[0] = 'PICT';        // Only load in "PICT" files...
  167.  
  168.  
  169.     SFGetFile(where, "\pSelect a PICT file:", nil, 1, typeList, nil, &tr);
  170.     if (tr.good) {
  171.         // User selected a file, now open the file with _FSOpen
  172.         rc = FSOpen(tr.fName, tr.vRefNum, &pictFileRef);
  173.         if (rc) {
  174.             // Hmm. File Manager had problems opening this file.
  175.             SysBeep(1);
  176.             return(nil);
  177.         }
  178.  
  179.         // Now get size of pict file
  180.         rc = GetEOF(pictFileRef, &pictFileLen);
  181.  
  182.         // This is the non-obvious part: skip over the first 512
  183.         // bytes of the pict file, since this contains header data
  184.         // and pretty much doesn't apply to us...
  185.         rc = SetFPos(pictFileRef, fsFromStart, kPictHeaderSize);
  186.  
  187.         // Adjust the length of the pict file (shorten by 512) to
  188.         // account for our skipping the first 512 bytes
  189.         pictFileLen -= kPictHeaderSize;
  190.  
  191.         // Now, allocate some memory with which to load our pict
  192.         // file in.
  193.         thePic = (PicHandle)NewHandleClear(pictFileLen);
  194.         if (thePic == nil) {
  195.             // Oops, unable to allocate in the heap!
  196.             // Probably the file's too big.
  197.             SysBeep(1);
  198.             return(nil);
  199.         }
  200.  
  201.         // Lock the buffer
  202.         HLock(Handle(thePic));
  203.  
  204.         // Okay, read in the pict file
  205.         rc = FSRead(pictFileRef, &pictFileLen, (Ptr)*thePic);
  206.  
  207.         // Unlock our pic buffer and close the file.
  208.         HUnlock(Handle(thePic));
  209.         FSClose(pictFileRef);
  210.  
  211.         // Update the picture frame rect
  212.         picRect = (**thePic).picFrame;
  213.     }
  214.     else
  215.         return(nil);
  216.  
  217.     // If we get all the way to here, no errors have occurred—GREAT!
  218.     // Return the pic buffer we allocated.
  219.     // Note that it's up to the caller to dispose of the pic buffer
  220.     // via DisposeHandle, since there's no way for GetPictFile to do it...
  221.     return(thePic);
  222. } // END GetPictFile
  223.  
  224. // END Main.c++