public static byte[] CreateExePackedImage()
        {
            var egaCmn  = Resource.Load("EGA.CMN");
            var mcgaCod = Resource.Load("MCGA.COD");
            var mcgaDif = Resource.Load("MCGA.DIF");
            var mcgaHdr = Resource.Load("MCGA.HDR");

            var bytesInLastPage    = ReadUshortAt(mcgaHdr, 2);
            var pagesInExecutable  = ReadUshortAt(mcgaHdr, 4);
            var paragraphsInHeader = ReadUshortAt(mcgaHdr, 8);

            int executableSize = pagesInExecutable << 9;

            if (bytesInLastPage > 0)
            {
                executableSize += bytesInLastPage - 0x1f0;
            }

            int headerSize = paragraphsInHeader << 4;

            var executableImage = new byte[executableSize];

            mcgaHdr.CopyTo(executableImage, 0);
            egaCmn.CopyTo(executableImage, headerSize);
            mcgaCod.CopyTo(executableImage, headerSize + egaCmn.Length);

            var difStream   = new ReadStream(mcgaDif);
            int writeOffset = headerSize - 1;

            while (true)
            {
                var jump = (ushort)difStream.ReadShort();
                if (jump == 0)
                {
                    break;
                }
                writeOffset += jump & 0x7fff;
                executableImage[writeOffset]     = difStream.ReadByte();
                executableImage[writeOffset + 1] = difStream.ReadByte();
                if ((jump & 0x8000) != 0)
                {
                    executableImage[writeOffset + 2] = difStream.ReadByte();
                    executableImage[writeOffset + 3] = difStream.ReadByte();
                }
            }

            return(executableImage);
        }
예제 #2
0
        public static IEnumerable <ProgressStatus> ImportMeshes()
        {
            var   importSettings = FindOrCreateAssetAtPath <ImportSettings>(ImportSettingsPath);
            var   carCodes       = GetCarCodes();
            float progress       = 0;
            float progressStep   = 1f / carCodes.Count;

            Directory.CreateDirectory("Assets/Resources/Cars/InGameMeshes");
            Directory.CreateDirectory("Assets/Resources/Cars/ShowRoomMeshes");
            Directory.CreateDirectory("Assets/Resources/Cars/CollisionMeshes");
            Directory.CreateDirectory("Assets/Resources/Terrain");

            foreach (var carCode in carCodes)
            {
                var dataResource = Resource.ReadResourceMap(Resource.Load("CAR" + carCode + ".RES"));
                var carName      = new ReadStream(dataResource["gnam"]).ReadString().Replace('/', '-');
                yield return(new ProgressStatus("Importing cars (" + carName + ")", progress));

                progress += progressStep;
                var modelResource  = Resource.ReadResourceMap(Resource.Load("ST" + carCode + ".P3S"));
                var inGameModel    = new Model(new ReadStream(modelResource["car1"]));
                var showRoomModel  = new Model(new ReadStream(modelResource["car0"]));
                var collisionModel = new Model(new ReadStream(modelResource["car2"]));
                var inGameMesh     = inGameModel.ToMesh(importSettings);
                var showRoomMesh   = showRoomModel.ToMesh(importSettings);
                var collisionMesh  = collisionModel.ToMesh(importSettings);
                AssetDatabase.CreateAsset(inGameMesh, "Assets/Resources/Cars/InGameMeshes/" + carName + ".asset");
                AssetDatabase.CreateAsset(showRoomMesh, "Assets/Resources/Cars/ShowRoomMeshes/" + carName + ".asset");
                AssetDatabase.CreateAsset(collisionMesh, "Assets/Resources/Cars/CollisionMeshes/" + carName + ".asset");
            }

            var resourceMap1 = Resource.ReadResourceMap(Resource.Load("GAME1.P3S"));
            var resourceMap2 = Resource.ReadResourceMap(Resource.Load("GAME2.P3S"));

            progress     = 0;
            progressStep = 1f / (resourceMap1.Count + resourceMap2.Count);
            foreach (var resource in resourceMap1.Concat(resourceMap2))
            {
                yield return(new ProgressStatus("Importing tiles (" + resource.Key + ")", progress));

                progress += progressStep;
                var mesh = new Model(new ReadStream(resource.Value)).ToMesh(importSettings);
                AssetDatabase.CreateAsset(mesh, "Assets/Resources/Terrain/" + resource.Key + ".asset");
            }

            yield return(null);
        }
예제 #3
0
        public Primitive(int paintJobCount, ReadStream input)
        {
            var primitiveCode = input.ReadByte();
            int indexCount    = primitiveCode;

            switch (primitiveCode)
            {
            case 1:
                Type = PrimitiveType.Particle;
                break;

            case 2:
                Type = PrimitiveType.Line;
                break;

            case 11:
                Type       = PrimitiveType.Sphere;
                indexCount = 2;
                break;

            case 12:
                Type       = PrimitiveType.Wheel;
                indexCount = 6;
                break;

            default:
                if (3 <= primitiveCode && primitiveCode <= 10)
                {
                    Type = PrimitiveType.Polygon;
                }
                else
                {
                    Type       = PrimitiveType.Ignored;
                    indexCount = 0;
                }
                break;
            }

            var flags = input.ReadByte();

            IsTwoSided = (flags & 1) != 0;
            HasZBias   = (flags & 2) != 0;

            Materials = input.ReadByteArray(paintJobCount);
            Indices   = input.ReadByteArray(indexCount);
        }
예제 #4
0
        public static void GenerateTileMapping()
        {
            const int baseAddress      = 0xabcc;
            const int nameBaseAddress  = 0x9584;
            const int nameSize         = 5;
            const int shapeBaseAddress = 0x764c;
            const int shapeSize        = 22;

            var importSettings = FindOrCreateAssetAtPath <ImportSettings>(ImportSettingsPath);

            UnpackCode();

            importSettings.tileDescriptions = new List <TileDescription>();
            for (int i = 0; i < 0xf7; i++)
            {
                var tileDescription = new TileDescription();
                int structAddress   = baseAddress + i * 14;

                tileDescription.orientation    = unpackedCode[structAddress + 3] & 0x03;
                tileDescription.otherPartIndex = unpackedCode[structAddress + 8];
                tileDescription.materialIndex  = unpackedCode[structAddress + 9];

                int sizeFlags = unpackedCode[structAddress + 11];
                tileDescription.xSize = (sizeFlags & 2) == 0 ? 1 : 2;
                tileDescription.ySize = (sizeFlags & 1) == 0 ? 1 : 2;

                int    shapeAddress = unpackedCode[structAddress + 4] + unpackedCode[structAddress + 5] * 0x100;
                int    nameOffset   = (shapeAddress - shapeBaseAddress) * nameSize / shapeSize + nameBaseAddress;
                string meshName     = new ReadStream(unpackedCode, nameOffset).ReadFixedLengthString(4);
                if (!meshName.All(c => c > 0x20 && c < 0x80))
                {
                    meshName = "";
                }

                tileDescription.meshName = meshName;
                tileDescription.name     = string.Format("{0} ({1})", i, tileDescription.Displayname);

                importSettings.tileDescriptions.Add(tileDescription);
            }
        }
예제 #5
0
        public Model(ReadStream input)
        {
            var vertexCount    = input.ReadByte();
            var primitiveCount = input.ReadByte();

            PaintJobCount = input.ReadByte();
            input.Skip(1);

            Vertices = new Vector3[vertexCount];
            for (int i = 0; i < vertexCount; i++)
            {
                Vertices[i] = input.ReadVertex();
            }

            input.Skip(8 * primitiveCount);

            Primitives = new Primitive[primitiveCount];
            for (int i = 0; i < primitiveCount; i++)
            {
                Primitives[i] = new Primitive(PaintJobCount, input);
            }
        }
예제 #6
0
        public static Dictionary <string, byte[]> ReadResourceMap(byte[] rawResource)
        {
            var result = new Dictionary <string, byte[]>();
            var input  = new ReadStream(rawResource);

            input.Skip(4);
            var resourceCount = input.ReadShort();

            var ids = new string[resourceCount];

            for (int i = 0; i < resourceCount; i++)
            {
                ids[i] = input.ReadFixedLengthString(4);
            }

            var sortedIds = new SortedDictionary <int, string>();

            for (int i = 0; i < resourceCount; i++)
            {
                sortedIds[input.ReadInt()] = ids[i];
            }

            var data          = new ReadBuffer(rawResource).Drop(6 + 8 * resourceCount);
            var sortedOffsets = new List <int>(sortedIds.Keys);

            sortedOffsets.Add(data.Length);

            for (int i = 0; i < resourceCount; i++)
            {
                var startOffset = sortedOffsets[i];
                var endOffset   = sortedOffsets[i + 1];
                result[sortedIds[startOffset]] = data.Slice(startOffset, endOffset - startOffset).ToArray();
            }

            return(result);
        }