Devilmarkus Geschrieben 29. Oktober 2009 Geschrieben 29. Oktober 2009 Hallo zusammen, ich möchte ein altes BASIC Programm in Java verwenden. Dazu habe ich das Programm so gut, wie ich kann, in Java übersetzt, an meine Bedürfnisse angepasst, und verwende es nun. Das Programm ansich tut auch das, was es soll: Nämlich Bereiche füllen. Das Problem hierbei ist nun, dass es mir bei längeren Füllvorgängen einen StackOverFlow error auswirft. Diesen Fehler konnte ich zwar erfolgreich 'catch'en, aber er ist ja immernoch vorhanden. Was nun ist an meinem Code noch falsch? protected int[] x = new int[52]; protected int[] y = new int[52]; protected int z, xStep; protected Color hf, vfl, vfr, fr, fl; protected int fillX, fillY; public Color test(int x, int y){ Color result = CPC.getCol(pen); if (x <= img.getWidth() && y <= img.getHeight() && x>=0 && y>=0) result = new Color(img.getRGB(x, y)); return result; } public void Fill(int x, int y, int p){ fillX = x; fillY = y; xStep = 1; if (mode == 1) xStep = 2; if (mode == 0) xStep = 4; putScreen(); z = 0; hf = new Color(img.getRGB(fillX, fillY)); System.out.println(Util.hex(hf.getRGB())); if (hf.getRGB() == CPC.getCol(p).getRGB()) return; getCoords(); } protected void getCoords(){ if (fillX <0 || fillX >640-xStep || fillY <0 || fillY>399){ getnewCoords(); } else searchUP(); } public void searchUP(){ try{ while (test(fillX, fillY).getRGB() == hf.getRGB() && fillY < 398) fillY+=2; fillY-=2; fl = new Color (0x44,0x44,0x44); fr = fl; fillDown(); } catch (java.lang.StackOverflowError So){System.gc();} } public void fillDown(){ while (fillY>=0 && test(fillX, fillY).getRGB() == hf.getRGB() && fillX<(640-xStep)){ // look to left vfl = fl; fl = test(fillX-xStep, fillY); if (vfl.getRGB() != hf.getRGB() && fl.getRGB() == hf.getRGB()){ x[z] = fillX-xStep; y[z] = fillY; z++; } // look to right vfr = fr; fr = test(fillX+xStep, fillY); if (vfr.getRGB() != hf.getRGB() && fr.getRGB() == hf.getRGB()){ x[z] = fillX+xStep; y[z] = fillY; z++; } int cpcY = fillY / 2; int cpcX = fillX / xStep; // plot point CPC.PLOT(cpcX, cpcY, pen, mode); Graphics page = getGraphics(); img.getGraphics().setColor(CPC.getCol(pen)); page.setColor(CPC.getCol(pen)); img.getGraphics().fillRect(fillX, fillY, xStep, 2); page.fillRect(fillX, fillY, xStep, 2); fillY-=2; } getnewCoords(); } protected void getnewCoords(){ // get new coordinates z--; if (z>=0){ fillX=x[z]; fillY=y[z]; getCoords(); } } Hier übrigens das Original BASIC-Listing: (Schneider CPC Basic 1.0) 10 '*********************************** 20 '*********** FILL - Basic ********** 30 '*********************************** 40 MODE 1:DEFINT a-z:DIM x(50),y(50) 50 '*** Testfigur zeichnen 60 MOVE 100,100:DRAW 150,150,2:DRAW 100,200:DRAW 200,200:DRAW 180,180:DRAW 200,140:DRAW 200,100:DRAW 100,100 70 MOVE 120,120:TAG:PRINT"X Y Z";:TAGOFF 80 '*** Startpunkt und Farbe bestimmen 90 x=160:y=160:f=3:GOSUB 1000:END 1000 '******** FILL-Subroutine ******** 1010 '*** Hintergrundfarbe ermitteln 1020 z=0:hf=TEST(x,y):IF hf=f THEN RETURN 1030 '*** Koord. auf dem Bildschirm ? 1040 IF x<0 OR x>639 OR y<0 OR y>399 THEN 1190 1050 '*** Oberen Rand suchen 1060 WHILE TEST(x,y)=hf AND y<399:y=y+2:WEND 1070 y=y-2:fl=-1:fr=-1 1080 '*** Linie nach unten zeichnen 1090 WHILE y>=0 AND TEST(x,y)=hf 1100 '*** Schaue nach links 1110 vfl=fl:fl=TEST(x-2,y) 1120 IF vfl<>hf AND fl=hf THEN x(z)=x-2:y(z)=y:z=z+1 1130 '*** Schaue nach rechts 1140 vfr=fr:fr=TEST(x+2,y) 1150 IF vfr<>hf AND fr=hf THEN x(z)=x+2:y(z)=y:z=z+1 1160 '*** Punkt setzen 1170 PLOT x,y,f:y=y-2 1180 WEND 1190 '*** Neue Koordinaten holen 1200 z=z-1 1210 IF z>=0 THEN x=x(z):y=y(z):GOTO 1040 1220 '*** Zurueck,falls keine mehr da 1230 RETURN Zitieren
flashpixx Geschrieben 29. Oktober 2009 Geschrieben 29. Oktober 2009 Poste immer die vollständige Klasse und die vollständige Fehlermeldung. So nach meiner Überlegung ist der Fehler in Deiner test-Methode: if (x <= img.getWidth() && y <= img.getHeight() && x>=0 && y>=0) Die Pixel-Positionen sind von [0,getWidth) und [0,getHeight), Du hast immer eine Zeile und Spalte zu viel Zitieren
Devilmarkus Geschrieben 29. Oktober 2009 Autor Geschrieben 29. Oktober 2009 (bearbeitet) Poste immer die vollständige Klasse und die vollständige Fehlermeldung. So nach meiner Überlegung ist der Fehler in Deiner test-Methode: if (x <= img.getWidth() && y <= img.getHeight() && x>=0 && y>=0) Die Pixel-Positionen sind von [0,getWidth) und [0,getHeight), Du hast immer eine Zeile und Spalte zu viel Ich habe das geändert. Dennoch: Exception in thread "AWT-EventQueue-0" java.lang.StackOverflowError at sun.java2d.loops.SurfaceType.pixelFor(SurfaceType.java:416) at sun.java2d.SurfaceData.pixelFor(SurfaceData.java:789) at sun.java2d.SunGraphics2D.validateColor(SunGraphics2D.java:1646) at sun.java2d.SunGraphics2D.<init>(SunGraphics2D.java:237) at sun.java2d.d3d.D3DScreenUpdateManager.createGraphics(D3DScreenUpdateManager.java:255) at sun.awt.windows.WComponentPeer.getGraphics(WComponentPeer.java:524) at java.awt.Component.getGraphics(Component.java:2772) at jemu.system.cpc.PaintCanvas.fillDown(PaintCanvas.java:1743) at jemu.system.cpc.PaintCanvas.searchUP(PaintCanvas.java:1722) at jemu.system.cpc.PaintCanvas.getCoords(PaintCanvas.java:1713) at jemu.system.cpc.PaintCanvas.getnewCoords(PaintCanvas.java:1757) at jemu.system.cpc.PaintCanvas.fillDown(PaintCanvas.java:1750) at jemu.system.cpc.PaintCanvas.searchUP(PaintCanvas.java:1722) at jemu.system.cpc.PaintCanvas.getCoords(PaintCanvas.java:1713) at jemu.system.cpc.PaintCanvas.getnewCoords(PaintCanvas.java:1757) at jemu.system.cpc.PaintCanvas.fillDown(PaintCanvas.java:1750) at jemu.system.cpc.PaintCanvas.searchUP(PaintCanvas.java:1722) at jemu.system.cpc.PaintCanvas.getCoords(PaintCanvas.java:1713) at jemu.system.cpc.PaintCanvas.getnewCoords(PaintCanvas.java:1757) at jemu.system.cpc.PaintCanvas.fillDown(PaintCanvas.java:1750) at jemu.system.cpc.PaintCanvas.searchUP(PaintCanvas.java:1722) at jemu.system.cpc.PaintCanvas.getCoords(PaintCanvas.java:1713) at jemu.system.cpc.PaintCanvas.getnewCoords(PaintCanvas.java:1757) at jemu.system.cpc.PaintCanvas.fillDown(PaintCanvas.java:1750) at jemu.system.cpc.PaintCanvas.searchUP(PaintCanvas.java:1722) at jemu.system.cpc.PaintCanvas.getCoords(PaintCanvas.java:1713) at jemu.system.cpc.PaintCanvas.getnewCoords(PaintCanvas.java:1757) at jemu.system.cpc.PaintCanvas.fillDown(PaintCanvas.java:1750) at jemu.system.cpc.PaintCanvas.searchUP(PaintCanvas.java:1722) at jemu.system.cpc.PaintCanvas.getCoords(PaintCanvas.java:1713) at jemu.system.cpc.PaintCanvas.getnewCoords(PaintCanvas.java:1757) at jemu.system.cpc.PaintCanvas.fillDown(PaintCanvas.java:1750) etc... Die ganze Klasse hier posten macht wenig Sinn. Man kann z.b. das CPC.PLOT... wegdenken, es ist hier unwichtig. img ist ein bufferedImage... Edit: Um hier die ganze Klasse posten zu können, müsste ich einige Seiten Code posten. Denn es sind einige Sachen dabei, die wiederum aus anderen Klassen verwendet werden, welche auf einer komplexen Emulation beruhen. Allerdings gebe ich gerne den kompletten Sourcecode raus. Das Image ist übrigens 640x400 Pixel gross. Bearbeitet 29. Oktober 2009 von Devilmarkus Zitieren
flashpixx Geschrieben 29. Oktober 2009 Geschrieben 29. Oktober 2009 Das scheint auf einen Fehler in einer Rekursion hinzudeuten bzw zu viele Aufrufe des new-Operators z.B. in einem Listener, aber da Dein Code unvollständig ist, kann man nicht wirklich helfen Zitieren
Devilmarkus Geschrieben 29. Oktober 2009 Autor Geschrieben 29. Oktober 2009 Das scheint auf einen Fehler in einer Rekursion hinzudeuten bzw zu viele Aufrufe des new-Operators z.B. in einem Listener, aber da Dein Code unvollständig ist, kann man nicht wirklich helfen Hier die komplette Klasse: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package jemu.system.cpc; /** * Title: JavaCPC * Description: The Java CPC Emulator * Copyright: Copyright (c) 2002-2009 * Company: * @author: Markus */ import java.awt.*; import java.awt.event.*; import jemu.ui.Switches; import jemu.core.Util; import java.awt.image.*; import javax.imageio.*; import java.net.*; import javax.swing.*; import java.io.*; class PaintCanvas extends Canvas implements MouseListener, MouseMotionListener { String[] output = {""}; String minitext=""; int textpen = 1; int smoothpen = 16; int minisize = 0; int transback = 16; boolean debug = false; boolean resPal = false; int RedPixel; int GreenPixel; int BluePixel; int startup = 1; miniFont minifont = new miniFont(); JCheckBox restorePal = new JCheckBox("Restore palette"); public Color random = new Color(20,60,90); public int[] INK0 = { 0,1,3,4,9,13 }; public int[] INK1 = { 1,0,2,5,3,10,11,13 }; public int[] INK2 = { 2,5,11,14,13,20,23 }; public int[] INK3 = { 3,4,5,1,0,6,7,13,15,16 }; public int[] INK4 = { 4,3,1,0,6,7,8,13,15,16 }; public int[] INK5 = { 5,2,11,0,14,10,13,15}; public int[] INK6 = { 6,7,8,15,16,13,12,3,4,1,0}; public int[] INK7 = { 7,6,8,17,16,15,13,12,4,3,1,0 }; public int[] INK8 = { 8,7,17,16,15,6,3,1,0 }; public int[] INK9 = { 9,10,12,13,3,1,0 }; public int[] INK10 = { 10,13,12,9,5,1,3,0 }; public int[] INK11 = { 11,14,10,13,5,2,1,0 }; public int[] INK12 = { 12,13,10,9,3,1,0 }; public int[] INK13 = { 13,10,12,5,3,6,14,15,16,23,25,26 }; public int[] INK14 = { 14,11,13,5,15,16,20,23,25,26 }; public int[] INK15 = { 15,16,8,7,6,13,10,24,25,26 }; public int[] INK16 = { 16,17,15,8,7,6,13,10,24,25,26 }; public int[] INK17 = { 17,16,8,7,6,13,10,24,25,26 }; public int[] INK18 = { 18,21,22,19,20,23,24,25,26,16,15,13 }; public int[] INK19 = { 19,22,18,21,20,23,24,25,26,16,15,13 }; public int[] INK20 = { 20,23,22,19,18,21,24,25,26,16,15,13,11,14 }; public int[] INK21 = { 21,18,19,22,20,23,24,25,26,16,15,13 }; public int[] INK22 = { 22,19,18,21,20,23,24,25,26,16,15,13 }; public int[] INK23 = { 23,20,22,19,18,21,24,25,26,16,15,13,10,11,14 }; public int[] INK24 = { 24,25,22,19,26,16,15,13,10,11,14 }; public int[] INK25 = { 25,24,22,19,26,16,15,13,10,11,14 }; public int[] INK26 = { 26,25,24,23,22,21,20,17,16,15,13,10,11,14 }; public int[] realInks = new int[27]; public int checkPal = 0; boolean flip; public int transpen = 17; int shapeX, shapeY, shapeW, shapeH; public int bold = 0, italic = 0; byte[] input; int reload = 0; public boolean raster = false; public boolean gray = false; String loadname = ""; public String showname = "JavaCPC Paint 1.0"; BufferedImage newmag = null; BufferedImage imag = null; BufferedImage img = null; BufferedImage shape = null; BufferedImage nimg = null; boolean doCycle = true; int recalculate = 0; int[] counted; protected String[] cpccolors = { "Black", "Blue", "Bright Blue", "Red", "Magenta", "Mauve", "Bright Red", "Purple", "Bright Magenta", "Green" , "Cyan", "Sky Blue", "Yellow", "White", "Pastel Blue", "Orange", "Pink", "Pastel Magenta", "Bright Green", "Sea Green", "Bright Cyan", "Lime", "Pastel Green", "Pastel Cyan", "Bright Yellow", "Pastel Yellow", "Bright White" }; protected int[] GAInks = { 20,4,21,28,24,29,12,5,13,22,6,23,30,0,31,14,7,15,18,2,19,26,25,27,10,3,11 }; protected static final int[] GACols = { /*R G B */ 0x000000, /* 0*/ 0x00007D, /* 1*/ 0x0000FF, /* 2*/ 0x7D0000, /* 3*/ 0x7D007D, /* 4*/ 0x7D00FF, /* 5*/ 0xFF0000, /* 6*/ 0xFF007D, /* 7*/ 0xFF00FF, /* 8*/ 0x007D00, /* 9*/ 0x007D7D, /*10*/ 0x007DFF, /*11*/ 0x7D7D00, /*12*/ 0x7D7D7D, /*13*/ 0x7D7DFF, /*14*/ 0xFF7D00, /*15*/ 0xFF7D7D, /*16*/ 0xFF7DFF, /*17*/ 0x00FF00, /*18*/ 0x00FF7D, /*19*/ 0x00FFFF, /*20*/ 0x7DFF00, /*21*/ 0x7DFF7D, /*22*/ 0x7DFFFF, /*23*/ 0xFFFF00, /*24*/ 0xFFFF7D, /*25*/ 0xFFFFFF /*26*/ }; protected Color[] GACol = new Color[27]; protected Color[] Col = new Color[27]; private final int CANVAS_WIDTH = 640; private final int CANVAS_HEIGHT = 400; public int bright = 85; public boolean keep = false; public boolean keepinks = false; public static boolean horizontal = false; public int scroll = 0; public int scrollb = 0; int cyclec = 0; int cycled = 0; protected boolean paintscreen = false; public int CPCRed, CPCBlue, CPCGreen; int[] palcount; int[] outcount = new int[27]; public String fontname="Verdana"; public int[] undo = new int[0x4000]; final URL cursor1 = getClass().getResource("icons/cursor1.gif"); final Image Cursor1 = getToolkit().getImage(cursor1); final Cursor cursor = Toolkit.getDefaultToolkit().createCustomCursor (Cursor1, new Point(15, 15), "Cursor"); public int MODE_PAINT = 0x01; public int MODE_TEXT = 0x02; public int MODE_LINE = 0x03; public int MODE_RECTANGLE = 0x04; public int MODE_CIRCLE = 0x05; public int MODE_FRECT = 0x06; public int MODE_FCIRCLE = 0x07; public int MODE_IMPORT = 0x08; public int MODE_COPY = 0x09; public int MODE_PASTE = 0x0a; public int MODE_MINITEXT = 0x0b; public int MODE_FILL = 0x0c; public int MODE = MODE_PAINT; public int textX, textY; public String text =""; public int textsize = 30; boolean draw = false; private int lineX,lineY,toX,toY; protected boolean paint; private int lastX, lastY; public int pen = 1; public int mode = GateArray.getSMode(); protected boolean painted = true; BufferedImage loadImg = null; public PaintCanvas () { for (int pf = 0; pf < 27; pf++){ Col[pf] = new Color(GACols[pf]); } addMouseListener (this); addMouseMotionListener (this); setCursor(cursor); setBackground (Color.white); setSize (CANVAS_WIDTH, CANVAS_HEIGHT); restorePal.addItemListener(restoreListener); } public void mousePressed (MouseEvent event) { makeUndo(); Point first = event.getPoint(); lastX = first.x; lastY = first.y; int x = lastX; int y = lastY/2; if (mode == 0) x/=4; if (mode == 1) x/=2; switch (MODE){ case 1:{ if (paint) plot(x, y, pen); painted = true; putScreen(); break; } case 3:{ Point current = event.getPoint(); lineX = current.x; lineY = current.y; break; } case 4:{ Point current = event.getPoint(); lineX = current.x; lineY = current.y; break; } case 5:{ Point current = event.getPoint(); lineX = current.x; lineY = current.y; break; } case 6:{ Point current = event.getPoint(); lineX = current.x; lineY = current.y; break; } case 7:{ Point current = event.getPoint(); lineX = current.x; lineY = current.y; break; } case 9:{ Point current = event.getPoint(); lineX = current.x; lineY = current.y; break; } } } public void mouseDragged (MouseEvent event) { Point current = event.getPoint(); int xn = current.x; int xs = 1; int ys = 2; if (mode == 0) xs = 4; if (mode == 1) xs = 2; int xc = (current.x/xs)*xs; int yc = (current.y/ys)*ys; lineX = (lineX/xs)*xs; lineY = (lineY/ys)*ys; int yn = current.y/2; if (mode == 0) xn/=4; if (mode == 1) xn/=2; int fromx = lineX; int fromy = lineY; int tox = toX-lineX; int toy = toY-lineY; if (toX < lineX){ fromx = toX; tox = lineX-toX; } else { fromx = lineX; tox = toX-lineX; } if (toY < lineY){ fromy = toY; toy = lineY-toY; } else{ fromy = lineY; toy = toY-lineY; } tox = (tox/xs)*xs; toy = (toy/ys)*ys; switch (MODE){ case 1:{ if (paint){ plot(xn, yn, pen); } lastX = current.x; lastY = current.y; putScreen(); painted = true; break; } case 3:{ putScreen(); toX = current.x; toY = current.y; Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); page.setColor(random); page.drawLine(lineX, lineY, toX, toY); page.drawLine(lineX, lineY+1, toX, toY+1); if (mode == 1 || mode == 0){ page.drawLine(lineX+1, lineY, toX+1, toY); page.drawLine(lineX+1, lineY+1, toX+1, toY+1); } if (mode == 0){ page.drawLine(lineX+2, lineY, toX+2, toY); page.drawLine(lineX+2, lineY+1, toX+2, toY+1); page.drawLine(lineX+3, lineY, toX+3, toY); page.drawLine(lineX+3, lineY+1, toX+3, toY+1); } break; } case 4:{ putScreen(); toX = current.x; toY = current.y; Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); page.setColor(random); page.drawRect(fromx, fromy, tox, toy); page.drawRect(fromx, fromy+1, tox, toy); if (mode == 1 || mode == 0){ page.drawRect(fromx+1, fromy, tox, toy); page.drawRect(fromx+1, fromy+1, tox, toy); } if (mode == 0){ page.drawRect(fromx+2, fromy, tox, toy); page.drawRect(fromx+2, fromy+1, tox, toy); page.drawRect(fromx+3, fromy, tox, toy); page.drawRect(fromx+3, fromy+1, tox, toy); } break; } case 5:{ putScreen(); toX = current.x; toY = current.y; Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); cross(xc,yc); page.drawOval(fromx, fromy, tox, toy); break; } case 6:{ putScreen(); toX = current.x; toY = current.y; Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); page.setColor(random); page.fillRect(fromx, fromy, tox, toy); break; } case 7:{ putScreen(); toX = current.x; toY = current.y; Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); cross(xc,yc); page.fillOval(fromx, fromy, tox, toy); break; } case 9:{ putScreen(); toX = current.x; toY = current.y; Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); page.setColor(random); page.drawRect(fromx, fromy, tox, toy); page.drawRect(fromx, fromy+1, tox, toy); shapeX = fromx; shapeY = fromy; shapeW = tox; shapeH = toy; if (mode == 1 || mode == 0){ page.drawRect(fromx+1, fromy, tox, toy); page.drawRect(fromx+1, fromy+1, tox+1, toy); } if (mode == 0){ page.drawRect(fromx+2, fromy, tox, toy); page.drawRect(fromx+2, fromy+1, tox, toy); page.drawRect(fromx+3, fromy, tox, toy); page.drawRect(fromx+3, fromy+1, tox, toy); } break; } } } public void plot(int x, int y, int p){ CPC.PLOT(x, y, p, mode); } public void convertScreen(){ recalculate = 0; MODE = MODE_IMPORT; FileDialog filedia = new FileDialog((Frame) new Frame(), "Import screen", FileDialog.LOAD); filedia.setFile("*.png; *.bmp; *.gif; *.jpg; *.scr"); filedia.setVisible(true); String filename = filedia.getFile(); if (filename != null) { doCycle = false; filename = filedia.getDirectory() + filedia.getFile(); loadname = filename; showname = filedia.getFile(); JavaCPCPaint.output.append("Reading " + loadname + " in progress...\n"); } if (loadname.length() > 2) convertScreen(loadname); } public void SCRimport(String loadname){ try{ final BufferedInputStream bos = new BufferedInputStream(new FileInputStream(loadname)); input = new byte[bos.available()]; int count = 0; while (bos.available() > 0) { input[count] = (byte)bos.read(); count++; } bos.close(); int start = 0; if (input.length > 16384) start = 0x80; int address = 0xc000; int smode = input[0x17d0 + start]; if (smode != GateArray.getSMode()){ if (smode == 0) CPC.POKE(0x4fff,3); else CPC.POKE(0x4fff,smode); reload = 1; return; } int palette = 0x17d1 + start; for (int i = 0; i< 16; i++) INK(i, input[palette+i]); for (int i = start; i < input.length; i++) CPC.POKE(address++, input[i]); } catch (IOException e){} } public void reload(){ int start = 0; if (input.length > 16384) start = 0x80; int palette = 0x17d1 + start; for (int i = 0; i< 16; i++) INK(i, input[palette+i]); int address = 0xc000; for (int i = start; i < input.length; i++) CPC.POKE(address++, input[i]); } public String showname(){ return showname; } public void convertScreen(String loadname){ recalculate = 0; MODE = MODE_IMPORT; if (loadname.toLowerCase().endsWith(".scr")){ SCRimport(loadname); return; } cyclec=0; cycled=0; imag = null; newmag = null; img = null; try{ loadImg = null; loadImg = ImageUtil.readImage(loadname); } catch (Exception e){ System.err.println("Load failed..."); return; } int orig_width = loadImg.getWidth(); int orig_height = loadImg.getHeight(); int newwidth = 640; int newheight = 400; float ratio = (float)orig_width/(float)orig_height; double scale = orig_width/640.0; if (ratio > 1.6) scale = orig_height/400.0; double width = orig_width/scale; double height = orig_height/scale; JavaCPCPaint.scroll.setValue(0); JavaCPCPaint.scrollb.setValue(0); newwidth = (int)width; newheight = (int)height; if (keep){ newwidth = orig_width; newheight = orig_height; } JavaCPCPaint.output.append("Image size: " + orig_width+"x" + orig_height + ", ratio = "+ ratio + "\n"); JavaCPCPaint.output.append("Size viewed: 640x400, ratio = " + (float)640/400+" Origin : (" + scroll+","+scrollb+"\n"); JavaCPCPaint.output.select(2000000000, 2000000000); mode = GateArray.getSMode(); if (gray) img = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_BYTE_GRAY); else if (raster) img = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_BYTE_INDEXED); else img = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_INT_RGB); img.getGraphics().drawImage(loadImg, 0, 0, newwidth, newheight, this); loadImg = new BufferedImage(img.getWidth() , img.getHeight() , img.getType()); loadImg.getGraphics().drawImage(img, 0, 0, newwidth, newheight, this); if (raster && gray){ img = new BufferedImage(newwidth, newheight, BufferedImage.TYPE_BYTE_INDEXED); img.getGraphics().drawImage(loadImg, 0, 0, newwidth, newheight, this); loadImg = new BufferedImage(img.getWidth() , img.getHeight() , img.getType()); loadImg.getGraphics().drawImage(img, 0, 0, newwidth, newheight, this); } imag = loadImg; checkImag(); if (imag.getHeight() - 400 > 0){ int value = imag.getHeight() - 400; JavaCPCPaint.scroll.setMaximum(value); // JavaCPCPaint.scroll.setValue(value/2); } else JavaCPCPaint.scroll.setMaximum(0); if (imag.getWidth() - 640 > 0){ int value = imag.getWidth() - 640; JavaCPCPaint.scrollb.setMaximum(value); // JavaCPCPaint.scrollb.setValue(value/2); } else JavaCPCPaint.scrollb.setMaximum(0); JavaCPCPaint.scroll.setEnabled(true); JavaCPCPaint.scrollb.setEnabled(true); newmag = null; paintscreen = true; cycled=1; clear(); JavaCPCPaint.output.append("Reading Ok.\n"); JavaCPCPaint.output.select(2000000000, 2000000000); doCycle = true; } public void scrollImage(){ recalculate = 1; Graphics page = getGraphics(); page.drawImage(imag, 0-scrollb, 0-scroll, 640,400,0,0,640+scrollb,400+scroll,this); } public void recalculate(){ loadImg = new BufferedImage(640, 400, BufferedImage.SCALE_SMOOTH); loadImg.getGraphics().drawImage(imag, 0-scrollb, 0-scroll, 640,400,0,0,640+scrollb,400+scroll,this); } public void makecpc(){ if (!draw) recalculate(); JavaCPCPaint.output.append("Process pass 1...\n"); if (loadImg == null) return; int width = loadImg.getWidth(); int height = loadImg.getHeight(); int xstep = 1, ystep = 1; if (!draw){ if (width > 640) width = 640; if (height > 400) height = 400; ystep = 2; if (mode == 1) xstep = 2; if (mode == 0) xstep = 4; } int keeppen = pen; palcount = new int[27]; if (draw){ newmag = new BufferedImage(loadImg.getWidth(),loadImg.getHeight(),BufferedImage.TYPE_INT_RGB); } int countr = 0; for (int xdot = 0; xdot < width; xdot+=xstep){ countr++; for (int ydot = 0; ydot < height; ydot+=ystep){ Color test = new Color(loadImg.getRGB(xdot, ydot)); findCPCInk(test); if (draw){ Graphics build = newmag.createGraphics(); build.setColor(new Color (CPCRed , CPCGreen , CPCBlue)); build.drawLine(xdot, ydot, xdot, ydot); if (countr==32){ Graphics page = getGraphics(); page.drawImage(newmag, 0, 0, this); countr = 0; } } Color peng = new Color (CPCRed , CPCGreen , CPCBlue); for (int p = 0; p < 27; p++){ if (Col[p].getRGB() == peng.getRGB()){ palcount[p]++; } } } } int count = 0; int[] check = new int[27]; outcount = new int[270000]; int number = 0; for (int p = 0; p < 27; p++){ if (palcount[p] !=0) number++; check[p] = palcount[p]; } JavaCPCPaint.output.append( number + " INKs found.\n"); java.util.Arrays.sort(check); int [] recheck = new int[27]; int collect = 16; if (mode == 1) collect = 4; if (mode == 2) collect = 2; collect = 16; for (int p = 0; p < 27; p++) recheck[p] = check[26-p]; check = recheck; for (int p = 0; p < 27; p++){ for (int q = 0; q < 27; q++){ if (palcount[q] == check[p]){ outcount[count] = q; count++; } if (count==collect+1) break; } } for (int p = 0; p < 27; p++) realInks[p] = -1; for (int p = 0; p < 27; p++){ for (int q = 0; q < 27; q++){ if (palcount[q] == check[p]) realInks[p] = q; } } //imag = newmag; counted = new int[collect]; for (int pf = 0; pf < 16; pf++) INK(pf, 0); for (int pf = 0; pf < 27; pf++){ GACol[pf] = new Color(GACols[pf]); } System.out.println(); String outtext = ("Palette: (INKs) "); for (int pf = 0; pf < collect; pf++){ INK(pf, outcount[pf]); outtext+=(outcount[pf]); counted[pf] = outcount[pf]; if (pf<collect-1) outtext+=(","); } JavaCPCPaint.output.append("Process pass 2...\n"); outtext+="\n"; // for (int pf = 0; pf < collect; pf++) // outtext += " ("+cpccolors[outcount[pf]]+")\n"; JavaCPCPaint.output.append(outtext); JavaCPCPaint.output.select(2000000000, 2000000000); pen = keeppen; } public void checkLoadImg(){ int checksum = 0; for (int xdot = 0; xdot < loadImg.getWidth(); xdot+=10) for (int ydot = 0; ydot < loadImg.getHeight(); ydot+=10){ Color test = new Color(loadImg.getRGB(xdot, ydot)); checksum+=test.getRGB(); } if (checksum == 0){ convertScreen(loadname); } } public void checkImag(){ int checksum = 0; for (int xdot = 0; xdot < imag.getWidth(); xdot+=10) for (int ydot = 0; ydot < imag.getHeight(); ydot+=10){ Color test = new Color(imag.getRGB(xdot, ydot)); checksum+=test.getRGB(); } if (checksum == 0){ convertScreen(loadname); } } public void exportscreen(){ draw = true; convertScreen(loadname); makecpc(); draw = false; FileDialog filedia = new FileDialog((Frame) new Frame(), "Export CPC posterized screen", FileDialog.SAVE); filedia.setFile("*.gif"); filedia.setVisible(true); String filename = filedia.getFile(); if (filename != null) { filename = filedia.getDirectory() + filedia.getFile(); if (!filename.toLowerCase().endsWith("gif")) filename+=".gif"; try { File file = new File(filename); ImageIO.write(newmag, "gif", file); } catch (Exception e){} } } public void savescreen(BufferedImage ima, String filename){ try { File file = new File(filename); ImageIO.write(ima, "png", file); } catch (Exception e){} } public void convert(boolean detect){ checkLoadImg(); if (keepinks) detect = false; if (detect){ makecpc(); return; } mode = GateArray.getSMode(); int keeppen = pen; if (loadImg == null) return; int width = loadImg.getWidth(); int height = loadImg.getHeight(); if (width > 640) width = 640; if (height > 400) height = 400; int xstep = 1, ystep = 2; if (mode == 1) xstep = 2; if (mode == 2) xstep = 1; if (mode == 0) xstep = 4; int cols = 2; if (mode == 1) cols = 4; if (mode == 0) cols = 16; for (int ydot = 0; ydot < height; ydot+=ystep) for (int xdot = 0; xdot < width; xdot+=xstep) { Color test = new Color(loadImg.getRGB(xdot, ydot)); findCPCInk(test); Color peng = new Color (CPCRed , CPCGreen , CPCBlue); for (int p = 0; p < 27; p++){ pen = p; if (getCol(realInks[p]).getRGB() == peng.getRGB()) break; } int t = 0; while (pen>=cols){ t++; pen = recalculatePen(cols,pen); if (t==10) break; } if (pen>=cols) pen = badpen(cols, getCol(realInks[pen])); int cpcX = xdot/xstep; int cpcY = ydot/ystep; plot(cpcX, cpcY, pen & (cols-1)); } pen = keeppen; } public void findCPCInk(Color test){ RedPixel = test.getRed(); GreenPixel = test.getGreen(); BluePixel = test.getBlue(); int dark = bright; int medium = bright * 2 & 0xff; if (RedPixel < dark) CPCRed = 0; else if (RedPixel >= dark && RedPixel < medium) CPCRed = 0x7D; else CPCRed = 0xff; if (GreenPixel < dark) CPCGreen = 0; else if (GreenPixel >= dark && GreenPixel < medium) CPCGreen = 0x7D; else CPCGreen = 0xff; if (BluePixel < dark) CPCBlue = 0; else if (BluePixel >= dark && BluePixel < medium) CPCBlue = 0x7D; else CPCBlue = 0xff; } public int replaceInk(int[]inInk){ int outInk = realInks[pen]; int cols = 16; if (mode == 1) cols = 4; if (mode == 2) cols = 2; for (int c = 0; c < inInk.length; c++) for (int pn = 0; pn < cols; pn++) if (realInks[pn] == inInk[c]){ outInk = inInk[c]; return outInk; } return outInk; } public int recalculatePen(int cols, int penNo){ if (debug) System.out.println("PEN" + penNo); if (realInks[penNo] == -1) return penNo; int inkno = realInks[penNo]; if (debug) System.out.println("INK found: " + inkno); switch (inkno){ case 0: inkno = replaceInk(INK0); break; case 1: inkno = replaceInk(INK1); break; case 2: inkno = replaceInk(INK2); break; case 3: inkno = replaceInk(INK3); break; case 4: inkno = replaceInk(INK4); break; case 5: inkno = replaceInk(INK5); break; case 6: inkno = replaceInk(INK6); break; case 7: inkno = replaceInk(INK7); break; case 8: inkno = replaceInk(INK8); break; case 9: inkno = replaceInk(INK9); break; case 10: inkno = replaceInk(INK10); break; case 11: inkno = replaceInk(INK11); break; case 12: inkno = replaceInk(INK12); break; case 13: inkno = replaceInk(INK13); break; case 14: inkno = replaceInk(INK14); break; case 15: inkno = replaceInk(INK15); break; case 16: inkno = replaceInk(INK16); break; case 17: inkno = replaceInk(INK17); break; case 18: inkno = replaceInk(INK18); break; case 19: inkno = replaceInk(INK19); break; case 20: inkno = replaceInk(INK20); break; case 21: inkno = replaceInk(INK21); break; case 22: inkno = replaceInk(INK22); break; case 23: inkno = replaceInk(INK23); break; case 24: inkno = replaceInk(INK24); break; case 25: inkno = replaceInk(INK25); break; case 26: inkno = replaceInk(INK26); break; } for (int pn = 0; pn < cols; pn++) if (realInks[pn] == inkno){ if (debug) System.out.println("INK replaced: " + realInks[pn]); return pn; } return penNo; } public int badpen(int cols, Color incoming){ //Gray = 0.299*Red + 0.587*Green + 0.114*Blue int badpenr = CPCRed; int badpeng = CPCGreen; int badpenb = CPCBlue; int bestpen = -1; int K_Red = 9798; int K_Green = 19235; int K_Blue = 3735; long bestdist = 0x7FFFFFFF; for (int goodpen = 0; goodpen < cols; goodpen++){ int goodpenr = GACol[goodpen].getRed(); int goodpeng = GACol[goodpen].getGreen(); int goodpenb = GACol[goodpen].getBlue(); int rdiff = Math.abs(goodpenr - badpenr); int gdiff = Math.abs(goodpeng - badpeng); int bdiff = Math.abs(goodpenb - badpenb); long dist = (Math.abs(badpenr - cols >> goodpenr)*K_Red) + (Math.abs(badpeng - cols >> goodpeng)*K_Green) + (Math.abs(badpenb - cols >> goodpenb)*K_Blue); // dist = rdiff*rdiff + gdiff*gdiff + bdiff*bdiff; if (dist < bestdist) { bestdist = dist; bestpen = goodpen; } } return bestpen; } public Color getCol(int index){ return CPC.Palcols[index]; // Color colo = CPC.Palcols[GateArray.getInk(pen)]; // return colo; } //----------------------------------------------------------------- // Clears the canvas. //----------------------------------------------------------------- public void clear () { Graphics page = getGraphics(); setBackground(CPC.getCol(0)); page.drawRect (0, 0, CANVAS_WIDTH, CANVAS_HEIGHT); repaint(); for (int y = 0; y < 0x3fff; y++) CPC.POKE(0xc000 + y, 0); } public void putScreen (){ Graphics page = getGraphics(); img = new BufferedImage(640, 400, BufferedImage.SCALE_SMOOTH); nimg = new BufferedImage(768, 272, BufferedImage.SCALE_SMOOTH); nimg.getGraphics().drawImage(Switches.image, 0, 0, 768, 272, this); img.getGraphics().drawImage(nimg, 0, 0, 640, 400, 64, 40, 640+64, 200+40, this); page.drawImage(img, 0, 0, this); } public void buildScreen(BufferedImage image){ for (int x = 0; x < 640; x++) for (int y = 0; y < 400; y++) { Color test = new Color(image.getRGB(x, y)); Color testb = CPC.getCol(pen); if (test.getRGB() == testb.getRGB()){ int cpcX = x; int cpcY = y/2; if (mode == 0) cpcX/=4; if (mode == 1) cpcX/=2; plot(cpcX, cpcY, pen); } } } public void putText(){ BufferedImage off_Image = new BufferedImage(640, 400, BufferedImage.TYPE_INT_RGB); Graphics page = off_Image.createGraphics(); page.setColor(new Color(255,113,222)); page.fillRect(0, 0, 640, 400); page.setFont(new Font(fontname, 0+italic+bold,Integer.parseInt(JavaCPCPaint.textsize.getText()))); page.setColor(CPC.getCol(pen)); page.drawString(JavaCPCPaint.text.getText(), textX, textY); buildScreen(off_Image); // MODE = MODE_PAINT; } public void putObject(int number){ BufferedImage off_Image = new BufferedImage(640, 400, BufferedImage.TYPE_INT_RGB); Graphics page = off_Image.createGraphics(); page.setColor(new Color(255,113,222)); page.fillRect(0, 0, 640, 400); page.setColor(CPC.getCol(pen)); int xs = 1; int ys = 2; if (mode == 0) xs = 4; if (mode == 1) xs = 2; lineX = (lineX/xs)*xs; lineY = (lineY/ys)*ys; int fromx = lineX; int fromy = lineY; int tox = toX-lineX; int toy = toY-lineY; if (toX < lineX){ fromx = toX; tox = lineX-toX; } else { fromx = lineX; tox = toX-lineX; } if (toY < lineY){ fromy = toY; toy = lineY-toY; } else{ fromy = lineY; toy = toY-lineY; } tox = (tox/xs)*xs; toy = (toy/ys)*ys; if (number == 1) page.drawLine(lineX, lineY, toX, toY); if (number == 2) page.drawRect(fromx, fromy, tox, toy); if (number == 3) page.drawOval(fromx, fromy, tox, toy); if (number == 4) page.fillRect(fromx, fromy, tox, toy); if (number == 5) page.fillOval(fromx, fromy, tox, toy); buildScreen(off_Image); // MODE = MODE_PAINT; } public void copyShape(){ putScreen(); BufferedImage buffimg = new BufferedImage(640,400,BufferedImage.TYPE_INT_RGB); buffimg.getGraphics().drawImage(nimg, 0, 0, 640, 400, 64, 40, 640+64, 200+40, this); shape = new BufferedImage(shapeW, shapeH, BufferedImage.TYPE_INT_RGB); shape.getGraphics().drawImage(buffimg, 0-shapeX, 0-shapeY, shapeW,shapeH,0,0,shapeW+shapeX,shapeH+shapeY,this); int checksum = 0; for (int xdot = 0; xdot < shape.getWidth(); xdot+=2) for (int ydot = 0; ydot < shape.getHeight(); ydot+=2){ Color test = new Color(shape.getRGB(xdot, ydot)); checksum+=test.getRGB(); } if (checksum == 0){ System.err.println("Black image!!!"); copyShape(); } } public void showShape(int x,int y){ if (shape==null) return; putScreen(); Graphics page = getGraphics(); page.drawImage(shape, x, y, this); } public void buildShape(int xpos, int ypos){ if (shape==null) return; int xs = 4; int ys = 2; int pns = 16; if (mode == 1){ xs = 2; pns = 4; } if (mode == 2){ xs = 1; pns =2; } for (int x = 0; x < shape.getWidth(); x+=xs) for (int y = 0; y < shape.getHeight(); y+=ys) for (int pn = 0; pn < pns; pn++) { Color test = new Color(shape.getRGB(x, y)); Color testb = Col[GateArray.getInk(pn)]; if (test.getBlue() >= testb.getBlue()-0x40 && test.getBlue() <= testb.getBlue()+0x40 && test.getGreen() >= testb.getGreen()-0x40 && test.getGreen() <= testb.getGreen()+0x40 && test.getRed() >= testb.getRed()-0x40 && test.getRed() <= testb.getRed()+0x40){ int cpcX = x+xpos; int cpcY = (y+ypos)/2; if (mode == 0) cpcX/=4; if (mode == 1) cpcX/=2; try{ if (pn != transpen) plot(cpcX, cpcY, pn); } catch (Exception e){}; } } } public void mouseReleased (MouseEvent event) { int xs = 1; int ys = 2; if (mode == 0) xs = 4; if (mode == 1) xs = 2; int xc = (event.getX()/xs)*xs; int yc = (event.getY()/ys)*ys; if (MODE == MODE_MINITEXT){ putText(xc,yc); } if (MODE == MODE_TEXT){ putText(); } if (MODE == MODE_LINE){ putObject(1); } if (MODE == MODE_RECTANGLE){ putObject(2); } if (MODE == MODE_CIRCLE){ putObject(3); } if (MODE == MODE_FRECT){ putObject(4); } if (MODE == MODE_FILL){ Fill(xc,yc, pen); } if (MODE == MODE_FCIRCLE){ putObject(5); } if (MODE == MODE_COPY){ copyShape(); MODE = MODE_PASTE; } else if (MODE == MODE_PASTE){ if (xc >= 640-shape.getWidth()) xc = 640-shape.getWidth(); if (yc >= 400-shape.getHeight()) yc = 400-shape.getHeight(); buildShape(xc,yc); } // putScreen(); } public void mouseClicked (MouseEvent event) {} public void mouseEntered (MouseEvent event) {paint = true;} public void mouseExited (MouseEvent event) {paint = false;} public void mouseMoved (MouseEvent event) { int xs = 1; int ys = 2; if (mode == 0) xs = 4; if (mode == 1) xs = 2; int xc = (event.getX()/xs)*xs; int yc = (event.getY()/ys)*ys; JavaCPCPaint.reset(); if (painted) putScreen(); painted = false; if (MODE == MODE_MINITEXT){ Graphics page = getGraphics(); page.setColor(CPC.getCol(textpen)); page.fillRect(xc, yc, minisize, 10); } if (MODE == MODE_PAINT || MODE == MODE_LINE){ Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); page.fillRect(xc, yc, xs, ys); painted = true; } if (MODE == MODE_CIRCLE || MODE == MODE_FCIRCLE || MODE == MODE_COPY || MODE == MODE_RECTANGLE || MODE == MODE_FRECT){ Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); cross(xc,yc); page.fillRect(xc, yc, xs, ys); painted = true; } if (MODE == MODE_PASTE && shape != null){ if (xc >= 640-shape.getWidth()) xc = 640-shape.getWidth(); if (yc >= 400-shape.getHeight()) yc = 400-shape.getHeight(); showShape(xc, yc); } if (MODE == MODE_TEXT){ putScreen(); Point current = event.getPoint(); textX = (current.x/xs)*xs; textY = (current.y/ys)*ys; Graphics page = getGraphics(); page.setFont(new Font(fontname, 0+italic+bold,Integer.parseInt(JavaCPCPaint.textsize.getText()))); page.setColor(CPC.getCol(pen)); page.drawString(JavaCPCPaint.text.getText(), textX, textY); } } public void cross(int xc,int yc){ Graphics page = getGraphics(); page.setColor(random); page.drawLine(0, yc, 640, yc); page.drawLine(0, yc+1, 640, yc+1); page.drawLine(xc, 0, xc, 400); if (mode == 1 || mode == 0) page.drawLine(xc+1, 0, xc+1, 400); if (mode == 0){ page.drawLine(xc+2, 0, xc+2, 400); page.drawLine(xc+3, 0, xc+3, 400);} } public void cycle(){ random = new Color(Util.random(255),Util.random(255),Util.random(255)); if (checkPal>0){ checkPal++; if (checkPal > 20){ setPal(); putScreen(); } if (checkPal == 290){ checkPal = 0; } } if (reload > 0){ reload++; if (reload == 20){ reload(); } if (reload == 40){ putScreen(); JavaCPCPaint.reset(); reload = 0; } } if (doCycle){ if (MODE != MODE_IMPORT){ if (JavaCPCPaint.scroll.isEnabled()) JavaCPCPaint.scroll.setEnabled(false); if (JavaCPCPaint.scrollb.isEnabled()) JavaCPCPaint.scrollb.setEnabled(false); } else { if (!JavaCPCPaint.scroll.isEnabled()) JavaCPCPaint.scroll.setEnabled(true); if (!JavaCPCPaint.scrollb.isEnabled()) JavaCPCPaint.scrollb.setEnabled(true); } cyclec++; if (recalculate > 0){ recalculate++; if (recalculate == 20){ recalculate(); convert(true); } if (recalculate == 30){ convert(false); } if (recalculate == 40){ recalculate = 0; JavaCPCPaint.output.append("Size viewed: 640x400, ratio = " + (float)640/400+" Origin : (" + scroll+","+scrollb+")\n"); JavaCPCPaint.output.select(2000000000, 2000000000); putScreen(); } } /* if (CPC.initpaint == 0 && CPC.PEEK(0x4000) != 0x3a && CPC.PEEK(0x4128) != 0x52){ CPC.initpaint = 1; cyclec = 0; }*/ if (cycled > 0){ cycled++; if (cycled == 10){ convert(true); } if (cycled == 20){ putScreen(); cycled=0; } } if (cyclec == 20){ if (paintscreen){ convert(false); paintscreen = false; painted = true; } else convert(true); } if (cyclec == 30){ if (painted){ putScreen(); painted = false; } } } mode = GateArray.getSMode(); } public void makeUndo(){ for (int y = 0; y < 0x3fff; y++) undo[y] = CPC.PEEK(0xc000 + y); } public void INK(int pen, int ink){ int addressA = 0xb1d9; int addressB = 0xb1ea; if (Switches.ROM.equals("CPC6128") || Switches.ROM.equals("CPC664")) { addressA = 0xb7d4; addressB = 0xb7e5; } CPC.POKE(addressA+1+pen, GAInks[ink]); CPC.POKE(addressB+1+pen, GAInks[ink]); } public void Undo(){ for (int y = 0; y < 0x3fff; y++) CPC.POKE(0xc000 + y, undo[y]); putScreen(); } public void DSKLoad(){ JComboBox filelist = new JComboBox(); filelist.setFont(new Font("Courier",1,12)); String[] files = JavaCPCPaint.files; for (int y = 0; y < files.length; y++) files[y] = files[y].substring(0,12); for (int y = 0; y < files.length; y++) // if (files[y].endsWith("SCR") || files[y].endsWith("BIN") || files[y].endsWith(" ")) filelist.addItem(files[y]); Object[] object = { filelist, restorePal }; int selectedValue = JOptionPane.showOptionDialog(this, object, "Choose file:", JOptionPane.OK_CANCEL_OPTION, JOptionPane.OK_CANCEL_OPTION,null,null,null); if(selectedValue != JOptionPane.OK_OPTION) { return; } try{ String lname = filelist.getSelectedItem().toString(); byte[] load = lname.getBytes("UTF-8"); for (int i = 0x315; i < 0x315+12; i++){ CPC.POKE(0x4000+i, load[i-0x315]); } CPC.POKE(0x4fff,10); if (resPal){ checkPal = 1; } } catch (Exception e){} } public void setPal(){ int checksum = 0; for (int i = 0; i< 16; i++){ checksum+=CPC.PEEK(0xd7d1+i); } if (checksum != 0){ for (int i = 0; i< 16; i++){ INK (i, CPC.PEEK(0xd7d1+i)); } checksum = CPC.PEEK(0xd7d0); if (checksum == 0) checksum = 3; CPC.POKE(0x4fff, checksum); } } ItemListener restoreListener = new ItemListener() { public void itemStateChanged(ItemEvent itemEvent) { int state = itemEvent.getStateChange(); if (state == ItemEvent.SELECTED) { resPal = true; } if (state == ItemEvent.DESELECTED) { resPal = false; } } }; public void minitext(){ String[] pena = {"0", "1", "2", "3", "4","5","6","7","8","9","10" ,"11", "12", "13", "14", "15"}; String[] penb = {"0", "1", "2", "3", "4","5","6","7","8","9","10" ,"11", "12", "13", "14", "15", "Off"}; String[] transb = {"0", "1", "2", "3", "4","5","6","7","8","9","10" ,"11", "12", "13", "14", "15", "Transparent"}; JPanel pen1 = new JPanel(); pen1.setLayout(new FlowLayout(FlowLayout.RIGHT, 1, 2)); JPanel pen2 = new JPanel(); pen2.setLayout(new FlowLayout(FlowLayout.RIGHT, 1, 2)); JPanel backg = new JPanel(); backg.setLayout(new FlowLayout(FlowLayout.RIGHT, 1, 2)); JComboBox penA = new JComboBox(pena); JComboBox penB = new JComboBox(penb); JComboBox transB = new JComboBox(transb); penA.setSelectedIndex(textpen); penB.setSelectedIndex(smoothpen); transB.setSelectedIndex(transback); if (mode == 2){ penB.setEnabled(false); penB.setSelectedIndex(16); } JLabel penaa = new JLabel("Text-PEN "); JLabel penbb = new JLabel("Smooth-PEN "); JLabel transbb = new JLabel("Background "); backg.add(transbb); backg.add(transB); pen1.add(penaa); pen1.add(penA); pen2.add(penbb); pen2.add(penB); JTextField inputtext = new JTextField(); inputtext.setText(minitext); Object[] object = { inputtext, pen1, pen2, backg }; int selectedValue = JOptionPane.showOptionDialog(this, object, "Enter mini-text:", JOptionPane.OK_CANCEL_OPTION, JOptionPane.OK_CANCEL_OPTION,null,null,null); if(selectedValue != JOptionPane.OK_OPTION) { return; } try{ int pn1 = Integer.parseInt(penA.getSelectedItem().toString()); String pn2s = penB.getSelectedItem().toString(); String pn3s = transB.getSelectedItem().toString(); int pn2 = 0; int pn3 = 0; if (pn2s.equals("Off")) pn2 = 16; else pn2 = Integer.parseInt(penB.getSelectedItem().toString()); if (pn3s.equals("Transparent")) pn3 = 16; else pn3 = Integer.parseInt(transB.getSelectedItem().toString()); String enteredText = inputtext.getText(); createText(pn1, pn2,pn3, enteredText); } catch (Exception e){} } public void createText(int pen1, int pen2,int pen3, String text){ textpen = pen1; smoothpen = pen2; transback = pen3; minitext = text; text = text.toUpperCase(); output = new String[text.length()]; for (int i = 0; i< output.length; i++){ output[i] = text.substring(i,i+1); } minisize = output.length*5; if (mode == 1) minisize*=2; if (mode == 0) minisize*=4; MODE = MODE_MINITEXT; } public void putText(int x, int y){ y/=2; int width = minisize; if (mode == 1){ x/=2; width/=2; } if (mode == 0){ x/=4; width/=4; } int posx = x; int[] letter; for (int i = 0; i< width/5; i++){ letter = minifont.sp; if (output[i].equals("A")) letter = minifont.A; if (output[i].equals("B")) letter = minifont.B; if (output[i].equals("C")) letter = minifont.C; if (output[i].equals("D")) letter = minifont.D; if (output[i].equals("E")) letter = minifont.E; if (output[i].equals("F")) letter = minifont.F; if (output[i].equals("G")) letter = minifont.G; if (output[i].equals("H")) letter = minifont.H; if (output[i].equals("I")) letter = minifont.I; if (output[i].equals("J")) letter = minifont.J; if (output[i].equals("K")) letter = minifont.K; if (output[i].equals("L")) letter = minifont.L; if (output[i].equals("M")) letter = minifont.M; if (output[i].equals("N")) letter = minifont.N; if (output[i].equals("O")) letter = minifont.O; if (output[i].equals("P")) letter = minifont.P; if (output[i].equals("Q")) letter = minifont.Q; if (output[i].equals("R")) letter = minifont.R; if (output[i].equals("S")) letter = minifont.S; if (output[i].equals("T")) letter = minifont.T; if (output[i].equals("U")) letter = minifont.U; if (output[i].equals("V")) letter = minifont.V; if (output[i].equals("W")) letter = minifont.W; if (output[i].equals("X")) letter = minifont.X; if (output[i].equals("Y")) letter = minifont.Y; if (output[i].equals("Z")) letter = minifont.Z; if (output[i].equals("1")) letter = minifont.n1; if (output[i].equals("2")) letter = minifont.n2; if (output[i].equals("3")) letter = minifont.n3; if (output[i].equals("4")) letter = minifont.n4; if (output[i].equals("5")) letter = minifont.n5; if (output[i].equals("6")) letter = minifont.n6; if (output[i].equals("7")) letter = minifont.n7; if (output[i].equals("8")) letter = minifont.n8; if (output[i].equals("9")) letter = minifont.n9; if (output[i].equals("0")) letter = minifont.n0; if (output[i].equals("©")) letter = minifont.cr; if (output[i].equals("@")) letter = minifont.at; if (output[i].equals("-")) letter = minifont.mn; if (output[i].equals("+")) letter = minifont.pl; if (output[i].equals(",")) letter = minifont.km; if (output[i].equals(";")) letter = minifont.sm; if (output[i].equals(".")) letter = minifont.pt; if (output[i].equals(":")) letter = minifont.dp; if (output[i].equals("/")) letter = minifont.sl; if (output[i].equals("\\")) letter = minifont.bs; if (output[i].equals("\"")) letter = minifont.qt; if (output[i].equals("?")) letter = minifont.qm; if (output[i].equals("!")) letter = minifont.xm; if (output[i].equals("$")) letter = minifont.dl; if (output[i].equals("&")) letter = minifont.nd; if (output[i].equals("#")) letter = minifont.rt; if (output[i].equals("*")) letter = minifont.mp; if (output[i].equals("_")) letter = minifont.us; if (output[i].equals("(")) letter = minifont.bo; if (output[i].equals(")")) letter = minifont.bc; if (output[i].equals("[")) letter = minifont.co; if (output[i].equals("]")) letter = minifont.cc; if (output[i].equals("=")) letter = minifont.eq; if (output[i].equals("<")) letter = minifont.st; if (output[i].equals(">")) letter = minifont.lt; if (output[i].equals("%")) letter = minifont.pc; if (output[i].equals("|")) letter = minifont.rx; if (output[i].equals("'")) letter = minifont.qo; if (output[i].equals("{")) letter = minifont.rc; if (output[i].equals("}")) letter = minifont.ro; int block = 0; for (int ypixel = 0; ypixel< 5; ypixel++){ for (int xpixel = 0; xpixel< 5; xpixel++){ if (letter[block] == 1) plot(posx+xpixel, y+ypixel, textpen); if (letter[block] == 2 && smoothpen < 16) plot(posx+xpixel, y+ypixel, smoothpen); if (letter[block] == 0 && transback<16) plot(posx+xpixel, y+ypixel, transback); block++; } } posx+=5; } } protected int[] x = new int[52]; protected int[] y = new int[52]; protected int z, xStep; protected Color hf, vfl, vfr, fr, fl; protected int fillX, fillY; public Color test(int x, int y){ Color result = CPC.getCol(pen); if (x >=0 && x <=640 && y >=0 && y<=400) result = new Color(img.getRGB(x, y)); return result; } public void Fill(int x, int y, int p){ fillX = x; fillY = y; xStep = 1; if (mode == 1) xStep = 2; if (mode == 0) xStep = 4; putScreen(); z = 0; hf = new Color(img.getRGB(fillX, fillY)); System.out.println(Util.hex(hf.getRGB())); if (hf.getRGB() == CPC.getCol(p).getRGB()) return; getCoords(); } protected void getCoords(){ if (fillX <0 || fillX >640-xStep || fillY <0 || fillY>399){ getnewCoords(); } searchUP(); } public void searchUP(){ // try{ while (test(fillX, fillY).getRGB() == hf.getRGB() && fillY < 398) fillY+=2; fillY-=2; fl = new Color (0x44,0x44,0x44); fr = fl; fillDown(); // } // catch (java.lang.StackOverflowError So){System.gc();} } public void fillDown(){ while (fillY>=0 && test(fillX, fillY).getRGB() == hf.getRGB() && fillX<(640-xStep)){ // look to left vfl = fl; fl = test(fillX-xStep, fillY); if (vfl.getRGB() != hf.getRGB() && fl.getRGB() == hf.getRGB()){ x[z] = fillX-xStep; y[z] = fillY; z++; } // look to right vfr = fr; fr = test(fillX+xStep, fillY); if (vfr.getRGB() != hf.getRGB() && fr.getRGB() == hf.getRGB()){ x[z] = fillX+xStep; y[z] = fillY; z++; } int cpcY = fillY / 2; int cpcX = fillX / xStep; // plot point CPC.PLOT(cpcX, cpcY, pen, mode); Graphics page = getGraphics(); img.getGraphics().setColor(CPC.getCol(pen)); page.setColor(CPC.getCol(pen)); img.getGraphics().fillRect(fillX, fillY, xStep, 2); page.fillRect(fillX, fillY, xStep, 2); fillY-=2; } getnewCoords(); } protected void getnewCoords(){ // get new coordinates z--; if (z>=0){ fillX=x[z]; fillY=y[z]; getCoords(); } } } Die Füllroutine befindet sich am Ende. Zitieren
Devilmarkus Geschrieben 29. Oktober 2009 Autor Geschrieben 29. Oktober 2009 Hier mal eine kurze GIF Animation, welche zeigt, was passiert: Im zweiten FILL soll der Hintergrund Cyanfarben gefüllt werden. Es werden nicht alle Bereiche gefüllt, sondern es kommt dort zum Fehler, wo er abbricht. Zitieren
flashpixx Geschrieben 29. Oktober 2009 Geschrieben 29. Oktober 2009 Dein Code ist weder strukturiert noch kommentiert und wie schon meine Vermutung war, dass es hierbei um Listener geht. Kommentiere und strukturiere den Code entsprechend und überlege Dir, ob diese Masse Code in einem Listener überhaupt sinnvoll ist, vor allem weil Du eine Menge Objekte auf dem Stack erzeugst Zitieren
Devilmarkus Geschrieben 29. Oktober 2009 Autor Geschrieben 29. Oktober 2009 Dein Code ist weder strukturiert noch kommentiert und wie schon meine Vermutung war, dass es hierbei um Listener geht. Kommentiere und strukturiere den Code entsprechend und überlege Dir, ob diese Masse Code in einem Listener überhaupt sinnvoll ist, vor allem weil Du eine Menge Objekte auf dem Stack erzeugst Dazu reichen meine Kenntnisse nicht aus, leider. Übrigens: Ich habe mal "test" geprüft. Das Ergebnis ist wirklich sonderbar: (Mein veränderter Code) public Color test(int x, int y){ Color result = CPC.getCol(pen); try{ result = new Color(img.getRGB(x, y));} catch (java.lang.ArrayIndexOutOfBoundsException ek){ System.out.println("img is " + img.getWidth() + "x"+img.getHeight() + " Pixels."); System.out.println("I tested here: " + x + " x " + y + " y"); System.out.println("Java means, this is bad. Why???"); System.out.println(ek.getMessage()); ek.printStackTrace(); System.exit(0);} return result; } Konsolenausgabe: img is 640x400 Pixels. I tested here: 640 x 396 y Java means, this is bad. Why??? Coordinate out of bounds! at sun.awt.image.IntegerInterleavedRaster.getDataElements(IntegerInterleavedRaster.java:202) at java.awt.image.BufferedImage.getRGB(BufferedImage.java:871) at jemu.system.cpc.PaintCanvas.test(PaintCanvas.java:1690) Zitieren
Klotzkopp Geschrieben 30. Oktober 2009 Geschrieben 30. Oktober 2009 Das ist überhaupt nicht sonderbar. Wenn etwas 640 x 400 Pixel groß ist, dann gehen die erlaubten x-Werte von 0 bis 639, und die y-Werte von 0 bis 399. Zitieren
Dragon8 Geschrieben 30. Oktober 2009 Geschrieben 30. Oktober 2009 Das scheint eindeutig nen Rekursionsproblem zu sein, wenn du dir mal den Stack Trace deiner Exception anschaust, führt er dort immer wieder deine 4 Methoden von vorne aus, ohne mal eine wirklich zu beenden. Wäre es vielleicht nicht sinnvoller dies ebenso wie im BASIC Programm mit einer Schleife zu lösen, anstatt per Rekursion? Zitieren
Devilmarkus Geschrieben 30. Oktober 2009 Autor Geschrieben 30. Oktober 2009 Habe es hinbekommen. protected int[] xx = new int[52]; protected int[] yy = new int[52]; protected int z, xStep; protected Color hf, vfl, vfr, fr, fl; protected int fillX, fillY; public void Fill(int x, int y, int p){ for (int pf = 0; pf < 52; pf++){ xx[pf] = 0; yy[pf] = 0; } fillX = x; fillY = y; xStep = 1; if (mode == 1) xStep = 2; if (mode == 0) xStep = 4; putScreen(); z = 0; hf = new Color(img.getRGB(fillX, fillY)); if (hf.getRGB() == CPC.getCol(p).getRGB()) return; getCoords(); } protected void getCoords(){ while (fillX <0 || fillX >640-xStep || fillY <0 || fillY>399){ z--; if (z>=0) fillX=xx[z]; fillY=yy[z]; } searchUP(); } public void searchUP(){ try{ //Graphics page = getGraphics(); //page.setColor(CPC.getCol(pen)); while (test(fillX, fillY).getRGB() == hf.getRGB() && fillY < 400) fillY+=2; fillY-=2; fl = new Color (0x44,0x44,0x44); fr = fl; while (fillY>=0 && test(fillX, fillY).getRGB() == hf.getRGB()&& fillX >=0 && fillX<=(640-xStep)){ // look to left vfl = fl; fl = test(fillX-xStep, fillY); if (vfl.getRGB() != hf.getRGB() && fl.getRGB() == hf.getRGB()){ if (fillX >= xStep){ xx[z] = fillX-xStep; yy[z] = fillY; z++;} else{ xx[z] = 0; yy[z] = fillY; z++;} } // look to right vfr = fr; fr = test(fillX+xStep, fillY); if (vfr.getRGB() != hf.getRGB() && fr.getRGB() == hf.getRGB()){ xx[z] = fillX+xStep; yy[z] = fillY; z++; } int cpcY = fillY / 2; int cpcX = fillX / xStep; // plot point CPC.PLOT(cpcX, cpcY, pen, mode); img.getGraphics().setColor(CPC.getCol(pen)); img.getGraphics().drawLine(fillX, fillY, fillX, fillY); //page.fillRect(fillX, fillY, xStep, 2); fillY-=2; } z--; if (z>=0){ fillX=xx[z]; fillY=yy[z]; getCoords(); } } catch (java.lang.StackOverflowError So){} } public Color test(int x, int y){ Color result = CPC.getCol(pen); try{ if (x<0) x = 0; if (y<0) y = 0; if (x>=640) x = 639; if (y>=400) y = 399; result = new Color(img.getRGB(x, y));} catch (java.lang.ArrayIndexOutOfBoundsException ek){ System.err.println("Error in TEST! X " + x + " Y " + y);} return result; } Zitieren
Dragon8 Geschrieben 30. Oktober 2009 Geschrieben 30. Oktober 2009 Ob das nun die beste Lösung ist, wage ich noch zu bezweifeln, weil deine beiden Funktionen getCoords() und searchUP() sich noch immer gegenseitig aufrufen, und dadurch eine Rekursion erzeugen. Du hast nun zwar die dritte Methode weggelassen, und wie es aussieht in die Methode searchUP() integriert, jedoch kann ich mir gut vorstellen, dass der Fehler in bestimmten Situationen weiterhin auftritt. Du hast halt jetzt einfach nur ~1/3 mehr Platz (eher weniger) auf dem Stack gewonnen bevor das Problem wieder auftritt. Und das Problem dann mit einer leeren catch Klausel abzufangen ohne benachrichtigt zu werden, ist dann auch nicht die beste Art Zitieren
Devilmarkus Geschrieben 30. Oktober 2009 Autor Geschrieben 30. Oktober 2009 Ich weiss leider nicht, wie ich die letze Rekursion raus bekomme. Irgendeine Idee? Wäre nett. Zitieren
Devilmarkus Geschrieben 30. Oktober 2009 Autor Geschrieben 30. Oktober 2009 Es scheint nun zu funktionieren: protected int[] xx = new int[51]; protected int[] yy = new int[51]; protected int z, xStep; protected Color hf, vfl, vfr, fr, fl; protected int fillX, fillY; public void Fill(int x, int y, int p){ for (int pf = 0; pf < 51; pf++){ xx[pf] = 0; yy[pf] = 0; } fillX = x; fillY = y; xStep = 1; if (mode == 1) xStep = 2; if (mode == 0) xStep = 4; putScreen(); z = 0; hf = new Color(img.getRGB(fillX, fillY)); if (hf.getRGB() == CPC.getCol(p).getRGB()) return; getCoords(); searchUP(); } protected void getCoords(){ while (fillX <0 || fillX >640-xStep || fillY <0 || fillY>399){ reCalc(); } } public void reCalc(){ z--; if (z>=0){ if (xx[z]>=0) fillX=xx[z]; if (yy[z]>=0) fillY=yy[z]; } } public void searchUP(){ while (z>=0){ Graphics page = getGraphics(); page.setColor(CPC.getCol(pen)); while (test(fillX, fillY).getRGB() == hf.getRGB() && fillY < 400) fillY+=2; fillY-=2; fl = new Color (0x44,0x44,0x44); fr = fl; while (fillY>=0 && test(fillX, fillY).getRGB() == hf.getRGB()&& fillX >=0 && fillX<=(640-xStep)){ // look to left vfl = fl; fl = test(fillX-xStep, fillY); if (vfl.getRGB() != hf.getRGB() && fl.getRGB() == hf.getRGB()){ if (fillX >= xStep){ xx[z] = fillX-xStep; yy[z] = fillY; z++;} else{ xx[z] = 0; yy[z] = fillY; z++;} } // look to right vfr = fr; fr = test(fillX+xStep, fillY); if (vfr.getRGB() != hf.getRGB() && fr.getRGB() == hf.getRGB()){ xx[z] = fillX+xStep; yy[z] = fillY; z++; } int cpcY = fillY / 2; int cpcX = fillX / xStep; // plot point CPC.PLOT(cpcX, cpcY, pen, mode); img.getGraphics().setColor(CPC.getCol(pen)); img.getGraphics().drawLine(fillX, fillY, fillX, fillY); page.fillRect(fillX, fillY, xStep, 2); fillY-=2; } reCalc(); } } public Color test(int x, int y){ Color result = CPC.getCol(pen); try{ if (x<0) x = 0; if (y<0) y = 0; if (x>=640) x = 639; if (y>=400) y = 399; result = new Color(img.getRGB(x, y));} catch (java.lang.ArrayIndexOutOfBoundsException ek){ System.err.println("Error in FILL! X " + x + " Y " + y);} return result; } Rekursionen sollten nun auch keine mehr drin sein. Bin dabei, es nun intensiv zu testen. Zitieren
flashpixx Geschrieben 30. Oktober 2009 Geschrieben 30. Oktober 2009 Das Problem wird immer noch auftreten, denn Du erzeugst immer noch in Deiner Listener Klasse, die auf die Mausevents reagiert mit new neue Objekte auf dem Stack, vielleicht jetzt nicht mehr so viele, aber durchaus kann es weiterhin zu Problemen kommen Zitieren
Devilmarkus Geschrieben 30. Oktober 2009 Autor Geschrieben 30. Oktober 2009 Wie sieht es denn damit aus? In der einen Klasse rufe ich nur dieses hier auf: public void Fill(int x, int y, int p, int m){ Fill fill = new Fill(); putScreen(); fill.img = img; fill.Fill(x, y, p, m); } Dann habe ich eine zweite Klasse: /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package jemu.system.cpc; import java.awt.Color; import java.awt.image.BufferedImage; /** * * @author Markus */ public class Fill { protected int[] xx = new int[400]; protected int[] yy = new int[400]; protected int z, xStep; protected Color hf, vfl, vfr, fr, fl; protected int fillX, fillY; public BufferedImage img; public int mode; public int pen; public void Fill(int x, int y, int p, int m){ mode = m; pen = p; for (int pf = 0; pf < 400; pf++){ xx[pf] = 0; yy[pf] = 0; } fillX = x; fillY = y; xStep = 1; if (mode == 1) xStep = 2; if (mode == 0) xStep = 4; z = 0; hf = new Color(img.getRGB(fillX, fillY)); if (hf.getRGB() == CPC.getCol(p).getRGB()) return; getCoords(); searchUP(); } protected void getCoords(){ while (fillX <0 || fillX >640-xStep || fillY <0 || fillY>399){ reCalc(); } } public void reCalc(){ z--; if (z>=0){ if (xx[z]>=0) fillX=xx[z]; if (yy[z]>=0) fillY=yy[z]; } } public void searchUP(){ while (z>=0){ while (test(fillX, fillY).getRGB() == hf.getRGB() && fillY < 400) fillY+=2; fillY-=2; fl = new Color (0x44,0x44,0x44); fr = fl; while (fillY>=0 && test(fillX, fillY).getRGB() == hf.getRGB()&& fillX >=0 && fillX<=(640-xStep)){ // look to left vfl = fl; fl = test(fillX-xStep, fillY); if (vfl.getRGB() != hf.getRGB() && fl.getRGB() == hf.getRGB()){ if (fillX >= xStep){ xx[z] = fillX-xStep; yy[z] = fillY; z++;} else{ xx[z] = 0; yy[z] = fillY; z++;} } // look to right vfr = fr; fr = test(fillX+xStep, fillY); if (vfr.getRGB() != hf.getRGB() && fr.getRGB() == hf.getRGB()){ xx[z] = fillX+xStep; yy[z] = fillY; z++; } int cpcY = fillY / 2; int cpcX = fillX / xStep; // plot point CPC.PLOT(cpcX, cpcY, pen, mode); img.getGraphics().setColor(CPC.getCol(pen)); img.getGraphics().drawLine(fillX, fillY, fillX, fillY); fillY-=2; } reCalc(); } } public Color test(int x, int y){ Color result = CPC.getCol(pen); try{ if (x<0) x = 0; if (y<0) y = 0; if (x>=640) x = 639; if (y>=400) y = 399; result = new Color(img.getRGB(x, y));} catch (java.lang.ArrayIndexOutOfBoundsException ek){ System.err.println("Error in FILL! X " + x + " Y " + y);} return result; } } Scheint fehlerfrei zu funktionieren. Zitieren
flashpixx Geschrieben 30. Oktober 2009 Geschrieben 30. Oktober 2009 Du hast immer noch den new-Operator innerhalb Deiner Routinen. Jedes Mal wenn Du "fill" aufrufst werden Objekte auf Deinem Stack abgelegt, da Du von "MouseMotionListener" ableitest, dürfte das relativ oft sein und Du wirst damit irgendwann wieder den Overflow bekommen Zitieren
Devilmarkus Geschrieben 30. Oktober 2009 Autor Geschrieben 30. Oktober 2009 Okay, das habe ich auch behoben. Fill wird nun bei Initialisierung 1x erstellt. Ich habe nun ein ganz anderes Problem: Wenn ich "weisse" Bereiche füllen möchte, hängt sich die Routine auf. Ich habe daher "weiss" den Farbwert 0xFEFEFE zugewiesen. Merkt man mit blossem Auge nicht, ist aber dennoch irgendwie doof. Ansonsten funktioniert diese Routine nun einwandfrei. Zitieren
Empfohlene Beiträge
Dein Kommentar
Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.