Exemple #1
0
//signal handler simply runs printHist()
void handle_SIGQUIT() {
  printHist();
}
int main (int argc, char**argv) {
    bool doHelp=false;
    if (argc<=1) {
        doHelp=true;
    }
    for (int i=1;i<argc;++i) {
        if (strcmp(argv[i],"-h")==0||
            strcmp(argv[i],"-help")==0||
            strcmp(argv[i],"--help")==0||
            strcmp(argv[i],"/help")==0||
            strcmp(argv[i],"/h")==0) {
            doHelp=true;
        }
    }
    if (doHelp) {
        printf("Usage Example:\n\n%s SAVE1.GAM SAVE2.GAM q0 SAVE3.GAM\nThe above example takes the planets from SAVE1.GAM applies it to the monsters and 4 player races and planet picks of SAVE2.GAM takes the 0th quadrant (numbered from 0 to 3) and saves the result into SAVE3.GAM\n\n",argv[0]);
        printf("Generic usage %s <planetInput> <raceInput> <quadrantSelection> <output>\n\n",argv[0]);
        printf("The general usage is that <planetInput> should be set to a Master of Orion II save game file, often the same file, that contains the planets and <raceInput> should be set to the save game that has the desired races. Then the quadrantSelection selects a portion of the map and rotates and mirrors it so that every player gets an even shake. <output> should be set to the final save file that may be reloaded for the fair game\n\n");
        printf("quadrant selection is limited to the following options:\n");
        printf("2 player options:\n");
        printf("h0 assume a 2 player game and take the left half and reflect it\n");
        printf("h1 assume a 2 player game and take the right half and reflect it\n");
        printf("v0 assume a 2 player game and take the top half and reflect it\n");
        printf("v1 assume a 2 player game and take the bottom half and reflect it\n");
        printf("4 player options:\n");
        printf("q0 assume a 4 player game and take the top left quarter and mirror it\n");
        printf("q1 assume a 4 player game and take the bottom left quarter and mirror it\n");
        printf("q2 assume a 4 player game and take the bottom right quarter and mirror it\n");
        printf("q3 assume a 4 player game and take the top right quarter and mirror it\n");
        printf("6 player options:\n");
        printf("x0 or x1 or x2 or x3 or x4 or x5 mirror the appropriate slice\n");

        return 0;
    }
    srand(0x31337);
    Star stars[MAX_NUM_STARS];
    Planet planets[MAX_NUM_PLANETS];
    Star newStars[MAX_NUM_STARS];
    Planet newPlanets[MAX_NUM_PLANETS];
    homeworlds.insert("Sol");
    homeworlds.insert("Nazin");
    homeworlds.insert("Meklon");
    homeworlds.insert("Altair");
    homeworlds.insert("Ursa");
    homeworlds.insert("Gnol");
    homeworlds.insert("Draconis");
    homeworlds.insert("Kholdan");
    homeworlds.insert("Sssla");
    homeworlds.insert("Mentar");
    homeworlds.insert("Fieras");
    homeworlds.insert("Cryslon");
    homeworlds.insert("Trilar");

    FILE * fp = fopen(argv[1],"rb");
    
    fseek(fp,0,SEEK_END);
    size_t fileSize = ftell(fp);
    fseek(fp,0,SEEK_SET);    
    byt * data = (byt*)malloc(fileSize);
    fread(data,1,fileSize,fp);
    fclose(fp);
    FILE * output;
    size_t writeFileSize=0;
    byt * writeData;
    if (argc>2) {
        output = fopen(argv[2],"rb");
        fseek(output,0,SEEK_END);
        writeFileSize = ftell(output);
        fseek(output,0,SEEK_SET);    
        writeData = (byt*)malloc(fileSize);
        fread(writeData,1,writeFileSize,output);
        fclose(output);
    }
    for (int doInput=(argc>2?0:1);doInput<2;++doInput) {
        for (int i=0;i<NUM_PLANETS;++i) {
            const byt * curData = (doInput?data:writeData)+(PLANET_OFFSET+i*PLANET_SIZE);
            Planet planetA;
            memcpy(&planetA,curData,PLANET_SIZE);
            Planet planetB;
            planetB.readPlanet(curData);
            //planetB.printPlanet(NULL);
            if (memcmp(&planetA,&planetB,PLANET_SIZE)) {
                printf("Endianness Mismatch: luckily we coded for that\n");
            }
            byt testIdempotency[PLANET_SIZE];
            planetB.writePlanet(testIdempotency);
            planetA.readPlanet(testIdempotency);
            if (memcmp(&planetA,&planetB,PLANET_SIZE)) {
                printf("Idempotency Mismatch: FAIL\n");
            }
            if (memcmp(testIdempotency,curData,PLANET_SIZE)) {
                printf("Idempotency Mismatch: FAIL Internal\n");
            }
            if (doInput) {
                planets[i]=planetB;
            }else {
                newPlanets[i]=planetB;
            }
        }
    }
    
    int maxx = -(1<<30);
    int minx = (1<<30);
    int maxy = -(1<<30);
    int miny = (1<<30);
    nerf(stars,planets);
    for (int doInput=(argc>2?0:1);doInput<2;++doInput) {
        for (int i=0;i<NUM_STARS;++i) {
            const byt * curData = (doInput?data:writeData)+(STAR_OFFSET+i*STAR_SIZE);
            Star starA;
            
            memcpy(&starA,curData,STAR_SIZE);
//        starA.printStar();
            Star starB;
            starB.readStar(curData);
            if (doInput) {
                if (starB.x!=0||starB.y!=0) {
                    if (starB.x<minx) {
                        minx = starB.x;
                    }
                    if (starB.x>maxx) {
                        maxx = starB.x;
                    }
                    if (starB.y<miny) {
                        miny = starB.y;
                    }
                    if (starB.y>maxy) {
                        maxy = starB.y;
                    }
                }else {
                    //invalid system
                }
                
                stars[i]=starB;
            }else {
                newStars[i]=starB;
            }
            if (memcmp(&starA,&starB,STAR_SIZE)) {
                printf("Endianness Mismatch: luckily we coded for that\n");
            }
            byt testIdempotency[STAR_SIZE];
            starB.writeStar(testIdempotency);
            starA.readStar(testIdempotency);
            if (memcmp(&starA,&starB,STAR_SIZE)) {
                starB.writeStar(testIdempotency);
                starA.readStar(testIdempotency);

                printf("Idempotency Mismatch: FAIL\n");
                if (!(starA==starB)) {
                    printf("Idempotency Mismatch: FAIL B\n");
                }
            }
            if (memcmp(testIdempotency,curData,STAR_SIZE)) {
                printf("Idempotency Mismatch: FAIL Internal\n");
            }
        }
    }
    for (int i=0;i<NUM_STARS;++i) {
        if (newStars[i].isEmpty()) {
            NUM_STARS=i;
            if (i==0) NUM_STARS=71;
            printf("Setting num stars to %d\n",NUM_STARS);
            break;
        }
    }
    if (argc==2) {
        for (int i=0;i<NUM_STARS;++i) {
            stars[i].recordHist();

            stars[i].printStar(planets,stars);
        }
        printf("Bounds: (%d,%d) - (%d,%d)\n",minx,miny,maxx,maxy);
        printHist();
        return 0;
    }
    printf("Bounds: (%d,%d) - (%d,%d)\n",minx,miny,maxx,maxy);
    if (false) {
        for (int i=0;i<NUM_STARS;++i) {
            isHomeworld(stars[i],planets);
        }
        for (int i=0;i<NUM_STARS;++i) {
            isHomeworld(newStars[i],newPlanets);
        }
        for (std::set<std::string>::iterator i=validNames.begin(),ie=validNames.end();i!=ie;++i) {
            starNames.push_back(*i);
        }
    }else {
        for (int i=0;i<sizeof(possibleNames)/sizeof(char*);++i) {
            starNames.push_back(possibleNames[i]);
        }
    }
    //wipePlanets(newStars,newPlanets);
    //wipeStars(newStars,newPlanets); no longer: we now work with what we have
    double percent_safe_zone=0;//.03125;
    double wid = maxx-minx;
    double hei = maxy-miny;
    char mode = argv[3][0];
    int slice=argv[3][1]-'0';//q2 is the 2nd quadrant  x5 is the 5th hex zone h0 is the 0th horizontal slice v0 is the 0th vertical slice
    double sourceminx;
    double sourcemaxx;
    double sourceminy;
    double sourcemaxy;
    
    bool flipX=true;
    bool flipY=true;
    int numX=2,numY=2;
    if (mode=='q') {
        NUM_PLAYERS=4;
        numX=2;
        numY=2;
        flipX=true;
        flipY=true;
    }
    if (mode=='h') {
        NUM_PLAYERS=2;
        numX=2;
        numY=1;
        flipX=true;
        flipY=false;

    }
    if (mode=='v') {
        NUM_PLAYERS=2;
        numX=1;
        numY=2;
        flipX=false;
        flipY=true;
    }
    if (mode=='x') {
        NUM_PLAYERS=6;
        numX=3;
        numY=2;
        flipX=false;
        flipY=true;
    }

    {
        std::set<int>homeworldlessQuadrant;
        std::vector<int> freePlanets;
        std::map<int,int> starMap;//destination star to source star (multiple desitnations may reference a single source)
        int freeStar=0;
        double homeX, homeY;
        for (int doPlace=0;doPlace<2;++doPlace) {
            int count=0;
            for (int x=0;x<numX;++x) {
                for (int y=0;y<numY;++y) {
                    double lenx = (maxx-minx)/(double)numX;
                    double leny = (maxy-miny)/(double)numY;

                    double localminx=minx+lenx*x;
                    double localminy=miny+leny*y;
                    double localmaxx=numX==1?lenx:lenx-percent_safe_zone;
                    double localmaxy=numY==1?leny:leny-percent_safe_zone;
                    localmaxx+=localminx;
                    localmaxy+=localminy;
                    if (numX>1) {//we shove things over so that we are flush with maxx by the end
                        double del = x*percent_safe_zone/(numX-1);
                        localminx+=del;
                        localmaxx+=del;
                        if (x+1==numX) {
                            localmaxx=maxx;//we don't want a float error here
                        }
                    }
                    if (numY>1) {//we shove things over so we are flush with maxx by the end
                        double del = y*percent_safe_zone/(numY-1);
                        localminy+=del;
                        localmaxy+=del;
                        if (y+1==numY) {
                            localmaxy=maxy;//we don't want a float error here cus we need every last star
                        }
                    }
                    if (!doPlace) {
                        //printf("Searching range (%f %f, %f %f)\n",localminx,localminy,localmaxx,localmaxy);
                        if (slice==count) {
                            sourceminx=localminx;
                            sourceminy=localminy;
                            sourcemaxx=localmaxx;
                            sourcemaxy=localmaxy;
                            int homeIndex = findHomeworld (stars,planets,localminx,localminy,localmaxx,localmaxy);
                            if (homeIndex==-1) {
                                printf("Cannot find homeworld in section %d...exiting\n",slice);
                                return -1;
                            }else {
                                Star homeSystem = stars[homeIndex];
                                homeX = ((flipX&&x)?localmaxx-homeSystem.x:homeSystem.x-localminx);
                                homeY = ((flipY&&y)?localmaxy-homeSystem.y:homeSystem.y-localminy);

                                printf("Homeworld located at %s %f %f (%d %d)\n",homeSystem.name,homeX,homeY,homeSystem.x,homeSystem.y);
                            }
                        }
                        //wipeQuadrant(newStars,newPlanets,localminx,localminy,localmaxx,localmaxy);
                    }else if (doPlace==1){
                        copyQuadrantStars(newStars,newPlanets, localminx,localminy,localmaxx,localmaxy,
                                          stars,planets,sourceminx,sourceminy,sourcemaxx,sourcemaxy,flipX,flipY,count,starMap,freePlanets, freeStar);//saves up some free planets for us
                        int newHomeX = (flipX&&x)?localmaxx-homeX:homeX+localminx;
                        int newHomeY = (flipY&&y)?localmaxy-homeY:homeY+localminy;
                        printf("Placing homeworld at %d %d (From %f %f)\n",newHomeX, newHomeY, homeX, homeY);
                        if (!fixupHomeworlds(newStars,newPlanets, localminx,localminy,localmaxx,localmaxy,
                                             newHomeX,newHomeY,count)) {
                            printf("Could not find %d th homeworld\n",count);
                        }

                    }
                    ++count;
                }
            }
        }
        {//go through and copy planets
            while ((freeStar=nextFreeStar(newStars,newPlanets,freeStar))!=-1) {
                //if (!isHomeworld(newStars[freeStar],newPlanets)) {freeStar should look for homeworlds
                //uSELESS STAR
                //strcpy(newStars[freeStar].name,"DANGER");
                printf("Found a free star\n");
                for (int p=0;p<5;++p) {
                    if (newStars[freeStar].planets[p]!=-1&&newStars[freeStar].planets[p]<NUM_PLANETS) {
                        if (newPlanets[newStars[freeStar].planets[p]].data[PARENT_STAR]==freeStar) {
                            freePlanets.push_back(newStars[freeStar].planets[p]);
                        }else {
                            if (newStars[freeStar].planets[p]!=0&&newStars[freeStar].planets[p]<NUM_PLANETS) {
                                printf("Odd syste in save file that's cross referenced\n");
                            }
                        }
                    }
                    newStars[freeStar].planets[p]=-1;
                }
                //}
                ++freeStar;
            } 
            printf("Orphan star size %d\n",(int)orphanStars.size());
            int orphanCount=orphanStars.size()==2?1:0;
            for (int index=0;index<NUM_STARS;++index) {
                Star &dst=newStars[index];
                if (starMap.find(index)!=starMap.end()) {
                    int destStarIndex = index;
                    
                    Star star = stars[starMap[index]];
                    for (int p=0;p<5;++p) {
                        if (dst.planets[p]!=-1&&dst.planets[p]<NUM_PLANETS) {
                            if (newPlanets[dst.planets[p]].data[PARENT_STAR]==destStarIndex) {
                                freePlanets.push_back(dst.planets[p]);//this will guarantee we pop these guys first to minimize change we can believe in
                            }else if (dst.planets[p]!=0&&dst.planets[p]<NUM_PLANETS) {
                                printf("Odder syste in save file that's cross referenced\n");
                            }
                            dst.planets[p]=-1;
                        }
                    }
                    bool didUltraRich=false;
                    bool isThisOrphan = orphanStars.find(destStarIndex)!=orphanStars.end();
                    if(isThisOrphan) {
                        dst.x=(minx+maxx)/2;
                        dst.y=(miny+maxy)/2;//put this in the middle of the map
                        if (orphanCount>0) {
                            double angle=0;
                            switch (orphanCount) {
                              case 1:
                                angle=0;
                                break;
                              case 2:
                                angle=M_PI;
                                break;
                              case 3:
                                angle=M_PI/2;
                                break;
                              case 4:
                                angle=3*M_PI/2;
                                break;
                              default:
                                angle = 3.1415926536*2*(.5+((orphanCount-5)/4.0));
                                break;
                            }
                            int del=(minx+maxx)/10;
                            int delx = (int)(del*cos(angle));
                            int dely = (int)(del*sin(angle));
                            dst.x+=delx;
                            dst.y+=dely;
                        }
                        ++orphanCount;
                    }
                    for (int p=0;p<5;++p) {
                            if (star.planets[p]!=-1&&star.planets[p]<NUM_PLANETS) {
                                if (freePlanets.size()) {
                                    int newPlanetIndex = freePlanets.back();
                                    freePlanets.pop_back();
                                    short originalOwner = newPlanets[newPlanetIndex].data[PARENT_STAR];
                                    if (originalOwner>=0&&originalOwner<NUM_STARS) {
                                        const Star &check = newStars[originalOwner];
                                        for (int pp=0;pp<5;++pp) {
                                            if (check.planets[pp]==newPlanetIndex&&check.planets[pp]!=-1) {
                                                printf("FATAL PLANETARY CROSS ALIGNMENT\n");
                                            }
                                        }
                                    }
                                    crossMapPlanetCopy(newPlanets[newPlanetIndex],planets[star.planets[p]]);
                                    
                                    if (isThisOrphan) {
                                        if (didUltraRich==false&&newPlanets[newPlanetIndex].data[TYPE]==0x3) {
                                            didUltraRich=true;
                                            if (NUM_STARS>50) {
                                                newPlanets[newPlanetIndex].data[MINERALS]=0x4;//set to ultra rich!!!!
                                                newPlanets[newPlanetIndex].data[G]=0x2;//set to heavy G!!!!
                                            }else {
                                                newPlanets[newPlanetIndex].data[MINERALS]=0x3;//set to rich!!!!
                                                newPlanets[newPlanetIndex].data[G]=0x1;//set to normal G!!!!
                                            }
                                            newPlanets[newPlanetIndex].data[PLANETSIZECLASS]=rand()%0x5;
                                            newPlanets[newPlanetIndex].data[ENVIRONMENT]=rand()%0xa;
                                        }else {
                                            newPlanets[newPlanetIndex].data[G]=0x1;//set to normal G!!!!
                                            
                                            if (NUM_STARS>50) {
                                                newPlanets[newPlanetIndex].data[MINERALS]=rand()%0x3+1;//not ultra rich
                                            }else {
                                                newPlanets[newPlanetIndex].data[MINERALS]=rand()%0x2+1;//not ultra poor
                                            }
                                            newPlanets[newPlanetIndex].data[PLANETSIZECLASS]=rand()%0x5;
                                            newPlanets[newPlanetIndex].data[ENVIRONMENT]=rand()%0xa;
                                        }
                                    }
                                    dst.planets[p]=newPlanetIndex;
                                    newPlanets[newPlanetIndex].data[PARENT_STAR]=destStarIndex;
                                }else {
                                    printf("Unable to allocate free planet for star %s\n",dst.name);
                                }
                            }
                        }
                }else {
                    printf("Could not locate source for %d\n",index);
                }
            }
            while (!freePlanets.empty()) {
                newPlanets[freePlanets.back()]=Planet();
                freePlanets.pop_back();
            }
            for (int index=0;index<NUM_STARS;++index) {
                bool error=false;
                for (int j=0;j<5;++j) {
                    int ind = newStars[index].planets[j];
                    if (ind!=-1&&ind<NUM_PLANETS) {
                        if (newPlanets[ind].data[PARENT_STAR]!=index) {
                            newStars[index].planets[j]=-1;
                            error=true;
                        }
                    }
                }
                if (error) {
                    if (starMap.find(index)!=starMap.end()) {
                        printf("MISMATCH ERROR in system %s index %d mapping to %s\n",newStars[index].name,index,stars[starMap[index]].name);
                    }else {
                        printf("MISMATCH ERROR in system %s index %d\n",newStars[index].name,index,stars[starMap[index]].name);
                    }
                }
            }
        }
        
    }
    free(data);
    if (argc>4) {//if we can write to a file
        output = fopen(argv[4],"w+b");//overwrite the output save file
        fwrite(writeData,1,writeFileSize,output);
        free(writeData);
        fseek(output,PLANET_OFFSET,SEEK_SET);
        for (int i=0;i<NUM_PLANETS;++i) {
            unsigned char planetData[PLANET_SIZE];
            newPlanets[i].writePlanet(planetData);
            fwrite(planetData,1,PLANET_SIZE,output);
        }
        fseek(output,STAR_OFFSET,SEEK_SET);
        for (int i=0;i<NUM_STARS;++i) {
            unsigned char starData[STAR_SIZE];
            newStars[i].writeStar(starData);
            fwrite(starData,1,STAR_SIZE,output);
        }
        fclose(output);
        return 0;
        char *args[2];
        args[0]=argv[0];
        args[1]=argv[4];
        return main(2,args);
    }else for (int i=0;i<NUM_STARS;++i) {
        newStars[i].printStar(newPlanets,newStars);
    }

}