//mapselection.cpp //let the user select a map #include #include #include "gamemem.h" #include "fileio.h" #include "gameinitexit.h" #include "parser.h" #include "config.h" #include "environment.h" #include "interfaceutil.h" #include "mapselection.h" #include "controls.h" #define kMaxMaps 1024 #define kMaxEnvironments 64 char *StripName(char *aName) { while(*aName==' '||*aName=='\t')aName++; while(*aName=='\255') { aName++; while(*aName!='\255'&&*aName!=0) aName++; if(*aName=='\255') aName++; while(*aName==' '||*aName=='\t')aName++; } return aName; } int CompareMaps(const void *a,const void *b) { tMapInfo *mapa=(tMapInfo*)FileGetParsedDataPtr(*(tFileRef*)a,kParserTypeMapInfoDesc,sizeof(tMapInfo)); tMapInfo *mapb=(tMapInfo*)FileGetParsedDataPtr(*(tFileRef*)b,kParserTypeMapInfoDesc,sizeof(tMapInfo)); return _stricmp(StripName(mapa->name),StripName(mapb->name)); } //get a list of available map files void GetAvailableMaps(int *availableMaps,int *mapCount) { *mapCount=0; for(int i=0;ihideMap) availableMaps[(*mapCount)++]=i; } qsort(availableMaps,*mapCount,sizeof(tFileRef),CompareMaps); } //get a list of available environment files void GetAvailableEnvironments(int *availableEnvironments,int *environmentCount,int timeTrial) { *environmentCount=0; for(int i=0;ilastRoad=*map; } void SelectPrevMap(tFileRef *map) { int availableMaps[kMaxMaps]; int mapCount; int selection=0; GetAvailableMaps(availableMaps,&mapCount); for(int i=0;ilastRoad=*map; } int SelectMapByChar(char ch) { tFileRef availableMaps[kMaxMaps]; int mapCount; GetAvailableMaps(availableMaps,&mapCount); for(int i=0;iname)[0])>=ch) return i; } return mapCount-1; } typedef struct{ float t; int *mapSelection; int (*Callback)(void*); void *userData; } tMapSelectionCallbackUserData; enum{ kMapSelectionMap, kMapSelectionReverse, kMapSelectionLaps, kMapSelectionEnvironment, // kMapSelectionMode, kMapSelectionAccept, kMapSelectionExit, kNumMapSelectionItems }; int MapSelectionCallback(void *ud) { char ch=toupper(PeekKeyInput(NULL)); if(ch>='A'&&ch<='Z') { *((tMapSelectionCallbackUserData*)ud)->mapSelection=SelectMapByChar(ch); GetKeyInput(NULL); return kNumMapSelectionItems; } if(((tMapSelectionCallbackUserData*)ud)->Callback) return ((tMapSelectionCallbackUserData*)ud)->Callback(((tMapSelectionCallbackUserData*)ud)->userData); return -1; } int InterfaceMapSelection(tGameInfo *gInfo,int (*Callback)(void*),void *userData,int timeTrial) { tFileRef availableMaps[kMaxMaps]; int availableEnvironments[kMaxEnvironments]; int mapSelection=0; int environmentSelection=0; int mapCount,environmentCount; int lapCount=gConfig->lastLaps; int reverse=gConfig->reverse; tMapSelectionCallbackUserData ud; ud.t=INFINITY; ud.mapSelection = &mapSelection; ud.Callback=Callback; ud.userData=userData; GetAvailableMaps(availableMaps,&mapCount); for(int i=0;ilastRoad==availableMaps[i]) mapSelection=i; GetAvailableEnvironments(availableEnvironments,&environmentCount,timeTrial); for(int i=0;ilastEnv==availableEnvironments[i]) environmentSelection=i; tInterfaceMenuDescribtion menu; InterfaceInitMenu(&menu,kNumMapSelectionItems,"Select Map"); menu.RenderCallback=InterfaceRenderReplay; InterfaceMenuZoomAnimation(&menu,-1,true); menu.items[kMapSelectionReverse-1].lineSpacing*=1.5; menu.items[kMapSelectionAccept-1].lineSpacing*=4.25; strcpy(menu.items[kMapSelectionExit].label,"Cancel"); menu.imageXScale=kMapImageXStretch; menu.imageYScale=kMapImageYStretch; menu.imageXPos+=0.1; menu.imageYPos-=0.03; menu.TimerCallback=MapSelectionCallback; menu.userData=&ud; menu.returnOnSpace=true; for(int i=0;i<=kMapSelectionEnvironment;i++) menu.items[i].flags|=kInterfaceMenuItemArrowInput; for(int i=kMapSelectionReverse;i<=kMapSelectionEnvironment;i++) { menu.items[i].size*=0.8; menu.items[i].lineSpacing*=0.8; } int exit=false; int sel; do{ tMapInfo *mapInfo=(tMapInfo*)FileGetParsedDataPtr(availableMaps[mapSelection],kParserTypeMapInfoDesc,sizeof(tMapInfo)); tEnvironment *environment=(tEnvironment*)FileGetParsedDataPtr(availableEnvironments[environmentSelection],kParserTypeEnvironmentDesc,sizeof(tEnvironment)); int demook=false; if(availableMaps[mapSelection]==FileGetReference("city2.mapinfo"))demook=true; if(availableMaps[mapSelection]==FileGetReference("highspeed.mapinfo"))demook=true; menu.image=mapInfo->image; menu.imageAlpha=1.0; strcpy(menu.items[kMapSelectionAccept].label,"Accept"); menu.items[kMapSelectionAccept].flags=0; if((!mapInfo->loop)||gInfo->numLaps==-1) menu.items[kMapSelectionLaps].flags|=kInterfaceMenuItemDisabled; else menu.items[kMapSelectionLaps].flags&=~kInterfaceMenuItemDisabled; menu.items[kMapSelectionEnvironment].flags&=~kInterfaceMenuItemDisabled; menu.items[kMapSelectionReverse].flags&=~kInterfaceMenuItemDisabled; sprintf(menu.items[kMapSelectionMap].label,"Selected Map: \255#a\255%s",mapInfo->name); sprintf(menu.items[kMapSelectionReverse].label,"Direction: \255#a\255%s",reverse?"Reverse":"Normal"); if(gInfo->numLaps!=-1) if(!mapInfo->loop) sprintf(menu.items[kMapSelectionLaps].label,"Number of Laps: \255#a\255Not Looped"); else sprintf(menu.items[kMapSelectionLaps].label,"Number of Laps: \255#a\255%d",lapCount); else sprintf(menu.items[kMapSelectionLaps].label,"Number of Laps: \255#a\255Unlimited"); if(mapInfo->useAltEnv&&environment->hasAltEnv) environment=(tEnvironment*)FileGetParsedDataPtr(environment->altEnv,kParserTypeEnvironmentDesc,sizeof(tEnvironment)); sprintf(menu.items[kMapSelectionEnvironment].label,"Weather: \255#a\255%s",environment->name); sel=InterfaceGetUserMenuSelection(&menu); if(sel==kNumMapSelectionItems) menu.initialSelection=0; else switch(menu.initialSelection=(sel&kInterfaceMenuItemMask)) { case kMapSelectionMap: if(sel&kInterfaceMenuLeftArrow) do{ mapSelection--; if(mapSelection<0)mapSelection=mapCount-1; mapInfo=(tMapInfo*)FileGetParsedDataPtr(availableMaps[mapSelection],kParserTypeMapInfoDesc,sizeof(tMapInfo)); }while(gInfo->numLaps==-1&&!mapInfo->loop); else if(sel&kInterfaceMenuRightArrow) do{ mapSelection=(mapSelection+1)%mapCount; mapInfo=(tMapInfo*)FileGetParsedDataPtr(availableMaps[mapSelection],kParserTypeMapInfoDesc,sizeof(tMapInfo)); }while(gInfo->numLaps==-1&&!mapInfo->loop); else exit=true; break; case kMapSelectionReverse: if(sel&(kInterfaceMenuRightArrow|kInterfaceMenuLeftArrow)) reverse=!reverse; else exit=true; break; case kMapSelectionLaps: if(sel&kInterfaceMenuLeftArrow){ lapCount--; if(lapCount<1)lapCount=kMaxLaps; } else if(sel&kInterfaceMenuRightArrow){ lapCount++; if(lapCount>kMaxLaps)lapCount=1; } else exit=true; break; case kMapSelectionEnvironment: if(sel&kInterfaceMenuLeftArrow){ environmentSelection--; if(environmentSelection<0)environmentSelection=environmentCount-1; } else if(sel&kInterfaceMenuRightArrow) environmentSelection=(environmentSelection+1)%environmentCount; else exit=true; break; /* case kMapSelectionMode: if(sel&kInterfaceMenuLeftArrow){ gInfo->arcade--; if(gInfo->arcade<0) gInfo->arcade=(sel&kInterfaceMenuEasterEgg?2:1); } else if(sel&kInterfaceMenuRightArrow) gInfo->arcade=(gInfo->arcade+1)%(sel&kInterfaceMenuEasterEgg?3:2); else exit=true; break; */ case kInterfaceMenuOK: case kMapSelectionAccept: exit=true; break; case kInterfaceMenuEsc: case kMapSelectionExit: exit=true; break; } }while(!exit); InterfaceDisposeMenu(&menu); sel&=kInterfaceMenuItemMask; if(sel!=kInterfaceMenuEsc&&sel!=kMapSelectionExit) { gInfo->reverse=reverse; if(gInfo->numLaps!=-1) gInfo->numLaps=lapCount; gInfo->map=availableMaps[mapSelection]; tMapInfo *mapInfo=(tMapInfo*)FileGetParsedDataPtr(gInfo->map,kParserTypeMapInfoDesc,sizeof(tMapInfo)); if(!mapInfo->loop) { gInfo->numLaps=1; } gInfo->environment=availableEnvironments[environmentSelection]; gConfig->lastRoad=availableMaps[mapSelection]; gConfig->reverse=reverse; gConfig->lastLaps=lapCount; gConfig->lastEnv=availableEnvironments[environmentSelection]; // gConfig->arcade=gInfo->arcade; return true; } return false; }