Back to Top

Home/Tutorials

Quik Painter


Guess what? This article will teach you how to create your own Paint-like application. The project is a bit more complex, but don't worry; I will walk you through the entire source code.


quik painter

function set_line(button_number);

function paint_canvas();

function pick_color();


The program begins with three function prototype definitions. These are usually placed at the top of the source code files, because the lines of code that call them would error out if the function body would be placed below the calling line.


BMAP* pointer_tga = "pointer.tga";


var format;

var pixel;

var coords_x;

var coords_y;

var alpha_value = 100;

var pen_size = 3;


VECTOR current_color;


BMAP* main_tga = "main.png";

BMAP* canvas_pcx = "canvas.pcx";

BMAP* pencils_pcx = "pencils.pcx";

BMAP* colors_tga = "colors.tga";

BMAP* brushsmall1_pcx = "brushsmall1.pcx";

BMAP* brushsmall2_pcx = "brushsmall2.pcx";

BMAP* brushmed1_pcx = "brushmed1.pcx";

BMAP* brushmed2_pcx = "brushmed2.pcx";

BMAP* brushbig1_pcx = "brushbig1.pcx";

BMAP* brushbig2_pcx = "brushbig2.pcx";

BMAP* canvas;

BMAP* my_colors;


The lines above define a bunch of variables, a vector and several bitmaps; we will encounter them all as we go through the code.


PANEL* main_pan =

{

bmap = main_tga;

layer = 10;

pos_x = 0;

pos_y = 0;

flags = SHOW;

}


PANEL* canvas_pan =

{

layer = 40;

pos_x = 148;

pos_y = 215;

button = 0, 0, canvas_pcx, canvas_pcx, canvas_pcx, paint_canvas, NULL, NULL;

flags = SHOW;

}


PANEL* color_picker =

{

layer = 30;

pos_x = 150;

pos_y = 70;

button = 0, 0, colors_tga, colors_tga, colors_tga, pick_color, NULL, NULL;

flags = SHOW;

}


PANEL* pencils_pan =

{

bmap = pencils_pcx;

layer = 20;

pos_x = 628;

pos_y = 70;

button = 1, 1, brushsmall2_pcx, brushsmall1_pcx, brushsmall2_pcx, set_line, NULL, NULL;

button = 1, 27 ,brushmed2_pcx, brushmed1_pcx, brushmed2_pcx, set_line, NULL, NULL;

button = 1, 53, brushbig2_pcx, brushbig1_pcx, brushbig2_pcx, set_line, NULL, NULL;

flags = SHOW;

}


Quik Painter uses four panels. Main_pan is the main graphic that shows up on the screen when you run the application, canvas_pan sets the digital canvas that we can paint on, and the other two panels are used to pick the desired paint color and brush size.


function main()

{

video_set(800, 600, 0, 1);

video_screen = 1;

}


Function main() sets the video resolution to 800x600 pixels, and then starts the application in full screen mode.


function mouse_startup()

{

mouse_map = pointer_tga;

while(1)

{

  mouse_mode = 1;

  vec_set(mouse_pos, mouse_cursor);

  wait(1);

}

}


Function mouse_startup() gives us a mouse pointer that can be moved around. You've seen it at work in other projects.


function set_line(button_number)

{

pen_size = button_number;

}


Function set_line() sets the size of the brush depending on the button that was clicked. If you press the first button, pen_size will be set to 1, and so on.


function pick_color()

{

my_colors = colors_tga;

while (mouse_left)

{

  coords_x = mouse_pos.x - color_picker.pos_x;

  coords_y = mouse_pos.y - color_picker.pos_y;  

  format = bmap_lock(my_colors, 0); // lock the bitmap

  pixel = pixel_for_bmap(my_colors,coords_x, coords_y);

  pixel_to_vec(current_color, alpha_value, format, pixel);

  bmap_unlock(my_colors);

  wait(1);

}  

}


Function pick_color() allows the player to pick the desired color by reading the pixel color and alpha values of the tiny colored bitmap squares in the color palette.


function paint_canvas()

{

canvas = canvas_pcx;

while(mouse_left)

{  

  coords_x = mouse_pos.x - canvas_pan.pos_x;

  coords_y = mouse_pos.y - canvas_pan.pos_y;

  format = bmap_lock(canvas, 0);

  pixel = pixel_for_vec(current_color, 100, format);

  pixel_to_bmap(canvas, coords_x, coords_y, pixel);

  if(pen_size == 1)

  {

   pixel_to_bmap(canvas,coords_x, coords_y,pixel);

  }  

  if(pen_size == 2) // medium brush?

  {

   pixel_to_bmap(canvas,coords_x, coords_y,pixel);

   pixel_to_bmap(canvas,coords_x, coords_y + 1,pixel);

   pixel_to_bmap(canvas,coords_x + 1, coords_y,pixel);

   pixel_to_bmap(canvas,coords_x + 1, coords_y + 1,pixel);

  }

  if(pen_size == 3)

  {  

   pixel_to_bmap(canvas,coords_x, coords_y,pixel);

   pixel_to_bmap(canvas,coords_x + 1, coords_y,pixel);

   pixel_to_bmap(canvas,coords_x + 2, coords_y,pixel);

   pixel_to_bmap(canvas,coords_x, coords_y + 1,pixel);

   pixel_to_bmap(canvas,coords_x, coords_y + 2,pixel);

   pixel_to_bmap(canvas,coords_x + 1, coords_y + 1,pixel);

   pixel_to_bmap(canvas,coords_x + 1, coords_y + 2,pixel);

   pixel_to_bmap(canvas,coords_x + 2, coords_y + 1,pixel);

   pixel_to_bmap(canvas,coords_x + 2, coords_y + 2,pixel);

  }

  bmap_unlock(canvas);

  wait(1);

}    

}


Function paint_canvas() does the actual drawing. It sets the pointer to our canvas, and then it runs a loop for as long as the left mouse button is being held down. The code extracts the x and y coordinates of the current pixel, locks the canvas bitmap, and then converts the color to a pixel.


It's time to "paint" the pixel at the (coords_x, coords_y) position, using a small (1 pixel), medium (4 pixels) or big (9 pixels) brush. Then, we unlock the bitmap, wait a frame, and then check if the left mouse button continues to be pressed.


That's how Quik Paint works! Don't forget to contact me if you have any code-related questions.