Redline/source/challenges.cpp

235 lines
8.0 KiB
C++
Raw Normal View History

#include <string.h>
#include <stdio.h>
#include "fileio.h"
#include "interfaceutil.h"
#include "gameinitexit.h"
#include "gameframe.h"
#include "challenges.h"
#include "config.h"
#include "carphysics.h"
#include "gametime.h"
#include "gamesystem.h"
#include "controls.h"
#include "carselection.h"
#include "writeout.h"
#include "environment.h"
#include "renderframe.h"
#include "text.h"
#include "screen.h"
#include "log.h"
#include "interface.h"
#include "textures.h"
#include "gamesound.h"
#include "reg_tool_3.h"
int HasChallengeRequirements(int requirements,int hasReq)
{
for(int i=0;i<16;i++)
if(((((unsigned int)requirements)>>(i*2))&0x3)>((((unsigned int)hasReq)>>(i*2)&0x3)))
return false;
return true;
}
void ChallengeRenderCallback(tChallenge *chal,int selection,void *menu)
{
InterfaceRenderReplay(NULL,selection,menu);
char info[1024];
tCarDefinition *car=(tCarDefinition*)FileGetParsedDataPtr(chal->car,kParserTypeCarDesc,sizeof(tCarDefinition));
sprintf(info,"Car: %s\n\n\255goldmedal.pct\255 Gold: %d:%02d'%02d\n\255silvermedal.pct\255 Silver: %d:%02d'%02d\n\255bronzemedal.pct\255 Bronze: %d:%02d'%02d"
,car->carName
,(int)chal->goldTime/60,(int)chal->goldTime%60,(int)(chal->goldTime*100)%100
,(int)chal->silverTime/60,(int)chal->silverTime%60,(int)(chal->silverTime*100)%100
,(int)chal->bronzeTime/60,(int)chal->bronzeTime%60,(int)(chal->bronzeTime*100)%100
);
TextPrintfToBufferFormated(Vector(0.3,0.6),0.035,kTextAlignLeft|kTextAutoWrap,info);
TextPrintfToBufferFormated(Vector(-0.9,-0.3),0.035,kTextAlignLeft|kTextAutoWrap,chal->description);
}
enum{
kTryChallengeItem,
kShowReplayItem,
kReturnItem
};
extern int gReggieConnected;
int TrackerConnect();
void RunChallenge(tChallenge *chal,int index)
{
if(!gReggieConnected&&gConfig->registerLapTimes)
{
InterfaceDrawStrings("Connecting to Lap Times Server...","One moment, please.",kFileErr);
TrackerConnect();
}
tGameInfo gInfo;
InitGInfo(&gInfo);
gInfo.numPlayers=1;
gInfo.reverse=chal->reverse;
gInfo.environment=chal->environment;
gInfo.numLaps=1;
gInfo.map=chal->map;
gInfo.maxTime=chal->bronzeTime;
gInfo.silverTime=chal->silverTime;
gInfo.goldTime=chal->goldTime;
gInfo.playerCars[0]=chal->car;
gInfo.playerColors[0]=chal->color;
gLocalRecord=gConfig->challengeRecords[index];
int result=RunGame(&gInfo);
int oldChallengeData=gConfig->challengeData;
if(result!=-1)
{
if(result-kStartGameDelaySeconds*kFPS<gConfig->challengeRecords[index]||gConfig->challengeRecords[index]==0)
gConfig->challengeRecords[index]=result-kStartGameDelaySeconds*kFPS;
if(result*kFrameTime<=chal->goldTime+kStartGameDelaySeconds)
gConfig->challengeData|=3<<(index*2);
else if(result*kFrameTime<=chal->silverTime+kStartGameDelaySeconds)
{
if((gConfig->challengeData&(3<<(index*2)))<(2<<(index*2)))
gConfig->challengeData=(gConfig->challengeData&~(3<<(index*2)))|(2<<(index*2));
}
else if(result*kFrameTime<=chal->bronzeTime+kStartGameDelaySeconds)
{
if((gConfig->challengeData&(3<<(index*2)))<(1<<(index*2)))
gConfig->challengeData=(gConfig->challengeData&~(3<<(index*2)))|(1<<(index*2));
}
}
if(gConfig->challengeData!=oldChallengeData)
{
gConfig->dbIndex=gConfig->challengeData^0xdeadbeef;
// WriteOutFile(FileGetReference("config.cfg"),gConfig,kParserTypeConfigDesc);
for(int i=0;i<gFileTableSize;i++)
if(char *extension=FileGetExtension(i))
if(!_stricmp(extension,kFileTypeCarDefinition))
{
tCarDefinition *car=(tCarDefinition*)FileGetParsedDataPtr(i,kParserTypeCarDesc,sizeof(tCarDefinition));
if(HasChallengeRequirements(car->challengeRequirements,gConfig->challengeData)>HasChallengeRequirements(car->challengeRequirements,oldChallengeData))
{
float startTime=TimeGetSeconds();
while((GetInterfaceKey(kInterfaceKeyReturn)||GetInterfaceKey(kInterfaceKeyEnter)||GetInterfaceKey(kInterfaceKeyEsc)));
float curTime;
do{
SystemPoll(false);
curTime=TimeGetSeconds()-startTime;
tEnvironment *oldEnv=gEnvironment;
tMapEnv* oldMapEnv=gMapEnv;
gMapEnv=NULL;
LoadEnvironment(FileGetReference("showroom.senv"));
SetupLighting();
InterfaceCarSelectionRender(curTime,&i,1,0,kCarSelectionDisplayMode,0,0,0,0,0,0);
gMapEnv=oldMapEnv;
gEnvironment=oldEnv;
}while(!(GetInterfaceKey(kInterfaceKeyReturn)||GetInterfaceKey(kInterfaceKeyEnter)||GetInterfaceKey(kInterfaceKeyEsc)));
FlushKeys();
}
}
}
}
int InterfaceRunChallengeMenu(tChallenge *chal,int index)
{
// while(GetInterfaceKey(kInterfaceKeyReturn)||GetInterfaceKey(kInterfaceKeyEnter)||GetInterfaceKey(kInterfaceKeyEsc));
tInterfaceMenuDescribtion menu;
InterfaceInitMenu(&menu,3,chal->name);
strcpy(menu.items[kTryChallengeItem].label,"Try the Challenge");
strcpy(menu.items[kShowReplayItem].label,"See Demonstration");
strcpy(menu.items[kReturnItem].label,"Return to previous menu");
if(index>2&&!RT3_IsRegistered())
{
strcpy(menu.items[kTryChallengeItem].label,"Not available in demo.");
menu.items[kTryChallengeItem].flags=kInterfaceMenuItemDisabled;
}
menu.items[kShowReplayItem].lineSpacing*=1.5;
menu.background=FileGetReference("background-clock.tif");
menu.RenderCallback=(void(*)(void*,int,void*))ChallengeRenderCallback;
menu.userData=chal;
menu.itemsYPos=0.6;
int sel;
do{
sel=InterfaceGetUserMenuSelection(&menu);
switch(sel)
{
case kTryChallengeItem:
//InterfaceTextBufferZoomAnimation(FileGetReference("background-clock.tif"),false);
RunChallenge(chal,index);
break;
case kShowReplayItem:
LogLoad(chal->replay,&gInterfaceGInfo);
gGameEnd=false;
gGameInfo=&gInterfaceGInfo;
StartBackgroundReplay();
gEnableTextureLoad=false;
gNumTexturesRequested=0;
ReplayFrame();
RenderFrame(false);
gNumTexturesLoaded=0;
gEnableTextureLoad=true;
gDisabledRestart=0;
for(int i=0;i<gFileTableSize;i++)
{
if(gFileTable[i].tagged&&!gFileTable[i].parsed)
{
// InterfaceDrawStatusBar("Loading Textures...",gFileTable[i].name,gNumTexturesLoaded/(float)gNumTexturesRequested);
if(gNumTexturesRequested>0)
InterfaceDrawStatusBar("Loading Textures...","Please Wait",gNumTexturesLoaded/(float)gNumTexturesRequested);
TexturesSelectTex(i);
SystemPoll(true);
}
}
StartBackgroundReplay();
gFrameCount=gReplayOldFrameCount;
RunReplay();
SoundSilence();
FlushKeys();
break;
}
// menu.initialSelection=sel;
}while(sel==kTryChallengeItem||sel==kShowReplayItem);
}
void InterfaceChallenge()
{
tChallengeList *cList=(tChallengeList*)FileGetParsedDataPtr(FileGetReference(kChallengeListFileName),kParserTypeChallengeList,sizeof(tChallengeList));
tInterfaceMenuDescribtion menu;
InterfaceInitMenu(&menu,cList->numChallenges,"Select a Challenge");
menu.background=FileGetReference("background-clock.tif");
menu.RenderCallback=InterfaceRenderReplay;
menu.scrollEnable=true;
// strcpy(menu.items[cList->numChallenges].label,"Return to previous menu");
// menu.items[cList->numChallenges-1].lineSpacing*=1.5;
int exit=false;
do{
for(int i=0;i<cList->numChallenges;i++)
{
if(!HasChallengeRequirements(cList->challenges[i].requirements,gConfig->challengeData))
menu.items[i].flags|=kInterfaceMenuItemDisabled;
else
menu.items[i].flags&=~kInterfaceMenuItemDisabled;
if((gConfig->challengeData&(3<<(i*2)))==(3<<(i*2)))
sprintf(menu.items[i].label,"%s \255goldmedal.pct\255",cList->challenges[i].name);
else if((gConfig->challengeData&(2<<(i*2)))==(2<<(i*2)))
sprintf(menu.items[i].label,"%s \255silvermedal.pct\255",cList->challenges[i].name);
else if((gConfig->challengeData&(1<<(i*2)))==(1<<(i*2)))
sprintf(menu.items[i].label,"%s \255bronzemedal.pct\255",cList->challenges[i].name);
else
strcpy(menu.items[i].label,cList->challenges[i].name);
}
int i=(menu.initialSelection=InterfaceGetUserMenuSelection(&menu));
if(i!=kInterfaceMenuEsc&&i!=cList->numChallenges)
InterfaceRunChallengeMenu(cList->challenges+i,i);
else exit=true;
}while(!exit);
InterfaceDisposeMenu(&menu);
}