Ejemplo n.º 1
0
 internal override ModelBase Serialize()
 {
     return(new GMLinuxOptionsModel
     {
         id = Id,
         name = "Linux",
         option_linux_display_name = DisplayName,
         option_linux_version = Version,
         option_linux_maintainer_email = MaintainerEmail,
         option_linux_homepage = Homepage,
         option_linux_short_desc = ShortDescription,
         option_linux_long_desc = LongDescription,
         option_linux_splash_screen = SplashScreen,
         option_linux_display_splash = DisplaySplash,
         option_linux_icon = Icon,
         option_linux_start_fullscreen = StartFullscreen,
         option_linux_allow_fullscreen = AllowFullscreen,
         option_linux_interpolate_pixels = InterpolatePixels,
         option_linux_display_cursor = DisplayCursor,
         option_linux_sync = Vsync,
         option_linux_resize_window = ResizeWindow,
         option_linux_scale = ScaleMode,
         option_linux_texture_page = TexturePage.ToString(),
         option_linux_enable_steam = EnableSteam,
         option_linux_disable_sandbox = DisableSandbox
     });
 }
Ejemplo n.º 2
0
 internal override ModelBase Serialize()
 {
     return(new GMMacOptionsModel
     {
         id = Id,
         name = "macOS",
         option_mac_display_name = DisplayName,
         option_mac_app_id = AppId,
         option_mac_version = Version,
         option_mac_output_dir = OutputDirectory,
         option_mac_team_id = TeamId,
         option_mac_signing_identity = SigningIdentity,
         option_mac_copyright = Copyright,
         option_mac_splash_png = SplashPng,
         option_mac_icon_png = IconPng,
         option_mac_menu_dock = MenuDock,
         option_mac_display_cursor = DisplayCursor,
         option_mac_start_fullscreen = StartFullscreen,
         option_mac_allow_fullscreen = AllowFullscreenSwitching,
         option_mac_interpolate_pixels = InterpolatePixels,
         option_mac_vsync = Vsync,
         option_mac_resize_window = ResizeWindow,
         option_mac_scale = Scale,
         option_mac_texture_page = TexturePage.ToString(),
         option_mac_build_app_store = AppStore,
         option_mac_allow_incoming_network = AllowIncomingNetwork,
         option_mac_allow_outgoing_network = AllowOutgoingNetwork,
         option_mac_app_category = AppCategory,
         option_mac_enable_steam = EnableSteam,
         option_mac_disable_sandbox = DisableSandbox
     });
 }
Ejemplo n.º 3
0
 internal override ModelBase Serialize()
 {
     return(new GMWindowsOptionsModel
     {
         id = Id,
         name = "Windows",
         option_windows_display_name = DisplayName,
         option_windows_executable_name = ExecutableName,
         option_windows_version = Version,
         option_windows_company_info = CompanyInfo,
         option_windows_product_info = ProductInfo,
         option_windows_copyright_info = CopyrightInfo,
         option_windows_description_info = DescriptionInfo,
         option_windows_display_cursor = DisplayCursor,
         option_windows_icon = Icon,
         option_windows_save_location = SaveLocation,
         option_windows_splash_screen = SplashScreen,
         option_windows_use_splash = UseSplash,
         option_windows_start_fullscreen = StartFullscreen,
         option_windows_allow_fullscreen_switching = AllowFullscreenSwitching,
         option_windows_interpolate_pixels = InterpolatePixels,
         option_windows_vsync = Vsync,
         option_windows_resize_window = ResizeWindow,
         option_windows_borderless = Borderless,
         option_windows_scale = Scale,
         option_windows_sleep_margin = SleepMargin,
         option_windows_texture_page = TexturePage.ToString(),
         option_windows_installer_finished = InstallerFinished,
         option_windows_installer_header = InstallerHeader,
         option_windows_license = License,
         option_windows_nsis_file = NsisFile,
         option_windows_enable_steam = EnableSteam,
         option_windows_disable_sandbox = DisableSandbox
     });
 }
        protected TexturePage GetTexturePage(ushort tPage)
        {
            TexturePage texturePage = new TexturePage
            {
                tPage  = tPage,
                tp     = (tPage >> 7) & 0x001, //(tPage >> 7) & 0x003,
                abr    = 0,                    //(tPage >> 5) & 0x003,
                x      = (tPage << 6) & 0x1c0, //(tPage << 6) & 0x7c0,
                y      = (tPage << 4) & 0x100, //((tPage << 4) & 0x100) + ((tPage >> 2) & 0x200),
                pixels = null
            };

            ushort[,] pixels = new ushort[_ImageHeight, _ImageWidth];

            int scaledX = texturePage.x;
            int scaledY = texturePage.y;

            for (int y = 0; y < _ImageHeight; y++)
            {
                int yOffset = (scaledY + y) * _TotalWidth;
                for (int x = 0; x < _ImageWidth;)
                {
                    int xOffset = scaledX;                     // / 2;

                    try
                    {
                        if (texturePage.tp == 0)                         // 4 bit
                        {
                            xOffset += x / 4;
                            ushort val = _TextureData[yOffset + xOffset];
                            pixels[y, x++] = (ushort)(val & 0x000F);
                            pixels[y, x++] = (ushort)((val & 0x00F0) >> 4);
                            pixels[y, x++] = (ushort)((val & 0x0F00) >> 8);
                            pixels[y, x++] = (ushort)((val & 0xF000) >> 12);
                        }
                        else if (texturePage.tp == 1)                         // 8 bit
                        {
                            xOffset += x;
                            xOffset /= 2;
                            ushort val = _TextureData[yOffset + xOffset];
                            pixels[y, x++] = (ushort)(val & 0x00FF);
                            pixels[y, x++] = (ushort)((val & 0xFF00) >> 8);
                        }
                        else if (texturePage.tp == 2)                         // 16 bit
                        {
                            xOffset += x;
                            ushort val = _TextureData[yOffset + xOffset];
                            pixels[y, x++] = val;
                        }
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }

            texturePage.pixels = pixels;
            return(texturePage);
        }
Ejemplo n.º 5
0
        public RenderingTextureAllocator(RenderingDevice device, Description description)
        {
            logger.Info("Rendering texture allocated of size \"" + description.Size + "\".");

            Pages = new TexturePage[description.Size.Z];
            for (int i = 0; i < description.Size.Z; ++i)
            {
                Pages[i] = new TexturePage(new VectorInt2(description.Size.X, description.Size.Y));
            }
            Size = description.Size;
        }
Ejemplo n.º 6
0
 public TextureRegion(int x, int y, TexturePage page, TextureBuffer buffer)
 {
     this.x         = x;
     this.y         = y;
     this.page      = page;
     this.buffer    = buffer;
     width          = page.width;
     bytesPerPixel  = TextureUtil.GetBytesPerPixel(page.format);
     bytes          = page.bytes;
     floatConverter = new ByteToFloatConverter
     {
         bytes = page.bytes
     };
 }
        protected Color[] GetGreyscalePalette(int index)
        {
            TexturePage tPage = _TPages[(ushort)index];

            int paletteSize = (tPage.tp == 0) ? 16 : 256;

            Color[] greyPalette = new Color[paletteSize];
            for (int i = 0; i < paletteSize; i++)
            {
                int luma = (i * 256) / paletteSize;
                greyPalette[i] = Color.FromArgb(luma, luma, luma);
            }

            return(greyPalette);
        }
        protected Bitmap GetTextureAsBitmap(int index, Color[] palette)
        {
            Bitmap tex = new Bitmap(_ImageWidth, _ImageHeight);

            TexturePage texturePage = _TPages[index];

            for (int y = 0; y < _ImageHeight; y++)
            {
                for (int x = 0; x < _ImageWidth; x++)
                {
                    int pixel = texturePage.pixels[y, x];
                    tex.SetPixel(x, y, palette[pixel]);
                }
            }

            return(tex);
        }
    public TexturePage Alloc(string name, int width, int height, TextureFormat format)
    {
        int num  = Clamp(width);
        int num2 = Clamp(height);
        int num3 = Time.frameCount % 2;

        foreach (TexturePage item in activePages[num3])
        {
            freePages.Add(item);
        }
        activePages[num3].Clear();
        for (int i = 0; i < freePages.Count; i++)
        {
            TexturePage texturePage = freePages[i];
            if (texturePage.width == num && texturePage.height == num2 && texturePage.format == format)
            {
                freePages.RemoveAt(i);
                texturePage.SetName(name);
                return(texturePage);
            }
        }
        return(new TexturePage(name, num, num2, format));
    }
Ejemplo n.º 10
0
 internal override ModelBase Serialize()
 {
     return(new GMHtml5OptionsModel
     {
         id = Id,
         name = "HTML5",
         option_html5_allow_fullscreen = AllowFullscreen,
         option_html5_browser_title = BrowserTitle,
         option_html5_centregame = CentreGame,
         option_html5_display_cursor = DisplayCursor,
         option_html5_facebook_app_display_name = FacebookAppDisplayName,
         option_html5_facebook_id = FacebookId,
         option_html5_flurry_enable = FlurryEnable,
         option_html5_flurry_id = FlurryId,
         option_html5_foldername = FolderName,
         option_html5_google_analytics_enable = GoogleAnalyticsEnable,
         option_html5_google_tracking_id = GoogleTrackingId,
         option_html5_icon = Icon,
         option_html5_index = Index,
         option_html5_interpolate_pixels = InterpolatePixels,
         option_html5_jsprepend = JsPrepend,
         option_html5_loadingbar = LoadingBar,
         option_html5_localrunalert = LocalRunAlert,
         option_html5_outputdebugtoconsole = OutDebugToConsole,
         option_html5_outputname = OutputName,
         option_html5_scale = ScaleMode,
         option_html5_splash_png = SplashPng,
         option_html5_texture_page = TexturePage.ToString(),
         option_html5_usebuiltinfont = UseBuiltinFont,
         option_html5_usebuiltinparticles = UseBuiltinParticles,
         option_html5_usesplash = UseSplash,
         option_html5_use_facebook = UseFacebook,
         option_html5_version = Version,
         option_html5_webgl = WebGl
     });
 }
        public void BuildTexturesFromPolygonData(Gex3PlaystationPolygonTextureData[] texData, ushort[] texturePages, bool drawGreyScaleFirst, bool quantizeBounds, CDC.Objects.ExportOptions options)
        {
            if (_TPages == null)
            {
                List <TexturePage> tPages = new List <TexturePage>();

                for (int i = 0; i < texturePages.Length; i++)
                {
                    ushort tPage = (ushort)(texturePages[i] & 0x0000FFFFu);
                    if (tPages.FindIndex(x => x.tPage == tPage) < 0)
                    {
                        tPages.Add(GetTexturePage(tPage));
                    }
                }

                _TPages       = tPages.ToArray();
                _TextureCount = _TPages.Length;
                _Textures     = new Bitmap[_TPages.Length];
            }

            // hashtable to store counts of palette usage
            Hashtable palettes = new Hashtable();

            bool debugTextureCollisions = false;

            // initialize textures
            if (drawGreyScaleFirst)
            {
                for (int i = 0; i < _TextureCount; i++)
                {
                    _Textures[i] = GetTextureAsBitmap(i, GetGreyscalePalette(i));
                }
            }
            else
            {
                Color chromaKey = Color.FromArgb(1, 128, 128, 128);
                //Color chromaKey = Color.FromArgb(255, 128, 128, 128);
                for (int i = 0; i < _TextureCount; i++)
                {
                    _Textures[i] = new Bitmap(_ImageWidth, _ImageHeight);
                    for (int y = 0; y < _ImageHeight; y++)
                    {
                        for (int x = 0; x < _ImageWidth; x++)
                        {
                            _Textures[i].SetPixel(x, y, chromaKey);
                        }
                    }
                }
            }

            Dictionary <int, Dictionary <int, ulong> > handledPixels = new Dictionary <int, Dictionary <int, ulong> >();

            //Dictionary<int, ulong> handledPixels = new Dictionary<int, ulong>();

            // use the polygon data to colour in all possible parts of the textures
            foreach (Gex3PlaystationPolygonTextureData poly in texData)
            {
                TexturePage texturePage = _TPages[poly.textureID];

                bool                    dumpPreviousTextureVersion = false;
                bool                    wrotePixels     = false;
                List <byte[]>           textureHashes   = new List <byte[]>();
                Bitmap                  previousTexture = (Bitmap)_Textures[poly.textureID].Clone();
                Dictionary <int, ulong> polyPixelList   = new Dictionary <int, ulong>();
                if (handledPixels.ContainsKey(poly.textureID))
                {
                    polyPixelList = handledPixels[poly.textureID];
                }

                int uMin = 255;
                int uMax = 0;
                int vMin = 255;
                int vMax = 0;

                Color[] palette = GetPalette(poly.textureID, poly.CLUT);

                //bool exportAllPaletteVariations = false;
                //if (exportAllPaletteVariations)
                //{
                //    if (!Directory.Exists("Texture_Debugging"))
                //    {
                //        Directory.CreateDirectory("Texture_Debugging");
                //    }
                //    //string fileName = string.Format(@"Texture_Debugging\Texture-{0:X8}-row_{1:X4}-column_{2:X4}-CLUT_{3:X4}.png", poly.textureID, poly.paletteColumn, poly.paletteRow, poly.CLUT);
                //    string fileName = string.Format(@"Texture_Debugging\Texture-{0:X8}-CLUT_{3:X4}-row_{1:X4}-column_{2:X4}.png", poly.textureID, poly.paletteColumn, poly.paletteRow, poly.CLUT);
                //    if (!File.Exists(fileName))
                //    {
                //        Bitmap currentVariation = GetTextureAsBitmap(poly.textureID, palette);
                //        currentVariation.Save(fileName, ImageFormat.Png);
                //    }
                //}
                if (options.UseEachUniqueTextureCLUTVariation)
                {
                    CreateARGBTextureFromCLUTIfNew(poly.textureID, poly.CLUT, palette);
                }

                // some basic sanity-checking for bad palette information obtained via incorrect parsing of data
                bool paletteIsValid = true;
                //if ((poly.paletteColumn % 2) == 1)
                //{
                //    paletteIsValid = false;
                //}
                //int numTransparentColours = 0;
                //foreach (Color c in palette)
                //{
                //    if (c.A == 0)
                //    {
                //        numTransparentColours++;
                //    }
                //}
                //if (numTransparentColours > 1)
                //{
                //    paletteIsValid = false;
                //}
                //if (!paletteIsValid)
                //{
                //    palette = GetGreyscalePalette();
                //    Console.WriteLine(string.Format("Invalid palette detected for texture ID {0}: row {1}, column {2}", poly.textureID, poly.paletteRow, poly.paletteColumn));
                //}
                // get the rectangle defined by the minimum and maximum U and V coords
                foreach (int u in poly.u)
                {
                    uMin = Math.Min(uMin, u);
                    uMax = Math.Max(uMax, u);
                }
                foreach (int v in poly.v)
                {
                    vMin = Math.Min(vMin, v);
                    vMax = Math.Max(vMax, v);
                }

                int width = uMax - uMin;
                for (int b = 0; b < 8; b++)
                {
                    if ((1 << b) >= width)
                    {
                        width = 1 << b;
                        break;
                    }
                }

                int height = vMax - vMin;
                for (int b = 0; b < 8; b++)
                {
                    if ((1 << b) >= height)
                    {
                        height = 1 << b;
                        break;
                    }
                }

                // if specified, quantize the rectangle's boundaries
                //if (quantizeBounds)
                //{
                //    while ((uMin % width) > 0)
                //    {
                //        uMin--;
                //    }
                //    while ((uMax % width) > 0)
                //    {
                //        uMax++;
                //    }
                //    while ((vMin % height) > 0)
                //    {
                //        vMin--;
                //    }
                //    while ((vMax % height) > 0)
                //    {
                //        vMax++;
                //    }
                //    if (uMin < 0)
                //    {
                //        uMin = 0;
                //    }
                //    if (uMax > 256)
                //    {
                //        uMax = 256;
                //    }
                //    if (vMin < 0)
                //    {
                //        vMin = 0;
                //    }
                //    if (vMax > 256)
                //    {
                //        vMax = 256;
                //    }
                //}

                //// if specified, quantize the rectangle's boundaries to a multiple of 16
                if (quantizeBounds)
                {
                    //int quantizeRes = 16;
                    int quantizeRes = 16;
                    while ((uMin % quantizeRes) > 0)
                    {
                        uMin--;
                    }
                    while ((uMax % quantizeRes) > 0)
                    {
                        uMax++;
                    }
                    while ((vMin % quantizeRes) > 0)
                    {
                        vMin--;
                    }
                    while ((vMax % quantizeRes) > 0)
                    {
                        vMax++;
                    }
                    if (uMin < 0)
                    {
                        uMin = 0;
                    }
                    if (uMax > 256)
                    {
                        uMax = 256;
                    }
                    if (vMin < 0)
                    {
                        vMin = 0;
                    }
                    if (vMax > 256)
                    {
                        vMax = 256;
                    }
                }

                for (int y = vMin; y < vMax; y++)
                {
                    for (int x = uMin; x < uMax; x++)
                    {
                        int dataOffset = (_ImageHeight * y) + x;
                        int pixel      = texturePage.pixels[y, x];

                        Color pixelColour   = palette[pixel];
                        uint  materialAlpha = (poly.materialColour & 0xFF000000) >> 24;
                        //materialAlpha = 255;
                        //if (materialAlpha < 255)
                        //{
                        //    pixelColour = Color.FromArgb((byte)materialAlpha, palette[pixel].R, palette[pixel].G, palette[pixel].B);
                        //}
                        //ulong checkPixels = ((ulong)materialAlpha << 56) | ((ulong)palette[pixel].R << 48) | ((ulong)palette[pixel].G << 40)
                        //    | ((ulong)palette[pixel].B << 32) | ((ulong)materialAlpha << 24);
                        ulong checkPixels = ((ulong)palette[pixel].A << 56) | ((ulong)palette[pixel].R << 48) | ((ulong)palette[pixel].G << 40)
                                            | ((ulong)palette[pixel].B << 32);
                        bool writePixels = true;
                        if (polyPixelList.ContainsKey(dataOffset))
                        {
                            if (polyPixelList[dataOffset] != checkPixels)
                            {
                                bool drawPixels = true;
                                //if (materialAlpha == 0)
                                //{
                                //    //Console.WriteLine("Debug: Material has an alpha of 0 - ignoring");
                                //    drawPixels = false;
                                //}
                                //if (materialAlpha < 0x40)
                                //{
                                //    //Console.WriteLine("Debug: Material has an alpha of less than 0x40 - ignoring");
                                //    drawPixels = false;
                                //}
                                if (!poly.textureUsed)
                                {
                                    //Console.WriteLine("Debug: polygon does not use a texture - ignoring");
                                    drawPixels = false;
                                }
                                if (!poly.visible)
                                {
                                    //Console.WriteLine("Debug: polygon is invisible - ignoring");
                                    drawPixels = false;
                                }
                                if (drawPixels)
                                {
                                    if ((uMin != 0) && (vMin != 0))
                                    {
                                        dumpPreviousTextureVersion = true;
                                    }
                                    //Console.WriteLine(string.Format("Warning: pixels with offset {0} in texture with ID {1} have already been written with a different value. Existing: 0x{2:X16}, New:  0x{3:X16}", dataOffset, poly.textureID, polyPixelList[dataOffset], checkPixels));
                                }
                                else
                                {
                                    //Console.WriteLine(string.Format("Warning: not updating pixels with offset {0} in texture with ID {1}, because the new values are for a polygon that is not drawn/invisible, or has no texture. Existing: 0x{2:X16}, Ignored:  0x{3:X16}", dataOffset, poly.textureID, polyPixelList[dataOffset], checkPixels));
                                    writePixels = false;
                                }
                            }
                        }
                        else
                        {
                            polyPixelList.Add(dataOffset, checkPixels);
                        }

                        if (writePixels)
                        {
                            _Textures[poly.textureID].SetPixel(x, y, pixelColour);
                            wrotePixels = true;
                        }
                    }
                }
                if (handledPixels.ContainsKey(poly.textureID))
                {
                    handledPixels[poly.textureID] = polyPixelList;
                }
                else
                {
                    handledPixels.Add(poly.textureID, polyPixelList);
                }

                if (wrotePixels)
                {
                    // add or update palette list
                    string paletteIDString = poly.textureID.ToString() + "-" + poly.CLUT.ToString();
                    if (palettes.Contains(paletteIDString))
                    {
                        int palCount = (int)palettes[paletteIDString];
                        palCount++;
                        palettes[paletteIDString] = palCount;
                    }
                    else
                    {
                        int newPalCount = 1;
                        palettes.Add(paletteIDString, newPalCount);
                    }
                }

                if (debugTextureCollisions)
                {
                    if (dumpPreviousTextureVersion)
                    {
                        if (!Directory.Exists("Texture_Debugging"))
                        {
                            Directory.CreateDirectory("Texture_Debugging");
                        }
                        // dump each overwritten version of the texture for debugging
                        byte[] previousHash = new MD5CryptoServiceProvider().ComputeHash(ImageToByteArray(previousTexture));
                        if (!ListContainsByteArray(textureHashes, previousHash))
                        {
                            int    fileNum     = 0;
                            bool   gotFilename = false;
                            string fileName    = "";
                            while (!gotFilename)
                            {
                                fileName = string.Format(@"Texture_Debugging\Texture-{0:X8}-version_{1:X8}.png", poly.textureID, fileNum);
                                if (!File.Exists(fileName))
                                {
                                    gotFilename = true;
                                }
                                fileNum++;
                            }
                            if (fileName != "")
                            {
                                //_Textures[poly.textureID].Save(fileName, ImageFormat.Png);
                                previousTexture.Save(fileName, ImageFormat.Png);
                            }
                            textureHashes.Add(previousHash);
                        }
                    }
                }
            }

            if (!drawGreyScaleFirst)
            {
                bool exportAllPaletteVariations = false;

                if (exportAllPaletteVariations)
                {
                    foreach (string pID in palettes.Keys)
                    {
                        int      useCount   = (int)palettes[pID];
                        string[] palDecode2 = pID.Split('-');
                        int      tID        = int.Parse(palDecode2[0]);
                        ushort   clut       = ushort.Parse(palDecode2[1]);

                        for (int texNum = 0; texNum < _Textures.Length; texNum++)
                        {
                            TexturePage texturePage       = _TPages[texNum];
                            Bitmap      exportTemp        = (Bitmap)_Textures[texNum].Clone();
                            Color[]     pal               = GetPalette(texNum, clut);
                            bool        exportThisTexture = false;
                            for (int y = 0; y < _ImageHeight; y++)
                            {
                                for (int x = 0; x < _ImageWidth; x++)
                                {
                                    bool pixChroma = (exportTemp.GetPixel(x, y).A == 1);
                                    if (pixChroma)
                                    {
                                        exportThisTexture = true;
                                        int   pixel       = texturePage.pixels[y, x];
                                        Color pixelColour = pal[pixel];
                                        if (pixChroma)
                                        {
                                            exportTemp.SetPixel(x, y, pixelColour);
                                        }
                                    }
                                }
                            }
                            if (exportThisTexture)
                            {
                                if (!Directory.Exists("Texture_Debugging"))
                                {
                                    Directory.CreateDirectory("Texture_Debugging");
                                }
                                string fileName = string.Format(@"Texture_Debugging\Texture-{0:X8}-count_{1:X8}-palette_texture_ID_{2:X8}-clut_{4:X8}.png", texNum, useCount, tID, clut);
                                exportTemp.Save(fileName, ImageFormat.Png);
                            }
                        }
                    }
                }

                List <int> allTexturesWithPalettes = new List <int>();
                foreach (string pID in palettes.Keys)
                {
                    string[] pd   = pID.Split('-');
                    int      txID = int.Parse(pd[0]);
                    ushort   clut = ushort.Parse(pd[1]);
                    if (!allTexturesWithPalettes.Contains(txID))
                    {
                        if (clut != 0)
                        {
                            allTexturesWithPalettes.Add(txID);
                        }
                    }
                }

                for (int texNum = 0; texNum < _Textures.Length; texNum++)
                {
                    TexturePage texturePage = _TPages[texNum];

                    // find the most frequently-used palette
                    string palID    = "";
                    int    palCount = 0;
                    ushort mostCommonPaletteClut     = 0;
                    bool   hasAtLeastOneVisiblePixel = false;
                    foreach (string pID in palettes.Keys)
                    {
                        string[] pd              = pID.Split('-');
                        int      txID            = int.Parse(pd[0]);
                        bool     considerPalette = true;
                        // don't use palettes from other textures unless there were no palettes found for this texture
                        if (allTexturesWithPalettes.Contains(texNum))
                        {
                            if (txID != texNum)
                            {
                                considerPalette = false;
                            }
                        }
                        if (considerPalette)
                        {
                            ushort clut   = ushort.Parse(pd[1]);
                            int    pCount = (int)palettes[pID];
                            if (pCount > palCount)
                            {
                                palID = pID;
                                if (clut != 0)
                                {
                                    mostCommonPaletteClut = clut;
                                }
                                // don't use palettes with column/row zero or with odd column numbers unless there's no other choice
                                //if ((pc != 0) && (pr != 0) && (pc % 2 == 0))
                                //{
                                //    break;
                                //}
                            }
                        }
                    }
                    Color[] commonPalette = GetPalette(texNum, mostCommonPaletteClut);

                    // use a greyscale palette instead of column 0, row 0, because column 0, row 0 is always garbage that makes
                    // the texture impossible to view properly, and full of random transparent pixels
                    if (options.AlwaysUseGreyscaleForMissingPalettes || mostCommonPaletteClut == 0)
                    {
                        commonPalette = GetGreyscalePalette(texNum);
                    }

                    for (int y = 0; y < _ImageHeight; y++)
                    {
                        for (int x = 0; x < _ImageWidth; x++)
                        {
                            if (!hasAtLeastOneVisiblePixel)
                            {
                                if (_Textures[texNum].GetPixel(x, y).A > 1)
                                {
                                    hasAtLeastOneVisiblePixel = true;
                                }
                            }
                            bool pixChroma = (_Textures[texNum].GetPixel(x, y).A == 1);
                            if (pixChroma)
                            {
                                int   dataOffset  = (_ImageHeight * y) + x;
                                int   pixel       = texturePage.pixels[y, x];
                                Color pixelColour = commonPalette[pixel];
                                if (pixChroma)
                                {
                                    _Textures[texNum].SetPixel(x, y, pixelColour);
                                }
                            }
                        }
                    }
                    if ((!hasAtLeastOneVisiblePixel) && (options.UnhideCompletelyTransparentTextures))
                    {
                        for (int y = 0; y < _Textures[texNum].Width; y++)
                        {
                            for (int x = 0; x < _Textures[texNum].Height; x++)
                            {
                                Color pix = _Textures[texNum].GetPixel(x, y);
                                if (pix.A < 2)
                                {
                                    _Textures[texNum].SetPixel(x, y, Color.FromArgb(128, pix.R, pix.G, pix.B));
                                }
                            }
                        }
                    }
                }
            }

            // dump all textures as PNGs for debugging
            //texNum = 0;
            //foreach (Bitmap tex in _Textures)
            //{
            //    tex.Save(@"C:\Debug\Tex-" + texNum + ".png", ImageFormat.Png);
            //    texNum++;
            //}
        }
        protected Color[] GetPalette(int index, ushort clut)
        {
            TexturePage texturePage = _TPages[index];

            return(GetTextureClut(clut, texturePage.tp == 0 ? 16 : 256).colours);
        }
    public void Release(TexturePage page)
    {
        int num = (Time.frameCount + 1) % 2;

        activePages[num].Add(page);
    }
Ejemplo n.º 14
0
        /// <summary> Removes and compresses texture space. Updates all buffers with texture coordinates.</summary>
        public bool GarbageCollect(bool checkTime = true)
        {
            if (GarbageCollectionInProgress)
            {
                return(false);
            }

            // We don't want to garbage collect the texture all the time because it will make the program very slow.
            // So if we just collected it and only a bit of time elapsed, if it's already full again we must give up.
            long  elapsedTicks   = Stopwatch.GetTimestamp() - GarbageCollectionLastTimestamp;
            float elapsedSeconds = (float)elapsedTicks / Stopwatch.Frequency;

            if (checkTime && elapsedSeconds < GarbageCollectionWaitSeconds)
            {
                logger.Warn("Garbage collection of texture (size " + Size + ") was aborted because only " + elapsedSeconds + " seconds elapsed " +
                            "since the last collection. (Minimum time: " + GarbageCollectionWaitSeconds + " seconds)");
                return(false);
            }

            // Start garbage collection
            try
            {
                logger.Info("Started garbage collecting of texture (size " + Size + ") after " + elapsedSeconds + " seconds.");
                GarbageCollectionInProgress = true;

                // Collect
                var map          = new Map(this);
                var usedTextures = new HashSet <Map.Entry>();
                var adjustEvent  = new List <GarbageCollectionAdjustDelegate>();
                foreach (var collectDelegate in GarbageCollectionCollectEvent)
                {
                    var adjustDelegate = collectDelegate(this, map, usedTextures);
                    if (adjustDelegate != null)
                    {
                        adjustEvent.Add(adjustDelegate);
                    }
                }
                logger.Error("Removed " + (AvailableTextures.Count - usedTextures.Count) + " textures of previously " + AvailableTextures.Count + ".");

                // Reset
                for (int i = 0; i < Size.Z; ++i)
                {
                    Pages[i] = new TexturePage(new VectorInt2(Size.X, Size.Y));
                }
                AvailableTextures.Clear();

                // Read textures that were still used
                var usedTexturesSorted = usedTextures.ToArray();
                Array.Sort(usedTexturesSorted, new GarbageCollectionTextureOrder());
                foreach (Map.Entry usedTexture in usedTexturesSorted)
                {
                    if (AllocateTexture(usedTexture.Texture) == null)
                    {
                        logger.Error("Unable to add texture after garbage collecting texture!");
                    }
                }

                // Adjust
                foreach (var adjustDelegate in adjustEvent)
                {
                    adjustDelegate(this, map);
                }

                // Finished
                return(true);
            }
            finally
            {
                logger.Info("Garbage collection of texture (size " + Size + ") finished.");
                GarbageCollectionLastTimestamp = Stopwatch.GetTimestamp();
                GarbageCollectionInProgress    = false;
            }
        }
    public TextureRegion Lock(int x, int y, int width, int height)
    {
        TexturePage page = pool.Alloc(name, width, height, format);

        return(new TextureRegion(x, y, page, this));
    }