예제 #1
0
        static void G_LoadGameData()
        {
            int   length;
            Int32 i, j;
            byte  rtemp;

            //For records
            UInt32 recscore;
            UInt32 rectime;
            UInt16 recrings;

            byte  recmares;
            Int32 curmare;

            // Clear things so previously read gamedata doesn't transfer
            // to new gamedata
            G_ClearRecords();             // main and nights records
            M_ClearSecrets();             // emblems, unlocks, maps visited, etc
            totalplaytime = 0;            // total play time (separate from all)
            byte[] bytes;
            try
            {
                bytes = File.ReadAllBytes(gamedatafilename);
            }
            catch (IOException e)
            {
                Console.WriteLine("{0}: {1}", e.GetType().Name, e.Message);
                return;
            }

            length = bytes.Length;
            if (length == 0)             // Aw, no game data. Their loss!
            {
                return;
            }

            SaveBuffer save_p = new SaveBuffer(bytes);

            // Version check
            if (save_p.READUINT32() != 0xFCAFE211)
            {
                Console.WriteLine("Game data is from another version of SRB2.\nDelete {0} and try again.", gamedatafilename);
            }

            totalplaytime = save_p.READUINT32();

            modified = save_p.READUINT8();

            // Aha! Someone's been screwing with the save file!
            if ((modified == 1))
            {
                Console.WriteLine("Warning, the game data is modified. If this gamedata doesn't belong to a mod, you're screwed.");
            }
            else if (modified != 1 && modified != 0)
            {
                goto datacorrupt;
            }

            // TODO put another cipher on these things? meh, I don't care...
            for (i = 0; i < NUMMAPS; i++)
            {
                if ((mapvisited[i] = save_p.READUINT8()) > MV_MAX)
                {
                    goto datacorrupt;
                }
            }

            // To save space, use one bit per collected/achieved/unlocked flag
            for (i = 0; i < MAXEMBLEMS;)
            {
                rtemp = save_p.READUINT8();
                for (j = 0; j < 8 && j + i < MAXEMBLEMS; ++j)
                {
                    emblemlocations[j + i] = (byte)((rtemp >> j) & 1);
                }
                i += j;
            }
            for (i = 0; i < MAXEXTRAEMBLEMS;)
            {
                rtemp = save_p.READUINT8();
                for (j = 0; j < 8 && j + i < MAXEXTRAEMBLEMS; ++j)
                {
                    extraemblems[j + i] = (byte)((rtemp >> j) & 1);
                }
                i += j;
            }
            for (i = 0; i < MAXUNLOCKABLES;)
            {
                rtemp = save_p.READUINT8();
                for (j = 0; j < 8 && j + i < MAXUNLOCKABLES; ++j)
                {
                    unlockables[j + i] = (byte)((rtemp >> j) & 1);
                }
                i += j;
            }
            for (i = 0; i < MAXCONDITIONSETS;)
            {
                rtemp = save_p.READUINT8();
                for (j = 0; j < 8 && j + i < MAXCONDITIONSETS; ++j)
                {
                    conditionSets[j + i] = (byte)((rtemp >> j) & 1);
                }
                i += j;
            }

            timesBeaten             = save_p.READUINT32();
            timesBeatenWithEmeralds = save_p.READUINT32();
            timesBeatenUltimate     = save_p.READUINT32();

            // Main records
            for (i = 0; i < NUMMAPS; ++i)
            {
                recscore = save_p.READUINT32();
                rectime  = save_p.READUINT32();
                recrings = save_p.READUINT16();
                //save_p++; // compat
                save_p.READUINT8();

                if (recrings > 10000 || recscore > MAXSCORE)
                {
                    goto datacorrupt;
                }

                if (mainrecords[i] == null)
                {
                    mainrecords[i] = new Record();
                }
                mainrecords[i].score = recscore;
                mainrecords[i].time  = rectime;
                mainrecords[i].rings = recrings;
            }

            // Nights records
            for (i = 0; i < NUMMAPS; ++i)
            {
                if (nightsrecords[i] == null)
                {
                    nightsrecords[i] = new NightsRecord();
                }
                if ((recmares = save_p.READUINT8()) == 0)
                {
                    continue;
                }


                nightsrecords[i].mares = new Mare[recmares + 1];

                for (curmare = 0; curmare < (recmares + 1); ++curmare)
                {
                    if (nightsrecords[i].mares[curmare] == null)
                    {
                        nightsrecords[i].mares[curmare] = new Mare();
                    }
                    nightsrecords[i].mares[curmare].score = save_p.READUINT32();
                    nightsrecords[i].mares[curmare].grade = save_p.READUINT8();
                    nightsrecords[i].mares[curmare].time  = save_p.READUINT32();

                    if (nightsrecords[i].mares[curmare].grade > GRADE_S)
                    {
                        goto datacorrupt;
                    }
                }

                nightsrecords[i].nummares = recmares;
            }

            save_p = null;
            return;

            // Landing point for corrupt gamedata
datacorrupt:
            {
                Console.WriteLine("Corrupt game data file.\nDelete {0} and try again.", gamedatafilename);
            }
        }
예제 #2
0
        static void G_SaveGameData()
        {
            int   length;
            Int32 i, j;
            byte  btemp;

            Int32 curmare;

            SaveBuffer saveBuffer = new SaveBuffer();

            // Version test
            saveBuffer.WRITEUINT32(0xFCAFE211);

            saveBuffer.WRITEUINT32(totalplaytime);

            btemp = (byte)modified;
            saveBuffer.WRITEUINT8(btemp);

            // TODO put another cipher on these things? meh, I don't care...
            for (i = 0; i < NUMMAPS; i++)
            {
                saveBuffer.WRITEUINT8((byte)(mapvisited[i] & MV_MAX));
            }

            // To save space, use one bit per collected/achieved/unlocked flag
            for (i = 0; i < MAXEMBLEMS;)
            {
                btemp = 0;
                for (j = 0; j < 8 && j + i < MAXEMBLEMS; ++j)
                {
                    btemp |= (byte)(emblemlocations[j + i] << j);
                }
                saveBuffer.WRITEUINT8(btemp);
                i += j;
            }
            for (i = 0; i < MAXEXTRAEMBLEMS;)
            {
                btemp = 0;
                for (j = 0; j < 8 && j + i < MAXEXTRAEMBLEMS; ++j)
                {
                    btemp |= (byte)(extraemblems[j + i] << j);
                }
                saveBuffer.WRITEUINT8(btemp);
                i += j;
            }
            for (i = 0; i < MAXUNLOCKABLES;)
            {
                btemp = 0;
                for (j = 0; j < 8 && j + i < MAXUNLOCKABLES; ++j)
                {
                    btemp |= (byte)(unlockables[j + i] << j);
                }
                saveBuffer.WRITEUINT8(btemp);
                i += j;
            }
            for (i = 0; i < MAXCONDITIONSETS;)
            {
                btemp = 0;
                for (j = 0; j < 8 && j + i < MAXCONDITIONSETS; ++j)
                {
                    btemp |= (byte)(conditionSets[j + i] << j);
                }
                saveBuffer.WRITEUINT8(btemp);
                i += j;
            }

            saveBuffer.WRITEUINT32(timesBeaten);
            saveBuffer.WRITEUINT32(timesBeatenWithEmeralds);
            saveBuffer.WRITEUINT32(timesBeatenUltimate);

            // Main records
            for (i = 0; i < NUMMAPS; i++)
            {
                if (mainrecords[i] != null)
                {
                    saveBuffer.WRITEUINT32(mainrecords[i].score);
                    saveBuffer.WRITEUINT32(mainrecords[i].time);
                    saveBuffer.WRITEUINT16(mainrecords[i].rings);
                }
                else
                {
                    saveBuffer.WRITEUINT32(0);
                    saveBuffer.WRITEUINT32(0);
                    saveBuffer.WRITEUINT16(0);
                }
                saveBuffer.WRITEUINT8(0);                 // compat
            }

            // NiGHTS records
            for (i = 0; i < NUMMAPS; i++)
            {
                if (nightsrecords[i] == null || nightsrecords[i].nummares == 0)
                {
                    saveBuffer.WRITEUINT8(0);
                    continue;
                }

                saveBuffer.WRITEUINT8(nightsrecords[i].nummares);

                for (curmare = 0; curmare < (nightsrecords[i].nummares + 1); ++curmare)
                {
                    saveBuffer.WRITEUINT32(nightsrecords[i].mares[curmare].score);
                    saveBuffer.WRITEUINT8(nightsrecords[i].mares[curmare].grade);
                    saveBuffer.WRITEUINT32(nightsrecords[i].mares[curmare].time);
                }
            }
            length = saveBuffer.Length;

            byte[] bytes = new byte[length];
            bytes = saveBuffer.save_p.SkipLast(saveBuffer.save_p.Length - length).ToArray();
            using (BinaryWriter writer = new BinaryWriter(File.Open(gamedatafilename, FileMode.Create)))
            {
                writer.Write(bytes);
            }
        }