From: pottier@clipper.ens.fr (Francois Pottier) Subject: csmp-digest-v3-032 Date: Mon, 30 May 94 14:02:04 MET DST C.S.M.P. Digest Mon, 30 May 94 Volume 3 : Issue 32 Today's Topics: Are there any Disassemblers for Mac? Drawing strings vertically. I HATE GWorlds! Is FSpExchangeFiles still broken? Looping sounds PPC Toolbox GetDefaultUser() bug SU3.0 programming tip The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier (pottier@clipper.ens.fr). The digest is a collection of article threads from the internet newsgroup comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi- regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. If you don't have access to news, you may still be able to post messages to the group by using a mail server like anon.penet.fi (mail help@anon.penet.fi for more information). Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at nef.ens.fr). Article threads are not added to the digest until the last article added to the thread is at least two weeks old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The digest is officially distributed by two means, by email and ftp. If you want to receive the digest by mail, send email to listserv@ens.fr with no subject and one of the following commands as body: help Sends you a summary of commands subscribe csmp-digest Your Name Adds you to the mailing list signoff csmp-digest Removes you from the list Once you have subscribed, you will automatically receive each new issue as it is created. The official ftp info is //ftp.dartmouth.edu/pub/csmp-digest. Questions related to the ftp site should be directed to scott.silver@dartmouth.edu. Currently no previous volumes of the CSMP digest are available there. Also, the digests are available to WAIS users as comp.sys.mac.programmer.src. ------------------------------------------------------- >From fd () Subject: Are there any Disassemblers for Mac? Date: 13 May 1994 21:31:30 GMT Organization: Northwestern University, Evanston, IL USA I was wondering... is there a program out there which can take, say, a CODE or MDEF etc resource and at the very least, disassemble it into the 680x0 instructions? Even better if it could do more things, like maybe tell you what toolbox trap a jump was to, etc. Does Macsbug let you do this? any info/comments would be greatly appreciated on this or any other tool that helps you dissect code. many thanks in advance, usman +++++++++++++++++++++++++++ >From ray@netcom.com (Ray Fischer) Date: Sat, 14 May 1994 03:18:50 GMT Organization: Netcom. San Jose, California fd () writes ... >I was wondering... is there a program out there >which can take, say, a CODE or MDEF etc resource and >at the very least, disassemble it into the 680x0 instructions? Yes, and a nice (and free) tool it is, too. Look for the CODE editor for ResEdit. It disassembles most code resource types and has some nifty features. It's probably on ftp.apple.com or sumex.stanford.edu (or one of its mirror sites). -- Ray Fischer "Men become civilized, not in proportion to their ray@netcom.com willingness to believe, but in their readiness to doubt." -- H. L. Mencken +++++++++++++++++++++++++++ >From kenlong@netcom.com (Ken Long) Date: Sat, 14 May 1994 07:16:29 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) The ResEdit 'CODE' editor is good. Once installed (the resources pasted into ResEdit's pref's file) it will open a disassembled representation of the 'CODE' resources by double-clicking on the resource in the picker window. You can't edit from within the disassble window - you must open the ID with the hex editor to do that. but the "edit" window is great for navigating and "tree climbing" through the program. It does jumps within the 'CODE' resource - even ID to ID. If you want the port output in a text file, you have to copy/paste (unless someone knows of another way). I do this by opening the editor window, clicking in pageDown 18 times (LC/10MB/12"monitor) then holding down shift and clicking once in the hex at the screen right. Then copy to clip. Then I click in a new Think C editor window I already had set up and paste into it. Save, then click in the 'CODE' editor window anh hit right-arrow once. Then hit pageDown 18 more times. Any more and ResEdit barfs up a "can't" alert. Continue this sequence until you are at the end. Faster and easier, but less elegant output, is DisAsm 3.1. You open the file, select the resource (default is 'CODE' and you can save output to a text file. A few notches above this is RSC_Viewer II. I will save a 'CODE' ID at a time to a text file. The output is closest to ResEdit output. Then the big-money diassembler is MacNosy. It does a better job at a lot of things than other disassemblers, but a lousy job at some things. it leaves out most of the "(sp)" ((A7))s and puts "PUSH" and "POP" in where others (including ResEdit) put something else. But it lists generic variables and parameters before the routines they go in, which no other disassembler I've seen does. Not as good as "short one, two, three" but just the fact that it has locals or parameters, their order and size. Better than nothing. It also lists out globals in a similar way. I've set Think C to generate a map during a build, built the app., ran it through Nosy and compared the map with the Nosy output. It tracks. Of course, I have a lot to learn, so it may provide more info than I can see. Nosy also extracts strings, and says where in the code they go. When I got the asm source for Orion, I ran Orion through Nosy and it tracked exactly with the source. I did not get the star table when I first got the source, so I made them with what I got out of Nosy output. Then, later, when I did get them, and compared them with the ones I made, they were the same. Cool! Those four are the main ones. The MPW disassembler, I'm told, was used as the basis for the ResEdit 'CODE' editor. I have some MSQBasic source for an old console dumping disassembler. It's not a hex dumper, but outputs instructions and operands. I'd like to get some C source for one. That's about it - those 5. ResEdit, DisAsm 3.1, RSC_Viewer II, MPW and MacNosy. There may be more I've not seen. -Ken- +++++++++++++++++++++++++++ >From Vampire@crypt.demon.co.uk (Vampire) Date: Sat, 14 May 1994 16:25:37 GMT Organization: Pennangalan Software In article fd () writes: > >I was wondering... is there a program out there >which can take, say, a CODE or MDEF etc resource and >at the very least, disassemble it into the 680x0 instructions? > >Even better if it could do more things, like maybe tell you >what toolbox trap a jump was to, etc. > Yes, there is a Disassembler extension for ResEdit 2.1 that does everything you mention. Vampire ============================================================================= |"If I knock on your door, you're a fool; VAMPIRE | if you invite me in, you're a dead fool" (Pennangalan Software) | My dust resides @crypt.demon.co.uk ============================================================================= +++++++++++++++++++++++++++ >From peirce@outpost.SF-Bay.org (Michael Peirce) Date: Sat, 14 May 94 15:52:12 PST Organization: Peirce Software, Inc. In article (comp.sys.mac.programmer), fd () writes: > > I was wondering... is there a program out there > which can take, say, a CODE or MDEF etc resource and > at the very least, disassemble it into the 680x0 instructions? > > Even better if it could do more things, like maybe tell you > what toolbox trap a jump was to, etc. > > Does Macsbug let you do this? > > any info/comments would be greatly appreciated on this or > any other tool that helps you dissect code. Two come to mind: (1) ResEdit has a CODE editor (really a viewer) that disassembles CODE, INIT, WDEF, and more code resources. It's pretty god really. (2) MacNosey from Jasik Designs. This is the industrial strength disassembler. It it invaluable if you are really going to, err, well, I'll say it, reverse engineer something :-) __ Michael Peirce __ peirce@outpost.sf-bay.org __ Peirce Software, Inc. __ 719 Hibiscus Place, Suite 301 __ __ San Jose, California USA 95117-1844 __ Makers of: Smoothie & __ voice: +1.408.244.6554 fax: +1.408.244.6882 __ Peirce Print Tools __ AppleLink: peirce & AOL: AFC Peirce --------------------------- >From kenlong@netcom.com (Ken Long) Subject: Drawing strings vertically. Date: Sat, 14 May 1994 22:09:15 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) /* This is a little thing I tossed together when I saw a c.s.m.p. message requesting source for writing vertical text. There may have been a reply I missed, but if not, this source will do. Add MacTraps and ANSI (for strlen) and you're cookin' The vertical text routine came from the SplatMaster Pascal source, by Jon Benton, which I'm porting to Think C. It doesn't totally run yet, otherwise I'd post it, too (though not here). Anyway, as stated below, vertical strings are excellent for scroll labels, as well as about box goodies, vertical progress bars, etc. Enjoy! */ // VerticalText.c MenuHandle appleMenu, fileMenu, editMenu; enum { appleID = 1, fileID, editID }; enum { openItem = 1, closeItem, quitItem = 4 }; WindowPtr genericWindow; Rect dragRect; Rect windowBounds = { 20, 0, 384, 512}; Rect strRect ={5, 20, 364, 40}; int width = 1; // Prototypes. void SetUpWindow (void); void DrawTheStrings (short active); void SetUpMenus (void); void AdjustMenus (void); static enable (MenuHandle menu, short item, short ok); void HandleMenu (long mSelect); void InitMacintosh (void); void HandleMouseDown (EventRecord *theEvent); void HandleEvent (void); int main (void); void SetUpWindow (void) { dragRect = qd.screenBits.bounds; genericWindow = NewWindow (0L, &windowBounds, "\pWhat about it?", true, noGrowDocProc, (WindowPtr) -1L, true, 0); SetPort (genericWindow); } void SetUpMenus (void) { InsertMenu (appleMenu = NewMenu (appleID, "\p\024"), 0); InsertMenu (fileMenu = NewMenu (fileID, "\pFile"), 0); InsertMenu (editMenu = NewMenu (editID, "\pEdit"), 0); DrawMenuBar (); AddResMenu (appleMenu, 'DRVR'); AppendMenu (fileMenu, "\pOpen/O;Close/W;(-;Quit/Q"); AppendMenu (editMenu, "\pUndo/Z; (-;Cut/X;Copy/C;Paste/V;Clear"); } void VerticalString (Rect word_rect, Str255 word_string) { #define center 5 // center of label is 'center' pixels from left of rect. short numChars, leading, stringCenter, x, curVert; FontInfo fInfo; TextFont (monaco); TextSize (9); TextFace (0); GetFontInfo (&fInfo); leading = fInfo.ascent + fInfo.descent + fInfo.leading; stringCenter = word_rect.left - center; // ForeColor (redColor); // oldStyle color. curVert = word_rect.top + leading; // primed for first character. numChars = strlen (word_string); for (x = 1; x < numChars; x++) { MoveTo (stringCenter - (CharWidth (word_string[x]) / 2), curVert); DrawChar ((char) word_string[x]); curVert = curVert + leading; } // ForeColor (blackColor); // oldStyle color. } // VerticalString. void DrawTheStrings (short active) { int color = true; SetPort (genericWindow); VerticalString (strRect, "\pMy name is Long but this is "); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pnot Chinese writing."); OffsetRect (&strRect, 40, 0); VerticalString (strRect, "\pSuperman\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pStrange visitor\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pfrom another planet\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pwho came to Earth beyond\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pwith powers and abilities far\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pbeyond those of mortal men.\0"); OffsetRect (&strRect, 40, 0); VerticalString (strRect, "\pThe VerticalString Routine was\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\ptaken from 'SplatMaster' Pascal\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\psource code. It was ported to\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pThink C by Kenneth A. Long in\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pmid 1992 and put into this demo\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pin May of 1994 for YOUR use and\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\p enjoyment. Please do so!\0"); OffsetRect (&strRect, 40, 0); VerticalString (strRect, "\pVertical strings are excellent\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pfor labeling vertical scrolls.\0"); OffsetRect (&strRect, 40, 0); VerticalString (strRect, "\pBullseye was used for the shell.\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pJon Benton wrote SplatMaster.\0"); OffsetRect (&strRect, 20, 0); VerticalString (strRect, "\pVertical String Demo is PD.\0"); } void AdjustMenus (void) { register WindowPeek wp = (WindowPeek) FrontWindow (); short kind = wp ? wp->windowKind : 0; Boolean DA = kind < 0; enable (editMenu, 1, DA); enable (editMenu, 3, DA); enable (editMenu, 4, DA); enable (editMenu, 5, DA); enable (editMenu, 6, DA); enable (fileMenu, openItem, ! ((WindowPeek) genericWindow)->visible); enable (fileMenu, closeItem, DA || ((WindowPeek) genericWindow)->visible); } static enable (MenuHandle menu, short item, short ok) { if (ok) EnableItem (menu, item); else DisableItem (menu, item); } void HandleMenu (long mSelect) { int menuID = HiWord (mSelect); int menuItem = LoWord (mSelect); Str255 name; GrafPtr savePort; WindowPeek frontWindow; switch (menuID) { case appleID: GetPort (&savePort); GetItem (appleMenu, menuItem, name); OpenDeskAcc (name); SetPort (savePort); break; case fileID: switch (menuItem) { case openItem: ShowWindow (genericWindow); SelectWindow (genericWindow); break; case closeItem: if ((frontWindow = (WindowPeek) FrontWindow ()) == 0L) break; if (frontWindow->windowKind < 0) CloseDeskAcc (frontWindow->windowKind); else if (frontWindow = (WindowPeek) genericWindow) HideWindow (genericWindow); break; case quitItem: ExitToShell (); break; } break; case editID: if (!SystemEdit (menuItem-1)) SysBeep (5); break; } } void InitMacintosh (void) { MaxApplZone (); InitGraf (& (qd.thePort)); InitFonts (); FlushEvents (everyEvent, 0); InitWindows (); InitMenus (); TEInit (); InitDialogs (0L); InitCursor (); } void HandleMouseDown (EventRecord *theEvent) { WindowPtr theWindow; int windowCode = FindWindow (theEvent->where, &theWindow); switch (windowCode) { case inSysWindow: SystemClick (theEvent, theWindow); break; case inMenuBar: AdjustMenus (); HandleMenu (MenuSelect (theEvent->where)); break; case inDrag: if (theWindow == genericWindow) DragWindow (genericWindow, theEvent->where, &dragRect); break; case inContent: // if (theWindow == genericWindow) // { // if (theWindow != FrontWindow ()) // SelectWindow (genericWindow); // else // InvalRect (&genericWindow->portRect); // } break; case inGoAway: if (theWindow == genericWindow && TrackGoAway (genericWindow, theEvent->where)) HideWindow (genericWindow); break; } } void HandleEvent (void) { int ok; EventRecord theEvent; HiliteMenu (0); SystemTask (); /* Handle desk accessories */ ok = GetNextEvent (everyEvent, &theEvent); if (ok) switch (theEvent.what) { case mouseDown: HandleMouseDown (&theEvent); break; case keyDown: case autoKey: if ((theEvent.modifiers & cmdKey) != 0) { AdjustMenus (); HandleMenu (MenuKey ((char) (theEvent.message & charCodeMask))); } break; case updateEvt: BeginUpdate (genericWindow); DrawTheStrings (((WindowPeek) genericWindow)->hilited); EndUpdate (genericWindow); break; case activateEvt: InvalRect (&genericWindow->portRect); break; } } main () { InitMacintosh (); SetUpMenus (); SetUpWindow (); for (;;) HandleEvent (); } +++++++++++++++++++++++++++ >From kenlong@netcom.com (Ken Long) Date: Sun, 15 May 1994 06:16:46 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) I don't care how many times I check it, a typo manages to get through. Must be old-timer's disease creaping in! The quote is: "Superman! Strange visitor, from another planet, who came to Earth with powers and abilities far beyond those of mortal men." (no "beyond" after "Earth") -Ken- :| --------------------------- >From mprince@mail.trincoll.edu (Matthew Prince) Subject: I HATE GWorlds! Date: 5 May 1994 05:21:30 GMT Organization: Trinity College I'm confused. I thought that I'd venture into the world of Offscreen GWorld drawing with my new copy of Inside Macintosh Imaging. I thought that everything would be nice and easy. I thought that I could have everything working in a few days, and if not, I could figure out what was wrong easily. I was wrong. I've set up an offscreen GWorld that has the same dimensions as my on screen window. I think that it's set up correctly because the first time that I CopyBits from it everything works fine. And if I CopyBits a simple image it works fine too. But when I try to CopyBits a complex image from it once, and then change the image slightly and try to CopyBits it again, it looks as if someone has taken a shotgun to the image. I'd say about half the pixels are there. And while it's in the same basic shape and color of the original image, it looks as if it's had a bunch of information lost. I'm confused. It's late. I'm sure this is a stupid question. Please forgive me. But if anyone has any idea what is going on, I'd appreciate any help they could lend. Thanks, Matthew Prince mprince@mail.trincoll.edu +++++++++++++++++++++++++++ >From Thomas Reed Date: 6 May 1994 14:08:26 GMT Organization: Washington University In article <2q9voq$nt1@yar.trincoll.edu> Matthew Prince, mprince@mail.trincoll.edu writes: >I'm confused. I thought that I'd venture into the world of Offscreen >GWorld drawing with my new copy of Inside Macintosh Imaging. I thought >that everything would be nice and easy. I thought that I could have >everything working in a few days, and if not, I could figure out what >was wrong easily. I was wrong. You bet! And you were using GWorlds -- try it with offscreen GrafPorts! It took me two years to find information on how to do it with GrafPorts. Of course, this was before I had access to all the wonderful information on the Internet! So things were harder to find back then... Anyway, I'm not sure what's going wrong with your code, but here's some source code to look at. First, here's what I do when I want to transfer from an offscreen GWorld to an onscreen window: UseOffWorld(gGeneralWorld); EraseRect(&thePort->portRect); /* do some drawing in the offscreen GWorld */ DoneWithOffWorld(gGeneralWorld); CopyBits(*GetGWorldPixMap(gGeneralWorld), &myWind->portBits, &myWind->portRect, &myWind->portRect, srcCopy, myWind->visRgn); Now, many of you may not recognize the UseOffWorld and DoneWithOffWorld calls. They're in a custom library I've written that contains code for both GWorlds and for GrafPorts. I'll stick the entire library at the end of this message. Hope this helps! -Thomas - ------- begin offscreen library --------- #define NIL 0L /* for BitMap calls */ #define kIsVisible TRUE #define kNoGoAway FALSE #define kNoWindowStorage 0L #define kFrontWindow ((WindowPtr) -1L) GDHandle gOldDevice; CGrafPtr gOldPort; void UseOffWorld(GWorldPtr offWorlder); /* call before drawing to offscreen GWorld */ void DoneWithOffWorld(GWorldPtr offWorlder); /* call after drawing to offscreen GWorld, before CopyBits */ Boolean CreateOffscreenBitMap(GrafPtr *, Rect *); void DestroyOffscreenBitMap(GrafPtr); void UseOffWorld(GWorldPtr offWorlder) { GetGWorld(&gOldPort, &gOldDevice); LockPixels(GetGWorldPixMap(offWorlder)); SetGWorld(offWorlder, NIL); } void DoneWithOffWorld(GWorldPtr offWorlder) { UnlockPixels(GetGWorldPixMap(offWorlder)); SetGWorld(gOldPort, gOldDevice); } /* === BitMap routines === */ Boolean CreateOffscreenBitMap(GrafPtr *newOffscreen, Rect *inBounds) { GrafPtr savePort; GrafPtr newPort; GetPort(&savePort); /* need this to restore thePort after OpenPort */ newPort = (GrafPtr)NewPtr(sizeof(GrafPort));/* allocate the grafPort */ if(MemError() != noErr) return FALSE; /* failure to allocate off-screen port */ /* the call to OpenPort does the following: allocates space for visRgn (set to screenBits.bounds) and clipRgn (set wide open) sets portBits to screenBits sets portRect to screenBits.bounds etc. (see Inside Macintosh Volume 1 pages 163-164) side effect: does a SetPort (&offScreen) */ OpenPort(newPort); /* make bitmap the size of the bounds that caller supplied */ newPort->portRect = *inBounds; newPort->portBits.bounds = *inBounds; RectRgn(newPort->clipRgn, inBounds); RectRgn(newPort->visRgn, inBounds); /* rowBytes is size of row, must be rounded up to an even number of bytes */ newPort->portBits.rowBytes = ((inBounds->right - inBounds->left + 15) >> 4) << 1; /* number of bytes in BitMap is rowBytes * number of rows */ /* see notes at end of example about using NewPtr instead of NewHandle */ newPort->portBits.baseAddr = NewPtr(newPort->portBits.rowBytes * (long)(inBounds->bottom - inBounds->top)); if(MemError() != noErr) { SetPort(savePort); ClosePort(newPort); /* dump the visRgn and clipRgn */ DisposPtr((Ptr)newPort); /* dump the GrafPort */ return FALSE; /* tell caller we failed */ } /* since the bits are just memory, let's clear them before we start */ EraseRect(inBounds);/* OpenPort did a SetPort(newPort) so we are OK*/ *newOffscreen = newPort; SetPort(savePort); return TRUE; /* success */ } /* DestroyOffscreenBitMap - get rid of an off-screen bitmap created by CreateOffscreenBitMap */ void DestroyOffscreenBitMap(GrafPtr oldOffscreen) { ClosePort(oldOffscreen); /* dump the visRgn and clipRgn */ DisposPtr(oldOffscreen->portBits.baseAddr); /* dump the bits */ DisposPtr((Ptr)oldOffscreen); /* dump the port */ } - ------- end offscreen library ---------- ===================================================== Thomas Reed Washington University Reed@telesphere.wustl.edu Medical School (also: Reed@medicine.wustl.edu) - --------------------------------------------------- Clothes make the man. Naked people have little or no influence on society. -- Mark Twain ===================================================== +++++++++++++++++++++++++++ >From tgaul@halcyon.com (Troy Gaul) Date: 9 May 1994 05:10:25 GMT Organization: Infinity Systems In article <2q9voq$nt1@yar.trincoll.edu>, mprince@mail.trincoll.edu (Matthew Prince) wrote: > I'm confused. I thought that I'd venture into the world of Offscreen > GWorld drawing with my new copy of Inside Macintosh Imaging. I thought > that everything would be nice and easy. I thought that I could have > everything working in a few days, and if not, I could figure out what > was wrong easily. I was wrong. I've set up an offscreen GWorld that > has the same dimensions as my on screen window. I think that it's set > up correctly because the first time that I CopyBits from it everything > works fine. And if I CopyBits a simple image it works fine too. But > when I try to CopyBits a complex image from it once, and then change > the image slightly and try to CopyBits it again, it looks as if someone > has taken a shotgun to the image. I'd say about half the pixels are > there. And while it's in the same basic shape and color of the > original image, it looks as if it's had a bunch of information lost. > I'm confused. It's late. I'm sure this is a stupid question. Please > forgive me. But if anyone has any idea what is going on, I'd > appreciate any help they could lend. Just to make sure this isn't the case (I don't have the New Inside Mac here to look at to see what they say about the topic): Are you locking the GWorld's pixel map before calling CopyBits? Also, when modifying the image between CopyBits's, are you setting and resetting the GWorld (with Get/SetGWorld)? GWorld's really aren't that bad once you get all of these little things worked out. Keep at it. You'll be glad you did. (And good luck.) _troy +++++++++++++++++++++++++++ >From Jens Alfke Date: Wed, 11 May 1994 18:41:07 GMT Organization: Apple Computer Matthew Prince, mprince@mail.trincoll.edu writes: > I'm confused. I thought that I'd venture into the world of Offscreen > GWorld drawing with my new copy of Inside Macintosh Imaging. I thought > that everything would be nice and easy. I thought that I could have > everything working in a few days, and if not, I could figure out what > was wrong easily. I was wrong. Matthew, for the crime of dissing GWorlds I sentence you to write offscreen color graphics code _without_ using them. (I did it once, with help from Andrew Welch. I could post some source code that would curl your hair!) Mistakes you might be making: - Don't make assumptions about the rowBytes of the offscreen data. It often gets rounded up for efficiency. Get the rowBytes out of the pixMap and use that in all your calculations. - If you're groping into the pixel data (which is fine) make sure to do your math with longints, as things can overflow 32k pretty quickly. - Remember that the pixel data is in a handle and can move around unless you lock it down with the appropriate calls. - When drawing, you must be set to the graphics world of the destination or colors will map wrong. I.e. SetGWorld to your offscreen world when drawing to it, and SetGWorld back to the screen when drawing to the screen from your offscreen world. I think once you figure out what mistake you're making, you'll find that GWorlds are actually pretty easy to use. --Jens Alfke jens_alfke@powertalk Rebel girl, rebel girl, .apple.com Rebel girl you are the queen of my world +++++++++++++++++++++++++++ >From dwareing@apanix.apana.org.au (David Wareing) Date: 10 May 94 15:28:23 GMT Organization: Apanix Public Access Unix, +61 8 373 5485 (5 lines) tgaul@halcyon.com (Troy Gaul) writes: >In article <2q9voq$nt1@yar.trincoll.edu>, mprince@mail.trincoll.edu >(Matthew Prince) wrote: >Just to make sure this isn't the case (I don't have the New Inside Mac here >to look at to see what they say about the topic): Are you locking the >GWorld's pixel map before calling CopyBits? I may be utterly wrong on this, and someone please correct me if I am, but I believe that CopyBits locks the PixMaps for you. But still, I guess its good programming practice to lock them anyway. >Also, when modifying the image between CopyBits's, are you setting and >resetting the GWorld (with Get/SetGWorld)? My money's on this one. Either that or the wrong rects are inadvertently being used after the GWorld PixMap has been altered, and CopyBits is scaling the image or otherwise screwing it up. >GWorld's really aren't that bad once you get all of these little things >worked out. Keep at it. You'll be glad you did. (And good luck.) Dead right. There's a hell of a lot more things to go wrong if you had to create and maintain your offscreen PixMaps by yourself. In fact, the only real obstacle to learning to use GWorlds is learning to use CopyBits properly first. In comparison, GWorlds are a breeze and easily one of the best things Apple ever came up with in the graphics dept. -- David Wareing Adelaide, South Australia Mac Games & Multimedia Development dwareing@apanix.apana.org.au - -------------------------------------------------------------------- +++++++++++++++++++++++++++ >From forrest@hprnd.rose.hp.com (Forrest Tanaka) Date: 16 May 1994 15:45:48 GMT Organization: Hewlett-Packard, Roseville Networks Division In article dwareing@apanix.apana.org.au (David Wareing) writes: > tgaul@halcyon.com (Troy Gaul) writes: > > >In article <2q9voq$nt1@yar.trincoll.edu>, mprince@mail.trincoll.edu > >(Matthew Prince) wrote: > > >Just to make sure this isn't the case (I don't have the New Inside Mac here > >to look at to see what they say about the topic): Are you locking the > >GWorld's pixel map before calling CopyBits? > > I may be utterly wrong on this, and someone please correct me if I am, but > I believe that CopyBits locks the PixMaps for you. But still, I guess its > good programming practice to lock them anyway. > There are two issues here. One is locking the GWorld's pixels, and one is locking the GWorld's PixMap. You *must* lock a GWorld's pixels before drawing into a GWorld, but you probably don't have to lock a GWorld's PixMap at any time. You must lock a GWorld's pixels because the pixel image of every GWorld is created as a relocatable block that's MoveHHi'd right after allocation. It just floats there like any other handle until you call LockPixels which locks the pixel image wherever it is in memory so that you can draw into it. As soon as you feel you're done drawing into it for now, you call UnlockPixels so that it can move in memory again. Remember, pixel images can be *very* big if you ask for a big GWorld, so don't be surprised if you find big delays as your pixel image is moved around. There might be times that you want to lock your pixel images just to be sure 10MB doesn't have to be moved in memory when you don't want it to. You probably don't ever have to lock a GWorld's PixMap, nor any PixMap for that matter. Color QuickDraw was designed so that you never have to lock a PixMap--all Color QuickDraw drawing routines expect that they're unlocked, so they do what they can to avoid moving them at a bad time. When I was in Apple DTS, I did find a bug where CopyBits had a very small but potential chance to move a PixMap structure and not take the fact that it moved into account. This can only happen if you have a Picture open at the time. I don't know if this was ever fixed. If you want to experiment with this one, try a simple program with heap scramble on in your low-level debugger of choice. > >GWorld's really aren't that bad once you get all of these little things > >worked out. Keep at it. You'll be glad you did. (And good luck.) > > Dead right. There's a hell of a lot more things to go wrong if you had to > create and maintain your offscreen PixMaps by yourself. In fact, the only > real obstacle to learning to use GWorlds is learning to use CopyBits > properly first. In comparison, GWorlds are a breeze and easily one of the > best things Apple ever came up with in the graphics dept. > I third that--it's more than worth it to try to get GWorld's working. Having seen the source code to GWorlds, I can assure you that they're not that magic if you don't have a QuickDraw accelerator card, and they're really fast if you do. If you use GWorlds, you can save yourself a lot of coding. > -- > David Wareing > Adelaide, South Australia > Mac Games & Multimedia Development dwareing@apanix.apana.org.au > ---------------------------------------------------------------------- -- Forrest Tanaka Hewlett-Packard, Roseville Networks Division Speaking on behalf of myself. --------------------------- >From partingt@fwi.uva.nl (Vincent Partington) Subject: Is FSpExchangeFiles still broken? Date: 13 May 1994 11:43:39 GMT Organization: FWI, University of Amsterdam Hi, I got a code-snippet from umich-mac last week which contains some code to do FSpExchangeFiles for volumes that don't support it (CAP a.o.). It came with a message from Jim Luther to Jon W{tte in which Jim said FSpExchangeFiles was broken on some third-party servers (and AU/X?) so he advised you to program around this bug with the code he supplied. I don't like cramming large bits of code into my program to fix a bug in the System software (just like the System shouldn't work around bugs of known programs...) so my questions is: is all this still necessary? Vincent. -- My opinions are not my own. I copy them | Internet : partingt@fwi.uva.nl from books, television, video, the net, | vincent@tnc.nl my friends, my parents, my teachers and | FidoNet : 2:281/202.15 and numerous other contributors. | NeST : 90:500/202.15 +++++++++++++++++++++++++++ >From zaccone@rigel.cs.bucknell.edu (Rick Zaccone) Date: 13 May 1994 14:51:43 GMT Organization: Bucknell University, Lewisburg, Pa. >I got a code-snippet from umich-mac last week which contains some code to >do FSpExchangeFiles for volumes that don't support it (CAP a.o.). >It came with a message from Jim Luther to Jon W{tte in which Jim said >FSpExchangeFiles was broken on some third-party servers (and AU/X?) so >he advised you to program around this bug with the code he supplied. >I don't like cramming large bits of code into my program to fix a bug in the >System software (just like the System shouldn't work around bugs of known >programs...) so my questions is: is all this still necessary? > >Vincent. Why not use PBHGetVolParms to find out if the volume supports FSpExchangeFiles? (That is, the bHasFileIDs bit of vMAttrib is set.) If it does, use it. Otherwise, save without it. There's one thing to watch out for though. AUX 3.0 will tell you it has file IDs when it fact it doesn't. I got a message from someone at Apple that said this is fixed in AUX 3.0.1 and later. Rick Zaccone -- zaccone@bucknell.edu +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 14 May 1994 03:02:53 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <2qvp5b$pp6@hermes.fwi.uva.nl>, partingt@fwi.uva.nl (Vincent Partington) writes: >I got a code-snippet from umich-mac last week which contains some code to >do FSpExchangeFiles for volumes that don't support it >... >is all this still necessary? FSpExchangeFiles is fixed by System Update 3.0. However, unless you can ensure that *all* users of your code update their systems, you need to include the work-around code. The latest and greatest version of the FSpExchangeFiles work-around, FSpExchangeFilesCompat(), can be found in MoreFiles 1.1 or later, the DTS sample code/library that I wrote. You can find it in the FSpCompat.c file. My code checks to see if the bug has been fixed and if not, does everything the right way. The fix will add around 800 bytes to your application (if you copy just the routines related to FSpExchangeFiles into your code) - well worth it if you depend on FSpExchangeFiles doing the right thing. If you really don't want to add that code, then use PBExchangeFiles instead of FSpExchangeFiles. PBExchangeFiles only works on volumes that support file reference IDs so it will fail with a paramErr (-50) on some volumes (mostly old external file systems or file servers that haven't been updated for System 7 features). That means you can't do the safe-save thing on those volumes without adding your own code (which will look a *lot* like the code in FSpExchangeFilesCompat). - Jim Luther --------------------------- >From andrew@random.demon.co.uk (Andrew Walker) Subject: Looping sounds Date: Sat, 14 May 1994 10:05:24 GMT Organization: Inner Workings How can I get a sound to loop? What I would like to acheive is to set up a channel which is dedicated to playing a 10 second piece of music over and over again. I have been trying to acheive this using the callBackCmd command but up until now I have been unsucessful. Is there anyone out there with any advice on how to acheive this? cheers, Andrew. ========================================================================= Andrew Walker - Inner Workings, Suite 406, The Pentagon Centre, 36 Washington Street, Glasgow, UK, G3 8AZ INTERNET:- andrew@random.demon.co.uk Compuserve:- 100102,1634 +++++++++++++++++++++++++++ >From alex@metcalf.demon.co.uk (Alex Metcalf) Date: Sat, 14 May 1994 13:19:55 GMT Organization: Best Before Yesterday In article <43@random.demon.co.uk>, andrew@random.demon.co.uk (Andrew Walker) wrote: > > > How can I get a sound to loop? > > What I would like to acheive is to set up a channel which is dedicated to > playing a 10 second piece of music over and over again. I have been trying > to acheive this using the callBackCmd command but up until now I have been > unsucessful. > > Is there anyone out there with any advice on how to acheive this? In a call back routine (when your sound finishes playing), you can't play the sound again, because the callback is an interrupt so playing a sound may move or purge memory. There are two solutions: just send the sound to the channel as many times as you like (hundreds if necessary). Make sure your sound channel queue length is big enough. or in your call back, set a global boolean saying "play again". Then, continuously call a routine in your main loop of your application which checks this boolean and starts the sound off if its true. in order to set the global boolean in your callback, you'll need to sent the current A5 setting as a parameter to the callback routine. You'll need GetA5 and SetA5. This second method will work indefinitely, but there will be a very small pause between the end of the sound and the time it takes to start it playing again. Hope this helps, Alex -- Alex Metcalf, Best Before Yesterday Mac programmer in C, C++, HyperTalk, assembler Internet, AOL, BIX: alex@metcalf.demon.co.uk "Surely you AppleLink: alex@metcalf.demon.co.uk@internet# can't be CompuServe: INTERNET:alex@metcalf.demon.co.uk serious?" Delphi: alex@metcalf.demon.co.uk@inet# FirstClass: alex@metcalf.demon.co.uk,Internet "I am serious... Fax (UK): (0570) 45636 and don't call Fax (US / Canada): 011 44 570 45636 me Shirley." +++++++++++++++++++++++++++ >From kluev@jonathan.srcc.msu.su (Kluev) Date: Sun, 15 May 94 20:31:21 +0400 Organization: (none) In article <43@random.demon.co.uk> alex@metcalf.demon.co.uk (Alex Metcalf) wrote: >In article <43@random.demon.co.uk>, andrew@random.demon.co.uk (Andrew >Walker) wrote: >> How can I get a sound to loop? >> >> What I would like to acheive is to set up a channel which is dedicated to >> playing a 10 second piece of music over and over again. I have been trying >> to acheive this using the callBackCmd command but up until now I have been >> unsucessful. >> >> Is there anyone out there with any advice on how to acheive this? > In a call back routine (when your sound finishes playing), you can't >play the sound again, because the callback is an interrupt so playing a >sound may move or purge memory. There was a thread about PlayingSoundAtInterruptTime some time ago, Here are extracts from there. You *CAN* play sound in callback procedure. Yes it is interrupt time and you can't issue some sound commands like "reinitCmd", "freeCmd" (via SndDisposeChannel), etc., i.e. commands that moves memory. But you can issue commands like "bufferCmd" to play sounds. By the way, QuickTime use this technique. Note however that with the presence of new sound manager (3.0) bufferCmd, sometimes needs to reconfigure channel. This happened when you start to play a "different sort" of sound. By "sort" I mean "Compressed or No", SampleRate, SampleSize, ... (May be this list is not exact). So to ensure that SM will not reconfigure channel (read: Move Memory) at interrupt time - issue first bufferCmd at main time, and feel free to call other bufferCmds at interrupt time (PROVIDED they are the same sort sound commands). Then, whenever you want to play different sort of sound - repeat from the beginning - First command at main, other commands at callback. The original poster's question was about sound looping: this can be done also by modifying loopStart and loopEnd fields, "installing sound as a voice" (using soundCmd) (IM VI terminology), and issuing freqCmd or freqDurationCmd. All this can be done within 'snd' resource, so you can just SndPlay on this resource and it will play forever. Michael Kluev. +++++++++++++++++++++++++++ >From folta@netcom.com (Steve Folta) Date: Mon, 16 May 1994 07:32:31 GMT Organization: NETCOM On-line Communication Services (408 261-4700 guest) andrew@random.demon.co.uk (Andrew Walker) writes: >How can I get a sound to loop? Install the sound with a soundCmd, start playing it with a freqCmd, stop it with a restCmd or quietCmd. If you want the sound to play out when you stop the looping, make sure your restCmd has a long enough duration. You can use a callBackCmd after the restCmd to set a flag when the sound is done, so you'll know when it's safe to dispose the sound (and the channel if you're not going to reuse it). Oh yeah, and make sure the looping points are set in the sound resource. -- Steve Folta folta@netcom.com +++++++++++++++++++++++++++ >From Thomas Reed Date: 16 May 1994 14:52:05 GMT Organization: Washington University In article Alex Metcalf, alex@metcalf.demon.co.uk writes: >just send the sound to the channel as many times as you like >or >in your call back, set a global boolean saying "play again". > >This second method will work indefinitely, but there will be a very small >pause between the end of the sound and the time it takes to start it >playing again. I wrote a small test program that uses the second method, and it works pretty well, with no pause most places. Of course, to manage this, you have to keep the sound channel open constantly, which, I've heard, can play havoc with other things. One combination of these two methods would be to constantly keep two sounds in the queue. When the one that's playing finishes, the next one will start playing, and you send the next sound into the queue. Doesn't need as big a queue, and there won't be any pause anywhere. (Well, not counting disk accesses or stuff like that.) If the original poster (or anyone else, for that matter) is interested in seeing my asynch sounds library, I'd be willing to e-mail it. -Thomas ===================================================== Thomas Reed Washington University Reed@telesphere.wustl.edu Medical School (also: Reed@medicine.wustl.edu) - --------------------------------------------------- Clothes make the man. Naked people have little or no influence on society. -- Mark Twain ===================================================== --------------------------- >From zwelch@nyx.cs.du.edu (Zach Welch) Subject: PPC Toolbox GetDefaultUser() bug Date: Sat, 7 May 94 20:57:54 GMT Organization: Nyx, Public Access Unix at U. of Denver Math/CS dept. Has anyone else out there had the problems I have had with the PPC Toolbox call GetDefaultUser()? I am using Symantec C++ 7.0 (I've tried it with 6.0 as well). I called Symantec Tech Support, and they couldn't get it to work either. Every time I try to make the call, I get the error return code noLoggedInErr (-923). The information in the Sharing Setup control panel is all valid, so that's not the problem. All I'm trying to do is get the name that appears there. I know that the info is saved in the Users & Groups Prefs file, thought I more than a little hesitant to try to hack the format. If anyone has any idea as to why this call always fails, please let me know. Zach ` +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 14 May 1994 01:51:04 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <1994May7.205754.23878@mnemosyne.cs.du.edu>, zwelch@nyx.cs.du.edu (Zach Welch) writes: >Every time I try to make the call, I get the error return code >noLoggedInErr (-923). That error means the default user reference hasn't been used yet, or that it has been deleted. "Huh, what's the default user reference" you say? Let me explain... Each time a PPC Toolbox session is authenticated, PPCStart() (via StartSecureSession()) returns a user reference number that's associated with the user name/password combination entered. That user reference number can be used to reopen a closed PPC Toolbox session using PPCStart() (and thus bypassing the user authentication dialog). One user reference number is special, the default user reference number. The default user reference number is associated with the user name/password combination that was entered in the Sharing Setup control panel and is created the first time a PPC connection is opened using that particular user name/password combination. So, if you call GetDefaultUser() and get the error noLoggedInErr, it means that either: a) the user hasn't authenticated a PPC Toolbox session using their default name and password, or b) some piece of code has deleted the default user reference number with DeleteUserIdentity(). By the way, the Event PPC code (what the Apple Event Manager uses to open PPC sessions) has a bug in that is deletes all user reference numbers returned by StartSecureSession(). It should only delete the non-default user reference numbers as shown in the example code on page 7-36 of Inside Macintosh volume VI. Fortunately, I believe it has been fixed for the future. I hope that explains PPC Toolbox user reference numbers better than IM did. User reference numbers were somewhat of a mystery to me when I reviewed that chapter of Inside Macintosh, but after we shipped System 7, I got to answer enough questions about them that I ended up digging the PPC Toolbox's sources to find out what they're really used for. - Jim Luther --------------------------- >From dazuma@cco.caltech.edu (Daniel Azuma) Subject: SU3.0 programming tip Date: Mon, 16 May 1994 07:10:45 -0700 Organization: California Institute of Technology, Pasadena Just a few quick things about programming with System Update 3.0 in mind. Some of us at TopSoft ran into these problems while debugging an alpha of FilterTop. We use a custom GetFile dialog to get a set of files. Similarly to THINK's and CodeWarrior's "add files..." commands, this dialog "adds" the files from the Standard File's list into a custom list below, and then opens the files en masse when the user clicks "done". Our first problem was that, starting with SU 3.0, it appears that passing sfItemOpenButton back from the DlogHook does NOT dismiss the dialog IF no items are selected in the Standard File package's main list. We were mapping presses of our "done" button to sfItemOpenButton in order to dismiss the dialog, and all of a sudden, that stopped working in the case where we had items present in our "to add" list but nothing actually selected in the Standard File's main list. This wasn't happening before we installed SU 3!! The solution, should you run into this, is to return sfItemCancelButton instead from your DlogHook, whenever you want to dismiss the dialog and it is possible that nothing is selected in the Standard File's main list. The second problem has to do with the new (very cool) color icons. There are certain circumstances when they're not color! One notable example is the Open... dialog in Microsoft Word (definitely version 5.1a, but probably all the others as well). The reason is, if you use a custom "DLOG" resource for your GetFile dialog, you also need to include a "dctb" resource in order for it to plot color icons. The easiest way to add a "dctb" resource is to do the following: 1) Open the appropriate "DLOG" resource in ResEdit 2.1.1. 2) Change the color option radio button to "custom". 3) Use the pop-ups to change one of the colors (doesn't matter which one). 4) Click ok in the alert that pops up. 5) Use the pop-ups to change the color BACK to what it was. Hope this makes life easier for someone! -Dan (Thanks to George Tempel and Jim Brunner for their help in tracking this down.) _______________________________________________________________________ Daniel Azuma | "Life's bad enough as it is without wanting Caltech | to invent any more of it." dazuma@cco.caltech.edu | --Douglas Adams --------------------------- End of C.S.M.P. Digest **********************