Esempio n. 1
0
        private void SaveTilemapButton_Click(object sender, EventArgs e)
        {
            // Create a new resource
            int      tilemapAddress = Convert.ToInt32(TilemapAddress.Text, 16);
            int      width          = Convert.ToInt32(Width.Text);
            int      height         = Convert.ToInt32(Height.Text);
            Resource resource       = new Resource()
            {
                Name         = "Tile Editor Map",
                Length       = width * height,
                FileType     = ResourceType.tilemap,
                StartAddress = tilemapAddress
            };

            // if this resource is already in the list of resource
            Resource oldRes = resCheckerRef.Find(ResourceType.tilemap, tilemapAddress);

            resCheckerRef.Items.Remove(oldRes);
            resCheckerRef.Add(resource);
            AssetWindow.Instance.UpdateAssets();
        }
Esempio n. 2
0
        private unsafe void ConvertBitmapToRaw(Bitmap bitmap, ResourceChecker.Resource resource, byte lutIndex, int stride, int maxHeight)
        {
            if (ResChecker.Add(resource))
            {
                // Load LUT from memory - ignore indexes 0 and 1
                int lutBaseAddress = MemoryLocations.MemoryMap.GRP_LUT_BASE_ADDR + lutIndex * 0x400 - MemoryLocations.MemoryMap.VICKY_BASE_ADDR;

                // Limit how much data is imported based on the type of image
                int importedLines = maxHeight < bitmap.Height ? maxHeight : bitmap.Height;
                int importedCols  = stride < bitmap.Width ? stride : bitmap.Width;

                byte[] data = new byte[stride * importedLines]; // the bitmap is based on resolution of the machine
                resource.Length = stride * bitmap.Height;       // one byte per pixel - palette is separate

                Rectangle  rect           = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
                BitmapData bitmapData     = bitmap.LockBits(rect, ImageLockMode.ReadOnly, bitmap.PixelFormat);
                int        bytesPerPixel  = bitmapData.Stride / bitmap.Width;
                byte *     bitmapPointer  = (byte *)bitmapData.Scan0.ToPointer();
                bool       tooManyColours = false;
                bool       done           = false;
                byte       mask           = 0xFF;
                List <int> lut            = null;
                while (!done && mask != 0xc0)
                {
                    int transparentColor = 0;
                    try
                    {
                        transparentColor = Convert.ToInt32(textTransparentColor.Text, 16) & ((mask << 16) + (mask << 8) + mask);
                    }
                    finally
                    { }

                    done = true;
                    // Reset the Lookup Table
                    lut = new List <int>(256)
                    {
                        // Always add black (transparent) and white
                        0,
                        0xFFFFFF
                    };

                    // The user may decide to overwrite the palette from this bitmap
                    if (!checkOverwriteLUT.Checked)
                    {
                        for (int i = 2; i < 256; i++)
                        {
                            int value = MemMgrRef.VICKY.ReadLong(lutBaseAddress + 4 * i);
                            if (value != 0)
                            {
                                lut.Add(value);
                            }
                            else
                            {
                                break;
                            }
                        }
                    }

                    for (int line = 0; line < importedLines; line++)
                    {
                        for (int col = 0; col < importedCols; col++)
                        {
                            byte b = 0;
                            byte r = 0;
                            byte g = 0;

                            switch (bytesPerPixel)
                            {
                            case 1:
                                byte palIndex = bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel];
                                System.Drawing.Color palValue = bitmap.Palette.Entries[palIndex];
                                b = (byte)(palValue.B & mask);
                                g = (byte)(palValue.G & mask);
                                r = (byte)(palValue.R & mask);
                                break;

                            case 2:
                                ushort wordValue = (ushort)(bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel] + bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel + 1] * 256);
                                b = (byte)(wordValue & 0x1F);        //  5bits
                                g = (byte)((wordValue >> 5) & 0x3F); // 6 bits
                                r = (byte)(wordValue >> 11);         // 5 bits
                                break;

                            case 3:
                                b = (byte)(bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel] & mask);
                                g = (byte)(bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel + 1] & mask);
                                r = (byte)(bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel + 2] & mask);
                                break;

                            case 4:
                                b = (byte)(bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel] & mask);
                                g = (byte)(bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel + 1] & mask);
                                r = (byte)(bitmapPointer[line * bitmapData.Stride + col * bytesPerPixel + 2] & mask);
                                //alpha is ignored

                                break;
                            }
                            int rgb = b + g * 256 + r * 256 * 256;
                            // Check if the RBG matches the transparent color
                            int index = 0;
                            if (rgb != transparentColor)
                            {
                                // if not, look in the LUT
                                index = lut.IndexOf(rgb);
                            }
                            // If the index is undefined, add a new entry
                            if (index == -1)
                            {
                                if (lut.Count < 256)
                                {
                                    lut.Add(rgb);
                                    index = (byte)lut.IndexOf(rgb);
                                }
                                else
                                {
                                    tooManyColours = true;
                                    break;
                                }
                            }
                            if (index != -1)
                            {
                                data[line * stride + col] = (byte)index;
                            }
                        }
                        if (tooManyColours)
                        {
                            // TODO should use a colour histogram to count how many times a colour is used and then decimate here, based on low usage.
                            done           = false;
                            tooManyColours = false;
                            mask         <<= 1;
                            break;
                        }
                    }
                }

                if (mask != 0xc0)
                {
                    int videoAddress = resource.StartAddress - 0xB0_0000;

                    MemMgrRef.VIDEO.CopyBuffer(data, 0, videoAddress, data.Length);

                    if (lut != null)
                    {
                        for (int i = 0; i < lut.Count; i++)
                        {
                            int rbg = lut[i];
                            MemMgrRef.VICKY.WriteByte(lutBaseAddress + 4 * i, LowByte(rbg));
                            MemMgrRef.VICKY.WriteByte(lutBaseAddress + 4 * i + 1, MidByte(rbg));
                            MemMgrRef.VICKY.WriteByte(lutBaseAddress + 4 * i + 2, HighByte(rbg));
                        }
                    }

                    // Check if a LUT matching our index is present in the Resources, if so don't do anything.
                    Resource resLut = ResChecker.Find(ResourceType.lut, lutBaseAddress + MemoryLocations.MemoryMap.VICKY_BASE_ADDR);
                    if (resLut == null)
                    {
                        Resource lutPlaceholder = new Resource
                        {
                            Length       = 0x400,
                            FileType     = ResourceType.lut,
                            Name         = "Generated LUT",
                            StartAddress = lutBaseAddress + MemoryLocations.MemoryMap.VICKY_BASE_ADDR
                        };
                        ResChecker.Add(lutPlaceholder);
                    }
                }
                else
                {
                    MessageBox.Show("An error occured converting the image colors to LUT.\n" +
                                    "You can try loading the image with a different LUT or\n" +
                                    "Zero one of the LUTs or\n" +
                                    "Check the Overwrite Existing LUT checkbox");

                    ResChecker.Items.Remove(resource);
                    resource.Length = -1;
                }
            }
            else
            {
                resource.Length = -1;
            }
        }