home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sys / amiga / programm / 12387 < prev    next >
Encoding:
Text File  |  1992-08-16  |  8.7 KB  |  237 lines

  1. Path: sparky!uunet!mcsun!Germany.EU.net!unido!sbsvax!aldebaran!winter
  2. From: winter@cs.uni-sb.de (Stefan Winterstein)
  3. Newsgroups: comp.sys.amiga.programmer
  4. Subject: Upside-down graphics revisited
  5. Keywords: Kopfstand, hack, upside-down, negative modulo
  6. Message-ID: <20782@sbsvax.cs.uni-sb.de>
  7. Date: 17 Aug 92 08:39:40 GMT
  8. References: <1992Aug4.171235.19277@doug.cae.wisc.edu>
  9. Sender: news@sbsvax.cs.uni-sb.de
  10. Reply-To: winter@cs.uni-sb.de
  11. Followup-To: Upside down graphics??
  12. Organization: Universitaet des Saarlandes
  13. Lines: 222
  14.  
  15.  
  16. In article <1992Aug4.171235.19277@doug.cae.wisc.edu>
  17. pochanay@cae.wisc.edu (Adisak Pochanayon) asked:
  18. >
  19. >   Can anyone tell me if the hardware BitPlane Mod values are signed or
  20. >unsigned?  If they are signed, it should be extremely easy to display
  21. >a graphic screen upside down.  Has anyone tried this?  If so, is it
  22. >possible to do under 1.3 and 2.0 using the graphics.library functions
  23. >on a viewport?
  24.  
  25.     Yes - there really IS such a thing as a negative modulo.
  26.     Yes - this can be used to turn the display upside down - without
  27.           blitting tons of BitPlane data.
  28. And Yes - this can be done in a completely system-friendly (well, sort
  29.           of OS-supported) manner: Ever used a *negative* Bitplane width?
  30.  
  31.     Appended is the commented SAS/C source of my program 'Kopfstand'
  32. ("head-stand"?), which simply turns the frontmost screen upside-down.
  33. This can be Workbench or any other screen you like. Everything continues
  34. to work just fine, except the screen is turned.
  35.     Mouse pointer and movement are not mirrored, you have to guess the
  36. position on the original screen.  You exit the program by holding down
  37. the mouse button for about one second.  (You can use LALT-LAMIGA to
  38. simulate a mouse click without exiting Kopfstand.)
  39.  
  40.     Here is a quick explanation of how it works:  First, 'Kopfstand' makes
  41. a copy of the BitMap structure belonging to the frontmost screen, which it
  42. modifies in two ways:
  43.     - by calling InitBitMap with *negative* Screen width
  44.     - by making the plane pointers point to *last* row of their plane
  45.  
  46.     It then attaches this BitMap to the current ViewPort's BitMap pointer
  47. (while leaving the Screen's BitMap alone) and lets graphics.library
  48. recalculate the appropriate copperlist.  Et voila` - we have our negative
  49. modulo, which equals -2*ScreenWidth.
  50.     Since we changed the plane pointers, the last line of the plane is the
  51. first line on the screen.  Add the negative modulo and the next line
  52. displayed is the last-but-first line of the plane and so on (prove of
  53. correctness by induction on BitMap->Rows...).
  54.  
  55.     Warning:  This program does one nasty thing or two.  Especially
  56. changing plane pointers in the current ViewPort's BitMap is not a
  57. very safe thing to do (but since the usual way to get plane pointers is
  58. from the Screen's BitMap, it usually works).  Also 'Kopfstand' relies on
  59. the fact that the screen turned upside-down will not close before turned
  60. back again.
  61.     After all, this is a screen hack in the truest of sense - use it at
  62. your own risk.  Don't blame me if your Amiga gurus, formats your
  63. hard-drive or blows up your house (although I didn't encounter anything of
  64. the above ;-))
  65.  
  66.                 'Kopfstand' is dedicated to Leo L. Schwab.
  67.  
  68. Any reaction on this article is welcome. Enjoy!
  69.  
  70. -Stefan
  71.  
  72. P.S.: I posted it in c.s.a.programmer since c.s.a.sources seems to be
  73.       rather unreliable.
  74. ---                                                                 ///
  75.   Stefan Winterstein, Schwarzbachstr. 7, W-6650 Homburg 6, Germany ///
  76.   Usenet: winter@cs.uni-sb.de                                __   ///
  77.   SGNTR VRS VRSN 3.1B:                                       \\\ ///
  78.   Strppd nd cmprssd fr qckr trnsmssn. nfct yrs tdy!           \\X//
  79.  
  80.  
  81. -------- cut here -------- Kopfstand.c -------- cut here --------
  82. ;/*    Execute me to compile !
  83.     lc -cfist -j73 -ms -M -O -rr -v -w Kopfstand.c
  84.     blink Kopfstand.o SC SD ND
  85.     quit
  86.   */
  87. /*********************************************************************/
  88. /*                                                                   */
  89. /*                            Kopfstand.c                            */
  90. /*                            ~~~~~~~~~~~                            */
  91. /*                       by Stefan Winterstein                       */
  92. /*                       (winter@cs.uni-sb.de)                       */
  93. /*                                                                   */
  94. /*              Makes topmost Screen stand upside-down.              */
  95. /*                                                                   */
  96. /*                 Exit by pressing LMB for a while.                 */
  97. /*                                                                   */
  98. /*     Neither uses Blitter nor moves BitPlanes about in memory.     */
  99. /*                                                                   */
  100. /*  Ever heard of negative plane width and modulo??? Look and see!   */
  101. /*                                                                   */
  102. /*                    Dedicated to Leo L. Schwab                     */
  103. /*                                                                   */
  104. /*  Written 16-Aug-92 using SAS/C 5.10b                              */
  105. /*                                                                   */
  106. /*********************************************************************/
  107.  
  108. #include <exec/types.h>
  109. #include <exec/memory.h>
  110. #include <hardware/cia.h>
  111. #include <graphics/view.h>
  112. #include <intuition/intuitionbase.h>
  113.  
  114. #define _USEOLDEXEC_
  115. #include <proto/dos.h>
  116. #include <proto/exec.h>
  117. #include <proto/graphics.h>
  118. #include <proto/intuition.h>
  119.  
  120. #define CHECKDELAY    50L
  121. #define ciaa (*((struct CIA *) 0xbfe001))
  122.  
  123. void __stdargs __saveds
  124. main(void)             /* entry point */
  125. {
  126. struct DosLibrary    *DOSBase;
  127. struct GfxBase         *GfxBase;
  128. struct IntuitionBase *IntuitionBase;
  129.  
  130. struct View    *v;
  131. struct ViewPort *vp;
  132. struct Screen    *s;
  133. struct BitMap    *realbm, *mybm;
  134.  
  135. UWORD height, bpr, planedelta, width, depth, i;
  136.  
  137.  
  138.  if (IntuitionBase = (struct IntuitionBase *) OpenLibrary("intuition.library", 33L)) {
  139.   if (GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 33L)) {
  140.     if (DOSBase = (struct DosLibrary *) OpenLibrary("dos.library", 33L)) {
  141.       if (mybm = AllocMem(sizeof(*mybm), MEMF_PUBLIC | MEMF_CLEAR)) {
  142.  
  143.     Forbid();   /* Nobody should disturb us. */
  144.  
  145.         /* First we need to know a few addresses:           */
  146.         v = ViewAddress();            /* Intuition's View,   */
  147.         s = IntuitionBase->FirstScreen; /* the top-most Screen */
  148.         vp = &(s->ViewPort);        /* and its ViewPort.   */
  149.  
  150.         /*
  151.          * Now look for the BitMap structure
  152.          */
  153.         realbm = &s->BitMap;
  154.  
  155.         /* and make a copy of it. */
  156.         *mybm = *realbm;
  157.  
  158.         /* The following values are needed later */
  159.         depth = mybm->Depth;
  160.         height = mybm->Rows;
  161.         bpr = mybm->BytesPerRow;
  162.         width = bpr << 3;
  163.  
  164.         /* This is the byte offset for the last line of a plane. */
  165.         planedelta = bpr * (height-1);
  166.  
  167.         /*
  168.          * Here comes the trick:
  169.          *
  170.          * We call InitBitMap() with a *negative* width!
  171.          * When we supply the ViewPort with our faked BitMap
  172.          * to MakeVPort(), graphics.library will
  173.          * construct a copperlist with the appropriate
  174.          * negative modulo values for BPLxMOD.
  175.          */
  176.         InitBitMap(mybm, depth, -width, height);
  177.  
  178.         /*
  179.          * We want the last line of a plane to be the
  180.          * first line on the display, so we'll have to
  181.          * make eache plane pointer point to the last line
  182.          * of the plane, which is planedelta bytes away.
  183.          */
  184.         for (i=depth; i; )
  185.         mybm->Planes[--i] += planedelta;
  186.  
  187.         /*
  188.          * Now we patch in the faked BitMap into the ViewPort.
  189.          * The Screen's BitMap is not changed, so that all
  190.          * graphic output continues to go to the right place.
  191.          */
  192.         vp->RasInfo->BitMap = mybm;
  193.  
  194.         /* let graphics.library build that crazy copperlist */
  195.         MakeVPort(v, vp);
  196.         MrgCop(v);
  197.  
  198.         /* and load it. */
  199.         LoadView(v);
  200.  
  201.         /* Voil`! */
  202.  
  203.         /*
  204.          * We leave our faked BitMap in our ViewPort for
  205.          * a little longer so that every time Intuition builds up a
  206.          * new copperlist (e.g. ScreenToFront), it is fooled
  207.          * and displays our ViewPort upside-down.
  208.          * Lets hope nobody closes it in the meantime...
  209.          */
  210.  
  211.     Permit();
  212.  
  213.     /* Now check for a mouse click every once in a while. */
  214.     while ((ciaa.ciapra) & (1 << CIAB_GAMEPORT0))
  215.         Delay(CHECKDELAY);
  216.     /* (dirty, I know...) */
  217.  
  218.     /* We are done now, restore the original BitMap, */
  219.     vp->RasInfo->BitMap = realbm;
  220.     /* (even dirtier...) */
  221.  
  222.     /* and reach normality. */
  223.     MakeVPort(v, vp);
  224.     MrgCop(v);
  225.     LoadView(v);
  226.  
  227.     FreeMem(mybm, sizeof(*mybm));
  228.       }
  229.       CloseLibrary ((struct Library *) DOSBase);
  230.     }
  231.     CloseLibrary ((struct Library *) GfxBase);
  232.   }
  233.   CloseLibrary ((struct Library *) IntuitionBase);
  234.  }
  235. }
  236. -------- cut here -------- Kopfstand.c -------- cut here --------
  237.