1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
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);
}
|