예제 #1
0
        public bool merge_CHR(sprite_data _spr, SPReD.CHR_data_group.ECHRPackingType _packing_type, bool _mode8x16)
        {
            // check if data were already packed
            if (_spr.is_packed(_mode8x16))
            {
                return(false);
            }

            int last_CHR_cnt = get_CHR_data().get_data().Count;

            CHR_data_group spr_chr_data = _spr.get_CHR_data();

            get_CHR_data().add_data_range(spr_chr_data);

            int i;
            int size = _spr.get_CHR_attr().Count;

            for (i = 0; i < size; i++)
            {
                _spr.get_CHR_attr()[i].CHR_ind += last_CHR_cnt;
            }

            _spr.set_CHR_data(this.get_CHR_data());

            return(true);
        }
예제 #2
0
        public sprite_data copy(string _name, CHR_data_group _chr_data_group, List <CHR_data_attr> _chr_attrs)
        {
            sprite_params spr_params;

            spr_params.m_CHR_data = (_chr_data_group != null) ? _chr_data_group:m_CHR_data;
            spr_params.m_offset_x = m_offset_x;
            spr_params.m_offset_y = m_offset_y;
            spr_params.m_size_x   = m_size_x;
            spr_params.m_size_y   = m_size_y;
            spr_params.m_CHR_attr = new List <CHR_data_attr>(m_CHR_attr.Count);

            if (_chr_attrs == null)
            {
                m_CHR_attr.ForEach(delegate(CHR_data_attr _attr) { spr_params.m_CHR_attr.Add(_attr.copy()); });
            }
            else
            {
                spr_params.m_CHR_attr = _chr_attrs;
            }

            sprite_data spr = new sprite_data(_name);

            spr.setup(spr_params);

            return(spr);
        }
예제 #3
0
        public sprite_data load_sprite_png(string _filename, string _name, bool _apply_palette, bool _crop_image, int _palette_slot)
        {
            PngReader png_reader = FileHelper.CreatePngReader(_filename);

            try
            {
                if (!png_reader.ImgInfo.Indexed)
                {
                    throw new Exception(_filename + "\n\nNot indexed image!");
                }

                if (png_reader.IsInterlaced())
                {
                    throw new Exception(_filename + "\n\nOnly non interlaced .PNG images are supported!");
                }

//				if( ( png_reader.ImgInfo.Cols & 0x07 ) != 0 || ( png_reader.ImgInfo.Rows & 0x07 ) != 0 )
//				{
//					png_reader.End();
//					throw new Exception( _filename + "\n\nThe image size must be a multiple of 8 !" );
//				}

//				if( ( ( png_reader.ImgInfo.Cols >> 3 ) * ( png_reader.ImgInfo.Rows >> 3 ) ) > utils.CONST_CHR_BANK_MAX_SPRITES_CNT )
//				{
//					png_reader.End();
//					throw new Exception( _filename + "\n\nThe imported image contains more than " + utils.CONST_CHR_BANK_MAX_SPRITES_CNT + " CHRs!" );
//				}

#if DEF_NES
                if (png_reader.GetMetadata().GetPLTE().MinBitDepth() != 2)
                {
                    throw new Exception(_filename + "\n\nThe PNG image must have a 4 colors palette!");
                }
#elif DEF_SMS || DEF_PCE
                int img_bit_depth = png_reader.GetMetadata().GetPLTE().MinBitDepth();

                if (img_bit_depth != 4 && img_bit_depth != 2)
                {
                    throw new Exception(_filename + "\n\nThe PNG image must have a 4 or 2 bpp color depth!");
                }

                if (png_reader.GetMetadata().GetPLTE().GetNentries() > 16)
                {
                    throw new Exception(_filename + "\n\nThe PNG image must have a 16 or 4 colors palette!");
                }
#else
                ...
#endif
                sprite_params spr_params = m_CHR_data_storage.create(png_reader, _apply_palette, _crop_image, _palette_slot);

                sprite_data spr = new sprite_data(_name);
                spr.setup(spr_params);

                spr.update_dimensions();

                png_reader.End();

                return(spr);
            }
        public static void export_CHR_data(sprite_data _spr, string _filename)
        {
            int i;

            List <CHR_data_attr> attrs = _spr.get_CHR_attr();

            int[] exp_attrs     = new int[attrs.Count];
            int   exp_attrs_pos = 0;

            bool[] attr_usage = new bool[attrs.Count];                                          // used attributes

            Array.Clear(attr_usage, 0, attr_usage.Length);

            // collect sprite patterns
            {
                // 32x64
                for (i = 0; i < attrs.Count; i++)
                {
                    search_pattern(_spr, attrs[i], exp_attrs, ref exp_attrs_pos, attr_usage, 8);
                }

                // 32x32
                for (i = 0; i < attrs.Count; i++)
                {
                    search_pattern(_spr, attrs[i], exp_attrs, ref exp_attrs_pos, attr_usage, 4);
                }

                // 32x16
                for (i = 0; i < attrs.Count; i++)
                {
                    search_pattern(_spr, attrs[i], exp_attrs, ref exp_attrs_pos, attr_usage, 2);
                }

                // 16x16
                for (i = 0; i < attrs.Count; i++)
                {
                    search_pattern(_spr, attrs[i], exp_attrs, ref exp_attrs_pos, attr_usage, 1);
                }
            }

            // save collected patterns
            {
                BinaryWriter bw = new BinaryWriter(File.Open(_filename, FileMode.Create));

                for (i = 0; i < exp_attrs.Length; i++)
                {
                    save_CHR(bw, _spr.get_CHR_data().get_data()[attrs[exp_attrs[i]].CHR_ind]);
                }

                bw.Dispose();
            }
        }
        public static void save_attribute(StreamWriter _sw, sprite_data _spr, CHR_data_attr _chr_attr, int _cgx_cgy, int _CHRs_offset, int _CHR_ind_offset, int _palette_slot)
        {
            if (_chr_attr.CHR_ind + _CHRs_offset >= utils.CONST_PCE_MAX_SPRITES_CNT)
            {
                throw new Exception("CHRs indices overflow! Invalid CHRs offset value!");
            }

            int attr = (_chr_attr.palette_ind + _palette_slot) & 0x0f;

            attr |= _cgx_cgy;
            attr |= ((_chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_HFLIP) != 0) ? (1 << 11):0;
            attr |= ((_chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_VFLIP) != 0) ? (1 << 15):0;
            attr |= 1 << 7;             // sprite priority

            _sw.WriteLine("\t.word " + String.Format("${0:X2}, ${1:X2}, ${2:X2}, ${3:X2}", unchecked (( ushort )(_spr.offset_y + _chr_attr.y)), unchecked (( ushort )(_spr.offset_x + _chr_attr.x)), unchecked (( ushort )((_chr_attr.CHR_ind + _CHR_ind_offset + _CHRs_offset) << 1)), ( ushort )attr));
        }
예제 #6
0
        public void reset()
        {
            {
                m_sprite_layout_viewer.reset();

                sprite_data spr = null;
                m_sprite_layout_viewer.init(spr);
            }
            {
                m_CHR_bank_viewer.reset();
            }

            m_CHR_data_storage.reset();

            CHR_data_group.reset_ids_cnt();
        }
예제 #7
0
        public void reset()
        {
            m_offset_x = m_scr_half_width;
            m_offset_y = m_scr_half_height;

            m_changed_pixel_x = -1;
            m_changed_pixel_y = -1;

            m_scale = 2;
            update_status_label();

            m_selected_CHR = -1;

            clear_background(CONST_BACKGROUND_COLOR);

            m_spr_data = null;

            m_bmp_list.ForEach(delegate(Bitmap _bmp) { _bmp.Dispose(); });
            m_bmp_list.Clear();

            m_label.Text = "...";
        }
        public static int get_CGX_CGY_flags(sprite_data _spr, ref int _CHR_ind_offset)
        {
            int res = 0;

            int size_x = _spr.size_x;
            int size_y = _spr.size_y;

            List <CHR_data_attr> attrs = _spr.get_CHR_attr();

            if (size_x == 32)
            {
                string lower_name = _spr.name.ToLower();

                bool s16x_0 = lower_name.Contains("16x32_0") || lower_name.Contains("16x64_0");
                bool s16x_1 = lower_name.Contains("16x32_1") || lower_name.Contains("16x64_1");

                if (s16x_0 || s16x_1)
                {
                    if (size_y == 32 && attrs.Count == 4)
                    {
                        res = 0x10;
                    }
                    else
                    if (size_y == 64 && attrs.Count == 8)
                    {
                        res = 0x30;
                    }

                    if (res != 0)
                    {
                        if (s16x_1)
                        {
                            _CHR_ind_offset = 1;
                        }
                        else
                        {
                            _CHR_ind_offset = 0;
                        }
                    }
                }
                else
                {
                    if (size_y == 16 && attrs.Count == 2)
                    {
                        res = 0x01;
                    }
                    else
                    if (size_y == 32 && attrs.Count == 4)
                    {
                        res = 0x11;
                    }
                    else
                    if (size_y == 64 && attrs.Count == 8)
                    {
                        res = 0x31;
                    }
                }
            }

            if (res != 0)
            {
                // check coordinates multiples of 16
                CHR_data_attr attr;

                int x;
                int y;

                int offs_x = attrs[0].x;
                int offs_y = attrs[0].y;

                for (int i = 1; i < attrs.Count; i++)
                {
                    attr = attrs[i];

                    x = attr.x - offs_x;
                    y = attr.y - offs_y;

                    if ((x != 0 && ((x - 1) & 0x0f) != 0x0f) || (y != 0 && ((y - 1) & 0x0f) != 0x0f))
                    {
                        res             = 0;
                        _CHR_ind_offset = 0;

                        break;
                    }
                }
            }

            return(res << 8);
        }
        public static void export_sprite(StreamWriter _sw, sprite_data _spr, int _CHRs_offset, int _palette_slot, string _data_prefix)
        {
            int i;
            int num_sprites = 0;

            List <CHR_data_attr> attrs = _spr.get_CHR_attr();

            int[] exp_attrs     = new int[attrs.Count];
            int   exp_attrs_pos = 0;

            bool[] attr_usage = new bool[attrs.Count];                                          // used attributes

            int offset_x = _spr.offset_x;
            int offset_y = _spr.offset_y;

            CHR_data_attr chr_attr;

            Array.Clear(attr_usage, 0, attr_usage.Length);

            _sw.WriteLine(_data_prefix + _spr.name + ":");

            _sw.WriteLine("\t.word " + _data_prefix + _spr.name + "_end - " + _data_prefix + _spr.name + " - 3\t; data size");
            _sw.WriteLine("\t.byte " + _spr.get_CHR_data().id + "\t\t; GFX bank index (" + _spr.get_CHR_data().name + ")\n");

            // collect sprite patterns
            {
                // 32x64
                for (i = 0; i < attrs.Count; i++)
                {
                    chr_attr = attrs[i];

                    if (search_pattern(_spr, chr_attr, exp_attrs, ref exp_attrs_pos, attr_usage, 8))
                    {
                        chr_attr         = chr_attr.copy();
                        chr_attr.CHR_ind = exp_attrs_pos - 8;

                        if ((chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_HFLIP) != 0)
                        {
                            chr_attr.x -= utils.CONST_CHR_SIDE_PIXELS_CNT;
                        }

                        if ((chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_VFLIP) != 0)
                        {
                            chr_attr.y -= utils.CONST_CHR_SIDE_PIXELS_CNT * 3;
                        }

                        save_attribute(_sw, _spr, chr_attr, 0x31 << 8, _CHRs_offset, 0, _palette_slot);

                        ++num_sprites;
                    }
                }

                // 32x32
                for (i = 0; i < attrs.Count; i++)
                {
                    chr_attr = attrs[i];

                    if (search_pattern(_spr, chr_attr, exp_attrs, ref exp_attrs_pos, attr_usage, 4))
                    {
                        chr_attr         = chr_attr.copy();
                        chr_attr.CHR_ind = exp_attrs_pos - 4;

                        if ((chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_HFLIP) != 0)
                        {
                            chr_attr.x -= utils.CONST_CHR_SIDE_PIXELS_CNT;
                        }

                        if ((chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_VFLIP) != 0)
                        {
                            chr_attr.y -= utils.CONST_CHR_SIDE_PIXELS_CNT;
                        }

                        save_attribute(_sw, _spr, chr_attr, 0x11 << 8, _CHRs_offset, 0, _palette_slot);

                        ++num_sprites;
                    }
                }

                // 32x16
                for (i = 0; i < attrs.Count; i++)
                {
                    chr_attr = attrs[i];

                    if (search_pattern(_spr, chr_attr, exp_attrs, ref exp_attrs_pos, attr_usage, 2))
                    {
                        chr_attr         = chr_attr.copy();
                        chr_attr.CHR_ind = exp_attrs_pos - 2;

                        if ((chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_HFLIP) != 0)
                        {
                            chr_attr.x -= utils.CONST_CHR_SIDE_PIXELS_CNT;
                        }

                        save_attribute(_sw, _spr, chr_attr, 0x01 << 8, _CHRs_offset, 0, _palette_slot);

                        ++num_sprites;
                    }
                }

                // 16x16
                for (i = 0; i < attrs.Count; i++)
                {
                    chr_attr = attrs[i];

                    if (search_pattern(_spr, chr_attr, exp_attrs, ref exp_attrs_pos, attr_usage, 1))
                    {
                        chr_attr         = chr_attr.copy();
                        chr_attr.CHR_ind = exp_attrs_pos - 1;

                        save_attribute(_sw, _spr, chr_attr, 0, _CHRs_offset, 0, _palette_slot);

                        ++num_sprites;
                    }
                }
            }

            _sw.WriteLine(_data_prefix + _spr.name + "_end:\n");

            if (num_sprites > utils.CONST_SPRITE_MAX_NUM_ATTRS)
            {
                throw new Exception("The sprite - " + _spr.name + " - has more than " + utils.CONST_SPRITE_MAX_NUM_ATTRS.ToString() + " tiles that exceed the hardware limit!\n Please, fix it to avoid the sprite drawing error in your project!");
            }
        }
        private static bool search_pattern(sprite_data _spr, CHR_data_attr _attr, int[] _exp_attrs, ref int _exp_attrs_pos, bool[] _attr_usage, int _max_pttrn_sprts)
        {
            CHR_data_attr attr;

            int i;

            int[] pttrn_inds = new int[8];                      // max 32x64
            int   pttrn_pos  = 0;

            int offset_x;
            int offset_y;
            int ptrn_pos_x;
            int ptrn_pos_y;

            List <CHR_data_attr> attrs = _spr.get_CHR_attr();

            for (i = 0; i < attrs.Count; i++)
            {
                attr = attrs[i];

                if ((attr.palette_ind == _attr.palette_ind) && (_attr_usage[i] == false))
                {
                    offset_x = attr.x - _attr.x;
                    offset_y = attr.y - _attr.y;

                    ptrn_pos_x = pattern_arr[pttrn_pos << 1];
                    ptrn_pos_y = pattern_arr[(pttrn_pos << 1) + 1];

                    if ((attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_HFLIP) != 0)
                    {
                        if ((pttrn_pos & 0x01) != 0)
                        {
                            offset_x = -offset_x;
                        }
                    }

                    if ((attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_VFLIP) != 0)
                    {
                        offset_y = -offset_y;
                    }

                    if (ptrn_pos_x == offset_x && ptrn_pos_y == offset_y)
                    {
                        pttrn_inds[pttrn_pos] = i;
                        ++pttrn_pos;

                        if (pttrn_pos == _max_pttrn_sprts)
                        {
                            break;
                        }
                    }
                }
            }

            if (pttrn_pos == _max_pttrn_sprts)
            {
                for (i = 0; i < _max_pttrn_sprts; i++)
                {
                    _attr_usage[pttrn_inds[i]] = true;

                    _exp_attrs[_exp_attrs_pos] = pttrn_inds[i];

                    ++_exp_attrs_pos;
                }

                return(true);
            }

            return(false);
        }