/*************************************************************** * * * Copyright (C) 1995 by Sony Computer Entertainment * * All rights Reserved * * * * L.Evans May 97 * * * ***************************************************************/ /**************************************************************************** includes ****************************************************************************/ #include #include #include "pad.h" #include "2d1.h" #include "rand.h" #include "text_str.h" #include "address.h" #include "sound.h" #include "tmd.h" #include "object.h" #include "geom.h" #include "sincos.h" /**************************************************************************** structures and constants ****************************************************************************/ GsIMAGE FireTextureInfo; GsSPRITE FireSprite; GsIMAGE MascotsTextureInfo; GsSPRITE MascotsSprite; GsIMAGE WaveTextureInfo; GsSPRITE WaveSprite; GsIMAGE StarsTextureInfo; GsSPRITE StarsSprite; GsIMAGE PurpleNoiseTextureInfo; GsSPRITE PurpleNoiseSprite; int ScreenWidth = 320; int ScreenHeight = 240; #define PACKETMAX 2048 /* Max GPU packets */ #define PACKETMAX2 (PACKETMAX*24) PACKET packetArea[2][PACKETMAX2]; /* GPU PACKETS AREA */ PACKET packetArea2[2][PACKETMAX]; // another packet area PACKET packetArea3[2][PACKETMAX]; PACKET packetArea4[2][PACKETMAX]; PACKET packetArea5[2][PACKETMAX]; PACKET packetArea6[2][PACKETMAX]; PACKET packetArea7[2][PACKETMAX]; #define FIRST_OT_LENGTH 9 GsOT Wot[2]; /* Handler of OT */ GsOT_TAG wtags[2][1< (b)) ? (b) : (a)) #define max(a,b) ( ((a) > (b)) ? (a) : (b)) #define KeepWithinRange(quantity, min, max) \ { \ if ((quantity) < (min)) \ (quantity) = (min); \ else if ((quantity) > (max)) \ (quantity) = (max); \ } #define setVECTOR(vector, x, y, z) \ (vector)->vx = (x), (vector)->vy = (y), (vector)->vz = (z) #define setNORMAL(normal, x, y, z) \ (normal)->nx = (x), (normal)->ny = (y), (normal)->nz = (z) #define setVERTEX(vertex, x, y, z) \ (vertex)->vx = (x), (vertex)->vy = (y), (vertex)->vz = (z) #define copyRECT(from, to) \ (to)->x = (from)->x, (to)->y = (from)->y, (to)->w = (from)->w, (to)->h = (from)->h #define ALL_ONES 0xffffffff u_long onlyNthBitOn, onlyNthBitOffMask; #define TURN_NTH_BIT_OFF(argument, sizeInBits, N) \ { \ onlyNthBitOn = 1 << (N); \ onlyNthBitOffMask = ALL_ONES ^ onlyNthBitOn; \ argument &= onlyNthBitOn; \ } /**************************************************************************** functions ****************************************************************************/ void main (void) { int hsync = 0; int bufferIndex; u_short zValue; MATRIX tmpls; ObjectHandler *object; int i; InitialiseAll(); PrintDataTypeSizes(); bufferIndex = GsGetActiveBuff(); while (QuitFlag == FALSE) { FntPrint("~cf00frame %d\n", frameNumber); FntPrint("~cf00hsync %d\n", hsync); FntPrint("~cf00projection %d\n", ProjectionDistance); FntPrint("~cf00vp %d %d %d\n", TheView.vpx, TheView.vpy, TheView.vpz); FntPrint("~cf00ViewMoveTime %d\n", ViewMoveTime); FntPrint("~cf00ViewDistanceFromOrigin %d\n", ViewDistanceFromOrigin); switch(CubeSurfaceViewed) { case PLUS_X_Y_PLANE: FntPrint("~cf00back plane viewed\n"); break; case MINUS_X_Y_PLANE: FntPrint("~cf00front plane viewed\n"); break; case PLUS_X_Z_PLANE: FntPrint("~cf00bottom plane viewed\n"); break; case MINUS_X_Z_PLANE: FntPrint("~cf00top plane viewed\n"); break; case PLUS_Y_Z_PLANE: FntPrint("~cf00right plane viewed\n"); break; case MINUS_Y_Z_PLANE: FntPrint("~cf00left plane viewed\n"); break; case -1: FntPrint("~cf00 plane view interim\n"); break; default: assert(FALSE); } FntPrint("~cf00angle on plane %d\n", OrientationOntoSurface); #if 0 if (frameNumber % 15 == 0) { dumpMATRIX( &ViewCoords.coord); } #endif //RegisterTextStringForDisplay("test 1234", 0, 0); frameNumber++; DealWithControllerPad(); //GsSetRefView2(&TheView); HandleTheView(); HandleSound(); HandleAllObjects(); GsSetWorkBase( (PACKET*)packetArea[bufferIndex]); GsClearOt(0, 0, &Wot[bufferIndex]); DisplayTextStrings (&Wot[bufferIndex]); //CycleLightsAroundAxes(); for (i = 0; i < MAX_OBJECTS; i++) { if (ObjectArray[i] != NULL) if (ObjectArray[i]->alive == TRUE) { object = ObjectArray[i]; if (object->displayFlag == TMD) { GsGetLs(&(object->coord), &tmpls); // local to screen matrix GsSetLightMatrix(&tmpls); GsSetLsMatrix(&tmpls); GsSortObject4( &(object->handler), &Wot[bufferIndex], 3, getScratchAddr(0)); } else if (object->displayFlag == SPRITE) // speed-up here: use a fast flag { // some can use GsSortFastSprite zValue = SortSpriteObjectPosition(object); GsSortSprite( &object->sprite, &Wot[bufferIndex], zValue); } else { assert(FALSE); } } } #if 0 // sprite tester PurpleNoiseSprite.x = 0; PurpleNoiseSprite.y = 0; GsSortSprite( &PurpleNoiseSprite, &Wot[bufferIndex], 0); #endif DrawCube( &InsideCube, &Wot[bufferIndex]); DrawCube( &OutsideCube, &Wot[bufferIndex]); hsync = VSync(0); ResetGraph(1); GsSwapDispBuff(); GsSortClear(0,0,0,&Wot[bufferIndex]); GsDrawOt(&Wot[bufferIndex]); bufferIndex = GsGetActiveBuff(); FntFlush(-1); // handle list of tasks, each for drawing into off-screen area of VRAM HandleOffScreenDrawing(bufferIndex); } CleanupAndExit(); } void InitialiseAll (void) { PadInit(); InitialiseRandomNumbers(); InitialiseTextStrings(); InitialiseSound(); GsInitGraph(ScreenWidth, ScreenHeight, GsINTER|GsOFSGPU, 1, 0); GsDefDispBuff(0,0,0,ScreenHeight); GsInit3D(); // sort our first ordering table Wot[0].length = FIRST_OT_LENGTH; Wot[0].org = wtags[0]; Wot[1].length = FIRST_OT_LENGTH; Wot[1].org = wtags[1]; GsClearOt(0,0,&Wot[0]); GsClearOt(0,0,&Wot[1]); // sort our second ordering table Wot2[0].length = SECOND_OT_LENGTH; Wot2[0].org = wtags2[0]; Wot2[1].length = SECOND_OT_LENGTH; Wot2[1].org = wtags2[1]; GsClearOt(0,0,&Wot2[0]); GsClearOt(0,0,&Wot2[1]); // sort our third ordering table Wot3[0].length = SECOND_OT_LENGTH; Wot3[0].org = wtags3[0]; Wot3[1].length = SECOND_OT_LENGTH; Wot3[1].org = wtags3[1]; GsClearOt(0,0,&Wot3[0]); GsClearOt(0,0,&Wot3[1]); // sort our fourth ordering table Wot4[0].length = SECOND_OT_LENGTH; Wot4[0].org = wtags4[0]; Wot4[1].length = SECOND_OT_LENGTH; Wot4[1].org = wtags4[1]; GsClearOt(0,0,&Wot4[0]); GsClearOt(0,0,&Wot4[1]); // sort our fifth ordering table Wot5[0].length = SECOND_OT_LENGTH; Wot5[0].org = wtags5[0]; Wot5[1].length = SECOND_OT_LENGTH; Wot5[1].org = wtags5[1]; GsClearOt(0,0,&Wot5[0]); GsClearOt(0,0,&Wot5[1]); // sort our sixth ordering table Wot6[0].length = SECOND_OT_LENGTH; Wot6[0].org = wtags6[0]; Wot6[1].length = SECOND_OT_LENGTH; Wot6[1].org = wtags6[1]; GsClearOt(0,0,&Wot6[0]); GsClearOt(0,0,&Wot6[1]); // sort our seventh ordering table Wot7[0].length = SECOND_OT_LENGTH; Wot7[0].org = wtags7[0]; Wot7[1].length = SECOND_OT_LENGTH; Wot7[1].org = wtags7[1]; GsClearOt(0,0,&Wot7[0]); GsClearOt(0,0,&Wot7[1]); InitialiseLighting(); InitialiseView(); ProperInitialiseTexture(FIRE_TEXTURE_ADDRESS, &FireTextureInfo); LinkSpriteToImageInfo(&FireSprite, &FireTextureInfo); ProperInitialiseTexture(MASCOTS_TEXTURE_ADDRESS, &MascotsTextureInfo); LinkSpriteToImageInfo(&MascotsSprite, &MascotsTextureInfo); ProperInitialiseTexture(WAVE_TEXTURE_ADDRESS, &WaveTextureInfo); LinkSpriteToImageInfo(&WaveSprite, &WaveTextureInfo); ProperInitialiseTexture(STARS_TEXTURE_ADDRESS, &StarsTextureInfo); LinkSpriteToImageInfo(&StarsSprite, &StarsTextureInfo); ProperInitialiseTexture(PURPLE_NOISE_TEXTURE_ADDRESS, &PurpleNoiseTextureInfo); LinkSpriteToImageInfo(&PurpleNoiseSprite, &PurpleNoiseTextureInfo); // sort basic text printing FntLoad( 960, 256); FntOpen( -120, 30, 256, 200, 0, 512); InitialiseFaceGeometry(); InitialiseObjects(); ClearTheCreatedTmds(); InitialiseCubes(); InitialiseDrawingProcesses(); } void InitialiseLighting (void) { // three flat light sources TheLights[0].vx = ONE; TheLights[0].vy = 0; TheLights[0].vz = 0; TheLights[0].r = 128; TheLights[0].g = 0; TheLights[0].b = 0; GsSetFlatLight(0, &TheLights[0]); TheLights[1].vx = 0; TheLights[1].vy = ONE; TheLights[1].vz = 0; TheLights[1].r = 0; TheLights[1].g = 128; TheLights[1].b = 0; GsSetFlatLight(1, &TheLights[1]); TheLights[2].vx = 0; TheLights[2].vy = 0; TheLights[2].vz = ONE; TheLights[2].r = 0; TheLights[2].g = 0; TheLights[2].b = 128; GsSetFlatLight(2, &TheLights[2]); // background lighting GsSetAmbient(ONE/2, ONE/2, ONE/2); // distance colour blending ('fogging') TheFogging.dqa = -960; TheFogging.dqb = 5120*5120; TheFogging.rfc = 0; TheFogging.gfc = 0; TheFogging.bfc = 0; GsSetFogParam( &TheFogging); // overall lighting conditions OverallLightMode = 0; // does not allow fogging GsSetLightMode(OverallLightMode); } void InitialiseView (void) { // screen-to-viewpoint distance ProjectionDistance = 192; GsSetProjection(ProjectionDistance); ViewMoveFlag = FALSE; ViewMoveTime = 30; // half a second ViewMoveStartFrame = -1; ViewDistanceFromOrigin = 2000; TheView.vrx = 0; TheView.vry = 0; TheView.vrz = 0; TheView.vpx = 0; TheView.vpy = 0; TheView.vpz = -ViewDistanceFromOrigin; //-220; TheView.rz = 0; GsInitCoordinate2( WORLD, &ViewCoords); CopyCoordinateSystem( &ViewCoords, &PreviousViewCoords); TheView.super = &ViewCoords; GsSetRefView2(&TheView); CubeSurfaceViewed = FRONT; OrientationOntoSurface = 0; } void InitialiseFaceGeometry (void) { int i; // these go outwards from cube faces off into space setVECTOR( &FaceOutsideNormals[FRONT], 0, 0, -ONE); setVECTOR( &FaceOutsideNormals[RIGHT], ONE, 0, 0); setVECTOR( &FaceOutsideNormals[BACK], 0, 0, ONE); setVECTOR( &FaceOutsideNormals[LEFT], -ONE, 0, 0); setVECTOR( &FaceOutsideNormals[TOP], 0, -ONE, 0); setVECTOR( &FaceOutsideNormals[BOTTOM], 0, ONE, 0); // these go from face centres to centre of cube for (i = 0; i < 6; i++) { setVECTOR( &FaceInsideNormals[i], -FaceOutsideNormals[i].vx, -FaceOutsideNormals[i].vy, -FaceOutsideNormals[i].vz); } setVECTOR( &FaceXVectors[FRONT], ONE, 0, 0); setVECTOR( &FaceYVectors[FRONT], 0, -ONE, 0); setVECTOR( &FaceXVectors[RIGHT], 0, 0, ONE); setVECTOR( &FaceYVectors[RIGHT], 0, -ONE, 0); setVECTOR( &FaceXVectors[BACK], -ONE, 0, 0); setVECTOR( &FaceYVectors[BACK], 0, -ONE, 0); setVECTOR( &FaceXVectors[LEFT], 0, 0, -ONE); setVECTOR( &FaceYVectors[LEFT], 0, -ONE, 0); setVECTOR( &FaceXVectors[TOP], ONE, 0, 0); setVECTOR( &FaceYVectors[TOP], 0, 0, ONE); setVECTOR( &FaceXVectors[BOTTOM], ONE, 0, 0); setVECTOR( &FaceYVectors[BOTTOM], 0, 0, -ONE); // which can be got to from which others FaceAccessTable[FRONT][NORTH] = TOP; FaceAccessTable[FRONT][EAST] = RIGHT; FaceAccessTable[FRONT][SOUTH] = BOTTOM; FaceAccessTable[FRONT][WEST] = LEFT; FaceAccessTable[RIGHT][NORTH] = TOP; FaceAccessTable[RIGHT][EAST] = BACK; FaceAccessTable[RIGHT][SOUTH] = BOTTOM; FaceAccessTable[RIGHT][WEST] = FRONT; FaceAccessTable[BACK][NORTH] = TOP; FaceAccessTable[BACK][EAST] = LEFT; FaceAccessTable[BACK][SOUTH] = BOTTOM; FaceAccessTable[BACK][WEST] = RIGHT; FaceAccessTable[LEFT][NORTH] = TOP; FaceAccessTable[LEFT][EAST] = FRONT; FaceAccessTable[LEFT][SOUTH] = BOTTOM; FaceAccessTable[LEFT][WEST] = BACK; FaceAccessTable[TOP][NORTH] = BACK; FaceAccessTable[TOP][EAST] = RIGHT; FaceAccessTable[TOP][SOUTH] = FRONT; FaceAccessTable[TOP][WEST] = LEFT; FaceAccessTable[BOTTOM][NORTH] = FRONT; FaceAccessTable[BOTTOM][EAST] = RIGHT; FaceAccessTable[BOTTOM][SOUTH] = BACK; FaceAccessTable[BOTTOM][WEST] = LEFT; } void InitialiseObjects (void) { int i; InitialiseObjectClass(); InitialiseMiniObjectClass(); for (i = 0; i < MAX_CUBES; i++) { InitSingleObject(&TheCubes[i]); BringObjectToLife(&TheCubes[i], CUBE, CUBE_MODEL_ADDRESS, 0, NONE); RegisterObjectIntoObjectArray(&TheCubes[i]); } for (i = 0; i < MAX_POLYGONS; i++) { InitMiniObject( &ThePolygons[i]); RegisterMiniObjectIntoMiniObjectArray( &ThePolygons[i]); ThePolygons[i].alive = FALSE; } LinkAllObjectsToModelsOrSprites(); LinkAllObjectsToTheirCoordinateSystems(); for (i = 0; i < MAX_CUBES; i++) { TheCubes[i].alive = FALSE; // start off dead } #if 0 // bring alive the first cube, position it ahead of camera TheCubes[0].alive = TRUE; TheCubes[0].position.vz = 500; // this for later variable scaling SetObjectScaling( &TheCubes[0], ONE, ONE, ONE); #endif CreateMoreLittleCubesAroundLargerOne(); } void CreateMoreLittleCubesAroundLargerOne (void) { int i; for (i = 0; i < 8; i++) { TheCubes[i].alive = TRUE; } setVECTOR( &TheCubes[0].position, 400, 400, 400); setVECTOR( &TheCubes[1].position, 400, 400, -400); setVECTOR( &TheCubes[2].position, 400, -400, 400); setVECTOR( &TheCubes[3].position, -400, 400, 400); setVECTOR( &TheCubes[4].position, 400, -400, -400); setVECTOR( &TheCubes[5].position, -400, 400, -400); setVECTOR( &TheCubes[6].position, -400, -400, 400); setVECTOR( &TheCubes[7].position, -400, -400, -400); #if 0 for (i = 0; i < 8; i++) { if (TheCubes[i].position.vx == 400) SetObjectScaling( &TheCubes[i], ONE/2, ONE/2, ONE/2); if (TheCubes[i].position.vy == 400) { TheCubes[i].rotationMomentumFlag = TRUE; setVECTOR( &TheCubes[i].twist, 0, 0, (rand() % 30) ); } } #endif } void InitialiseCubes (void) { RECT insideTextureAreasList[6]; RECT singleInsideCubeTexture; //RECT outsideTextureAreasList[6]; RECT singleOutsideCubeTexture; int i; printf("Start of InitialiseCubes\n"); // init to void and dead InitCube(&InsideCube); InitCube(&OutsideCube); #if 0 // single texture setRECT( &singleInsideCubeTexture, WaveTextureInfo.px, WaveTextureInfo.py, WaveTextureInfo.pw, WaveTextureInfo.ph); CreateCube ( &InsideCube, INSIDE_CUBE, 400, VISIBLE_FROM_OUTSIDE, 1, SINGLE_CUBE_TEXTURE, &singleInsideCubeTexture); #endif #if 0 for (i = 0; i < 6; i++) { if ((i % 2) == 0) { setRECT( &insideTextureAreasList[i], WaveTextureInfo.px, WaveTextureInfo.py, WaveTextureInfo.pw, WaveTextureInfo.ph); } else { setRECT( &insideTextureAreasList[i], MascotsTextureInfo.px, MascotsTextureInfo.py, MascotsTextureInfo.pw, MascotsTextureInfo.ph); } } CreateCube ( &InsideCube, INSIDE_CUBE, 400, VISIBLE_FROM_OUTSIDE, 2, ONE_TEXTURE_PER_FACE, insideTextureAreasList); #endif #if 1 // first cube: two textures setRECT( &insideTextureAreasList[0], WaveTextureInfo.px, WaveTextureInfo.py, WaveTextureInfo.pw, WaveTextureInfo.ph); setRECT( &insideTextureAreasList[1], MascotsTextureInfo.px, MascotsTextureInfo.py, MascotsTextureInfo.pw, MascotsTextureInfo.ph); CreateCube ( &InsideCube, INSIDE_CUBE, 400, VISIBLE_FROM_OUTSIDE, 2, ONE_TEXTURE_PER_CORNER, insideTextureAreasList); #endif #if 1 // outside cube not ready setRECT( &singleOutsideCubeTexture, WaveTextureInfo.px, WaveTextureInfo.py, WaveTextureInfo.pw, WaveTextureInfo.ph); CreateCube ( &OutsideCube, OUTSIDE_CUBE, 5000, VISIBLE_FROM_INSIDE, 4, SINGLE_CUBE_TEXTURE, &singleOutsideCubeTexture); #endif printf("End of InitialiseCubes\n"); printf("INSIDE cube\n"); //PrintCubeInfo (&InsideCube); printf("OUTSIDE cube\n"); //PrintCubeInfo (&OutsideCube); } void CleanupAndExit (void) { //StoreScreen2 ( (u_long*)SCREEN_SAVE_ADDRESS, 0, 0, ScreenWidth, ScreenHeight); StoreScreen(); ResetGraph(3); CleanUpSound(); // if this program part of a multiple module, // can printf to siocons to tell user to // invoke a new batch file, etc } void CycleLightsAroundAxes (void) { int cyclePoint, theta; int lightEffectPeriod = 90; cyclePoint = (frameNumber % lightEffectPeriod); theta = ONE * cyclePoint / lightEffectPeriod; // not very sorted, but will do TheLights[0].vx = rcos(theta); TheLights[0].vy = rsin(theta); GsSetFlatLight(0, &TheLights[0]); TheLights[1].vz = rcos(theta); TheLights[1].vx = rsin(theta); GsSetFlatLight(1, &TheLights[1]); TheLights[2].vy = rcos(theta); TheLights[2].vz = rsin(theta); GsSetFlatLight(2, &TheLights[2]); } void DealWithControllerPad (void) { long pad; int controlSpeed; pad = PadRead(); // and