//interface.cpp //the game's main menu screen #include #include "gametime.h" #include #include "fileio.h" #include "textures.h" #include "controls.h" #include "screen.h" #include "gameinitexit.h" #include "gameframe.h" #include "initexit.h" #include "text.h" #include "config.h" #include "interface.h" #include "carselection.h" #include "mapselection.h" #include "random.h" #include "environment.h" #include "writeout.h" #include "challenges.h" #include "interfaceutil.h" #include "renderframe.h" #include "log.h" #include "gamesystem.h" #include "gamesound.h" #include "interfacemultiplayer.h" #include "tracker.h" #include tGameInfo gInterfaceGInfo; //initializes the user interface void InterfaceInit() { glClear(GL_COLOR_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f,0.0f,-1.0f); } void StartBackgroundReplay() { gMapInfo=(tMapInfo*)FileGetParsedDataPtr(gInterfaceGInfo.map,kParserTypeMapInfoDesc,sizeof(tMapInfo)); LoadEnvironment(gInterfaceGInfo.environment); gInterfaceGInfo.network=false; gReplay=true; gGameInfo=&gInterfaceGInfo; gReplayAutoCam=true; if(!(gGameInfo->numLaps==-1&&gBestLapTime==0)) gCurrentLapStart=0; StartReplay(); gReplayViewedEntityID=0; /* gFrameCount=0; gGraphFrameCount=0; gStartTime=TimeGetSeconds();*/ } int SelectRaceMode(tFileRef map,int (*TimerCallback)(void*),void *userData) { tMapInfo *mapInfo=(tMapInfo*)FileGetParsedDataPtr(map,kParserTypeMapInfoDesc,sizeof(tMapInfo)); tInterfaceMenuDescribtion menu; InterfaceInitMenu(&menu,5,"Select Gameplay Mode"); menu.RenderCallback=InterfaceRenderReplay; menu.initialSelection=gConfig->arcade; strcpy(menu.items[0].label,"Simulation"); strcpy(menu.items[0].describtion,"Simulation Mode tries to resemble real-life car physics as close as possible. Different cars may handle completely different depending on their mass distribution, drivetrain setup and many other factors."); strcpy(menu.items[1].label,"Arcade"); strcpy(menu.items[1].describtion,"Arcade Mode puts emphasis on playability and easy handling of cars, but is vastly inaccurate compared to real-life physics. Different cars handle quite similar and differ only in their acceleration and top speed characteristics."); strcpy(menu.items[2].label,"Turbo Arcade"); strcpy(menu.items[2].describtion,"Arcade Mode on steroids."); strcpy(menu.items[3].label,"Strict"); strcpy(menu.items[3].describtion,"Strict mode is like Simulation mode with modified collision physics to encourage clean racing."); strcpy(menu.items[menu.numItems-1].label,"Cancel"); menu.items[menu.numItems-2].lineSpacing*=1.5; menu.imageXScale=kMapImageXStretch; menu.imageYScale=kMapImageYStretch; menu.imageXPos+=0.1; menu.imageYPos-=0.03; menu.TimerCallback=TimerCallback; menu.userData=userData; menu.image=mapInfo->image; menu.descPos=Vector(-0.9,-0.6); int sel=InterfaceGetUserMenuSelection(&menu); InterfaceDisposeMenu(&menu); return sel==menu.numItems-1||sel==kInterfaceMenuEsc?-1:sel; } void InterfaceQuickRace() { tGameInfo gInfo; InitGInfo(&gInfo); //let user select a map... if(InterfaceMapSelection(&gInfo,NULL,NULL,false)) { int raceMode=SelectRaceMode(gInfo.map,NULL,NULL); if(raceMode==-1) return; else gConfig->arcade=raceMode; gInfo.arcade=gConfig->arcade; tFileRef playerCar=gConfig->lastCar; UInt8 playerColor=gConfig->lastColor; //...and a car... if(InterfaceCarSelection(&playerCar,kCarSelectionQuickMode,&playerColor,NULL,NULL,NULL)) { gConfig->lastCar=playerCar; gConfig->lastColor=playerColor; tMapInfo *mapInfo=(tMapInfo*)FileGetParsedDataPtr(gInfo.map,kParserTypeMapInfoDesc,sizeof(tMapInfo)); int numPlayers=mapInfo->maxPlayers; //...and opponets if(InterfaceSelectOpponentCars(&numPlayers,gInfo.playerCars+1,gInfo.playerColors+1,NULL,NULL)) { gInfo.numPlayers=numPlayers+1; gInfo.playerID=0; gInfo.playerCars[gInfo.playerID]=playerCar; gInfo.playerColors[gInfo.playerID]=playerColor; //and run the game RunGame(&gInfo); TeaserScreen(); } } } } void InterfaceTimeTrial() { tGameInfo gInfo; InitGInfo(&gInfo); gInfo.numPlayers=1; gInfo.numLaps=-1; //let user select a map... if(InterfaceMapSelection(&gInfo,NULL,NULL,true)) { int raceMode=SelectRaceMode(gInfo.map,NULL,NULL); if(raceMode==-1) return; else gConfig->arcade=raceMode; gInfo.arcade=gConfig->arcade; //...and a car... gInfo.playerCars[0]=gConfig->lastCar; gInfo.playerColors[0]=gConfig->lastColor; if(InterfaceCarSelection(gInfo.playerCars,kCarSelectionQuickMode,gInfo.playerColors,NULL,NULL,NULL)) { gConfig->lastCar=gInfo.playerCars[0]; gConfig->lastColor=gInfo.playerColors[0]; gLocalRecord=0; for(int i=0;inumPersonalRecords;i++) if(gConfig->records[i].map==gInfo.map&&gConfig->records[i].car==gInfo.playerCars[0] &&gConfig->records[i].mode==gInfo.arcade&&gConfig->records[i].direction==gInfo.reverse) gLocalRecord=gConfig->records[i].time; RunGame(&gInfo); WriteOutFile(FileGetReference(kConfigFileName),gConfig,kParserTypeConfigDesc); TeaserScreen(); } } } void InterfaceOptions(); enum{ kButtonQuickRace, kButtonTimeTrial, kButtonMultiplayer, kButtonCareer, kButtonOptions, kButtonAbout, kButtonQuit, kNumButtons }; void InterfaceDisplayRegisterName(void *userData,int selection) { // TextPrintfToBufferFormated(Vector(1.0,-0.9),0.03,kTextAlignRight,"%s%s",RT3_IsRegistered()?"Registered to: ":"",RT3_GetDisplayName()); TextPrintfToBufferFormated(Vector(1.0,0.95),0.03,kTextAlignRight,kVersionString); // TextPrintfToBufferFormated(Vector(-1.0,-0.9),0.03,kTextAlignLeft,kVersionString); } #define kTopSize 0.141 void InterfaceRenderReplay(void *userData,int selection,void *menu) { float *t,v=0; static int inited=false; if(userData) t=((float*)userData); else t=&v; if(gConfig->showReplays)//&&0) { gBackgroundReplay=true; if(!inited) { gEnableTextureLoad=false; gNumTexturesRequested=0; gClipEnable=false; RenderFrame(false); gClipEnable=true; gNumTexturesLoaded=0; gEnableTextureLoad=true; gDisabledRestart=0; for(int i=0;ibackground!=kFileErr||!gConfig->showReplays) { if(((tInterfaceMenuDescribtion*)menu)->background!=kFileErr) TexturesSelectTex(((tInterfaceMenuDescribtion*)menu)->background); else TexturesSelectTex(FileGetReference("background.tif")); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); if(!gConfig->showReplays) glDisable(GL_BLEND); glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(1,1); /*glColor4f(1,1,1,0);*/ glVertex2f(kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch); glTexCoord2d(1,0); /*glColor4f(1,1,1,0);*/ glVertex2f(kBackgroundXStretch,kBackgroundYStretch); glTexCoord2d(0,1); /*glColor4f(1,1,1,1);*/ glVertex2f(-kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch); glTexCoord2d(0,0); /*glColor4f(1,1,1,1);*/ glVertex2f(-kBackgroundXStretch,kBackgroundYStretch); glEnd(); glEnable(GL_BLEND); } if(((tInterfaceMenuDescribtion*)menu)->image!=kFileErr) { TexturesSelectTex(((tInterfaceMenuDescribtion*)menu)->image); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glColor4f(1,1,1,((tInterfaceMenuDescribtion*)menu)->imageAlpha); glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(1,1); glVertex2f(((tInterfaceMenuDescribtion*)menu)->imageXPos+((tInterfaceMenuDescribtion*)menu)->imageXScale,((tInterfaceMenuDescribtion*)menu)->imageYPos-((tInterfaceMenuDescribtion*)menu)->imageYScale); glTexCoord2d(1,0); glVertex2f(((tInterfaceMenuDescribtion*)menu)->imageXPos+((tInterfaceMenuDescribtion*)menu)->imageXScale,((tInterfaceMenuDescribtion*)menu)->imageYPos+((tInterfaceMenuDescribtion*)menu)->imageYScale); glTexCoord2d(0,1); glVertex2f(((tInterfaceMenuDescribtion*)menu)->imageXPos-((tInterfaceMenuDescribtion*)menu)->imageXScale,((tInterfaceMenuDescribtion*)menu)->imageYPos-((tInterfaceMenuDescribtion*)menu)->imageYScale); glTexCoord2d(0,0); glVertex2f(((tInterfaceMenuDescribtion*)menu)->imageXPos-((tInterfaceMenuDescribtion*)menu)->imageXScale,((tInterfaceMenuDescribtion*)menu)->imageYPos+((tInterfaceMenuDescribtion*)menu)->imageYScale); glEnd(); glColor4f(1,1,1,1); } TexturesSelectTex(FileGetReference("menustripe.tif")); glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(1,1); glVertex2f((2)*kScreenXPos, 0.7*kScreenYPos); glTexCoord2d(1,0); glVertex2f((2)*kScreenXPos, 1.0*kScreenYPos); glTexCoord2d(0,1); glVertex2f((-2)*kScreenXPos,0.7*kScreenYPos); glTexCoord2d(0,0); glVertex2f((-2)*kScreenXPos,1.0*kScreenYPos); glEnd(); glDisable(GL_TEXTURE_2D); glColor4f(0,0,0,1); glBegin(GL_TRIANGLE_STRIP); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch); glVertex2f(-2*kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch); glVertex2f(-2*kBackgroundXStretch,kBackgroundYStretch); glEnd(); glBegin(GL_TRIANGLE_STRIP); glVertex2f(2*kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch); glVertex2f(2*kBackgroundXStretch,kBackgroundYStretch); glVertex2f(kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch); glVertex2f(kBackgroundXStretch,kBackgroundYStretch); glEnd(); glColor4f(1,1,1,1); glEnable(GL_TEXTURE_2D); } else if(!gConfig->showReplays) { glDisable(GL_BLEND); TexturesSelectTex(FileGetReference("background.tif")); glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(1,1); /*glColor4f(1,1,1,0);*/ glVertex2f(kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch); glTexCoord2d(1,0); /*glColor4f(1,1,1,0);*/ glVertex2f(kBackgroundXStretch,kBackgroundYStretch); glTexCoord2d(0,1); /*glColor4f(1,1,1,1);*/ glVertex2f(-kBackgroundXStretch,kBackgroundYStretch-2*kBackgroundXStretch); glTexCoord2d(0,0); /*glColor4f(1,1,1,1);*/ glVertex2f(-kBackgroundXStretch,kBackgroundYStretch); glEnd(); glEnable(GL_BLEND); } if(*t<0) *t=TimeGetSeconds(); float time=TimeGetSeconds(); float d=1.5-(time-*t)*2; if(d<0)d=0; if(userData&&!isinf(*t)) { TexturesSelectTex(FileGetReference("menulogo.tif")); glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(1,1); glVertex2f((0.3-d)*kScreenXPos, 0.7*kScreenYPos); glTexCoord2d(1,0); glVertex2f((0.3-d)*kScreenXPos, 1.0*kScreenYPos); glTexCoord2d(0,1); glVertex2f((-0.95-d)*kScreenXPos,0.7*kScreenYPos); glTexCoord2d(0,0); glVertex2f((-0.95-d)*kScreenXPos,1.0*kScreenYPos); glEnd(); TexturesSelectTex(FileGetReference("logo.pct")); glColor4f(1,1,1,d); glBegin(GL_TRIANGLE_STRIP); glTexCoord2d(1,1); glVertex2f(kBackgroundXStretch,-kBackgroundYStretch); glTexCoord2d(1,0); glVertex2f(kBackgroundXStretch,kBackgroundYStretch); glTexCoord2d(0,1); glVertex2f(-kBackgroundXStretch,-kBackgroundYStretch); glTexCoord2d(0,0); glVertex2f(-kBackgroundXStretch,kBackgroundYStretch); glEnd(); TextPrintfToBufferFormated(Vector(1.0,-0.9),0.03,kTextAlignRight,"%s%s",RT3_IsRegistered()?"Registered to: ":"",RT3_GetDisplayName()); TextPrintfToBufferFormated(Vector(1.0,0.88),0.03,kTextAlignRight,kVersionString); } gTexturesQualityModifier=0; glPopAttrib(); } int InterfaceConfirmQuit() { tInterfaceMenuDescribtion menu; InterfaceInitMenu(&menu,2,"Do you really want to quit?"); menu.background=kFileErr; menu.RenderCallback=InterfaceRenderReplay; char itemStrings[][32]={"Quit","Cancel"}; menu.items[0].lineSpacing*=1.3; for(int i=0;i0) InterfaceDrawStatusBar("Loading Textures...","Please Wait",gNumTexturesLoaded/(float)gNumTexturesRequested); TexturesSelectTex(i); SystemPoll(true); } } StartBackgroundReplay(); gFrameCount=gReplayOldFrameCount; RunReplay(); SoundSilence(); FlushKeys(); } } //run the applications main loop void InterfaceMainLoop() { float userData=-1; tInterfaceMenuDescribtion menu; InterfaceInitMenu(&menu,kNumButtons+1,""); menu.numItems=kNumButtons; char itemStrings[][32]={"Quick Race","Time Trial","Multiplayer","Challenges","Options","About","Quit",""}; for(int i=0;i