cleanups
[supertux.git] / src / screen.c
1 /*
2   screen.c
3   
4   Super Tux - Screen Functions
5   
6   by Bill Kendrick
7   bill@newbreedsoftware.com
8   http://www.newbreedsoftware.com/supertux/
9   
10   April 11, 2000 - April 22, 2000
11 */
12
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
16 #include <errno.h>
17 #include <unistd.h>
18 #include <SDL.h>
19 #include <SDL_image.h>
20
21 #ifdef LINUX
22 #include <pwd.h>
23 #include <sys/types.h>
24 #include <ctype.h>
25 #endif
26
27 #include "defines.h"
28 #include "globals.h"
29 #include "screen.h"
30 #include "setup.h"
31 #include "type.h"
32
33 /* --- LOAD AND DISPLAY AN IMAGE --- */
34
35 void load_and_display_image(char * file)
36 {
37   SDL_Surface * img;
38   
39   img = load_image(file, IGNORE_ALPHA);
40   SDL_BlitSurface(img, NULL, screen, NULL);
41   SDL_FreeSurface(img);
42 }
43
44
45 /* --- CLEAR SCREEN --- */
46
47 void clearscreen(float r, float g, float b)
48 {
49 #ifndef NOOPENGL
50   if(use_gl)
51   {
52   glClearColor(r/256, g/256, b/256, 1.0);
53   glClear(GL_COLOR_BUFFER_BIT);
54   }
55   else
56 #endif
57   SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
58  
59 }
60
61
62 /* --- UPDATE SCREEN --- */
63
64 void updatescreen(void)
65 {
66   if(use_gl)  /*clearscreen(0,0,0);*/
67   SDL_GL_SwapBuffers();
68   else
69     SDL_UpdateRect(screen, 0, 0, screen->w, screen->h);
70 }
71
72 void flipscreen(void)
73 {
74 if(use_gl)
75 SDL_GL_SwapBuffers();
76 else
77 SDL_Flip(screen);
78 }
79
80 /* --- LOAD AN IMAGE --- */
81
82 SDL_Surface * load_image(char * file, int use_alpha)
83 {
84 /*
85 if(!faccessible(file))
86 {
87 if(!faccessible(st_dir,
88 */
89
90   SDL_Surface * temp, * surf;
91   
92   temp = IMG_Load(file);
93
94   if (temp == NULL)
95     st_abort("Can't load", file);
96     
97   surf = SDL_DisplayFormatAlpha(temp);
98
99   if (surf == NULL)
100     st_abort("Can't covert to display format", file);
101     
102   if (use_alpha == IGNORE_ALPHA)
103     SDL_SetAlpha(surf, 0, 0);
104   
105   SDL_FreeSurface(temp);
106
107   return(surf);
108 }
109
110 void update_rect(SDL_Surface *scr, Sint32 x, Sint32 y, Sint32 w, Sint32 h)
111 {
112 if(!use_gl)
113 SDL_UpdateRect(scr, x, y, w, h);
114 }
115
116 void drawtext(char * text, int x, int y, SDL_Surface * surf, int update, int shadowsize)
117 {
118         /* i - helps to keep tracking of the all string length
119                 j - helps to keep track of the length of the current line */
120   int i, j;
121   char c;
122   SDL_Rect src, dest;
123   
124   /* For each letter in the string... */
125   
126   for (i = 0; i < strlen(text); i++)
127     {
128       /* Set source rectangle: */
129       
130       c = text[i];
131       
132       if (c >= 'A' && c <= 'Z')
133         {
134           /* Capital letter - first row: */
135           
136           src.x = (c - 'A') * 16;
137           src.y = 0;
138         }
139       else if (c >= 'a' && c <= 'z')
140         {
141           /* Lowercase letter - first row: */
142           
143           src.x = (c - 'a') * 16;
144           src.y = 16;
145         }
146       else if (c >= '!' && c <= '9')
147         {
148           /* Punctuation (except '?') or number - third row: */
149           
150           src.x = (c - '!') * 16;
151           src.y = 32;
152         }
153       else if (c == '?')
154         {
155           /* Question mark - third row, last character: */
156           
157           src.x = 400;
158           src.y = 24;
159         }
160         else if (c == '\n')             /* support for multi-lines */
161         {
162         j = i + 1;
163         y += 18;
164         continue;
165         }
166       else
167         src.x = -1;
168       
169       src.w = 16;
170       src.h = 16;
171       
172
173       /* Draw character: */
174       
175       if (src.x != -1)
176         {
177           /* Set destination rectangle for shadow: */
178           
179           dest.x = x + (i * 16) + shadowsize;
180           dest.y = y + shadowsize;
181           dest.w = src.w;
182           dest.h = src.h;
183           
184           
185           /* Shadow: */
186           
187           SDL_BlitSurface(letters_black, &src, screen, &dest);
188           
189           
190           /* Set destination rectangle for text: */
191           
192           dest.x = x + (i * 16);
193           dest.y = y;
194           dest.w = src.w;
195           dest.h = src.h;
196           
197           
198           /* Shadow: */
199           
200           SDL_BlitSurface(surf, &src, screen, &dest);
201           
202
203 /* FIXME: Text doesn't work in OpenGL mode, below is experimental code */
204 /*
205
206           dest.x = 0;
207           dest.y = 0; 
208           dest.w = src.w;
209           
210           dest.h = src.h;
211           
212           temp = SDL_CreateRGBSurface(SDL_SWSURFACE, dest.w, dest.h, 32,
213 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
214             0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
215 #else
216             0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
217 #endif
218           SDL_BlitSurface(letters_black, &src, temp, NULL);
219           texture_type xyz;
220           texture_from_sdl_surface(&xyz,temp,IGNORE_ALPHA);
221           texture_draw(&xyz,x + (i * 16) + shadowsize,y + shadowsize, update);
222           texture_free(&xyz);
223           / * Set destination rectangle for text: * /
224           
225           dest.x = x + (i * 16);
226           dest.y = y;
227           dest.w = src.w;
228           dest.h = src.h;         
229           
230           / * Text: * /
231           
232           SDL_BlitSurface(surf, &src, temp, NULL);
233           texture_from_sdl_surface(&xyz,temp,IGNORE_ALPHA);
234           SDL_FreeSurface(temp);
235           texture_draw(&xyz,x + (i * 16) + shadowsize,y + shadowsize, update);
236           texture_free(&xyz);*/
237         }
238     }
239   
240   
241   /* Update */
242   
243   if (update == UPDATE)
244     {
245       dest.w = strlen(text) * 16 + 1;
246       
247       if (dest.w > screen->w)
248         dest.w = screen->w;
249       
250       update_rect(screen, x, y, dest.w, 17);
251     }
252     
253 }
254
255
256 /* --- DRAW HORIZONTALLY-CENTERED TEXT: --- */
257
258 void drawcenteredtext(char * text, int y, SDL_Surface * surf, int update, int shadowsize)
259 {
260   drawtext(text, screen->w / 2 - (strlen(text) * 8), y, surf, update, shadowsize);
261 }
262
263 /* --- ERASE TEXT: --- */
264
265 void erasetext(char * text, int x, int y, SDL_Surface * surf, int update, int shadowsize)
266 {
267   SDL_Rect dest;
268   
269   
270   dest.x = x;
271   dest.y = y;
272   dest.w = strlen(text) * 16 + shadowsize;
273   dest.h = 17;
274   
275   if (dest.w > screen->w)
276     dest.w = screen->w;
277   
278   SDL_BlitSurface(surf, &dest, screen, &dest);
279   
280   if (update == UPDATE)
281     update_rect(screen, dest.x, dest.y, dest.w, dest.h);
282 }
283
284
285 /* --- ERASE CENTERED TEXT: --- */
286
287 void erasecenteredtext(char * text, int y, SDL_Surface * surf, int update, int shadowsize)
288 {
289   erasetext(text, screen->w / 2 - (strlen(text) * 8), y, surf, update, shadowsize);
290 }