Example #1
0
        public static DisplayList.Command G_SETIMG(TextureImage.TextureFormat fmt, TextureImage.BitsPerPixel size, int width, int segmentedPointer)
        {
            int uFD = ((int)fmt << 0x15) |
                      ((int)size << 0x13) |
                      (width - 1);

            return(new DisplayList.Command(0xFD, uFD, segmentedPointer));
        }
Example #2
0
        public static DisplayList.Command G_SETTILE(TextureImage.TextureFormat fmt, TextureImage.BitsPerPixel size, int line, int tmem, int tile, int pallete, TextureInfo.AddressMode cmS, int maskS, int shiftS, TextureInfo.AddressMode cmT, int maskT, int shiftT)
        {
            int uF5 = ((int)fmt << 0x15) |
                      ((int)size << 0x13) |
                      (line << 0x9) |
                      tmem;
            int lF5 = (tile << 0x18) |
                      (pallete << 0x14) |
                      ((int)cmS << 0x12) | (maskS << 0xE) | (shiftS << 0xA) |
                      ((int)cmT << 0x8) | (maskT << 0x4) | shiftT;

            return(new DisplayList.Command(0xF5, uF5, lF5));
        }
Example #3
0
 public void SetFormat(TextureImage.TextureFormat format, TextureImage.BitsPerPixel bpp)
 {
     if (isCustom)
     {
         customFormat = format;
         customBpp    = bpp;
     }
     else
     {
         image.bpp    = bpp;
         image.format = format;
     }
     UpdateSizeInfo();
 }
Example #4
0
        public void AppendCommands(List <DisplayList.Command> targetList, int materialOffset, RenderStates states)
        {
            TextureImage.BitsPerPixel  usedBpp    = isCustom ? customBpp : image.bpp;
            TextureImage.TextureFormat usedFormat = isCustom ? customFormat : image.format;
            int usedOffset = isCustom ? customAddress : image.segmentOffset;
            int actualBpp  = 4 << (int)usedBpp;

            int  tile        = 0;
            int  tmemOffset  = 0;
            bool ignoreShift = states.RCP_TexGen == RenderStates.RCP_OP.set || states.RCP_TexGenLinear == RenderStates.RCP_OP.set;
            int  shiftParamS = ignoreShift ? 0 : (16 - shiftS);
            int  shiftParamT = ignoreShift ? 0 : (16 - shiftT);

            customClampX = 4 * (width - 1);
            customClampY = 4 * (height - 1);

            targetList.Add(Commands.G_SETTILE(TextureImage.TextureFormat.G_IM_FMT_RGBA, usedBpp, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0));
            targetList.Add(new DisplayList.Command(0xE8)); //G_RDPTILESYNC
            if (usedFormat == TextureImage.TextureFormat.G_IM_FMT_CI)
            {
                targetList.Add(Commands.G_SETTILE(TextureImage.TextureFormat.G_IM_FMT_RGBA, TextureImage.BitsPerPixel.G_IM_SIZ_4b, 0, 0x100, tile, 0, AddressMode.G_TX_WRAP, 0, 0, AddressMode.G_TX_WRAP, 0, 0));
                targetList.Add(Commands.G_SETIMG(TextureImage.TextureFormat.G_IM_FMT_RGBA, TextureImage.BitsPerPixel.G_IM_SIZ_16b, 1, usedOffset));
                targetList.Add(Commands.G_LOADTLUT(tile, 1 << actualBpp));
                targetList.Add(new DisplayList.Command(0xBA, 0x000E02, 0x00008000));
                usedOffset += 2 << actualBpp;
            }

            //This does not seem to be correct for "line" parameter in G_SETTILE with some graphics plugins
            int line      = (Math.Min(0x10, actualBpp) * width + 63) / 64;
            int txl2words = Math.Max(1, (width * actualBpp / 64));
            int dxt       = ((1 << 0xB) + txl2words - 1) / txl2words;

            wrapExponentX = (int)Math.Log(width, 2);
            wrapExponentY = (int)Math.Log(height, 2);
            targetList.Add(Commands.G_SETTILE(usedFormat, usedBpp, line, tmemOffset, tile, 0, addressY, wrapExponentY, shiftParamT, addressX, wrapExponentX, shiftParamS));

            //Scrolling textures are achieved changing the uls and ult parameters of G_SETTILESIZE
            scrollingTextureRelativePointer = targetList.Count * 8;
            targetList.Add(Commands.G_SETTILESIZE(tile, 0, 0, customClampX, customClampY));
            targetList.Add(Commands.G_SETIMG(usedFormat, usedBpp, width, usedOffset));

            targetList.Add(new DisplayList.Command(0xE6)); //G_RDPLOADSYNC
            targetList.Add(Commands.G_LOADBLOCK(7, 0, 0, width * height, dxt));


            targetList.Add(new DisplayList.Command(0x03, 0x860010, materialOffset + materialIndex * 0x20));        //Light 1
            targetList.Add(new DisplayList.Command(0x03, 0x880010, materialOffset + materialIndex * 0x20 + 0x10)); //Light 2
        }
Example #5
0
        void UpdateControls()
        {
            if (selectedTexture == null)
            {
                return;
            }
            txtCustomAddress.Text     = selectedTexture.customAddress.ToString("X8");
            numericCustomWidth.Value  = selectedTexture.customWidth;
            numericCustomHeight.Value = selectedTexture.customHeight;
            chkCustomAddress.Checked  = selectedTexture.isCustom;
            cmbAddressX.SelectedIndex = (int)selectedTexture.addressX;
            cmbAddressY.SelectedIndex = (int)selectedTexture.addressY;

            TextureImage.TextureFormat usedFormat = selectedTexture.isCustom ? selectedTexture.customFormat : selectedTexture.image.format;
            TextureImage.BitsPerPixel  usedBpp    = selectedTexture.isCustom ? selectedTexture.customBpp : selectedTexture.image.bpp;
            if (usedFormat == TextureImage.TextureFormat.G_IM_FMT_RGBA)
            {
                if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_16b)
                {
                    cmbFormat.SelectedIndex = 0;
                }
                else if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_32b)
                {
                    cmbFormat.SelectedIndex = 1;
                }
            }
            else if (usedFormat == TextureImage.TextureFormat.G_IM_FMT_CI)
            {
                if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_4b)
                {
                    cmbFormat.SelectedIndex = 2;
                }
                else if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_8b)
                {
                    cmbFormat.SelectedIndex = 3;
                }
            }
            else if (usedFormat == TextureImage.TextureFormat.G_IM_FMT_IA)
            {
                if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_4b)
                {
                    cmbFormat.SelectedIndex = 4;
                }
                else if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_8b)
                {
                    cmbFormat.SelectedIndex = 5;
                }
                else if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_16b)
                {
                    cmbFormat.SelectedIndex = 6;
                }
            }
            else if (usedFormat == TextureImage.TextureFormat.G_IM_FMT_I)
            {
                if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_4b)
                {
                    cmbFormat.SelectedIndex = 7;
                }
                else if (usedBpp == TextureImage.BitsPerPixel.G_IM_SIZ_8b)
                {
                    cmbFormat.SelectedIndex = 8;
                }
            }

            pointerScrollingTextures.SetRAMPointers(selectedTexture.stRAMPointers);
            pointerScrollingTextures.SetROMPointers(selectedTexture.stROMPointers);
        }
Example #6
0
        public static void ConvertRGBA(TextureImage.TextureFormat format, TextureImage.BitsPerPixel bpp, Bitmap source, byte[] outputStream, ref int cursor)
        {
            //Convert image to RGBA if necessary
            bool   createRGBA_convert = source.PixelFormat != PixelFormat.Format32bppArgb;
            Bitmap RGBAconvert        = createRGBA_convert ? new Bitmap(source.Width, source.Height, PixelFormat.Format32bppPArgb) : source;

            if (source.PixelFormat != PixelFormat.Format32bppArgb)
            {
                using (Graphics gr = Graphics.FromImage(RGBAconvert))
                    gr.DrawImage(source, new Rectangle(0, 0, RGBAconvert.Width, RGBAconvert.Height));
            }


            if (format == TextureImage.TextureFormat.G_IM_FMT_CI)
            {
                int    colors    = bpp == TextureImage.BitsPerPixel.G_IM_SIZ_4b ? 16 : 256;
                Bitmap quantized = (Bitmap)quantizer.QuantizeImage(RGBAconvert, colors);
                for (int i = 0; i < colors; i++)
                {
                    Color c = quantized.Palette.Entries[i];
                    WriteRGBA16(ref cursor, outputStream, c.R, c.G, c.B, c.A);
                }
                cursor = ((cursor + 0xF) / 0x10) * 0x10; //Align cursor to multiple of 16 bytes (8 would probably work fine, too)
                //Put image data into pixelData
                BitmapData data = quantized.LockBits(new Rectangle(0, 0, RGBAconvert.Width, RGBAconvert.Height), ImageLockMode.ReadOnly, quantized.PixelFormat);
                int        stride = data.Stride, width = data.Width, height = data.Height;
                byte[]     indexData = new byte[stride * data.Height];
                Marshal.Copy(data.Scan0, indexData, 0, indexData.Length);
                quantized.UnlockBits(data);
                //Write each pixel into the output stream
                if (bpp == TextureImage.BitsPerPixel.G_IM_SIZ_4b)
                {
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x += 2)
                        {
                            outputStream[cursor++] = (byte)((indexData[y * stride + x] << 0x4) | indexData[y * stride + x + 1]);
                        }
                    }
                }
                else
                {
                    for (int y = 0; y < height; y++)
                    {
                        for (int x = 0; x < width; x++)
                        {
                            outputStream[cursor++] = indexData[y * stride + x];
                        }
                    }
                }
            }
            else
            {
                //Put image data into pixelData
                BitmapData data = RGBAconvert.LockBits(new Rectangle(0, 0, RGBAconvert.Width, RGBAconvert.Height), ImageLockMode.ReadOnly, RGBAconvert.PixelFormat);
                int        stride = data.Stride / 4, width = data.Width, height = data.Height;
                byte[]     rgbaData = new byte[stride * data.Height * 4];
                Marshal.Copy(data.Scan0, rgbaData, 0, rgbaData.Length);
                RGBAconvert.UnlockBits(data);
                PixelDataWriter writer = writers[(int)format, (int)bpp];
                if (writer == null)
                {
                    throw new Exception("Unsupported format " + format.ToString() + " / " + bpp.ToString() + "!");
                }
                //Write each pixel into the output stream
                halfByte = false;
                for (int y = 0; y < height; y++)
                {
                    for (int x = 0; x < width; x++)
                    {
                        int i = (x + stride * (height - (y + 1))) * 4;
                        writer(ref cursor, outputStream, rgbaData[i + 2], rgbaData[i + 1], rgbaData[i + 0], rgbaData[i + 3]);
                    }
                }
            }
            if (createRGBA_convert)
            {
                RGBAconvert.Dispose();
            }
        }