5 * Copyright (C) 2003, 2007 Thomas Perl <thp@perli.net>
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 2
10 * of the License, or (at your option) any later version.
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
34 static SDL_Surface
*buffer
;
36 static Uint32 fading_start
= 0;
38 #include "data/graphics_data.c"
39 static const ResourceData graphics
[] = {
42 RESOURCE(player_racket
),
46 RESOURCE(smallish_font
),
50 void init_graphics( const char *data_dir
) {
56 tmp
= IMG_Load_RW( SDL_RWFromConstMem( icon
, sizeof(icon
)), 1);
58 SDL_WM_SetIcon( tmp
, NULL
);
59 SDL_FreeSurface( tmp
);
63 images
= (Image
*)calloc( GR_COUNT
, sizeof( Image
));
65 for( i
=0; i
<GR_COUNT
; i
++) {
66 tmp
= IMG_Load_RW( SDL_RWFromConstMem( graphics
[i
].data
, graphics
[i
].size
), 1);
68 fprintf( stderr
, "Error: %s\n", SDL_GetError());
72 SDL_SetColorKey( tmp
, SDL_SRCCOLORKEY
, SDL_MapRGB( tmp
->format
, 0, 0, 0));
73 data
= SDL_DisplayFormatAlpha( tmp
);
74 SDL_FreeSurface( tmp
);
77 fprintf( stderr
, "Error: %s\n", SDL_GetError());
80 images
[i
].data
= data
;
83 buffer
= SDL_CreateRGBSurface( SDL_HWSURFACE
, WIDTH
, HEIGHT
, screen
->format
->BitsPerPixel
, screen
->format
->Rmask
, screen
->format
->Gmask
, screen
->format
->Bmask
, screen
->format
->Amask
);
86 fprintf( stderr
, "Cannot create buffer surface: %s\n", SDL_GetError());
90 void uninit_graphics() {
93 for( i
=0; i
<GR_COUNT
; i
++) {
94 SDL_FreeSurface( images
[i
].data
);
98 SDL_FreeSurface( buffer
);
104 int get_image_width( unsigned int id
) {
105 return images
[id
].data
->w
;
108 int get_image_height( unsigned int id
) {
109 return images
[id
].data
->h
;
112 int get_sprite_width( unsigned int id
, int items
) {
113 return images
[id
].data
->w
/ items
;
116 void show_sprite( unsigned int id
, int pos
, int items
, int x_offset
, int y_offset
, int opacity
) {
120 bitmap
= images
[id
].data
;
124 SDL_SetAlpha( bitmap
, SDL_SRCALPHA
| SDL_RLEACCEL
, opacity
);
126 dst
.w
= src
.w
= bitmap
->w
/items
;
127 dst
.h
= src
.h
= bitmap
->h
;
133 SDL_BlitSurface( bitmap
, &src
, screen
, &dst
);
136 void line_horiz( int y
, Uint8 r
, Uint8 g
, Uint8 b
) {
137 Uint32 color
= SDL_MapRGB( screen
->format
, r
, g
, b
);
145 SDL_FillRect( screen
, &rect
, color
);
148 void line_vert( int x
, Uint8 r
, Uint8 g
, Uint8 b
) {
149 Uint32 color
= SDL_MapRGB( screen
->format
, r
, g
, b
);
157 SDL_FillRect( screen
, &rect
, color
);
160 void rectangle( int x
, int y
, int w
, int h
, Uint8 r
, Uint8 g
, Uint8 b
) {
161 Uint32 color
= SDL_MapRGB( screen
->format
, r
, g
, b
);
169 SDL_FillRect( screen
, &rect
, color
);
172 void draw_button( int x
, int y
, int w
, int h
, Uint8 r
, Uint8 g
, Uint8 b
, char pressed
) {
173 float diff
= (pressed
?1.0-BUTTON_HIGHLIGHT
:1.0+BUTTON_HIGHLIGHT
);
174 int border
= BUTTON_BORDER
;
175 rectangle( x
, y
, w
, h
, r
*diff
, g
*diff
, b
*diff
);
176 rectangle( x
+border
, y
+border
, w
-border
, h
-border
, r
/diff
, g
/diff
, b
/diff
);
177 rectangle( x
+border
, y
+border
, w
-2*border
, h
-2*border
, r
, g
, b
);
180 void draw_button_text( char* s
, int x
, int y
, int w
, int h
, Uint8 r
, Uint8 g
, Uint8 b
, char pressed
) {
182 pressed
= pressed
?1:0;
183 draw_button( x
, y
, w
, h
, r
, g
, b
, pressed
);
184 font_x
= x
+ w
/2 - font_get_string_width( GR_SMALLISH_FONT
, s
)/2 + pressed
*BUTTON_BORDER
;
185 font_y
= y
+ h
/2 - get_image_height( GR_SMALLISH_FONT
)/2 + pressed
*BUTTON_BORDER
;
186 font_draw_string( GR_SMALLISH_FONT
, s
, font_x
, font_y
, 0, 0);
189 void show_image( unsigned int id
, int x_offset
, int y_offset
, int opacity
) {
190 show_sprite( id
, 0, 1, x_offset
, y_offset
, opacity
);
193 void introimage( unsigned int id
) {
196 for( i
=0; i
<256; i
+=10) {
198 show_image( id
, 0, 0, i
);
206 for( i
=255; i
>=0; i
-=10) {
208 show_image( id
, 0, 0, i
);
224 SDL_FillRect( screen
, &rect
, SDL_MapRGB( screen
->format
, 0, 0, 0));
228 int ticks
= SDL_GetTicks();
230 if( ticks
< fading_start
+FADE_DURATION
) {
231 SDL_SetAlpha( buffer
, SDL_SRCALPHA
| SDL_RLEACCEL
, 255-255*(ticks
-fading_start
)/FADE_DURATION
);
232 SDL_BlitSurface( buffer
, NULL
, screen
, NULL
);
235 SDL_UpdateRect( screen
, 0, 0, 0, 0);
240 SDL_BlitSurface( screen
, NULL
, buffer
, NULL
);
241 fading_start
= SDL_GetTicks();
245 return SDL_GetTicks() < fading_start
+FADE_DURATION
;
248 int font_get_metrics( unsigned int id
, char ch
, int* xp
, int* wp
) {
250 int pos
, x
= -1, w
= 0;
251 int search_pos
= 0, search_x
= 0;
252 Uint8 red
, green
, blue
;
254 if( id
> GR_COUNT
) return 0;
256 pos
= toupper( ch
) - ' '; /* ' ' = first character in font bitmap */
258 bitmap
= images
[id
].data
;
260 SDL_LockSurface( bitmap
);
261 while( search_x
< bitmap
->w
) {
262 GET_PIXEL_RGB( bitmap
, search_x
, 0, &red
, &green
, &blue
);
264 /* Increase pos counter if we have a "marker" pixel (255,0,255) */
265 if( red
> 250 && green
< 10 && blue
> 250) {
267 if( search_pos
== pos
) {
269 } else if( search_pos
== pos
+ 1) {
277 SDL_UnlockSurface( bitmap
);
279 if( wp
!= NULL
) (*wp
) = w
;
280 if( xp
!= NULL
) (*xp
) = x
;
285 int font_draw_char( unsigned int id
, char ch
, int x_offset
, int y_offset
) {
290 font_get_metrics( id
, ch
, &x
, &w
);
291 if( x
== -1) return w
;
293 bitmap
= images
[id
].data
;
296 dst
.h
= src
.h
= bitmap
->h
- 1;
302 SDL_BlitSurface( bitmap
, &src
, screen
, &dst
);
307 void font_draw_string( unsigned int id
, char* s
, int x_offset
, int y_offset
, int start
, int animation
) {
311 float xw
= 0.0, xw_diff
;
313 if( animation
& ANIMATION_BUNGEE
) {
314 xw
= (25.0*sinf( start
/10.0));
319 if( animation
& ANIMATION_PENDULUM
) {
320 x
-= (int)(20.0*sinf( start
/20.0));
323 for( i
=0; i
<strlen(s
); i
++) {
324 if( animation
& ANIMATION_WAVE
) {
325 y
= y_offset
+ (int)(3.0*sinf( start
/10.0 + x
/30.0));
327 x
+= font_draw_char( id
, s
[i
], x
, y
);
328 if( animation
& ANIMATION_BUNGEE
) {
329 xw_diff
+= xw
/strlen(s
);
330 if( xw_diff
> 1.0 || xw_diff
< -1.0) {
342 int font_get_string_width( unsigned int id
, char* s
) {
345 for( i
=0; i
<strlen(s
); i
++) {
346 w
+= font_get_metrics( id
, s
[i
], NULL
, NULL
);
352 void draw_line_faded( int x1
, int y1
, int x2
, int y2
, int r
, int g
, int b
, int r2
, int g2
, int b2
) {
353 float step
, dx
, dy
, x
= x1
, y
= y1
;
355 char fade
= (r
!=r2
|| g
!=g2
|| b
!=b2
);
357 step
= (float)(abs(x2
-x1
)>abs(y2
-y1
)?abs(x2
-x1
):abs(y2
-y1
));
358 dx
= (float)(x2
-x1
) / step
;
359 dy
= (float)(y2
-y1
) / step
;
361 SDL_LockSurface( screen
);
362 for( i
=0; i
<step
; i
++) {
365 if( x
< 0.0 || x
>= WIDTH
|| y
< 0.0 || y
>= HEIGHT
) {
369 SET_PIXEL_RGB( screen
, (int)x
, (int)y
, (r
*(step
-i
)+r2
*i
)/step
, (g
*(step
-i
)+g2
*i
)/step
, (b
*(step
-i
)+b2
*i
)/step
);
371 SET_PIXEL_RGB( screen
, (int)x
, (int)y
, r
, g
, b
);
374 SDL_UnlockSurface( screen
);