/************************************************************ * * * main.c * * * * * LPGE 1997 * * * * Copyright (C) 1996 Sony Computer Entertainment Inc. * * All Rights Reserved * * * ***********************************************************/ // Between The Eyes // 3d tunnel racing game /**************************************************************************** includes ****************************************************************************/ #include "sys_libs.h" #include "general.h" #include "asssert.h" #include "dump.h" #include "pad.h" #include "2d1.h" #include "text_str.h" #include "address.h" #include "sound.h" #include "object.h" #include "trig.h" #include "vector.h" #include "matrix.h" #include "coord.h" #include "tunnel.h" #include "tunnel2.h" #include "flying.h" #include "menu.h" #include "tracks.h" #include "main.h" #include "drawproc.h" #include "camera.h" /**************************************************************************** structures, constants, globals ****************************************************************************/ GsGLINE SpeedLines[16]; GsIMAGE AsciiTextureInfo; GsSPRITE AsciiSetSprite; GsIMAGE FireBackgroundImageInfo; GsSPRITE FireBackgroundSprite; // lots of textures // most have GsIMAGE (info) and GsSPRITE (draw) GsIMAGE BarRedTextureInfo; GsSPRITE BarRedSprite; GsIMAGE SimpleBlueTextureInfo; GsSPRITE SimpleBlueSprite; GsIMAGE BarSpectrumTextureInfo; GsSPRITE BarSpectrumSprite; GsIMAGE SmoothSpectrumTextureInfo; GsSPRITE SmoothSpectrumSprite; GsIMAGE SmoothRedTextureInfo; GsSPRITE SmoothRedSprite; GsIMAGE Arrow2TextureInfo; GsSPRITE Arrow2Sprite; GsIMAGE Chevron1TextureInfo; GsSPRITE ChevronSprite; GsIMAGE CircleTextureInfo; GsSPRITE CircleSprite; GsIMAGE HorizontalLargeTextureInfo; GsSPRITE HorizontalLargeSprite; GsIMAGE PanelTextureInfo; GsSPRITE PanelSprite; GsIMAGE Wave16TextureInfo; GsIMAGE DynamicAreaTwoTextureInfo; GsIMAGE DynamicAreaThreeTextureInfo; GsIMAGE DynamicAreaFourTextureInfo; GsIMAGE TileFiveTextureInfo; GsSPRITE TileFiveSprite; GsIMAGE FireTextureInfo; GsSPRITE FireSprite; GsIMAGE Spectrum2TextureInfo; GsSPRITE Spectrum2Sprite; GsIMAGE Spectrum3TextureInfo; GsSPRITE Spectrum3Sprite; GsIMAGE Number1TextureInfo; // swirl_pp GsSPRITE Number1Sprite; GsIMAGE Number2TextureInfo; // swirl_rg GsSPRITE Number2Sprite; GsIMAGE Number3TextureInfo; // tilecube GsSPRITE Number3Sprite; GsIMAGE Number4TextureInfo; // water1 GsSPRITE Number4Sprite; GsIMAGE Number5TextureInfo; // ribbon GsSPRITE Number5Sprite; GsIMAGE Number6TextureInfo; // spheres GsSPRITE Number6Sprite; GsIMAGE Number7TextureInfo; // swirl_br GsSPRITE Number7Sprite; GsIMAGE Number8TextureInfo; // yellowsq GsSPRITE Number8Sprite; GsIMAGE Number9TextureInfo; // water3 GsSPRITE Number9Sprite; GsIMAGE Number10TextureInfo; // pinkflam GsSPRITE Number10Sprite; GsIMAGE Number11TextureInfo; // purp_web GsSPRITE Number11Sprite; GsIMAGE Number12TextureInfo; // purple1 GsSPRITE Number12Sprite; GsIMAGE Number13TextureInfo; // purple3 GsSPRITE Number13Sprite; GsIMAGE Number14TextureInfo; // fiery GsSPRITE Number14Sprite; GsIMAGE Number15TextureInfo; // greeny GsSPRITE Number15Sprite; GsIMAGE Number16TextureInfo; // knotwork GsSPRITE Number16Sprite; GsIMAGE Number17TextureInfo; // lava1 GsSPRITE Number17Sprite; GsIMAGE Number18TextureInfo; // red1 GsSPRITE Number18Sprite; GsIMAGE Number19TextureInfo; // bluish3 GsSPRITE Number19Sprite; GsIMAGE Number20TextureInfo; // peach GsSPRITE Number20Sprite; GsIMAGE Number21TextureInfo; // buckybal GsSPRITE Number21Sprite; GsIMAGE Number22TextureInfo; // bg_atoms GsSPRITE Number22Sprite; GsIMAGE Number23TextureInfo; // button GsSPRITE Number23Sprite; GsIMAGE Number24TextureInfo; // chains GsSPRITE Number24Sprite; GsIMAGE Number25TextureInfo; // faces GsSPRITE Number25Sprite; GsIMAGE Number26TextureInfo; // blackwav GsSPRITE Number26Sprite; GsIMAGE Number27TextureInfo; // bluesq GsSPRITE Number27Sprite; GsIMAGE Number28TextureInfo; // bluish GsSPRITE Number28Sprite; GsIMAGE Number29TextureInfo; // bluish2 GsSPRITE Number29Sprite; GsIMAGE Wave15ImageInfo; GsSPRITE Wave15Sprite; GsIMAGE Number30TextureInfo; // image3 GsSPRITE Number30Sprite; GsIMAGE Number31TextureInfo; // image4 GsSPRITE Number31Sprite; GsIMAGE Number32TextureInfo; // image5 GsSPRITE Number32Sprite; GsIMAGE Number33TextureInfo; // image6 GsSPRITE Number33Sprite; GsIMAGE Number34TextureInfo; // image7 GsSPRITE Number34Sprite; GsIMAGE Number35TextureInfo; // image8 GsSPRITE Number35Sprite; GsIMAGE Number36TextureInfo; // image11 GsSPRITE Number36Sprite; GsIMAGE Number37TextureInfo; // image13 GsSPRITE Number37Sprite; GsIMAGE Number38TextureInfo; // image14 GsSPRITE Number38Sprite; GsIMAGE Number39TextureInfo; // image16 GsSPRITE Number39Sprite; GsIMAGE Number40TextureInfo; // image18 GsSPRITE Number40Sprite; GsIMAGE Number41TextureInfo; // image19 GsSPRITE Number41Sprite; GsIMAGE Number42TextureInfo; // image21 GsSPRITE Number42Sprite; GsIMAGE Number43TextureInfo; // image22 GsSPRITE Number43Sprite; GsIMAGE Number44TextureInfo; // image23 GsSPRITE Number44Sprite; GsIMAGE Number45TextureInfo; // image25 GsSPRITE Number45Sprite; GsIMAGE Number46TextureInfo; // image68 GsSPRITE Number46Sprite; GsIMAGE Number47TextureInfo; // image71 GsSPRITE Number47Sprite; GsIMAGE Number48TextureInfo; // image84 GsSPRITE Number48Sprite; GsIMAGE Number49TextureInfo; // image111 GsSPRITE Number49Sprite; GsIMAGE Number50TextureInfo; // oden GsSPRITE Number50Sprite; GsIMAGE Number51TextureInfo; // dbtile GsSPRITE Number51Sprite; GsIMAGE Number52TextureInfo; // dirtchek GsSPRITE Number52Sprite; GsIMAGE Spiral1TextureInfo; GsSPRITE Spiral1Sprite; GsIMAGE Spiral2TextureInfo; GsSPRITE Spiral2Sprite; GsIMAGE Spiral3TextureInfo; GsSPRITE Spiral3Sprite; GsIMAGE Spiral4TextureInfo; GsSPRITE Spiral4Sprite; GsSPRITE ScreenSprite; GsSPRITE *GlobalSpriteList[MAX_GLOBAL_SPRITES]; int NumberGlobalSprites; int SelectedGlobalSprite; int ShowGlobalSpriteFlag; GsIMAGE *GlobalImageList[MAX_GLOBAL_IMAGES]; int NumberGlobalImages; int DrawProcessesClippingFlag; int DebugDynTexMarker = FALSE; int DebugSelectedDrawProcess = 0; GsBOXF FadeBox; int BackgroundColourRed, BackgroundColourGreen, BackgroundColourBlue; PACKET packetArea[2][1536 * MAX_SIZEOF_PRIMITIVE]; /* GPU PACKETS AREA */ // NOTE: small size of these means only 128 primitives per area // more will cause memory trashing PACKET packetArea2[2][128 * MAX_SIZEOF_PRIMITIVE]; PACKET packetArea3[2][128 * MAX_SIZEOF_PRIMITIVE]; PACKET packetArea4[2][128 * MAX_SIZEOF_PRIMITIVE]; PACKET packetArea5[2][128 * MAX_SIZEOF_PRIMITIVE]; PACKET packetArea6[2][1536 * MAX_SIZEOF_PRIMITIVE]; PACKET packetArea7[2][128 * MAX_SIZEOF_PRIMITIVE]; 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 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 &= onlyNthBitOffMask; \ } /**************************************************************************** functions ****************************************************************************/ #if (DEMO_SEGMENT_FLAG==1) u_long _ramsize = 0x00200000; u_long _stacksize = 0x00004000; #endif // all this nastiness due to possible use as demo segment // when it is, gets passed args from invoking bootstrap program // otherwise, takes no args #if (DEMO_SEGMENT_FLAG==1) int main (int argc, char **argv) #else int main (void) #endif { #if (DEMO_SEGMENT_FLAG==1) GlobalProgramMode = ((int *)argv)[0]; GlobalProgramTimeout = ((int *)argv)[1]; #endif InitialiseAll(); HandleTheGameStateMachine(); //printf("Have fallen back into main\n"); CleanUpProgram(); //printf("About to return zero from main\n"); return 0; } void InitialiseAll (void) { #if (DEVELOPMENT_ENVIRONMENT==DEV_KIT) { ResetCallback(); #if (DEMO_SEGMENT_FLAG==1) CdInit(); // TOTAL FAILURE UNDER DEV_KIT WITH LIB.34; // keeps printing Cd Opening in endless loop #endif ResetGraph(0); } #endif #if (DEMO_SEGMENT_FLAG==1) // READING DATA FILES FROM CD INTO RAM /* OLD: lib40 DatafileSearch(); DatafileRead();*/ DatafileSortAll(); // LIST of files needs to be current with batch/auto3 // the list in makefile.mak #endif PRINT("\n\n/******************************/\n"); PRINT("\tBetween The Eyes\t\n"); PRINT("/******************************/\n\n\n"); PadInit(0); // sort out standard controller pads InitialiseRandomNumbers(); // seed random number generator InitialiseCompactDiscBusiness(); InitialiseSound(); InitProfiler2(); ScreenResolution = HI_RES; #if (DEVELOPMENT_ENVIRONMENT==DEV_KIT) SetVideoMode(MODE_NTSC); #endif SetVideoMode(MODE_PAL); // PAL VERSION SET SortVideoMode(); // auto-detect, set dependent parameters switch(ScreenResolution) { case LOW_RES: ScreenWidth = 320; switch(ScreenVideoMode) { case MODE_NTSC: ScreenHeight = 240; break; case MODE_PAL: ScreenHeight = 240; // should be 256 but for library bug break; default: assert(FALSE); } GsInitGraph(ScreenWidth, ScreenHeight, GsINTER|GsOFSGPU, 1, 0); GsDefDispBuff(0,0,0,ScreenHeight); break; case HI_RES: ScreenWidth = 640; switch(ScreenVideoMode) { case MODE_NTSC: ScreenHeight = 480; break; case MODE_PAL: ScreenHeight = 480; // should be 512 but for library bug break; default: assert(FALSE); } GsInitGraph(ScreenWidth, ScreenHeight, GsINTER|GsOFSGPU, 1, 0); GsDefDispBuff(0,0,0,0); break; default: assert(FALSE); } GsInit3D(); // set up our ordering tables 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]); 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]); 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]); 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]); 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]); Wot6[0].length = OT_LENGTH; Wot6[0].org = wtags6[0]; Wot6[1].length = OT_LENGTH; Wot6[1].org = wtags6[1]; GsClearOt(0, 0, &Wot6[0]); GsClearOt(0, 0, &Wot6[1]); 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]); LinkDrawingFunctionsIntoFunctionTable(); // clear strings sprintf(SimplePrintString1, "\n"); sprintf(SimplePrintString2, "\n"); sprintf(SimplePrintString3, "\n"); sprintf(SimplePrintString4, "\n"); sprintf(SimplePrintString5, "\n"); sprintf(SimplePrintString6, "\n"); SetBasicParametersForAllShips(); InitialiseTexturesAndSprites(); InitialiseTextStrings(); InitialiseModels(); InitialiseObjects(); ResetShipModelsToDefault(); InitialiseLighting(); InitialiseView(); InitFntPrints(); // PrintDataTypeSizes(); FirstEverTunnelInit(); InitialiseMenuScreenBackgroundGraphics(); InitialiseDataCacheStackUse(); InitialiseTheGameState(); // misc globals GlobalShipLightingEffectFlag = FIRST; // dynamic texturing debug helpers DebugDynTexMarker = FALSE; DebugSelectedDrawProcess = 0; // screen fader primitive FadeBox.attribute = 0; FadeBox.r = 128; FadeBox.g = 128; FadeBox.b = 128; FadeBox.x = -320; FadeBox.y = -240; FadeBox.w = 640; FadeBox.h = 480; // timing trackers frameNumber = 0; hsync = 0; maxHsync = 0; gpuLoad = 0; cpuLoad = 0; frameLimiter = 1; GlobalPauseFlag = FALSE; framesSinceLongPauseToggle = 0; // getting screen snapshots flag StoreScreenFlag = FALSE; // screen sprite: 32x32 16-bit sprite InitGsSprite( &ScreenSprite); ScreenSprite.w = 32; ScreenSprite.h = 32; ScreenSprite.attribute |= SIXTEEN_BIT_MASK; ScreenSprite.tpage = GetTPage(2, 0, 0, 0); ScreenSprite.u = 0; ScreenSprite.v = 0; // dots for some dynamic processes SetUpSquareDots(); printf("End of InitialiseAll\n"); } #if (DEMO_SEGMENT_FLAG==1) // section for reading files from CD into main RAM #if 0 // OLD #define NUMBER_FILES 11 typedef struct { char fname[64]; void *addr; CdlFILE finfo; } FILE_INFO; // this generated from files and static FILE_INFO DataFiles[NUMBER_FILES] = { {"\\BETWEEN\\BETWEEN.DAT;1", (void *)0x80090000, 0 }, {"\\BETWEEN\\SPIRAL1.TIM;1", (void *)SPIRAL_1_TEXTURE_ADDRESS, 0 }, {"\\BETWEEN\\SPIRAL2.TIM;1", (void *)SPIRAL_2_TEXTURE_ADDRESS, 0 }, {"\\BETWEEN\\SPIRAL3.TIM;1", (void *)SPIRAL_3_TEXTURE_ADDRESS, 0 }, {"\\BETWEEN\\SPIRAL4.TIM;1", (void *)SPIRAL_4_TEXTURE_ADDRESS, 0 }, {"\\BETWEEN\\SHIP6.TMD;1", (void *)SHIP_2_MODEL_ADDRESS, 0 }, {"\\BETWEEN\\SHIP31.TMD;1", (void *)SHIP_4_MODEL_ADDRESS, 0 }, {"\\BETWEEN\\SHIP32.TMD;1", (void *)SHIP_5_MODEL_ADDRESS, 0 }, {"\\BETWEEN\\SHIP26.TMD;1", (void *)SHIP_6_MODEL_ADDRESS, 0 }, {"\\BETWEEN\\SHIP42.TMD;1", (void *)SHIP_7_MODEL_ADDRESS, 0 }, {"\\BETWEEN\\SHIP43.TMD;1", (void *)SHIP_8_MODEL_ADDRESS, 0 }, {"\\BETWEEN\\TRACKS16.DAT;1", (void *)TRACK_DATAFILE_ADDRESS, 0 } }; #endif // OLD #if 1 // NEW #define NUMBER_FILES 1 typedef struct { char fname[64]; void *addr; CdlFILE finfo; } FILE_INFO; // this generated from files and static FILE_INFO DataFiles[NUMBER_FILES] = { {"\\BETWEEN\\BETWEEN.DAT;1", (void *)0x80090000, 0 } }; #endif #if 0 // NOT WITH BOOTSTRAP // this CD-file-access code taken straight from other samples void DatafileSearch (void) { int i, j; int success = FALSE; for (i = 0; i < NUMBER_FILES; i++) { for (j = 0; j < 50; j++) { if (CdSearchFile(&(DataFiles[i].finfo), DataFiles[i].fname) != 0) { success = TRUE; break; } else printf("%s not found in DatafileSearch.\n", DataFiles[i].fname); } } switch(success) { case TRUE: printf("end of DatafileSearch: SUCCESSFUL\n\n"); break; case FALSE: printf("end of DatafileSearch: FAILURE\n\n"); break; default: assert(FALSE); } } void DatafileRead (void) { int i, j; int cnt; int success = FALSE; for (i = 0; i < NUMBER_FILES; i++) { for (j = 0; j < 50; j++) { CdReadFile(DataFiles[i].fname, DataFiles[i].addr, DataFiles[i].finfo.size); while ((cnt = CdReadSync(1, 0)) > 0 ) VSync(0); if (cnt == 0) { success = TRUE; break; } else { if (j == 49) { printf("failure to read file %s. in DatafileRead\n", DataFiles[i].fname); } } } } switch(success) { case TRUE: printf("end of DatafileRead: SUCCESSFUL\n\n"); break; case FALSE: printf("end of DatafileRead: FAILURE\n\n"); break; default: assert(FALSE); } } #endif // NOT WITH BOOTSTRAP void DatafileSortAll (void) { int i; for (i = 0; i < NUMBER_FILES; i++) { LoadFileFromCdIntoRAM( DataFiles[i].fname, DataFiles[i].addr); } printf("end of DatafileSortAll\n"); } #define FORM1_SIZE 2048 /* Size of an XA mode 1 form 1 sector. */ /* This macro gives the number of sectors a file of length x bytes takes up. */ #define Sectors(x) (((x)+FORM1_SIZE-1)/FORM1_SIZE) void LoadFileFromCdIntoRAM (char *name, unsigned long* address) { CdlFILE fp; u_long addr; int numSectors; /* Number of sectors the file takes up. */ int mode = 0; /* The mode word for CdRead. */ u_long size; if (!CdSearchFile(&fp, name)) /* Find the stream file on CD. */ { printf("Couldn't find %s.\n",name); } size = fp.size; /* Get the file length. */ /* Call Cd control (blocking) to seek to the logical file position. */ /* If the CD doesn't acknowledge, return 0 for an error code. */ if (!CdControlB(CdlSeekL,(unsigned char *)&fp.pos, 0)) { printf("TROUBLE\n"); HERE; } /* Work out the number of sectors from the length of the file on CD. */ numSectors = Sectors(size); /* Make up the CD mode word (just double speed flag). */ mode |= CdlModeSpeed; /* Call CdRead() to read the sectors into the buffer at double speed. */ /* If the CD doesn't respond, then return 0. */ if(!CdRead(numSectors, (unsigned long *)address, mode)) { printf("MORE TROUBLE\n"); HERE; } /* Block until the CD has finished reading (ie make the call block). */ while (CdReadSync(1,0) > 0 ); VSync(3); } #endif void InitialiseCompactDiscBusiness (void) { int i; CompactDiscTrackNumber = 1; CompactDiscVolumeSetting = 127; // track list: e.g. {1,2,3,4,5,0} // first track on PSX disc will always be code and data // all other tracks can be used as audio tracks for (i = 0; i < NUMBER_CD_TRACKS; i++) CompactDiscTrackList[i] = i+1; CompactDiscTrackList[NUMBER_CD_TRACKS-1] = 0; SoundToGraphicInUseFlag = FALSE; for (i = 0; i < 4096; i++) CdBuffer[i] = 0; CdDataPointer = NULL; for (i = 0; i < 32; i++) Cd32foldBuffer[i] = 0; for (i = 0; i < 16; i++) Cd16foldBuffer[i] = 0; for (i = 0; i < 8; i++) Cd8foldBuffer[i] = 0; for (i = 0; i < 4; i++) Cd4foldBuffer[i] = 0; CdTotalLeftVolume = 0; CdTotalRightVolume = 0; CdTotalVolume = 0; #if (DEMO_SEGMENT_FLAG==1) CompactDiscMusicPlayFlag = FALSE; #else #if (DEVELOPMENT_ENVIRONMENT==YAROZE) { CompactDiscMusicPlayFlag = FALSE; // used to be TRUE by default SsSetSerialVol(SS_CD, 127, 127); SsSetSerialAttr(SS_CD, SS_REV, SS_SOFF); SsSetSerialAttr(SS_CD, SS_MIX, SS_SON); // start program playing background tune instead of CD //CdPlay(2, CompactDiscTrackList, 0); // second track on disc } #else { CompactDiscMusicPlayFlag = FALSE; } #endif #endif } 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]); BackgroundColourRed = 0; BackgroundColourGreen = 0; BackgroundColourBlue = 0; // background lighting GsSetAmbient(ONE/4, ONE/4, ONE/4); // distance colour blending TheFogging.dqa = -15000; TheFogging.dqb = 5120*5120; TheFogging.rfc = 0; TheFogging.gfc = 0; TheFogging.bfc = 0; GsSetFogParam( &TheFogging); // overall lighting conditions OverallLightMode = 0; // start off with no fogging GsSetLightMode(OverallLightMode); } void SetThreeWhiteLights (void) { // all white, pointing along different cardinal axes TheLights[0].vx = ONE; TheLights[0].vy = 0; TheLights[0].vz = 0; TheLights[0].r = 128; TheLights[0].g = 128; TheLights[0].b = 128; GsSetFlatLight(0, &TheLights[0]); TheLights[1].vx = 0; TheLights[1].vy = ONE; TheLights[1].vz = 0; TheLights[1].r = 128; TheLights[1].g = 128; TheLights[1].b = 128; GsSetFlatLight(1, &TheLights[1]); TheLights[2].vx = 0; TheLights[2].vy = 0; TheLights[2].vz = ONE; TheLights[2].r = 128; TheLights[2].g = 128; TheLights[2].b = 128; GsSetFlatLight(2, &TheLights[2]); } void SetTheAbsenceOfFlatLight (void) { // all give zero illumination, pointing along different cardinal axes TheLights[0].vx = ONE; TheLights[0].vy = 0; TheLights[0].vz = 0; TheLights[0].r = 0; 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 = 0; 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 = 0; GsSetFlatLight(2, &TheLights[2]); } void SetThreeColouredLights (void) { // one red, another green, another blue 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]); } void InitialiseView (void) { // set viewpoint to screen distance ProjectionDistance = FIXED_PROJECTION_DISTANCE; GsSetProjection(ProjectionDistance); SetCoreViewParameters(); TheViewShip = NULL; } void InitialiseTexturesAndSprites (void) { // load TIM files to video memory // and obtain permanent records for later uses ProperInitialiseTexture(FIRE_BACKGROUND_TEXTURE_ADDRESS, &FireBackgroundImageInfo); LinkSpriteToImageInfo( &FireBackgroundSprite, &FireBackgroundImageInfo); ProperInitialiseTexture(ASCII_TEXTURE_ADDRESS, &AsciiTextureInfo); LinkSpriteToImageInfo( &AsciiSetSprite, &AsciiTextureInfo); /// texture for square model ProperInitialiseTexture(BAR_RED_TEXTURE_ADDRESS, &BarRedTextureInfo); LinkSpriteToImageInfo( &BarRedSprite, &BarRedTextureInfo); ProperInitialiseTexture(SIMPLE_BLUE_TEXTURE_ADDRESS, &SimpleBlueTextureInfo); LinkSpriteToImageInfo( &SimpleBlueSprite, &SimpleBlueTextureInfo); ProperInitialiseTexture(BAR_SPECTRUM_TEXTURE_ADDRESS, &BarSpectrumTextureInfo); LinkSpriteToImageInfo( &BarSpectrumSprite, &BarSpectrumTextureInfo); ProperInitialiseTexture(SMOOTH_SPECTRUM_TEXTURE_ADDRESS, &SmoothSpectrumTextureInfo); LinkSpriteToImageInfo( &SmoothSpectrumSprite, &SmoothSpectrumTextureInfo); ProperInitialiseTexture(SMOOTH_RED_TEXTURE_ADDRESS, &SmoothRedTextureInfo); LinkSpriteToImageInfo( &SmoothRedSprite, &SmoothRedTextureInfo); ProperInitialiseTexture(ARROW_TEXTURE_2_ADDRESS, &Arrow2TextureInfo); LinkSpriteToImageInfo( &Arrow2Sprite, &Arrow2TextureInfo); ProperInitialiseTexture(CHEVRON_TEXTURE_1_ADDRESS, &Chevron1TextureInfo); LinkSpriteToImageInfo( &ChevronSprite, &Chevron1TextureInfo); ProperInitialiseTexture(CIRCLE_TEXTURE_ADDRESS, &CircleTextureInfo); LinkSpriteToImageInfo( &CircleSprite, &CircleTextureInfo); ProperInitialiseTexture(HORIZONTAL_LARGE_TEXTURE_ADDRESS, &HorizontalLargeTextureInfo); LinkSpriteToImageInfo( &HorizontalLargeSprite, &HorizontalLargeTextureInfo); ProperInitialiseTexture(PANEL_TEXTURE_ADDRESS, &PanelTextureInfo); LinkSpriteToImageInfo( &PanelSprite, &PanelTextureInfo); ProperInitialiseTexture(WAVE_16_TEXTURE_ADDRESS, &Wave16TextureInfo); // put same TIM into other positions: a total of four dynamic texturing areas ForceTextureIntoPosition (WAVE_16_TEXTURE_ADDRESS, &DynamicAreaTwoTextureInfo, 832, 416, 0, 0); ForceTextureIntoPosition (WAVE_16_TEXTURE_ADDRESS, &DynamicAreaThreeTextureInfo, 896, 416, 0, 0); ForceTextureIntoPosition (WAVE_16_TEXTURE_ADDRESS, &DynamicAreaFourTextureInfo, 960, 416, 0, 0); ProperInitialiseTexture(TILE_FIVE_TEXTURE_ADDRESS, &TileFiveTextureInfo); LinkSpriteToImageInfo( &TileFiveSprite, &TileFiveTextureInfo); ProperInitialiseTexture(FIRE_TEXTURE_ADDRESS, &FireTextureInfo); LinkSpriteToImageInfo( &FireSprite, &FireTextureInfo); ProperInitialiseTexture(SPECTRUM_2_TEXTURE_ADDRESS, &Spectrum2TextureInfo); LinkSpriteToImageInfo( &Spectrum2Sprite, &Spectrum2TextureInfo); ProperInitialiseTexture(SPECTRUM_3_TEXTURE_ADDRESS, &Spectrum3TextureInfo); LinkSpriteToImageInfo( &Spectrum3Sprite, &Spectrum3TextureInfo); ProperInitialiseTexture(NUMBER_1_TEXTURE_ADDRESS, &Number1TextureInfo); LinkSpriteToImageInfo( &Number1Sprite, &Number1TextureInfo); ProperInitialiseTexture(NUMBER_2_TEXTURE_ADDRESS, &Number2TextureInfo); LinkSpriteToImageInfo( &Number2Sprite, &Number2TextureInfo); ProperInitialiseTexture(NUMBER_3_TEXTURE_ADDRESS, &Number3TextureInfo); LinkSpriteToImageInfo( &Number3Sprite, &Number3TextureInfo); ProperInitialiseTexture(NUMBER_4_TEXTURE_ADDRESS, &Number4TextureInfo); LinkSpriteToImageInfo( &Number4Sprite, &Number4TextureInfo); ProperInitialiseTexture(NUMBER_5_TEXTURE_ADDRESS, &Number5TextureInfo); LinkSpriteToImageInfo( &Number5Sprite, &Number5TextureInfo); ProperInitialiseTexture(NUMBER_6_TEXTURE_ADDRESS, &Number6TextureInfo); LinkSpriteToImageInfo( &Number6Sprite, &Number6TextureInfo); ProperInitialiseTexture(NUMBER_7_TEXTURE_ADDRESS, &Number7TextureInfo); LinkSpriteToImageInfo( &Number7Sprite, &Number7TextureInfo); ProperInitialiseTexture(NUMBER_8_TEXTURE_ADDRESS, &Number8TextureInfo); LinkSpriteToImageInfo( &Number8Sprite, &Number8TextureInfo); ProperInitialiseTexture(NUMBER_9_TEXTURE_ADDRESS, &Number9TextureInfo); LinkSpriteToImageInfo( &Number9Sprite, &Number9TextureInfo); ProperInitialiseTexture(NUMBER_10_TEXTURE_ADDRESS, &Number10TextureInfo); LinkSpriteToImageInfo( &Number10Sprite, &Number10TextureInfo); ProperInitialiseTexture(NUMBER_11_TEXTURE_ADDRESS, &Number11TextureInfo); LinkSpriteToImageInfo( &Number11Sprite, &Number11TextureInfo); ProperInitialiseTexture(NUMBER_12_TEXTURE_ADDRESS, &Number12TextureInfo); LinkSpriteToImageInfo( &Number12Sprite, &Number12TextureInfo); ProperInitialiseTexture(NUMBER_13_TEXTURE_ADDRESS, &Number13TextureInfo); LinkSpriteToImageInfo( &Number13Sprite, &Number13TextureInfo); ProperInitialiseTexture(NUMBER_14_TEXTURE_ADDRESS, &Number14TextureInfo); LinkSpriteToImageInfo( &Number14Sprite, &Number14TextureInfo); ProperInitialiseTexture(NUMBER_15_TEXTURE_ADDRESS, &Number15TextureInfo); LinkSpriteToImageInfo( &Number15Sprite, &Number15TextureInfo); ProperInitialiseTexture(NUMBER_16_TEXTURE_ADDRESS, &Number16TextureInfo); LinkSpriteToImageInfo( &Number16Sprite, &Number16TextureInfo); ProperInitialiseTexture(NUMBER_17_TEXTURE_ADDRESS, &Number17TextureInfo); LinkSpriteToImageInfo( &Number17Sprite, &Number17TextureInfo); ProperInitialiseTexture(NUMBER_18_TEXTURE_ADDRESS, &Number18TextureInfo); LinkSpriteToImageInfo( &Number18Sprite, &Number18TextureInfo); ProperInitialiseTexture(NUMBER_19_TEXTURE_ADDRESS, &Number19TextureInfo); LinkSpriteToImageInfo( &Number19Sprite, &Number19TextureInfo); ProperInitialiseTexture(NUMBER_20_TEXTURE_ADDRESS, &Number20TextureInfo); LinkSpriteToImageInfo( &Number20Sprite, &Number20TextureInfo); ProperInitialiseTexture(NUMBER_21_TEXTURE_ADDRESS, &Number21TextureInfo); LinkSpriteToImageInfo( &Number21Sprite, &Number21TextureInfo); ProperInitialiseTexture(NUMBER_22_TEXTURE_ADDRESS, &Number22TextureInfo); LinkSpriteToImageInfo( &Number22Sprite, &Number22TextureInfo); ProperInitialiseTexture(NUMBER_23_TEXTURE_ADDRESS, &Number23TextureInfo); LinkSpriteToImageInfo( &Number23Sprite, &Number23TextureInfo); ProperInitialiseTexture(NUMBER_24_TEXTURE_ADDRESS, &Number24TextureInfo); LinkSpriteToImageInfo( &Number24Sprite, &Number24TextureInfo); ProperInitialiseTexture(NUMBER_25_TEXTURE_ADDRESS, &Number25TextureInfo); LinkSpriteToImageInfo( &Number25Sprite, &Number25TextureInfo); ProperInitialiseTexture(NUMBER_26_TEXTURE_ADDRESS, &Number26TextureInfo); LinkSpriteToImageInfo( &Number26Sprite, &Number26TextureInfo); ProperInitialiseTexture(NUMBER_27_TEXTURE_ADDRESS, &Number27TextureInfo); LinkSpriteToImageInfo( &Number27Sprite, &Number27TextureInfo); ProperInitialiseTexture(NUMBER_28_TEXTURE_ADDRESS, &Number28TextureInfo); LinkSpriteToImageInfo( &Number28Sprite, &Number28TextureInfo); ProperInitialiseTexture(NUMBER_29_TEXTURE_ADDRESS, &Number29TextureInfo); LinkSpriteToImageInfo( &Number29Sprite, &Number29TextureInfo); ProperInitialiseTexture(WAVE_15_TEXTURE_ADDRESS, &Wave15ImageInfo); LinkSpriteToImageInfo( &Wave15Sprite, &Wave15ImageInfo); ProperInitialiseTexture(NUMBER_30_TEXTURE_ADDRESS, &Number30TextureInfo); LinkSpriteToImageInfo( &Number30Sprite, &Number30TextureInfo); ProperInitialiseTexture(NUMBER_31_TEXTURE_ADDRESS, &Number31TextureInfo); LinkSpriteToImageInfo( &Number31Sprite, &Number31TextureInfo); ProperInitialiseTexture(NUMBER_32_TEXTURE_ADDRESS, &Number32TextureInfo); LinkSpriteToImageInfo( &Number32Sprite, &Number32TextureInfo); ProperInitialiseTexture(NUMBER_33_TEXTURE_ADDRESS, &Number33TextureInfo); LinkSpriteToImageInfo( &Number33Sprite, &Number33TextureInfo); ProperInitialiseTexture(NUMBER_34_TEXTURE_ADDRESS, &Number34TextureInfo); LinkSpriteToImageInfo( &Number34Sprite, &Number34TextureInfo); ProperInitialiseTexture(NUMBER_35_TEXTURE_ADDRESS, &Number35TextureInfo); LinkSpriteToImageInfo( &Number35Sprite, &Number35TextureInfo); ProperInitialiseTexture(NUMBER_36_TEXTURE_ADDRESS, &Number36TextureInfo); LinkSpriteToImageInfo( &Number36Sprite, &Number36TextureInfo); ProperInitialiseTexture(NUMBER_37_TEXTURE_ADDRESS, &Number37TextureInfo); LinkSpriteToImageInfo( &Number37Sprite, &Number37TextureInfo); ProperInitialiseTexture(NUMBER_38_TEXTURE_ADDRESS, &Number38TextureInfo); LinkSpriteToImageInfo( &Number38Sprite, &Number38TextureInfo); ProperInitialiseTexture(NUMBER_39_TEXTURE_ADDRESS, &Number39TextureInfo); LinkSpriteToImageInfo( &Number39Sprite, &Number39TextureInfo); ProperInitialiseTexture(NUMBER_40_TEXTURE_ADDRESS, &Number40TextureInfo); LinkSpriteToImageInfo( &Number40Sprite, &Number40TextureInfo); ProperInitialiseTexture(NUMBER_41_TEXTURE_ADDRESS, &Number41TextureInfo); LinkSpriteToImageInfo( &Number41Sprite, &Number41TextureInfo); ProperInitialiseTexture(NUMBER_42_TEXTURE_ADDRESS, &Number42TextureInfo); LinkSpriteToImageInfo( &Number42Sprite, &Number42TextureInfo); ProperInitialiseTexture(NUMBER_43_TEXTURE_ADDRESS, &Number43TextureInfo); LinkSpriteToImageInfo( &Number43Sprite, &Number43TextureInfo); ProperInitialiseTexture(NUMBER_44_TEXTURE_ADDRESS, &Number44TextureInfo); LinkSpriteToImageInfo( &Number44Sprite, &Number44TextureInfo); ProperInitialiseTexture(NUMBER_45_TEXTURE_ADDRESS, &Number45TextureInfo); LinkSpriteToImageInfo( &Number45Sprite, &Number45TextureInfo); ProperInitialiseTexture(NUMBER_46_TEXTURE_ADDRESS, &Number46TextureInfo); LinkSpriteToImageInfo( &Number46Sprite, &Number46TextureInfo); ProperInitialiseTexture(NUMBER_47_TEXTURE_ADDRESS, &Number47TextureInfo); LinkSpriteToImageInfo( &Number47Sprite, &Number47TextureInfo); ProperInitialiseTexture(NUMBER_48_TEXTURE_ADDRESS, &Number48TextureInfo); LinkSpriteToImageInfo( &Number48Sprite, &Number48TextureInfo); ProperInitialiseTexture(NUMBER_49_TEXTURE_ADDRESS, &Number49TextureInfo); LinkSpriteToImageInfo( &Number49Sprite, &Number49TextureInfo); ProperInitialiseTexture(NUMBER_50_TEXTURE_ADDRESS, &Number50TextureInfo); LinkSpriteToImageInfo( &Number50Sprite, &Number50TextureInfo); ProperInitialiseTexture(NUMBER_51_TEXTURE_ADDRESS, &Number51TextureInfo); LinkSpriteToImageInfo( &Number51Sprite, &Number51TextureInfo); ProperInitialiseTexture(NUMBER_52_TEXTURE_ADDRESS, &Number52TextureInfo); LinkSpriteToImageInfo( &Number52Sprite, &Number52TextureInfo); ProperInitialiseTexture(SPIRAL_1_TEXTURE_ADDRESS, &Spiral1TextureInfo); LinkSpriteToImageInfo( &Spiral1Sprite, &Spiral1TextureInfo); ProperInitialiseTexture(SPIRAL_2_TEXTURE_ADDRESS, &Spiral2TextureInfo); LinkSpriteToImageInfo( &Spiral2Sprite, &Spiral2TextureInfo); ProperInitialiseTexture(SPIRAL_3_TEXTURE_ADDRESS, &Spiral3TextureInfo); LinkSpriteToImageInfo( &Spiral3Sprite, &Spiral3TextureInfo); ProperInitialiseTexture(SPIRAL_4_TEXTURE_ADDRESS, &Spiral4TextureInfo); LinkSpriteToImageInfo( &Spiral4Sprite, &Spiral4TextureInfo); // global sprite section NumberGlobalSprites = 0; GlobalSpriteList[NumberGlobalSprites] = &AsciiSetSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &FireBackgroundSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &BarRedSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &SimpleBlueSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &BarSpectrumSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &SmoothSpectrumSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &SmoothRedSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Arrow2Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &ChevronSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &HorizontalLargeSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &CircleSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &PanelSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &TileFiveSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &FireSprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Spectrum2Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Spectrum3Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number1Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number2Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number3Sprite; NumberGlobalSprites++; #if 0 // removed GlobalSpriteList[NumberGlobalSprites] = &Number4Sprite; NumberGlobalSprites++; #endif GlobalSpriteList[NumberGlobalSprites] = &Number5Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number6Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number7Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number8Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number9Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number10Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number11Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number12Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number13Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number14Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number15Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number16Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number17Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number18Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number19Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number20Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number21Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number22Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number23Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number24Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number25Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number26Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number27Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number28Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number29Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number30Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number31Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number32Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number33Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number34Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number35Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number36Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number37Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number38Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number39Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number40Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number41Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number42Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number43Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number44Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number45Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number46Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number47Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number48Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number49Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number50Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number51Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Number52Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Spiral1Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Spiral2Sprite; NumberGlobalSprites++; GlobalSpriteList[NumberGlobalSprites] = &Spiral3Sprite; NumberGlobalSprites++; #if 0 // removed GlobalSpriteList[NumberGlobalSprites] = &Spiral4Sprite; NumberGlobalSprites++; #endif assert(NumberGlobalSprites-1 <= MAX_GLOBAL_SPRITES); ShowGlobalSpriteFlag = FALSE; SelectedGlobalSprite = 0; // global image section NumberGlobalImages = 0; GlobalImageList[ASCII_TEXTURE_ID] = &AsciiTextureInfo; NumberGlobalImages++; GlobalImageList[FIRE_BACKGROUND_TEXTURE_ID] = &FireBackgroundImageInfo; NumberGlobalImages++; GlobalImageList[BAR_RED_TEXTURE_ID] = &BarRedTextureInfo; NumberGlobalImages++; GlobalImageList[SIMPLE_BLUE_TEXTURE_ID] = &SimpleBlueTextureInfo; NumberGlobalImages++; GlobalImageList[BAR_SPECTRUM_TEXTURE_ID] = &BarSpectrumTextureInfo; NumberGlobalImages++; GlobalImageList[SMOOTH_SPECTRUM_TEXTURE_ID] = &SmoothSpectrumTextureInfo; NumberGlobalImages++; GlobalImageList[SMOOTH_RED_TEXTURE_ID] = &SmoothRedTextureInfo; NumberGlobalImages++; GlobalImageList[ARROW_2_TEXTURE_ID] = &Arrow2TextureInfo; NumberGlobalImages++; GlobalImageList[CHEVRON_1_TEXTURE_ID] = &Chevron1TextureInfo; NumberGlobalImages++; GlobalImageList[CIRCLE_TEXTURE_ID] = &HorizontalLargeTextureInfo; NumberGlobalImages++; GlobalImageList[HORIZONTAL_LARGE_TEXTURE_ID] = &CircleTextureInfo; NumberGlobalImages++; GlobalImageList[PANEL_TEXTURE_ID] = &PanelTextureInfo; NumberGlobalImages++; GlobalImageList[WAVE_16_TEXTURE_ID] = &Wave16TextureInfo; NumberGlobalImages++; GlobalImageList[DYNAMIC_AREA_2_TEXTURE_ID] = &DynamicAreaTwoTextureInfo; NumberGlobalImages++; GlobalImageList[DYNAMIC_AREA_3_TEXTURE_ID] = &DynamicAreaThreeTextureInfo; NumberGlobalImages++; GlobalImageList[DYNAMIC_AREA_4_TEXTURE_ID] = &DynamicAreaFourTextureInfo; NumberGlobalImages++; GlobalImageList[TILE_FIVE_TEXTURE_ID] = &TileFiveTextureInfo; NumberGlobalImages++; GlobalImageList[FIRE_TEXTURE_ID] = &FireTextureInfo; NumberGlobalImages++; GlobalImageList[SPECTRUM_2_TEXTURE_ID] = &Spectrum2TextureInfo; NumberGlobalImages++; GlobalImageList[SPECTRUM_3_TEXTURE_ID] = &Spectrum3TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_1_TEXTURE_ID] = &Number1TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_2_TEXTURE_ID] = &Number2TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_3_TEXTURE_ID] = &Number3TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_4_TEXTURE_ID] = &Number4TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_5_TEXTURE_ID] = &Number5TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_6_TEXTURE_ID] = &Number6TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_7_TEXTURE_ID] = &Number7TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_8_TEXTURE_ID] = &Number8TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_9_TEXTURE_ID] = &Number9TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_10_TEXTURE_ID] = &Number10TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_11_TEXTURE_ID] = &Number11TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_12_TEXTURE_ID] = &Number12TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_13_TEXTURE_ID] = &Number13TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_14_TEXTURE_ID] = &Number14TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_15_TEXTURE_ID] = &Number15TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_16_TEXTURE_ID] = &Number16TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_17_TEXTURE_ID] = &Number17TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_18_TEXTURE_ID] = &Number18TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_19_TEXTURE_ID] = &Number19TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_20_TEXTURE_ID] = &Number20TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_21_TEXTURE_ID] = &Number21TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_22_TEXTURE_ID] = &Number22TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_23_TEXTURE_ID] = &Number23TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_24_TEXTURE_ID] = &Number24TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_25_TEXTURE_ID] = &Number25TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_26_TEXTURE_ID] = &Number26TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_27_TEXTURE_ID] = &Number27TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_28_TEXTURE_ID] = &Number28TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_29_TEXTURE_ID] = &Number29TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_30_TEXTURE_ID] = &Number30TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_31_TEXTURE_ID] = &Number31TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_32_TEXTURE_ID] = &Number32TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_33_TEXTURE_ID] = &Number33TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_34_TEXTURE_ID] = &Number34TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_35_TEXTURE_ID] = &Number35TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_36_TEXTURE_ID] = &Number36TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_37_TEXTURE_ID] = &Number37TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_38_TEXTURE_ID] = &Number38TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_39_TEXTURE_ID] = &Number39TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_40_TEXTURE_ID] = &Number40TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_41_TEXTURE_ID] = &Number41TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_42_TEXTURE_ID] = &Number42TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_43_TEXTURE_ID] = &Number43TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_44_TEXTURE_ID] = &Number44TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_45_TEXTURE_ID] = &Number45TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_46_TEXTURE_ID] = &Number46TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_47_TEXTURE_ID] = &Number47TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_48_TEXTURE_ID] = &Number48TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_49_TEXTURE_ID] = &Number49TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_50_TEXTURE_ID] = &Number50TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_51_TEXTURE_ID] = &Number51TextureInfo; NumberGlobalImages++; GlobalImageList[NUMBER_52_TEXTURE_ID] = &Number52TextureInfo; NumberGlobalImages++; GlobalImageList[SPIRAL_1_TEXTURE_ID] = &Spiral1TextureInfo; NumberGlobalImages++; GlobalImageList[SPIRAL_2_TEXTURE_ID] = &Spiral2TextureInfo; NumberGlobalImages++; GlobalImageList[SPIRAL_3_TEXTURE_ID] = &Spiral3TextureInfo; NumberGlobalImages++; GlobalImageList[SPIRAL_4_TEXTURE_ID] = &Spiral4TextureInfo; NumberGlobalImages++; assert(NumberGlobalImages-1 <= MAX_GLOBAL_IMAGES); } GsIMAGE *GetImageGivenID (int id) { GsIMAGE *image; //assert(id >= 0); if (id < 0) { printf("\n\n\nGetImageGivenID: bad argument id %d\n", id); printf("TRACK NUMBER %d\n\n\n\n", ChosenSetTrack); return &SimpleBlueTextureInfo; //exit(1); } assert(id < NumberGlobalImages); image = GlobalImageList[id]; return image; } int GetImageIdGivenPointer (GsIMAGE *imagePointer) { int id; int i; assert(imagePointer != NULL); id = -1; for (i = 0; i < NumberGlobalImages; i++) { if (GlobalImageList[i] == imagePointer) { id = i; break; } } assert(id >= 0); assert(id < NumberGlobalImages); return id; } void InitFntPrints (void) { // load font pattern to VRAM FntLoad(960, 256); // open streams fontStream1ID = FntOpen(-40, -40, 256, 200, 0, 512); fontStream2ID = FntOpen(120, 20, 512, 400, 0, 512); } void SortFntPrint (void) { // ensure we're using the right one for screen resolution switch(ScreenResolution) { case LOW_RES: currentFontStream = fontStream1ID; break; case HI_RES: currentFontStream = fontStream2ID; break; default: assert(FALSE); } } void InitialiseModels (void) { InitModel(CUBE_MODEL_ADDRESS); InitModel(SHIP_2_MODEL_ADDRESS); InitModel(SHIP_3_MODEL_ADDRESS); InitModel(SHIP_4_MODEL_ADDRESS); InitModel(SHIP_5_MODEL_ADDRESS); InitModel(SHIP_6_MODEL_ADDRESS); InitModel(SHIP_7_MODEL_ADDRESS); InitModel(SHIP_8_MODEL_ADDRESS); ShipModelAddresses[0] = SHIP_2_MODEL_ADDRESS; ShipModelAddresses[1] = SHIP_3_MODEL_ADDRESS; ShipModelAddresses[2] = SHIP_4_MODEL_ADDRESS; ShipModelAddresses[3] = SHIP_5_MODEL_ADDRESS; ShipModelAddresses[4] = SHIP_6_MODEL_ADDRESS; ShipModelAddresses[5] = SHIP_7_MODEL_ADDRESS; ShipModelAddresses[6] = SHIP_8_MODEL_ADDRESS; } void SetModelTypeForAllShips (int whichModel) { int i; assert(whichModel >= 0); assert(whichModel < NUMBER_SHIP_MODELS); SetModelForShip(whichModel, &PlayerOnesShip); SetModelForShip(whichModel, &PlayerTwosShip); for (i = 0; i < MAX_OTHER_SHIPS; i++) { SetModelForShip(whichModel, &OtherShips[i]); } } void SetModelForShip (int whichModel, ObjectHandler *object) { u_long modelAddress; assert(whichModel >= 0); assert(whichModel < NUMBER_SHIP_MODELS); assert(object != NULL); modelAddress = ShipModelAddresses[whichModel]; LinkObjectHandlerToSingleTMD ( &object->handler, modelAddress); } void SetRandomModelForShip (ObjectHandler *object) { u_long modelAddress; int whichModel; whichModel = rand() % NUMBER_SHIP_MODELS; assert(object != NULL); modelAddress = ShipModelAddresses[whichModel]; LinkObjectHandlerToSingleTMD ( &object->handler, modelAddress); } void SetPlayerOnesShipModel (int whichModel) { u_long modelAddress; assert(whichModel >= 0); assert(whichModel < NUMBER_SHIP_MODELS); modelAddress = ShipModelAddresses[whichModel]; LinkObjectHandlerToSingleTMD ( &PlayerOnesShip.handler, modelAddress); } void SetPlayerTwosShipModel (int whichModel) { u_long modelAddress; assert(whichModel >= 0); assert(whichModel < NUMBER_SHIP_MODELS); modelAddress = ShipModelAddresses[whichModel]; LinkObjectHandlerToSingleTMD ( &PlayerTwosShip.handler, modelAddress); } void SetFirstOtherShipModel (int whichModel) { u_long modelAddress; assert(whichModel >= 0); assert(whichModel < NUMBER_SHIP_MODELS); modelAddress = ShipModelAddresses[whichModel]; LinkObjectHandlerToSingleTMD ( &OtherShips[0].handler, modelAddress); } void SetBothPlayersShipModel (int whichModel) { assert(whichModel >= 0); assert(whichModel < NUMBER_SHIP_MODELS); SetPlayerOnesShipModel(whichModel); SetPlayerTwosShipModel(whichModel); } void InitialiseObjects (void) { int i; InitialiseObjectClass(); InitSingleObject(&PlayerOnesShip); BringObjectToLife (&PlayerOnesShip, PLAYER_ONES_SHIP, SHIP_3_MODEL_ADDRESS, 0, NONE); PlayerOnesShip.modelFlag = TMD_RIGHT_WAY; PlayerOnesShip.specialMovementFlag = HUMAN_PLAYER; SetObjectScaling( &PlayerOnesShip, ONE+4, ONE+4, ONE+4); SetStandardShipParameters( &PlayerOnesShip); PlayerOnesShip.viewMode = BASE_PLAYER_VIEW_MODE; // moves by physics PlayerOnesShip.properMovementFlag = TRUE; RegisterObjectIntoObjectArray(&PlayerOnesShip); InitSingleObject(&PlayerTwosShip); BringObjectToLife (&PlayerTwosShip, PLAYER_TWOS_SHIP, SHIP_3_MODEL_ADDRESS, 0, NONE); PlayerTwosShip.modelFlag = TMD_RIGHT_WAY; PlayerTwosShip.specialMovementFlag = HUMAN_PLAYER; SetObjectScaling( &PlayerTwosShip, ONE+4, ONE+4, ONE+4); SetStandardShipParameters( &PlayerTwosShip); PlayerTwosShip.viewMode = BASE_PLAYER_VIEW_MODE; // moves by physics PlayerTwosShip.properMovementFlag = TRUE; RegisterObjectIntoObjectArray(&PlayerTwosShip); for (i = 0; i < MAX_OTHER_SHIPS; i++) { InitSingleObject(&OtherShips[i]); BringObjectToLife(&OtherShips[i], OTHER_SHIP, SHIP_2_MODEL_ADDRESS, 0, NONE); OtherShips[i].modelFlag = TMD_RIGHT_WAY; // strategy might depend on difficulty level OtherShips[i].specialMovementFlag = AI_FLIER_1; SetObjectScaling( &OtherShips[i], ONE+4, ONE+4, ONE+4); SetStandardShipParameters( &OtherShips[i]); OtherShips[i].viewMode = BASE_PLAYER_VIEW_MODE; OtherShips[i].speedFactor = 64; OtherShips[i].discreteSpeed = 8; // moves by blaggery // CHANGE for good dynamic fliers OtherShips[i].properMovementFlag = FALSE; RegisterObjectIntoObjectArray(&OtherShips[i]); } LinkAllObjectsToModelsOrSprites(); LinkAllObjectsToTheirCoordinateSystems(); PlayerOnesShip.alive = FALSE; // dormant until awakened PlayerTwosShip.alive = FALSE; // dormant until awakened for (i = 0; i < MAX_OTHER_SHIPS; i++) { OtherShips[i].alive = FALSE; // dormant until awakened } // ship dynamic texturing ShipDrawProcessLabel = FORTY_SIXTH; SetDrawProcess2( &ShipDrawProcess, &Wave15ImageInfo, ShipDrawProcessLabel, FIFTH, FIFTH); } void ResetShipModelsToDefault (void) { int i; RollingDemoAiFlierModelNumber = 0; PlayerOneModelNumber = 1; PlayerTwoModelNumber = 1; SetModelForShip( PlayerOneModelNumber, &PlayerOnesShip); SetModelForShip( PlayerTwoModelNumber, &PlayerTwosShip); for (i = 0; i < MAX_OTHER_SHIPS; i++) { SetModelForShip( RollingDemoAiFlierModelNumber, &OtherShips[i]); } } void SetBasicParametersForAllShips (void) { BaseAccelerationPower = 2; // 5 BaseBrakePower = 3; // 10 BaseAngularTwist = ONE/1024; // 4 BaseMovementFrictionCoefficient = 36; // 56 BaseAngularFrictionCoefficient = 512; BaseDiscreteSpeed = 8; } void SetStandardShipParameters (ObjectHandler *ship) { assert(ship->type == PLAYER_ONES_SHIP || ship->type == PLAYER_TWOS_SHIP || ship->type == OTHER_SHIP); ship->accelerationSpeed = BaseAccelerationPower; ship->brakingSpeed = BaseBrakePower; setVECTOR( &ship->rotationPower, BaseAngularTwist, BaseAngularTwist, BaseAngularTwist); ship->movementMomentumFlag = TRUE; ship->movementFrictionCoefficient = BaseMovementFrictionCoefficient; ship->rotationMomentumFlag = TRUE; ship->rotationFrictionCoefficient = BaseAngularFrictionCoefficient; // infer maximum ship->maximumSpeed = (ship->accelerationSpeed * (ONE - ship->movementFrictionCoefficient)) / ship->movementFrictionCoefficient; ship->collisionRadius = 50; // 60 ship->tunnelCollisionTreatmentFlag = DETECT_AND_HANDLE_COLLISIONS; ship->shipCollisionTreatmentFlag = DETECT_AND_HANDLE_COLLISIONS; } void SortAllShipsParametersByFrameRate (void) { int i; assert(FrameRateDivider >= 1); AdjustShipParameters( &PlayerOnesShip, FrameRateDivider); AdjustShipParameters( &PlayerTwosShip, FrameRateDivider); for (i = 0; i < MAX_OTHER_SHIPS; i++) { AdjustShipParameters( &OtherShips[i], FrameRateDivider); } } void AdjustShipParameters (ObjectHandler *ship, int factor) { ship->accelerationSpeed = BaseAccelerationPower * factor; ship->brakingSpeed = BaseBrakePower * factor; setVECTOR( &ship->rotationPower, BaseAngularTwist * factor, BaseAngularTwist * factor, BaseAngularTwist * factor); assert(ship->movementFrictionCoefficient != 0); // infer maximum speed ship->maximumSpeed = (ship->accelerationSpeed * (ONE - ship->movementFrictionCoefficient)) / ship->movementFrictionCoefficient; #if 0 ship->discreteSpeed = BaseDiscreteSpeed * factor; #endif switch(ship->speedControlFlag) { case -1: // do nowt break; case SLOW_FLIER: ship->discreteSpeed = 8 * factor; break; case SLOWISH_FLIER: ship->discreteSpeed = 12 * factor; break; case FASTISH_FLIER: ship->discreteSpeed = 16 * factor; break; #if 0 case FAST_FLIER: ship->discreteSpeed = 64 * factor; break; #endif #if 0 // not yet, needs fixing case VARIABLE_SPEED_FLIER: OtherShips[0].discreteSpeed = 8; OtherShips[0].speedControlPeriod = MaximumGameFramesPerSecond * 10; break; #endif default: assert(FALSE); } } #define NUMBER_VEILS 24 int ListOfNiceDrawProcessesForShips[NUMBER_VEILS] = { FIRST, SECOND, THIRD, FOURTH, FIFTH, SIXTH, SEVENTH, EIGHTH, NINTH, FIFTEENTH, TWENTY_FIRST, TWENTY_SECOND, TWENTY_FOURTH, TWENTY_FIFTH, TWENTY_SIXTH, THIRTY_FIRST, THIRTY_SECOND, THIRTY_FOURTH, THIRTY_FIFTH, THIRTY_SIXTH, THIRTY_SEVENTH, THIRTY_EIGHTH, FORTY_SIXTH, FORTY_SEVENTH }; void PickNewAppearanceForShips (void) { int choice; #if 0 // pick randomly from list choice = rand() % NUMBER_VEILS; ShipDrawProcessLabel = ListOfNiceDrawProcessesForShips[choice]; #endif #if 1 // pick sequentially from list for (choice = 0; choice < NUMBER_VEILS; choice++) { if (ShipDrawProcessLabel == ListOfNiceDrawProcessesForShips[choice]) break; } if (choice == NUMBER_VEILS-1) choice = 0; else choice++; ShipDrawProcessLabel = ListOfNiceDrawProcessesForShips[choice]; #endif #if 0 // go through all of them in order if (ShipDrawProcessLabel == ListOfNiceDrawProcesses[NUMBER_VEILS-1]) ShipDrawProcessLabel = 0; else ShipDrawProcessLabel++; #endif SetDrawProcess2( &ShipDrawProcess, &Wave15ImageInfo, ShipDrawProcessLabel, FIFTH, FIFTH); printf("New ship draw proc: %d\n", ShipDrawProcessLabel); } void CleanUpProgram (void) { //StoreScreen(); // overwrites lots of memory // invoke by controller 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 ClosingSequenceLoop(); #if (DEVELOPMENT_ENVIRONMENT==DEV_KIT) { #if 0 ResetGraph(0); ResetCallback(); PadStop(); StopCallback(); #endif StopCallback(); PadStop(); ResetGraph(3); } #endif } #define PAUSE_DELAY 30 void DealWithControllerPad (void) { long pad; pad = PadRead(0); SystemInUse = HandleSystemControls(pad); if (SystemInUse == 1) return; if (RollingDemoActiveFlag == TRUE) { if (RollingDemoDeliberateFlag == FALSE) { if (pad != 0) { RollingDemoActiveFlag = FALSE; SetANewGameState(MAIN_MENU); return; } } } } // system controls (disable for final) // return value: are they being used? SVECTOR ScreenScaler = {ONE, ONE, ONE}; #define SYSTEM_CONTROLS_ENABLED_FLAG 0 int HandleSystemControls (long pad) { #if (SYSTEM_CONTROLS_ENABLED_FLAG != 1) return FALSE; #else SortFntPrint(); // L2 alone: hold-down pause if (pad & PADL2 && ((pad & PADL1)==0) && ((pad & PADR1)==0) && ((pad & PADR2)==0)) { while (pad & PADL2 && ((pad & PADL1)==0) && ((pad & PADR1)==0) && ((pad & PADR2)==0)) { pad = PadRead(0); } return TRUE; } // L1 and L2 - projection distance, scale ship if (pad & PADL1 && pad & PADL2 && ((pad & PADR1)==0)) { #if 0 FntPrint(currentFontStream, "Proj %d\n", ProjectionDistance); if (pad & PADRup) { ProjectionDistance += 5; GsSetProjection(ProjectionDistance); } if (pad & PADRdown) { ProjectionDistance -= 5; GsSetProjection(ProjectionDistance); } #endif #if 0 if (pad & PADRup && ((frameNumber % 20) == 0)) { MakeClunk(); } #endif #if 0 if (pad & PADLup) { PlayJasonsTune(); } if (pad & PADLdown) { TurnOffJasonsTune(); } #endif #if 0 FntPrint(currentFontStream, "ship scale\n%d %d %d\n", PlayerOnesShip.scalingVector.vx, PlayerOnesShip.scalingVector.vy, PlayerOnesShip.scalingVector.vz); if (pad & PADRleft) // this distorts the view, a cheap screen-scaler { PlayerOnesShip.scalingVector.vx -= 32; PlayerOnesShip.scalingVector.vy -= 32; PlayerOnesShip.scalingVector.vz -= 32; } if (pad & PADRright) { PlayerOnesShip.scalingVector.vx += 32; PlayerOnesShip.scalingVector.vy += 32; PlayerOnesShip.scalingVector.vz += 32; } #endif #if 0 if (pad & PADRleft) // this distorts the view, a cheap screen-scaler { PlayerOnesShip.scalingVector.vx -= 32; } if (pad & PADRright) { PlayerOnesShip.scalingVector.vx += 32; } if (pad & PADLleft) { PlayerOnesShip.scalingVector.vy -= 32; } if (pad & PADLright) { PlayerOnesShip.scalingVector.vy += 32; } if (pad & PADLup) { PlayerOnesShip.scalingVector.vz -= 32; } if (pad & PADLdown) { PlayerOnesShip.scalingVector.vz += 32; } #endif #if 0 // ScreenScaling FntPrint(currentFontStream, "scr scale\n%d %d %d\n", ScreenScaler.vx, ScreenScaler.vy, ScreenScaler.vz); if (pad & PADRleft) { ScreenScaler.vx -= 32; GsScaleScreen( &ScreenScaler); } if (pad & PADRright) { ScreenScaler.vx += 32; GsScaleScreen( &ScreenScaler); } if (pad & PADLleft) { ScreenScaler.vy -= 32; GsScaleScreen( &ScreenScaler); } if (pad & PADLright) { ScreenScaler.vy += 32; GsScaleScreen( &ScreenScaler); } if (pad & PADLup) { ScreenScaler.vz += 32; GsScaleScreen( &ScreenScaler); } if (pad & PADLdown) { ScreenScaler.vz -= 32; GsScaleScreen( &ScreenScaler); } #endif return TRUE; } // L1 and R1: vp - viewing controls if (pad & PADL1 && pad & PADR1 && ((pad & PADL2)==0)) { #if 0 FntPrint(currentFontStream, "ship light %d\n", GlobalShipLightingEffectFlag); if (pad & PADLup && ((frameNumber % 10) == 0)) { GlobalShipLightingEffectFlag--; if (GlobalShipLightingEffectFlag < BASE_SHIP_LIGHT_EFFECT) { GlobalShipLightingEffectFlag = BASE_SHIP_LIGHT_EFFECT; } if (GlobalShipLightingEffectFlag > (BASE_SHIP_LIGHT_EFFECT + NUMBER_SHIP_LIGHT_EFFECTS - 1)) { GlobalShipLightingEffectFlag = (BASE_SHIP_LIGHT_EFFECT + NUMBER_SHIP_LIGHT_EFFECTS - 1); } } if (pad & PADLdown && ((frameNumber % 10) == 0)) { GlobalShipLightingEffectFlag++; if (GlobalShipLightingEffectFlag < BASE_SHIP_LIGHT_EFFECT) { GlobalShipLightingEffectFlag = BASE_SHIP_LIGHT_EFFECT; } if (GlobalShipLightingEffectFlag > (BASE_SHIP_LIGHT_EFFECT + NUMBER_SHIP_LIGHT_EFFECTS - 1)) { GlobalShipLightingEffectFlag = (BASE_SHIP_LIGHT_EFFECT + NUMBER_SHIP_LIGHT_EFFECTS - 1); } } if (pad & PADLleft && ((frameNumber % 10) == 0)) { GlobalShipLightingEffectFlag = NONE; } if (pad & PADLright && ((frameNumber % 10) == 0)) { GlobalShipLightingEffectFlag = FIRST; } #endif #if 0 FntPrint(currentFontStream, "backR %d\n", BackgroundColourRed); FntPrint(currentFontStream, "backG %d\n", BackgroundColourGreen); FntPrint(currentFontStream, "backB %d\n", BackgroundColourBlue); if (pad & PADRup) BackgroundColourRed--; if (pad & PADRdown) BackgroundColourRed++; if (pad & PADRright) BackgroundColourGreen--; if (pad & PADRleft) BackgroundColourGreen++; if (pad & PADLup) BackgroundColourBlue--; if (pad & PADLdown) BackgroundColourBlue++; #endif #if 0 FntPrint(currentFontStream, "bit 30 %d\n", (FadeBox.attribute & (1<<30))); FntPrint(currentFontStream, "bit 29 %d\n", (FadeBox.attribute & (1<<29))); FntPrint(currentFontStream, "bit 28 %d\n", (FadeBox.attribute & (1<<28))); FntPrint(currentFontStream, "fadeR %d\n", FadeBox.r); FntPrint(currentFontStream, "fadeG %d\n", FadeBox.g); FntPrint(currentFontStream, "fadeB %d\n", FadeBox.b); if (pad & PADselect) { if (pad & PADRup) FadeBox.attribute |= GsALON; if (pad & PADRdown) { TURN_NTH_BIT_OFF( FadeBox.attribute, 32, 30); } if (pad & PADRright) FadeBox.attribute |= (1<<29); if (pad & PADRleft) { TURN_NTH_BIT_OFF( FadeBox.attribute, 32, 29); } if (pad & PADLup) FadeBox.attribute |= (1<<28); if (pad & PADLdown) { TURN_NTH_BIT_OFF( FadeBox.attribute, 32, 28); } } else // colours { if (pad & PADRup) FadeBox.r--; if (pad & PADRdown) FadeBox.r++; if (pad & PADRright) FadeBox.g--; if (pad & PADRleft) FadeBox.g++; if (pad & PADLup) FadeBox.b--; if (pad & PADLdown) FadeBox.b++; } #endif #if 0 FntPrint(currentFontStream, "accel %d\n", BaseAccelerationPower); //FntPrint("brake %d\n", BaseBrakePower); FntPrint(currentFontStream, "rotate %d\n", BaseAngularTwist); FntPrint(currentFontStream, "move fric %d\n", BaseMovementFrictionCoefficient); FntPrint(currentFontStream, "turn fric %d\n", BaseAngularFrictionCoefficient); if (pad & PADLup && ((frameNumber % 10) == 0)) { BaseAccelerationPower++; } if (pad & PADLdown && ((frameNumber % 10) == 0)) { BaseAccelerationPower--; if (BaseAccelerationPower < 1) BaseAccelerationPower = 1; } if (pad & PADLleft && ((frameNumber % 10) == 0)) { BaseAngularTwist++; } if (pad & PADLright && ((frameNumber % 10) == 0)) { BaseAngularTwist--; if (BaseAngularTwist < 1) BaseAngularTwist = 1; } if (pad & PADRup) { BaseMovementFrictionCoefficient--; if (BaseMovementFrictionCoefficient < 1) BaseMovementFrictionCoefficient = 1; } if (pad & PADRdown) BaseMovementFrictionCoefficient++; if (pad & PADRleft) { BaseAngularFrictionCoefficient--; if (BaseAngularFrictionCoefficient < 1) BaseAngularFrictionCoefficient = 1; } if (pad & PADRright) BaseAngularFrictionCoefficient++; #endif #if 0 FntPrint(currentFontStream, "dist %d\nangle %d\n", FixedBehindDistance, FixedBehindAboveAngle); if (pad & PADRup) { FixedBehindDistance += 2; } if (pad & PADRdown) { FixedBehindDistance -= 2; } if (pad & PADRleft) { FixedBehindAboveAngle -= 2; } if (pad & PADRright) { FixedBehindAboveAngle += 2; } #endif #if 0 FntPrint(currentFontStream, "dist %d\noffset %d\n", LocalDistance, LocalOffset); if (pad & PADRup) { LocalDistance += 2; } if (pad & PADRdown) { LocalDistance -= 2; } if (pad & PADRleft) { LocalOffset -= 2; } if (pad & PADRright) { LocalOffset += 2; } #endif #if 0 FntPrint(currentFontStream, "vp %d %d %d\n", TheView.vpx, TheView.vpy, TheView.vpz); if (pad & PADRup) { TheView.vpy += 10; } if (pad & PADRdown) { TheView.vpy -= 10; } if (pad & PADLdown) { TheView.vpz -= 10; } if (pad & PADLup) { TheView.vpz += 10; } if (pad & PADRleft) { TheView.vpx -= 10; } if (pad & PADRright) { TheView.vpx += 10; } #endif #if 1 FntPrint(currentFontStream, "v t %d %d %d\n", TheMatrixView.view.t[0], TheMatrixView.view.t[1], TheMatrixView.view.t[2]); if (pad & PADRup) { TheMatrixView.view.t[1] += 10; } if (pad & PADRdown) { TheMatrixView.view.t[1] -= 10; } if (pad & PADLdown) { TheMatrixView.view.t[2] -= 10; } if (pad & PADLup) { TheMatrixView.view.t[2] += 10; } if (pad & PADRleft) { TheMatrixView.view.t[0] -= 10; } if (pad & PADRright) { TheMatrixView.view.t[0] += 10; } #endif return TRUE; } // L1 and L2 and R1 if (pad & PADL1 && pad & PADR1 && pad & PADL2) { #if 0 FntPrint(currentFontStream, "accel %d\n", BaseAccelerationPower); //FntPrint("brake %d\n", BaseBrakePower); FntPrint(currentFontStream, "rotate %d\n", BaseAngularTwist); FntPrint(currentFontStream, "move fric %d\n", BaseMovementFrictionCoefficient); FntPrint(currentFontStream, "turn fric %d\n", BaseAngularFrictionCoefficient); if (pad & PADLup && ((frameNumber % 10) == 0)) { BaseAccelerationPower++; } if (pad & PADLdown && ((frameNumber % 10) == 0)) { BaseAccelerationPower--; if (BaseAccelerationPower < 1) BaseAccelerationPower = 1; } if (pad & PADLleft && ((frameNumber % 10) == 0)) { BaseAngularTwist++; } if (pad & PADLright && ((frameNumber % 10) == 0)) { BaseAngularTwist--; if (BaseAngularTwist < 1) BaseAngularTwist = 1; } if (pad & PADRup) { BaseMovementFrictionCoefficient--; if (BaseMovementFrictionCoefficient < 1) BaseMovementFrictionCoefficient = 1; } if (pad & PADRdown) BaseMovementFrictionCoefficient++; if (pad & PADRleft) { BaseAngularFrictionCoefficient--; if (BaseAngularFrictionCoefficient < 1) BaseAngularFrictionCoefficient = 1; } if (pad & PADRright) BaseAngularFrictionCoefficient++; #endif #if 0 FntPrint(currentFontStream, "view D %d\n", FixedBehindDistance); if (pad & PADRup) FixedBehindDistance++; if (pad & PADRdown) FixedBehindDistance--; #endif #if 1 FntPrint(currentFontStream, "number subdiv %d\n", TheTunnelDescription.numberSectionsSubdivided); FntPrint(currentFontStream, "subd EXT %d\n", TheTunnelDescription.subdivisionExtent); FntPrint(currentFontStream, "subd back off %d\n", TheTunnelDescription.subdivisionBackOffset); FntPrint(currentFontStream, "draw back off %d\n", TheTunnelDescription.drawBackOffset); if (pad & PADRup) { if ((frameNumber % 30) == 0) { TheTunnelDescription.subdivisionExtent++; if (TheTunnelDescription.subdivisionExtent > 2) TheTunnelDescription.subdivisionExtent = 2; } } if (pad & PADRdown) { if ((frameNumber % 30) == 0) { TheTunnelDescription.subdivisionExtent--; if (TheTunnelDescription.subdivisionExtent < 0) TheTunnelDescription.subdivisionExtent = 0; } } if (pad & PADRleft) { if ((frameNumber % 10) == 0) TheTunnelDescription.subdivisionBackOffset++; } if (pad & PADRright) { if ((frameNumber % 10) == 0) TheTunnelDescription.subdivisionBackOffset--; } if (pad & PADLup) { if ((frameNumber % 10) == 0) { TheTunnelDescription.drawBackOffset++; //if (TheTunnelDescription.drawBackOffset >= 4) // TheTunnelDescription.drawBackOffset = 4; } } if (pad & PADLdown) { if ((frameNumber % 10) == 0) { TheTunnelDescription.drawBackOffset--; //if (TheTunnelDescription.drawBackOffset < 0) // TheTunnelDescription.drawBackOffset = 0; } } if (pad & PADLleft) { if ((frameNumber % 10) == 0) { TheTunnelDescription.numberSectionsSubdivided++; if (TheTunnelDescription.numberSectionsSubdivided >= 4) TheTunnelDescription.numberSectionsSubdivided = 4; } } if (pad & PADLright) { if ((frameNumber % 10) == 0) { TheTunnelDescription.numberSectionsSubdivided--; if (TheTunnelDescription.numberSectionsSubdivided < 0) TheTunnelDescription.numberSectionsSubdivided = 0; } } #endif #if 0 // old: move both vp and vr if (pad & PADRup) { TheView.vpy += 10; TheView.vry += 10; } if (pad & PADRdown) { TheView.vpy -= 10; TheView.vry -= 10; } if (pad & PADLdown) { TheView.vpz -= 10 TheView.vrz -= 10; } if (pad & PADLup) { TheView.vpz += 10; TheView.vrz += 10; } if (pad & PADRleft) { TheView.vpx -= 10; TheView.vrx -= 10; } if (pad & PADRright) { TheView.vpx += 10; TheView.vrx += 10; } #endif return TRUE; } // L1 and R2: fogging / ship flying parameters if (pad & PADL1 && pad & PADR2) { #if 0 FntPrint(currentFontStream, "accel %d\n", BaseAccelerationPower); //FntPrint("brake %d\n", BaseBrakePower); FntPrint(currentFontStream, "rotate %d\n", BaseAngularTwist); FntPrint(currentFontStream, "move fric %d\n", BaseMovementFrictionCoefficient); FntPrint(currentFontStream, "turn fric %d\n", BaseAngularFrictionCoefficient); if (pad & PADLup && ((frameNumber % 10) == 0)) { BaseAccelerationPower++; } if (pad & PADLdown && ((frameNumber % 10) == 0)) { BaseAccelerationPower--; if (BaseAccelerationPower < 1) BaseAccelerationPower = 1; } if (pad & PADLleft && ((frameNumber % 10) == 0)) { BaseAngularTwist++; } if (pad & PADLright && ((frameNumber % 10) == 0)) { BaseAngularTwist--; if (BaseAngularTwist < 1) BaseAngularTwist = 1; } if (pad & PADRup) { BaseMovementFrictionCoefficient--; if (BaseMovementFrictionCoefficient < 1) BaseMovementFrictionCoefficient = 1; } if (pad & PADRdown) BaseMovementFrictionCoefficient++; if (pad & PADRleft) { BaseAngularFrictionCoefficient--; if (BaseAngularFrictionCoefficient < 1) BaseAngularFrictionCoefficient = 1; } if (pad & PADRright) BaseAngularFrictionCoefficient++; #endif #if 1 FntPrint(currentFontStream, "dqa %d\ndqb %d\n", TheFogging.dqa, TheFogging.dqb); FntPrint(currentFontStream, "fr %d fg %d fb %d\n", TheFogging.rfc, TheFogging.gfc, TheFogging.bfc); FntPrint(currentFontStream, "mode %d\n", OverallLightMode); if (pad & PADselect) // colours { if (pad & PADLup) TheFogging.rfc -= 5; if (pad & PADLdown) TheFogging.rfc += 5; if (pad & PADLleft) TheFogging.gfc -= 5; if (pad & PADLright) TheFogging.gfc += 5; if (pad & PADRup) TheFogging.bfc -= 5; if (pad & PADRdown) TheFogging.bfc += 5; } else // without select: alter fog distance { if (pad & PADLup) TheFogging.dqa -= 500; if (pad & PADLdown) TheFogging.dqa += 500; if (pad & PADLleft) TheFogging.dqb -= 500000; if (pad & PADLright) TheFogging.dqb += 500000; if (pad & PADRright) TheFogging.dqa -= 50; if (pad & PADRleft) TheFogging.dqa += 50; } #endif #if 0 // just alters fog colour brightness if (pad & PADRleft) { TheFogging.rfc -= 5; TheFogging.gfc -= 5; TheFogging.bfc -= 5; } if (pad & PADRright) { TheFogging.rfc += 5; TheFogging.gfc += 5; TheFogging.bfc += 5; } #endif GsSetFogParam( &TheFogging); //if (framesSinceLongPauseToggle > PAUSE_DELAY) { if (pad & PADRup) // fog off { OverallLightMode = 0; GsSetLightMode(OverallLightMode); framesSinceLongPauseToggle = 0; } else if (pad & PADRdown) { OverallLightMode = 1; GsSetLightMode(OverallLightMode); framesSinceLongPauseToggle = 0; } } return TRUE; } // L2 and R1: sort global sprites if (pad & PADL2 && pad & PADR1 && ((pad & PADL1)==0)) { assert(SelectedGlobalSprite >= 0); assert(SelectedGlobalSprite <= NumberGlobalSprites-1); #if 1 if (frameNumber % 20 == 0) { printf("global sprite %d, x %d y %d\n", SelectedGlobalSprite, GlobalSpriteList[SelectedGlobalSprite]->x, GlobalSpriteList[SelectedGlobalSprite]->y); } #endif if (pad & PADRup && ((frameNumber % 5) == 0)) { SelectedGlobalSprite++; if (SelectedGlobalSprite > NumberGlobalSprites-1) SelectedGlobalSprite = 0; } if (pad & PADRdown && ((frameNumber % 5) == 0)) { SelectedGlobalSprite--; if (SelectedGlobalSprite < 0) SelectedGlobalSprite = NumberGlobalSprites-1; } if (pad & PADLleft) GlobalSpriteList[SelectedGlobalSprite]->x--; if (pad & PADLright) GlobalSpriteList[SelectedGlobalSprite]->x++; if (pad & PADLup) GlobalSpriteList[SelectedGlobalSprite]->y--; if (pad & PADLdown) GlobalSpriteList[SelectedGlobalSprite]->y++; ShowGlobalSpriteFlag = TRUE; FntPrint(currentFontStream, "sprite %d\n", SelectedGlobalSprite); FntPrint(currentFontStream, "x %d y %d %d\n", GlobalSpriteList[SelectedGlobalSprite]->x, GlobalSpriteList[SelectedGlobalSprite]->y); #if 0 // flipping screen-res at runtime if (pad & PADLup && frameNumber % 12 == 0) { switch(ScreenResolution) { case LOW_RES: ResetGraphicResolution (640, 480); break; case HI_RES: ResetGraphicResolution (320, 240); break; default: assert(FALSE); } } #endif return TRUE; } else ShowGlobalSpriteFlag = FALSE; // L2 and R2: dynamic texture sorting if (pad & PADL2 && pad & PADR2) { DebugDynTexMarker = TRUE; } else { DebugDynTexMarker = FALSE; } if (DebugDynTexMarker == TRUE && TheTunnelDescription.numberDrawProcesses > 0) { if (DebugSelectedDrawProcess > TheTunnelDescription.numberDrawProcesses-1) DebugSelectedDrawProcess = 0; } if (framesSinceLongPauseToggle > 12 && TheTunnelDescription.numberDrawProcesses > 0 && DebugDynTexMarker == TRUE) { if (pad & PADLup) { //printf("TheTunnelDescription.numberDrawProcesses: %d\n", // TheTunnelDescription.numberDrawProcesses); //printf("DebugSelectedDrawProcess: %d\n", DebugSelectedDrawProcess); TheTunnelDescription.drawingProcesses[DebugSelectedDrawProcess].screenShowFlag = FALSE; DebugSelectedDrawProcess--; if (DebugSelectedDrawProcess < 0) DebugSelectedDrawProcess = TheTunnelDescription.numberDrawProcesses-1; TheTunnelDescription.drawingProcesses[DebugSelectedDrawProcess].screenShowFlag = TRUE; //printf("DebugSelectedDrawProcess: %d\n", DebugSelectedDrawProcess); framesSinceLongPauseToggle = 0; return TRUE; } if (pad & PADLdown) { //printf("TheTunnelDescription.numberDrawProcesses: %d\n", // TheTunnelDescription.numberDrawProcesses); //printf("DebugSelectedDrawProcess: %d\n", DebugSelectedDrawProcess); TheTunnelDescription.drawingProcesses[DebugSelectedDrawProcess].screenShowFlag = FALSE; DebugSelectedDrawProcess++; if (DebugSelectedDrawProcess > TheTunnelDescription.numberDrawProcesses-1) DebugSelectedDrawProcess = 0; TheTunnelDescription.drawingProcesses[DebugSelectedDrawProcess].screenShowFlag = TRUE; //printf("DebugSelectedDrawProcess: %d\n", DebugSelectedDrawProcess); framesSinceLongPauseToggle = 0; return TRUE; } if (pad & PADLleft) { int i; for (i = 0; i < TheTunnelDescription.numberDrawProcesses; i++) { TheTunnelDescription.drawingProcesses[i].screenShowFlag = FALSE; } ShipDrawProcess.screenShowFlag = TRUE; DebugSelectedDrawProcess = 0; framesSinceLongPauseToggle = 0; printf("displaying ship draw proc\n"); return TRUE; } } if (DebugDynTexMarker == TRUE) return TRUE; // R1 and R2: pause and screen-shot options if (pad & PADR1 && pad & PADR2) { //if (frameNumber % 5 == 0) // { // PrintViewMode(); // } if (pad & PADLup) // Lup: hold-down pause { for (;;) { pad = PadRead(0); if ( (pad & PADR1 && pad & PADR2 && pad & PADLup) == 0) break; } } // Ldown: step slowly if (pad & PADLdown) { int frameCount; frameCount = VSync(-1); while (frameCount + 25 > VSync(-1)) { ; } } // Rup/Rdown: set frame delay if (pad & PADRup) { frameLimiter++; } if (pad & PADRdown) { frameLimiter--; } // Rright and Rleft together: screen capture if (pad & PADRleft && pad & PADRright) { #if (DEVELOPMENT_ENVIRONMENT==YAROZE) StoreScreenFlag = TRUE; #if 0 StoreScreen(); CleanUpProgram(); exit(1); #endif #endif } if (pad & PADRleft && frameNumber % 10 == 0) { ShowGlobalGridFlag = 1 - ShowGlobalGridFlag; } return TRUE; } return FALSE; #endif } void DealWithPlayersControllerInput (ObjectHandler *player) { long pad; int effectiveControlPadInput; int shipDirectionalMultiplier = 1; pad = PadRead(0); player->framesSinceLastViewFlip++; // player one uses left hand pad, player two uses right hand one if (player == &PlayerOnesShip) { effectiveControlPadInput = pad & 0xffff; } else { assert(player == &PlayerTwosShip); effectiveControlPadInput = pad >> 16; } if (effectiveControlPadInput & PADselect) // quit current race { EndRaceNowFlag = TRUE; //printf("Setting end of race now\n"); return; } framesSinceLongPauseToggle++; if (effectiveControlPadInput & PADstart) { if (framesSinceLongPauseToggle > PAUSE_DELAY) { switch(GlobalPauseFlag) { case TRUE: // end pause GlobalPauseFlag = FALSE; SetObjectsInteractivity(TRUE); break; case FALSE: // begin pause GlobalPauseFlag = TRUE; SetObjectsInteractivity(FALSE); break; default: assert(FALSE); } framesSinceLongPauseToggle = 0; } } // is player allowed pad control? if (player->interactivityFlag == FALSE) return; switch(player->modelFlag) { case TMD_RIGHT_WAY: shipDirectionalMultiplier = 1; break; case TMD_WRONG_WAY: shipDirectionalMultiplier = -1; break; default: shipDirectionalMultiplier = 1; // assert(FALSE); } assert(player->velocity.vx == 0); assert(player->velocity.vy == 0); if (effectiveControlPadInput & PADRdown) // X for accelerate { player->velocity.vz += shipDirectionalMultiplier * player->accelerationSpeed; } else if (effectiveControlPadInput & PADRleft) // square for brake { player->velocity.vz -= shipDirectionalMultiplier * player->brakingSpeed; } #if 0 if (effectiveControlPadInput & PADRright) // circle flips ship mapping { if (player->framesSinceLastViewFlip > MaximumGameFramesPerSecond / 4) { PickNewAppearanceForShips(); player->framesSinceLastViewFlip = 0; } } #endif switch(player->modelFlag) { #if 1 // OLD case TMD_RIGHT_WAY: if (player->velocity.vz > player->maximumSpeed) player->velocity.vz = player->maximumSpeed; else if (player->velocity.vz < 0) player->velocity.vz = 0; break; case TMD_WRONG_WAY: if (player->velocity.vz < -player->maximumSpeed) player->velocity.vz = -player->maximumSpeed; else if (player->velocity.vz > 0) player->velocity.vz = 0; break; default: assert(FALSE); #endif #if 0 // NEW case TMD_WRONG_WAY: if (player->velocity.vz < -player->maximumSpeed) player->velocity.vz = -player->maximumSpeed; else if (player->velocity.vz > 0) player->velocity.vz = 0; break; default: if (player->velocity.vz > player->maximumSpeed) player->velocity.vz = player->maximumSpeed; else if (player->velocity.vz < 0) player->velocity.vz = 0; #endif } // ship's rotations switch(TheTunnelDescription.twoDflag) { case X_Z_PLANE_ONLY: if (effectiveControlPadInput & PADLleft) player->tilt -= player->rotationPower.vy; else if (effectiveControlPadInput & PADLright) player->tilt += player->rotationPower.vy; while(player->angle < 0) // tilt player->tilt += ONE; while (player->angle >= ONE) // tilt player->tilt -= ONE; break; case Y_Z_PLANE_ONLY: if (effectiveControlPadInput & PADLup) player->tilt -= player->rotationPower.vx; else if (effectiveControlPadInput & PADLdown) player->tilt += player->rotationPower.vx; while(player->angle < 0) // tilt player->tilt += ONE; while (player->angle >= ONE) // tilt player->tilt -= ONE; break; default: assert(FALSE); } // triangle flips through view modes if (effectiveControlPadInput & PADRup) { if (player->framesSinceLastViewFlip >= MaximumGameFramesPerSecond/4) { if (player->viewMode == (BASE_PLAYER_VIEW_MODE + NUMBER_OF_PLAYER_VIEW_MODES - 1)) player->viewMode = BASE_PLAYER_VIEW_MODE; else player->viewMode++; player->framesSinceLastViewFlip = 0; SetNewViewShip(TheViewShip); } } else if (effectiveControlPadInput & PADL1) // L1: look behind quickly { if (player->lookBehindFlag == TRUE) player->framesSinceLastLookBehind = 0; else { if (player->framesSinceLastLookBehind > LOOK_BEHIND_DURATION) { //printf("Pressed L1: setting look-behind NOW\n"); player->framesSinceLastLookBehind = 0; player->lookBehindFlag = TRUE; player->storedViewMode = player->viewMode; player->viewMode = VIEW_LOCAL_LOOKING_BACKWARDS; if (player == TheViewShip) SetNewViewShip(player); } } } // restore view to previous view after a brief look behind if ( (player->framesSinceLastLookBehind == (LOOK_BEHIND_DURATION-1)) && (player->lookBehindFlag == TRUE) ) { //printf("END of existing look-behind: restoring view NOW\n"); player->viewMode = player->storedViewMode; player->lookBehindFlag = FALSE; if (player == TheViewShip) SetNewViewShip(player); } player->framesSinceLastLookBehind++; } void HandleAllObjects (void) { ObjectHandler* object; int i; for (i = 0; i < MAX_OBJECTS; i++) { if (ObjectArray[i] != NULL) { if (ObjectArray[i]->alive == TRUE) { object = ObjectArray[i]; //HandleCommonUpdating(object); // NOT NEEDED // only does object->lifeTime++; switch(object->type) { case PLAYER_ONES_SHIP: HandleAPlayersShip(object); break; case PLAYER_TWOS_SHIP: HandleAPlayersShip(object); break; case OTHER_SHIP: HandleOtherShip(object); break; case CUBE: assert(FALSE); //HandleACube(object); break; case SQUARE: assert(FALSE); //HandleASquare(object); break; default: assert(FALSE); } } } } HandleAllShipCollisions(); } #if 0 // NOT NEEDED // updating common to all object types void HandleCommonUpdating (ObjectHandler* object) { object->lifeTime++; //if (object->canFire == TRUE) // object->framesSinceLastFire++; } #endif // NOT NEEDED void HandleAPlayersShip (ObjectHandler* object) { assert(object->type == PLAYER_ONES_SHIP || object->type == PLAYER_TWOS_SHIP); if (SystemInUse == FALSE) { DealWithPlayersControllerInput(object); } if (object->interactivityFlag != TRUE) return; HandleSomeShipsMovementInTunnel(object); SortMatrixFromAngle(object); SortCoordFromMatrix(object); } void HandleOtherShip (ObjectHandler* ship) { assert(ship->type == OTHER_SHIP); if (ship->interactivityFlag != TRUE) return; // LOTS TRIED HERE: ONLY HandleSplinePathFollower WORKS AS NOW switch(ship->specialMovementFlag) { case HUMAN_PLAYER: assert(FALSE); // should never get here break; case AI_FLIER_1: HandleSplinePathFollower(ship); break; case AI_FLIER_2: //HandleProperDynamicFlier(ship); //HandleProperDynamicFlier2(ship); HandleProperDynamicFlier3(ship); break; case AI_FLIER_3: HandleDubiousBlagger(ship); break; case AI_FLIER_4: HandleSplinePathDeviator(ship); break; default: assert(FALSE); } HandleSomeShipsMovementInTunnel(ship); SortMatrixFromAngle(ship); SortCoordFromMatrix(ship); switch(ship->speedControlFlag) { case -1: // speedControlFlag not being used break; case SLOW_FLIER: case SLOWISH_FLIER: case FASTISH_FLIER: #if 0 case FAST_FLIER: #endif // do nowt break; #if 0 case VARIABLE_SPEED_FLIER: { int time, tenthOfPeriod, fourTenthsOfPeriod, phase, subTime; assert(ship->speedControlPeriod > 0); time = (frameNumber - RollingDemoStartFrame) % ship->speedControlPeriod; if (time < 0) time = 0; tenthOfPeriod = ship->speedControlPeriod / 10; assert(tenthOfPeriod > 0); fourTenthsOfPeriod = 4 * tenthOfPeriod; phase = time * 10 / ship->speedControlPeriod; switch(phase) { case 0: case 1: case 2: case 3: // accelerating subTime = time; ship->discreteSpeed = 8 + (((64-8) * time) / fourTenthsOfPeriod); break; case 4: ship->discreteSpeed = 64; case 5: case 6: case 7: case 8: // decelerating subTime = time - (5 * tenthOfPeriod); ship->discreteSpeed = 64 - (((64-8) * time) / fourTenthsOfPeriod); break; case 9: ship->discreteSpeed = 8; default: assert(FALSE); } } break; #endif default: printf("ship type %d id %d has bad controlFlag %d\n", ship->type, ship->id, ship->speedControlFlag); assert(FALSE); } } // COORD2 reserved for drawing, scaling // matrix is the spatial descriptor of object position and orientation void SortCoordFromMatrix (ObjectHandler *object) { #if 1 // OLD CopyMatrix( &object->matrix, &object->coord.coord); if (object->scalingFlag == TRUE) { ScaleMatrix( &object->coord.coord, &object->scalingVector); } object->coord.flg = 0; #endif #if 0 // new: accounting for RSD-DXF conversion twists CopyMatrix( &object->matrix, &object->coord.coord); if (object->scalingFlag == TRUE) { ScaleMatrix( &object->coord.coord, &object->scalingVector); } object->coord.flg = 0; assert(object->modelFlag != TMD_RIGHT_WAY); assert(object->modelFlag != TMD_WRONG_WAY); if (object->modelFlag != NO_MODEL_ROTATION) { SVECTOR firstTwist, secondTwist; MATRIX twistMatrix; GetTwistVectorsGivenModelRotation(object->modelFlag, &firstTwist, &secondTwist); RotMatrix( &firstTwist, &twistMatrix); MulMatrix0(&object->coord.coord, &twistMatrix, &object->coord.coord); RotMatrix( &secondTwist, &twistMatrix); MulMatrix0(&object->coord.coord, &twistMatrix, &object->coord.coord); } #endif } #if 0 void GetTwistVectorsGivenModelRotation (int rotationFlag, SVECTOR *firstTwist, SVECTOR *secondTwist) { int point, orientation; point = rotationFlag >> 16; // top 16 bits orientation = rotationFlag & 0xffff; // bottom 16 bits assert(point >= ABOVE && point <= FORWARD); assert(orientation >= 0 && orientation <= 3); switch(point) { case FORWARD: setVECTOR(firstTwist, 0, 0, 0); setVECTOR(secondTwist, 0, 0, (orientation*1024)); break; case BACKWARD: setVECTOR(firstTwist, 0, 2048, 0); setVECTOR(secondTwist, 0, 0, -(orientation*1024)); break; case LEFT: setVECTOR(firstTwist, 0, 1024, 0); setVECTOR(secondTwist, 0, 0, orientation*1024); break; case RIGHT: setVECTOR(firstTwist, 0, 3072, 0); setVECTOR(secondTwist, 0, 0, orientation*1024); break; case ABOVE: setVECTOR(firstTwist, 1024, 0, 0); setVECTOR(secondTwist, 0, 0, orientation*1024); break; case BELOW: setVECTOR(firstTwist, 3072, 0, 0); setVECTOR(secondTwist, 0, 0, orientation*1024); break; default: assert(FALSE); } } #endif void SortMatrixFromAngle (ObjectHandler *object) { int angle; SVECTOR twistVector; MATRIX twistMatrix; assert(object != NULL); angle = object->angle; assert(angle >= 0); assert(angle < ONE); object->matrix.m[0][0] = ONE; object->matrix.m[0][1] = 0; object->matrix.m[0][2] = 0; object->matrix.m[1][0] = 0; object->matrix.m[1][1] = ONE; object->matrix.m[1][2] = 0; object->matrix.m[2][0] = 0; object->matrix.m[2][1] = 0; object->matrix.m[2][2] = ONE; switch(TheTunnelDescription.twoDflag) { case X_Z_PLANE_ONLY: setVECTOR( &twistVector, 0, angle, 0); RotMatrix( &twistVector, &twistMatrix); MulMatrix0( &object->matrix, &twistMatrix, &object->matrix); break; case Y_Z_PLANE_ONLY: setVECTOR( &twistVector, angle, 0, 0); RotMatrix( &twistVector, &twistMatrix); MulMatrix0( &object->matrix, &twistMatrix, &object->matrix); break; default: assert(FALSE); } #if (SHIPS_TILTING_FLAG==1) // YES, this makes it tilt nicely, // but must redo the view modes to use WORLD not ship // at present, camera tilts with ship (most poor) // plus, the spline path followers look very poor // jerky tilt when enter/exit curve; need smoother turning ... { int tiltAngle; if (object != &PlayerOnesShip && object != &PlayerTwosShip) { goto endOfTiltBlockLabel; } tiltAngle = object->tilt * TILT_ANGLE_FROM_TILT_RATIO; switch(TheTunnelDescription.twoDflag) { case X_Z_PLANE_ONLY: setVECTOR( &twistVector, 0, 0, tiltAngle); RotMatrix( &twistVector, &twistMatrix); MulMatrix0( &object->matrix, &twistMatrix, &object->matrix); break; case Y_Z_PLANE_ONLY: // do nowt break; default: assert(FALSE); } endOfTiltBlockLabel: ; } #endif object->matrix.t[0] = object->position.vx; object->matrix.t[1] = object->position.vy; object->matrix.t[2] = object->position.vz; } void GetShipMatrixWithoutTilt (ObjectHandler *object, MATRIX *output) { int angle; SVECTOR twistVector; MATRIX twistMatrix; assert(object != NULL); angle = object->angle; assert(angle >= 0); assert(angle < ONE); output->m[0][0] = ONE; output->m[0][1] = 0; output->m[0][2] = 0; output->m[1][0] = 0; output->m[1][1] = ONE; output->m[1][2] = 0; output->m[2][0] = 0; output->m[2][1] = 0; output->m[2][2] = ONE; switch(TheTunnelDescription.twoDflag) { case X_Z_PLANE_ONLY: setVECTOR( &twistVector, 0, angle, 0); RotMatrix( &twistVector, &twistMatrix); MulMatrix0( output, &twistMatrix, output); break; case Y_Z_PLANE_ONLY: setVECTOR( &twistVector, angle, 0, 0); RotMatrix( &twistVector, &twistMatrix); MulMatrix0( output, &twistMatrix, output); break; default: assert(FALSE); } output->t[0] = object->position.vx; output->t[1] = object->position.vy; output->t[2] = object->position.vz; } // get axes of object before tilt // ie 'real' axes void FindObjectAxesWithoutTilt (ObjectHandler *object, SVECTOR *xAxis, SVECTOR *yAxis, SVECTOR *zAxis) { int angle; SVECTOR twistVector; MATRIX matrix, twistMatrix; assert(object != NULL); angle = object->angle; assert(angle >= 0); assert(angle < ONE); InitMatrix( &matrix); switch(TheTunnelDescription.twoDflag) { case X_Z_PLANE_ONLY: setVECTOR( &twistVector, 0, angle, 0); RotMatrix( &twistVector, &twistMatrix); MulMatrix0( &matrix, &twistMatrix, &matrix); break; case Y_Z_PLANE_ONLY: setVECTOR( &twistVector, angle, 0, 0); RotMatrix( &twistVector, &twistMatrix); MulMatrix0( &matrix, &twistMatrix, &matrix); break; default: assert(FALSE); } setVECTOR( xAxis, matrix.m[0][0], matrix.m[1][0], matrix.m[2][0]); setVECTOR( yAxis, matrix.m[0][1], matrix.m[1][1], matrix.m[2][1]); setVECTOR( zAxis, matrix.m[0][2], matrix.m[1][2], matrix.m[2][2]); } void SortViewShipCoordinates (void) { CopyMatrix( &TheViewShip->matrix, &ViewShipCoordinates.coord); ViewShipCoordinates.flg = 0; } // make all ships active or inactive void SetObjectsInteractivity (int flag) { int i; switch(flag) { case TRUE: PlayerOnesShip.interactivityFlag = TRUE; PlayerTwosShip.interactivityFlag = TRUE; for (i = 0; i < MAX_OTHER_SHIPS; i++) { OtherShips[i].interactivityFlag = TRUE; } break; case FALSE: PlayerOnesShip.interactivityFlag = FALSE; PlayerTwosShip.interactivityFlag = FALSE; for (i = 0; i < MAX_OTHER_SHIPS; i++) { OtherShips[i].interactivityFlag = FALSE; } break; default: assert(FALSE); } } #if 0 // NOT NEEDED // this function does object-relative movement and rotation void UpdateObjectCoordinates (VECTOR* twist, VECTOR* position, VECTOR* velocity, GsCOORDINATE2* coordSystem, MATRIX* matrix) { VECTOR realMovement; MATRIX xMatrix, yMatrix, zMatrix; SVECTOR xVector, yVector, zVector; // find the object-local velocity in super coordinate terms ApplyMatrixLV(matrix, velocity, &realMovement); // update position by actual movement position->vx += realMovement.vx; position->vy += realMovement.vy; position->vz += realMovement.vz; if (twist->vx != 0) { xVector.vx = twist->vx; xVector.vy = 0; xVector.vz = 0; RotMatrix(&xVector, &xMatrix); MulMatrix0(matrix, &xMatrix, matrix); } else if (twist->vy != 0) { yVector.vx = 0; yVector.vy = twist->vy; yVector.vz = 0; RotMatrix(&yVector, &yMatrix); MulMatrix0(matrix, &yMatrix, matrix); } else if (twist->vz != 0) { zVector.vx = 0; zVector.vy = 0; zVector.vz = twist->vz; RotMatrix(&zVector, &zMatrix); MulMatrix0(matrix, &zMatrix, matrix); } coordSystem->coord = *matrix; // set position absolutely coordSystem->coord.t[0] = position->vx; coordSystem->coord.t[1] = position->vy; coordSystem->coord.t[2] = position->vz; // tell GTE that coordinate system has been updated coordSystem->flg = 0; } // this does world-relative movement and rotation void UpdateObjectCoordinates2 (SVECTOR* rotationVector, VECTOR* translationVector, GsCOORDINATE2* coordSystem) { MATRIX tempMatrix; // get rotation matrix from rotation vector RotMatrix(rotationVector, &tempMatrix); // assign new matrix to coordinate system coordSystem->coord = tempMatrix; // set position by absolute coordinates coordSystem->coord.t[0] = translationVector->vx; coordSystem->coord.t[1] = translationVector->vy; coordSystem->coord.t[2] = translationVector->vz; // tell GTE that coordinate system has been updated coordSystem->flg = 0; } #endif // NOT NEEDED #if 0 // not needed // sort out the conversion of coordinates from local->world->screen // for objects that are displayed by GsSPRITE rather than GsDOBJ2 // NOTE: can use this for getting screen coordinates of ANY object // hence do own 3d clipping: compare sx and sy // with +/- ScreenWidth/2 and +/- ScreenHeight/2, // compare sz with ProjectionDistance/2 u_short SortSpriteObjectPosition (ObjectHandler* object) { VECTOR screen; int visualWidth, visualHeight; u_short zValue; PushMatrix(); ApplyMatrixLV( &GsWSMATRIX, &object->position, &screen); screen.vx += GsWSMATRIX.t[0]; screen.vy += GsWSMATRIX.t[1]; screen.vz += GsWSMATRIX.t[2]; if (screen.vz == 0) // prevent division by zero return 0; // right at the front visualWidth = object->sprite.w * ProjectionDistance / screen.vz; visualHeight = object->sprite.h * ProjectionDistance / screen.vz; object->sprite.x = ((screen.vx * ProjectionDistance / screen.vz) - visualWidth/2); object->sprite.y = ((screen.vy * ProjectionDistance / screen.vz) - visualHeight/2); object->sprite.scalex = object->scaleX * ProjectionDistance / screen.vz; object->sprite.scaley = object->scaleY * ProjectionDistance / screen.vz; PopMatrix(); // 3D clipping if (screen.vz < ProjectionDistance/2) object->sprite.attribute |= GsDOFF; // display off else TURN_NTH_BIT_OFF(object->sprite.attribute, 32, 31) // ensure 31st bit is OFF zValue = (u_short) (screen.vz >> 6); // NOTE: need to adjust this // just a blagg to make it look right return zValue; // NOT YET CORRECT } #endif #define STORING_SCREEN 1 void StoreScreen (void) { #if STORING_SCREEN u_long* destination; int x, y, w, h; RECT rect; VSync(0); // new addition DrawSync(0); // new addition destination = (u_long *) SCREEN_SAVE_ADDRESS; x = y = 0; // top left of frame buffer w = ScreenWidth; h = ScreenHeight; *(destination+0) = 0x00000010; /* ID */ *(destination+1) = 0x00000002; /* FLAG(15bit Direct,No Clut) */ *(destination+2) = (w*h/2+3)*4; /* pixel bnum */ *(destination+3) = ((0 & 0xffff) << 16) | (640 & 0xffff); /* pixel DX,DY: at 640, 0 */ *(destination+4) = ((h & 0xffff) << 16) | (w & 0xffff); /* pixel W,H */ // NO CLUT since 16-bit mode used rect.x = x; rect.y = y; rect.w = w; rect.h = h; DrawSync(0); StoreImage(&rect, destination+5); printf("\n\nPress [F10][F4] for dsave, to get screen picture\n"); printf("Dsave[0]: filename %08x %x\n\n\n", (u_int)destination, (w*h/2+5)*4); DrawSync(0); VSync(0); #endif } void PrintDataTypeSizes (void) { ObjectHandler temp1; TunnelSection temp3; TunnelChunk temp31; TunnelDescription temp32; VECTOR temp4; SVECTOR temp5; MATRIX temp6; GsCOORDINATE2 temp7; GsDOBJ2 temp8; GsIMAGE temp9; GsSPRITE temp10; RECT temp11; PACKET temp12; ClutAnimation clutAnimation; DrawProcess drawProcess; printf("\n\n\nPrinting Data Type Sizes in bytes\n\n"); printf("ObjectHandler: %d\n", sizeof(temp1) ); printf("TunnelSection: %d\n", sizeof(temp3) ); printf("TunnelChunk: %d\n", sizeof(temp31) ); printf("TunnelDescription: %d\n", sizeof(temp32) ); printf("ClutAnimation: %d\n", sizeof(clutAnimation) ); printf("DrawProcess: %d\n", sizeof(drawProcess) ); printf("\n\n\n"); printf("VECTOR: %d\n", sizeof(temp4) ); printf("SVECTOR: %d\n", sizeof(temp5) ); printf("MATRIX: %d\n", sizeof(temp6) ); printf("GsCOORDINATE2: %d\n", sizeof(temp7) ); printf("GsDOBJ2: %d\n", sizeof(temp8) ); printf("GsIMAGE: %d\n", sizeof(temp9) ); printf("GsSPRITE: %d\n", sizeof(temp10) ); printf("RECT: %d\n", sizeof(temp11) ); printf("PACKET: %d\n", sizeof(temp12) ); printf("\n\n\n"); printf("ObjectArray: %d\n", sizeof(ObjectArray) ); printf("TheTunnel: %d\n", sizeof(TheTunnel) ); printf("TheTunnelDescription: %d\n", sizeof(TheTunnelDescription) ); printf("PlayerOnesShip: %d\n", sizeof(PlayerOnesShip) ); printf("OtherShips: %d\n", sizeof(OtherShips) ); //printf("ThePolygons: %d\n", sizeof(ThePolygons) ); printf("SetTracks: %d\n", sizeof(SetTracks) ); printf("packetArea: %d\n", sizeof(packetArea) ); printf("\n\n\n"); } void InitialiseRace (void) { int i; FrameWhenRaceStarts = -1; RaceFrameCounter = 0; NumberOfLapsInRace = -1; NumberOfShipsInRace = -1; for (i = 0; i < MAX_SHIPS_PER_RACE; i++) { ShipsInTunnel[i] = NULL; } TheViewShip = NULL; ChosenSetTrack = -1; for (i = 0; i < MAX_SHIPS_PER_RACE; i++) { InitialPositions[i] = -1; FinalPositions[i] = -1; } EndRaceNowFlag = FALSE; RaceOnFlag = FALSE; } // simplest overall initialiser void SortVideoMode (void) { ScreenVideoMode = GetVideoMode(); #if 1 // print info to inform user printf("\n"); switch(ScreenVideoMode) { case MODE_PAL: printf("Currently in video mode PAL\n"); break; case MODE_NTSC: printf("Currently in video mode NTSC\n"); break; default: assert(FALSE); } //printf("If everything is black and white\n"); //printf("or there are lines at bottom or top of screen\n"); //printf("Then you need to change video mode\n\n"); #endif // useful if you want to force same ScreenWidth and ScreenHeight // under both PAL and NTSC switch(ScreenVideoMode) { case MODE_PAL: //GsDISPENV.screen.y = 29; GsDISPENV.screen.y = 40; ScreenVerticalOffset = 29; MaximumGameFramesPerSecond = 50; MaximumScanLinesPerFrame = 270; break; case MODE_NTSC: GsDISPENV.screen.y = 0; ScreenVerticalOffset = 0; MaximumGameFramesPerSecond = 60; MaximumScanLinesPerFrame = 240; break; default: assert(FALSE); } } void ClearPrintStrings (void) { sprintf(SimplePrintString1, "\n"); sprintf(SimplePrintString2, "\n"); sprintf(SimplePrintString3, "\n"); sprintf(SimplePrintString4, "\n"); sprintf(SimplePrintString5, "\n"); sprintf(SimplePrintString6, "\n"); } #if 0 // OLD // uses global strings SimplePrintString 1 - 6 void GuiLoopForSeveralFntPrints (void) { GsSetRefView2(&TheView); HandleSound(); SortFntPrint(); FntPrint(currentFontStream, SimplePrintString1); FntPrint(currentFontStream, SimplePrintString2); FntPrint(currentFontStream, SimplePrintString3); FntPrint(currentFontStream, SimplePrintString4); FntPrint(currentFontStream, SimplePrintString5); FntPrint(currentFontStream, SimplePrintString6); GsSetWorkBase( (PACKET*)packetArea[bufferIndex]); GsClearOt(0, 0, &Wot[bufferIndex]); cpuLoad = VSync(1); DrawSync(0); gpuLoad = VSync(1); hsync = VSync(0); ResetGraph(1); GsSwapDispBuff(); GsSortClear(0, 0, 0, &Wot[bufferIndex]); GsDrawOt(&Wot[bufferIndex]); bufferIndex = GsGetActiveBuff(); FntFlush(currentFontStream); } #endif // OLD // uses TextStringList; displayed more attractively than FntPrint void GuiLoopForDisplayingStrings (int numberOfStrings, int initialFrameDelay) { int x = 0, y = 0; int stringLength; int i; int framesSoFar; long pad; assert(numberOfStrings > 0 && numberOfStrings <= 12); //printf("numberOfStrings %d\n", numberOfStrings); switch(ScreenResolution) { case LOW_RES: y = -10 * numberOfStrings; break; case HI_RES: y = -20 * numberOfStrings; break; default: assert(FALSE); } ClearAllTextStrings(); for (i = 0; i < numberOfStrings; i++) { stringLength = strlen(TextStringList[i]); // adjust text for strings to be centred switch(ScreenResolution) { case LOW_RES: x = (-stringLength * 8) / 2; break; case HI_RES: x = (-stringLength * 16) / 2; break; default: assert(FALSE); } //printf("x %d y %d string: %s.\n", x, y, TextStringList[i]); RegisterStringForPermanentDisplay(TextStringList[i], x, y, NORMAL_COLOUR); switch(ScreenResolution) { case LOW_RES: y += 20; break; case HI_RES: y += 40; break; default: assert(FALSE); } } framesSoFar = 0; for (;;) { HandleSound(); GsSetWorkBase( (PACKET*)packetArea[bufferIndex]); GsClearOt(0, 0, &Wot[bufferIndex]); // drawing DisplayPermanentStringList( &Wot[bufferIndex]); //ApplyStringColouringEffect(FIRST); ApplyStringColouringEffect(SECOND); DrawSync(0); hsync = VSync(0); GsSwapDispBuff(); GsSortClear(0, 0, 0, &Wot[bufferIndex]); GsDrawOt(&Wot[bufferIndex]); bufferIndex = GsGetActiveBuff(); pad = PadRead(0); if (framesSoFar > initialFrameDelay) { if (pad & PADR1 && pad & PADR2) // slow down { for (i = 0; i < 5; i++) VSync(0); } else if (pad != 0) break; } framesSoFar++; frameNumber++; } ClearAllTextStrings(); } // simple mechanism for oscillating the time periods of other mechanisms // easy way to give more life to graphical effects // Danger: lots of mechanisms rely on period being constant, changing it // may cause them to fail the (frameNumber or counter % period == 0 --> reset business) // case int *AffectedPeriod; int MinimumPeriodValue, MaximumPeriodValue; int OscillationPeriod; void InitialiseTimePeriodOscillation (void) { AffectedPeriod = NULL; MinimumPeriodValue = -1; MaximumPeriodValue = -1; OscillationPeriod = -1; } void InitTimePeriodOscillation (int oscillationPeriod, int minValue, int maxValue, int *affectedPeriod) { assert(oscillationPeriod > 0); assert(minValue > 0); assert(maxValue > minValue); assert(affectedPeriod != NULL); AffectedPeriod = affectedPeriod; MinimumPeriodValue = minValue; MaximumPeriodValue = maxValue; OscillationPeriod = oscillationPeriod; } void HandleTimePeriodOscillation (void) { int time, cycleRatio; assert(OscillationPeriod > 0); time = frameNumber % OscillationPeriod; cycleRatio = (time * ONE) / OscillationPeriod; if (cycleRatio < 2048) { *AffectedPeriod = MinimumPeriodValue + (((MaximumPeriodValue-MinimumPeriodValue) * cycleRatio) / 2048); } else { *AffectedPeriod = MaximumPeriodValue - (((MaximumPeriodValue-MinimumPeriodValue) * (cycleRatio-2048)) / 2048); } } void ClearTimePeriodOscillation (void) { assert(AffectedPeriod != NULL); *AffectedPeriod = MinimumPeriodValue; InitialiseTimePeriodOscillation(); } void ResetGraphicResolution (int newScreenWidth, int newScreenHeight) { int interlaceFlag; // stop drawing DrawSync(0); //ResetGraph(1); assert(newScreenWidth == 256 || newScreenWidth == 320 || newScreenWidth == 384 || newScreenWidth == 512 || newScreenWidth == 640); assert(newScreenHeight == 240 || newScreenHeight == 256 || newScreenHeight == 480 || newScreenHeight == 512); ScreenWidth = newScreenWidth; ScreenHeight = newScreenHeight; if (ScreenHeight > 256) { interlaceFlag = GsINTER; ScreenResolution = HI_RES; } else { interlaceFlag = GsNONINTER; ScreenResolution = LOW_RES; } GsInitGraph(ScreenWidth, ScreenHeight, interlaceFlag|GsOFSGPU, 1, 0); if (ScreenHeight > 256) GsDefDispBuff(0, 0, 0, 0); else GsDefDispBuff(0, 0, 0, ScreenHeight); GsSetOrign(ScreenWidth/2, ScreenHeight/2); if (ScreenVerticalOffset != 0) // NEW { GsDISPENV.screen.y = ScreenVerticalOffset; PutDispEnv( &GsDISPENV); } //PRINT("Have just set GS origin to %d %d\n", // ScreenWidth/2, ScreenHeight/2); //PRINT("GS OFFSETS %d %d\n", // GsDRAWENV.ofs[0], GsDRAWENV.ofs[1]); #if 0 if (ScreenHeight > 256) { printf("Setting Hi Res\n"); } else { printf("Setting Low Res\n"); } #endif } #define PROFILER_ON 0 #define MAX_TIMES_PER_FRAME 12 short profilerTimes[MAX_PROFILE_TIMES][MAX_TIMES_PER_FRAME]; int ProfileFrameCounter, ProfileWithinFrameCounter, ProfilerCurrentFrameEstimate; void InitProfiler2 (void) { #if PROFILER_ON int i, j; for (i = 0; i < MAX_PROFILE_TIMES; i++) { for (j = 0; j < MAX_TIMES_PER_FRAME; j++) { profilerTimes[i][j] = -1; } } ProfileFrameCounter = 0; ProfileWithinFrameCounter = 0; ProfilerCurrentFrameEstimate = frameNumber; #endif } void GetTimeNow (void) { #if PROFILER_ON if (ProfilerCurrentFrameEstimate != frameNumber) // next/new frame { //assert(ProfilerCurrentFrameEstimate == frameNumber-1); if (ProfilerCurrentFrameEstimate != frameNumber-1) { printf("ERROR\n"); printf("ProfilerCurrentFrameEstimate %d\n", ProfilerCurrentFrameEstimate); printf("frameNumber %d\n", frameNumber); } ProfilerCurrentFrameEstimate = frameNumber; if (ProfileFrameCounter == MAX_PROFILE_TIMES) { ProfileFrameCounter = 0; PrintTimingData2(); } else ProfileFrameCounter++; ProfileWithinFrameCounter = 0; } profilerTimes[ProfileFrameCounter][ProfileWithinFrameCounter] = GetRCnt(1); ProfileWithinFrameCounter++; if (ProfileWithinFrameCounter >= MAX_TIMES_PER_FRAME) ProfileWithinFrameCounter = 0; #endif } void PrintTimingData2 (void) { #if PROFILER_ON int i, j; printf("\n\n\n\nSTART OF PROFILING RESULTS\n\n\n\n"); for (i = 0; i < MAX_PROFILE_TIMES; i++) { printf("profile frame %d\n", i); for (j = 0; j < MAX_TIMES_PER_FRAME; j++) { printf("withinFrame %d\n", j); printf("TIME %d\n", profilerTimes[i][j]); } } printf("\n\n\n\nEND OF PROFILING RESULTS\n\n\n\n"); // clear data after printing for (i = 0; i < MAX_PROFILE_TIMES; i++) { for (j = 0; j < MAX_TIMES_PER_FRAME; j++) { profilerTimes[i][j] = -1; } } ProfileFrameCounter = 0; ProfileWithinFrameCounter = 0; ProfilerCurrentFrameEstimate = frameNumber; #endif } // return value is 32 bit: top 16 are whole seconds, rest is fraction: // ONE is 1 second, ie fraction < ONE long FramesToSeconds (int frames) { long returnValue; int wholeSeconds, fraction; assert(frames >= 0); assert(((MaximumGameFramesPerSecond == 50) || (MaximumGameFramesPerSecond == 60))); assert(FrameRateDivider >= 1); wholeSeconds = (frames * FrameRateDivider) / MaximumGameFramesPerSecond; fraction = ((frames % (MaximumGameFramesPerSecond/FrameRateDivider)) << 12) / (MaximumGameFramesPerSecond/FrameRateDivider); assert(wholeSeconds < 32767); assert(fraction < ONE); returnValue = (wholeSeconds << 16) + fraction; return returnValue; } #if 0 // not used int GetNumberOfLivingShips (void) { int number = 0; int i; if (PlayerOnesShip.alive == TRUE) number++; if (PlayerTwosShip.alive == TRUE) number++; for (i = 0; i < MAX_OTHER_SHIPS; i++) { if (OtherShips[i].alive == TRUE) number++; } return number; } #endif // not used #if 0 // UNUSED void ClearScreenToColour (int r, int g, int b) { RECT rect; assert(r >= 0 && r <= 255); assert(g >= 0 && g <= 255); assert(b >= 0 && b <= 255); setRECT( &rect, 0, 0, ScreenWidth, 512); ClearImage( &rect, r, g, b); DrawSync(0); ClearImage( &rect, r, g, b); DrawSync(0); printf("Have cleared screen to colour r %d g %d b %d\n", r, g, b); printf("rect cleared: "); dumpRECT( &rect); } #endif int GetSpeedOfViewShip (void) { int speed = -1; if (TheViewShip == &PlayerOnesShip || TheViewShip == &PlayerTwosShip) speed = abs(TheViewShip->velocity.vz); else { switch(TheViewShip->specialMovementFlag) { case HUMAN_PLAYER: printf("TheViewShip %08x\n", (u_int) TheViewShip); printf("&PlayerOnesShip %08x\n", (u_int) &PlayerOnesShip); printf("&PlayerTwosShip %08x\n", (u_int) &PlayerTwosShip); DumpObject(TheViewShip); assert(FALSE); break; case AI_FLIER_1: // using 3rd blagger assert(TheViewShip->speedFactor != 0); speed = (TunnelSectionLength * TheViewShip->discreteSpeed) / TheViewShip->speedFactor; break; case AI_FLIER_2: assert(FALSE); // NOT YET break; case AI_FLIER_3: assert(FALSE); // NOT YET break; default: assert(FALSE); } } return speed; } int GetSpeedFractionOfViewShip (void) { int speedFraction = -1; if (TheViewShip == &PlayerOnesShip || TheViewShip == &PlayerTwosShip) { speedFraction = abs(TheViewShip->velocity.vz); assert(TheViewShip->maximumSpeed > 0); //speedFraction = (speedFraction * ONE) / TheViewShip->maximumSpeed; speedFraction = (speedFraction << 12) / TheViewShip->maximumSpeed; } else { switch(TheViewShip->specialMovementFlag) { case HUMAN_PLAYER: printf("TheViewShip %08x\n", (u_int) TheViewShip); printf("&PlayerOnesShip %08x\n", (u_int) &PlayerOnesShip); printf("&PlayerTwosShip %08x\n", (u_int) &PlayerTwosShip); DumpObject(TheViewShip); assert(FALSE); break; case AI_FLIER_1: // using 3rd blagger assert(TheViewShip->speedFactor != 0); speedFraction = (TunnelSectionLength * TheViewShip->discreteSpeed) / TheViewShip->speedFactor; //speedFraction = (speedFraction * ONE) / TheViewShip->maximumSpeed; speedFraction = (speedFraction << 12) / TheViewShip->maximumSpeed; break; case AI_FLIER_2: assert(FALSE); // NOT YET break; case AI_FLIER_3: assert(FALSE); // NOT YET break; default: assert(FALSE); } } return speedFraction; } void InitialiseDataCacheStackUse (void) { DataCacheInStackUseFlag = FALSE; } void PutStackOntoDataCache (void) { switch(DataCacheInStackUseFlag) { case FALSE: __asm__ volatile ("sw $29,(StackSavePointer)"); __asm__ volatile ("la $29,0x1f8003f0" ); DataCacheInStackUseFlag = TRUE; break; case TRUE: printf("stack ALREADY on dcache, trying to put it on again\n"); break; default: assert(FALSE); } } void RestoreStackFromDataCache (void) { switch(DataCacheInStackUseFlag) { case TRUE: __asm__ volatile ("lw $29,(StackSavePointer)"); DataCacheInStackUseFlag = FALSE; break; case FALSE: printf("stack NOT on dcache, trying to take it off\n"); break; default: assert(FALSE); } } void InitialiseRandomNumbers (void) { int value; value = GetRCnt(1); srand(value); #if 0 // compile-time variation char time[64]; int arbitraryValue; // attempt to make rand() more random: // seed using the seconds // (NOTE: compile-time only: NOT the real time...) strcpy(time, __TIME__); arbitraryValue = ((int) time[6]) + ((int) time[7]); srand(arbitraryValue); #endif } #if 0 // NO LONGER USED void InitialiseGrid (void) { int i; for (i = 0; i <= GRID_GRANULARITY; i++) { GridLines[i].attribute = 0; GridLines[i].x0 = 0; GridLines[i].y0 = 0; GridLines[i].x1 = 0; GridLines[i].y1 = 0; GridLines[i].r = 128; GridLines[i].g = 128; GridLines[i].b = 128; } ShowGlobalGridFlag = FALSE; } void DrawGrid (GsOT *ot) { int i; int startX, startY; int xIncrement, yIncrement; switch(ScreenResolution) { case LOW_RES: startX = 160; startY = 120; xIncrement = 320 / GRID_GRANULARITY; yIncrement = 240 / GRID_GRANULARITY; break; case HI_RES: startX = 320; startY = 240; xIncrement = 640 / GRID_GRANULARITY; yIncrement = 480 / GRID_GRANULARITY; break; default: assert(FALSE); } for (i = 0; i <= GRID_GRANULARITY; i++) { GridLines[i].x0 = -startX + (i * xIncrement); GridLines[i].y0 = -startY; GridLines[i].x1 = GridLines[i].x0; GridLines[i].y1 = startY; GsSortLine( &GridLines[i], ot, 0); } for (i = 0; i <= GRID_GRANULARITY; i++) { GridLines[i].x0 = -startX; GridLines[i].y0 = -startY + (i * yIncrement); GridLines[i].x1 = startX; GridLines[i].y1 = GridLines[i].y0; GsSortLine( &GridLines[i], ot, 0); } } #endif #if 0 // NOT YET void RenderPoint (VECTOR *worldPoint, int projectionDistance, int otLength, SVECTOR *screenPoint) { VECTOR screen; int screenX, screenY; u_short zValue; PushMatrix(); ApplyMatrixLV( &GsWSMATRIX, worldPoint, &screen); screen.vx += GsWSMATRIX.t[0]; screen.vy += GsWSMATRIX.t[1]; screen.vz += GsWSMATRIX.t[2]; if (screen.vz == 0) // prevent division by zero { setVECTOR(screenPoint, 0, 0, 0); return; } screenX = (screen.vx * projectionDistance) / screen.vz; screenY = (screen.vy * projectionDistance) / screen.vz; PopMatrix(); zValue = (u_short) (screen.vz >> (16 - otLength)); setVECTOR(screenPoint, screenX, screenY, zValue); } #endif #define MAX_SLOWDOWN_FACTOR 12 void CalculateCurrentFrameRate (int hsync) { int hsyncCopy; assert(MaximumScanLinesPerFrame > 0); if (hsync >= (MaximumScanLinesPerFrame * MAX_SLOWDOWN_FACTOR)) { FrameRateDivider = 1; CurrentFrameRate = MaximumGameFramesPerSecond; return; // too much time taken for interactive runtime } // must be changing game state hsyncCopy = hsync; FrameRateDivider = 1; while (hsyncCopy >= MaximumScanLinesPerFrame) { hsyncCopy -= MaximumScanLinesPerFrame; FrameRateDivider++; } assert(FrameRateDivider >= 1); //assert(FrameRateDivider <= MAX_SLOWDOWN_FACTOR); if (FrameRateDivider > MAX_SLOWDOWN_FACTOR) FrameRateDivider = MAX_SLOWDOWN_FACTOR; CurrentFrameRate = MaximumGameFramesPerSecond / FrameRateDivider; #if 0 if (frameNumber % 20 == 0) { printf("hsync %d\n", hsync); printf("MaximumScanLinesPerFrame %d\n", MaximumScanLinesPerFrame); printf("FrameRateDivider %d\n", FrameRateDivider); printf("CurrentFrameRate %d\n", CurrentFrameRate); printf("MaximumGameFramesPerSecond %d\n", MaximumGameFramesPerSecond); } #endif } #if (DEVELOPMENT_ENVIRONMENT==YAROZE) typedef struct { short vx, vy; } DVECTOR; #endif // every point on sides of square 31 by 31 // start off at bottom left (0,0) and proceed anticlockwise DVECTOR pointsOnSquareSides[120]; void SetUpSquareDots (void) { int i; for (i = 0; i < 30; i++) { pointsOnSquareSides[i].vx = i; pointsOnSquareSides[i].vy = 0; } for (i = 30; i < 60; i++) { pointsOnSquareSides[i].vx = 30; pointsOnSquareSides[i].vy = i-30; } for (i = 60; i < 90; i++) { pointsOnSquareSides[i].vx = 30-(i-60); pointsOnSquareSides[i].vy = 30; } for (i = 90; i < 120; i++) { pointsOnSquareSides[i].vx = 0; pointsOnSquareSides[i].vy = 120-i; } } int GetNextIndex (int start, int direction, int displacement) { int result = 0; assert(start >= 0 && start < 120); assert(displacement > 0); switch(direction) { case CLOCKWISE: result = start - displacement; while (result < 0) result += 120; break; case ANTICLOCKWISE: result = start + displacement; while (result >= 120) result -= 120; break; default: assert(FALSE); } assert(result >= 0); assert(result < 120); return result; } void GetXandYofPointIndex (int index, int *x, int *y) { assert(index >= 0); assert(index < 120); *x = pointsOnSquareSides[index].vx; *y = pointsOnSquareSides[index].vy; } void SetPacketAreaInSystem (int whichOne, int bufferIndex) { switch(whichOne) { case USE_FIRST_PACKET_AREA: assert(FALSE); // should never get here break; case USE_SECOND_PACKET_AREA: assert(FALSE); // should never get here break; case USE_BOTH_PACKET_AREAS: switch(bufferIndex) { case 0: GsSetWorkBase( (PACKET*) packetArea[0]); break; case 1: GsSetWorkBase( (PACKET*) packetArea6[0]); break; default: assert(FALSE); } break; default: assert(FALSE); } }