3 // SuperTux - A Jump'n Run
4 // Copyright (C) 2000 Bill Kendrick <bill@newbreedsoftware.com>
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
27 #include <SDL_image.h>
30 #include <sys/types.h>
40 /* Needed for line calculations */
41 #define SGN(x) ((x)>0 ? 1 : ((x)==0 ? 0:(-1)))
42 #define ABS(x) ((x)>0 ? (x) : (-x))
44 /* --- CLEAR SCREEN --- */
46 void clearscreen(int r, int g, int b)
51 glClearColor(r/256, g/256, b/256, 1.0);
52 glClear(GL_COLOR_BUFFER_BIT);
58 SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
65 /* --- DRAWS A VERTICAL GRADIENT --- */
67 void drawgradient(Color top_clr, Color bot_clr)
73 glColor3ub(top_clr.red, top_clr.green, top_clr.blue);
75 glVertex2f(screen->w, 0);
76 glColor3ub(bot_clr.red, bot_clr.green, bot_clr.blue);
77 glVertex2f(screen->w, screen->h);
78 glVertex2f(0, screen->h);
85 //void fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
87 for(float y = 0; y < screen->h; y += 2)
88 fillrect(0, (int)y, screen->w, 2,
89 (int)(((float)(top_clr.red-bot_clr.red)/(0-screen->h)) * y + top_clr.red),
90 (int)(((float)(top_clr.green-bot_clr.green)/(0-screen->h)) * y + top_clr.green),
91 (int)(((float)(top_clr.blue-bot_clr.blue)/(0-screen->h)) * y + top_clr.blue),
93 /* calculates the color for each line, based in the generic equation for functions: y = mx + b */
101 /* --- FADE IN --- */
103 /** Fades the given surface into a black one. If fade_out is true, it will fade out, else
106 void fade(Surface *surface, int seconds, bool fade_out);
108 void fade(const std::string& surface, int seconds, bool fade_out)
110 Surface* sur = new Surface(datadir + surface, IGNORE_ALPHA);
111 fade(sur, seconds, fade_out);
115 void fade(Surface *surface, int seconds, bool fade_out)
123 int cur_time, old_time;
124 cur_time = SDL_GetTicks();
126 while(alpha >= 0 && alpha < 256)
128 surface->draw(0,0,(int)alpha);
132 cur_time = SDL_GetTicks();
134 /* Calculate the next alpha value */
135 float calc = (float) ((cur_time - old_time) / seconds);
143 /* 'Stolen' from the SDL documentation.
144 * Set the pixel at (x, y) to the given value
145 * NOTE: The surface must be locked before calling this!
147 void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
149 int bpp = surface->format->BytesPerPixel;
150 /* Here p is the address to the pixel we want to set */
151 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
160 *(Uint16 *)p = pixel;
164 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
166 p[0] = (pixel >> 16) & 0xff;
167 p[1] = (pixel >> 8) & 0xff;
173 p[1] = (pixel >> 8) & 0xff;
174 p[2] = (pixel >> 16) & 0xff;
179 *(Uint32 *)p = pixel;
184 /* Draw a single pixel on the screen. */
185 void drawpixel(int x, int y, Uint32 pixel)
187 /* Lock the screen for direct access to the pixels */
188 if ( SDL_MUSTLOCK(screen) )
190 if ( SDL_LockSurface(screen) < 0 )
192 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
197 if(!(x < 0 || y < 0 || x > screen->w || y > screen->h))
198 putpixel(screen, x, y, pixel);
200 if ( SDL_MUSTLOCK(screen) )
202 SDL_UnlockSurface(screen);
204 /* Update just the part of the display that we've changed */
205 SDL_UpdateRect(screen, x, y, 1, 1);
208 void drawline(int x1, int y1, int x2, int y2, int r, int g, int b, int a)
214 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
215 glColor4ub(r, g, b,a);
227 /* Basic unantialiased Bresenham line algorithm */
228 int lg_delta, sh_delta, cycle, lg_step, sh_step;
229 Uint32 color = SDL_MapRGBA(screen->format, r, g, b, a);
233 lg_step = SGN(lg_delta);
234 lg_delta = ABS(lg_delta);
235 sh_step = SGN(sh_delta);
236 sh_delta = ABS(sh_delta);
237 if (sh_delta < lg_delta)
239 cycle = lg_delta >> 1;
242 drawpixel(x1, y1, color);
244 if (cycle > lg_delta)
251 drawpixel(x1, y1, color);
253 cycle = sh_delta >> 1;
256 drawpixel(x1, y1, color);
258 if (cycle > sh_delta)
265 drawpixel(x1, y1, color);
272 /* --- FILL A RECT --- */
274 void fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
291 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
292 glColor4ub(r, g, b,a);
297 glVertex2f(x+w, y+h);
306 SDL_Surface *temp = NULL;
315 temp = SDL_CreateRGBSurface(screen->flags, rect.w, rect.h, screen->format->BitsPerPixel,
316 screen->format->Rmask,
317 screen->format->Gmask,
318 screen->format->Bmask,
319 screen->format->Amask);
327 SDL_FillRect(temp, &src, SDL_MapRGB(screen->format, r, g, b));
329 SDL_SetAlpha(temp, SDL_SRCALPHA, a);
331 SDL_BlitSurface(temp,0,screen,&rect);
333 SDL_FreeSurface(temp);
336 SDL_FillRect(screen, &rect, SDL_MapRGB(screen->format, r, g, b));
345 /* --- UPDATE SCREEN --- */
347 void updatescreen(void)
349 if(use_gl) /*clearscreen(0,0,0);*/
350 SDL_GL_SwapBuffers();
352 SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
355 void flipscreen(void)
358 SDL_GL_SwapBuffers();
365 clearscreen(0, 0, 0);
366 white_text->draw_align("Loading...", screen->w/2, screen->h/2, A_HMIDDLE, A_TOP);
370 void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h)
373 SDL_UpdateRect(scr, x, y, w, h);