private void update() { clear_background(CONST_BACKGROUND_COLOR); // sprite data drawing if (m_spr_data != null) { disable(false); draw_chars(); if (m_selected_CHR >= 0 && m_mode == EMode.m_build) { // draw a frame of the selected CHR CHR_data_attr chr_attr = m_spr_data.get_CHR_attr()[m_selected_CHR]; CHR_data chr_data = m_spr_data.get_CHR_data().get_data()[chr_attr.CHR_ind]; float chr_scr_pos_x = transform_to_scr_pos(chr_attr.x + m_offset_x + m_spr_data.offset_x, m_scr_half_width); float chr_scr_pos_y = transform_to_scr_pos(chr_attr.y + m_offset_y + m_spr_data.offset_y, m_scr_half_height); float CHR_height = get_CHR_height(); m_pen.Color = Color.Red; m_gfx.DrawRectangle(m_pen, chr_scr_pos_x, chr_scr_pos_y, m_CHR_size, CHR_height); m_pen.Color = Color.White; m_gfx.DrawRectangle(m_pen, chr_scr_pos_x - 1, chr_scr_pos_y - 1, m_CHR_size + 2, CHR_height + 2); #if DEF_NES m_label.Text = "Pos: " + chr_attr.x + ";" + chr_attr.y + " / Palette: " + (chr_attr.palette_ind + 1) + " / Id: " + chr_attr.CHR_ind + " / Tiles: " + m_spr_data.get_CHR_attr().Count; #elif DEF_SMS || DEF_PCE m_label.Text = "Pos: " + chr_attr.x + ";" + chr_attr.y + " / Id: " + chr_attr.CHR_ind + " / Tiles: " + m_spr_data.get_CHR_attr().Count;
private void Layout_MouseUp(object sender, MouseEventArgs e) { if (m_mouse_in_area_bounds) { if (m_mode == EMode.m_draw) { if (m_pix_box.Capture && e.Button == MouseButtons.Left) { m_changed_pixel_x = -1; m_changed_pixel_y = -1; } } else if (m_mode == EMode.m_build) { if (m_pix_box.Capture && m_selected_CHR >= 0 && e.Button == MouseButtons.Right) { CHR_data_attr chr_attr = m_spr_data.get_CHR_attr()[m_selected_CHR]; int x_pos = chr_attr.x + m_spr_data.offset_x + ((snap == true) ? (utils.CONST_CHR_SIDE_PIXELS_CNT >> 1):0); int y_pos = chr_attr.y + m_spr_data.offset_y + ((snap == true) ? (utils.CONST_CHR_SIDE_PIXELS_CNT >> 1):0); get_snapped_pos(x_pos, y_pos, out x_pos, out y_pos); chr_attr.x = x_pos - m_spr_data.offset_x; chr_attr.y = y_pos - m_spr_data.offset_y; m_spr_data.update_dimensions(); update(); } } } }
private void check_and_update_pixel(int _X, int _Y) { calc_selected_CHR(_X, _Y); if (m_selected_CHR >= 0) { int img_x_pos = transform_to_img_pos(_X, m_scr_half_width, m_offset_x); int img_y_pos = transform_to_img_pos(_Y, m_scr_half_height, m_offset_y); CHR_data_attr chr_attr = m_spr_data.get_CHR_attr()[m_selected_CHR]; int spr_height = m_mode8x16 ? utils.CONST_CHR_SIDE_PIXELS_CNT << 1:utils.CONST_CHR_SIDE_PIXELS_CNT; m_changed_pixel_x = (img_x_pos - (m_spr_data.offset_x + chr_attr.x)) % utils.CONST_CHR_SIDE_PIXELS_CNT; m_changed_pixel_y = (img_y_pos - (m_spr_data.offset_y + chr_attr.y)) % spr_height; if ((chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_HFLIP) > 0) { m_changed_pixel_x = utils.CONST_CHR_SIDE_PIXELS_CNT - m_changed_pixel_x - 1; } if ((chr_attr.flip_flag & CHR_data_attr.CONST_CHR_ATTR_FLAG_VFLIP) > 0) { m_changed_pixel_y = (m_mode8x16 ? (utils.CONST_CHR_SIDE_PIXELS_CNT << 1):utils.CONST_CHR_SIDE_PIXELS_CNT) - m_changed_pixel_y - 1; } if (UpdatePixel != null) { UpdatePixel(this, null); } update(); } }
public static Bitmap create_CHR_bitmap(CHR_data _chr_data, CHR_data_attr _attr, bool _alpha, int _plt_ind, palette_small[] _plt_arr = null) { Bitmap bmp = new Bitmap(CONST_CHR_SIDE_PIXELS_CNT, CONST_CHR_SIDE_PIXELS_CNT, PixelFormat.Format32bppPArgb); update_CHR_bitmap(_chr_data, bmp, _attr, _alpha, _plt_ind, _plt_arr); return(bmp); }
public CHR_data_attr copy() { CHR_data_attr attr = new CHR_data_attr(x, y); attr.m_flip_flag = flip_flag; attr.palette_ind = palette_ind; attr.CHR_ind = CHR_ind; return(attr); }
public static void update_CHR_bitmap(CHR_data _chr_data, Bitmap _bmp, CHR_data_attr _attr, bool _alpha, int _plt_ind, palette_small[] _plt_arr) { BitmapData bmp_data = _bmp.LockBits(new Rectangle(0, 0, _bmp.Width, _bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb); if (bmp_data != null) { fill_CHR_bmp_data(bmp_data.Scan0, 0, _chr_data, _attr, _alpha, _plt_ind, _plt_arr); _bmp.UnlockBits(bmp_data); flip_bmp(_bmp, (_attr != null ? _attr.flip_flag:0)); } }
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)); }
private void Layout_MouseMove(object sender, MouseEventArgs e) { if (m_mouse_in_area_bounds) { if (m_pix_box.Capture && e.Button == MouseButtons.Left) { if (m_mode == EMode.m_build) { m_offset_x += e.X - m_last_mouse_x; m_offset_y += e.Y - m_last_mouse_y; clamp_offsets(); m_last_mouse_x = e.X; m_last_mouse_y = e.Y; update(); } else if (m_mode == EMode.m_draw && m_spr_data != null) { check_and_update_pixel(e.X, e.Y); } } if (m_mode == EMode.m_build) { if (m_pix_box.Capture && m_selected_CHR >= 0 && e.Button == MouseButtons.Right) { CHR_data_attr chr_attr = m_spr_data.get_CHR_attr()[m_selected_CHR]; int x_pos = transform_to_img_pos(e.X, m_scr_half_width, m_offset_x); int y_pos = transform_to_img_pos(e.Y, m_scr_half_height, m_offset_y); chr_attr.x += x_pos - m_last_mouse_x; chr_attr.y += y_pos - m_last_mouse_y; m_last_mouse_x = x_pos; m_last_mouse_y = y_pos; update(); } } } }
private void Layout_MouseDown(object sender, MouseEventArgs e) { if (m_mouse_in_area_bounds) { if (m_mode == EMode.m_build) { if (e.Button == MouseButtons.Left) { m_last_mouse_x = e.X; m_last_mouse_y = e.Y; } if (m_selected_CHR >= 0 && e.Button == MouseButtons.Right) { CHR_data_attr chr_attr = m_spr_data.get_CHR_attr()[m_selected_CHR]; int chr_pos_x = ( int )transform_to_scr_pos(chr_attr.x + m_offset_x + m_spr_data.offset_x, m_scr_half_width); int chr_pos_y = ( int )transform_to_scr_pos(chr_attr.y + m_offset_y + m_spr_data.offset_y, m_scr_half_height); if (e.X > chr_pos_x && e.X < chr_pos_x + m_CHR_size && e.Y > chr_pos_y && e.Y < chr_pos_y + get_CHR_height()) { m_last_mouse_x = transform_to_img_pos(e.X, m_scr_half_width, m_offset_x); m_last_mouse_y = transform_to_img_pos(e.Y, m_scr_half_height, m_offset_y); } else { m_selected_CHR = -1; dispatch_event_set_selected_CHR(); update(); } } } } }
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); }
private sprite_params cut_CHRs(sprite_params _spr_params, int _min_x, int _max_x, int _min_y, int _max_y, List <byte[]> _lines_arr, bool _alpha, int _alpha_ind, int _num_colors, bool _crop_image, int _palette_slot) { // cut sprite by tiles 8x8 { _spr_params.m_offset_x = _min_x; _spr_params.m_offset_y = _min_y; int dx_incr = _max_x - _min_x + 1; int dy_incr = _max_y - _min_y + 1; _spr_params.m_size_x = ((dx_incr % utils.CONST_CHR_SIDE_PIXELS_CNT != 0) ? (((dx_incr) + utils.CONST_CHR_SIDE_PIXELS_CNT) & -utils.CONST_CHR_SIDE_PIXELS_CNT):dx_incr) >> utils.CONST_CHR_SIDE_PIXELS_CNT_POW_BITS; _spr_params.m_size_y = ((dy_incr % utils.CONST_CHR_SIDE_PIXELS_CNT != 0) ? (((dy_incr) + utils.CONST_CHR_SIDE_PIXELS_CNT) & -utils.CONST_CHR_SIDE_PIXELS_CNT):dy_incr) >> utils.CONST_CHR_SIDE_PIXELS_CNT_POW_BITS; int x; int y; int i; byte[] pixels_line = null; byte[] pixels_row = new byte[utils.CONST_CHR_SIDE_PIXELS_CNT]; int n_lines = _lines_arr.Count; CHR_data chr_data = null; CHR_data_attr chr_attr = null; int chr_pos_x = 0; int chr_pos_y = 0; byte pix_ind = 0; int num_row_pixs = 0; int pix_acc = 0; int col_n; int row_n; int x_offset = 0; for (y = 0; y < _spr_params.m_size_y; y++) { x_offset = 0; for (x = 0; x < _spr_params.m_size_x; x++) { chr_pos_x = x * utils.CONST_CHR_SIDE_PIXELS_CNT; chr_pos_y = y * utils.CONST_CHR_SIDE_PIXELS_CNT; pix_acc = 0; chr_data = new CHR_data(); chr_attr = new CHR_data_attr(chr_pos_x, chr_pos_y); #if DEF_FIXED_LEN_PALETTE16_ARR chr_attr.palette_ind = _palette_slot; #endif chr_pos_x += _min_x; chr_pos_y += _min_y; // calc first non zero column if (_alpha) { pix_acc = 0; chr_pos_x += x_offset; for (col_n = 0; col_n < utils.CONST_CHR_SIDE_PIXELS_CNT; col_n++) { for (row_n = 0; row_n < utils.CONST_CHR_SIDE_PIXELS_CNT; row_n++) { pixels_line = (chr_pos_y + row_n < _lines_arr.Count) ? _lines_arr[chr_pos_y + row_n]:null; pix_ind = (chr_pos_x + col_n <= _max_x) ? (pixels_line != null ? pixels_line[chr_pos_x + col_n]:(_alpha ? (byte)_alpha_ind:(byte)0)):(_alpha ? (byte)_alpha_ind:(byte)0); if (_alpha && (_alpha_ind != 0)) { pix_ind += ( byte )(_num_colors - _alpha_ind); pix_ind %= ( byte )_num_colors; } pix_acc += pix_ind; } if (pix_acc != 0) { x_offset += col_n; chr_pos_x += col_n; chr_attr.x += x_offset; break; } } if (col_n == utils.CONST_CHR_SIDE_PIXELS_CNT) { continue; } } for (i = 0; i < utils.CONST_CHR_SIDE_PIXELS_CNT; i++) { pixels_line = (chr_pos_y + i < _lines_arr.Count) ? _lines_arr[chr_pos_y + i]:null; // copy line num_row_pixs = 0; do { pix_ind = (chr_pos_x + num_row_pixs <= _max_x) ? (pixels_line != null ? pixels_line[chr_pos_x + num_row_pixs]:(_alpha ? (byte)_alpha_ind:(byte)0)):(_alpha ? (byte)_alpha_ind:(byte)0); // fix the pixel index so that the first one will be transparency index if (_alpha && (_alpha_ind != 0)) { pix_ind += ( byte )(_num_colors - _alpha_ind); pix_ind %= ( byte )_num_colors; } pix_acc += pix_ind; pixels_row[num_row_pixs] = pix_ind; }while(++num_row_pixs < utils.CONST_CHR_SIDE_PIXELS_CNT); chr_data.push_line(pixels_row); } // save non-zero tile if (!_crop_image || (pix_acc != 0 || !_alpha)) { chr_attr.CHR_ind = m_CHR_arr.Count; _spr_params.m_CHR_attr.Add(chr_attr); m_CHR_arr.Add(chr_data); if (m_CHR_arr.Count >= utils.CONST_CHR_BANK_MAX_SPRITES_CNT) { break; } } } if (m_CHR_arr.Count >= utils.CONST_CHR_BANK_MAX_SPRITES_CNT) { MainForm.message_box("The CHR bank is full!", "Data Import", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Warning); break; } } } // convert tiles into pixels _spr_params.m_size_x <<= utils.CONST_CHR_SIDE_PIXELS_CNT_POW_BITS; _spr_params.m_size_y <<= utils.CONST_CHR_SIDE_PIXELS_CNT_POW_BITS; return(_spr_params); }
private static void fill_CHR_bmp_data(IntPtr _data_ptr, int _data_offset, CHR_data _chr_data, CHR_data_attr _attr, bool _alpha, int _plt_ind, palette_small[] _plt_arr) { unsafe { int *img_buff = ( int * )(_data_ptr + _data_offset); #if DEF_NES bool apply_palette = (_plt_arr != null && _plt_ind >= 0); int[] clr_inds = apply_palette ? _plt_arr[_plt_ind].get_color_inds():null; int alpha; #endif int clr = 0; int pix_ind; for (int p = 0; p < CONST_CHR_TOTAL_PIXELS_CNT; p++) { pix_ind = _chr_data.get_data()[p]; #if DEF_NES if (apply_palette) #endif { #if DEF_NES clr = palette_group.Instance.main_palette[clr_inds[pix_ind]]; #elif DEF_SMS clr = palette_group.Instance.main_palette[palette_group.Instance.get_palettes_arr()[pix_ind / CONST_NUM_SMALL_PALETTES].get_color_inds()[pix_ind % CONST_NUM_SMALL_PALETTES]]; #endif #if DEF_FIXED_LEN_PALETTE16_ARR if (_attr != null) { clr = palette_group.Instance.main_palette[palettes_array.Instance.get_color((_attr.palette_ind < 0 ? 0:_attr.palette_ind), pix_ind)]; } else { clr = palette_group.Instance.main_palette[palette_group.Instance.get_palettes_arr()[pix_ind / CONST_NUM_SMALL_PALETTES].get_color_inds()[pix_ind % CONST_NUM_SMALL_PALETTES]]; } #endif if ((pix_ind != 0 && _alpha == true) || _alpha == false) { clr |= 0xFF << 24; } } #if DEF_NES else { alpha = (pix_ind == 0) ? (_alpha ? 0x00:0xFF):0xFF; pix_ind <<= 6; clr = alpha << 24 | pix_ind << 16 | pix_ind << 8 | pix_ind; } #endif img_buff[p] = clr; } } }
public static void update_bitmap8x16(CHR_data _chr_data1, CHR_data _chr_data2, Bitmap _bmp, CHR_data_attr _attr, bool _alpha, int _plt_ind, palette_small[] _plt_arr) { BitmapData bmp_data = _bmp.LockBits(new Rectangle(0, 0, _bmp.Width, _bmp.Height), ImageLockMode.ReadWrite, PixelFormat.Format32bppPArgb); if (bmp_data != null) { fill_CHR_bmp_data(bmp_data.Scan0, 0, _chr_data1, _attr, _alpha, _plt_ind, _plt_arr); if (_chr_data2 != null) { fill_CHR_bmp_data(bmp_data.Scan0, (8 * bmp_data.Stride), _chr_data2, _attr, _alpha, _plt_ind, _plt_arr); _bmp.UnlockBits(bmp_data); } else { _bmp.UnlockBits(bmp_data); Graphics gfx = Graphics.FromImage(_bmp); utils.brush.Color = Color.Red; gfx.FillRectangle(utils.brush, 0, 8, 8, 8); gfx.Flush(); } flip_bmp(_bmp, (_attr != null ? _attr.flip_flag:0)); } }
public static Bitmap create_bitmap8x16(CHR_data _chr_data1, CHR_data _chr_data2, CHR_data_attr _attr, bool _alpha, int _plt_ind, palette_small[] _plt_arr = null) { Bitmap bmp = new Bitmap(8, 16, PixelFormat.Format32bppPArgb); update_bitmap8x16(_chr_data1, _chr_data2, bmp, _attr, _alpha, _plt_ind, _plt_arr); return(bmp); }