From: pottier@clipper.ens.fr (Francois Pottier) Subject: csmp-digest-v3-016 Date: Mon, 18 Apr 94 14:57:43 MET DST C.S.M.P. Digest Mon, 18 Apr 94 Volume 3 : Issue 16 Today's Topics: AppleTalk ON and OFF CtoPstr in THINK C 6.0 Highlight colour? Picture Recording Speeding up animation; questions Tools to improve segmentation? copy file question, code available? skeleton code generators? 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 makmur@aramis.rutgers.edu (Hanz Makmur) Subject: AppleTalk ON and OFF Date: 18 Mar 94 21:02:12 GMT Organization: Rutgers Univ., New Brunswick, N.J. Hi.. I am learning how to program a Mac and trying to figure out a way to Turn ON and Off appletalk at will from a program. Does anyone have any idea how to do this ? There is a program called: AppleTalkON by Jon Pugh@apple that does appletalk ON and OFF. I tried to contact Jon but it looks like he is no longer at Apple. If any one can help, I appreciate the help. A pointer or sample source code will help. Thank you. Hanz If possible at all, please reply by mail to: makmur@cs.rutgers.edu -- - ---------------------------The opinions expressed in this message are Hanz Makmur my own and do not necessarily reflect those of makmur@cs.rutgers.edu The State University of New Jersey. U.S.A +++++++++++++++++++++++++++ >From jonpugh@netcom.com (Jon Pugh) Date: Sun, 20 Mar 1994 07:41:23 GMT Organization: NETCOM On-line Communication Services (408 241-9760 guest) Hanz Makmur (makmur@aramis.rutgers.edu) wrote: > Does anyone have any idea how to do this ? There is a program called: > AppleTalkON by Jon Pugh@apple that does appletalk ON and OFF. I tried > to contact Jon but it looks like he is no longer at Apple. That doesn't mean I'm dead. ;) I simply call MPPOpen and MPPClose. If you want it to stick across reboots then you also need to twiddle the PortB global. See IM 1-3 for the specifics. Jon +++++++++++++++++++++++++++ >From zben@ni.umd.edu (Charles B. Cranston) Date: 20 Mar 1994 19:02:31 GMT Organization: UMCP Network Infrastructures In article , jonpugh@netcom.com (Jon Pugh) wrote: > I simply call MPPOpen and MPPClose. If you want it to stick across reboots > then you also need to twiddle the PortB global. See IM 1-3 for the > specifics. I've written an INIT to force it on and off. It does a reboot to get the change to 'take'. Does the code below do the appropriate kind of fiddling with the PortB global? I just dumped PRAM and found it contained 1 in one case and 2 in the other. In particular, IM 1-3 was written when ALAP was the only LAP for AppleTalk and the extension to a world in which the Ether/Token LAPs are also an alternative is not obvious to me... =============== ... Move.L #$00010013,D0 ; Byte 13 LEA S.Curr(A6),A0 ; Point to stack space _ReadXPram ; Read current setting from parameter RAM BNE.S @900 ; If error then get out Move.B #1,D1 ; Get "ON" value Tst.L S.Want(A6) ; Do we want it on? BNE.S @040 ; Yes, go set it ON Move.B #2,D1 ; Else get "OFF" value @040 ; LEA S.Curr(A6),A0 ; Get address of current value Move.B (A0),D2 ; Get current value And.B #$0F,D2 ; Get AppleTalk config bits Cmp.B D2,D1 ; Is it the desired value? BEq.S @050 ; Yes, go check LAP status * * Rewrite AppleTalk On/Off selection in PRAM and force reboot. * Move.B (A0),D2 ; Get current value And.B #$F0,D2 ; Keep upper 4 bits Or.B D1,D2 ; Use our lower bits Move.B D2,(A0) ; Set current value Move.L #$00010013,D0 ; Bytes E0 thru E3 _WriteXPram ; Write back to parameter RAM Move.W #1,S.Boot(A6) ; Set flag to force reboot ... =============== Title 'Force AppleTalk and LAP settings' ; * * Module for "Force" shell. * Ben Cranston March 1, 1994 * Print Off ; Here be includes Include 'RomEqu.a' ; Include 'Traps.a' ; Print On,NoGen ; Here be includes Main ; Begin module * S Record {A6Link},Decr ; Stack frame A6Link DS.L 1 ; Caller's A6 SPB DS SpBlock ; Slot Parameter Block Curr DS.L 1 ; Current PRAM value Want DS.L 1 ; Desired PRAM value Flag DS.W 1 ; Desired PRAM setup flags Boot DS.W 1 ; Set if reboot required SS Equ * ; Stack size EndR ; Stack frame * * Get resource containing the desired PRAM contents. * Link A6,#S.SS ; Make local frame Clr.W S.Boot(A6) ; Initially set no reboot Tst.L D1 ; Was our data resource present? BEq.W @999 ; If not then just return Move.L D1,A0 ; Get resource handle Move.L (A0),A0 ; Get pointer Move.W (A0),S.Flag(A6) ; Get desired value * Eject ; * * Test if AppleTalk is to be turned off entirely. * Clr.L S.Want(A6) ; Initially set AppleTalk OFF Move.B S.Flag+0(A6),D1 ; Get master flag BEq.S @030 ; Is AppleTalk to be turned off entirely? * * Test if LocalTalk is wanted. * Move.B #1,S.Want+3(A6) ; Set AppleTalk on LocalTalk Cmp.B #1,D1 ; Want LocalTalk or EtherTalk? BEq.S @030 ; Want EtherTalk, skip * * Find Ethernet card address to complete the desired PRAM value. * LEA S.SPB(A6),A0 ; Get spBlock address Move.B S.Flag+1(A6),spBlock.spSlot(A0) ; Set slot to start searching at Clr.B spBlock.spId(A0) ; Find any resource number Clr.B spBlock.spExtDev(A0) ; External device zero? Clr.B spBlock.spHwDev(A0) ; Ignore external hardware Move.B #3,spBlock.spTBMask(A0) ; Look at Category and CType Move.W #catNetwork,spBlock.spCategory(A0) ; Network category Move.W #typEtherNet,spBlock.spCType(A0) ; EtherNet type _sNextTypesRsrc ; Get next sResource info BNE.W @900 ; If nofind then get out Move.B spBlock.spSlot(A0),S.Want+0(A6) ; Get network card slot number Move.B spBlock.spId(A0),S.Want+1(A6) ; Get slot resource ID number Clr.B S.Want+2(A6) ; Clear unused field Move.B #$A,D1 ; Get EtherTalk Phase 2 code Cmp.B #2,S.Flag+0(A6) ; Did he want Phase 1? BNE.S @020 ; If not then assume Phase 2 Move.B #$2,D1 ; Get EtherTalk Phase 1 code @020 ; Move.B D1,S.Want+3(A6) ; Set Phase 1 / Phase 2 code * Eject ; * * Read PRAM for AppleTalk On/Off selection, decide if we must change it. * @030 ; Move.L #$00010013,D0 ; Byte 13 LEA S.Curr(A6),A0 ; Point to stack space _ReadXPram ; Read current setting from parameter RAM BNE.S @900 ; If error then get out Move.B #1,D1 ; Get "ON" value Tst.L S.Want(A6) ; Do we want it on? BNE.S @040 ; Yes, go set it ON Move.B #2,D1 ; Else get "OFF" value @040 ; LEA S.Curr(A6),A0 ; Get address of current value Move.B (A0),D2 ; Get current value And.B #$0F,D2 ; Get AppleTalk config bits Cmp.B D2,D1 ; Is it the desired value? BEq.S @050 ; Yes, go check LAP status * * Rewrite AppleTalk On/Off selection in PRAM and force reboot. * Move.B (A0),D2 ; Get current value And.B #$F0,D2 ; Keep upper 4 bits Or.B D1,D2 ; Use our lower bits Move.B D2,(A0) ; Set current value Move.L #$00010013,D0 ; Bytes E0 thru E3 _WriteXPram ; Write back to parameter RAM Move.W #1,S.Boot(A6) ; Set flag to force reboot Tst.L S.Want(A6) ; Did we want it off? BEq.S @999 ; Yes, we are done * Eject ; * * Read PRAM for AppleTalk LAP selection, decide if we must change it. * @050 ; Move.L #$000400E0,D0 ; Bytes E0 thru E3 LEA S.Curr(A6),A0 ; Point to stack space _ReadXPram ; Read current from parameter RAM BNE.S @900 ; If error then get out Move.B S.Curr+1(A6),D1 ; Get current alt atalk type Cmp.B S.Want+1(A6),D1 ; Same as desired? BNE.S @060 ; No, must reset and reboot Move.B S.Curr+3(A6),D1 ; Get current alt level Cmp.B S.Want+3(A6),D1 ; Same as desired? BEq.S @999 ; If so then skip * * Rewrite AppleTalk LAP selection in PRAM and force reboot. * @060 ; LEA S.Want(A6),A0 ; Get address of desired Move.L #$000400E0,D0 ; Bytes E0 thru E3 _WriteXPram ; Write back to parameter RAM Move.W #1,S.Boot(A6) ; Set flag to force reboot Bra.S @999 ; Return to driver * * Some kind of error, just return OK status. * @900 ; Clr.W S.Boot(A6) ; Set no reboot * @999 ; Move.W S.Boot(A6),D0 ; Set return value UnLk A6 ; Drop local frame RTS ; Return to INIT31 * EndMain ; Keep MPW happy End ; ForceAppleTalk.a +++++++++++++++++++++++++++ >From walkerj@math.scarolina.edu (Jim Walker) Date: 21 Mar 1994 02:42:16 GMT Organization: University of South Carolina - Columbia - Computer Science jonpugh@netcom.com (Jon Pugh) writes: >I simply call MPPOpen and MPPClose. If you want it to stick across reboots >then you also need to twiddle the PortB global. See IM 1-3 for the >specifics. When I tried MPPOpen, I got a -98 error unless I cleared the low nybble of SPConfig first. The current AppleTalk.h says that MPPClose is obsolete, but so far as I know Apple has not released a new Inside Mac volume discussing AppleTalk. Anyone know what should be used instead of MPPClose? -- -- Jim Walker USC Dept. of Math. walkerj@math.scarolina.edu +++++++++++++++++++++++++++ >From mahboud@aggroup.com (Mahboud Zabetian) Date: Mon, 21 Mar 1994 12:43:21 -0800 Organization: AG Group, Inc. In article <2mj1i8$jki@redwood.cs.scarolina.edu>, walkerj@math.scarolina.edu (Jim Walker) wrote: > jonpugh@netcom.com (Jon Pugh) writes: > > >I simply call MPPOpen and MPPClose. If you want it to stick across reboots > >then you also need to twiddle the PortB global. See IM 1-3 for the > >specifics. > > When I tried MPPOpen, I got a -98 error unless I cleared the low nybble of > SPConfig first. > > The current AppleTalk.h says that MPPClose is obsolete, but so far as I know > Apple has not released a new Inside Mac volume discussing AppleTalk. Anyone > know what should be used instead of MPPClose? > > I remember seeing a TechNote that said use PBOpen (OpenDriver) and PBClose instead. Check the Networking TechNotes. I believe that MPPClose is one of the calls that will not be ported to the PowerPC. I think that it will still be available emulated, but if your native app want to get to it, it'll have to go through some hoops. -mahboud - ------------------------------------------------------------- Mahboud Zabetian mahboud@aggroup.com ag group, inc. 2540 camino diablo, suite 200 walnut creek, ca 94596 510-937-7900 voice 510-937-2479 fax 510-937-6704 ara ftp.aggroup.com anonymous ftp +++++++++++++++++++++++++++ >From Mark_Day@powertalk.apple.com (Mark Day) Date: Fri, 1 Apr 1994 18:10:08 GMT Organization: Apple Computer, Inc. In article <2mj1i8$jki@redwood.cs.scarolina.edu>, walkerj@math.scarolina.edu (Jim Walker) wrote: > When I tried MPPOpen, I got a -98 error unless I cleared the low nybble of > SPConfig first. Fiddling with SPConfig sounds kind of dangerous. If .MPP won't open the printer port for LocalTalk, it's probably because some other piece of software says it is still using the port. I'd suggest tracking down what other code thinks it's using the printer port, first (and make sure it clears the in use bit when it really is done with the port). > The current AppleTalk.h says that MPPClose is obsolete, but so far as I know > Apple has not released a new Inside Mac volume discussing AppleTalk. Anyone > know what should be used instead of MPPClose? MPPOpen is the equivalent of OpenDriver(".MPP"), and MPPClose is equivalent to closing the .MPP driver. Theoretically, you shouldn't close the network drivers from your application because some other application may be using them. Ask yourself if you REALLY need to close .MPP. If you do have a valid reason to close the driver (for example, you're providing a user with the ability to turn AppleTalk on or off, like the Chooser does), I'd suggest using OpenDriver and CloseDriver on the .MPP driver. The other thing you should look at is the AppleTalk Transition Queue, which is used to notify clients of changes to AppleTalk's state. I don't know enough of the details to tell you what the right thing to do is, there. It's documented, but offhand, I don't know where. -- Mark Day, Apple Computer, Inc. mday@apple.com +++++++++++++++++++++++++++ >From walkerj@math.scarolina.edu (Jim Walker) Date: 2 Apr 1994 04:28:54 GMT Organization: University of South Carolina - Columbia - Computer Science Mark_Day@powertalk.apple.com (Mark Day) writes: >If you do have a valid reason to close the driver (for example, you're >providing a user with the ability to turn AppleTalk on or off, like the >Chooser does), I'd suggest using OpenDriver and CloseDriver on the .MPP >driver. Yes, that's the idea, I want to make a utility that turns AppleTalk on and off. I would not do that without the user's consent. But unlike the Chooser, I would like to be able to turn AppleTalk on without restarting the Mac. Calling OpenDriver on .MPP just gives a -23 error in that case. Anyone know the trick? -- -- Jim Walker USC Dept. of Math. walkerj@math.scarolina.edu +++++++++++++++++++++++++++ >From ugtalbot@mcs.drexel.edu (George T. "14K F/D" Talbot) Date: Sat, 2 Apr 94 20:54:00 GMT Organization: Drexel University In article <2nisa6$i6u@redwood.cs.scarolina.edu> walkerj@math.scarolina.edu (Jim Walker) writes: >Mark_Day@powertalk.apple.com (Mark Day) writes: > >>If you do have a valid reason to close the driver (for example, you're >>providing a user with the ability to turn AppleTalk on or off, like the >>Chooser does), I'd suggest using OpenDriver and CloseDriver on the .MPP >>driver. > >Yes, that's the idea, I want to make a utility that turns AppleTalk on and >off. I would not do that without the user's consent. But unlike the >Chooser, I would like to be able to turn AppleTalk on without restarting the >Mac. Calling OpenDriver on .MPP just gives a -23 error in that case. >Anyone know the trick? >-- > > -- Jim Walker USC Dept. of Math. walkerj@math.scarolina.edu I've run into this using the .ENET driver. You have to set the read/write permissions in the Open parameter block to fsSharedRdWrPerm (or something like that) to open the driver. This means you'll have to use the PBOpen call, rather than OpenDriver. Hope this helps. -- George T. Talbot - ------------------------------------------------------------------------- Finger my account for PGP public key. | This is very political software. +++++++++++++++++++++++++++ >From mahboud@aggroup.com (mahboud) Date: Mon, 04 Apr 1994 15:53:33 -0800 Organization: AG Group, Inc. In article <2nisa6$i6u@redwood.cs.scarolina.edu>, walkerj@math.scarolina.edu (Jim Walker) wrote: > Mark_Day@powertalk.apple.com (Mark Day) writes: > > >If you do have a valid reason to close the driver (for example, you're > >providing a user with the ability to turn AppleTalk on or off, like the > >Chooser does), I'd suggest using OpenDriver and CloseDriver on the .MPP > >driver. > > Yes, that's the idea, I want to make a utility that turns AppleTalk on and > off. I would not do that without the user's consent. But unlike the > Chooser, I would like to be able to turn AppleTalk on without restarting the > Mac. Calling OpenDriver on .MPP just gives a -23 error in that case. > Anyone know the trick? > -- > > -- Jim Walker USC Dept. of Math. walkerj@math.scarolina.edu If AppleTalk was off when you restarted, a major portion of its code will not be in memory and will not be loaded up with an MPPOpen (or PBOpen) call. This cahnge was put in after the original System 7 Tuner in order to save about 100K of memory for people who are not using their macs on networks. I think that you will have to restart if you did not have AppleTalk active, the last time you restarted. On the other hand, I have had no trouble turning AppleTalk off and on, if it was already active. I use MPPOpen and MPPClose. -mahboud - ------------------------------------------------------------- Mahboud Zabetian mahboud@aggroup.com ag group, inc. 2540 camino diablo, suite 200 walnut creek, ca 94596 510-937-7900 voice 510-937-2479 fax 510-937-6704 ara ftp.aggroup.com anonymous ftp --------------------------- >From wang_dj@dev.gdb.org (David J. Wang) Subject: CtoPstr in THINK C 6.0 Date: Sat, 2 Apr 1994 01:40:17 GMT Organization: Genome Database I have a newbie programmer question. Can anyone instruct me as to the correct way to use CtoPstr and PtoCstr. I suppose the problem isn't so much in using those functions, but rather trying to pass the result to a function that requires a Str255 (for example DrawString() ). For example: char *foo; CtoPstr(foo); DrawString(WHAT GOES IN HERE?); or am I totally off base. On a related note, why does CtoPstr take a pointer to a char for an argument while PtoCstr take a pointer to an unsigned char. This being the case, does that mean that I have to always cast one or the other? Finally, I would appreciate any hints in getting started in Mac programming, or where I could turn (good books, etc). Thanks, David -- ************************************************************************* David J. Wang #include wang_dj@gdb.org (410)614-0393 wang_dj@server.cs.jhu.edu Biology@The Johns Hopkins University Baltimore, Maryland 21210 ************************************************************************/ +++++++++++++++++++++++++++ >From omh@cs.brown.edu (Owen M. Hartnett) Date: Sat, 2 Apr 1994 05:10:17 GMT Organization: Brown University Department of Computer Science In article <1994Apr2.014017.6498@news.gdb.org> wang_dj@dev.gdb.org (David J. Wang) writes: >I have a newbie programmer question. Can anyone instruct me as to the >correct way to use CtoPstr and PtoCstr. I suppose the problem isn't >so much in using those functions, but rather trying to pass the result >to a function that requires a Str255 (for example DrawString() ). >For example: > char *foo; > CtoPstr(foo); > DrawString(WHAT GOES IN HERE?); > > or am I totally off base. On a related note, why does CtoPstr >take a pointer to a char for an argument while PtoCstr take a pointer >to an unsigned char. This being the case, does that mean that I have >to always cast one or the other? > >Finally, I would appreciate any hints in getting started in Mac >programming, or where I could turn (good books, etc). > Hi David! This is an excellent newbie question. Thanks for posing it. Your question actually has many facets, so I will attempt to answer the whole scope here. 1) First of all, in your code above, strictly speaking, will cause the computer to crash. The definition: char *foo; only defines enough space for a pointer to a string of characters, not the string itself. You have to define the space yourself, as in: char foo[255]; This allocates an array of 255 characters and makes space for the characters themselves. Once you do this you can than use the name of the array, foo, as a pointer to the first character, foo[0]. Thus, you could assign it to another char pointer, as so: char *foo char bar[255]; foo = bar; This will make the pointer foo act the same as the pointer bar. 2) I went through the above explanation even though I thought you might already know it because of the way you used your code example. Also, I wanted to point out the fact that CtoPstr and PtoCstr change the strings *in place*. They expect that you are passing to them a pointer to a string of characters which already exist in memory, and they move the test over a byte one way or the other and write in either a trailing zero or a beginning length byte. 3) Because of the nature of these bad boys, and that the string you want to C may be declared as C or P or vice versa, you end up casting a lot. A useful type for casting is StringPtr. This can be used to cast a char * into a Str255 * (which you can't do directly, hence your above problem.) Thus, here is the compleat guide for string casting, along with sundry baits and lures: char foo[255]; Str255 bar; char mac[255]; Str255 ibm; /* Assume appropriate data has been moved into strings */ /* straight, no casting required */ CtoPstr(foo); PtoCstr(bar); /* cast your pointers to the winds! */ CtoPstr((char *) ibm); PtoCstr((StringPtr) mac); Remember, let he whose programs are without bugs cast the first pointers. -Owen -Owen -- Owen Hartnett omh@cs.brown.edu "FAITH, n. Belief without evidence in what is told by one who speaks without knowledge, of things without parallel." -Ambrose Bierce - The Devil's Dictionary +++++++++++++++++++++++++++ >From benh@fdn.org (Benjamin Herrenschmidt) Date: Sun, 3 Apr 94 12:36:41 +0100 Organization: (none) Be careful to allocate your Pascal string as an array of 256 chars, not 255 ! There is the length byte ! char foo[256]; // is ok. Str255 foo; // is ok too BenH. --------------------------- >From ikb_macd@ECE.Concordia.CA (Ian Keith Baker Mac Donald) Subject: Highlight colour? Date: Mon, 4 Apr 1994 03:59:56 GMT Organization: ECE - Concordia University I'd like to use the highlight colour as specified by the user in the Colors control panel, can anyone tell me how to get the color information? IM says that there's a global called HiliteRGB, but ThinkP doesn't recognize it. Thanks, Keith +++++++++++++++++++++++++++ >From rlvd_cif@uhura.cc.rochester.edu (Rob Levandowski) Date: Mon, 4 Apr 94 05:27:18 GMT Organization: University of Rochester - Rochester, New York In ikb_macd@ECE.Concordia.CA (Ian Keith Baker Mac Donald) writes: >I'd like to use the highlight colour as specified by the user in the Colors >control panel, can anyone tell me how to get the color information? IM >says that there's a global called HiliteRGB, but ThinkP doesn't recognize >it. >Thanks, >Keith Try adding "SysEqu.p" to your project. The recommended way to use the hilight colour is detailed in Inside Mac vol. V, p. V-61. (I don't have the new IM.) Issue the command BitClr(Ptr(Hilite,pHiliteBit)); immediately before InvertRect,InvertRgn,InvertArc,InvertRoundRct, or InvertPoly, or any other drawing done in srcXor mode. The inversion will be done using the user-selected hilite color on a color-capable Mac; otherwise B&W is used. This is safe to call on all Macs. You must make the call immediately before each call that you want to use hilite color with; it is reset each time a drawing call is made. -- --Rob Levandowski Computer Interest Floor associate / University of Rochester macwhiz@cif.rochester.edu [Opinions expressed are mine, not UR's.] +++++++++++++++++++++++++++ >From platypus@cirrus.som.cwru.edu (Gary Kacmarcik) Date: 04 Apr 1994 13:26:38 GMT Organization: Case Western Reserve University, Cleveland, Ohio (USA) In article <1994Apr4.052718.8957@galileo.cc.rochester.edu> rlvd_cif@uhura.cc.rochester.edu (Rob Levandowski) writes: > > In ikb_macd@ECE.Concordia.CA (Ian Keith Baker Mac Donald) writes: > > >I'd like to use the highlight colour as specified by the user in the Colors > >control panel, can anyone tell me how to get the color information? IM > >says that there's a global called HiliteRGB, but ThinkP doesn't recognize > >it. > > The recommended way to use the hilight colour is detailed in Inside Mac > vol. V, p. V-61. (I don't have the new IM.) Issue the command > > BitClr(Ptr(Hilite,pHiliteBit)); > > immediately before InvertRect,InvertRgn,InvertArc,InvertRoundRct, or this is no longer the recommended way to do this. in fact, accessing any Low Memory global _directly_ is frowned upon. the proper way is to use the accessor functions: extern unsigned char LMGetHiliteMode(void); extern void LMSetHiliteMode(unsigned char HiliteModeValue); these are defined as part of the new Universal Headers (in LowMem.h) if you compile a native version of your code using the "set the Low Mem global directly" method, you are likely to run into problems. > This is safe to call on all Macs. the direct method is "safe" to call on all 68k macs and PowerMacs running in 68k emulation, but not on PowerMacs in native mode. the accessor functions will compile to the right thing on 68k and PowerPC based Macs. -gary j kacmarcik platypus@curie.ces.cwru.edu +++++++++++++++++++++++++++ >From d88-jwa@mumrik.nada.kth.se (Jon Wätte) Date: 4 Apr 1994 14:19:07 GMT Organization: The Royal Institute of Technology In platypus@cirrus.som.cwru.edu (Gary Kacmarcik) writes: >this is no longer the recommended way to do this. in fact, accessing >any Low Memory global _directly_ is frowned upon. That's because the new Macintosh OS will supposedly do away with the globals, but retain accessors for the equivalent functionality. > extern unsigned char LMGetHiliteMode(void); > extern void LMSetHiliteMode(unsigned char HiliteModeValue); >these are defined as part of the new Universal Headers (in LowMem.h) Yes, but using the lo-mem global at all is only marginally better than addressing it directly. Instead, use PenMode(hilite) like so: PenMode ( hilite ) ; InvertRgn ( selectionRgn ) ; >if you compile a native version of your code using the "set the Low Mem >global directly" method, you are likely to run into problems. No problem. ALL lo-mem globals are still there on the PowerPC. I spoke to an engineer who translated part of ROM (things like Button :-) and he said they pretty much kept ALL quirks of the ROM, for compatibility (like journalling, which is why Button may move memory) -- -- Jon W{tte, h+@nada.kth.se, Mac Hacker Deluxe -- Not speaking for the Liberian Government. --------------------------- >From weip@engin.umich.edu (Patrick Wei) Subject: Picture Recording Date: 4 Apr 1994 17:22:32 GMT Organization: University of Michigan Engineering, Ann Arbor I can't seem to get drawing information recorded into a picture that is loaded from a resource file. Should I call OpenPicture in addition to DrawPicture? The code is the following: - -------------------------------- resFileNum = OpenResFile( (ConstStr255Param) pictInfo[j].name); if((thePicture = GetPicture( (short) pictInfo[j].id)) == 0) { printf("can't get picture\n"); goto end_of_loop; } r = (*thePicture)->picFrame; width = r.right - r.left; height = r.bottom - r.top; SetRect(&r, 0, 0, width, height); OffsetRect(&r, 50, 50); DrawPicture(thePicture, &r); followed by a bunch of Line and LineTo operations. //save resource { Handle pictHandle; PtrToHand(*thePicture, &pictHandle, (*thePicture)->picSize); AddResource(pictHandle, 'PICT', 401, "\p"); CloseResFile(resFileNum); } - -------------------------------------- When I tried the save thePicture, the original picture is saved to disk, not the altered version that I want. The drawing information is never recorded into the picture +++++++++++++++++++++++++++ >From Carl R. Osterwald Date: Mon, 4 Apr 94 21:43:51 GMT Organization: National Renewable Energy Laboratory In article <2npicoINNq72@srvr1.engin.umich.edu> Patrick Wei, weip@engin.umich.edu writes: >I can't seem to get drawing information recorded into a picture that is loaded from >a resource file. Should I call OpenPicture in addition to DrawPicture? > resFileNum = OpenResFile( (ConstStr255Param) pictInfo[j].name); > DrawPicture(thePicture, &r); > > followed by a bunch of Line and LineTo operations. > > //save resource > { > Handle pictHandle; > PtrToHand(*thePicture, &pictHandle, (*thePicture)->picSize); > AddResource(pictHandle, 'PICT', 401, "\p"); > CloseResFile(resFileNum); > } >When I tried the save thePicture, the original picture is saved to disk, not the altered >version that I want. The drawing information is never recorded into the picture If you are trying to make a new PICT, you have to use: * OpenPicture * (QD drawing commands) * ClosePicture * AddResource If you are trying to modify or add to an existing PICT, you need: * OpenPicture (new pic) * DrawPicture (existing pic) * (QD drawing commands) * ClosePicture (new pic) * RemoveResourse (existing pic) * AddResource You also could use ChangedResourse instead of Add/Remove, but you would have to make the existing pic the same as the new pic with something like: * SetHandleSize(0) (existing pic) * HandAndHand(new pic, existing pic) * ChangedResourse (existing pic) +++++++++++++++++++++++++++ >From scottsquir@aol.com (ScottSquir) Date: 5 Apr 1994 02:50:04 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <2npicoINNq72@srvr1.engin.umich.edu>, weip@engin.umich.edu (Patrick Wei) writes: >Should I call OpenPicture in addition to DrawPicture? yes, you need to do an OpenPicture to start recording QuickDraw operations and then close it to create a PICT resource. -scott +++++++++++++++++++++++++++ >From jwbaxter@olympus.net (John W. Baxter) Date: Mon, 04 Apr 1994 22:05:26 -0700 Organization: Internet for the Olympic Peninsula In article , Carl R. Osterwald wrote: > If you are trying to modify or add to an existing PICT, you need: > * OpenPicture (new pic) > * DrawPicture (existing pic) > * (QD drawing commands) > * ClosePicture (new pic) > * RemoveResourse (existing pic) > * AddResource Remembering along the way that the existing PICT resource is quite likely to be marked purgeable, so it may have gone away between being gotten (getPicture () or getResource () and the time above when you are ready to call DrawPicture () on it. A LoadResource () to ensure that it's still around would be a nice idea. Or a variety of possibilities to keep it from being purged. -- John Baxter Port Ludlow, WA, USA [West shore, Puget Sound] jwbaxter@pt.olympus.net --------------------------- >From ua025@freenet.Victoria.BC.CA (Cody Jones) Subject: Speeding up animation; questions Date: Sun, 27 Mar 1994 09:13:55 GMT Organization: The Victoria Freenet Association (VIFA), Victoria, B.C., Canada A fair number of coders are complaining about the Mac's lack of screen-pages. Perhaps I may suggest a technique I'm presently using. Maybe you are all already acceptably aquainted [and aggravated by my alliteration - sorry, couldn't help myself] with it, but I may as well mention it. Divide your 8-bit palette into 2 halves. You now have 2, 4-bit screens. It's simple to switch screens - it's just a palette change. You can draw directly onto the screen (using nondisplaying colors, of course) - there's no need to assemble all your images in an off-screen buffer and blit it the screen. There's only two drawbacks: you only get 16 colors, and you need 2 copies of every sprite/background. (Why a second copy? Because otherwise you'd have to shift every pixel left 4 bits before drawing it onto your second page. Slow.) I am presently hacking away at a Doom-style engine, and using a 4-bit grayscale palette with this method looks pretty decent. I hope that other people will also try doing decent things with this technique. Cody Jones, Zerius Development -- +++++++++++++++++++++++++++ >From pburgess@netcom.com (Phillip Burgess) Date: Sun, 27 Mar 1994 22:59:16 GMT Organization: NETCOM On-line Communication Services (408 241-9760 guest) ua025@freenet.Victoria.BC.CA (Cody Jones) writes: >Divide your 8-bit palette into 2 halves. You now have 2, 4-bit screens. >It's simple to switch screens - it's just a palette change. The thought had occurred to me... I just assumed it would be much too slow doing all that bit wrangling to draw stuff. How un-scientific of me! What sort of speed improvement are you getting with this technique vs. 8-bit drawing & CopyBits? 8-D.. . . <- Me, drooling like an imbecile -- Phillip Burgess (pburgess@netcom.com) +++++++++++++++++++++++++++ >From ua025@freenet.Victoria.BC.CA (Cody Jones) Date: Mon, 28 Mar 1994 06:29:19 GMT Organization: The Victoria Freenet Association (VIFA), Victoria, B.C., Canada > The thought had occurred to me... I just assumed it would be much too slow > doing all that bit wrangling to draw stuff. How un-scientific of me! What > sort of speed improvement are you getting with this technique vs. 8-bit > drawing & CopyBits? Unfortunately I haven't updated my sprite routines, so I can't give you any figures (yet). But here's some points in this method's favour: Here's how I used to do masking for sprites (ie. only one screen page). Note this is exactly how Maelstrom's sprite code operates. Assume we're working with 1 pixel here, and the mask is either a 0xFF for 'solid' pixels and 0x00 for 'transparent' pixels: 1. AND the mask with the sprite 2. NOT the mask 3. AND the result of step 2 with the background 4. OR the result of step 1 with the result of step 3 Note that steps 1 and 2 can be done just after the sprite(s) are loaded in; there's no need to do them every time you draw a sprite. OK: here's how I draw individual pixels with the 2-buffer method. Assume that screen one uses the low-order nybble; screen 2 uses the high-order. For screen 1, AND 0xF0 with a pixel taken from the screen (or your pixmap, it doesn't matter). This clears the nybble you'll need for step 2, which is simply an OR with your color value. Screen 2 is very similar: AND 0x0F with your original pixel and then OR with your color value. Note, however, that this color value must be shifted left 4 bits... Finally, how all this ties together! I expect you'll like the sound of this: NO modification to the sprite code is required. All you need are 2 copies in memory of every sprite/background (1 per screen), and some modification to the sprite preprocessor (steps 1 and 2 as described above regarding normal sprite drawing). Imagine a mask and sprite from a normal (?) '1-screen' display: Mask = 0xFF00FF Sprite = 0x010203 Your sprite preprocessor would, for the screen 1 (scr1) version, involve an additional step after the first 2: every high-order nybble from every pixel of the mask should be set to 0xF. Thus, when masking onto scr1, the "mask AND background" operation preserves the contents of all scr2 pixels. The preprocessor for scr2 is almost identical: the additional step is instead to set every low-order nybble from every mask pixel to 0xF. Whew! A fair bit of text there! There's some big benefits involved here, though. I'm assuming you're drawing directly into screen memory: using CopyBits won't work with this technique, because you have to copy a full screen's worth every frame *anyway*, so there's no difference... Anyway, one major stage of memory-moving is eliminated: from the completed off-screen buffer onto the screen. You can draw backgrounds, sprites, text (etc) onto the undisplaying screen, and flip the palette when the next vertical retrace occurs. Say you're wanting a scrolling background that's 512x384 pixels big on the screen. That's 196,608 bytes you no longer have to copy... which will result in a good speed increase. A wise use of colors will help mask your lack of them (16-color grayscale looks good). Have fun with this one! Cody Jones, Zerius Development -- +++++++++++++++++++++++++++ >From dwareing@apanix.apana.org.au (David Wareing) Date: 16 Mar 94 11:51:28 GMT Organization: Apanix Public Access Unix, +61 8 373 5485 (5 lines) snozer@cats.ucsc.edu (Daniel Craig Jalkut) writes: >In dwareing@apanix.apana.org.au (David Wareing) writes: >But the bottom line is that the Amiga can do everything the Mac can >do, but the converse is not true. The advantages you point out for >the Mac are all software(which is why i'm a mac user and no longer an >Amigan), if the software were written as well for the Amiga(including >the OS), then you'd have the equivalent of a Macintosh with the bonus >of excellent graphics hardware. And the Amiga computers were sold >for much less than macs in the past, so it's not infeasable cost-wise >that the Macs have this type of hardware for graphics. I don't want this to become yet another brandX vs mac flamewar, but there are many reasons why amigas have been sold for much less than macs in the past. Amiga equipment, in general (and I'm not talking about their custom chipsets), is piss-poor. Everything from the floppy drive (screech screech kerklunk) to the keyboards were of a quality that made the machines look even more like toys. You had a gui that sucked rocks. Period. You had a system where the only way to play the majority of games, was to turn the thing off or vulcan-nerve-pinch it, shove the disk in, and turn it on again. You had non-existant developer support from Commodore. Commodore themselves actively promoted their machines as "entertainment" platforms (i.e. games machines). Until not all that long ago, a look inside an amiga 'starter kit' would show you a handful of floppies, most of which were games, and a few lame word-processors such as KindWords. In contrast, apple equipment has been expensive, but of generally high quality. You can't compare the Sony Trinitrons to the Philips monitors such as Commodore's 1084 etc. You also can't compare the price. In comparison to the amiga, the mac is an extremely well thought out design, and extremely well supported by both manufacturer and third parties. In the amiga's case, the only support is from its huge third party hardware manufacturer base and developers (most of whom appear to be of the hacker variety). That's part of the reason why the prices are much different. Which would you prefer? A custom blitting chipset, or monitors you could actually read word-processing text from, and an overall architecture that is consistent and of high quality? -- David Wareing Adelaide, South Australia dwareing@apanix.apana.org.au +++++++++++++++++++++++++++ >From jmunkki@beta.hut.fi (Juri Munkki) Date: 28 Mar 1994 19:35:12 GMT Organization: Helsinki University of Technology In article ua025@freenet.Victoria.BC.CA (Cody Jones) writes: >Divide your 8-bit palette into 2 halves. You now have 2, 4-bit screens. >It's simple to switch screens - it's just a palette change. You can draw >directly onto the screen (using nondisplaying colors, of course) - >there's no need to assemble all your images in an off-screen buffer and >blit it the screen. There's only two drawbacks: you only get 16 colors, >and you need 2 copies of every sprite/background. (Why a second copy? >Because otherwise you'd have to shift every pixel left 4 bits before >drawing it onto your second page. Slow.) Arashi (STORM) splits an 8 bit pixel into four parts: two 3 bit (7 colors+ transparency) buffers (double-buffered) and two 1 bit buffers for background graphics. Including the background color, this gives you 10 colors to work with. Since everything is done with vector graphics, this doesn't create as much of a performance problem as with sprites (where you would have to do at least twice the work). The Arashi animation toolkit is available with anonymous ftp from ics.uci.edu (pub/mac/think-c/apps or something like that). There's a big catch, however...and I didn't discover it than until when the game was pretty well along: video cards behave differently on palette changes. Some cards wait for the next vertical blanking to switch palettes and some cards do it immediately. Method #1 wastes time and method #2 produces partial frames where the bottom and top do not match. With some cards, calling the palette change from within the vertical blanking routine will wait until the next vertical blank (stupid, stupid) and on some cards it will simply not work at all... The video card driver specifications give some guidelines, but it seems people are not following all those guidelines. So...in my current animation kit I'm doing something totally different. I'm not using Quickdraw, it's fast, supports 2, 4, 16, 256, 32768 and millions of colors (with a maximum of 32768 colors), multiple screens (the animation can be split on several screen of different depth and different color maps) and it's completely flicker-free. (Partial frames do occur, but it doesn't seem too bothersome and it would be pretty hard to avoid on a system with 8 monitors, for instance.) Animation timing is done with the time manager, so you can set your frame rate to anything you want. I should have some kind of demo game out for WWDC (May) and I will convert this software to PowerPC once CodeWarrior ships with an inline assembler (it runs quite well under emulation though). Oh, and the class library I built on the basic animation engine supports unrestricted scaling and rotation and warping with 2x3 matrices and it now also supports very fast collision detection in a user coordinate system (doesn't depend on screen resolution). Finally, the animation engine is not available to developers, unless you can be very, very convincing ($$$). The first game will be something simple and will probably not show all the neat things that can be done with the animation kit. I just want something out there to show the world that I'm still alive and working on software... -- Juri Munkki There ain't so such thing as a shareware lunch. jmunkki@hut.fi Windsurfing: Faster than the wind. +++++++++++++++++++++++++++ >From ua025@freenet.Victoria.BC.CA (Cody Jones) Date: Tue, 29 Mar 1994 04:10:19 GMT Organization: The Victoria Freenet Association (VIFA), Victoria, B.C., Canada > There's a big catch, however...and I didn't discover it than until when the > game was pretty well along: video cards behave differently on palette > changes. Some cards wait for the next vertical blanking to switch palettes > and some cards do it immediately. Method #1 wastes time and method #2 > produces partial frames where the bottom and top do not match. With some > cards, calling the palette change from within the vertical blanking routine > will wait until the next vertical blank (stupid, stupid) and on some > cards it will simply not work at all... The video card driver > specifications give some guidelines, but it seems people are not following > all those guidelines. What!! I thought that SetEntries (that's the lowest-level I could get for palette stuff :) always waited for a vertical retrace before doing its palette-change. I believe I read this in an Apple document. Are you saying that it's really up to the card, not SetEntries? That would mean Apple wants this to be a standard and so goes around saying to high-level programmers that SetEntries does the work (when that's just a fabrication). If this is true... well, I'm not about to give up on a decent technique. The people with the wrong type of video card can play someone else's game instead... Cody Jones, Zerius Development -- +++++++++++++++++++++++++++ >From dwareing@apanix.apana.org.au (David Wareing) Date: 22 Mar 94 13:46:07 GMT Organization: Apanix Public Access Unix, +61 8 373 5485 (5 lines) rhn@netcom.com (Ron Nicholson) writes: >One idea used the in Apple II days for fast graphics animation, that I >haven't seen mentioned, is pre-shifted sprites. Since copybits runs >fastest when the source and distination are 32 bit aligned (64 bit for >PowerPC), having 4 or 8 pre-aligned sprite pixmaps, would mean copybits >would never waste any time shifting. Has anyone experimented with >this? An easier way to do this is to create your aligned pixmaps with a call to NewGWorld. Give it a depth of 0. This supposedly creates a pixmap that is aligned to the screen. And yes, it is certainly worth your while. You can get *very* nice speed increases with aligned pixmaps. Repeat the following mantra until a state similar to coma is reached: "GWorlds are my friends. GWorlds are my friends. GWorlds are my friends." -- David Wareing Adelaide, South Australia Mac Games & Multimedia Programming dwareing@apanix.apana.org.au - -------------------------------------------------------------------- +++++++++++++++++++++++++++ >From jmunkki@beta.hut.fi (Juri Munkki) Date: 29 Mar 1994 15:59:35 GMT Organization: Helsinki University of Technology In article ua025@freenet.Victoria.BC.CA (Cody Jones) writes: >What!! I thought that SetEntries (that's the lowest-level I could get for >palette stuff :) always waited for a vertical retrace before doing its >palette-change. I believe I read this in an Apple document. Are you >saying that it's really up to the card, not SetEntries? That would mean >Apple wants this to be a standard and so goes around saying to high-level >programmers that SetEntries does the work (when that's just a fabrication). Apple's video drivers wait for the next refresh, but I have seen at least one third party card that didn't wait for them. That was quite a few years ago, so they might not be sold anymore. Unless you use very careful timing, you'll waste up to one full frame of CPU time by doing SetEntries-type buffer switching on most cards. It's also limited to one video card because of this problem. -- Juri Munkki There ain't so such thing as a shareware lunch. jmunkki@hut.fi Windsurfing: Faster than the wind. +++++++++++++++++++++++++++ >From sigurasg@rhi.hi.is (Sigurdur Asgeirsson) Date: 29 Mar 1994 21:11:24 GMT Organization: University of Iceland In <2n9j97$6e@nntp.hut.fi> jmunkki@beta.hut.fi (Juri Munkki) writes: >In article ua025@freenet.Victoria.BC.CA (Cody Jones) writes: >>What!! I thought that SetEntries (that's the lowest-level I could get for >>palette stuff :) always waited for a vertical retrace before doing its >>palette-change. I believe I read this in an Apple document. Are you >>saying that it's really up to the card, not SetEntries? That would mean >>Apple wants this to be a standard and so goes around saying to high-level >>programmers that SetEntries does the work (when that's just a fabrication). I believe that SetEntries is just a wrapper for a control call to the driver, it is (naturally) the driver's work to actually set the hardware CLUT, and to wait for the blanking interval (if it is requested to do so, see below) since for both tasks you need to talk to the hardware. >Apple's video drivers wait for the next refresh, but I have seen at least >one third party card that didn't wait for them. That was quite a few years >ago, so they might not be sold anymore. [snip] According to C&D, the drivers are supposed to do this only if they're called at interrupt level 0, if the interrupt level has been raised (this is from memory, there might be a specific level required - possibly 2) the driver should not wait for blanking (talk about weird calling conventions, passing parameters in SR! :-). -- Sigurdur Asgeirsson | "Well you know, C isn't that hard, void (*(*f[])())() Kambasel 26 | for instance declares f as an array of unspecified 109 Reykjavik, Iceland | size, of pointers to functions that return pointers to sigurasg@rhi.hi.is | functions that return void... I think" +++++++++++++++++++++++++++ >From ua025@freenet.Victoria.BC.CA (Cody Jones) Date: Wed, 30 Mar 1994 00:52:51 GMT Organization: The Victoria Freenet Association (VIFA), Victoria, B.C., Canada > Unless you use very careful timing, you'll waste up to one full frame > of CPU time by doing SetEntries-type buffer switching on most cards. Why? Here's how I see it: after doing all your drawing to the non-displayed screen, you call SetEntries to swap the screens. Yes, the CPU does wait for a VR and thus waste some time between frames, but what else can your program do with that time? If your drawing code takes less than 1 refresh cycle, your graphics will keep up with the retrace. If it takes just over 1 cycle, then your FPS rate will drop by 2x - but that's unavoidable. Cody Jones, Zerius Development -- +++++++++++++++++++++++++++ >From jmunkki@beta.hut.fi (Juri Munkki) Date: 30 Mar 1994 15:36:54 GMT Organization: Helsinki University of Technology In article <2na5hs$5fp@eldborg.rhi.hi.is> sigurasg@rhi.hi.is (Sigurdur Asgeirsson) writes: > I believe that SetEntries is just a wrapper for a control call to the >driver, it is (naturally) the driver's work to actually set the hardware >CLUT, and to wait for the blanking interval (if it is requested to do so, >see below) since for both tasks you need to talk to the hardware. The driver waits for the VBL. SetEntries also seems to invalidate the ctSeed for the gDevice, so calling GetNextEvent or WaitNextEvent can cause a lot of extra processing to happen when Finder tries to figure out what happened. Because of this, Arashi calls the driver directly. > According to C&D, the drivers are supposed to do this only if they're >called at interrupt level 0, if the interrupt level has been raised >(this is from memory, there might be a specific level required - >possibly 2) the driver should not wait for blanking (talk about weird >calling conventions, passing parameters in SR! :-). Either I missed this or this is a new spec. Designing Cards & Drivers has been updated several times and I wrote the Arashi animation code years ago. I tried making the call from the vertical blanking interrupt (what's the interrupt level for those?), from a time manager task (very unreliable) and from the program itself. -- Juri Munkki There ain't so such thing as a shareware lunch. jmunkki@hut.fi Windsurfing: Faster than the wind. +++++++++++++++++++++++++++ >From Bruce_Burkhalter@inetlink.berksys.com (Bruce Burkhalter) Date: 30 Mar 1994 17:46:17 GMT Organization: Berkeley Systems In article <2nc6am$gui@nntp.hut.fi>, jmunkki@beta.hut.fi (Juri Munkki) wrote: > In article <2na5hs$5fp@eldborg.rhi.hi.is> sigurasg@rhi.hi.is (Sigurdur Asgeirsson) writes: > > I believe that SetEntries is just a wrapper for a control call to the > >driver, it is (naturally) the driver's work to actually set the hardware > >CLUT, and to wait for the blanking interval (if it is requested to do so, > >see below) since for both tasks you need to talk to the hardware. > > The driver waits for the VBL. SetEntries also seems to invalidate the ctSeed > for the gDevice, so calling GetNextEvent or WaitNextEvent can cause a lot of > extra processing to happen when Finder tries to figure out what happened. > > Because of this, Arashi calls the driver directly. A couple After Dark modules do this as well. Making the Control() call is a lot faster than SetEntries(). A neat trick you can do if you want to cycle the table continously is to make a copy of the table immediately following the it. To cycle through the colors, you just increment your ptr and reset it to the top when you get to 255. -- Bruce Burkhalter Bruce_Burkhalter@inetlink.berksys.com All opinions are mine. Berkeley Systems Inc. +++++++++++++++++++++++++++ >From jmunkki@beta.hut.fi (Juri Munkki) Date: 30 Mar 1994 22:11:36 GMT Organization: Helsinki University of Technology In article ua025@freenet.Victoria.BC.CA (Cody Jones) writes: >> Unless you use very careful timing, you'll waste up to one full frame >> of CPU time by doing SetEntries-type buffer switching on most cards. > >Why? Here's how I see it: after doing all your drawing to the >non-displayed screen, you call SetEntries to swap the screens. Yes, the >CPU does wait for a VR and thus waste some time between frames, but what >else can your program do with that time? If your drawing code takes less >than 1 refresh cycle, your graphics will keep up with the retrace. If it >takes just over 1 cycle, then your FPS rate will drop by 2x - but that's >unavoidable. You could start calculating stuff for the next frame. The way Arashi works is that it sets a game rate goal of 20 steps per second. On most monitors, this isn't an even multiple of the vertical blanking rate. Depending on what is happening in the game and depending what the game is running on, it may not be possible to display 20 frames per second. If this happens (as it often happens on the Color Classic and other slow machines), no drawing is done even though the game keeps running. This temporarily drops the frame rate to 10 fps or even lower. What I'm trying to say is that there's no way to tell how long it is going to take to process one game step or wether that game step is going to draw at all. In the future, I might want to write a game that runs at 100 fps or more internally and draw as often as possible. In this case, any waiting in an interrupt routine will be time wasted and will increase the probability that frames will have to be "skipped". Running at a fast enough internal rate sometimes makes hit and collision testing easier without being too costly otherwise. And, as I said in another posting, having to wait for one card makes it very hard to use this method on two or more cards. Another thing where at least two buffers are useful is displaying objects in stereo 3D for LC shutter glasses. (You need four buffers for double- buffering stereo 3D.) In the four buffer case you will be drawing into two of the buffers and flipping between the other two. Any time wasted is away from the time that you have available for drawing the next frame. In stereo 3D applications, anything below the true vertical blanking rate of the monitor is too slow. Fortunately, I think that machines are now getting fast enough so that these things can be more flexibly done with software solutions. This is better for the user, because it does not limit the amount of colors (you can do it in 15 or 24 bit color if you want) and you do not force the user to a certain bit depth. -- Juri Munkki There ain't so such thing as a shareware lunch. jmunkki@hut.fi Windsurfing: Faster than the wind. +++++++++++++++++++++++++++ >From sigurasg@rhi.hi.is (Sigurdur Asgeirsson) Date: 31 Mar 1994 13:22:12 GMT Organization: University of Iceland In <2nc6am$gui@nntp.hut.fi> jmunkki@beta.hut.fi (Juri Munkki) writes: >In article <2na5hs$5fp@eldborg.rhi.hi.is> sigurasg@rhi.hi.is (Sigurdur Asgeirsson) writes: [snip] >> According to C&D, the drivers are supposed to do this only if they're >>called at interrupt level 0, if the interrupt level has been raised >>(this is from memory, there might be a specific level required - >>possibly 2) the driver should not wait for blanking (talk about weird >>calling conventions, passing parameters in SR! :-). >Either I missed this or this is a new spec. Designing Cards & Drivers has >been updated several times and I wrote the Arashi animation code years ago. In my copy of C&D second edition, on page 185 (in the description of the SetEntries routine in the DRVR code example) there is the following text: 2) If SetEntries is entered while the interrupt level is non-zero, it should write immediately to the CLUT hardware. However, this is in reference to an optional feature of the driver, that of doing CLUT updates asyncronously, so drivers aren't required to do this. -- Sigurdur Asgeirsson | "Well you know, C isn't that hard, void (*(*f[])())() Kambasel 26 | for instance declares f as an array of unspecified 109 Reykjavik, Iceland | size, of pointers to functions that return pointers to sigurasg@rhi.hi.is | functions that return void... I think" +++++++++++++++++++++++++++ >From jmunkki@beta.hut.fi (Juri Munkki) Date: 31 Mar 1994 20:40:29 GMT Organization: Helsinki University of Technology In article <2neiq4$rth@eldborg.rhi.hi.is> sigurasg@rhi.hi.is (Sigurdur Asgeirsson) writes: > In my copy of C&D second edition, on page 185 (in the description of >the SetEntries routine in the DRVR code example) there is the following >text: > > 2) If SetEntries is entered while the interrupt level is non-zero, > it should write immediately to the CLUT hardware. > > However, this is in reference to an optional feature of the driver, >that of doing CLUT updates asyncronously, so drivers aren't required to >do this. Now I remember it. I tried and it and found it very unreliable. Apple's drivers tended to wait for the next VB period no matter how I called them. (I think I was using a TOBY 8 bit card on a Mac II... at least that card supported multiple pages. My Quadra 700 doesn't have support for more than one video page.) -- Juri Munkki There ain't so such thing as a shareware lunch. jmunkki@hut.fi Windsurfing: Faster than the wind. --------------------------- >From jhiggins@mathworks.com (John M. Higgins) Subject: Tools to improve segmentation? Date: 24 Mar 1994 21:13:33 GMT Organization: The MathWorks, Inc. Are there any tools which help optimize CODE segmentation by monitoring frequency of intersegment calls and segment use? -- John M. Higgins The MathWorks, Inc. jhiggins@mathworks.com +++++++++++++++++++++++++++ >From ari@world.std.com (Ari I Halberstadt) Date: Mon, 4 Apr 1994 04:20:07 GMT Organization: The World Public Access UNIX, Brookline, MA In article , John M. Higgins wrote: >Are there any tools which help optimize CODE segmentation by monitoring >frequency of intersegment calls and segment use? Efficient segmentation of applications has troubled me since my first multisegment Macintosh application. Unfortunately, due to the lack of tools to automatically segment applications, the only practical solution I've found has been to effectively ignore the problem. Fortunately, this is finally a reasonably viable approach, as the PowerPC no longer uses segmented applications. That said, this is what I've managed to do with my messing around in the Segment Loader. You can arrange to have inactive segments unloaded automatically. An inactive segment is a segment that does not contain the program counter and which is not pointed to by a return address on the stack. To unload inactive segments, you need to walk the stack to access all of the return addresses that are pointed to by register a6. You can then search for the segments containing the return addresses from among all segments that are in memory. All segments found to contain a return address are deemed active and are not unloaded. All other segments can be unloaded with UnloadSeg. There are some complications to this scheme that can arise if you attempt to unload segments from a routine called by the OS or if you are using a multi-threaded application. You also must know the format of the jump table produced by your compiler. This is somewhat similar to what Windows does to manage program segments, though Windows goes a step further and can unload active segments as well as inactive segments. I have implemented the above algorithm in Winter Shell, though support for multiple threads is not present yet in the current released version. You can use a program to generate a function call tree for your application. For instance, you can use the "cflow" program on a Unix system to generate a function call tree. Cflow supports two forms of function call trees. The default format shows the function call sequence, while a reversed format lists all functions that call a function. I have found the reversed format to be most useful. Unfortunately, the version of cflow that I have used omits many functions from its listings. To process Macintosh source code also requires uploading the code to a Unix machine (assuming you don't have A/UX). Since cflow doesn't have access to all of the Macintosh header files, it tends to produce volumes of error messages (5 megs for 1 meg of source code) that should be redirected to /dev/null. Once you have a function call tree, you can get some idea of how functions might most efficiently be segmented. To gather segment usage statistics, you can use the compiler's profiler. In THINK C, you can modify the profiler to gather information about the segment containing the profiled functions. Even if you can't modify your compiler's profiler, you could generate a link map for your application and use a script to correlate the link map with the profiler's output. You could also patch the _LoadSeg trap and gather statistics when it is executed, but you will need to unload the application's segments for it to be called with any regularity. I have tried segmenting a large program (again, Winter Shell) into many small segments with only one file per segment. This turned out to be a poor method to segment applications. In the current development version of Winter Shell I have simply segmented the application in a manner that is most convenient and logical for me, the programmer. With the new segmentation scheme, Winter Shell doesn't require much more memory than it did with the former method. Furthermore, the application spends less time loading and unloading segments. Today, most applications can assume that all of their code can be loaded into memory (or virtual memory). This assumption greatly simplifies segmentation, since you effectively don't have to worry about it. In the extreme case, you could just use far-code and one huge segment and forget about the whole issue. I used this extremely lazy approach to port a large 600K Unix application to the Macintosh. If you expect your application will run in a memory partition that will not allow all of its code to be resident, then you will obviously need to work out a good segmentation strategy. If your application's memory usage peaks while performing certain operations, then you could optimize the segmentation towards those peak operations. For instance, when printing, you could unload most of your application's code. The automatic segment unloading code that I mentioned above is in the file "SegmentLib.c" in Winter Shell. Winter Shell is a free application framework written in C. You can retrieve Winter Shell 1.0d2 by ftp'ing any of the following files: sumex-aim.stanford.edu:/info-mac/dev/src/winter-shell-10d2-c.hqx mac.archive.umich.edu:/mac/development/source/wintershell1.0d2.sit.hqx umich also has three mirrors that are updated daily: "wuarchive.wustl.edu" in the directory "mirrors/archive.umich.edu", (apple2,mac,atari,msdos,next) "src.doc.ic.ac.uk" in the directory "packages/mac/umich", and "archie.au" in the directory "micros/mac/umich". there are additional mirrors of info-mac in Europe, among them nic.switch.ch (Switzerland) metten.fenk.wau.nl (The Netherlands) swdsrv.edvz.univie.ac.at (Austria) Several people have mentioned the lack of documentation for Winter Shell. I'm working on an update to Winter Shell that will include at least some automatically extracted documentation that will provide minimal comments for all of the functions in Winter Shell. The update will also add a better event handling mechanism. I will probably also add a "ws_" prefix to all externally defined functions and symbols to prevent symbol name conflicts. No promises on when it will be available though. -- Ari Halberstadt ari@world.std.com #include "These beetles were long considered to be very rare because very few entomologists look for beetles in the mountains, in winter, at night, during snow storms." -- Purves W. K., et al, "Life: The Science of --------------------------- >From dsf5454@ritvax.isc.rit.edu Subject: copy file question, code available? Date: Wed, 30 Mar 1994 18:42:23 GMT Organization: Rochester Institute of Technology Hello... I'm curious if there are any routines available to copy a file to a different subdirectory..? I'm certainly interested in finding out as I have a need for such a beast... even the pseudocode or tips on how to do one would help.. thanks! Much appreciated. -Dan Foster Internet: dsf5454@ritvax.isc.rit.edu BITNET/CREN: dsf5454@ritvax.BITNET +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 30 Mar 1994 21:48:02 -0500 Organization: America Online, Inc. (1-800-827-6364) In article <1994Mar30.184223.9555@ultb.isc.rit.edu>, dsf5454@ritvax.isc.rit.edu writes: > I'm curious if there are any routines available to copy a file to a > different subdirectory..? I'm certainly interested in finding out as I have a > need for such a beast... even the pseudocode or tips on how to do one would > help.. thanks! Much appreciated. Dan, look at the MoreFiles sample code from Apple DTS. It available on the last few Developer CDs and at Apple's FTP site. - Jim Luther +++++++++++++++++++++++++++ >From kenlong@netcom.com (Ken Long) Date: Thu, 31 Mar 1994 18:06:12 GMT Organization: NETCOM On-line Communication Services (408 241-9760 guest) Also, there's a demo of that beast, complete with tooth and claw, in the "Other K&R's" Mac Prog Secrets source. -Ken- +++++++++++++++++++++++++++ >From rollin@newton.apple.com (Keith Rollin) Date: Fri, 1 Apr 1994 00:37:51 GMT Organization: Little to none In article , kenlong@netcom.com (Ken Long) wrote: > Also, there's a demo of that beast, complete with tooth and claw, in the > "Other K&R's" Mac Prog Secrets source. I can't remember if this was mentioned in an earlier part of the thread, but Jim Luther of Mac DTS has released a package called MoreFiles (now in version 1.1.1). This package has a lot of File Manager utilities (such as pre-7.0 glue for the FSSpec routines). One of the utilities is a file copy routine that does everything the exact right way. I haven't poured over the code yet to see how it works, but I know this guy, and he does good work. I'd trust his version over mine (for instance, his version works with AppleShare drop boxes, and mine doesn't). The package can be found on ftp.apple.com in /dts/mac/sc. - -------------------------------------------------------------------------- Keith Rollin --- Phantom Programmer --- Apple Computer, Inc. --- Team Newton +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 3 Apr 1994 14:02:02 -0400 Organization: America Online, Inc. (1-800-827-6364) In article , rollin@newton.apple.com (Keith Rollin) writes: > I haven't poured over the yet to see how it works, but I know this guy, > and he does good work. It works and I've only made one minor change to it lately. The next version of FileCopy won't attempt to copy empty forks (that makes it work better with foreign file systems that don't support multiple forks natively). - Jim Luther --------------------------- >From guapo@news.cs.columbia.edu (J. Robert Diana) Subject: skeleton code generators? Date: 28 Mar 1994 08:42:40 -0500 Organization: Columbia University Department of Computer Science Are there any free/shareware code generators for C? I do not need to see full prgrams, just some things like what one would do to make Mac specific stuff. I have found that trying to study a fully implemented program is quite a hassle. Any info is greatly appreciated. Thanks in advance. Rob Diana guapo@cs.columbia.edu +++++++++++++++++++++++++++ >From chuck@gte.com (Chuck Hoffman) Date: Fri, 1 Apr 1994 16:37:21 GMT Organization: GTE Laboratories In article <2n6msg$b2d@ground.cs.columbia.edu>, guapo@news.cs.columbia.edu (J. Robert Diana) wrote: > > Are there any free/shareware code generators for C? I do not need to see full > prgrams, just some things like what one would do to make Mac specific stuff. > I have found that trying to study a fully implemented program is quite a > hassle. > Any info is greatly appreciated. > Thanks in advance. Chassis 6.0 is not a code generator. It is a basic application framework which you might find useful anyway. It is not as confusing to look at as a fully developed application, and there is a program flow-chart provided with the code. I am working on Chassis 6.1 right now, which will be AppleEvent aware. Chassis 6.0 compiles with either THINK C 6 or 5. 6.1 will compile only with THINK C 6. Don't use the version of Chassis at sumex-aim.stanford.edu. They have an old version which is not 32-bit clean. They never posted the new version. Chassis is in the following anonymous ftp locations: ftp.gte.com: /pub/chuck/Chassis_6.0.sea.hqx mac.archive.umich.edu: /mac/development/source/chassis6.0.cpt.hqx -- Chuck Hoffman GTE Laboratories, Waltham, MA, USA 617-466-2131 - ------------------------------------------------ I'm not sure why we're here, but I am sure that while we're here we're supposed to help each other. - ------------------------------------------------ +++++++++++++++++++++++++++ >From jumplong@aol.com (Jump Long) Date: 3 Apr 1994 13:51:02 -0400 Organization: America Online, Inc. (1-800-827-6364) In article <2n6msg$b2d@ground.cs.columbia.edu>, guapo@news.cs.columbia.edu (J. Robert Diana) writes: > Are there any free/shareware code generators for C? You might want to get a copy of AppsToGo, a shell from Apple Developer Technical Support. There are a couple of sample applications built with AppsToGo that you can look at, too (DTS Draw and Kibitz). Available on Apple's Developer CD and FTP site. - Jim Luther --------------------------- End of C.S.M.P. Digest **********************