/*************************************************************** * * * 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 GreenCircleTextureInfo; GsSPRITE GreenCircleSprite; GsIMAGE StarsTextureInfo; GsSPRITE StarsSprite; GsIMAGE PurpleNoiseTextureInfo; GsSPRITE PurpleNoiseSprite; GsIMAGE OrangeTileTextureInfo; GsSPRITE OrangeTileSprite; GsIMAGE MultipleTextureInfo; GsSPRITE MultipleSprite; int ScreenWidth = 320; int ScreenHeight = 240; #define PACKETMAX 2048 /* Max GPU packets */ #define PACKETMAX2 (PACKETMAX*24) static PACKET packetArea[2][PACKETMAX2]; /* GPU PACKETS AREA */ #define OT_LENGTH 9 static GsOT Wot[2]; /* Handler of OT */ static 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 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; // buffer index u_short zValue; MATRIX tmpls; ObjectHandler *object; VECTOR rvp, vp, rvr, vr; int i; InitialiseAll(); 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); // find and print vp and vr in world coordinate space setVECTOR( &rvp, TheView.vpx, TheView.vpy, TheView.vpz); //dumpVECTOR( &rvp); ExpressSuperPointInSub( &rvp, TheView.super, &vp); FntPrint("~cf00viewpoint in world %d %d %d\n", vp.vx, vp.vy, vp.vz); setVECTOR( &rvr, TheView.vrx, TheView.vry, TheView.vrz); //dumpVECTOR( &rvr); ExpressSuperPointInSub( &rvr, TheView.super, &vr); FntPrint("~cf00view reference in world %d %d %d\n", vr.vx, vr.vy, vr.vz); //printf("\n\n\n"); /****** RegisterTextStringForDisplay("right pad to move cube", -150, -100); RegisterTextStringForDisplay("right pad plus START to rotate cube", -150, -90); RegisterTextStringForDisplay("right pad plus Lleft to scale cube", -150, -80); RegisterTextStringForDisplay("right pad plus L1 changes projection", -150, -70); RegisterTextStringForDisplay("right pad plus L2 to move viewpoint", -150, -60); RegisterTextStringForDisplay("select makes controls act quicker", -150, -50); RegisterTextStringForDisplay("start and select to quit", -150, -40); ******/ //RegisterTextStringForDisplay("test 1234", 0, 0); frameNumber++; DealWithControllerPad(); //GsSetRefView2(&TheView); HandleTheView(); HandleSound(); HandleAllObjects(); GsSetWorkBase( (PACKET*)packetArea[bufferIndex]); GsClearOt(0, 0, &Wot[bufferIndex]); DisplayTextStrings (&Wot[bufferIndex]); 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); } } } DrawCube( &InsideCube, &Wot[bufferIndex]); DrawCube( &OutsideCube, &Wot[bufferIndex]); hsync = VSync(0); ResetGraph(1); GsSwapDispBuff(); GsSortClear(0,0,4,&Wot[bufferIndex]); GsDrawOt(&Wot[bufferIndex]); bufferIndex = GsGetActiveBuff(); FntFlush(-1); } CleanupAndExit(); } void InitialiseAll (void) { PadInit(); InitialiseRandomNumbers(); InitialiseTextStrings(); InitialiseSound(); GsInitGraph(ScreenWidth, ScreenHeight, GsINTER|GsOFSGPU, 1, 0); GsDefDispBuff(0,0,0,ScreenHeight); GsInit3D(); // sort our only ordering table Wot[0].length=OT_LENGTH; Wot[0].org=wtags[0]; Wot[1].length=OT_LENGTH; Wot[1].org=wtags[1]; GsClearOt(0,0,&Wot[0]); GsClearOt(0,0,&Wot[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(GREEN_CIRCLE_TEXTURE_ADDRESS, &GreenCircleTextureInfo); LinkSpriteToImageInfo(&GreenCircleSprite, &GreenCircleTextureInfo); ProperInitialiseTexture(STARS_TEXTURE_ADDRESS, &StarsTextureInfo); LinkSpriteToImageInfo(&StarsSprite, &StarsTextureInfo); ProperInitialiseTexture(PURPLE_NOISE_TEXTURE_ADDRESS, &PurpleNoiseTextureInfo); LinkSpriteToImageInfo(&PurpleNoiseSprite, &PurpleNoiseTextureInfo); ProperInitialiseTexture(ORANGE_TILE_TEXTURE_ADDRESS, &OrangeTileTextureInfo); LinkSpriteToImageInfo(&OrangeTileSprite, &OrangeTileTextureInfo); ProperInitialiseTexture(MULTIPLE_TEXTURE_ADDRESS, &MultipleTextureInfo); LinkSpriteToImageInfo(&MultipleSprite, &MultipleTextureInfo); // sort basic text printing FntLoad( 960, 256); FntOpen( -120, 30, 256, 200, 0, 512); InitialiseObjects(); ClearTheCreatedTmds(); InitialiseCubes(); } 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 = 1000; 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); } 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); 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) ); } } } 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 // 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, 1, ONE_TEXTURE_PER_CORNER, insideTextureAreasList); #if 0 // outside cube not ready setRECT( &singleOutsideCubeTexture, WaveTextureInfo.px, WaveTextureInfo.py, WaveTextureInfo.pw, WaveTextureInfo.ph); CreateCube ( &OutsideCube, OUTSIDE_CUBE, 25000, VISIBLE_FROM_INSIDE, 1, 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 DealWithControllerPad (void) { long pad; int controlSpeed; pad = PadRead(); // and