304 lines
7.7 KiB
C++
304 lines
7.7 KiB
C++
/** 32 bit DrawSprockets pluggable framework
|
||
*
|
||
* Jason Rohrer, 4-28-99
|
||
*
|
||
* Mods:
|
||
* Jason Rohrer 11-8-99 Changed to use GraphicBuffer object as screen buffer
|
||
* Jason Rohrer 12-15-99 Added support for keyboard querying
|
||
* Jason Rohrer 3-21-2000 Added support for mouse querying
|
||
*
|
||
*/
|
||
|
||
|
||
#include <DrawSprocket.h>
|
||
#include <QuickDraw.h>
|
||
#include <Events.h> // for keyboard events
|
||
|
||
#include <stdlib.h>
|
||
#include <string.h>
|
||
#include "swapBuffers.h" // interface for swapping buffers
|
||
#include "getKey.h" // interface for getting key states
|
||
#include "getMouse.h" // interface for getting mouse state
|
||
|
||
//#include "ALifeGuiRunner.h"
|
||
#include "GoGUIRunner.h"
|
||
#include "GraphicBuffer.h"
|
||
|
||
// Constants
|
||
#define BallWidth 20
|
||
#define BallHeight 20
|
||
#define BobSize 8 /* Size of text in each ball */
|
||
|
||
//MT Tutorial
|
||
#define rWindow 128 // resource ID number for window
|
||
|
||
|
||
// Globals
|
||
Rect windRect;
|
||
WindowPtr w;
|
||
DSpContextReference theContext;
|
||
unsigned long *double_buffer = NULL; // the double buffer
|
||
unsigned long *screen_buffer = NULL;
|
||
|
||
GraphicBuffer *graphicDoubleBuffer;
|
||
|
||
|
||
short bufferHigh = 480;
|
||
short bufferWide = 640;
|
||
|
||
|
||
// prototypes
|
||
void Initialize(void);
|
||
void graphixPicker(void); // our mother function, picks effect order, etc.
|
||
void initVideo(DSpContextReference *theContext);
|
||
void MyInitAttributes(DSpContextAttributes*);
|
||
void CleanUp(DSpContextReference theContext);
|
||
|
||
|
||
|
||
int main() {
|
||
|
||
Initialize(); // setup a window
|
||
MaxApplZone();
|
||
|
||
initVideo( &theContext ); // set up and switch video
|
||
|
||
graphixPicker();
|
||
|
||
CleanUp( theContext);
|
||
|
||
}
|
||
|
||
|
||
void graphixPicker() { // our "mother function"
|
||
// selects which effect to run next
|
||
|
||
// graphix plug-in format:
|
||
// myGraphix( bufferPtr, bufferHigh, bufferWide, colorBits, numFrames)
|
||
// function can cll "swapBuffer32" internally whenever it needs the back buffer
|
||
// sent to the screen.
|
||
|
||
|
||
|
||
// jcrTorus( double_buffer, 480, 640, 32, 100);
|
||
// jcrVoxels( double_buffer, 480, 640, 32, 230);
|
||
// jcrTorus( double_buffer, 480, 640, 32, 50);
|
||
|
||
|
||
//jcrBloom( double_buffer, 480, 640, 32, 100);
|
||
|
||
// GraphicBuffer passed in contains all needed info about screen
|
||
// pass in number of frames to run for
|
||
//ALifeGuiRunner( *graphicDoubleBuffer, 1000 );
|
||
|
||
GoGUIRunner( *graphicDoubleBuffer, 0 );
|
||
}
|
||
|
||
|
||
// Initialize the draw sprockets
|
||
// set up the video, fade out display, and switch video modes
|
||
void initVideo(DSpContextReference *theContext) {
|
||
|
||
CGrafPtr backBuffer;
|
||
PixMapHandle bufferMap;
|
||
|
||
DSpContextAttributes theDesiredAttributes;
|
||
OSStatus theError;
|
||
|
||
|
||
|
||
MyInitAttributes(&theDesiredAttributes);
|
||
theDesiredAttributes.displayWidth = 640;
|
||
theDesiredAttributes.displayHeight = 480;
|
||
theDesiredAttributes.colorNeeds = kDSpColorNeeds_Require;
|
||
theDesiredAttributes.backBufferDepthMask = kDSpDepthMask_32;
|
||
theDesiredAttributes.displayDepthMask = kDSpDepthMask_32;
|
||
theDesiredAttributes.backBufferBestDepth = 32;
|
||
theDesiredAttributes.displayBestDepth = 32;
|
||
theError = DSpFindBestContext(&theDesiredAttributes, theContext);
|
||
|
||
// add page flipping by video card to request
|
||
theDesiredAttributes.contextOptions |= kDSpContextOption_PageFlip;
|
||
//theDesiredAttributes.contextOptions |= kDSpContextOption_DontSyncVBL;
|
||
|
||
// Reserver a display
|
||
theError = DSpContext_Reserve(*theContext, &theDesiredAttributes);
|
||
|
||
// fade out
|
||
theError = DSpContext_FadeGammaOut(NULL, NULL);
|
||
|
||
theError = DSpContext_SetState(*theContext, kDSpContextState_Active);
|
||
ShowCursor();
|
||
HideCursor();
|
||
|
||
|
||
// setup global pointers to screen and back buffer
|
||
|
||
theError = DSpContext_GetBackBuffer(*theContext, kDSpBufferKind_Normal, &backBuffer);
|
||
bufferMap = (PixMapHandle)GetGWorldPixMap(backBuffer);
|
||
double_buffer = (unsigned long*)(**bufferMap).baseAddr;
|
||
|
||
// create GraphicBuffer object
|
||
graphicDoubleBuffer = new GraphicBuffer( double_buffer, 640, 480 );
|
||
|
||
theError = DSpContext_GetFrontBuffer(*theContext, &backBuffer);
|
||
bufferMap = (PixMapHandle)GetGWorldPixMap(backBuffer);
|
||
screen_buffer = (unsigned long*)(**bufferMap).baseAddr;
|
||
|
||
theError = DSpContext_FadeGammaIn(NULL, NULL);
|
||
|
||
}
|
||
|
||
|
||
// initialize a set of Display attributes to zero
|
||
void MyInitAttributes (DSpContextAttributes *inAttributes)
|
||
{
|
||
if (NULL == inAttributes)
|
||
DebugStr("\pStimpy! You Idiot!");
|
||
|
||
inAttributes->frequency = 0;
|
||
inAttributes->displayWidth = 0;
|
||
inAttributes->displayHeight = 0;
|
||
inAttributes->reserved1 = 0;
|
||
inAttributes->reserved2 = 0;
|
||
inAttributes->colorNeeds = 0;
|
||
inAttributes->colorTable = NULL;
|
||
inAttributes->contextOptions = 0;
|
||
inAttributes->backBufferDepthMask = 0;
|
||
inAttributes->displayDepthMask = 0;
|
||
inAttributes->backBufferBestDepth = 0;
|
||
inAttributes->displayBestDepth = 0;
|
||
inAttributes->pageCount = 0;
|
||
inAttributes->gameMustConfirmSwitch = false;
|
||
inAttributes->reserved3[0] = 0;
|
||
inAttributes->reserved3[1] = 0;
|
||
inAttributes->reserved3[2] = 0;
|
||
inAttributes->reserved3[3] = 0;
|
||
}
|
||
|
||
void CleanUp(DSpContextReference theContext) {
|
||
OSStatus theError;
|
||
|
||
theError = DSpContext_FadeGammaOut(NULL, NULL);
|
||
|
||
/* put the context into the inactive state */
|
||
theError = DSpContext_SetState(theContext, kDSpContextState_Inactive);
|
||
|
||
/* fade back in */
|
||
theError = DSpContext_FadeGammaIn(NULL, NULL);
|
||
|
||
/* release the context */
|
||
theError = DSpContext_Release(theContext);
|
||
|
||
ShowCursor();
|
||
}
|
||
|
||
|
||
|
||
|
||
|
||
// swap bufferB to the screen (32 bit version)
|
||
void swapBuffers32( GraphicBuffer &bufferB ) {
|
||
OSStatus theError;
|
||
|
||
// swap buffers
|
||
theError = DSpContext_SwapBuffers(theContext, NULL, 0);
|
||
|
||
|
||
// get pointer to new back buffer and return it
|
||
CGrafPtr backBuffer;
|
||
PixMapHandle bufferMap;
|
||
theError = DSpContext_GetBackBuffer(theContext, kDSpBufferKind_Normal, &backBuffer);
|
||
bufferMap = (PixMapHandle)GetGWorldPixMap(backBuffer);
|
||
|
||
// replace the buffer in bufferB with the new double buffer
|
||
bufferB.setBuffer( (unsigned long*)(**bufferMap).baseAddr );
|
||
|
||
// memcpy(screen_buffer, bufferPtrB, 4*bufferWide*bufferHigh);
|
||
|
||
|
||
|
||
} // end of swapBuffers
|
||
|
||
|
||
|
||
// returns true if key represented by given key code is down
|
||
char getKeyDown( int vKeyCode ) {
|
||
|
||
unsigned char keyArray [16];
|
||
GetKeys( (long *)keyArray );
|
||
|
||
return ((keyArray[vKeyCode>>3] >> (vKeyCode & 7)) & 1);
|
||
}
|
||
|
||
// returns true if key is up
|
||
char getKeyUp( int vKeyCode ) {
|
||
|
||
unsigned char keyArray [16];
|
||
GetKeys( (long *)keyArray );
|
||
|
||
return !((keyArray[vKeyCode>>3] >> (vKeyCode & 7)) & 1);
|
||
}
|
||
|
||
|
||
void getMouse( int *x, int *y ) {
|
||
Point mousePoint;
|
||
DSpGetMouse( &mousePoint );
|
||
|
||
*x = mousePoint.h;
|
||
*y = mousePoint.v;
|
||
}
|
||
|
||
|
||
|
||
void Initialize(void)
|
||
{
|
||
WindowPtr mainPtr;
|
||
OSErr error;
|
||
SysEnvRec theWorld;
|
||
|
||
//
|
||
// Test the computer to be sure we can do color.
|
||
// If not we would crash, which would be bad.
|
||
// If we can<61>t run, just beep and exit.
|
||
//
|
||
|
||
error = SysEnvirons(1, &theWorld);
|
||
if (theWorld.hasColorQD == false) {
|
||
// SysBeep(50);
|
||
ExitToShell(); // If no color QD, we must leave.
|
||
}
|
||
|
||
// Initialize all the needed managers.
|
||
InitGraf(&qd.thePort);
|
||
// InitFonts();
|
||
InitWindows();
|
||
InitMenus();
|
||
TEInit();
|
||
InitDialogs(nil);
|
||
InitCursor();
|
||
|
||
//
|
||
// To make the Random sequences truly random, we need to make the seed start
|
||
// at a different number. An easy way to do this is to put the current time
|
||
// and date into the seed. Since it is always incrementing the starting seed
|
||
// will always be different. Don<6F>t for each call of Random, or the sequence
|
||
// will no longer be random. Only needed once, here in the init.
|
||
//
|
||
GetDateTime((unsigned long*) &qd.randSeed);
|
||
|
||
//
|
||
// Make a new window for drawing in, and it must be a color window.
|
||
// The window is full screen size, made smaller to make it more visible.
|
||
//
|
||
mainPtr = GetNewCWindow(rWindow, nil, (WindowPtr) -1); // MW Tutorial
|
||
windRect = mainPtr->portRect;
|
||
|
||
SetPort(mainPtr); // set window to current graf port
|
||
TextSize(BobSize); // smaller font for drawing.
|
||
}
|
||
|
||
|
||
|
||
|
||
|