예제 #1
0
		void LoadMod(MiniYaml yaml, string path = null, bool forceRegistration = false)
		{
			var mod = FieldLoader.Load<ExternalMod>(yaml);

			if (sheetBuilder != null)
			{
				var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon");
				if (iconNode != null && !string.IsNullOrEmpty(iconNode.Value.Value))
					using (var stream = new MemoryStream(Convert.FromBase64String(iconNode.Value.Value)))
						mod.Icon = sheetBuilder.Add(new Png(stream));

				var icon2xNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon2x");
				if (icon2xNode != null && !string.IsNullOrEmpty(icon2xNode.Value.Value))
					using (var stream = new MemoryStream(Convert.FromBase64String(icon2xNode.Value.Value)))
						mod.Icon2x = sheetBuilder.Add(new Png(stream), 1f / 2);

				var icon3xNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon3x");
				if (icon3xNode != null && !string.IsNullOrEmpty(icon3xNode.Value.Value))
					using (var stream = new MemoryStream(Convert.FromBase64String(icon3xNode.Value.Value)))
						mod.Icon3x = sheetBuilder.Add(new Png(stream), 1f / 3);
			}

			// Avoid possibly overwriting a valid mod with an obviously bogus one
			var key = ExternalMod.MakeKey(mod);
			if ((forceRegistration || File.Exists(mod.LaunchPath)) && (path == null || Path.GetFileNameWithoutExtension(path) == key))
				mods[key] = mod;
		}
예제 #2
0
        public override void Init(ModData modData, Dictionary <string, string> info)
        {
            base.Init(modData, info);

            // Avoid standard loading mechanisms so we
            // can display the loadscreen as early as possible
            r = Game.Renderer;
            if (r == null)
            {
                return;
            }

            if (info.ContainsKey("Text"))
            {
                messages = info["Text"].Split(',');
            }

            if (info.ContainsKey("Palette"))
            {
                using (var stream = modData.DefaultFileSystem.Open(info["Palette"]))
                {
                    palette = new ImmutablePalette(stream, new int[] { });
                }

                hardwarePalette = new HardwarePalette();
                hardwarePalette.AddPalette("loadscreen", palette, false);
                hardwarePalette.Initialize();
                r.SetPalette(hardwarePalette);
            }

            if (info.ContainsKey("Image"))
            {
                using (var stream = modData.DefaultFileSystem.Open(info["Image"]))
                {
                    CpsD2Loader loader = new CpsD2Loader();
                    if (!loader.TryParseSprite(stream, out frames))
                    {
                        return;
                    }
                }

                if (frames.Length == 0)
                {
                    return;
                }

                sheetBuilder = new SheetBuilder(SheetType.Indexed, 512);
                logo         = sheetBuilder.Add(frames[0]);

                logoPos = new float2((r.Resolution.Width - logo.Size.X) / 2, (r.Resolution.Height - logo.Size.Y) / 2);
            }
        }
예제 #3
0
        void LoadMod(MiniYaml yaml)
        {
            var mod      = FieldLoader.Load <ExternalMod>(yaml);
            var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon");

            if (iconNode != null && !string.IsNullOrEmpty(iconNode.Value.Value))
            {
                using (var stream = new MemoryStream(Convert.FromBase64String(iconNode.Value.Value)))
                    using (var bitmap = new Bitmap(stream))
                        mod.Icon = sheetBuilder.Add(bitmap);
            }

            mods.Add(ExternalMod.MakeKey(mod), mod);
        }
예제 #4
0
        Manifest LoadMod(string id, string path)
        {
            IReadOnlyPackage package = null;

            try
            {
                if (Directory.Exists(path))
                {
                    package = new Folder(path);
                }
                else
                {
                    try
                    {
                        using (var fileStream = File.OpenRead(path))
                            package = new ZipFile(fileStream, path);
                    }
                    catch
                    {
                        throw new InvalidDataException(path + " is not a valid mod package");
                    }
                }

                if (!package.Contains("mod.yaml"))
                {
                    throw new InvalidDataException(path + " is not a valid mod package");
                }

                using (var stream = package.GetStream("icon.png"))
                    if (stream != null)
                    {
                        using (var bitmap = new Bitmap(stream))
                            icons[id] = sheetBuilder.Add(bitmap);
                    }

                // Mods in the support directory and oramod packages (which are listed later
                // in the CandidateMods list) override mods in the main install.
                return(new Manifest(id, package));
            }
            catch (Exception)
            {
                if (package != null)
                {
                    package.Dispose();
                }

                return(null);
            }
        }
예제 #5
0
        void LoadAsyncInternal()
        {
            Log.Write("debug", "MapCache.LoadAsyncInternal started");

            // Milliseconds to wait on one loop when nothing to do
            var emptyDelay = 50;
            // Keep the thread alive for at least 5 seconds after the last minimap generation
            var maxKeepAlive = 5000 / emptyDelay;
            var keepAlive    = maxKeepAlive;

            while (keepAlive-- > 0)
            {
                List <MapPreview> todo;
                lock (syncRoot)
                {
                    todo = generateMinimap.Where(p => p.GetMinimap() == null).ToList();
                    generateMinimap.Clear();
                }
                if (todo.Count == 0)
                {
                    Thread.Sleep(emptyDelay);
                    continue;
                }
                else
                {
                    keepAlive = maxKeepAlive;
                }

                // Render the minimap into the shared sheet
                foreach (var p in todo)
                {
                    // The rendering is thread safe because it only reads from the passed instances and writes to a new bitmap
                    var bitmap = p.CustomPreview ?? Minimap.RenderMapPreview(modData.DefaultRules.TileSets[p.Map.Tileset], p.Map, modData.DefaultRules, true);
                    // Note: this is not generally thread-safe, but it works here because:
                    //   (a) This worker is the only thread writing to this sheet
                    //   (b) The main thread is the only thread reading this sheet
                    //   (c) The sheet is marked dirty after the write is completed,
                    //       which causes the main thread to copy this to the texture during
                    //       the next render cycle.
                    //   (d) Any partially written bytes from the next minimap is in an
                    //       unallocated area, and will be committed in the next cycle.
                    p.SetMinimap(sheetBuilder.Add(bitmap));

                    // Yuck... But this helps the UI Jank when opening the map selector significantly.
                    Thread.Sleep(Environment.ProcessorCount == 1 ? 25 : 5);
                }
            }
            Log.Write("debug", "MapCache.LoadAsyncInternal ended");
        }
        Manifest LoadMod(string id, string path)
        {
            IReadOnlyPackage package = null;

            try
            {
                if (!Directory.Exists(path))
                {
                    Log.Write("debug", path + " is not a valid mod package");
                    return(null);
                }

                package = new Folder(path);
                if (package.Contains("mod.yaml"))
                {
                    var manifest = new Manifest(id, package);

                    if (package.Contains("icon.png"))
                    {
                        using (var stream = package.GetStream("icon.png"))
                            if (stream != null)
                            {
                                using (var bitmap = new Bitmap(stream))
                                    icons[id] = sheetBuilder.Add(bitmap);
                            }
                    }
                    else if (!manifest.Metadata.Hidden)
                    {
                        Log.Write("debug", "Mod '{0}' is missing 'icon.png'.".F(path));
                    }

                    return(manifest);
                }
            }
            catch (Exception e)
            {
                Log.Write("debug", "Load mod '{0}': {1}".F(path, e));
            }

            if (package != null)
            {
                package.Dispose();
            }

            return(null);
        }
예제 #7
0
        static Sheet SpriteFrameToSheet(ISpriteFrame frame, PaletteReference p)
        {
            var          size         = Exts.NextPowerOf2(Math.Max(frame.FrameSize.Width, frame.FrameSize.Height));
            SheetBuilder sheetBuilder = new SheetBuilder(SheetType.BGRA, size);

            byte[] data;
            if (frame.Type == SpriteFrameType.Indexed)
            {
                data = IndexedSpriteFrameToData(frame, p);
            }
            else
            {
                data = frame.Data;
            }

            var sprite = sheetBuilder.Add(data, frame.FrameSize);

            return(sprite.Sheet);
        }
예제 #8
0
        void LoadMod(MiniYaml yaml, string path = null)
        {
            var mod      = FieldLoader.Load <ExternalMod>(yaml);
            var iconNode = yaml.Nodes.FirstOrDefault(n => n.Key == "Icon");

            if (iconNode != null && !string.IsNullOrEmpty(iconNode.Value.Value))
            {
                using (var stream = new MemoryStream(Convert.FromBase64String(iconNode.Value.Value)))
                    using (var bitmap = new Bitmap(stream))
                        mod.Icon = sheetBuilder.Add(bitmap);
            }

            // Avoid possibly overwriting a valid mod with an obviously bogus one
            var key = ExternalMod.MakeKey(mod);

            if (File.Exists(mod.LaunchPath) && (path == null || Path.GetFileNameWithoutExtension(path) == key))
            {
                mods[key] = mod;
            }
        }
예제 #9
0
        void LoadAsyncInternal()
        {
            for (;;)
            {
                MapPreview p;
                lock (syncRoot)
                {
                    if (generateMinimap.Count == 0)
                    {
                        break;
                    }

                    p = generateMinimap.Peek();

                    // Preview already exists
                    if (p.Minimap != null)
                    {
                        generateMinimap.Dequeue();
                        continue;
                    }
                }

                // Render the minimap into the shared sheet
                // Note: this is not generally thread-safe, but it works here because:
                //   (a) This worker is the only thread writing to this sheet
                //   (b) The main thread is the only thread reading this sheet
                //   (c) The sheet is marked dirty after the write is completed,
                //       which causes the main thread to copy this to the texture during
                //       the next render cycle.
                //   (d) Any partially written bytes from the next minimap is in an
                //       unallocated area, and will be committed in the next cycle.
                var bitmap = p.CustomPreview ?? Minimap.RenderMapPreview(modData.DefaultRules.TileSets[p.Map.Tileset], p.Map, modData.DefaultRules, true);
                p.Minimap = sheetBuilder.Add(bitmap);

                lock (syncRoot)
                    generateMinimap.Dequeue();

                // Yuck... But this helps the UI Jank when opening the map selector significantly.
                Thread.Sleep(50);
            }
        }
예제 #10
0
        Manifest LoadMod(string id, string path)
        {
            IReadOnlyPackage package = null;

            try
            {
                if (!Directory.Exists(path))
                {
                    throw new InvalidDataException(path + " is not a valid mod package");
                }

                package = new Folder(path);
                if (!package.Contains("mod.yaml"))
                {
                    throw new InvalidDataException(path + " is not a valid mod package");
                }

                using (var stream = package.GetStream("icon.png"))
                    if (stream != null)
                    {
                        using (var bitmap = new Bitmap(stream))
                            icons[id] = sheetBuilder.Add(bitmap);
                    }

                return(new Manifest(id, package));
            }
            catch (Exception)
            {
                if (package != null)
                {
                    package.Dispose();
                }

                return(null);
            }
        }
예제 #11
0
        public override void Draw()
        {
            if (video == null)
            {
                return;
            }

            var sheetBuilder = new SheetBuilder(SheetType.Indexed, 512);
            var videoSprite  = sheetBuilder.Add(video.Frame);

            Game.Renderer.EnableScissor(RenderBounds);
            Game.Renderer.RgbaColorRenderer.FillRect(
                new float2(RenderBounds.Left, RenderBounds.Top),
                new float2(RenderBounds.Right, RenderBounds.Bottom), OpenRA.Primitives.Color.Black);
            Game.Renderer.DisableScissor();

            Game.Renderer.SpriteRenderer.DrawSprite(videoSprite, videoOrigin, pr, videoSize);

/*
 *                      Game.Renderer.RgbaSpriteRenderer.DrawSprite(
 *                              videoSprite,
 *                              videoOrigin,
 *                              videoSize);
 */

            if (!stopped && !paused)
            {
                if (video.CurrentFrame >= video.Length - 1)
                {
                    Stop();
                    return;
                }

                video.AdvanceFrame();
            }
        }
예제 #12
0
        public ModBrowserLogic(Widget widget)
        {
            var panel      = widget;
            var loadButton = panel.Get <ButtonWidget>("LOAD_BUTTON");

            loadButton.OnClick    = () => LoadMod(selectedMod);
            loadButton.IsDisabled = () => selectedMod.Id == Game.ModData.Manifest.Mod.Id;

            panel.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            modList     = panel.Get("MOD_LIST");
            modTemplate = modList.Get <ButtonWidget>("MOD_TEMPLATE");

            panel.Get <LabelWidget>("MOD_DESC").GetText    = () => selectedDescription;
            panel.Get <LabelWidget>("MOD_TITLE").GetText   = () => selectedMod.Title;
            panel.Get <LabelWidget>("MOD_AUTHOR").GetText  = () => selectedAuthor;
            panel.Get <LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Version;

            var prevMod = panel.Get <ButtonWidget>("PREV_MOD");

            prevMod.OnClick   = () => { modOffset -= 1; RebuildModList(); };
            prevMod.IsVisible = () => modOffset > 0;

            var nextMod = panel.Get <ButtonWidget>("NEXT_MOD");

            nextMod.OnClick   = () => { modOffset += 1; RebuildModList(); };
            nextMod.IsVisible = () => modOffset + 5 < allMods.Length;

            panel.Get <RGBASpriteWidget>("MOD_PREVIEW").GetSprite = () =>
            {
                Sprite ret = null;
                previews.TryGetValue(selectedMod.Id, out ret);
                return(ret);
            };

            sheetBuilder = new SheetBuilder(SheetType.BGRA);
            allMods      = ModMetadata.AllMods.Values.Where(m => !m.Hidden)
                           .OrderBy(m => m.Title)
                           .ToArray();

            // Load preview images, and eat any errors
            foreach (var mod in allMods)
            {
                try
                {
                    using (var preview = new Bitmap(Platform.ResolvePath(".", "mods", mod.Id, "preview.png")))
                        if (preview.Width == 296 && preview.Height == 196)
                        {
                            previews.Add(mod.Id, sheetBuilder.Add(preview));
                        }
                }
                catch (Exception) { }

                try
                {
                    using (var logo = new Bitmap(Platform.ResolvePath(".", "mods", mod.Id, "logo.png")))
                        if (logo.Width == 96 && logo.Height == 96)
                        {
                            logos.Add(mod.Id, sheetBuilder.Add(logo));
                        }
                }
                catch (Exception) { }
            }

            ModMetadata initialMod = null;

            ModMetadata.AllMods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
            SelectMod(initialMod ?? ModMetadata.AllMods["ra"]);

            RebuildModList();
        }
예제 #13
0
        public ModBrowserLogic(Widget widget, ModData modData)
        {
            modInstallStatus          = new Cache <ModMetadata, bool>(IsModInstalled);
            modPrerequisitesFulfilled = new Cache <string, bool>(Game.IsModInstalled);

            modChooserPanel       = widget;
            loadButton            = modChooserPanel.Get <ButtonWidget>("LOAD_BUTTON");
            loadButton.OnClick    = () => LoadMod(selectedMod);
            loadButton.IsDisabled = () => selectedMod.Id == modData.Manifest.Mod.Id;

            modChooserPanel.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            modList     = modChooserPanel.Get("MOD_LIST");
            modTemplate = modList.Get <ButtonWidget>("MOD_TEMPLATE");

            modChooserPanel.Get <LabelWidget>("MOD_DESC").GetText    = () => selectedDescription;
            modChooserPanel.Get <LabelWidget>("MOD_TITLE").GetText   = () => selectedMod.Title;
            modChooserPanel.Get <LabelWidget>("MOD_AUTHOR").GetText  = () => selectedAuthor;
            modChooserPanel.Get <LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Version;

            var prevMod = modChooserPanel.Get <ButtonWidget>("PREV_MOD");

            prevMod.OnClick   = () => { modOffset -= 1; RebuildModList(); };
            prevMod.IsVisible = () => modOffset > 0;

            var nextMod = modChooserPanel.Get <ButtonWidget>("NEXT_MOD");

            nextMod.OnClick   = () => { modOffset += 1; RebuildModList(); };
            nextMod.IsVisible = () => modOffset + 5 < allMods.Length;

            modChooserPanel.Get <RGBASpriteWidget>("MOD_PREVIEW").GetSprite = () =>
            {
                Sprite ret = null;
                previews.TryGetValue(selectedMod.Id, out ret);
                return(ret);
            };

            sheetBuilder = new SheetBuilder(SheetType.BGRA);
            allMods      = ModMetadata.AllMods.Values.Where(m => !m.Hidden)
                           .OrderBy(m => m.Title)
                           .ToArray();

            // Load preview images, and eat any errors
            foreach (var mod in allMods)
            {
                try
                {
                    using (var stream = ModMetadata.AllMods[mod.Id].Package.GetStream("preview.png"))
                        using (var preview = new Bitmap(stream))
                            if (preview.Width == 296 && preview.Height == 196)
                            {
                                previews.Add(mod.Id, sheetBuilder.Add(preview));
                            }
                }
                catch (Exception) { }

                try
                {
                    using (var stream = ModMetadata.AllMods[mod.Id].Package.GetStream("logo.png"))
                        using (var logo = new Bitmap(stream))
                            if (logo.Width == 96 && logo.Height == 96)
                            {
                                logos.Add(mod.Id, sheetBuilder.Add(logo));
                            }
                }
                catch (Exception) { }
            }

            ModMetadata initialMod;

            ModMetadata.AllMods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
            SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : ModMetadata.AllMods["ra"]);

            RebuildModList();
        }
예제 #14
0
파일: MapCache.cs 프로젝트: hadow/Commander
        void LoadAsyncInternal()
        {
            //Log.Write("debug", "MapCache.LoadAsyncInternal started");

            // Milliseconds to wait on one loop when nothing to do
            var emptyDelay = 50;

            // Keep the thread alive for at least 5 seconds after the last minimap generation
            var maxKeepAlive = 5000 / emptyDelay;
            var keepAlive    = maxKeepAlive;

            for (; ;)
            {
                List <MapPreview> todo;
                lock (syncRoot)
                {
                    todo = generateMinimap.Where(p => p.GetMinimap() == null).ToList();
                    generateMinimap.Clear();
                    if (keepAlive > 0)
                    {
                        keepAlive--;
                    }
                    if (keepAlive == 0 && todo.Count == 0)
                    {
                        previewLoaderThreadShutDown = true;
                        break;
                    }
                }

                if (todo.Count == 0)
                {
                    Thread.Sleep(emptyDelay);
                    continue;
                }
                else
                {
                    keepAlive = maxKeepAlive;
                }

                // Render the minimap into the shared sheet
                foreach (var p in todo)
                {
                    if (p.Preview != null)
                    {
                        WarGame.RunAfterTick(() =>
                        {
                            try
                            {
                                p.SetMinimap(sheetBuilder.Add(p.Preview));
                            }
                            catch (Exception e)
                            {
                                //Log.Write("debug", "Failed to load minimap with exception: {0}", e);
                            }
                        });
                    }

                    // Yuck... But this helps the UI Jank when opening the map selector significantly.
                    Thread.Sleep(Environment.ProcessorCount == 1 ? 25 : 5);
                }
            }

            // The buffer is not fully reclaimed until changes are written out to the texture.
            // We will access the texture in order to force changes to be written out, allowing the buffer to be freed.
            WarGame.RunAfterTick(() =>
            {
                sheetBuilder.Current.ReleaseBuffer();
                sheetBuilder.Current.GetTexture();
            });
            //Log.Write("debug", "MapCache.LoadAsyncInternal ended");
        }
예제 #15
0
        public void Draw2()
        {
            //вызовы SetPalette в Draw для UI элементов, конкурируют с RefreshPalette в World.Draw.
            //Game.Renderer.SetPalette(hardwarePalette); //теперь не нужно, так как обнаружен файл palettes.yaml, в котором все палитры есть и сделано через него.

            if (String.IsNullOrEmpty(cachedVideo))
            {
                return;
            }
            //if (video==null)
            //{
            //    return;
            //}
            //Game.RunTime MilliSeconds 1s=1000ms=50ms*20times
            var deltaScale = Game.RunTime - lastDrawTime;

            CountForWaitNextFrameMs += deltaScale;

            //if we need pause wait it

            if (CountForPause > PauseInSeconds * 1000)
            {
                if (VideoStackList != null)
                {//only move next, first video must be dequed from PlayVideoStack
                    if (VideoStackList.Count > 0)
                    {
                        CountForPause           = 0;
                        CountForWaitNextFrameMs = 0;
                        Load(VideoStackList.Dequeue());
                        lastDrawTime = Game.RunTime;
                        stopped      = paused = false;
                        return;
                    }
                    //stop video
                }
                //нужно остановить медиа=сцену и передать контроль дальше
                cachedVideo = null;
                Exit();
                return;
            }
            if (CountForWaitNextFrameMs < DrawPrevFrameEveryXMs) //code runs every tick before Next Video frame to fill the gap
            {
                if (prevSprite != null)
                {
                    //just draw the same frame
                    Game.Renderer.SpriteRenderer.DrawSprite(prevSprite, videoOrigin, pr, videoSize);
                }
                if (prevText != null)
                {
                    DrawWsaText(prevText);
                }
                return;
            }
            else
            {
                if (video != null && prevSprite != null)
                {
                    if (video.CurrentFrame >= video.Length - 1) //this code runs every DrawFrameEveryXMilliseconds when video is ended.
                    {
                        //on video last frame draw always last frame
                        Game.Renderer.SpriteRenderer.DrawSprite(prevSprite, videoOrigin, pr, videoSize);
                        CountForPause += deltaScale; //incerease CountForPause to enter at if (CountForPause > PauseInSeconds * 1000)
                        lastDrawTime   = Game.RunTime;
                        if (prevText != null)
                        {
                            DrawWsaText(prevText);
                        }

                        return;
                    }

                    //if not last frame of video, move next frame
                    video.AdvanceFrame();
                }
                if (image != null && prevSprite != null)
                {
                    Game.Renderer.SpriteRenderer.DrawSprite(prevSprite, videoOrigin, pr, videoSize);
                    CountForPause += deltaScale; //incerease CountForPause to enter at if (CountForPause > PauseInSeconds * 1000)
                    lastDrawTime   = Game.RunTime;
                    return;
                }

                if (prevText != null)
                {
                    DrawWsaText(prevText);
                }
                //||
                //\/
            }

            if (video != null)
            {
                if (frameSoundLine == null)
                {
                }

                else
                {
                    if (frameSoundLine.Contains(new FrameSoundLine()
                    {
                        WSAfilename = cachedVideo, FrameNumber = video.CurrentFrame
                    }))
                    {
                        var vocfilename = frameSoundLine.Find(x => x.WSAfilename.Contains(cachedVideo) && x.FrameNumber == video.CurrentFrame).VOCfilename;
                        if (vocfilename.Contains("ADL"))
                        {
                            IReadOnlyFileSystem fileSystem = Game.ModData.DefaultFileSystem;

                            if (!fileSystem.Exists(vocfilename))
                            {
                                Log.Write("sound", "LoadSound, file does not exist: {0}", vocfilename);
                            }
                            DuneMusic.Quit();
                            DuneMusic.Init(44100, "", DuneMusic.DuneMusicOplEmu.kOplEmuNuked);

                            using (var stream = fileSystem.Open(vocfilename))
                            {
                                DuneMusic.InsertMemoryFile("test", stream.ReadAllBytes());
                                byte[] temp = new byte[28106880];

                                UIntPtr temp3;
                                temp3 = (UIntPtr)1000000;
                                temp3 = DuneMusic.SynthesizeAudio("test", 52, -1, temp, (UIntPtr)temp.Length);
                                ISoundSource soundSource;
                                soundSource = Game.Sound.soundEngine.AddSoundSourceFromMemory(temp, 2, 16, 44100);
                                ISound temp2 = Game.Sound.soundEngine.Play2D(Game.LocalTick, soundSource, false, true, WPos.Zero, 100, false);
                            }
                        }
                        else
                        {
                            Game.Sound.Play(SoundType.UI, vocfilename);
                        }
                    }
                }
                if (frameTextLine == null)
                {
                    prevText = new FrameTextLine()
                    {
                        Text = ""
                    };
                    DrawWsaText(prevText);
                }

                else
                {
                    if (frameTextLine.Contains(new FrameTextLine()
                    {
                        WSAfilename = cachedVideo, FrameNumber = video.CurrentFrame
                    }))
                    {
                        FrameTextLine ft = frameTextLine.Find(x => x.WSAfilename.Contains(cachedVideo) && x.FrameNumber == video.CurrentFrame);

                        DrawWsaText(ft);
                        prevText = ft;
                    }
                }
            }
            var sheetBuilder = new SheetBuilder(SheetType.Indexed, 512);

            //router for WSA  frame or CPS frame
            Sprite videoSprite = null;

            if (cachedVideo.Contains("WSA"))
            {
                videoSprite = sheetBuilder.Add(video.Frame);
            }
            else
            {
                //videoSprite = new Sprite(sheetBuilder.Current, new Rectangle(0, 0, 320, 200), TextureChannel.RGBA);
                videoSprite = sheetBuilder.Add(imageSprite[0]);
                //дампинг ресурсов игры в png
                //videoSprite.Sheet.CreateBuffer();
                //videoSprite.Sheet.ReleaseBuffer();
                ////videoSprite.Sheet.AsPng().Save("VIRGIN.png");
                //IPalette exppal;
                //try
                //{
                //    exppal = hardwarePalette.GetPalette(cachedVideo);
                //}
                //catch (Exception)
                //{

                //    exppal = null;
                //}

                //if (exppal==null)
                //{
                //    LoadPalette();
                //    videoSprite.Sheet.AsPng(TextureChannel.Blue, hardwarePalette.GetPalette("chrome")).Save(cachedVideo + ".png");
                //}
                //else
                //{
                //    videoSprite.Sheet.AsPng(TextureChannel.Blue, exppal).Save(cachedVideo + ".png");
                //}
            }
            prevSprite = videoSprite;


            Game.Renderer.SpriteRenderer.DrawSprite(videoSprite, videoOrigin, pr, videoSize);


            CountForWaitNextFrameMs = 0;
            lastDrawTime            = Game.RunTime;
        }
예제 #16
0
        public override void Init(ModData modData, Dictionary <string, string> info)
        {
            base.Init(modData, info);

            this.modData = modData;
            this.info    = info;

            /*
             * Unpack files needed, because in some PAK files, some VOC files can have prefix 'Z'
             * Unpacking files will unpack such files and rename. so no modifications in yaml needed.
             * LoadScreen.Init, possibly not the best place to do this, but need to do that early, before
             * data will be used. and do this in LoadScreen.Init just works fine.
             */
            if (D2UnpackContent.UnpackFiles(modData, info) > 0)
            {
                // Some files unpacked. need to reload mod packages
                modData.ModFiles.LoadFromManifest(modData.Manifest);
            }

            /*
             * Like for unpack files, OpenRA engine do not have proper place for import maps.
             * And can't import in LoadScreen.Init, because engine not ready.
             * but Game.OnShellmapLoaded just works.
             */
            Game.OnShellmapLoaded += ImportOriginalMaps;

            // Avoid standard loading mechanisms so we
            // can display the loadscreen as early as possible
            r = Game.Renderer;
            if (r == null)
            {
                return;
            }

            if (info.ContainsKey("Text"))
            {
                messages = info["Text"].Split(',');
            }

            if (info.ContainsKey("Palette"))
            {
                using (var stream = modData.DefaultFileSystem.Open(info["Palette"]))
                    palette = new ImmutablePalette(stream, new int[] { });

                hardwarePalette = new HardwarePalette();
                hardwarePalette.AddPalette("loadscreen", palette, false);
                hardwarePalette.Initialize();
                r.SetPalette(hardwarePalette);
                var pal = hardwarePalette.GetPalette("loadscreen");
                pr = new PaletteReference("loadscreenref", hardwarePalette.GetPaletteIndex("loadscreen"), pal, hardwarePalette);
            }

            if (info.ContainsKey("Image"))
            {
                using (var stream = modData.DefaultFileSystem.Open(info["Image"]))
                {
                    CpsD2Loader    loader = new CpsD2Loader();
                    TypeDictionary metadata;

                    if (!loader.TryParseSprite(stream, out frames, out metadata))
                    {
                        return;
                    }
                }

                if (frames.Length == 0)
                {
                    return;
                }

                sheetBuilder = new SheetBuilder(SheetType.Indexed, 512);
                logo         = sheetBuilder.Add(frames[0]);

                logoPos = new float2((r.Resolution.Width - logo.Size.X) / 2, (r.Resolution.Height - logo.Size.Y) / 2);
            }
        }
예제 #17
0
        void LoadAsyncInternal()
        {
            Log.Write("debug", "MapCache.LoadAsyncInternal started");

            // Milliseconds to wait on one loop when nothing to do
            var emptyDelay = 50;

            // Keep the thread alive for at least 5 seconds after the last minimap generation
            var maxKeepAlive = 5000 / emptyDelay;
            var keepAlive    = maxKeepAlive;

            for (;;)
            {
                List <MapPreview> todo;
                lock (syncRoot)
                {
                    todo = generateMinimap.Where(p => p.GetMinimap() == null).ToList();
                    generateMinimap.Clear();
                    if (keepAlive > 0)
                    {
                        keepAlive--;
                    }
                    if (keepAlive == 0 && todo.Count == 0)
                    {
                        previewLoaderThreadShutDown = true;
                        break;
                    }
                }

                if (todo.Count == 0)
                {
                    Thread.Sleep(emptyDelay);
                    continue;
                }
                else
                {
                    keepAlive = maxKeepAlive;
                }

                // Render the minimap into the shared sheet
                foreach (var p in todo)
                {
                    // The rendering is thread safe because it only reads from the passed instances and writes to a new bitmap
                    var createdPreview = false;
                    var bitmap         = p.CustomPreview;
                    if (bitmap == null)
                    {
                        createdPreview = true;
                        bitmap         = Minimap.RenderMapPreview(modData.DefaultRules.TileSets[p.Map.Tileset], p.Map, modData.DefaultRules, true);
                    }

                    Game.RunAfterTick(() =>
                    {
                        try
                        {
                            p.SetMinimap(sheetBuilder.Add(bitmap));
                        }
                        finally
                        {
                            if (createdPreview)
                            {
                                bitmap.Dispose();
                            }
                        }
                    });

                    // Yuck... But this helps the UI Jank when opening the map selector significantly.
                    Thread.Sleep(Environment.ProcessorCount == 1 ? 25 : 5);
                }
            }

            // The buffer is not fully reclaimed until changes are written out to the texture.
            // We will access the texture in order to force changes to be written out, allowing the buffer to be freed.
            Game.RunAfterTick(() =>
            {
                sheetBuilder.Current.ReleaseBuffer();
                sheetBuilder.Current.GetTexture();
            });
            Log.Write("debug", "MapCache.LoadAsyncInternal ended");
        }
예제 #18
0
        public ModBrowserLogic(Widget widget, ModData modData)
        {
            modChooserPanel       = widget;
            loadButton            = modChooserPanel.Get <ButtonWidget>("LOAD_BUTTON");
            loadButton.OnClick    = () => LoadMod(selectedMod);
            loadButton.IsDisabled = () => selectedMod.Id == modData.Manifest.Id;

            var contentButton = modChooserPanel.Get <ButtonWidget>("CONFIGURE_BUTTON");

            contentButton.OnClick = () =>
            {
                var widgetArgs = new WidgetArgs
                {
                    { "mod", selectedMod },
                    { "content", content[selectedMod] },
                    { "onCancel", () => { } }
                };

                Ui.OpenWindow("CONTENT_PANEL", widgetArgs);
            };

            modChooserPanel.Get <ButtonWidget>("QUIT_BUTTON").OnClick = Game.Exit;

            modList     = modChooserPanel.Get("MOD_LIST");
            modTemplate = modList.Get <ButtonWidget>("MOD_TEMPLATE");

            modChooserPanel.Get <LabelWidget>("MOD_DESC").GetText    = () => selectedDescription;
            modChooserPanel.Get <LabelWidget>("MOD_TITLE").GetText   = () => selectedMod.Metadata.Title;
            modChooserPanel.Get <LabelWidget>("MOD_AUTHOR").GetText  = () => selectedAuthor;
            modChooserPanel.Get <LabelWidget>("MOD_VERSION").GetText = () => selectedMod.Metadata.Version;

            var prevMod = modChooserPanel.Get <ButtonWidget>("PREV_MOD");

            prevMod.OnClick   = () => { modOffset -= 1; RebuildModList(); };
            prevMod.IsVisible = () => modOffset > 0;

            var nextMod = modChooserPanel.Get <ButtonWidget>("NEXT_MOD");

            nextMod.OnClick   = () => { modOffset += 1; RebuildModList(); };
            nextMod.IsVisible = () => modOffset + 5 < allMods.Length;

            modChooserPanel.Get <RGBASpriteWidget>("MOD_PREVIEW").GetSprite = () =>
            {
                Sprite ret = null;
                previews.TryGetValue(selectedMod.Id, out ret);
                return(ret);
            };

            sheetBuilder = new SheetBuilder(SheetType.BGRA);
            allMods      = Game.Mods.Values.Where(m => !m.Metadata.Hidden)
                           .OrderBy(m => m.Metadata.Title)
                           .ToArray();

            // Load preview images, and eat any errors
            foreach (var mod in allMods)
            {
                try
                {
                    using (var stream = mod.Package.GetStream("preview.png"))
                        using (var preview = new Bitmap(stream))
                            if (preview.Width == 296 && preview.Height == 196)
                            {
                                previews.Add(mod.Id, sheetBuilder.Add(preview));
                            }
                }
                catch (Exception) { }

                try
                {
                    using (var stream = mod.Package.GetStream("logo.png"))
                        using (var logo = new Bitmap(stream))
                            if (logo.Width == 96 && logo.Height == 96)
                            {
                                logos.Add(mod.Id, sheetBuilder.Add(logo));
                            }
                }
                catch (Exception) { }
            }

            Manifest initialMod;

            Game.Mods.TryGetValue(Game.Settings.Game.PreviousMod, out initialMod);
            SelectMod(initialMod != null && initialMod.Id != "modchooser" ? initialMod : Game.Mods["ra"]);

            RebuildModList();
        }
예제 #19
0
        public DefaultTileCache(DefaultTerrain terrainInfo, Action <uint, string> onMissingImage = null)
        {
            var allocated = false;

            Func <Sheet> allocate = () =>
            {
                if (allocated)
                {
                    throw new SheetOverflowException("Terrain sheet overflow. Try increasing the tileset SheetSize parameter.");
                }
                allocated = true;

                return(new Sheet(SheetType.Indexed, new Size(terrainInfo.SheetSize, terrainInfo.SheetSize)));
            };

            random = new MersenneTwister();

            var frameCache = new FrameCache(Game.ModData.DefaultFileSystem, Game.ModData.SpriteLoaders);

            foreach (var t in terrainInfo.Templates)
            {
                var variants     = new List <Sprite[]>();
                var templateInfo = (DefaultTerrainTemplateInfo)t.Value;

                foreach (var i in templateInfo.Images)
                {
                    ISpriteFrame[] allFrames;
                    if (onMissingImage != null)
                    {
                        try
                        {
                            allFrames = frameCache[i];
                        }
                        catch (FileNotFoundException)
                        {
                            onMissingImage(t.Key, i);
                            continue;
                        }
                    }
                    else
                    {
                        allFrames = frameCache[i];
                    }

                    var frameCount = terrainInfo.EnableDepth ? allFrames.Length / 2 : allFrames.Length;
                    var indices    = templateInfo.Frames != null ? templateInfo.Frames : Exts.MakeArray(t.Value.TilesCount, j => j);

                    var start = indices.Min();
                    var end   = indices.Max();
                    if (start < 0 || end >= frameCount)
                    {
                        throw new YamlException("Template `{0}` uses frames [{1}..{2}] of {3}, but only [0..{4}] actually exist"
                                                .F(t.Key, start, end, i, frameCount - 1));
                    }

                    variants.Add(indices.Select(j =>
                    {
                        var f    = allFrames[j];
                        var tile = t.Value.Contains(j) ? (DefaultTerrainTileInfo)t.Value[j] : null;

                        // The internal z axis is inverted from expectation (negative is closer)
                        var zOffset = tile != null ? -tile.ZOffset : 0;
                        var zRamp   = tile != null ? tile.ZRamp : 1f;
                        var offset  = new float3(f.Offset, zOffset);
                        var type    = SheetBuilder.FrameTypeToSheetType(f.Type);

                        // Defer SheetBuilder creation until we know what type of frames we are loading!
                        // TODO: Support mixed indexed and BGRA frames
                        if (sheetBuilder == null)
                        {
                            sheetBuilder = new SheetBuilder(SheetBuilder.FrameTypeToSheetType(f.Type), allocate);
                        }
                        else if (type != sheetBuilder.Type)
                        {
                            throw new YamlException("Sprite type mismatch. Terrain sprites must all be either Indexed or RGBA.");
                        }

                        var s = sheetBuilder.Allocate(f.Size, zRamp, offset);
                        OpenRA.Graphics.Util.FastCopyIntoChannel(s, f.Data, f.Type);

                        if (terrainInfo.EnableDepth)
                        {
                            var depthFrame = allFrames[j + frameCount];
                            var ss         = sheetBuilder.Allocate(f.Size, zRamp, offset);
                            OpenRA.Graphics.Util.FastCopyIntoChannel(ss, depthFrame.Data, depthFrame.Type);

                            // s and ss are guaranteed to use the same sheet
                            // because of the custom terrain sheet allocation
                            s = new SpriteWithSecondaryData(s, s.Sheet, ss.Bounds, ss.Channel);
                        }

                        return(s);
                    }).ToArray());
                }

                var allSprites = variants.SelectMany(s => s);

                // Ignore the offsets baked into R8 sprites
                if (terrainInfo.IgnoreTileSpriteOffsets)
                {
                    allSprites = allSprites.Select(s => new Sprite(s.Sheet, s.Bounds, s.ZRamp, new float3(float2.Zero, s.Offset.Z), s.Channel, s.BlendMode));
                }

                if (onMissingImage != null && !variants.Any())
                {
                    continue;
                }

                templates.Add(t.Value.Id, new TheaterTemplate(allSprites.ToArray(), variants.First().Count(), templateInfo.Images.Length));
            }

            // 1x1px transparent tile
            if (sheetBuilder.Type == SheetType.BGRA)
            {
                missingTile = sheetBuilder.Add(new byte[4], SpriteFrameType.Bgra32, new Size(1, 1));
            }
            else
            {
                missingTile = sheetBuilder.Add(new byte[1], SpriteFrameType.Indexed8, new Size(1, 1));
            }

            Sheet.ReleaseBuffer();
        }