Path: utzoo!mnetor!tmsoft!torsqnt!jarvis.csri.toronto.edu!rutgers!tut.cis.ohio-state.edu!ucbvax!dewey.soe.berkeley.edu!oster From: oster@dewey.soe.berkeley.edu (David Phillip Oster) Newsgroups: comp.sys.mac.programmer Subject: Re: A Mac novice & C Message-ID: <31399@ucbvax.BERKELEY.EDU> Date: 20 Sep 89 07:30:36 GMT References: <10715@dasys1.UUCP> Sender: usenet@ucbvax.BERKELEY.EDU Reply-To: oster@dewey.soe.berkeley.edu.UUCP (David Phillip Oster) Distribution: comp Organization: School of Education, UC-Berkeley Lines: 334 In article <10715@dasys1.UUCP> rpaul@dasys1.UUCP (Rod Paul) writes: >This is where I've run into a brick wall, could some kind soul give me >some tips on how to go about say, displaying a 256x256 type char array >on the screen? Once again, here is my simple program for reacing in an ascii file of hexbytes, and displaying it on the screen. Some things you'll need to change to use this program: It reads a file of postscript data, at 4 bits per pixel. You'll need to make the pixmap longer to get 256 bits per pixel, and you'll need to change the read routine. Postscript images are upside down compared to mac images, so you'll need to remove the image inversion routine. /* ShowBush.c - short program to display a postscript picture of Bush. in color quickdraw. You also get Bush on your clipboard. by David Phillip Oster. Copy and use this in any way you see fit. Basically an example of the pain you have to go through to actually use color quickdraw. In old quickdraw, you had some data and a window, and you CopyBit()s the data to the window. In color quickdraw, you have as your source: a.) the data. b.) a color table. c.) a "pixmap" that connects the data to the color table. as your destination, you have: a.) a color window b.) a palette, that informs the window manager of which colors you'll be using, so the color manager can change the color table in the video board to make those color available. This program works best with at least 16 colors! */ #include #define HEIGHT 200 #define WIDTH 200 #define NIL 0L #define NOT ! SysEnvRec *world; Handle myPixels; WindowPtr myWin; PixMapHandle myPixMap; CTabHandle myCTable; PaletteHandle myPm; enum { READERROR = 1, NEEDSCOLORQD, /* this demo needs color quickdraw */ NOPIXMAP, NOPIXELS, NOCTABLE, NOPALETTE, PIXDATACHANGED }; enum { UNDOI = 1, COPYI = UNDOI + 1 }; main(){ EventRecord myEvent; Init(); for(;;){ if(GetNextEvent(everyEvent, &myEvent)){ HandleEvent(&myEvent); } } } Init(){ PaletteHandle oldPm; FlushEvents(everyEvent, NIL); InitGraf( (Ptr) &thePort); InitFonts(); InitWindows(); InitCursor(); InitDialogs(NIL); InitMenus(); TEInit(); world = (SysEnvRec *) NewPtr(sizeof(SysEnvRec)); SysEnvirons(1, world); if( NOT world->hasColorQD){ Error(NEEDSCOLORQD, ""); } myWin = GetNewCWindow(128, NIL, -1L); /* set up the window */ SetPort(myWin); ClipRect(&thePort->portRect); myPixMap = NewPixMap(); /* allocate the pixmap */ if(NIL == myPixMap){ Error(NOPIXMAP, ""); } myPixels = NewHandle( ((long) HEIGHT/2)*WIDTH); /* allocate the pixel data */ if(NIL == myPixels){ Error(NOPIXELS, ""); } /* allocate the color table */ myCTable = (CTabHandle) NewHandle(sizeof(ColorTable) + 15L*sizeof(ColorSpec)); if(NIL == myCTable){ Error(NOCTABLE, ""); } InitPixels(myPixels); /* set up the pixel data */ InitCTable(myCTable); /* set up the color table */ (**myPixMap).bounds.left = 0; /* set up the pixmap */ (**myPixMap).bounds.top = 0; (**myPixMap).bounds.right = WIDTH; (**myPixMap).bounds.bottom = HEIGHT; (**myPixMap).rowBytes = 0x8000 | (WIDTH/2); if(NIL != (**myPixMap).pmTable) DisposHandle((**myPixMap).pmTable); (**myPixMap).pmTable = myCTable; (**myPixMap).pixelSize = 4; myPm = NewPalette(16, myCTable, pmTolerant, 0); /* set up the palette */ if(NIL == myPm){ Error(NOPALETTE, ""); } if(NIL != (oldPm = GetPalette(thePort))){ DisposePalette(oldPm); } SetPalette(thePort, myPm, TRUE); ActivatePalette(thePort); } /* SwapMove - copy from src to dest, moving scan lines from top to bottom as you go (postscript images are upside down compared to quickdraw images) */ SwapMove(src, dest, cnt)Ptr src, dest;long cnt;{ register short i, j; for(i = 0;i <200;i++){ BlockMove(src + (i*(WIDTH/2)), dest + ((199-i)*(WIDTH/2)), WIDTH/2); } } /* InitPixels- initialize our handle to the bush data SwapMove since Postscript is upside down from Mac. */ InitPixels(h)Handle h;{ register Ptr p, pMax; register short i; Handle h2, GetBush(); h2 = GetBush(); SwapMove(*h2, *h, GetHandleSize(h)); } /* InitCTable - initialize our color table to uniform gray */ InitCTable(ct)CTabHandle ct;{ short i; (**ct).ctSeed = GetCTSeed(); (**ct).ctFlags = 0; (**ct).ctSize = 16 - 1; for(i = 0;i < 16;i++){ (**ct).ctTable[i].value = i; (**ct).ctTable[i].rgb.red = (**ct).ctTable[i].rgb.green = (**ct).ctTable[i].rgb.blue = (unsigned) i * 16*257; } } /* Error - print the error message */ Error(i, s1)short i;Str255 s1;{ Str255 s; GetIndString(s, 128, i); ParamText(s, s1, "", ""); Alert(129, NIL); ExitToShell(); } /* HandleEvent - quit on mouse or key event */ HandleEvent(event)EventRecord *event;{ switch(event->what){ case mouseDown: case keyDown: ExitToShell(); case updateEvt: GoUpdate(event); break; } } /* GoUpdate - handle update event, paste it to clipboard */ GoUpdate(event)EventRecord *event;{ SetPort(event->message); BeginUpdate(thePort); CopyMyBits(); EndUpdate(thePort); } /* CopyMyBits - put bits to screen, put bits to clipboard */ CopyMyBits(){ Rect r, r2; PicHandle ph; HLock(myPixels); HLock(myPixMap); (**myPixMap).baseAddr = *myPixels; r.left = 0; r.top = 0; r.right = WIDTH; r.bottom = HEIGHT; r2 = r; r2.top *= 2; r2.left *= 2; r2.right *= 2; r2.bottom *= 2; ph = OpenPicture(&r); CopyBits(*myPixMap, &thePort->portBits, &r, &r, srcCopy, NIL); ClosePicture(); CopyBits(*myPixMap, &thePort->portBits, &r, &r2, srcCopy, NIL); HUnlock(myPixMap); HUnlock(myPixels); ZeroScrap(); HLock(ph); PutScrap(GetHandleSize(ph), 'PICT', *ph); SystemEdit(COPYI-1); /* so multifinder will take the scrap */ KillPicture(ph); } /* GetBush */ Handle GetBush(){ OSErr val; short ref; Handle h; long len; Str255 s; ref = 0; h = NIL; val = FSOpen("\pbush.ps", 0, &ref); if(noErr == val)val = GetEOF(ref, &len); if(noErr == val)h = NewHandle(len - 4); if(noErr == val && NIL != h){ HLock(h); len = GetHandleSize(h); if(noErr == val)val = FSRead(ref, &len, *h); HexToBin(h); HUnlock(h); } if(0 != ref){ FSClose(ref); } if(noErr != val){ NumToString(val, s); Error(READERROR, s); if(NIL != h){ DisposHandle(h); h = NIL; } } return h; } /* SkipHeader - advance p to point to data */ unsigned char *SkipHeader(p)register unsigned char *p;{ while( NOT (p[0] == '\r' && p[1] == '0')) p++; return &p[1]; } /* HexToBin - h is a locked handle containing text. turn it into binary Sorry about this. It is a quick and dirty hex ascii to binary routine. */ HexToBin(h)Handle h;{ register unsigned char *src, *srcMax, *dest; src = dest = (unsigned char *) *h; src = SkipHeader(src); srcMax = src + GetHandleSize(h); while(src < srcMax){ if(*src >= '0' && *src <= '9'){ *dest = (*src++ - '0') << 4; if(*src >= '0' && *src <= '9'){ *dest++ |= *src++ - '0'; }else if(*src >= 'A' && *src <= 'F'){ *dest++ |= *src++ - 'A' + 10; }else if(*src >= 'a' && *src <= 'f'){ *dest++ |= *src++ - 'a' + 10; } }else if(*src >= 'A' && *src <= 'F'){ *dest = (*src++ - 'A' + 10) << 4; if(*src >= '0' && *src <= '9'){ *dest++ |= *src++ - '0'; }else if(*src >= 'A' && *src <= 'F'){ *dest++ |= *src++ - 'A' + 10; }else if(*src >= 'a' && *src <= 'f'){ *dest++ |= *src++ - 'a' + 10; } }else if(*src >= 'a' && *src <= 'f'){ *dest = (*src++ - 'a' + 10) << 4; if(*src >= '0' && *src <= '9'){ *dest++ |= *src++ - '0'; }else if(*src >= 'A' && *src <= 'F'){ *dest++ |= *src++ - 'A' + 10; }else if(*src >= 'a' && *src <= 'f'){ *dest++ |= *src++ - 'a' + 10; } }else{ src++; } } SetHandleSize(h, dest - (unsigned char *) *h); }