PixelEngine/src/sig/engine/Panel.java

750 lines
24 KiB
Java
Raw Normal View History

2022-11-28 10:29:34 -06:00
package sig.engine;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.ColorModel;
import java.awt.image.MemoryImageSource;
import java.util.ArrayList;
import java.util.HashMap;
2022-11-28 10:29:34 -06:00
import java.util.List;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.GraphicsEnvironment;
import java.awt.GraphicsConfiguration;
2022-11-28 10:29:34 -06:00
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.MouseInputListener;
import java.awt.event.KeyListener;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
2022-11-28 10:29:34 -06:00
import sig.JavaProjectTemplate;
public class Panel extends JPanel implements Runnable,KeyListener {
2022-11-28 10:29:34 -06:00
JFrame window;
static JavaProjectTemplate gameInstance;
2022-11-28 10:29:34 -06:00
public int pixel[];
final int CIRCLE_PRECISION=32;
final int OUTLINE_COL=Color.BRIGHT_WHITE.getColor();
private Thread thread;
private Image imageBuffer;
private MemoryImageSource mImageProducer;
private ColorModel cm;
int scanLine=0;
int nextScanLine=0;
double x_offset=0;
double y_offset=0;
int frameCount=0;
long lastSecond=0;
boolean resizing=false;
long lastUpdate=System.nanoTime();
final long TARGET_FRAMETIME = 8333333l;
public double nanaX = 0;
public double nanaY = 0;
public int button = 0;
public HashMap<Integer,Boolean> MOUSE = new HashMap<>();
private Point mousePosition = new Point(0,0);
private MouseScrollValue scrollWheel=null;
public static final int UPDATE_LOOP_FRAMERATE = 244;
public static final long UPDATE_LOOP_NANOTIME = (long)((1d/UPDATE_LOOP_FRAMERATE)*1000000000l);
public static final double UPDATE_MULT = 1d / UPDATE_LOOP_FRAMERATE;
public static RenderingHints RENDERHINTS = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
static long lastReportedTime = System.currentTimeMillis();
public static long TIME = 0;
public static long scaleTime;
public static Panel p;
public static JFrame f;
public static void InitializeEngine(JavaProjectTemplate instance){
System.setProperty("sun.java2d.transaccel", "True");
System.setProperty("sun.java2d.d3d", "True");
System.setProperty("sun.java2d.ddforcevram", "True");
System.setProperty("sun.java2d.xrender", "True");
gameInstance=instance;
RENDERHINTS.put(RenderingHints.KEY_COLOR_RENDERING,RenderingHints.VALUE_COLOR_RENDER_SPEED);
RENDERHINTS.put(RenderingHints.KEY_DITHERING,RenderingHints.VALUE_DITHER_DISABLE);
RENDERHINTS.put(RenderingHints.KEY_FRACTIONALMETRICS,RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
RENDERHINTS.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_SPEED);
f = new JFrame(JavaProjectTemplate.PROGRAM_NAME);
f.setResizable(false);
f.setSize(JavaProjectTemplate.WINDOW_WIDTH,JavaProjectTemplate.WINDOW_HEIGHT);
p = new Panel(f);
JavaProjectTemplate.game=p;
p.init();
f.add(p);
f.addKeyListener(p);
f.setLocation((int) ((Toolkit.getDefaultToolkit().getScreenSize().getWidth() - f.getWidth()) / 2),
(int) ((Toolkit.getDefaultToolkit().getScreenSize().getHeight() - f.getHeight()) / 2));
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
p.render();
long lastGameTime = System.nanoTime();
long dt = 0;
while (true) {
dt += System.nanoTime() - lastGameTime;
lastGameTime = System.nanoTime();
while (dt >= UPDATE_LOOP_NANOTIME) {
gameInstance.updateGame(UPDATE_LOOP_NANOTIME/1000000000d);
dt -= UPDATE_LOOP_NANOTIME;
TIME += UPDATE_LOOP_NANOTIME;
}
gameUpdateLoopStabilizer(dt); //This is hackish. Removing this slows down the game by about 30%. The timer runs slower. ???
}
}
private static void gameUpdateLoopStabilizer(long dt) {
if (dt < UPDATE_LOOP_NANOTIME) {
lastReportedTime = System.currentTimeMillis();
} else {
if (System.currentTimeMillis() - lastReportedTime > 5000) {
System.out.println("WARNING! Game is lagging behind! Frames Behind: " + (dt / UPDATE_LOOP_NANOTIME));
lastReportedTime = System.currentTimeMillis();
}
}
try {
Thread.sleep(4);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
2022-11-28 10:29:34 -06:00
public Panel(JFrame f) {
super(true);
this.window=f;
thread = new Thread(this, "MyPanel Thread");
this.addMouseListener(new MouseInputListener(){
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
MOUSE.put(e.getButton(),true);
}
@Override
public void mouseReleased(MouseEvent e) {
MOUSE.put(e.getButton(),false);
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseDragged(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
}
});
this.addMouseMotionListener(new MouseMotionListener(){
@Override
public void mouseDragged(MouseEvent e) {
mousePosition.set(e.getX(),e.getY());
}
@Override
public void mouseMoved(MouseEvent e) {
mousePosition.set(e.getX(),e.getY());
}
});
this.addMouseWheelListener(new MouseWheelListener(){
//-1 is UP, 1 is DOWN
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
scrollWheel=MouseScrollValue.getValue(e.getWheelRotation());
}
});
2022-11-28 10:29:34 -06:00
}
/**
2022-11-28 10:29:34 -06:00
* Get Best Color model available for current screen.
* @return color model
*/
protected static ColorModel getCompatibleColorModel(){
GraphicsConfiguration gfx_config = GraphicsEnvironment.
getLocalGraphicsEnvironment().getDefaultScreenDevice().
getDefaultConfiguration();
return gfx_config.getColorModel();
}
2022-11-28 10:29:34 -06:00
/**
* Call it after been visible and after resizes.
*/
public void init(){
cm = getCompatibleColorModel();
int screenSize = JavaProjectTemplate.WINDOW_WIDTH * JavaProjectTemplate.WINDOW_HEIGHT;
2022-11-28 10:29:34 -06:00
if(pixel == null || pixel.length < screenSize){
pixel = new int[screenSize];
}
mImageProducer = new MemoryImageSource(JavaProjectTemplate.WINDOW_WIDTH, JavaProjectTemplate.WINDOW_HEIGHT, cm, pixel,0, JavaProjectTemplate.WINDOW_WIDTH);
2022-11-28 10:29:34 -06:00
mImageProducer.setAnimated(true);
mImageProducer.setFullBufferUpdates(true);
imageBuffer = Toolkit.getDefaultToolkit().createImage(mImageProducer);
if(thread.isInterrupted() || !thread.isAlive()){
thread.start();
}
2022-11-28 10:29:34 -06:00
}
@Override
public void paintComponent(Graphics g) {
//super.paintComponent(g);
// perform draws on pixels
long startTime = System.currentTimeMillis();
g.drawImage(this.imageBuffer,0,0,JavaProjectTemplate.WINDOW_WIDTH,JavaProjectTemplate.WINDOW_HEIGHT,0,0,JavaProjectTemplate.WINDOW_WIDTH,JavaProjectTemplate.WINDOW_HEIGHT,this);
scaleTime=System.currentTimeMillis()-startTime;
2022-11-28 10:29:34 -06:00
}
/**
* Overrides ImageObserver.imageUpdate.
* Always return true, assuming that imageBuffer is ready to go when called
*/
@Override
public boolean imageUpdate(Image image, int a, int b, int c, int d, int e) {
return true;
}
/**
* Do your draws in here !!
* pixel is your canvas!
*/
2022-11-28 10:29:34 -06:00
public /* abstract */ void render(){
gameInstance.drawGame();
2022-11-28 10:29:34 -06:00
}
public void FillCircle(double center_x,double center_y,double r,Color col) {
2022-11-28 10:29:34 -06:00
int counter=0;
Point[] points = new Point[CIRCLE_PRECISION];
for (double theta=0;theta<Math.PI*2;theta+=((Math.PI*2)/CIRCLE_PRECISION)) {
//System.out.println("Loop "+counter+++". Theta:"+theta);
//System.out.println("X:"+(Math.sin(theta)*r+center_x)+" Y:"+(Math.cos(theta)*r+center_y));
points[counter++]=new Point((int)(Math.round(Math.sin(theta)*r+center_x)),(int)(Math.round(Math.cos(theta)*r+center_y)));
}
FillPolygon(0,0,col,points);
2022-11-28 10:29:34 -06:00
}
public void FillOval(double center_x,double center_y,double w,double h,Color col) {
2022-11-28 10:29:34 -06:00
int counter=0;
Point[] points = new Point[CIRCLE_PRECISION];
double r = Math.max(w,h);
double ratio = Math.min(w,h)/r;
for (double theta=0;theta<Math.PI*2;theta+=((Math.PI*2)/CIRCLE_PRECISION)) {
//System.out.println("Loop "+counter+++". Theta:"+theta);
//System.out.println("X:"+(Math.sin(theta)*r+center_x)+" Y:"+(Math.cos(theta)*r+center_y));
Point newP = new Point((int)(Math.round(Math.sin(theta)*r)),(int)(Math.round(Math.cos(theta)*r)));
if (w<h) {
newP.x=(int)Math.round(newP.x*ratio);
} else {
newP.y=(int)Math.round(newP.y*ratio);
}
newP.x+=center_x;
newP.y+=center_y;
points[counter++]=newP;
}
FillPolygon(0,0,col,points);
2022-11-28 10:29:34 -06:00
}
public void FillPolygon(double x_offset,double y_offset,Color col,Point...points) {
2022-11-28 10:29:34 -06:00
Edge[] edges = new Edge[points.length];
List<Edge> edges_sorted = new ArrayList<Edge>();
for (int i=0;i<points.length;i++) {
edges[i] = new Edge(points[i],points[(i+1)%points.length]);
if (!Double.isInfinite(edges[i].inverse_slope)) {
if (edges_sorted.size()==0) {
edges_sorted.add(edges[i]);
} else {
boolean inserted=false;
for (int j=0;j<edges_sorted.size();j++) {
Edge e2 = edges_sorted.get(j);
if (e2.min_y>=edges[i].min_y) {
edges_sorted.add(j,edges[i]);
inserted=true;
break;
}
}
if (!inserted) {
edges_sorted.add(edges[i]);
}
}
}
}
//System.out.println(edges_sorted);
List<Edge> active_edges = new ArrayList<Edge>();
scanLine = edges_sorted.get(0).min_y-1;
nextScanLine = scanLine+1;
do {
for (int i=0;i<active_edges.size();i+=2) {
if (i>=active_edges.size()-1) break;
2022-11-28 10:29:34 -06:00
Edge e1 = active_edges.get(i);
Edge e2 = active_edges.get(i+1);
//System.out.println("Drawing from "+((int)Math.round(e1.x_of_min_y))+" to "+e2.x_of_min_y+" on line "+scanLine);
for (int x=(int)Math.round(e1.x_of_min_y);x<=e2.x_of_min_y;x++) {
if (x<0||x>JavaProjectTemplate.WINDOW_WIDTH) continue;
int index = (scanLine+(int)y_offset)*getWidth()+x+(int)x_offset;
if (index<pixel.length&&index>=0) {
Draw(index,col.getColor());
2022-11-28 10:29:34 -06:00
}
}
}
List<Edge> new_active_edges = new ArrayList<Edge>();
for (int i=0;i<active_edges.size();i++) {
Edge e = active_edges.get(i);
if (e.max_y==scanLine+1) {
active_edges.remove(i--);
} else {
e.x_of_min_y+=e.inverse_slope;
}
}
scanLine++;
for (int i=0;i<active_edges.size();i++) {
Edge e = active_edges.get(i);
boolean inserted=false;
for (int j=0;j<new_active_edges.size();j++) {
Edge e2 = new_active_edges.get(j);
if (e2.x_of_min_y>e.x_of_min_y) {
new_active_edges.add(j,e);
inserted=true;
break;
}
}
if (!inserted) {
new_active_edges.add(e);
}
}
active_edges=new_active_edges;
GetNextScanLineEdges(edges_sorted, active_edges);
}
while (active_edges.size()>0);
}
private void GetNextScanLineEdges(List<Edge> edges_sorted, List<Edge> active_edges) {
if (scanLine==nextScanLine) {
for (int i=0;i<edges_sorted.size();i++) {
Edge e = edges_sorted.get(i);
if (e.min_y==scanLine) {
e = edges_sorted.remove(i--);
boolean inserted=false;
for (int j=0;j<active_edges.size();j++) {
if (e.x_of_min_y<active_edges.get(j).x_of_min_y) {
active_edges.add(j,e);
inserted=true;
break;
}
}
if (!inserted) {
active_edges.add(e);
}
} else
if (e.min_y>scanLine) {
nextScanLine=e.min_y;
break;
}
}
}
}
public void Draw(int x, int y, Color col) {
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
}
void Draw(int index, int col) {
pixel[index]=col;
2022-11-28 10:29:34 -06:00
}
@Override
public void run() {
while (true) {
// request a JPanel re-drawing
render();
mImageProducer.newPixels();
if (f!=null) {
Graphics2D g2 = (Graphics2D)f.getGraphics();
if (g2!=null) {
g2.setRenderingHints(RENDERHINTS);
try {
repaint();
} finally {
g2.dispose();
}
}
}
updateFPSCounter();
2022-11-28 10:29:34 -06:00
//System.out.println("Repaint "+frameCount++);
waitForNextFrame();
2022-11-28 10:29:34 -06:00
}
}
private void waitForNextFrame() {
long newTime = System.nanoTime();
if (newTime-lastUpdate<TARGET_FRAMETIME) {
long timeRemaining=TARGET_FRAMETIME-(newTime-lastUpdate);
long millis = timeRemaining/1000000l;
int nanos = (int)(timeRemaining-millis*1000000l);
//System.out.println(timeRemaining+"/"+millis+" Nanos:"+nanos);
try {
Thread.sleep(millis,nanos);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
lastUpdate=newTime;
}
private void updateFPSCounter() {
if (window!=null&&System.currentTimeMillis()-lastSecond>=1000) {
window.setTitle(JavaProjectTemplate.PROGRAM_NAME+" - FPS: "+(frameCount));
frameCount=0;
lastSecond=System.currentTimeMillis();
}
frameCount++;
}
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
if (!Key.isKeyHeld(e.getKeyCode())) {
Key.setKeyHeld(e.getKeyCode(), true);
}
//System.out.println("Key List: "+KEYS);
}
@Override
public void keyReleased(KeyEvent e) {
Key.setKeyHeld(e.getKeyCode(), false);
//System.out.println("Key List: "+KEYS);
}
public void Draw_Text(double x, double y, String s, Font f) {
Draw_Text_Ext(x,y,s,f,Color.BLACK);
}
public void Draw_Text_Ext(double x, double y, String s, Font f, Color col) {
java.lang.String finalS = s.toString();
int charCount=0;
int yOffset=0;
int xOffset=0;
Color currentCol = col;
for (int i=0;i<finalS.length();i++) {
if (finalS.charAt(i)=='\n') {
xOffset+=(charCount+1)*f.getGlyphWidth();
yOffset+=f.getGlyphHeight();
charCount=0;
} else {
Draw_Sprite_Partial_Ext(x+i*f.getGlyphWidth()-xOffset, y+yOffset, f.getCharInfo(finalS.charAt(i)).getX(), f.getCharInfo(finalS.charAt(i)).getY(), f.getCharInfo(finalS.charAt(i)).getWidth(), f.getCharInfo(finalS.charAt(i)).getHeight(), f.getSprite(), 0,currentCol,Transform.NONE);
charCount++;
}
}
}
public void Draw_Line(int x1,int y1,int x2,int y2,Color col) {
int x,y,dx,dy,dx1,dy1,px,py,xe,ye;
dx=x2-x1;dy=y2-y1;
dx1=Math.abs(dx);dy1=Math.abs(dy);
px=2*dy1-dx1;py=2*dx1-dy1;
if (dy1<=dx1) {
if (dx>=0) {
x=x1;y=y1;xe=x2-1;
} else {
x=x2-1;y=y2-1;xe=x1;
}
while (x<xe) {
x=x+1;
if (px<0) {
px=px+2*dy1;
} else {
if ((dx<0&&dy<0)||(dx>0&&dy>0)) {
y=y+1;
} else {
y=y-1;
}
px=px+2*(dy1-dx1);
}
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
}
} else {
if (dy>=0) {
x=x1;y=y1;ye=y2-1;
} else {
x=x2-1;y=y2-1;ye=y1;
}
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
while (y<ye) {
y=y+1;
if (py<=0) {
py=py+2*dx1;
} else {
if ((dx<0&&dy<0)||(dx>0&&dy>0)) {
x=x+1;
} else {
x=x-1;
}
py=py+2*(dx1-dy1);
}
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
}
}
}
public void Fill_Rect(double x,double y,double w,double h,Color col) {
for (int xx=0;xx<w;xx++) {
for (int yy=0;yy<h;yy++) {
if (x+xx>=0&&y+yy>=0&&x+xx<JavaProjectTemplate.WINDOW_WIDTH&&y+yy<JavaProjectTemplate.WINDOW_HEIGHT) {
int index = ((int)y+yy)*JavaProjectTemplate.WINDOW_WIDTH+(int)x+xx;
Draw(index,col.getColor());
}
}
}
}
public void Draw_Sprite(double x, double y, Sprite sprite){
Draw_Sprite_Partial(x,y,0,0,sprite.getWidth(),sprite.getHeight(),sprite,0,Transform.NONE );
}
public void Draw_Animated_Sprite(double x, double y, AnimatedSprite sprite, double frameIndex){
Rectangle frameRectangle=sprite.getFrame((int)frameIndex);
Draw_Sprite_Partial(x,y,frameRectangle.getX(),frameRectangle.getY(),frameRectangle.getWidth(),frameRectangle.getHeight(),sprite,frameIndex,Transform.NONE);
}
public void Draw_Sprite(double x, double y, Sprite sprite, Transform transform){
Draw_Sprite_Partial(x,y,0,0,sprite.getWidth(),sprite.getHeight(),sprite,0,transform);
}
public void Draw_Animated_Sprite(double x, double y, AnimatedSprite sprite, double frameIndex, Transform transform){
Rectangle frameRectangle=sprite.getFrame((int)frameIndex);
Draw_Sprite_Partial(x,y,frameRectangle.getX(),frameRectangle.getY(),frameRectangle.getWidth(),frameRectangle.getHeight(),sprite,frameIndex, transform);
}
public void Draw_Sprite_Partial(double x, double y, double xOffset, double yOffset, double w, double h, Sprite sprite, double frame_index, Transform transform){
Draw_Sprite_Partial_Ext(x,y,xOffset,yOffset,w,h,sprite,frame_index, Color.WHITE,transform);
}
public void Draw_Sprite_Partial_Ext(double x, double y, double xOffset, double yOffset, double w, double h, Sprite sprite, Transform transform){
Draw_Sprite_Partial_Ext(x, y, xOffset, yOffset, w, h, sprite, 0, Color.WHITE, transform);
}
public void Draw_Animated_Sprite_Partial_Ext(double x, double y, double xOffset, double yOffset, double w, double h, AnimatedSprite sprite, double frameIndex, Transform transform){
Rectangle frameRectangle=sprite.getFrame((int)frameIndex);
Draw_Sprite_Partial_Ext(x, y, frameRectangle.getX(), frameRectangle.getY(), frameRectangle.getWidth(), frameRectangle.getHeight(), sprite, 0, Color.WHITE, transform);
}
public void Draw_Sprite_Partial_Ext(double x, double y, double xOffset, double yOffset, double w, double h, Sprite sprite, double frame_index, Color col, Transform transform){
boolean horizontal = transform==Transform.HORIZONTAL||transform==Transform.HORIZ_VERTIC;
boolean vertical = transform==Transform.VERTICAL||transform==Transform.HORIZ_VERTIC;
for(int X=(int)xOffset;X<(int)(w+xOffset);X++){
for(int Y=(int)yOffset;Y<(int)(h+yOffset);Y++){
if (X+x-xOffset<0||Y+y-yOffset<0||X-xOffset+x>=JavaProjectTemplate.WINDOW_WIDTH||Y-yOffset+y>=JavaProjectTemplate.WINDOW_HEIGHT) {
continue;
} else {
int index =
((vertical?
sprite.getHeight()-(Y-(int)yOffset):
(Y-(int)yOffset))
+(int)y)*JavaProjectTemplate.WINDOW_WIDTH+
(horizontal?
sprite.getWidth()-(X-(int)xOffset):
(X-(int)xOffset))
+(int)x;
if (((sprite.getImg().getRGB(X,Y)>>>24)&0xFF)==0||index<0||index>=pixel.length) {
continue;
} else {
Draw(index,(col==Color.WHITE)?sprite.getImg().getRGB(X,Y):col.getColor());
}
}
}
}
}
public void Draw_Rect(double x,double y, double w, double h, Color col) {
Draw_Line((int)x, (int)y, (int)x+(int)w, (int)y, col);
Draw_Line((int)x+(int)w, (int)y, (int)x+(int)w, (int)y+(int)h, col);
Draw_Line((int)x+(int)w, (int)y+(int)h, (int)x, (int)y+(int)h, col);
Draw_Line((int)x, (int)y+(int)h, (int)x, (int)y, col);
}
public void Draw_Triangle(double x1, double y1, double x2, double y2, double x3, double y3, Color col) {
Draw_Line((int)x1, (int)y1, (int)x2, (int)y2, col);
Draw_Line((int)x2, (int)y2, (int)x3, (int)y3, col);
Draw_Line((int)x3, (int)y3, (int)x1, (int)y1, col);
}
private void drawline(int sx,int ex,int ny,Color col){
for (int i = sx; i <= ex; i++) Draw(i, ny, col);
}
public void Fill_Triangle(double x1, double y1, double x2, double y2, double x3, double y3, Color col){
int t1x, t2x, y, minx, maxx, t1xp, t2xp;
boolean changed1 = false;
boolean changed2 = false;
int signx1, signx2, dx1, dy1, dx2, dy2;
int e1, e2;
// Sort vertices
int temp;
if (y1 > y2) {temp=(int)y1;y1=y2;y2=temp;temp=(int)x1;x1=x2;x2=temp;}
if (y1 > y3) {temp=(int)y1;y1=y3;y3=temp;temp=(int)x1;x1=x3;x3=temp;}
if (y2 > y3) {temp=(int)y2;y2=y3;y3=temp;temp=(int)x2;x2=x3;x3=temp;}
t1x = t2x = (int)x1; y = (int)y1; // Starting points
dx1 = (int)(x2 - x1);
if (dx1 < 0) { dx1 = -dx1; signx1 = -1; }
else signx1 = 1;
dy1 = (int)(y2 - y1);
dx2 = (int)(x3 - x1);
if (dx2 < 0) { dx2 = -dx2; signx2 = -1; }
else signx2 = 1;
dy2 = (int)(y3 - y1);
if (dy1 > dx1) {temp=dx1;dx1=dy1;dy1=temp;changed1 = true; }
if (dy2 > dx2) {temp=dx2;dx2=dy2;dy2=temp;changed2 = true; }
e2 = (int)(dx2 >> 1);
// Flat top, just process the second half
boolean firstHalfDone=false;
if (y1 == y2) firstHalfDone=true;
if (!firstHalfDone) {
e1 = (int)(dx1 >> 1);
for (int i = 0; i < dx1;) {
t1xp = 0; t2xp = 0;
if (t1x < t2x) { minx = t1x; maxx = t2x; }
else { minx = t2x; maxx = t1x; }
// process first line until y value is about to change
next0:
while (i < dx1) {
i++;
e1 += dy1;
while (e1 >= dx1) {
e1 -= dx1;
if (changed1) t1xp = signx1;//t1x += signx1;
else {
break next0;
}
}
if (changed1) break;
else t1x += signx1;
}
// Move line
next1:
// process second line until y value is about to change
while (true) {
e2 += dy2;
while (e2 >= dx2) {
e2 -= dx2;
if (changed2) t2xp = signx2;//t2x += signx2;
else {
break next1;
}
}
if (changed2) break;
else t2x += signx2;
}
if (minx > t1x) minx = t1x;
if (minx > t2x) minx = t2x;
if (maxx < t1x) maxx = t1x;
if (maxx < t2x) maxx = t2x;
drawline(minx, maxx, y, col); // Draw line from min to max points found on the y
// Now increase y
if (!changed1) t1x += signx1;
t1x += t1xp;
if (!changed2) t2x += signx2;
t2x += t2xp;
y += 1;
if (y == y2) break;
}
}
// Second half
dx1 = (int)(x3 - x2); if (dx1 < 0) { dx1 = -dx1; signx1 = -1; }
else signx1 = 1;
dy1 = (int)(y3 - y2);
t1x = (int)x2;
if (dy1 > dx1) { // swap values
temp=dy1;dx1=dy1;dy1=temp;
changed1 = true;
}
else changed1 = false;
e1 = (int)(dx1 >> 1);
for (int i = 0; i <= dx1; i++) {
t1xp = 0; t2xp = 0;
if (t1x < t2x) { minx = t1x; maxx = t2x; }
else { minx = t2x; maxx = t1x; }
// process first line until y value is about to change
next3:
while (i < dx1) {
e1 += dy1;
while (e1 >= dx1) {
e1 -= dx1;
if (changed1) { t1xp = signx1; break; }//t1x += signx1;
else break next3;
}
if (changed1) break;
else t1x += signx1;
if (i < dx1) i++;
}
next4:
// process second line until y value is about to change
while (t2x != x3) {
e2 += dy2;
while (e2 >= dx2) {
e2 -= dx2;
if (changed2) t2xp = signx2;
else break next4;
}
if (changed2) break;
else t2x += signx2;
}
if (minx > t1x) minx = t1x;
if (minx > t2x) minx = t2x;
if (maxx < t1x) maxx = t1x;
if (maxx < t2x) maxx = t2x;
drawline(minx, maxx, y,col);
if (!changed1) t1x += signx1;
t1x += t1xp;
if (!changed2) t2x += signx2;
t2x += t2xp;
y += 1;
if (y > y3) return;
}
}
public void Clear(Color col){
for (int y=0;y<JavaProjectTemplate.WINDOW_HEIGHT;y++) {
for (int x=0;x<JavaProjectTemplate.WINDOW_WIDTH;x++) {
Draw(y*JavaProjectTemplate.WINDOW_WIDTH+x,col.getColor());
}
}
}
2022-11-28 10:29:34 -06:00
}