1 #include "bumprace.h"
2 #include "SDL_image.h"
3 #include <stdlib.h>
4 #include <string.h>
5
6 #define PATHNUM 8
7 #define BPP 0
8 #define RECTS_NUM 40000
9 #ifndef DATADIR
10 #define DATADIR "BumpRace.app/Contents/Resources/data"
11 #endif
12 char DATAPATH[200]=DATADIR;
13 const char PATH[PATHNUM][200]={DATADIR,".","data","/usr/local/share/bumprace"
14 ,"/usr/lib/bumprace","../data","/usr/share/bumprace", DATADIR};
15 SDL_Surface *Screen,*BackBuffer,*fadebuffer;
16 SDL_Rect blitrect,blitrects[RECTS_NUM];
17 int blitrects_num=0;
18 #ifdef DATADIR
ComplainAndExit(void)19 void ComplainAndExit(void)
20 {
21 fprintf(stderr, "Problem: %s\n", SDL_GetError());
22 exit(1);
23 }
24 #endif
abrand(int a,int b)25 int abrand(int a,int b) //random number between a and b (inclusive)
26 {
27 return(a+(rand() % (b-a+1)));
28 }
29
30 int (*_PutPixel)(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color);
31
fast_putpixel1(SDL_Surface * Surface,Sint32 X,Sint32 Y,Uint32 Color)32 int fast_putpixel1(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
33 {
34 if (X < 0 || X > Surface->w || Y < 0 || Y > Surface->h)
35 return -1;
36
37 *((Uint8 *)Surface->pixels + Y * Surface->pitch + X) = Color;
38
39 return 0;
40 }
41
fast_putpixel2(SDL_Surface * Surface,Sint32 X,Sint32 Y,Uint32 Color)42 int fast_putpixel2(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
43 {
44 if (X < 0 || X > Surface->w || Y < 0 || Y > Surface->h)
45 return -1;
46
47 *((Uint16 *)Surface->pixels + Y * Surface->pitch/2 + X) = Color;
48
49 return 0;
50 }
51
fast_putpixel3(SDL_Surface * Surface,Sint32 X,Sint32 Y,Uint32 Color)52 int fast_putpixel3(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
53 {
54 Uint8 *pix;
55 int shift;
56
57 if (X < 0 || X > Surface->w || Y < 0 || Y > Surface->h)
58 return -1;
59
60 /* Gack - slow, but endian correct */
61 pix = (Uint8 *)Surface->pixels + Y * Surface->pitch + X*3;
62 shift = Surface->format->Rshift;
63 *(pix+shift/8) = Color>>shift;
64 shift = Surface->format->Gshift;
65 *(pix+shift/8) = Color>>shift;
66 shift = Surface->format->Bshift;
67 *(pix+shift/8) = Color>>shift;
68
69 return 0;
70 }
71
fast_putpixel4(SDL_Surface * Surface,Sint32 X,Sint32 Y,Uint32 Color)72 int fast_putpixel4(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
73 {
74 if (X < 0 || X > Surface->w || Y < 0 || Y > Surface->h)
75 return -1;
76
77 *((Uint32 *)Surface->pixels + Y * Surface->pitch/4 + X) = Color;
78
79 return 0;
80 }
81
init_SDL()82 void init_SDL() // sets the video mode
83 {
84 int bpp=BPP;
85 const SDL_VideoInfo *info;
86
87 if ( SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER|SDL_INIT_AUDIO) < 0 ) {ComplainAndExit();}
88 info = SDL_GetVideoInfo();
89 if (info->vfmt->BitsPerPixel==8) bpp=16;
90 atexit(SDL_Quit);
91 // Set the video mode (800x600 at 16-bit depth)
92 if (fullscreen)
93 Screen = SDL_SetVideoMode(800, 600, BPP, SDL_FULLSCREEN);
94 else
95 { Screen = SDL_SetVideoMode(800, 600, BPP, 0); }
96 if ( Screen == NULL ) {ComplainAndExit();}
97 // create BackBuffer
98 BackBuffer = SDL_AllocSurface(Screen->flags,
99 800,
100 600,
101 Screen->format->BitsPerPixel,
102 Screen->format->Rmask,
103 Screen->format->Gmask,
104 Screen->format->Bmask, 0);
105 if (BackBuffer == NULL)
106 printf("ERROR: Couldn't create BackBuffer: %s\n", SDL_GetError());
107 fadebuffer = SDL_AllocSurface(Screen->flags,
108 800,
109 600,
110 Screen->format->BitsPerPixel,
111 Screen->format->Rmask,
112 Screen->format->Gmask,
113 Screen->format->Bmask, 0);
114 if (fadebuffer == NULL)
115 printf("ERROR: Couldn't create fadebuffer: %s\n", SDL_GetError());
116 // Figure out what putpixel routine to use
117 switch (Screen->format->BytesPerPixel)
118 {
119 case 1:
120 _PutPixel = fast_putpixel1;
121 break;
122 case 2:
123 _PutPixel = fast_putpixel2;
124 break;
125 case 3:
126 _PutPixel = fast_putpixel3;
127 break;
128 case 4:
129 _PutPixel = fast_putpixel4;
130 break;
131 }
132 }
133
lock()134 void lock()
135 {
136 if ( SDL_MUSTLOCK(Screen) ) {
137 if ( SDL_LockSurface(Screen) < 0 )
138 return; }
139 }
140
unlock()141 void unlock()
142 {
143 if ( SDL_MUSTLOCK(Screen) ) {
144 SDL_UnlockSurface(Screen); }
145 }
146
147 // Performs Callback at each line point. This came straight from the
148 // asphyxia vga trainers
DoLine(SDL_Surface * Surface,Sint32 X1,Sint32 Y1,Sint32 X2,Sint32 Y2,Uint32 Color,int Callback (SDL_Surface * Surf,Sint32 X,Sint32 Y,Uint32 Color))149 int DoLine (SDL_Surface *Surface, Sint32 X1, Sint32 Y1, Sint32 X2, Sint32 Y2, Uint32 Color, int Callback (SDL_Surface *Surf, Sint32 X, Sint32 Y, Uint32 Color))
150 {
151 Sint32 dx, dy, sdx, sdy, x, y, px, py;
152
153 dx = X2 - X1;
154 dy = Y2 - Y1;
155
156 sdx = (dx < 0) ? -1 : 1;
157 sdy = (dy < 0) ? -1 : 1;
158
159 dx = sdx * dx + 1;
160 dy = sdy * dy + 1;
161
162 x = y = 0;
163
164 px = X1;
165 py = Y1;
166
167 if (dx >= dy)
168 {
169 for (x = 0; x < dx; x++)
170 {
171 Callback(Surface, px, py, Color);
172
173 y += dy;
174 if (y >= dx)
175 {
176 y -= dx;
177 py += sdy;
178 }
179 px += sdx;
180 }
181 }
182 else
183 {
184 for (y = 0; y < dy; y++)
185 {
186
187 Callback(Surface, px, py, Color);
188
189 x += dx;
190 if (x >= dy)
191 {
192 x -= dy;
193 px += sdx;
194 }
195 py += sdy;
196 }
197 }
198 return 0;
199 }
200
fadeout()201 void fadeout()
202 {
203 int y;
204 SDL_Rect rect;
205 Uint32 time;
206
207 rect.x = 0;
208 rect.w = 800;
209 rect.h = 1;
210 for (y=0; y<600; y+=2) {
211 time = SDL_GetTicks();
212 rect.y = y;
213 SDL_FillRect(Screen, &rect, SDL_MapRGB(Screen->format, 0,0,0));
214 SDL_UpdateRects(Screen, 1, &rect);
215 if (time == SDL_GetTicks())
216 SDL_Delay(1);
217 }
218 for (y=599; y>0; y-=2) {
219 rect.y = y;
220 SDL_FillRect(Screen, &rect, SDL_MapRGB(Screen->format, 0,0,0));
221 SDL_UpdateRects(Screen, 1, &rect);
222 }
223
224 /*
225 int x,y;
226
227 if (dofadeout==0) return;
228
229 for (x=0;x<800;x++)
230 {
231 lock();
232 for (y=0;y<300;y++)
233 {
234 PutPixel(Screen,x,y*2,SDL_MapRGB(Screen->format,0,0,0));
235 }
236 unlock();
237 Update();
238 }
239 for (x=799;x>=0;x--)
240 {
241 lock();
242 for (y=299;y>0;y--)
243 {
244 PutPixel(Screen,x,y*2+1,SDL_MapRGB(Screen->format,0,0,0));
245 }
246 unlock();
247 Update();
248 }*/
249 }
250
Update()251 void Update()
252 {
253 SDL_UpdateRects(Screen,blitrects_num,blitrects);
254 blitrects_num=0;
255 }
256
AddRect(int x1,int y1,int x2,int y2)257 void AddRect(int x1, int y1, int x2, int y2)
258 {
259 int temp;
260
261 /* Make sure X1 is before X2 */
262 if (x2 < x1){
263 temp = x2;
264 x2 = x1;
265 x1 = temp;
266 }
267 /* Make sure Y1 is before Y2 */
268 if (y2 < y1){
269 temp = y2;
270 y2 = y1;
271 y1 = temp;
272 }
273 blitrect.x = x1;
274 blitrect.y = y1;
275 blitrect.w = x2-x1+1;
276 blitrect.h = y2-y1+1;
277 if (x1<0) printf("x is too small in function AddRect! - %d\n",x1);else
278 if (y1<0) printf("y is too small in function AddRect! - %d\n",y1);else
279 if (x2>=800) printf("x is too big in function AddRect! - %d\n",x2);else
280 if (y2>=600) printf("y is too big in function AddRect! - %d\n",y2);else {
281 blitrects[blitrects_num]=blitrect;
282 if (++blitrects_num>=RECTS_NUM-2)
283 {printf("Too many blits!\n");blitrects_num--;Update();}
284 }
285 }
286
AddThisRect(SDL_Rect blitrect)287 void AddThisRect(SDL_Rect blitrect)
288 {
289 blitrects[blitrects_num]=blitrect;
290 if (++blitrects_num>=RECTS_NUM-2)
291 {printf("Too many blits!\n");blitrects_num--;Update();}
292 }
293
Blit(int Xpos,int Ypos,SDL_Surface * image)294 void Blit(int Xpos,int Ypos,SDL_Surface *image) //blits one GIF or BMP from the memory to the screen
295 {
296 blitrect.x = Xpos;
297 blitrect.y = Ypos;
298 blitrect.w = image->w;
299 blitrect.h = image->h;
300
301 if (Xpos<-image->w) printf("WRONG BLIT: Xpos is too small! - %d\n",Xpos); else
302 if (Xpos>=800) printf("WRONG BLIT: Xpos is too big! - %d\n",Xpos); else
303 if (Ypos<-image->h) printf("WRONG BLIT: Ypos is too small! - %d\n",Ypos); else
304 if (Ypos>=600) printf("WRONG BLIT: Ypos is too big! - %d\n",Ypos); else
305 if ( SDL_BlitSurface(image, NULL, Screen, &blitrect) < 0 )
306 {
307 SDL_FreeSurface(image);
308 ComplainAndExit();
309 }
310 blitrects[blitrects_num]=blitrect;
311 blitrects_num++;
312 }
313
LoadImage(char * datafile,int transparent)314 SDL_Surface *LoadImage(char *datafile, int transparent) // reads one png into the memory
315 {
316 SDL_Surface *pic,*pic2;
317 char filename[200];
318 int i=0;
319
320 sprintf(filename,"%s/gfx/%s",DATAPATH,datafile);
321 pic=IMG_Load(filename);
322 while ( pic == NULL ) {
323 strcpy(DATAPATH,PATH[i]);
324 sprintf(filename,"%s/gfx/%s",DATAPATH,datafile);
325 pic=IMG_Load(filename);
326 i++;
327
328 if (i>=PATHNUM)
329 {
330 fprintf(stderr,"Couldn't load %s: %s\n", filename, SDL_GetError());
331 exit(2);
332 }
333 }
334 if (transparent==3) return(pic);
335 if (transparent==1)
336 SDL_SetColorKey(pic,SDL_SRCCOLORKEY|SDL_RLEACCEL,SDL_MapRGB(pic->format,0xFF,0xFF,0xFF));
337 if (transparent==2)
338 SDL_SetColorKey(pic,SDL_SRCCOLORKEY|SDL_RLEACCEL,SDL_MapRGB(pic->format,0x00,0x00,0x00));
339 pic2 = SDL_DisplayFormat(pic);
340 SDL_FreeSurface(pic);
341 // blit(0,0,pic2);
342 // SDL_UpdateRect(screen,0,0,0,0);
343 return (pic2);
344 }
345
BlitToBB(int Xpos,int Ypos,SDL_Surface * image)346 void BlitToBB(int Xpos,int Ypos,SDL_Surface *image) //blits one GIF or BMP from the memory to the screen
347 {
348 blitrect.x = Xpos;
349 blitrect.y = Ypos;
350 blitrect.w = image->w;
351 blitrect.h = image->h;
352 if ( SDL_BlitSurface(image, NULL, BackBuffer, &blitrect) < 0 )
353 {
354 SDL_FreeSurface(image);
355 ComplainAndExit();
356 }
357 }
358
BlitPart(int Xpos,int Ypos,SDL_Surface * image,SDL_Rect srcrect)359 void BlitPart(int Xpos,int Ypos,SDL_Surface *image, SDL_Rect srcrect)
360 {
361 blitrect.x = srcrect.x;
362 blitrect.y = srcrect.y;
363 blitrect.w = srcrect.w;
364 blitrect.h = srcrect.h;
365 if ( SDL_BlitSurface(image, &srcrect , Screen, &blitrect) < 0 )
366 {
367 SDL_FreeSurface(image);
368 ComplainAndExit();
369 }
370 blitrects[blitrects_num]=blitrect;
371 blitrects_num++;
372 }
373
FadeScreen(float speed)374 void FadeScreen(float speed)
375 {
376 Sint32 now,i;
377
378 SDL_BlitSurface(Screen,NULL,fadebuffer,NULL);
379 now=SDL_GetTicks();
380 for (i=255*speed;i>=0;i-=SDL_GetTicks()-now)
381 {
382 now=SDL_GetTicks();
383 SDL_BlitSurface(fadebuffer,&blitrect,Screen,&blitrect);
384 SDL_SetAlpha(BackBuffer,SDL_SRCALPHA,255-(int)(i/speed));
385 Blit(0,0,BackBuffer);
386 Update();
387 }
388 SDL_SetAlpha(BackBuffer,SDL_SRCALPHA,255);
389 Blit(0,0,BackBuffer);
390 Update();
391 }
392
PutPixel(SDL_Surface * Surface,Sint32 X,Sint32 Y,Uint32 Color)393 int PutPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
394 {
395 if (X<0) printf("X < 0 in function PutPixel! - %d\n",X); else
396 if (X>=800) printf("X >= 800 in function PutPixel! - %d\n",X); else
397 if (Y<0) printf("Y < 0 in function PutPixel! - %d\n",Y); else
398 if (Y>=600) printf("Y >= 600 in function PutPixel! - %d\n",Y); else
399 {
400 _PutPixel(Surface,X,Y,Color);
401 AddRect(X,Y,X,Y);
402 }
403 return 0;
404 }
405
PutPixelC(SDL_Surface * Surface,Sint32 X,Sint32 Y,Uint32 Color)406 int PutPixelC(SDL_Surface *Surface, Sint32 X, Sint32 Y, Uint32 Color)
407 {
408 if (X<0) printf("X < 0 in function PutPixelC! - %d\n",X); else
409 if (X>=800) printf("X >= 800 in function PutPixelC! - %d\n",X); else
410 if (Y<0) printf("Y < 0 in function PutPixelC! - %d\n",Y); else
411 if (Y>=600) printf("Y >= 600 in function PutPixelC! - %d\n",Y); else
412 {
413 _PutPixel(Surface,X,Y,Color);
414 AddRect(X,Y,X,Y);
415 }
416 return 0;
417 }
418
PutBackPixel(SDL_Surface * Surface,Sint32 X,Sint32 Y)419 void PutBackPixel(SDL_Surface *Surface, Sint32 X, Sint32 Y)
420 {
421 SDL_Rect rect;
422
423 rect.w=1;
424 rect.h=1;
425 rect.x=X;
426 rect.y=Y;
427 SDL_BlitSurface(BackBuffer, &rect, Surface, &rect);
428 AddThisRect(rect);
429 }
430