1 // $Id: screen.cpp 2334 2005-04-04 16:26:14Z grumbel $
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.
31 #include <SDL_image.h>
34 #include <sys/types.h>
38 #include "gameconfig.hpp"
41 #include "video/drawing_context.hpp"
42 #include "audio/sound_manager.hpp"
43 #include "math/vector.hpp"
45 static const float LOOP_DELAY = 20.0;
46 extern SDL_Surface* screen;
48 /* 'Stolen' from the SDL documentation.
49 * Return the pixel value at (x, y)
50 * NOTE: The surface must be locked before calling this!
52 Uint32 getpixel(SDL_Surface *surface, int x, int y)
54 int bpp = surface->format->BytesPerPixel;
55 /* Here p is the address to the pixel we want to retrieve */
56 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
66 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
67 return p[0] << 16 | p[1] << 8 | p[2];
69 return p[0] | p[1] << 8 | p[2] << 16;
75 return 0; /* shouldn't happen, but avoids warnings */
79 /* 'Stolen' from the SDL documentation.
80 * Set the pixel at (x, y) to the given value
81 * NOTE: The surface must be locked before calling this!
83 void putpixel(SDL_Surface *surface, int x, int y, Uint32 pixel)
85 int bpp = surface->format->BytesPerPixel;
86 /* Here p is the address to the pixel we want to set */
87 Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;
99 if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
101 p[0] = (pixel >> 16) & 0xff;
102 p[1] = (pixel >> 8) & 0xff;
108 p[1] = (pixel >> 8) & 0xff;
109 p[2] = (pixel >> 16) & 0xff;
114 *(Uint32 *)p = pixel;
122 /* Draw a single pixel on the screen. */
123 void drawpixel(int x, int y, Uint32 pixel)
125 /* Lock the screen for direct access to the pixels */
126 if ( SDL_MUSTLOCK(screen) )
128 if ( SDL_LockSurface(screen) < 0 )
130 fprintf(stderr, "Can't lock screen: %s\n", SDL_GetError());
135 if(!(x < 0 || y < 0 || x > SCREEN_WIDTH || y > SCREEN_HEIGHT))
136 putpixel(screen, x, y, pixel);
138 if ( SDL_MUSTLOCK(screen) )
140 SDL_UnlockSurface(screen);
142 /* Update just the part of the display that we've changed */
143 SDL_UpdateRect(screen, x, y, 1, 1);
146 /* --- FILL A RECT --- */
148 void fillrect(float x, float y, float w, float h, int r, int g, int b, int a)
160 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
161 glColor4ub(r, g, b,a);
166 glVertex2f(x+w, y+h);
172 /* Needed for line calculations */
173 #define SGN(x) ((x)>0 ? 1 : ((x)==0 ? 0:(-1)))
174 #define ABS(x) ((x)>0 ? (x) : (-x))
176 void draw_line(float x1, float y1, float x2, float y2,
177 int r, int g, int b, int a)
180 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
181 glColor4ub(r, g, b,a);
191 void fadeout(int fade_time)
193 float alpha_inc = 256 / (fade_time / LOOP_DELAY);
198 fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0,0,0, (int)alpha_inc); // left side
200 DrawingContext context; // ugly...
201 context.do_drawing();
202 sound_manager->update();
204 SDL_Delay(int(LOOP_DELAY));
207 fillrect(0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0, 255);
210 void shrink_fade(const Vector& point, int fade_time)
212 float left_inc = point.x / ((float)fade_time / LOOP_DELAY);
213 float right_inc = (SCREEN_WIDTH - point.x) / ((float)fade_time / LOOP_DELAY);
214 float up_inc = point.y / ((float)fade_time / LOOP_DELAY);
215 float down_inc = (SCREEN_HEIGHT - point.y) / ((float)fade_time / LOOP_DELAY);
217 float left_cor = 0, right_cor = 0, up_cor = 0, down_cor = 0;
219 while(left_cor < point.x && right_cor < SCREEN_WIDTH - point.x &&
220 up_cor < point.y && down_cor < SCREEN_HEIGHT - point.y) {
221 left_cor += left_inc;
222 right_cor += right_inc;
224 down_cor += down_inc;
226 fillrect(0, 0, left_cor, SCREEN_HEIGHT, 0,0,0); // left side
227 fillrect(SCREEN_WIDTH - right_cor, 0, right_cor, SCREEN_HEIGHT, 0,0,0); // right side
228 fillrect(0, 0, SCREEN_WIDTH, up_cor, 0,0,0); // up side
229 fillrect(0, SCREEN_HEIGHT - down_cor, SCREEN_WIDTH, down_cor+1, 0,0,0); // down side
230 DrawingContext context; // ugly...
231 context.do_drawing();
233 sound_manager->update();
234 SDL_Delay(int(LOOP_DELAY));