1 /*
2  * file x11c_pixmap.c - double buffer for drawing
3  *
4  * $Id: sdl_pixmap.c,v 1.5 2006/03/28 11:50:25 fzago Exp $
5  *
6  * Program XBLAST
7  * (C) by Oliver Vogel (e-mail: m.vogel@ndh.net)
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published
11  * by the Free Software Foundation; either version 2; or (at your option)
12  * any later version
13  *
14  * This program is distributed in the hope that it will be entertaining,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILTY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
17  * Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.
21  * 675 Mass Ave, Cambridge, MA 02139, USA.
22  */
23 
24 #include "xblast.h"
25 
26 #include "sdl_common.h"
27 #include "sdl_image.h"
28 
29 /*
30  * local constants
31  */
32 #define CLEAR_WIDTH  (24*BASE_X)
33 #define CLEAR_HEIGHT (24*BASE_Y)
34 #define FADE_STEP 16
35 
36 /*
37  * local variables
38  */
39 
40 /* Changed by VVL (Chat) 12/11/99 */
41 #ifdef SMPF
42 static SDL_Rect xrec[MAZE_W * (MAZE_H + 3) + STAT_W * 4];
43 #else
44 static SDL_Rect xrec[MAZE_W * (MAZE_H + 2) + STAT_W * 4];
45 #endif
46 int counter = 0;
47 static SDL_Rect *xrecMax = xrec;
48 
49 /* fading */
50 static XBFadeMode fadeMode;
51 static int fadeMax;				/* maximum y coordinate */
52 static int fadeStep;			/* step width between lines */
53 
54 /* GC to use*/
55 static Uint32 fadeColor;
56 static SDL_Surface *clearPix;
57 
58 /* This SDL_Surface is used as a work around to blit back the screen after a
59    fading. The right fix would be to force an entire drawing after fading.
60    TODO: remove this hack and force entire drawing where needed.
61 */
62 
63 static SDL_Surface *screen_copy;
64 
65 /*
66  *
67  */
68 XBBool
InitPixmap(void)69 InitPixmap (void)
70 {
71 
72 	SDL_Surface *temp;
73 	temp =
74 		ReadCchPixmap (imgPathMisc, imgFileTitle, COLOR_BLACK, COLOR_GRAY_75, COLOR_MIDNIGHT_BLUE);
75 	if (!temp) {
76 		fprintf (stderr, "Error: file not found.\n");
77 		return XBFalse;
78 	}
79 	clearPix = SDL_DisplayFormat (temp);
80 	SDL_FreeSurface (temp);
81 	if (clearPix == NULL) {
82 		fprintf (stderr, "ReadCchPixmap Failed in InitPixmap\n");
83 		return XBFalse;
84 	};
85 
86 	screen_copy = SDL_CreateRGBSurface (screen->flags, screen->w, screen->h,
87 										screen->format->BitsPerPixel, screen->format->Rmask,
88 										screen->format->Gmask, screen->format->Bmask,
89 										screen->format->Amask);
90 	if (screen_copy == NULL) {
91 		fprintf (stderr, "Error: failed to init screen_copy. Reason: %s\n", SDL_GetError ());
92 		return XBFalse;
93 	};
94 
95 	return XBTrue;
96 
97 }								/* InitPixmap */
98 
99 /*
100  * Clear screen with clearpix
101  */
102 void
GUI_ClearPixmap(void)103 GUI_ClearPixmap (void)
104 {
105 
106 	int x;
107 	int y;
108 
109 	SDL_Rect DstRect;
110 	DstRect.x = 0;
111 	DstRect.y = 0;
112 	DstRect.w = PIXW;
113 	for (DstRect.x = 0; DstRect.x < PIXW; x += CLEAR_WIDTH) {
114 		for (DstRect.y = 0; DstRect.y < PIXH + SCOREH; y += CLEAR_HEIGHT) {
115 			SDL_BlitSurface (clearPix, NULL, screen, &DstRect);
116 			DstRect.y += clearPix->h;
117 		}
118 		DstRect.x += clearPix->w;
119 	}
120 	SDL_Flip (screen);
121 
122 }								/* GUI_ClearPixmap */
123 
124 /*
125  *
126  */
127 void
GUI_AddMazeRectangle(int x,int y)128 GUI_AddMazeRectangle (int x, int y)
129 {
130 	xrecMax->x = BLOCK_WIDTH * x;
131 	xrecMax->y = BLOCK_HEIGHT * y;
132 	xrecMax->w = BLOCK_WIDTH;
133 	xrecMax->h = BLOCK_HEIGHT;
134 
135 	if (xrecMax != xrec) {
136 		SDL_Rect *prev = xrecMax - 1;
137 		if ((prev->y == xrecMax->y) && ((xrecMax->x - prev->x) == prev->w)) {
138 			prev->w += BLOCK_WIDTH;
139 			xrecMax = prev;
140 		}
141 	}
142 
143 	xrecMax++;
144 }								/* GUI_AddMazeRectangle */
145 
146 /*
147  *
148  */
149 void
GUI_AddStatRectangle(int x,int y)150 GUI_AddStatRectangle (int x, int y)
151 {
152 	xrecMax->x = x * STAT_WIDTH;
153 	xrecMax->y = MAZE_H * BLOCK_HEIGHT + y * STAT_HEIGHT;
154 	xrecMax->w = STAT_WIDTH;
155 	xrecMax->h = (y < STAT_H) ? STAT_HEIGHT : LED_HEIGHT;
156 
157 	if (xrecMax != xrec) {
158 		SDL_Rect *prev = xrecMax - 1;
159 		/* try to join rectangles */
160 		if ((prev->y == xrecMax->y) && ((xrecMax->x - prev->x) == prev->w)) {
161 			prev->w += BLOCK_WIDTH;
162 			xrecMax = prev;
163 			counter--;
164 		}
165 	}
166 
167 	xrecMax++;
168 }								/* GUI_AddStatRectangle */
169 
170 /* Added by VVL (Chat) 12/11/99 : Begin */
171 /* Added by VVL (Chat) 12/11/99 : Begin */
172 void
GUI_AddChatRectangle(int x,int y)173 GUI_AddChatRectangle (int x, int y)
174 {
175 #ifdef SMPF
176 	int i = 2;
177 #else
178 	int i = 1;
179 #endif
180 	int j;
181 	j = MAZE_W * (MAZE_H + 1) + STAT_W * 4;
182 	xrecMax->h = i * STAT_HEIGHT + BLOCK_HEIGHT + 8;
183 	xrecMax->x = x * STAT_WIDTH;
184 	xrecMax->y = (MAZE_H + i) * BLOCK_HEIGHT;
185 	xrecMax->w = STAT_WIDTH;
186 
187 	if (xrecMax != xrec) {
188 		SDL_Rect *prev = xrecMax - 1;
189 		if ((prev->y == xrecMax->y)
190 			&& ((xrecMax->x - prev->x) == prev->w)) {
191 			prev->w += BLOCK_WIDTH;
192 			xrecMax = prev;
193 
194 		}
195 	}
196 	if (xrec + MAZE_W * (MAZE_H + 1) + STAT_W * 4 == xrecMax) {
197 		return;
198 	}
199 	xrecMax++;
200 
201 }
202 
203 /* Added by VVL (Chat) 12/11/99 : End */
204 /* Added by VVL (Chat) 12/11/99 : End */
205 /* Added by VVL (Chat) 12/11/99 : Begin */
206 /*
207 void
208 AddTilesRectangle (int x, int y)
209 {
210 } */
211 
212 void
GUI_AddTilesRectangle(int x,int y)213 GUI_AddTilesRectangle (int x, int y)
214 {
215 #ifdef SMPF
216 	int i = 0;
217 #else
218 	int i = 0;
219 #endif
220 	xrecMax->h = i * STAT_HEIGHT;
221 	xrecMax->x = x * STAT_WIDTH;
222 	xrecMax->y = (MAZE_H + i) * BLOCK_HEIGHT;
223 	xrecMax->w = STAT_WIDTH;
224 	if (xrecMax != xrec) {
225 		SDL_Rect *prev = xrecMax - 1;
226 
227 		if ((prev->y == xrecMax->y)
228 			&& ((xrecMax->x - prev->x) == prev->w)) {
229 			prev->w += BLOCK_WIDTH;
230 			xrecMax = prev;
231 		}
232 	}
233 
234 	xrecMax++;
235 
236 }
237 
238 /* Added by VVL (Chat) 12/11/99 : End */
239 
240 /*
241  *
242  */
243 void
GUI_FlushPixmap(XBBool flag)244 GUI_FlushPixmap (XBBool flag)
245 {
246 	SDL_Flip (screen);
247 
248 	if (flag) {
249 		counter = 0;
250 		xrecMax = xrec;
251 	}
252 }								/* GUI_FlushPixmap  */
253 
254 /*
255  *
256  */
257 void
GUI_FlushScoreBoard(void)258 GUI_FlushScoreBoard (void)
259 {
260 }								/* GUI_FlushScoreBoard  */
261 
262 /*
263  *
264  */
265 // maxLines are not used in this SDL implementation.
266 void
GUI_InitFade(XBFadeMode mode,int maxLines)267 GUI_InitFade (XBFadeMode mode, int maxLines)
268 {
269 	fadeMax = maxLines;
270 	fadeStep = FADE_STEP;
271 	fadeMode = mode;
272 	switch (mode) {
273 	case XBFM_BLACK_OUT:
274 		fadeColor = SDL_MapRGB (screen->format, 0, 0, 0);
275 		break;
276 	case XBFM_WHITE_OUT:
277 		fadeColor = SDL_MapRGB (screen->format, 0xFF, 0xFF, 0xFF);
278 		break;
279 	case XBFM_IN:				// just to keep compiler happy
280 		break;
281 	}
282 	if (mode != XBFM_IN)		// save a copy of the current screen (before fade)
283 	{
284 		SDL_BlitSurface (screen, NULL, screen_copy, NULL);
285 	}
286 }								/* GUI_InitFade */
287 
288 /*
289  *
290  */
291 
292 XBBool
GUI_DoFade(void)293 GUI_DoFade (void)
294 {
295 	int y;
296 	SDL_Rect r;
297 
298 	if (fadeStep <= 0) {
299 		if (fadeMode != XBFM_IN)
300 			SDL_FillRect (screen, NULL, fadeColor);
301 		SDL_Flip (screen);
302 		SDL_Delay (200);
303 		if (fadeMode != XBFM_IN)
304 			SDL_BlitSurface (screen_copy, NULL, screen, NULL);
305 		return XBFalse;
306 	}
307 
308 	r.x = 0;
309 	r.w = screen->w;
310 	r.h = (FADE_STEP + 1) - fadeStep;
311 	for (y = 0; y < screen->h; y += FADE_STEP) {
312 		r.y = y;
313 		if (fadeMode == XBFM_IN)
314 			SDL_UpdateRect (screen, r.x, r.y, r.w, r.h);
315 		else					// fade out
316 			SDL_FillRect (screen, &r, fadeColor);
317 	}
318 
319 	if (fadeMode != XBFM_IN)
320 		SDL_Flip (screen);
321 
322 	/* preparing next fade. */
323 	fadeStep -= 2;
324 
325 	/* thats all */
326 	return XBTrue;
327 }								/* GUI_FadeOut */
328 
329 /*
330  * end of file x11c_pixmap.c
331  */
332