papa@bacall.UUCP (03/14/87)
Since I wanted to allow zoom and pan in my A-Talk + Tektronix emulator, I started to look at examples of the use of Superbitmaps. Unfortunately the only thing that I found was a neat program by Leo L. Schwab that allows scrolling a superbitmap, but does not work under Intuition. The program, bigmap.c, takes over the machine. So my first cut was to Intuition-it, and here is the result that will work on a custom screen under intuition. Two things came up. Leo's code uses ScrollVPort, and the scroll is really smooth. My intuition-compatible code must use ScrollLayer. ScrollLayer works properply only under WB 1.2 (actually >=32). Second, ScrollLayer is not smooth at all, and the screen flashes a lot during scrolling. Rob Peck, in his just published book "Programmer's Guide to the Amiga", advises to use Delay(5) after each call to ScrollLayer, but I found that it doesn't help. WaitTOF() doesn't help either. If anybody finds out a better way I'd love to know about it. With a program similar to this I allow the user to zoom and pan on a Tektronix 4014 screen at the max res of 1008x1024. By the way, in my opinion Robert "Rob" Peck's book is the BEST book on the Amiga. It is very useful as a companion of the RKMs. It is FULL of programming examples and a disk is also available for $15 with all the programs. It covers Amigados, Exec, Intuition, Graphics, Animation (with real working examples of VSprites), Sound and Tasks. It is published by SYBEX, and I bought it at Dalton for $22.95. I tested the following code only under MANX: cc ibigmap.c ln ibigmap.o -lc -o ibigmap Enjoy. -- Marco /* :ts=8 bk=0 * Super big bitmap explorer. * Now under Intuition! * Jon would call this a parlor trick. * * Leo L. Schwab 8607.30 * Intuitioned by Marco Papa 8703.11 */ /* I shouldn't have to include graphics/copper.h myself */ #include <exec/types.h> #include <exec/memory.h> #include <graphics/gfxbase.h> #include <graphics/copper.h> #include <graphics/view.h> #include <graphics/rastport.h> #include <graphics/layers.h> #include <devices/gameport.h> #include <devices/inputevent.h> #include <intuition/intuition.h> #include <intuition/intuitionbase.h> #define REV 32L #define DEPTH 2 #define WIDTH 960L #define HEIGHT 600L #define DWIDTH 320 #define DHEIGHT 200 #define MAXXOFF (WIDTH-DWIDTH) #define MAXYOFF (HEIGHT-DHEIGHT) #define ever (;;) extern void *OpenLibrary(), *AllocRaster(), *AllocMem(), *GetColorMap(), *CreateStdIO(), *CreatePort(); extern long OpenDevice(), DoIO(); extern struct Screen *OpenScreen(); extern struct Window *OpenWindow(); struct GamePortTrigger gpt = { GPTF_UPKEYS | GPTF_DOWNKEYS, 0, 1, 1 }; UWORD colors[] = { 0, 0xf00, 0x0f0, 0x00f }; struct NewScreen NewScreen = { 0, 0, DWIDTH, DHEIGHT, DEPTH, 0,1, NULL, CUSTOMSCREEN, NULL, (UBYTE *) "Scroll SuperBitMap Example", NULL, NULL }; struct NewWindow NewWindow = { 0, 0, /* start position */ DWIDTH, DHEIGHT, /* width, height */ -1, -1, /* detail pen, block pen */ NULL, /* IDCMP flags */ GIMMEZEROZERO|BACKDROP|ACTIVATE|BORDERLESS|SMART_REFRESH|SUPER_BITMAP, /* window flags */ NULL, /* pointer to first user gadget */ NULL, /* pointer to user checkmark */ NULL, /* window title */ NULL, /* pointer to screen (later) */ NULL, /* pointer to superbitmap */ 0,0,DWIDTH,DHEIGHT, /* sizing limits min and max */ CUSTOMSCREEN }; struct ViewPort *vp; struct ColorMap *cm; struct BitMap *bm; struct RastPort *rp; struct Layer *l; struct Layer_Info *li; struct GfxBase *GfxBase; struct IntuitionBase *IntuitionBase; struct LayersBase *LayersBase; struct Screen *Screen; struct Window *Window; struct InputEvent joyreport; struct IOStdReq *gameio; struct MsgPort *gameport; main () { int i = 1, x, y; int oldx, oldy; openstuff (); makescreen (); /* NOT Intuition call */ initjoystick (); SetDrMd (rp, JAM1); SetRast (rp, 0L); SetAPen (rp, 1L); for (x=0, y=0; x<WIDTH; x += 16, y += 10) { Move (rp, (long) x, 0L); Draw (rp, WIDTH-1, (long) y); Draw (rp, WIDTH-1-x, HEIGHT-1); Draw (rp, 0L, HEIGHT-1-y); Draw (rp, (long) x, 0L); if (!(++i & 3)) /* I love weird expressions like this */ ++i; SetAPen (rp, (long) i); } SetAPen (rp, 3L); Move (rp, 429L, 301L); Text (rp, "Hello, World!", 13L); SetAPen (rp, 1L); Move (rp, 428L, 300L); Text (rp, "Hello, World!", 13L); x = oldx = 0; y = oldx = 0; SendIO (gameio); for ever { WaitIO (gameio); if (joyreport.ie_Code == IECODE_LBUTTON) /* Fire button pressed; exit program */ break; x += joyreport.ie_X; if (x < 0 || x > MAXXOFF) x = x<0 ? 0 : MAXXOFF; y += joyreport.ie_Y; if (y < 0 || y > MAXYOFF) y = y<0 ? 0 : MAXYOFF; if (oldx != x || oldy != y) { /* WaitTOF (); */ ScrollLayer(li, l, (long)x-oldx, (long)y-oldy); /* Delay(5L); /* 5 = delay 1/10th of a second */ oldx = x; oldy = y; } SendIO (gameio); } closeeverything (); } openstuff () { long err; if (!(IntuitionBase = OpenLibrary ("intuition.library", REV))) die ("No intuition library.\n"); if (!(GfxBase = OpenLibrary ("graphics.library", REV))) die ("No graphics library.\n"); if (!(LayersBase = OpenLibrary ("layers.library", REV))) die ("No layers library.\n"); if (!(Screen = (struct Screen *) OpenScreen(&NewScreen))) die ("No screen.\n"); if (!(gameport = CreatePort (0L, 0L))) die ("Can't make msgport.\n"); if (!(gameio = CreateStdIO (gameport))) die ("Can't make IO packet.\n"); if (err = OpenDevice ("gameport.device", 1L, gameio, 0L)) die ("Games closed.\n"); if (!(bm = AllocMem ((long) sizeof (*bm), MEMF_CHIP | MEMF_CLEAR))) die ("Can't allocate BitMap.\n"); } makescreen () { register int i; InitBitMap (bm, (long) DEPTH, WIDTH, HEIGHT); vp = &Screen->ViewPort; for (i=0; i<DEPTH; i++) if (!(bm -> Planes[i] = AllocRaster (WIDTH, HEIGHT))) die ("Can't allocate memory for plane.\n"); else BltClear(bm->Planes[i],RASSIZE(WIDTH,HEIGHT)); NewWindow.Screen = Screen; NewWindow.BitMap = bm; if ((Window = (struct Window *) OpenWindow (&NewWindow)) == NULL) die ("No window.\n"); rp = Window->RPort; l = rp->Layer; li = l->LayerInfo; rp->Layer->Window = (APTR) Window; LoadRGB4 (vp, colors, 4L); } closeeverything () { register int i; if (Window) CloseWindow(Window); if (bm) { for (i=0; i<DEPTH; i++) if (bm -> Planes[i]) FreeRaster (bm -> Planes[i], WIDTH, HEIGHT); FreeMem (bm, (long) sizeof (*bm)); } if (gameio) { if (gameio -> io_Device) CloseDevice (gameio); DeleteStdIO (gameio); } if (gameport) DeletePort (gameport); if (Screen) CloseScreen(Screen); if (LayersBase) CloseLibrary (LayersBase); if (GfxBase) CloseLibrary (GfxBase); if (IntuitionBase) CloseLibrary (IntuitionBase); } die (str) char *str; { puts (str); closeeverything (); exit (100); } initjoystick () { UBYTE type = GPCT_RELJOYSTICK; gameio -> io_Command = GPD_SETCTYPE; gameio -> io_Length = 1; gameio -> io_Data = (APTR) &type; if (DoIO (gameio)) die ("Error in setting controller type.\n"); gameio -> io_Command = GPD_SETTRIGGER; gameio -> io_Length = sizeof (gpt); gameio -> io_Data = (APTR) &gpt; if (DoIO (gameio)) die ("Error in setting trigger values.\n"); gameio -> io_Command = GPD_READEVENT; gameio -> io_Length = sizeof (joyreport); gameio -> io_Data = (APTR) &joyreport; } -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Marco Papa 3175 S. Hoover St., Ste. 275 (213)747-8498 Los Angeles, CA 90007 USC: (213)743-3752 F E L S I N A Now working for ::::::: BIX: papa But in no way :: :: Officially representing ::::::: ...!usc-oberon!bacall!papa S O F T W A R E papa@usc-cse.usc.edu -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-