[comp.sys.mac.programmer] Alternate screen buffer ... How?

c8637197@cc.nu.oz (Phil the Grk) (06/14/89)

Hi guys, I'm another new one on the net.  I have a question about the alternate
screen buffer.  How do you get to use it?  In IM, it says that the segment
loader makes it usable if a flag is set.  Great.  Beautiful.  But how?  IM
states that _Chain and _Launch check a value to see which screen buffers are
required, which implies (to me anyway) that there is some information that the
Finder uses to set the appropriate values up.  Once again, how?

I'm writing a game, you see, and I want to have a shoot-em-up thing as part of
the game and I use the whole screen for this.  So I have two 21888 byte blocks
which I use.  The first is the background scene.  This gets copied onto the
"canvas" and the "animated"  objects are drawn on to the canvas.  Then I do a
blockmove from the canvas to thePort's bitmap.  (I know, it won't work on a
different size screen, but I'm working on it.)  In any case I would like to
use the alternate screen buffer and install a little doodad as a Vertical
Blanking Task so that the alternate screen buffer will be the "canvas" until
I've finished drawing there, then the main screen buffer will be the canvas.
It would be a lot quicker doing a simple bitset or whatever than it is copying
22K, I think.

Thanks in advance for any information anyone has.  BTW, it costs us undergrads
money to receive mail from outside - about $160 per 1000 blocks. Neither are we
permitted to mail offsite.  So could any responses be short or posted?  Thanks. 
If (when?) I receive anything I'll summarize and post ... it if it's not already
there ...

						Phil.

heberlei@iris.ucdavis.edu (Todd) (06/15/89)

I would be interested in this too.  I know nothing about an Alternate
sceen buffer; I didn't even know one existed (guess I'll wade through
my books tonight).  Would someone please post a short blurb describing

	* what it is
	* where to find info on it
	* maybe a short piece of code showing how to use it

[I currently draw in an offscreen buffer and CopyBits onto the screen]

--------------
Todd Heberlein
heberlei@iris.ucdavis.edu	128.120.57.20

oster@dewey.soe.berkeley.edu (David Phillip Oster) (06/15/89)

In article <4656@ucdavis.ucdavis.edu> heberlei@iris.ucdavis.edu (Todd) writes:
>	* what it is
You point the video controller at a different block or RAM on the MacPlus,
and earlier machines. Newer machines, particularly MacII and up don't have
one.
>	* where to find info on it
The Segment Loader chapter of the phone book addition of inside macintosh
tells how to issue a Launch system call to get it.
>	* maybe a short piece of code showing how to use it
Since it is not compatible with the RAM Cache, System 7 and future, nor
with newer Macintoshes, it seems like a WOMBAT:
Waste Of Money Brains And Time.
>[I currently draw in an offscreen buffer and CopyBits onto the screen]
This is already about the best you can do, espically as some of the newer
video boards on the Mac II have such large video memory that they have to
flip the system into 32-bit mode during the CopyBits, then flip it back to
24-bit afterward. This means the base address stored in the PixMap isn't
even valid in 24-bit mode, so you can't just decode the data structures
and twiddle the screen bits directly.

d88-jwa@nada.kth.se (Jon W{tte) (06/16/89)

In article <8042@cc.nu.oz> c8637197@cc.nu.oz (Phil the Grk) writes:
>different size screen, but I'm working on it.)  In any case I would like to
>use the alternate screen buffer and install a little doodad as a Vertical
>Blanking Task so that the alternate screen buffer will be the "canvas" until
>I've finished drawing there, then the main screen buffer will be the canvas.
>It would be a lot quicker doing a simple bitset or whatever than it is copying
>22K, I think.

Not all screens are 22K, and the _Launch and _Chain are not the newest
routines in the world... Also, you ARE aware of the fact that a VBL has
no global variables, may not move or purge memory, and can't depend on
the A5 frame being valid ? I really should suggest another approach...

-- 
 __       Jon W{tte (The dread Smiley Shark) email:h+@nada.kth.se
/  \      (+46 (0) 8 258 268)
   /---   (c) 1989 Yessbox Allright Professional Products Inc. - Y.A.P.P.I.
  /       -- No More --

cjr20670@uxa.cso.uiuc.edu (06/16/89)

  Okay, but remember, you asked for it.  As (almost) always, the answers are
in IM. Look in Vol III, page 18 for a description of the alternate buffer.
I've never used it, so I can't help you there.  I'm not going to encourage
you to pursue this because the Mac ]['s don't have alternate screen buffers
and have different VBL routines to deal with multiple screens.  Oh, lastly,
the simplist way to get a VBL lock is to just watch tickCount till it
changes, then do what you need (like CopyBits).  This allows your program
to have direct control over the animation and avoid all the memory
problems that VBL's tasks may be prone to develop.

/\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ /\ 
\/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/ \/
Charlie Reiman           
creiman@ncsa.uiuc.edu
cjr20670@uxa.uiuc.edu
"Be excellent to each other!"
            -Abe Lincoln

sdh@wind.bellcore.com (Stephen D Hawley) (06/17/89)

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 <Quickdraw.h>
#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 */
}

holland@m2.csc.ti.com (Fred Hollander) (06/21/89)

In article <227700007@uxa.cso.uiuc.edu> cjr20670@uxa.cso.uiuc.edu writes:
>
>you to pursue this because the Mac ]['s don't have alternate screen buffers
>and have different VBL routines to deal with multiple screens.  Oh, lastly,
>the simplist way to get a VBL lock is to just watch tickCount till it
>changes, then do what you need (like CopyBits).  This allows your program

I may be wrong, but, I don't beleive that this is necessary on Mac II's.

Fred Hollander
Computer Science Center
Texas Instruments, Inc.
hollander@ti.com

The above statements are my own and not representative of Texas Instruments.