applied leveleditor and multiline-drawtext patches from Ricardo Cruz <rick2@aeiou...
[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
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(int r, int g, int b)
48 {
49   SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, r, g, b));
50 }
51
52
53 /* --- UPDATE SCREEN --- */
54
55 void updatescreen(void)
56 {
57   SDL_UpdateRect(screen, 0, 0, 640, 480);
58 }
59
60
61 /* --- LOAD AN IMAGE --- */
62
63 SDL_Surface * load_image(char * file, int use_alpha)
64 {
65
66   SDL_Surface * temp, * surf;
67   
68   temp = IMG_Load(file);
69
70   if (temp == NULL)
71     st_abort("Can't load", file);
72     
73   surf = SDL_DisplayFormatAlpha(temp);
74
75   if (surf == NULL)
76     st_abort("Can't covert to display format", file);
77     
78   if (use_alpha == IGNORE_ALPHA)
79     SDL_SetAlpha(surf, 0, 0);
80   
81   SDL_FreeSurface(temp);
82
83   return(surf);
84 }
85
86
87 /* --- DRAW AN IMAGE ONTO THE SCREEN --- */
88
89 void drawimage(SDL_Surface * surf, int x, int y, int update)
90 {
91   SDL_Rect dest;
92   
93   dest.x = x;
94   dest.y = y;
95   dest.w = surf->w;
96   dest.h = surf->h;
97   
98   SDL_BlitSurface(surf, NULL, screen, &dest);
99   
100   if (update == UPDATE)
101     SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
102 }
103
104
105 /* --- DRAW PART OF AN IMAGE ONTO THE SCREEN --- */
106
107 void drawpart(SDL_Surface * surf, int x, int y, int w, int h, int update)
108 {
109   SDL_Rect src, dest;
110   
111   src.x = x;
112   src.y = y;
113   src.w = w;
114   src.h = h;
115
116   dest.x = x;
117   dest.y = y;
118   dest.w = w;
119   dest.h = h;
120   
121   SDL_BlitSurface(surf, &src, screen, &dest);
122   
123   if (update == UPDATE)
124     SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
125 }
126
127 /* --- DRAW TEXT ONTO THE SCREEN --- */
128
129 void drawtext(char * text, int x, int y, SDL_Surface * surf, int update, int shadowsize)
130 {
131         /* i - helps to keep tracking of the all string length
132                 j - helps to keep track of the length of the current line */
133   int i, j;
134   char c;
135   SDL_Rect src, dest;
136   
137   /* For each letter in the string... */
138   
139   for (i = 0; i < strlen(text); i++)
140     {
141       /* Set source rectangle: */
142       
143       c = text[i];
144       
145       if (c >= 'A' && c <= 'Z')
146         {
147           /* Capital letter - first row: */
148           
149           src.x = (c - 'A') * 16;
150           src.y = 0;
151         }
152       else if (c >= 'a' && c <= 'z')
153         {
154           /* Lowercase letter - first row: */
155           
156           src.x = (c - 'a') * 16;
157           src.y = 16;
158         }
159       else if (c >= '!' && c <= '9')
160         {
161           /* Punctuation (except '?') or number - third row: */
162           
163           src.x = (c - '!') * 16;
164           src.y = 32;
165         }
166       else if (c == '?')
167         {
168           /* Question mark - third row, last character: */
169           
170           src.x = 400;
171           src.y = 24;
172         }
173         else if (c == '\n')             /* support for multi-lines */
174         {
175         j = i + 1;
176         y += 18;
177         continue;
178         }
179       else
180         src.x = -1;
181       
182       src.w = 16;
183       src.h = 16;
184       
185
186       /* Draw character: */
187       
188       if (src.x != -1)
189         {
190           /* Set destination rectangle for shadow: */
191           
192           dest.x = x + (i * 16) + shadowsize;
193           dest.y = y + shadowsize;
194           dest.w = src.w;
195           dest.h = src.h;
196           
197           
198           /* Shadow: */
199           
200           SDL_BlitSurface(letters_black, &src, screen, &dest);
201           
202           
203           /* Set destination rectangle for text: */
204           
205           dest.x = x + (i * 16);
206           dest.y = y;
207           dest.w = src.w;
208           dest.h = src.h;
209           
210           
211           /* Shadow: */
212           
213           SDL_BlitSurface(surf, &src, screen, &dest);
214         }
215     }
216   
217   
218   /* Update */
219   
220   if (update == UPDATE)
221     {
222       dest.w = strlen(text) * 16 + 1;
223       
224       if (dest.w > 640)
225         dest.w = 640;
226       
227       SDL_UpdateRect(screen, x, y, dest.w, 17);
228     }
229     
230 }
231
232
233 /* --- DRAW HORIZONTALLY-CENTERED TEXT: --- */
234
235 void drawcenteredtext(char * text, int y, SDL_Surface * surf, int update, int shadowsize)
236 {
237   drawtext(text, 320 - (strlen(text) * 8), y, surf, update, shadowsize);
238 }
239
240 /* --- ERASE TEXT: --- */
241
242 void erasetext(char * text, int x, int y, SDL_Surface * surf, int update, int shadowsize)
243 {
244   SDL_Rect dest;
245   
246   
247   dest.x = x;
248   dest.y = y;
249   dest.w = strlen(text) * 16 + shadowsize;
250   dest.h = 17;
251   
252   if (dest.w > 640)
253     dest.w = 640;
254   
255   SDL_BlitSurface(surf, &dest, screen, &dest);
256   
257   if (update == UPDATE)
258     SDL_UpdateRect(screen, dest.x, dest.y, dest.w, dest.h);
259 }
260
261
262 /* --- ERASE CENTERED TEXT: --- */
263
264 void erasecenteredtext(char * text, int y, SDL_Surface * surf, int update, int shadowsize)
265 {
266   erasetext(text, 320 - (strlen(text) * 8), y, surf, update, shadowsize);
267 }