home *** CD-ROM | disk | FTP | other *** search
/ Amiga Developer CD v1.2 / amidev_cd_12.iso / reference / amiga_mail_vol2 / vii-17 / camg.c < prev    next >
C/C++ Source or Header  |  1996-01-30  |  8KB  |  253 lines

  1. ;/* Camg.c - Execute me to compile me with SAS/C 6.56
  2. sc NMINC STRMERGE STREQ NOSTKCHK SAVEDS IGNORE=73 camg.c
  3. slink FROM LIB:c.o,camg.o TO camg LIBRARY LIB:sc.lib,LIB:amiga.lib
  4. quit
  5. */
  6. /*
  7. Copyright (c) 1991 Commodore-Amiga, Inc.
  8.  
  9. This example is provided in electronic form by Commodore-Amiga,
  10. Inc. for use with the Amiga Mail Volume II technical publication.
  11. Amiga Mail Volume II contains additional information on the correct
  12. usage of the techniques and operating system functions presented in
  13. these examples.  The source and executable code of these examples may
  14. only be distributed in free electronic form, via bulletin board or
  15. as part of a fully non-commercial and freely redistributable
  16. diskette.  Both the source and executable code (including comments)
  17. must be included, without modification, in any copy.  This example
  18. may not be published in printed form or distributed with any
  19. commercial product. However, the programming techniques and support
  20. routines set forth in these examples may be used in the development
  21. of original executable software products for Commodore Amiga
  22. computers.
  23.  
  24. All other rights reserved.
  25.  
  26. This example is provided "as-is" and is subject to change; no
  27. warranties are made.  All use is at your own risk. No liability or
  28. responsibility is assumed.
  29. */
  30.  
  31. /*
  32.  * Camg.c Demonstrates use of ILBM.CAMG value. Filters out junk CAMGs and bad
  33.  * bits. Adapts to 2.0 and 1.3
  34.  *
  35.  * Note - Under 2,0, when writing a CAMG you should write the 32-bit value
  36.  * returned by the 2.0 graphics function GetVPModeID(viewport);
  37.  */
  38.  
  39. #include <exec/types.h>
  40. #include <exec/libraries.h>
  41. #include <intuition/intuition.h>
  42. #include <graphics/displayinfo.h>
  43.  
  44. #include <clib/exec_protos.h>
  45. #include <clib/intuition_protos.h>
  46. #include <clib/graphics_protos.h>
  47.  
  48. #include <stdio.h>
  49.  
  50. struct Screen  *openidscreen(SHORT wide, SHORT high, SHORT deep, ULONG modeid);
  51. ULONG           modefallback(ULONG modeid, SHORT wide, SHORT high, SHORT deep);
  52.  
  53. #define DEBUG
  54.  
  55. struct Library *GfxBase;
  56. struct Library *IntuitionBase;
  57.  
  58. void            main(int argc, char **argv)
  59. {
  60.     struct Screen  *screen;
  61.  
  62.     /*
  63.      * Test the routines by passing various bad or possibly unavailable CAMG
  64.      * modeid values
  65.      */
  66.     if (GfxBase = OpenLibrary("graphics.library", 0))
  67.     {
  68.         if (IntuitionBase = OpenLibrary("intuition.library", 0))
  69.         {
  70.             /* Junk CAMG    */
  71.             if (screen = openidscreen(640, 400, 3, 0x12340000))
  72.                 CloseScreen(screen);
  73.  
  74.             /* Bad bits like VP_HIDE and SPRITES */
  75.             if (screen = openidscreen(320, 400, 3, 0x00006004))
  76.                 CloseScreen(screen);
  77.  
  78.             /* Extended bit set but not a valid modeid */
  79.             if (screen = openidscreen(320, 400, 3, 0x00009004))
  80.                 CloseScreen(screen);
  81.  
  82.             /* An ECS Mode - demonstrates modefallback if not available */
  83.             if (screen = openidscreen(640, 400, 2, 0x00039025))
  84.                 CloseScreen(screen);
  85.  
  86.             CloseLibrary(IntuitionBase);
  87.         }
  88.         CloseLibrary(GfxBase);
  89.     }
  90. }
  91.  
  92.  
  93. struct NewScreen ns = {NULL};
  94.  
  95. /*
  96.  * simple openidscreen
  97.  *
  98.  * Passed width, height, depth, and modeid, attempts to open a 2.0 or 1.3 screen.
  99.  * Demonstrates filtering out of bad CAMGs and modefallback() for unavailable
  100.  * modes.
  101.  */
  102.  
  103. struct Screen  *
  104. openidscreen(SHORT wide, SHORT high, SHORT deep, ULONG modeid)
  105. {
  106.     extern struct Library *GfxBase;
  107.     struct Screen  *screen = NULL;
  108.  
  109. #ifdef DEBUG
  110.     printf("\nAsked to open screen with modeid $%08lx\n", modeid);
  111. #endif
  112.  
  113.     /*
  114.      * BEFORE USING A CAMG YOU HAVE READ, YOU MUST SCREEN OUT JUNK CAMGs AND
  115.      * INAPPROPRIATE BITS IN OLD 16-BIT CAMGs. YOU MAY WANT TO PLACE THESE
  116.      * FIRST TWO TESTS WITH YOUR CAMG-READING CODE TO SCREEN OUT BAD CAMGs
  117.      * IMMEDIATELY.
  118.      */
  119.  
  120.     /*
  121.      * Knock bad bits out of old-style CAMG modes before checking availability.
  122.      * (some ILBM CAMG's have these bits set in old 1.3 modes, and should not)
  123.      * If not an extended monitor ID, or if marked as extended but missing
  124.      * upper 16 bits, screen out inappropriate bits now.
  125.      */
  126.     if ((!(modeid & MONITOR_ID_MASK)) ||
  127.         ((modeid & EXTENDED_MODE) && (!(modeid & 0xFFFF0000))))
  128.         modeid &=
  129.             (~(EXTENDED_MODE | SPRITES | GENLOCK_AUDIO | GENLOCK_VIDEO | VP_HIDE));
  130.  
  131.     /*
  132.      * Check for bogus CAMG like some brushes have, with junk in upper word and
  133.      * extended bit NOT set not set in lower word.
  134.      */
  135.     if ((modeid & 0xFFFF0000) && (!(modeid & EXTENDED_MODE)))
  136.     {
  137.         /*
  138.          * Bad CAMG, so ignore CAMG and determine a mode based on based on
  139.          * pagesize or aspect
  140.          */
  141.         modeid = NULL;
  142.         if (wide >= 640)
  143.             modeid |= HIRES;
  144.         if (high >= 400)
  145.             modeid |= LACE;
  146.     }
  147.  
  148. #ifdef DEBUG
  149.     printf("After filtering, mode is now $%08lx\n", modeid);
  150. #endif
  151.  
  152.     /*
  153.      * Now see if mode is available
  154.      */
  155.     if (GfxBase->lib_Version >= 36)
  156.     {
  157.         /* if mode is not available, try a fallback mode */
  158.         if (ModeNotAvailable(modeid))
  159.             modeid = modefallback(modeid, wide, high, deep);
  160.  
  161.  
  162.         if (!(ModeNotAvailable(modeid)))         /* if mode is available */
  163.         {
  164.             /*
  165.              * We have an available mode id Here you may wish to create a
  166.              * custom, or centered, or overscan display clip based on the size
  167.              * of the image.  Or just use one of the standard clips.
  168.              *
  169.              * The 2.0 Display program uses QueryOverscan to get the settings of
  170.              * this modeid's OSCAN_TEXT, OSCAN_STANDARD, and OSCAN_MAX. Display
  171.              * centers the screen (via TopEdge and LeftEdge) within the user's
  172.              * closest OSCAN rectangle, and creates a display clip by using the
  173.              * same values and then clipping the values to be within OSCAN_MAX
  174.              * limits.  If the centered screen ends up lower than user's
  175.              * OSCAN_TEXT settings, I move it up to same MinY as his OSCAN_TEXT
  176.              * --- otherwise his Workbench might peek over the top.
  177.              */
  178.  
  179.             /*
  180.              * Now use extended OpenScreen or OpenScreenTags for this modeid.
  181.              * (this gives you the benefit of system-supported overscan, etc.)
  182.              */
  183. #ifdef DEBUG
  184.             printf("Doing OpenScreenTags of modeid $%08lx\n", modeid);
  185. #endif
  186.             screen = OpenScreenTags(NULL,
  187.                                     SA_Width, wide,
  188.                                     SA_Height, high,
  189.                                     SA_Depth, deep,
  190.                                     SA_DisplayID, modeid);
  191.         }
  192.     }
  193.  
  194.  
  195.     if (!screen) /* not 2.0, or mode not
  196.                   * available, or can't open */
  197.     {
  198.         /*
  199.          * Try an old-style OpenScreen with modefallback() modeid
  200.          */
  201.  
  202.         modeid = modefallback(modeid, wide, high, deep);
  203.  
  204.         ns.Width = wide;
  205.         ns.Height = high;
  206.         ns.Depth = deep;
  207.         ns.ViewModes = modeid;
  208.  
  209. #ifdef DEBUG
  210.         printf("Doing old OpenScreen of mode $%04lx\n", modeid);
  211. #endif
  212.  
  213.         screen = OpenScreen(&ns);
  214.     }
  215.  
  216.     return (screen);
  217. }
  218.  
  219.  
  220.  
  221. /*
  222.  * modefallback - passed an unavailable modeid, attempts to provide an
  223.  * available replacement modeid to use instead
  224.  */
  225.  
  226. ULONG
  227. modefallback(ULONG modeid, SHORT wide, SHORT high, SHORT deep)
  228. {
  229.     extern struct Library *GfxBase;
  230.     ULONG           newmodeid;
  231.  
  232.     /*
  233.      * Here you should either be asking the user what mode they want OR
  234.      * searching the display database and choosing an appropriate replacement
  235.      * mode based on what you or the user deem important (colors, or aspect, or
  236.      * size, etc.).  You could also use a built in table for modes you know
  237.      * about, and substitute mode you wish to use when the desired mode is not
  238.      * available.
  239.      *
  240.      * This simple routine simply masks out everything but old modes. This is a
  241.      * way to get some kind of display open but not necessarily a suitable or
  242.      * compatible display.
  243.      */
  244.  
  245.     newmodeid = modeid & (HIRES | LACE | HAM | EXTRA_HALFBRITE);
  246.  
  247. #ifdef DEBUG
  248.     printf("Modefallback passed 0x%08lx, returning 0x%08lx\n", modeid, newmodeid);
  249. #endif
  250.  
  251.     return (newmodeid);
  252. }
  253.