|
1 /** |
|
2 * test/demos/pmc/surface.cc |
|
3 * Copyright (C) 2008 Markus Broeker |
|
4 */ |
|
5 |
|
6 #include <surface.h> |
|
7 |
|
8 #define max(a,b) (((a) > (b)) ? (a) : (b)) |
|
9 #define min(a,b) (((a) < (b)) ? (a) : (b)) |
|
10 #define abs(a) (((a)<0) ? -(a) : (a)) |
|
11 #define sign(a) (((a)<0) ? -1 : (a)>0 ? 1 : 0) |
|
12 |
|
13 Surface::Surface (int w, int h, int d) |
|
14 { |
|
15 width = w; |
|
16 height = h; |
|
17 depth = d; |
|
18 |
|
19 SDL_Init (SDL_INIT_VIDEO); |
|
20 screen = SDL_SetVideoMode (width, height, depth, SDL_HWSURFACE); |
|
21 red = SDL_MapRGB (screen->format, 0xff, 0x00, 0x00); |
|
22 black = SDL_MapRGB (screen->format, 0x00, 0x00, 0x00); |
|
23 |
|
24 color = red; |
|
25 } |
|
26 |
|
27 Surface::~Surface () |
|
28 { |
|
29 SDL_Quit (); |
|
30 } |
|
31 |
|
32 void Surface::drawPixel (int x, int y) |
|
33 { |
|
34 if (SDL_MUSTLOCK (screen)) { |
|
35 if (SDL_LockSurface (screen) < 0) { |
|
36 return; |
|
37 } |
|
38 } |
|
39 |
|
40 switch (screen->format->BytesPerPixel) { |
|
41 case 1:{ /* vermutlich 8 Bit */ |
|
42 Uint8 *bufp; |
|
43 |
|
44 bufp = (Uint8 *) screen->pixels + y * screen->pitch + x; |
|
45 *bufp = color; |
|
46 } |
|
47 break; |
|
48 |
|
49 case 2:{ /* vermutlich 15 Bit oder 16 Bit */ |
|
50 Uint16 *bufp; |
|
51 |
|
52 bufp = (Uint16 *) screen->pixels + y * screen->pitch / 2 + x; |
|
53 *bufp = color; |
|
54 } |
|
55 break; |
|
56 |
|
57 case 3:{ /* langsamer 24-Bit-Modus, selten verwendet */ |
|
58 Uint8 *bufp; |
|
59 |
|
60 bufp = (Uint8 *) screen->pixels + y * screen->pitch + x * 3; |
|
61 if (SDL_BYTEORDER == SDL_LIL_ENDIAN) { |
|
62 bufp[0] = color; |
|
63 bufp[1] = color >> 8; |
|
64 bufp[2] = color >> 16; |
|
65 } else { |
|
66 bufp[2] = color; |
|
67 bufp[1] = color >> 8; |
|
68 bufp[0] = color >> 16; |
|
69 } |
|
70 } |
|
71 break; |
|
72 |
|
73 case 4:{ /* vermutlich 32 Bit */ |
|
74 Uint32 *bufp; |
|
75 |
|
76 bufp = (Uint32 *) screen->pixels + y * screen->pitch / 4 + x; |
|
77 *bufp = color; |
|
78 } |
|
79 break; |
|
80 } |
|
81 |
|
82 if (SDL_MUSTLOCK (screen)) { |
|
83 SDL_UnlockSurface (screen); |
|
84 } |
|
85 } |
|
86 |
|
87 void Surface::drawLine (int x1, int y1, int x2, int y2) |
|
88 { |
|
89 int d; |
|
90 int x; |
|
91 int y; |
|
92 int ax; |
|
93 int ay; |
|
94 int sx; |
|
95 int sy; |
|
96 int dx; |
|
97 int dy; |
|
98 |
|
99 Uint8 *lineAddr; |
|
100 Sint32 yOffset; |
|
101 |
|
102 /* |
|
103 * SANITY CHECK: fix segfault in *((Uint16 *) (lineAddr + (x << 1))) = (Uint16) color; |
|
104 */ |
|
105 if (y1 < 0 || y2 < 0) |
|
106 return; |
|
107 |
|
108 if (x1 < 0 || x2 < 0) |
|
109 return; |
|
110 |
|
111 dx = x2 - x1; |
|
112 ax = abs (dx) << 1; |
|
113 sx = sign (dx); |
|
114 |
|
115 dy = y2 - y1; |
|
116 ay = abs (dy) << 1; |
|
117 sy = sign (dy); |
|
118 yOffset = sy * screen->pitch; |
|
119 |
|
120 x = x1; |
|
121 y = y1; |
|
122 |
|
123 lineAddr = ((Uint8 *) screen->pixels) + (y * screen->pitch); |
|
124 if (ax > ay) { /* x dominant */ |
|
125 d = ay - (ax >> 1); |
|
126 for (;;) { |
|
127 *((Uint16 *) (lineAddr + (x << 1))) = (Uint16) color; |
|
128 |
|
129 if (x == x2) { |
|
130 return; |
|
131 } |
|
132 if (d >= 0) { |
|
133 y += sy; |
|
134 lineAddr += yOffset; |
|
135 d -= ax; |
|
136 } |
|
137 x += sx; |
|
138 d += ay; |
|
139 } |
|
140 } else { /* y dominant */ |
|
141 d = ax - (ay >> 1); |
|
142 for (;;) { |
|
143 *((Uint16 *) (lineAddr + (x << 1))) = (Uint16) color; |
|
144 |
|
145 if (y == y2) { |
|
146 return; |
|
147 } |
|
148 if (d >= 0) { |
|
149 x += sx; |
|
150 d -= ay; |
|
151 } |
|
152 y += sy; |
|
153 lineAddr += yOffset; |
|
154 d += ax; |
|
155 } |
|
156 } |
|
157 } |
|
158 |
|
159 void Surface::flip () |
|
160 { |
|
161 SDL_Flip (screen); |
|
162 } |
|
163 |
|
164 void Surface::setColor (foregroundColor c) |
|
165 { |
|
166 switch (c) { |
|
167 case BLACK: |
|
168 color = black; |
|
169 break; |
|
170 case RED: |
|
171 color = red; |
|
172 break; |
|
173 }; |
|
174 } |