public void Reset(bool force = false) { if (!bitmapCpc.isCalc || force) { int startImg = force ? 0 : selImage; int endImg = force ? maxImage : selImage; for (int i = startImg; i < endImg; i++) { selImage = i; int col = System.Drawing.SystemColors.Control.ToArgb(); for (int y = 0; y < tabBmpLock[i].Height; y += 2) { int startX = y < BitmapCpc.TailleY ? BitmapCpc.TailleX : 0; tabBmpLock[i].SetHorLineDouble(0, y, startX, GetPalCPC(BitmapCpc.Palette[0])); tabBmpLock[i].SetHorLineDouble(startX, y, tabBmpLock[i].Width - startX, col); } } } int tx = BitmapCpc.CalcTx(); int maxPen = BitmapCpc.MaxPen(2); for (int i = 0; i < 16; i++) { colors[i].Visible = lockColors[i].Visible = i < maxPen; } ToolModeDraw(null); }
// // Passe 1 : Réduit la palette aux x couleurs de la palette du CPC. // Effectue également un traitement de l'erreur (tramage) si demandé. // Calcule le nombre de couleurs utilisées dans l'image, et // remplit le tableau coulTrouvee avec ces couleurs // static private void ConvertPasse1(DirectBitmap source, ImageCpc dest, Param prm) { int pct = Dither.SetMatDither(prm); RvbColor p = new RvbColor(0), choix, n1, n2; int indexChoix = 0; int incY = prm.trameTc ? 4 : 2; for (int yPix = 0; yPix < BitmapCpc.TailleY; yPix += incY) { int Tx = BitmapCpc.CalcTx(yPix); for (int xPix = 0; xPix < BitmapCpc.TailleX; xPix += Tx) { for (int yy = 0; yy < incY; yy += 2) { p = GetPixel(source, xPix, yy + yPix, Tx, prm, pct); // Recherche le point dans la couleur cpc la plus proche if (prm.cpcPlus) { choix = new RvbColor((byte)((p.r >> 4) * 17), (byte)((p.v >> 4) * 17), (byte)((p.b >> 4) * 17)); indexChoix = ((choix.v << 4) & 0xF00) + ((choix.b) & 0xF0) + ((choix.r) >> 4); } else { indexChoix = GetNumColorPixelCpc(prm, p); choix = BitmapCpc.RgbCPC[indexChoix]; } coulTrouvee[indexChoix, yPix >> 1]++; if (!prm.trameTc) { source.SetPixel(xPix, yy + yPix, prm.setPalCpc ? choix : p); } } if (prm.trameTc) { // Moyenne des 2 pixels RvbColor p0 = GetPixel(source, xPix, yPix, Tx, prm, pct); RvbColor p1 = GetPixel(source, xPix, yPix + 2, Tx, prm, pct); int r = (p0.r + p1.r); int v = (p0.v + p1.v); int b = (p0.b + p1.b); if (prm.cpcPlus) { n1 = new RvbColor((byte)((r >> 4) * 8), (byte)((v >> 4) * 8), (byte)((b >> 4) * 8)); n2 = new RvbColor((byte)((r >> 5) * 8), (byte)((v >> 5) * 8), (byte)((b >> 5) * 8)); } else { n1 = BitmapCpc.RgbCPC[(r > prm.cstR3 ? 6 : r > prm.cstR1 ? 3 : 0) + (v > prm.cstV3 ? 18 : v > prm.cstV1 ? 9 : 0) + (b > prm.cstB3 ? 2 : b > prm.cstB1 ? 1 : 0)]; n2 = BitmapCpc.RgbCPC[(r > prm.cstR4 ? 6 : r > prm.cstR2 ? 3 : 0) + (v > prm.cstV4 ? 18 : v > prm.cstV2 ? 9 : 0) + (b > prm.cstB4 ? 2 : b > prm.cstB2 ? 1 : 0)]; } source.SetPixel(xPix, yPix, (xPix & Tx) == 0 ? n1 : n2); source.SetPixel(xPix, yPix + 2, (xPix & Tx) == 0 ? n2 : n1); } } } }
private void ToolModeDraw(MouseEventArgs e) { int incY = BitmapCpc.modeVirtuel >= 8 ? 8 : 2; int yReel = e != null ? (offsetY + (e.Y / zoom)) & -incY : 0; int tx = BitmapCpc.CalcTx(yReel); drawColor.BackColor = Color.FromArgb(bitmapCpc.GetColorPal(drawCol % (BitmapCpc.modeVirtuel == 6 ? 16 : 1 << tx)).GetColorArgb); undrawColor.BackColor = Color.FromArgb(bitmapCpc.GetColorPal(undrawCol % (BitmapCpc.modeVirtuel == 6 ? 16 : 1 << tx)).GetColorArgb); drawColor.Width = undrawColor.Width = 35 * Math.Min(tx, 4); drawColor.Refresh(); undrawColor.Refresh(); if (e == null || e.Button == MouseButtons.None) { if (doDraw) { doDraw = false; undo.EndUndoRedo(); } } else { int pen = e.Button == MouseButtons.Left ? drawCol : undrawCol; for (int y = 0; y < penWidth * incY; y += 2) { tx = BitmapCpc.CalcTx(yReel); int nbCol = BitmapCpc.modeVirtuel == 6 ? 16 : 1 << tx; int realColor = GetPalCPC(BitmapCpc.Palette[pen % nbCol]); int yStart = zoom * (yReel - offsetY); for (int x = 0; x < penWidth * tx; x += tx) { int xReel = (x + offsetX + (e.X / zoom)) & -tx; if (xReel >= 0 && yReel >= 0 && xReel < BitmapCpc.TailleX && yReel < BitmapCpc.TailleY) { undo.MemoUndoRedo(xReel, yReel, BmpLock.GetPixel(xReel, yReel), realColor, doDraw); doDraw = true; BmpLock.SetHorLineDouble(xReel, yReel, tx, realColor); if (zoom != 1) { for (int yz = yStart; yz < Math.Min(tmpLock.Height, yStart + (zoom << 1)); yz += 2) { if (yz >= 0) { tmpLock.SetHorLineDouble(zoom * (xReel - offsetX), yz, zoom * tx, realColor); } } } } } yReel += 2; } Render(); } }
public void Render(bool forceDrawZoom = false) { UpdatePalette(); modeCaptureSprites.Visible = BitmapCpc.modeVirtuel == 11; modeEdition.Visible = BitmapCpc.modeVirtuel != 11; if (chkDoRedo.Checked && modeEdition.Checked) { Enabled = false; List <MemoPoint> lst = undo.lstUndoRedo; foreach (MemoPoint p in lst) { int Tx = BitmapCpc.CalcTx(p.posy); BmpLock.SetHorLineDouble(p.posx, p.posy, Tx, p.newColor); } forceDrawZoom = true; bpUndo.Enabled = undo.CanUndo; bpRedo.Enabled = undo.CanRedo; Enabled = true; } if (zoom != 1) { if (tmpLock == null) { tmpLock = new DirectBitmap(imgOrigine.Width, imgOrigine.Height); } if (forceDrawZoom) { for (int y = 0; y < imgOrigine.Height; y += 2) { int ySrc = Math.Min(offsetY + (y / zoom), BitmapCpc.TailleY - 1); for (int x = 0; x < imgOrigine.Width; x += zoom) { tmpLock.SetHorLineDouble(x, y, Math.Min(zoom, imgOrigine.Width - x - 1), BmpLock.GetPixel(offsetX + (x / zoom), ySrc)); } } } pictureBox.Image = tmpLock.Bitmap; } else { pictureBox.Image = imgCopy != null ? imgCopy.Bitmap : BmpLock.Bitmap; tmpLock = null; } pictureBox.Refresh(); if (fenetreRendu != null) { fenetreRendu.Picture.Refresh(); } }
// Conversion "standard" static private void SetPixCol(DirectBitmap bitmap, Param prm, ImageCpc dest, int maxPen, RvbColor[,] tabCol) { int incY = BitmapCpc.modeVirtuel >= 8 && BitmapCpc.modeVirtuel <= 10 ? 8 : 2; RvbColor pix; for (int y = 0; y < BitmapCpc.TailleY; y += incY) { int Tx = BitmapCpc.CalcTx(y); maxPen = BitmapCpc.MaxPen(y); for (int x = 0; x < BitmapCpc.TailleX; x += Tx) { int oldDist = 0x7FFFFFFF; int r = 0, v = 0, b = 0; for (int j = 0; j < incY; j += 2) { pix = bitmap.GetPixelColor(x, y + j); r += pix.r; v += pix.v; b += pix.b; } r = r / (incY >> 1); v = v / (incY >> 1); b = b / (incY >> 1); pix = new RvbColor((byte)r, (byte)v, (byte)b); int choix = 0; for (int i = 0; i < maxPen; i++) { RvbColor c = tabCol[i, y >> 1]; if (c != null) { int dist = (c.r - pix.r) * (c.r - pix.r) * prm.coefR + (c.v - pix.v) * (c.v - pix.v) * prm.coefV + (c.b - pix.b) * (c.b - pix.b) * prm.coefB; if (dist < oldDist) { choix = i; oldDist = dist; if (dist == 0) { i = maxPen; } } } } for (int j = 0; j < incY; j += 2) { dest.SetPixelCpc(x, y + j, choix, Tx); } } } }
private byte[] MakeSprite() { byte[] ret = new byte[(BitmapCpc.TailleX * BitmapCpc.TailleY) >> 4]; Array.Clear(ret, 0, ret.Length); for (int y = 0; y < BitmapCpc.TailleY; y += 2) { int tx = BitmapCpc.CalcTx(y); for (int x = 0; x < BitmapCpc.TailleX; x += 8) { byte pen = 0, octet = 0; for (int p = 0; p < 8; p++) { if ((p % tx) == 0) { RvbColor col = BmpLock.GetPixelColor(x + p, y); if (BitmapCpc.cpcPlus) { for (pen = 0; pen < 16; pen++) { if ((col.v >> 4) == (BitmapCpc.Palette[pen] >> 8) && (col.r >> 4) == ((BitmapCpc.Palette[pen] >> 4) & 0x0F) && (col.b >> 4) == (BitmapCpc.Palette[pen] & 0x0F)) { break; } } } else { for (pen = 0; pen < 16; pen++) { RvbColor fixedCol = BitmapCpc.RgbCPC[BitmapCpc.Palette[pen]]; if (fixedCol.r == col.r && fixedCol.b == col.b && fixedCol.v == col.v) { break; } } } if (pen > 15) { pen = 0; // Pb peut survenir si la palette n'est pas la même pour chaque image d'une animation... } octet |= (byte)(tabOctetMode[pen % 16] >> (p / tx)); } } ret[(x >> 3) + (y >> 1) * (BitmapCpc.TailleX >> 3)] = octet; } } return(ret); }
private void DrawCopy(MouseEventArgs e) { if (imgMotif != null && imgCopy != null) { imgCopy.CopyBits(BmpLock); int yReel = ((e.Y / zoom) & 0xFFE) * zoom; int tx = BitmapCpc.CalcTx(yReel); int xReel = ((e.X / zoom) & -tx) * zoom; if (xReel < BitmapCpc.NbCol << 3 && yReel < BitmapCpc.NbLig << 1) { Graphics g = Graphics.FromImage(pictureBox.Image); g.DrawImage(imgMotif.Bitmap, xReel, yReel); pictureBox.Refresh(); } } }
private void bpRedo_Click(object sender, System.EventArgs e) { Enabled = false; List <MemoPoint> lst = undo.Redo(); foreach (MemoPoint p in lst) { int tx = BitmapCpc.CalcTx(p.posy); BmpLock.SetHorLineDouble(p.posx, p.posy, tx, p.newColor); } if (imgCopy != null) { imgCopy.CopyBits(BmpLock); } Render(true); bpUndo.Enabled = undo.CanUndo; bpRedo.Enabled = undo.CanRedo; Enabled = true; }
// Sur déplacement de la souris... private void TrtMouseMove(object sender, MouseEventArgs e) { if (modeCaptureSprites.Checked) { CaptureSprites(e); // Capture de sprites hard } else if (modeEdition.Checked) { int incY = BitmapCpc.modeVirtuel >= 8 ? 8 : 2; int yReel = ((offsetY + (e.Y / zoom)) & -incY) >> 1; int tx = BitmapCpc.CalcTx(yReel); int xReel = (offsetX + (e.X / zoom)) & -tx; lblInfoPos.Text = "x:" + xReel.ToString("000") + " y:" + yReel.ToString("000"); switch (editToolMode) { case EditTool.Draw: ToolModeDraw(e); break; case EditTool.Zoom: ToolModeZoom(e); break; case EditTool.Copy: ToolModeCopy(e); break; } if (e.Button == MouseButtons.None) { bpUndo.Enabled = undo.CanUndo; bpRedo.Enabled = undo.CanRedo; } } else { MoveOrSize(e); // Déplacement/Zoom image } }
// // Passe 2 : réduit l'image à MaxPen couleurs. // static private void Passe2(DirectBitmap source, ImageCpc dest, Param p, ref int colSplit) { RvbColor[,] tabCol = new RvbColor[16, 272]; int[] MemoLockState = new int[16]; int i; int Tx = BitmapCpc.CalcTx(); int maxPen = BitmapCpc.MaxPen(2); for (i = 0; i < 16; i++) { MemoLockState[i] = p.lockState[i]; } if (BitmapCpc.modeVirtuel == 3 || BitmapCpc.modeVirtuel == 4) { int newMax = BitmapCpc.MaxPen(0); RechercheCMax(newMax, MemoLockState, p); for (i = 0; i < newMax; i++) { MemoLockState[i] = 1; } } if (BitmapCpc.modeVirtuel == 5 || BitmapCpc.modeVirtuel == 6) { if (BitmapCpc.modeVirtuel == 5) { colSplit = RechercheCMaxModeX(dest.colMode5, MemoLockState, BitmapCpc.TailleY, p); } else { colSplit = RechercheCMaxModeSplit(dest.colMode5, MemoLockState, BitmapCpc.TailleY, p); maxPen = 9; } // réduit l'image à MaxPen couleurs. for (int y = 0; y < BitmapCpc.TailleY >> 1; y++) { for (i = 0; i < maxPen; i++) { tabCol[i, y] = p.cpcPlus ? new RvbColor((byte)((dest.colMode5[y, i] & 0x0F) * 17), (byte)(((dest.colMode5[y, i] & 0xF00) >> 8) * 17), (byte)(((dest.colMode5[y, i] & 0xF0) >> 4) * 17)) : BitmapCpc.RgbCPC[dest.colMode5[y, i] < 27 ? dest.colMode5[y, i] : 0]; } } } else { RechercheCMax(maxPen, MemoLockState, p); // réduit l'image à MaxPen couleurs. for (int y = 0; y < BitmapCpc.TailleY; y += 2) { maxPen = BitmapCpc.MaxPen(y); for (i = 0; i < maxPen; i++) { tabCol[i, y >> 1] = dest.bitmapCpc.GetColorPal(i); } } } switch (BitmapCpc.modeVirtuel) { case 6: SetPixColSplit(source, p, dest, tabCol); break; case 7: SetPixTrameM1(source, p, dest, maxPen, tabCol); break; default: SetPixCol(source, p, dest, maxPen, tabCol); break; } }
public byte[] GetCpcScr(Param param, bool spriteMode = false) { int maxSize = (BitmapCpc.TailleX >> 3) + ((BitmapCpc.TailleY - 2) >> 4) * (BitmapCpc.TailleX >> 3) + ((BitmapCpc.TailleY - 2) & 14) * 0x400; if (spriteMode) { maxSize = (BitmapCpc.TailleX * BitmapCpc.TailleY) >> 4; } else if (maxSize >= 0x4000) { maxSize += 0x3800; } byte[] ret = new byte[maxSize]; Array.Clear(ret, 0, ret.Length); int posRet = 0; for (int y = 0; y < BitmapCpc.TailleY; y += 2) { int adrCPC = BitmapCpc.GetAdrCpc(y); int tx = BitmapCpc.CalcTx(y); for (int x = 0; x < BitmapCpc.TailleX; x += 8) { byte pen = 0, octet = 0; for (int p = 0; p < 8; p++) { if ((p % tx) == 0) { RvbColor col = BmpLock.GetPixelColor(x + p, y); if (BitmapCpc.cpcPlus) { for (pen = 0; pen < 16; pen++) { if ((col.v >> 4) == (BitmapCpc.Palette[pen] >> 8) && (col.r >> 4) == ((BitmapCpc.Palette[pen] >> 4) & 0x0F) && (col.b >> 4) == (BitmapCpc.Palette[pen] & 0x0F)) { break; } } } else { for (pen = 0; pen < 16; pen++) { RvbColor fixedCol = BitmapCpc.RgbCPC[BitmapCpc.Palette[pen]]; if (fixedCol.r == col.r && fixedCol.b == col.b && fixedCol.v == col.v) { break; } } } octet |= (byte)(tabOctetMode[pen] >> (p / tx)); } } if (!spriteMode) { posRet = BitmapCpc.GetAdrCpc(y) + (x >> 3); } ret[posRet++] = octet; } } return(ret); }
private void ToolModeCopy(MouseEventArgs e) { int yReel = ((e.Y / zoom) & 0xFFE) * zoom; int tx = BitmapCpc.CalcTx(yReel); int xReel = ((e.X / zoom) & -tx) * zoom; if (e.Button == MouseButtons.Left && xReel >= 0 && yReel >= 0) { if (imgMotif != null) { for (int y = 0; y < imgMotif.Height; y += 2) { tx = BitmapCpc.CalcTx(y + yReel); for (int x = 0; x < imgMotif.Width; x += tx) { if (x + xReel < BitmapCpc.NbCol << 3 && y + yReel < BitmapCpc.NbLig << 1) { int c = imgMotif.GetPixel(x, y); undo.MemoUndoRedo(x + xReel, y + yReel, BmpLock.GetPixel(x + xReel, y + yReel), c, doDraw); BmpLock.SetHorLineDouble(x + xReel, y + yReel, tx, c); doDraw = true; } } } imgCopy.CopyBits(BmpLock); Render(); } else { if (!setCopyRect) { setCopyRect = true; copyRectx = xReel; copyRecty = yReel; copyRecth = copyRectw = 0; } else { Graphics g = Graphics.FromImage(pictureBox.Image); if (copyRecth != 0 || copyRectw != 0) { XorDrawing.DrawXorRectangle(g, (Bitmap)pictureBox.Image, copyRectx, copyRecty, copyRectx + copyRectw, copyRecty + copyRecth); } copyRectw = xReel - copyRectx; copyRecth = yReel - copyRecty; XorDrawing.DrawXorRectangle(g, (Bitmap)pictureBox.Image, copyRectx, copyRecty, copyRectx + copyRectw, copyRecty + copyRecth); pictureBox.Refresh(); } } } else { if (setCopyRect) { setCopyRect = false; if (copyRectw != 0 && copyRecth != 0) { Graphics g = Graphics.FromImage(pictureBox.Image); XorDrawing.DrawXorRectangle(g, (Bitmap)pictureBox.Image, copyRectx, copyRecty, copyRectx + copyRectw, copyRecty + copyRecth); imgMotif = new DirectBitmap(Math.Abs(copyRectw / zoom), Math.Abs(copyRecth / zoom)); for (int x = 0; x < imgMotif.Width; x++) { for (int y = 0; y < imgMotif.Height; y++) { imgMotif.SetPixel(x, y, BmpLock.GetPixel(offsetX + x + copyRectx / zoom, offsetY + y + copyRecty / zoom)); } } if (zoom != 1) { zoom = 1; DoZoom(); } imgCopy = new DirectBitmap(BmpLock.Width, BmpLock.Height); pictureBox.Image = imgCopy.Bitmap; } } if (doDraw) { doDraw = false; undo.EndUndoRedo(); } DrawCopy(e); pictureBox.Refresh(); } }