/*------ | | Copyright © 1995 by Perceptics Corporation. All rights reserved. | | PixelStoreSupport.c contains routines for the Perceptics PixelTools | PixelStore board built on top of the PixelTools 5.0 driver. | +-----*/ /*------ | | Defined Routines | ================ | | In addition to the acquisition routines listed above, this module contains | several other useful routines that perform a variety of functions. These | are listed below: | | DoesPixelStoreExist - Determines if a PixelStore card exists. | +-----*/ /*------ | | INTERNAL (PERCEPTICS) DEVELOPMENT NOTE: | --------------------------------------- | | There is a companion include (PixelStoreSupport.h) file for this module. | If you add a routine to this module, you'll need to add a prototype to the | .h file as well. | | +-----*/ /* Prototypes and useful definitions. */ #include "Types.h" #include "Quickdraw.h" #include "Memory.h" #include "Resources.h" #include "OSUtils.h" #include "Errors.h" #include "Lists.h" #include "Dialogs.h" #include "Packages.h" #include "String.h" #include "PT50DriverDefs.h" #include "PT50DriverIFLib.h" #include "PixelTools50Lib.h" #include "PixelStoreSupport.h" #include "PixelToolsBits.h" #define PS_VIDEO_INPUT_BUS_A 1 #define PS_VIDEO_OUTPUT_BUS_A 1 #define PS_SAMPLING_FACTOR_1 0 #define PS_SEQ_DIR_FORWARD 0 #define PS_DATA_DIR_INPUT 1 #define PS_FIRST_TILE_0 0 /* segment definition for MPW */ /* #ifdef CompilerIsMPW3 /* #pragma segment PixelStoreSupport /* #endif */ /*------ | | PTPixelStoreExists | | This routine determines if a PixelStore card exists. The memory size | of the card is returned, zero if no PixelStore card exists. | +-----*/ pascal unsigned long PTPixelStoreExists() { PTCardInfo CardInfo[MaxCards]; OSErr status; short refNum, i; Str255 outLine; /* figger out if we've seen a card of this type before. If not, use */ /* default values. */ status = PTOpenDriver (&refNum); if (status != noErr) return(0); PTGetCardInfo (refNum, &CardInfo[0]); for (i = 0; i < MaxCards; ++i) { if (CardInfo[i].CardType == PIXELSTORE || CardInfo[i].CardType == SMARTSTORE) { return(CardInfo[i].CardMemSize); } } /* No PixelStore card found, return zero for not found. */ return(0); } /* End of PTPixelStoreExists routine */ /*------ | | PTGetPixelStoreMemAddr | | This routine returns the PixelStore card's memory start address. | Zero is returned if no PixelStore card exists. | +-----*/ pascal unsigned long PTGetPixelStoreMemAddr() { PTCardInfo CardInfo[MaxCards]; OSErr status; short refNum, i; Str255 outLine; /* figger out if we've seen a card of this type before. If not, use */ /* default values. */ status = PTOpenDriver (&refNum); if (status != noErr) return(0); PTGetCardInfo (refNum, &CardInfo[0]); for (i = 0; i < MaxCards; ++i) { if (CardInfo[i].CardType == PIXELSTORE || CardInfo[i].CardType == SMARTSTORE) { switch (CardInfo[i].CardMemSize) { case PSCardSize_4Meg: case PSCardSize_8Meg: case PSCardSize_20Meg: return(CardInfo[i].CardMemAddr + 0xC00000); case PSCardSize_16Meg: case PSCardSize_32Meg: return(CardInfo[i].CardMemAddr); default: return(0); } } } /* No PixelStore card found, return zero for not found. */ return(0); } /* End of PTGetPixelStoreMemAddr routine */ /*------ | | PTDoPixelStoreMovie | Writes values to the PixelStore board to configure it for the | movie function, then initiates the movie sequence capture. | | Return Value: | status: The completion status of the operation | +-----*/ pascal OSErr PTDoPixelStoreMovie ( long tileSize, /* Row, col size for each frame */ short numFrames, /* No. of frames to be captured */ short frameDelays) /* delay (secs) between frame grabs */ { OSErr status; long timeoutTicks, startTicks, tileSizeSelect, longParm; long longFrameDelays, longNumFrames; unsigned long regValue; short cardType, cardUnit, refNum, i; PTCardInfo CardInfo[MaxCards]; Str255 outLine; long tileCols, tileRows, firstTile; /* Open the PT50 driver and get the card info to determine if */ /* we're dealing with a PixelStore or SmartStore card. */ status = PTOpenDriver (&refNum); if (status != noErr) return(status); status = PTGetCardInfo (refNum, CardInfo); if (status != noErr) return(status); /* Convert the frame size parameters into register values */ if (tileSize == 262144) { tileSizeSelect = 0; tileCols = 512; tileRows = 512; } else if (tileSize == 524288) { tileSizeSelect = 4; tileCols = 1024; tileRows = 512; } else return(noErr); cardType = 0; cardUnit = 0; for (i = 0; i < MaxCards; ++i) { if (CardInfo[i].CardType == PIXELSTORE || CardInfo[i].CardType == SMARTSTORE) { cardType = CardInfo[i].CardType; firstTile = 0; if ((CardInfo[i].CardConfig & CONFIG_PTR_4M_BASE) == CONFIG_PTR_4M_BASE) firstTile = ((1024/tileCols) * (1024/tileRows) * 48) / 4; break; } } if (!cardType) return(unitEmptyErr); /* Combine the params for PixelStore register 0 and write it. */ regValue = 0; longParm = PS_VIDEO_INPUT_BUS_A; regValue |= (longParm & 0x3) << 1; longParm = PS_VIDEO_OUTPUT_BUS_A; regValue |= (longParm & 0x3) << 3; longParm = PS_SAMPLING_FACTOR_1; regValue |= (longParm & 0x3) << 6; regValue |= (tileSizeSelect & 0x7) << 8; regValue |= (PS_SEQ_DIR_FORWARD & 0x1) << 13; longParm = PS_DATA_DIR_INPUT; regValue |= (longParm & 0x1) << 14; status = PTSetDeviceRegister (refNum, cardType, cardUnit, 0, regValue, 0x000067FF); if (status != noErr) return(status); /* Combine the params for register 1 and write it */ longFrameDelays = frameDelays; longNumFrames = numFrames; regValue = 0; regValue |= (~longFrameDelays & 0xFF) << 24; regValue |= (~(longNumFrames-1) & 0xFFF) << 12; longParm = PS_FIRST_TILE_0 + firstTile; regValue |= (longParm & 0x7FF); status = PTSetDeviceRegister (refNum, cardType, cardUnit, 1, regValue, 0xFFFFF7FF); if (status != noErr) return(status); /* Set the Sequence Go bit to initiate the movie frames capture. */ regValue = 0x00008000; status = PTSetDeviceRegister (refNum, cardType, cardUnit, 0, regValue, 0x00008000); if (status != noErr) return(status); /* Wait for the Go bit to go away indicating sequence is done. */ timeoutTicks = numFrames * (frameDelays + 1) * 3; startTicks = TickCount(); while (1) { status = PTGetDeviceRegister (refNum, cardType, cardUnit, 0, ®Value); if (status == noErr) { if ((regValue & 0x00008000) == 0) break; } else { return(status); } if ((TickCount() - startTicks) > timeoutTicks) { status = genericErr; break; } } /* Cleanup before exiting. */ regValue = 0; status = PTSetDeviceRegister (refNum, cardType, cardUnit, 0, regValue, 0x000067FF); if (status != noErr) return(status); /* return the status */ return(status); } /* End of PTSetupPixelStoreForMovie routine */ /*------ | | PTCopyPixelStoreFBToScreen | Copies all (or part) of the specified frame buffer from the PixelStore | card to the screen window. The origin within the PixelStore frame | buffer is always (0,0). | | Return Value: | status: The completion status of the operation | +-----*/ pascal OSErr PTCopyPixelStoreFBToScreen ( short frameBufferNum, /* Frame buffer number to read */ short frameBufferH, /* No. of columns per frame */ short frameBufferV, /* No. of rows per frame */ Rect *srcRect, /* Camera capture rect (in FB) */ PixMapHandle offscreenPM, /* Handle to destination PixMap */ Rect dstRect) /* Display window rect */ { OSErr status; short cardType, cardUnit, refNum, i; PTCardInfo CardInfo[MaxCards]; CopyInfoBlk CopyInfo; Str255 outLine; /* Open the PT50 driver and get the card info to determine if */ /* we're dealing with a PixelStore or SmartStore card. */ status = PTOpenDriver (&refNum); if (status != noErr) return(status); status = PTGetCardInfo (refNum, CardInfo); if (status != noErr) return(status); cardType = 0; cardUnit = 0; for (i = 0; i < MaxCards; ++i) { if (CardInfo[i].CardType == PIXELSTORE || CardInfo[i].CardType == SMARTSTORE) { cardType = CardInfo[i].CardType; break; } } if (!cardType) return(unitEmptyErr); CopyInfo.copyMode = 2; CopyInfo.bufferID = frameBufferNum; CopyInfo.srcRect = *srcRect; CopyInfo.destPM = offscreenPM; CopyInfo.dstRect = dstRect; SetPt (&CopyInfo.tileSize, frameBufferH, frameBufferV); status = PTSetupScreenCopies (refNum, cardType, cardUnit, &CopyInfo); if (status != noErr) return(status); status = PTCopyFBtoScreen (refNum, cardType, cardUnit, &CopyInfo); if (status != noErr) return(status); /* return the status */ return(status); } /* End of PTSetupPixelStoreForMovie routine */ /*------ | | PTSetGrabberMode | Sets the 640/512 mode bit on the grabber board appropriately | for a movie sequence capture. | | Return Value: | status: The completion status of the operation | +-----*/ pascal OSErr PTSetGrabberMode ( long tileSize) /* width of tiles in sequence */ { OSErr status; short cardType, cardUnit, refNum, i; PTCardInfo CardInfo[MaxCards]; /* Open the PT50 driver and get the card info to determine if */ /* we're dealing with a PixelStore or SmartStore card. */ status = PTOpenDriver (&refNum); if (status != noErr) return(status); status = PTGetCardInfo (refNum, CardInfo); if (status != noErr) return(status); cardType = 0; cardUnit = 0; for (i = 0; i < MaxCards; ++i) { if (CardInfo[i].CardType == PIXELGRABBER || CardInfo[i].CardType == PIXELGRABBER2 || CardInfo[i].CardType == PIXELBUFFER || CardInfo[i].CardType == PIXELBUFFER2 || CardInfo[i].CardType == PIXELPIPELINE || CardInfo[i].CardType == PIXELPIPELINE2) { cardType = CardInfo[i].CardType; /* Convert the frame size parameters into register values */ if (tileSize == 1024) status = PTSetDeviceRegister (refNum, cardType, cardUnit, VIDEO_COL_REG, VIDEO_COL_PPL_640, VIDEO_COL_PPL_SEL); else status = PTSetDeviceRegister (refNum, cardType, cardUnit, VIDEO_COL_REG, VIDEO_COL_PPL_512, VIDEO_COL_PPL_SEL); } } if (!cardType) return(unitEmptyErr); /* return the status */ return(status); } /* End of PTSetGrabberMode routine */ /*------ | | PTCopyPMtoPixelStoreFB | Copies all (or part) of the specified frame buffer from the PixelStore | card to the screen window. The origin within the PixelStore frame | buffer is always (0,0). | | Return Value: | status: The completion status of the operation | +-----*/ pascal OSErr PTCopyPMtoPixelStoreFB ( short frameBufferNum, /* Frame buffer number to write */ short frameBufferH, /* No. of columns per frame */ short frameBufferV, /* No. of rows per frame */ long fbSize, /* Row, col size of tiles in FB */ Rect *srcRect, /* Source rect (in pixMap) */ PixMapHandle srcPM, /* Handle to source PixMap */ Rect *dstRect) /* Destination rect in FB */ { OSErr status; short cardType, cardUnit, refNum, i; PTCardInfo CardInfo[MaxCards]; Point tileSize; short tileCols, tileRows; /* Open the PT50 driver and get the card info to determine if */ /* we're dealing with a PixelStore or SmartStore card. */ status = PTOpenDriver (&refNum); if (status != noErr) return(status); status = PTGetCardInfo (refNum, CardInfo); if (status != noErr) return(status); cardType = 0; cardUnit = 0; for (i = 0; i < MaxCards; ++i) { if (CardInfo[i].CardType == PIXELSTORE || CardInfo[i].CardType == SMARTSTORE) { cardType = CardInfo[i].CardType; break; } } if (!cardType) return(unitEmptyErr); if (fbSize == 524288) { tileCols = 1024; tileRows = 512; } else { tileCols = 512; tileRows = 512; } SetPt (&tileSize, tileCols, tileRows); status = PTCopyPixMapToFB (refNum, cardType, cardUnit, frameBufferNum, srcPM, srcRect, dstRect, tileSize); if (status != noErr) return(status); /* return the status */ return(status); } /* End of PTCopyPMtoPixelStoreFB routine */