aboutsummaryrefslogtreecommitdiff
path: root/paint/paint.c
diff options
context:
space:
mode:
Diffstat (limited to 'paint/paint.c')
-rw-r--r--paint/paint.c137
1 files changed, 137 insertions, 0 deletions
diff --git a/paint/paint.c b/paint/paint.c
new file mode 100644
index 0000000..d7f5ba9
--- /dev/null
+++ b/paint/paint.c
@@ -0,0 +1,137 @@
+/*
+This is an example paint program for beginning C programmers.
+It simply creates a blank surface on which you can paint with the mouse.
+Each mouse press gets a new random color.
+
+To verify that you have the required SDL library files installed use the
+pkg-config utility at your shell prompt:
+$ pkg-config --version sdl
+
+On Debian and Ubuntu you can install the SDL library files using apt-get:
+$ sudo apt-get install libsdl1.2-dev
+
+To build this program using the accompanying Makefile run the make utility at
+your shell prompt:
+$ make
+
+Run the resulting program at your shell prompt:
+$ ./paint
+*/
+
+#include <stdlib.h>
+#include <SDL.h>
+
+// paint: Utility function that paints colors to a surface.
+void paint(SDL_Surface *surface, int x, int y,
+ Uint8 red, Uint8 green, Uint8 blue);
+
+void main() {
+ int return_code;
+
+ // Initialize the SDL library
+ return_code = SDL_Init(SDL_INIT_VIDEO);
+ if(return_code < 0) {
+ fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError());
+ exit(1);
+ }
+ atexit(SDL_Quit);
+
+ // Set the video mode we want
+ SDL_Surface *surface;
+ int width = 0; // 0 means any width
+ int height = 0; // 0 means any height
+ int bits_per_pixel = 0; // 0 means use the current bpp
+ Uint32 flags = SDL_RESIZABLE; // make a resizable window
+ surface = SDL_SetVideoMode(width, height, bits_per_pixel, flags);
+ if(NULL == surface) {
+ fprintf(stderr, "Unable to set video mode: %s\n", SDL_GetError());
+ exit(2);
+ }
+
+ // Main loop
+ int painting = 0; // variable to keep track of mouse-down state
+ Uint8 red, green, blue; // variables to keep track of our current color
+ while(1) {
+ SDL_Event event;
+
+ // Wait for the user to do something
+ SDL_WaitEvent(&event);
+
+ // Act on the various event types
+ if(SDL_QUIT == event.type) { // the user wants to quit
+ exit(0);
+ } else if(SDL_VIDEORESIZE == event.type) { // our window was resized
+ // Update our surface with the new size
+ width = event.resize.w;
+ height = event.resize.h;
+ surface = SDL_SetVideoMode(width, height, bits_per_pixel, flags);
+ if(NULL == surface) {
+ fprintf(stderr, "Unable to resize video mode: %s\n", SDL_GetError());
+ exit(2);
+ }
+ } else if(SDL_MOUSEBUTTONDOWN == event.type) { // a button is being pressed
+ // Start painting with a random color
+ painting = 1;
+ red = (rand() % 7 + 1) * 32;
+ green = (rand() % 7 + 1) * 32;
+ blue = (rand() % 7 + 1) * 32;
+ paint(surface, event.button.x, event.button.y, red, green, blue);
+ } else if(SDL_MOUSEMOTION == event.type) { // the mouse moved
+ if(painting) {
+ // Continue painting
+ paint(surface, event.motion.x, event.motion.y, red, green, blue);
+ }
+ } else if(SDL_MOUSEBUTTONUP == event.type) { // a button is being released
+ // Stop painting
+ painting = 0;
+ }
+ }
+}
+
+/*
+paint: Utility function that paints colors to a surface.
+The location to paint is given by x and y, the color to paint is
+a mixture of red, green, and blue values in the range 0 to 255.
+*/
+void paint(SDL_Surface *surface, int x, int y,
+ Uint8 red, Uint8 green, Uint8 blue) {
+ if(SDL_MUSTLOCK(surface)) {
+ // The surface must be locked to access surface->pixels
+ SDL_LockSurface(surface);
+ }
+ // This is the size of each pixel in bytes
+ int bytes_per_pixel = surface->format->BytesPerPixel;
+ // surface->pixels is a pointer into memory, it points at the first pixel in
+ // the surface which is at (0, 0).
+ // We create our own pointer which we are going to move around until we find
+ // the pixel we want to modify.
+ Uint8 *pixel;
+ // We start at (0, 0)
+ pixel = surface->pixels;
+ // surface->pitch is the number of bytes between each row of pixels, we move
+ // our pointer forward in memory until we find the start of the row for y
+ pixel += y * surface->pitch;
+ // We move our pointer forward in memory unitl we find the pixel in this row
+ // for x
+ pixel += x * bytes_per_pixel;
+ // For the given red, green, and blue values we need to know the corresponding
+ // number to write into memory to make that color
+ Uint32 color = SDL_MapRGB(surface->format, red, green, blue);
+ // Figure out the integer type used to write the color into memory
+ if(sizeof(Uint8) == bytes_per_pixel) {
+ *pixel = color;
+ } else if(sizeof(Uint16) == bytes_per_pixel) {
+ Uint16 *pixel2 = (Uint16 *)pixel;
+ *pixel2 = color;
+ } else if(sizeof(Uint32) == bytes_per_pixel) {
+ Uint32 *pixel4 = (Uint32 *)pixel;
+ *pixel4 = color;
+ }
+ if(SDL_MUSTLOCK(surface)) {
+ // We're done with surface->pixels so unlock the surface
+ SDL_UnlockSurface(surface);
+ }
+ // Make our changes to surface memory visible on the screen
+ Sint32 rect_width = 1, rect_height = 1;
+ SDL_UpdateRect(surface, x, y, rect_width, rect_height);
+}