Flood fill?

Right, let’s start again.

Before you #include <Pokitto.h>,
make sure to #define DISABLEAVRMIN.

Then #include <stack>.

Then this:

class Point
{
public:
	unsigned x;
	unsigned y;

public:
	// C++03
	Point(void) : x(0), y(0) {}
	// C++11
	//Point(void) = default;
	
	Point(unsigned x, unsigned y) : x(x), y(y) {}
};

void floodFill(unsigned x, unsigned y, uint8_t fillColour)
{
	std::stack<Point> stack = std::stack<Point>();

	// If you're using C++11, replace all uses of stack.push(Point(x, y) with stack.emplace(x, y);
	stack.push(Point(x, y));
	
	while(!stack.empty())
	{
		Point point = stack.top();


		if((x % 10) == 0)
		{
			// so I can watch the fill...
			Pokitto::Display::update();
		}
	
		if((point.x >= Pokitto::Display::width) || (point.y >= Pokitto::Display::height))
			return;
			
		unsigned colour = Pokitto::Display::getPixel(point.x, point.y);
		if(colour != fillColour)
		{
			Pokitto::Display::drawPixel(point.x, point.y, fillColour);
			
			if(point.x < Pokitto::Display::width)
				stack.push(Point(point.x + 1, point.y));
				
			if(point.x > 0)
				stack.push(Point(point.x - 1, point.y));
				
			if(point.y < Pokitto::Display::height)
				stack.push(Point(point.x, point.y + 1));
				
			if(point.y > 0)
				stack.push(Point(point.x, point.y - 1));
		}

		// Almost forgot this bit
		stack.pop();
	}	
}

And now there should probably be no compiler errors I hope.

This should probably be in the loop. :stuck_out_tongue:

1 Like

It is now.
(Clearly I’m trying to do too much at once again.)

1 Like

@FManga is debugging you @Pharap

@spinal, did you get this working in the end?

Nope, unfortunately I have been completely distracted by useless things again. :frowning:

1 Like

I just tried the floodfill with the following code, it nearly works…

#define DISABLEAVRMIN
#include "Pokitto.h"
#include <stack>
#include "Smile.h"

using PC = Pokitto::Core;
using PD = Pokitto::Display;


const uint16_t palette[] = {
0xFFFF,0x0000,0x73B9,0xBDD7,
};

const uint8_t script[] = {
0xFF,0x01,0x23,0x0B,0x3A,0x0B,0x3A,0x21,0x71,0x21,0x71,0x0B,0x7D,0x0B,0x88,0x16,0x88,0x5E,0x7F,0x5E,0x7F,0x38,0x40,0x38,
0x3E,0x36,0x35,0x36,0x34,0x38,0x2D,0x38,0x2D,0x41,0x23,0x48,0x23,0x0B,0xFE,0x02,0x25,0x45,0xFF,0x01,0x21,0x48,0x21,0x0A,
0x7E,0x0A,0x8A,0x16,0x8A,0x5F,0x56,0x5F,0x56,0x64,0x52,0x6C,0x4E,0x71,0x4A,0x74,0x44,0x7D,0x3C,0x81,0x3C,0x8C,0x0A,0x8C,
0x0A,0x6D,0x09,0x6D,0x09,0x51,0x0D,0x4B,0x14,0x45,0x15,0x41,0x19,0x3A,0x1E,0x37,0x21,0x36,0x21,0x36,0x1E,0x38,0x1A,0x3A,
0x16,0x41,0x15,0x45,0x0E,0x4B,0x0A,0x51,0x0A,0x6C,0x0B,0x6D,0x0B,0x8B,0x28,0x8B,0x28,0x76,0x30,0x76,0x34,0x72,0x34,0x5F,
0x32,0x5C,0x32,0x52,0x41,0x45,0x41,0x39,0x3E,0x37,0x3B,0x37,0x3E,0x3A,0x3E,0x41,0x3D,0x42,0x36,0x42,0x33,0x3F,0x2A,0x46,
0x1E,0x4C,0x12,0x55,0x12,0x54,0x1E,0x4B,0x1A,0x4A,0x17,0x47,0x1A,0x49,0x1E,0x4A,0x21,0x48,0xFF,0x01,0x32,0x3D,0x34,0x36,
0x3C,0x37,0x3D,0x3A,0x3D,0x41,0x36,0x41,0x32,0x3D,0xFF,0x01,0x33,0x5C,0x33,0x52,0x42,0x45,0x42,0x39,0x7D,0x39,0x7D,0x5E,
0x34,0x5E,0x33,0x5A,0xFF,0x01,0x3C,0x0B,0x6F,0x0B,0x6F,0x20,0x3C,0x20,0x3C,0x0B,0xFF,0x01,0x60,0x0E,0x6B,0x0E,0x6B,0x1C,
0x60,0x1C,0x60,0x0E,0xFE,0x03,0x3E,0x1F,0xFF,0x01,0x62,0x0F,0x69,0x0F,0x69,0x1B,0x62,0x1B,0x62,0x0F,0xFE,0x02,0x63,0x1A,
0xFF,0x01,0x2F,0x39,0x32,0x39,0x32,0x3B,0x2F,0x3F,0x2F,0x39,0xFF,0x01,0x29,0x8B,0x29,0x77,0x30,0x77,0x35,0x72,0x35,0x69,
0x39,0x6B,0x41,0x6B,0x41,0x6D,0x45,0x72,0x49,0x72,0x49,0x74,0x43,0x7D,0x3B,0x80,0x3B,0x8B,0x29,0x8B,0xFF,0x01,0x35,0x5F,
0x35,0x64,0x3A,0x61,0x35,0x5F,0xFF,0x01,0x39,0x62,0x35,0x64,0x35,0x5F,0x4A,0x5F,0x40,0x69,0x3F,0x69,0x41,0x67,0x3C,0x62,
0x39,0x62,0xFF,0x01,0x4E,0x5F,0x55,0x5F,0x55,0x64,0x51,0x6C,0x4E,0x70,0x49,0x71,0x46,0x71,0x43,0x6D,0x43,0x6A,0x4E,0x5F,
0xFF,0x01,0x44,0x6A,0x44,0x6D,0x46,0x70,0x48,0x70,0x4C,0x6F,0x4D,0x6C,0x49,0x69,0x44,0x6A,0xFF,0x01,0x36,0x68,0x3E,0x6A,
0x40,0x67,0x3C,0x63,0x39,0x63,0x36,0x65,0x36,0x68,0xFF,0x01,0x7E,0x0B,0x89,0x16,0x89,0x5E,0xFE,0x01,0x22,0x0B,0xFE,0x01,
0x3B,0x0B,0xFE,0x01,0x61,0x0F,0xFE,0x01,0x6A,0x1B,0xFE,0x01,0x70,0x0F,0xFE,0x01,0x7E,0x5E,0xFE,0x01,0x4B,0x60,0xFE,0x01,
0x2E,0x39,0xFF,0xFF,
};


class Point
{
public:
	unsigned x;
	unsigned y;

public:
	// C++03
	Point(void) : x(0), y(0) {}
	// C++11
	//Point(void) = default;
	
	Point(unsigned x, unsigned y) : x(x), y(y) {}
};

void floodFill(unsigned x, unsigned y, uint8_t fillColour)
{
	std::stack<Point> stack = std::stack<Point>();

	// If you're using C++11, replace all uses of stack.push(Point(x, y) with stack.emplace(x, y);
	stack.push(Point(x, y));
	
	while(!stack.empty())
	{
		Point point = stack.top();

		if((x % 10) == 0)
		{
			// so I can watch the fill...
			Pokitto::Display::update();
		}
	
		if((point.x >= Pokitto::Display::width) || (point.y >= Pokitto::Display::height))
			return;
			
		unsigned colour = Pokitto::Display::getPixel(point.x, point.y);
		if(colour != fillColour)
		{
			Pokitto::Display::drawPixel(point.x, point.y, fillColour);
			
			if(point.x < Pokitto::Display::width)
				stack.push(Point(point.x + 1, point.y));
				
			if(point.x > 0)
				stack.push(Point(point.x - 1, point.y));
				
			if(point.y < Pokitto::Display::height)
				stack.push(Point(point.x, point.y + 1));
				
			if(point.y > 0)
				stack.push(Point(point.x, point.y - 1));
		}

		// Almost forgot this bit
		stack.pop();
	}	
}

int main() {
    PC::begin();
    PD::persistence = true;
    PD::invisiblecolor = 0;
    PD::load565Palette(palette);

    int ending=0;
    int t=0;
    int colour = 0;
    int lastX, lastY=0;
    int offX, offY=0;
    int b1,b2,task=0;
    while(ending==0){
        PC::update();

        b1 = script[t++];
        b2 = script[t++];
        if(b1==0xFF && b2==0xFF){
            ending = 1;
        }else if(b1==0xFF){
            // new line
            colour = b2;
            PD::setColor(b2);
            task = 2;
        }else if(b1==0xFE){
            //flood fill
            colour = b2;
            PD::setColor(b2);
            task = 1;
        }else if(task==0){
            // continue line
            PD::drawLine(offX+lastX, offY+lastY, b1, b2);
            lastX = b1;
            lastY = b2;
        }else if(task==1){
            //floodfill
            floodFill(offX+b1, offY+b2, colour);
            task = 0;
        }else if(task==2){
            //start line
            lastX=b1;
            lastY=b2;
            task=0;
        }
        
        // watch it draw!
        wait_us(10000);
    }

    while( PC::isRunning() ){
        if( !PC::update() ) continue;
    }    


    return 1; 
}

Before going into the loop, you need to store a reference color (referenceColor = getPixel(x, y)) then, in the loop, do if(colour == referenceColour) instead of if(color != fillColour).

That’s weird, with that change, it only seems to fill downwards…
image

Even though I can clearly see in the code that it should be going up also

			if(point.y > 0)
				stack.push(Point(point.x, point.y - 1));

Does it work if you try to fill a very small area?

One of those areas is only 12x22.
There seems to be an issue in the following if() where it wont reach the 4th statement.

		if(colour == referenceColor)
		{
			Pokitto::Display::drawPixel(point.x, point.y, fillColour);
			
			if(point.x < Pokitto::Display::width)
				stack.push(Point(point.x + 1, point.y));
				
			if(point.x > 0)
				stack.push(Point(point.x - 1, point.y));
				
			if(point.y < Pokitto::Display::height)
				stack.push(Point(point.x, point.y + 1));
				
			if(point.y > 0)
				stack.push(Point(point.x, point.y - 1));
		}

If I swap them around, for example

		if(colour == referenceColor)
		{
			Pokitto::Display::drawPixel(point.x, point.y, fillColour);
			
			if(point.x < Pokitto::Display::width)
				stack.push(Point(point.x + 1, point.y));
				
			if(point.x > 0)
				stack.push(Point(point.x - 1, point.y));

			if(point.y > 0)
				stack.push(Point(point.x, point.y - 1));
				
			if(point.y < Pokitto::Display::height)
				stack.push(Point(point.x, point.y + 1));
				
		}

It will fill ‘up’ and not ‘down’…
image

It’s a little confusing.

From the look of the screenshot, it works in the gray area or in the window… right? In which case it looks like it works in small areas and runs out of RAM in large ares. Try using unsigned char instead of unsigned in Point.

The gray starts filling right at the edge. It’s as after watching it fill slowly, it seems to work fully for every pixel other than the first one.

Oh, you are drawing the Amiga disk image using vectors :slight_smile:

1 Like

So the only issue is that you need to force it to paint the first one… which makes sense since that one has the reference color.

1 Like

Turns out it was vector anyway. I just thought it was badly drawn bitmap, but no, badly drawn vector.

It’s just ocurred to me that the bounds checks should be:

if(point.x < (Pokitto::Display::width - 1))
	stack.push(Point(point.x + 1, point.y));
	
if(point.x > 0)
	stack.push(Point(point.x - 1, point.y));
	
if(point.y < (Pokitto::Display::height - 1))
	stack.push(Point(point.x, point.y + 1));
	
if(point.y > 0)
	stack.push(Point(point.x, point.y - 1));

Otherwise it’ll try to draw outside the screen.

That could be related to the problem.

If the issue is down to running out of RAM then you’ll have to look for a fixed memory algorithm,
though fixed-memory flood fill algorithms tend to be a fair bit slower.

Tried a different one,

int point(int x, int y){
    return Pokitto::Display::getPixel(x, y);
}

void line(int x1,int y1,int x2,int y2, int colour){
    Pokitto::Display::setColor(colour);
    Pokitto::Display::drawLine(x1, y1, x2, y2);
}

void flood_fill(int x, int y, int target, int fill_color){

    // check current pixel
    if(point(x,y) != target) return;
 
    int l = x, r = x;
    // find furthest left pixel to fill from
    while(point(l -1, y) == target && l -1 > -1){
        l--;
    }
    // find furthes right pixel to fill to
    while(point(r +1, y) == target && r +1 < Pokitto::Display::width - 1){
        r++;
    }
 
    // draw a line between the two
    line (l,y,r,y, fill_color);
    PC::update();
    wait_us(2000);

    // move along that line and see if we can fill above or below
    for(x = l; x<r; x++){
        if(y +1 < Pokitto::Display::height - 1) flood_fill(x, y +1, target, fill_color);
        if(y -1 > -1) flood_fill(x, y -1, target, fill_color);
    }
}

This one similarly fails ‘sometimes’. This time it fails if the starting point of the fill is only 1px wide. I just don’t see why though.

Full Code…
Flashes a red pixel at the start point, press A to continue filling.

#include "Pokitto.h"

using PC = Pokitto::Core;
using PD = Pokitto::Display;

const uint16_t palette[] = {
0xFFFF,0x0000,0x73B9,0xBDD7,0xF00F
};

const uint8_t script[] = {
0xFF,0x01,0x23,0x0B,0x3A,0x0B,0x3A,0x21,0x71,0x21,0x71,0x0B,0x7D,0x0B,0x88,0x16,0x88,0x5E,0x7F,0x5E,0x7F,0x38,0x40,0x38,
0x3E,0x36,0x35,0x36,0x34,0x38,0x2D,0x38,0x2D,0x41,0x23,0x48,0x23,0x0B,0xFE,0x02,0x25,0x45,0xFF,0x01,0x21,0x48,0x21,0x0A,
0x7E,0x0A,0x8A,0x16,0x8A,0x5F,0x56,0x5F,0x56,0x64,0x52,0x6C,0x4E,0x71,0x4A,0x74,0x44,0x7D,0x3C,0x81,0x3C,0x8C,0x0A,0x8C,
0x0A,0x6D,0x09,0x6D,0x09,0x51,0x0D,0x4B,0x14,0x45,0x15,0x41,0x19,0x3A,0x1E,0x37,0x21,0x36,0x21,0x36,0x1E,0x38,0x1A,0x3A,
0x16,0x41,0x15,0x45,0x0E,0x4B,0x0A,0x51,0x0A,0x6C,0x0B,0x6D,0x0B,0x8B,0x28,0x8B,0x28,0x76,0x30,0x76,0x34,0x72,0x34,0x5F,
0x32,0x5C,0x32,0x52,0x41,0x45,0x41,0x39,0x3E,0x37,0x3B,0x37,0x3E,0x3A,0x3E,0x41,0x3D,0x42,0x36,0x42,0x33,0x3F,0x2A,0x46,
0x1E,0x4C,0x12,0x55,0x12,0x54,0x1E,0x4B,0x1A,0x4A,0x17,0x47,0x1A,0x49,0x1E,0x4A,0x21,0x48,0xFF,0x01,0x32,0x3D,0x34,0x36,
0x3C,0x37,0x3D,0x3A,0x3D,0x41,0x36,0x41,0x32,0x3D,0xFF,0x01,0x33,0x5C,0x33,0x52,0x42,0x45,0x42,0x39,0x7D,0x39,0x7D,0x5E,
0x34,0x5E,0x33,0x5A,0xFF,0x01,0x3C,0x0B,0x6F,0x0B,0x6F,0x20,0x3C,0x20,0x3C,0x0B,0xFF,0x01,0x60,0x0E,0x6B,0x0E,0x6B,0x1C,
0x60,0x1C,0x60,0x0E,0xFE,0x03,0x3E,0x1F,0xFF,0x01,0x62,0x0F,0x69,0x0F,0x69,0x1B,0x62,0x1B,0x62,0x0F,0xFE,0x02,0x63,0x1A,
0xFF,0x01,0x2F,0x39,0x32,0x39,0x32,0x3B,0x2F,0x3F,0x2F,0x39,0xFF,0x01,0x29,0x8B,0x29,0x77,0x30,0x77,0x35,0x72,0x35,0x69,
0x39,0x6B,0x41,0x6B,0x41,0x6D,0x45,0x72,0x49,0x72,0x49,0x74,0x43,0x7D,0x3B,0x80,0x3B,0x8B,0x29,0x8B,0xFF,0x01,0x35,0x5F,
0x35,0x64,0x3A,0x61,0x35,0x5F,0xFF,0x01,0x39,0x62,0x35,0x64,0x35,0x5F,0x4A,0x5F,0x40,0x69,0x3F,0x69,0x41,0x67,0x3C,0x62,
0x39,0x62,0xFF,0x01,0x4E,0x5F,0x55,0x5F,0x55,0x64,0x51,0x6C,0x4E,0x70,0x49,0x71,0x46,0x71,0x43,0x6D,0x43,0x6A,0x4E,0x5F,
0xFF,0x01,0x44,0x6A,0x44,0x6D,0x46,0x70,0x48,0x70,0x4C,0x6F,0x4D,0x6C,0x49,0x69,0x44,0x6A,0xFF,0x01,0x36,0x68,0x3E,0x6A,
0x40,0x67,0x3C,0x63,0x39,0x63,0x36,0x65,0x36,0x68,0xFF,0x01,0x7E,0x0B,0x89,0x16,0x89,0x5E,0xFE,0x01,0x22,0x0B,0xFE,0x01,
0x3B,0x0B,0xFE,0x01,0x61,0x0F,0xFE,0x01,0x6A,0x1B,0xFE,0x01,0x70,0x0F,0xFE,0x01,0x7E,0x5E,0xFE,0x01,0x4B,0x60,0xFE,0x01,
0x2E,0x39,0xFF,0xFF,
};

int point(int x, int y){
    return Pokitto::Display::getPixel(x, y);
}

void line(int x1,int y1,int x2,int y2, int colour){
    Pokitto::Display::setColor(colour);
    Pokitto::Display::drawLine(x1, y1, x2, y2);
}

void flood_fill(int x, int y, int target, int fill_color){

    // check current pixel
    if(point(x,y) != target) return;
 
    int l = x, r = x;
    // find furthest left pixel to fill from
    while(point(l -1, y) == target && l -1 > -1){
        l--;
    }
    // find furthes right pixel to fill to
    while(point(r +1, y) == target && r +1 < Pokitto::Display::width - 1){
        r++;
    }
 
    // draw a line between the two
    line (l,y,r,y, fill_color);
    PC::update();
    wait_us(2000);

    // move along that line and see if we can fill above or below
    for(x = l; x<r; x++){
        if(y +1 < Pokitto::Display::height - 1) flood_fill(x, y +1, target, fill_color);
        if(y -1 > -1) flood_fill(x, y -1, target, fill_color);
    }
}


int main() {
    PC::begin();
    PD::persistence = true;
    PD::invisiblecolor = 0;
    PD::load565Palette(palette);

    int ending=0;
    int t=0;
    int colour = 0;
    int lastX, lastY=0;
    int offX, offY=0;
    int b1,b2,task=0;
    while(ending==0){
        PC::update();

        b1 = script[t++];
        b2 = script[t++];
        if(b1==0xFF && b2==0xFF){
            ending = 1;
        }else if(b1==0xFF){
            // new line
            colour = b2;
            PD::setColor(b2);
            task = 2;
        }else if(b1==0xFE){
            //flood fill
            colour = b2;
            PD::setColor(b2);
            task = 1;
        }else if(task==0){
            // continue line
            PD::drawLine(offX+lastX, offY+lastY, b1, b2);
            lastX = b1;
            lastY = b2;
        }else if(task==1){
            //floodfill
            int col = point(offX+b1, offY+b2);
            PD::setColor(4);
            Pokitto::Display::drawPixel(offX+b1, offY+b2);
            int OK = 0;
            while(OK==0){
                if(Pokitto::Buttons::aBtn()) OK = 1;
                PD::setColor(4);
                Pokitto::Display::drawPixel(offX+b1, offY+b2);
                PC::update();
                PD::setColor(col);
                Pokitto::Display::drawPixel(offX+b1, offY+b2);
                PC::update();
            }
            while(Pokitto::Buttons::aBtn()){
                PC::update();
            }
            PD::setColor(col);
            Pokitto::Display::drawPixel(offX+b1, offY+b2);
            flood_fill(offX+b1, offY+b2, 0, colour);
            task = 0;
        }else if(task==2){
            //start line
            lastX=b1;
            lastY=b2;
            task=0;
        }
        
        // watch it draw!
        wait_us(20000);
    }

    while( PC::isRunning() ){
        if( !PC::update() ) continue;
    }    


    return 1; 
}

sounds like it needs this:
for(x = l; x<=r; x++)

Problem solved…

The pokitto line function does not draw the last pixel (odd decision). Replacing it fixed the issue.

AmigaHand.bin.1

#include "Pokitto.h"

using PC = Pokitto::Core;
using PD = Pokitto::Display;

const uint16_t palette[] = {
0xFFFF,0x0000,0x73B9,0xBDD7,0xF00F
};

const uint8_t script[] = {
0xFF,0x01,0x23,0x0B,0x3A,0x0B,0x3A,0x21,0x71,0x21,0x71,0x0B,0x7D,0x0B,0x88,0x16,0x88,0x5E,0x7F,0x5E,0x7F,0x38,0x40,0x38,
0x3E,0x36,0x35,0x36,0x34,0x38,0x2D,0x38,0x2D,0x41,0x23,0x48,0x23,0x0B,0xFE,0x02,0x25,0x45,0xFF,0x01,0x21,0x48,0x21,0x0A,
0x7E,0x0A,0x8A,0x16,0x8A,0x5F,0x56,0x5F,0x56,0x64,0x52,0x6C,0x4E,0x71,0x4A,0x74,0x44,0x7D,0x3C,0x81,0x3C,0x8C,0x0A,0x8C,
0x0A,0x6D,0x09,0x6D,0x09,0x51,0x0D,0x4B,0x14,0x45,0x15,0x41,0x19,0x3A,0x1E,0x37,0x21,0x36,0x21,0x36,0x1E,0x38,0x1A,0x3A,
0x16,0x41,0x15,0x45,0x0E,0x4B,0x0A,0x51,0x0A,0x6C,0x0B,0x6D,0x0B,0x8B,0x28,0x8B,0x28,0x76,0x30,0x76,0x34,0x72,0x34,0x5F,
0x32,0x5C,0x32,0x52,0x41,0x45,0x41,0x39,0x3E,0x37,0x3B,0x37,0x3E,0x3A,0x3E,0x41,0x3D,0x42,0x36,0x42,0x33,0x3F,0x2A,0x46,
0x1E,0x4C,0x12,0x55,0x12,0x54,0x1E,0x4B,0x1A,0x4A,0x17,0x47,0x1A,0x49,0x1E,0x4A,0x21,0x48,0xFF,0x01,0x32,0x3D,0x34,0x36,
0x3C,0x37,0x3D,0x3A,0x3D,0x41,0x36,0x41,0x32,0x3D,0xFF,0x01,0x33,0x5C,0x33,0x52,0x42,0x45,0x42,0x39,0x7D,0x39,0x7D,0x5E,
0x34,0x5E,0x33,0x5A,0xFF,0x01,0x3C,0x0B,0x6F,0x0B,0x6F,0x20,0x3C,0x20,0x3C,0x0B,0xFF,0x01,0x60,0x0E,0x6B,0x0E,0x6B,0x1C,
0x60,0x1C,0x60,0x0E,0xFE,0x03,0x3E,0x1F,0xFF,0x01,0x62,0x0F,0x69,0x0F,0x69,0x1B,0x62,0x1B,0x62,0x0F,0xFE,0x02,0x63,0x1A,
0xFF,0x01,0x2F,0x39,0x32,0x39,0x32,0x3B,0x2F,0x3F,0x2F,0x39,0xFF,0x01,0x29,0x8B,0x29,0x77,0x30,0x77,0x35,0x72,0x35,0x69,
0x39,0x6B,0x41,0x6B,0x41,0x6D,0x45,0x72,0x49,0x72,0x49,0x74,0x43,0x7D,0x3B,0x80,0x3B,0x8B,0x29,0x8B,0xFF,0x01,0x35,0x5F,
0x35,0x64,0x3A,0x61,0x35,0x5F,0xFF,0x01,0x39,0x62,0x35,0x64,0x35,0x5F,0x4A,0x5F,0x40,0x69,0x3F,0x69,0x41,0x67,0x3C,0x62,
0x39,0x62,0xFF,0x01,0x4E,0x5F,0x55,0x5F,0x55,0x64,0x51,0x6C,0x4E,0x70,0x49,0x71,0x46,0x71,0x43,0x6D,0x43,0x6A,0x4E,0x5F,
0xFF,0x01,0x44,0x6A,0x44,0x6D,0x46,0x70,0x48,0x70,0x4C,0x6F,0x4D,0x6C,0x49,0x69,0x44,0x6A,0xFF,0x01,0x36,0x68,0x3E,0x6A,
0x40,0x67,0x3C,0x63,0x39,0x63,0x36,0x65,0x36,0x68,0xFF,0x01,0x7E,0x0B,0x89,0x16,0x89,0x5E,0xFE,0x01,0x22,0x0B,0xFE,0x01,
0x3B,0x0B,0xFE,0x01,0x61,0x0F,0xFE,0x01,0x6A,0x1B,0xFE,0x01,0x70,0x0F,0xFE,0x01,0x7E,0x5E,0xFE,0x01,0x4B,0x60,0xFE,0x01,
0x2E,0x39,0xFF,0xFF,
};

int point(int x, int y){
    return Pokitto::Display::getPixel(x, y);
}

void line(int x1,int y1,int x2,int y2, int colour){
    Pokitto::Display::setColor(colour);
    //Pokitto::Display::drawLine(x1, y1, x2, y2);
    for(int x = x1; x<=x2; x++){
        Pokitto::Display::drawPixel(x, y1);
    }

}

void flood_fill(int x, int y, int fill_color){

    // grab current pixel
    int target = point(x,y);

    int l = x, r = x;
    // find furthest left pixel to fill from
    while(point(l -1, y) == target && l -1 > -1){
        l--;
    }
    // find furthes right pixel to fill to
    while(point(r +1, y) == target && r +1 < Pokitto::Display::width - 1){
        r++;
    }

 
    // draw a line between the two
    line (l,y,r,y, fill_color);
    PC::update();
    wait_us(1000);
    
    if(r==l){
        // here is the problem
        if(y +1 < Pokitto::Display::height - 1 && point(x,y+1)==target) flood_fill(x, y +1, fill_color);
        if(y -1 > -1 && point(x,y-1)==target) flood_fill(x, y -1, fill_color);
    }else{
        // move along that line and see if we can fill above or below
        for(x = l; x<=r; x++){
            if(y +1 < Pokitto::Display::height - 1 && point(x,y+1)==target) flood_fill(x, y +1, fill_color);
            if(y -1 > -1 && point(x,y-1)==target) flood_fill(x, y -1, fill_color);
        }
    }
}


int main() {
    PC::begin();
    PD::persistence = true;
    PD::invisiblecolor = 0;
    PD::load565Palette(palette);

    int ending=0;
    int t=0;
    int colour = 0;
    int lastX, lastY=0;
    int offX, offY=0;
    int b1,b2,task=0;
    while(ending==0){
        PC::update();

        b1 = script[t++];
        b2 = script[t++];
        if(b1==0xFF && b2==0xFF){
            ending = 1;
        }else if(b1==0xFF){
            // new line
            colour = b2;
            PD::setColor(b2);
            task = 2;
        }else if(b1==0xFE){
            //flood fill
            colour = b2;
            PD::setColor(b2);
            task = 1;
        }else if(task==0){
            // continue line
            PD::drawLine(offX+lastX, offY+lastY, b1, b2);
            lastX = b1;
            lastY = b2;
        }else if(task==1){
            //floodfill
            flood_fill(offX+b1, offY+b2, colour);
            task = 0;
        }else if(task==2){
            //start line
            lastX=b1;
            lastY=b2;
            task=0;
        }
        
        // watch it draw!
        wait_us(20000);
    }

    while( PC::isRunning() ){
        if( !PC::update() ) continue;
    }    


    return 1; 
}
5 Likes