Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!bellcore!wind!sdh From: sdh@wind.bellcore.com (Stephen D Hawley) Newsgroups: comp.sys.mac.programmer Subject: Re: Alternate screen buffer ... How? Message-ID: <16888@bellcore.bellcore.com> Date: 17 Jun 89 01:09:34 GMT References: <8042@cc.nu.oz> <227700007@uxa.cso.uiuc.edu> Sender: news@bellcore.bellcore.com Reply-To: sdh@wind.UUCP (Stephen D Hawley) Organization: Bellcore, Morristown, NJ Lines: 185 Here's how to do double buffering. Remember that this is a hack. Don't take the animation seriously --it runs just as smoothly on a single buffered system, I just put it in for a quick demonstration. This is for LSC, put in a project with mactraps and you should be all hunky-dorey. Enjoy. Steve Hawley sdh@flash.bellcore.com PS - if anyone has written a better driver to multiplex sampled sounds without that annoying 'pop', let me hear about it. /* * Program to do double buffering. * This will crash with debuggers and the multifinder and * all kinds of other things. Largely, it follows as many * rules as possible from IM, but is bound to break. * Steve Hawley */ #include #define vPage2 6 /* VBL offsets from IM */ #define vBase 0xefe1fe #define vBufA (512*15) /* set page one */ #define ScreenOne() asm { BSET #vPage2,vBase+vBufA } /* set page two */ #define ScreenTwo() asm { BCLR #vPage2,vBase+vBufA } #define PAGEDIFF 0x8000 /* this is what inside mac says is the difference between * pages -probably a bad assumption. */ extern int CurPageOption: 0x936; /* current page in low memory */ extern char *MemTop: 0x108; int *page1, *page2, *currpage; unsigned int rwords, maxv; GrafPort myPort; /* globals used for my own grafport */ SwapPages() { if (currpage == page1) { ScreenOne(); currpage = page2; } else { ScreenTwo(); currpage = page1; } } SetUpDouble() /* set double buffering */ { int ref; Handle ahandle; Str255 ApplName; if (CurPageOption != -1) { /* no double paging, restart */ GetAppParms(ApplName, &ref, &ahandle); /* get application name */ Launch(-1, ApplName); /* sets up double buffers */ } else { HideCursor(); page1 = (int *)myPort.portBits.baseAddr; /* start of page */ asm { move.l page1, d0 sub.l #PAGEDIFF, d0 move.l d0, page2 } maxv = myPort.portBits.bounds.bottom - myPort.portBits.bounds.top; /* how many scan lines? */ rwords = myPort.portBits.rowBytes/2; /* words per row */ clr(page1, 0x0000); clr(page2, 0x0000); currpage = page2; } } clr(ptr, what) register int *ptr; register int what; { register long i; /* fill screen with "what" */ i = maxv * rwords; do { *ptr++ = what; } while (--i); } blitblackbox(x, y, h, where) register int x, y; register long *where; { register int sline = rwords * 2; asm { move.w y, d0 ; quick clipping test: is y + h > maxv? add.w h, d0 cmp.w maxv, d0 bls @0 move.w maxv, h sub.w y, h @0 muls.w #4, x ; turn x into long word offsets ext.l x add.l x, where ; offset start clr.l d0 move.w y, d0 muls.w sline, d0 add.l d0, where @1 move.l #0xffffffff, (where) add.l sline, where sub.w #1, h bne @1 } } blitwhitebox(x, y, h, where) register int x, y; register long *where; { register int sline = rwords * 2; asm { move.w y, d0 ; quick clipping test: is y + h > maxv? add.w h, d0 cmp.w maxv, d0 bls @0 move.w maxv, h sub.w y, h @0 muls.w #4, x ; turn x into long word offsets ext.l x add.l x, where ; offset start clr.l d0 move.w y, d0 muls.w sline, d0 add.l d0, where @1 clr.l (where) add.l sline, where sub.w #1, h bne @1 } } slide() { static int partial = 32, state = 0; register int x, y; for (x=0; x < 8; x++) if ((x + state) & 1) blitwhitebox(x, 0, partial, currpage); else blitblackbox(x, 0, partial, currpage); for (y=0; y < 10; y++) { for (x=0; x < 8; x++) { if ((x + y + state) & 1) blitblackbox(x, 32 * y + partial, 32, currpage); else blitwhitebox(x, 32 * y + partial, 32, currpage); } } partial += 4; if (partial > 32) { partial = 1; state ^= 1; } } main() { InitGraf(&thePort); /* set up quickdraw globals */ OpenPort(&myPort); /* get my own grafport */ SetUpDouble(); /* do double buffering */ while(!Button()) { slide(); SwapPages(); } ScreenOne(); /* put normal page for return to shell */ }