Example #1
0
        private Metadata RequestMetadataInner(string path, bool async)
        {
            //System.Diagnostics.Debug.WriteLine("Loading metadata \"" + path + "\"...");

#if UNCOMPRESSED_CONTENT
            string pathAbsolute = PathOp.Combine(DualityApp.DataDirectory, "Metadata", path + ".res");
#else
            string pathAbsolute = PathOp.Combine(DualityApp.DataDirectory, "Main.dz", "Metadata", path + ".res");
#endif

            MetadataJson json;
            using (Stream s = FileOp.Open(pathAbsolute, FileAccessMode.Read)) {
                lock (jsonParser) {
                    json = jsonParser.Parse<MetadataJson>(s);
                }
            }

            Metadata metadata = new Metadata();
            metadata.Referenced = true;
            metadata.AsyncFinalizingRequired = async;

            // Pre-load graphics
            if (json.Animations != null) {
                metadata.Graphics = new Dictionary<string, GraphicResource>();

                foreach (KeyValuePair<string, MetadataJson.AnimationsSection> g in json.Animations) {
                    if (g.Value.Path == null) {
                        // No path provided, skip resource...
                        continue;
                    }

#if !THROW_ON_MISSING_RESOURCES
                    try {
#endif
                        bool isIndexed = (g.Value.Flags & 0x02) != 0x00;

                        ColorRgba color;
                        if (g.Value.ShaderColor == null || g.Value.ShaderColor.Count < 4) {
                            color = (isIndexed ? new ColorRgba(0, 255) : ColorRgba.White);
                        } else {
                            color = new ColorRgba((byte)g.Value.ShaderColor[0], (byte)g.Value.ShaderColor[1], (byte)g.Value.ShaderColor[2], (byte)g.Value.ShaderColor[3]);
                        }

                        GenericGraphicResource resBase = RequestGraphicResource(g.Value.Path, async);

                        // Create copy of generic resource
                        GraphicResource res;
                        if (async) {
                            res = GraphicResource.From(resBase, g.Value.Shader, color, isIndexed);
                        } else {
                            ContentRef<DrawTechnique> drawTechnique;
                            if (g.Value.Shader == null) {
                                drawTechnique = (isIndexed ? paletteNormal : basicNormal);
                            } else {
                                drawTechnique = RequestShader(g.Value.Shader);
                            }

                            res = GraphicResource.From(resBase, drawTechnique, color, isIndexed, paletteTexture);
                        }

                        res.FrameOffset = g.Value.FrameOffset;

                        string raw1, raw2; int raw3;
                        if ((raw1 = g.Value.FrameCount as string) != null && int.TryParse(raw1, out raw3)) {
                            res.FrameCount = raw3;
                        } else {
                            res.FrameCount -= res.FrameOffset;
                        }
                        if ((raw2 = g.Value.FrameRate as string) != null && int.TryParse(raw2, out raw3)) {
                            res.FrameDuration = (raw3 <= 0 ? -1 : (1f / raw3) * 5); // ToDo: I don't know...
                        }

                        res.OnlyOnce = (g.Value.Flags & 0x01) != 0x00;

                        if (g.Value.States != null) {
                            res.State = new HashSet<AnimState>();
                            for (int i = 0; i < g.Value.States.Count; i++) {
                                res.State.Add((AnimState)g.Value.States[i]);
                            }
                        }

                        metadata.Graphics[g.Key] = res;
#if !THROW_ON_MISSING_RESOURCES
                    } catch (Exception ex) {
#if !SERVER
                        Log.Write(LogType.Warning, "Can't load animation \"" + g.Key + "\" from metadata \"" + path + "\": " + ex.Message);
#endif
                    }
#endif
                    }
            }

#if !DISABLE_SOUND
            // Pre-load sounds
            if (json.Sounds != null) {
                metadata.Sounds = new Dictionary<string, SoundResource>();

                foreach (var sound in json.Sounds) {
                    if (sound.Value.Paths == null || sound.Value.Paths.Count == 0) {
                        // No path provided, skip resource...
                        continue;
                    }

#if !THROW_ON_MISSING_RESOURCES
                    try {
#endif
                        IList<string> filenames = sound.Value.Paths;
                        ContentRef<AudioData>[] data = new ContentRef<AudioData>[filenames.Count];
                        for (int i = 0; i < data.Length; i++) {
#if UNCOMPRESSED_CONTENT
                            using (Stream s = FileOp.Open(PathOp.Combine(DualityApp.DataDirectory, "Animations", filenames[i]), FileAccessMode.Read))
#else
                            using (Stream s = FileOp.Open(PathOp.Combine(DualityApp.DataDirectory, "Main.dz", "Animations", filenames[i]), FileAccessMode.Read))
#endif
                            {
                                data[i] = new AudioData(s);
                            }
                        }

                        SoundResource resource = new SoundResource();
                        resource.Sound = new Sound(data);
                        metadata.Sounds[sound.Key] = resource;
#if !THROW_ON_MISSING_RESOURCES
                    } catch (Exception ex) {
#if !SERVER
                        Log.Write(LogType.Warning, "Can't load sound \"" + sound.Key + "\" from metadata \"" + path + "\": " + ex.Message);
#endif
                    }
#endif
                    }
                }
#endif

            // Bounding Box
            if (json.BoundingBox != null && json.BoundingBox.Count == 2) {
                metadata.BoundingBox = new Point2(json.BoundingBox[0], json.BoundingBox[1]);
            }

            cachedMetadata[path] = metadata;

            // Request children
            if (json.Preload != null) {
                for (int i = 0; i < json.Preload.Count; i++) {
                    PreloadAsync(json.Preload[i]);
                }
            }

            return metadata;
        }
Example #2
0
        public GenericGraphicResource RequestGraphicResource(string path, bool async = false)
        {
            GenericGraphicResource resource;
            if (!cachedGraphics.TryGetValue(path, out resource)) {
#if UNCOMPRESSED_CONTENT
                string pathAbsolute = PathOp.Combine(DualityApp.DataDirectory, "Animations", path);
#else
                string pathAbsolute = PathOp.Combine(DualityApp.DataDirectory, "Main.dz", "Animations", path);
#endif

                SpriteJson json;
                using (Stream s = FileOp.Open(pathAbsolute + ".res", FileAccessMode.Read)) {
                    lock (jsonParser) {
                        json = jsonParser.Parse<SpriteJson>(s);
                    }
                }

                resource = new GenericGraphicResource {
                    FrameDimensions = new Point2(json.FrameSize[0], json.FrameSize[1]),
                    FrameConfiguration = new Point2(json.FrameConfiguration[0], json.FrameConfiguration[1]),
                    FrameDuration = (json.FrameRate <= 0 ? -1 : (1f / json.FrameRate) * 5),
                    FrameCount = json.FrameCount
                };

                if (json.Hotspot != null) {
                    resource.Hotspot = new Point2(json.Hotspot[0], json.Hotspot[1]);
                }

                if (json.Coldspot != null) {
                    resource.Coldspot = new Point2(json.Coldspot[0], json.Coldspot[1]);
                    resource.HasColdspot = true;
                }

                if (json.Gunspot != null) {
                    resource.Gunspot = new Point2(json.Gunspot[0], json.Gunspot[1]);
                }

                PixelData pixelData;
                using (Stream s = FileOp.Open(pathAbsolute, FileAccessMode.Read)) {
                    pixelData = new Png(s).GetPixelData();
                }

                // Use external palette
                if ((json.Flags & 0x01) != 0x00) {
                    ColorRgba[] palette = paletteTexture.Res.BasePixmap.Res.MainLayer.Data;

                    ColorRgba[] data = pixelData.Data;
#if !DISABLE_ASYNC
                    Parallel.ForEach(Partitioner.Create(0, data.Length), range => {
                        for (int i = range.Item1; i < range.Item2; i++) {
#else
                        for (int i = 0; i < data.Length; i++) {
#endif

                            int colorIdx = data[i].R;
                            data[i] = palette[colorIdx].WithAlpha(palette[colorIdx].A * data[i].A / (255f * 255f));

                            // ToDo: Pinball sprites have strange palette (1-3 indices down), CandionV looks bad, other levels look different
                        }
#if !DISABLE_ASYNC
                    });
#endif
                }

                bool linearSampling = (json.Flags & 0x02) != 0x00;

                Pixmap map = new Pixmap(pixelData);
                map.GenerateAnimAtlas(resource.FrameConfiguration.X, resource.FrameConfiguration.Y, 0);
                if (async) {
                    GenericGraphicResourceAsyncFinalize asyncFinalize = new GenericGraphicResourceAsyncFinalize();
                    asyncFinalize.TextureMap = map;

#if !DISABLE_NORMAL_MAPPING
                    string filenameNormal = pathAbsolute.Replace(".png", ".n.png");
                    if (FileOp.Exists(filenameNormal)) {
                        using (Stream s = FileOp.Open(filenameNormal, FileAccessMode.Read)) {
                            asyncFinalize.TextureNormalMap = new Pixmap(new Png(s).GetPixelData());
                        }
                    } else {
                        resource.TextureNormal = defaultNormalMap;
                    }
#else
                    resource.TextureNormal = defaultNormalMap;
#endif

                    asyncFinalize.LinearSampling = linearSampling;

                    resource.AsyncFinalize = asyncFinalize;
                } else {
                    TextureMagFilter magFilter; TextureMinFilter minFilter;
                    if (linearSampling) {
                        magFilter = TextureMagFilter.Linear;
                        minFilter = TextureMinFilter.LinearMipmapLinear;
                    } else {
                        magFilter = TextureMagFilter.Nearest;
                        minFilter = TextureMinFilter.Nearest;
                    }

                    resource.Texture = new Texture(map, TextureSizeMode.NonPowerOfTwo,
                        magFilter, minFilter, json.TextureWrap, json.TextureWrap);

#if !DISABLE_NORMAL_MAPPING
                    string filenameNormal = pathAbsolute.Replace(".png", ".n.png");
                    if (FileOp.Exists(filenameNormal)) {
                        using (Stream s = FileOp.Open(filenameNormal, FileAccessMode.Read)) {
                            pixelData = new Png(s).GetPixelData();
                        }

                        resource.TextureNormal = new Texture(new Pixmap(pixelData), TextureSizeMode.NonPowerOfTwo,
                            magFilter, minFilter, json.TextureWrap, json.TextureWrap);

                        resource.TextureNormal.Res.DetachSource();
                    } else {
                        resource.TextureNormal = defaultNormalMap;
                    }
#else
                    resource.TextureNormal = defaultNormalMap;
#endif
                }

                cachedGraphics[path] = resource;
            }

            resource.Referenced = true;
            return resource;
        }
Example #3
0
        private void FinalizeAsyncLoadedResources(Metadata metadata)
        {
            if (metadata.Graphics != null)
            {
                foreach (var pair in metadata.Graphics)
                {
                    GraphicResource        res     = pair.Value;
                    GenericGraphicResource resBase = res.Base;
                    if (resBase.AsyncFinalize != null)
                    {
                        TextureMagFilter magFilter; TextureMinFilter minFilter;
                        if (resBase.AsyncFinalize.LinearSampling)
                        {
                            magFilter = TextureMagFilter.Linear;
                            minFilter = TextureMinFilter.LinearMipmapLinear;
                        }
                        else
                        {
                            magFilter = TextureMagFilter.Nearest;
                            minFilter = TextureMinFilter.Nearest;
                        }

                        resBase.Texture = new Texture(resBase.AsyncFinalize.TextureMap, TextureSizeMode.NonPowerOfTwo,
                                                      magFilter, minFilter, resBase.AsyncFinalize.TextureWrap, resBase.AsyncFinalize.TextureWrap);

                        if (resBase.AsyncFinalize.TextureNormalMap != null)
                        {
                            resBase.TextureNormal = new Texture(resBase.AsyncFinalize.TextureNormalMap, TextureSizeMode.NonPowerOfTwo,
                                                                magFilter, minFilter, resBase.AsyncFinalize.TextureWrap, resBase.AsyncFinalize.TextureWrap);
                        }

                        resBase.AsyncFinalize = null;
                    }

                    if (res.AsyncFinalize != null)
                    {
                        ContentRef <DrawTechnique> drawTechnique;
                        if (res.AsyncFinalize.Shader == null)
                        {
                            drawTechnique = (res.AsyncFinalize.BindPaletteToMaterial ? paletteNormal : basicNormal);
                        }
                        else
                        {
                            drawTechnique = RequestShader(res.AsyncFinalize.Shader);
                        }

                        Material material = new Material(drawTechnique, res.AsyncFinalize.Color);

                        material.SetTexture("mainTex", resBase.Texture);
                        if (resBase.TextureNormal != null)
                        {
                            material.SetTexture("normalTex", resBase.TextureNormal);
                        }

                        if (res.AsyncFinalize.BindPaletteToMaterial)
                        {
                            material.SetTexture("paletteTex", paletteTexture);
                        }

                        res.Material = material;

                        res.AsyncFinalize = null;
                    }
                }
            }
        }