~ubuntu-branches/ubuntu/utopic/bumprace/utopic

« back to all changes in this revision

Viewing changes to src/gfx.c

  • Committer: Bazaar Package Importer
  • Author(s): Christian T. Steigies
  • Date: 2002-04-13 17:39:40 UTC
  • Revision ID: james.westby@ubuntu.com-20020413173940-n9k99o4wvsw4ztkp
Tags: upstream-1.4.5
ImportĀ upstreamĀ versionĀ 1.4.5

Show diffs side-by-side

added added

removed removed

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