Annotation of froggix/src/froggix.c, revision 1.3
1.1 nick 1: /*
2: * Froggix
3: *
4: * Nicholas DeClario 2009
5: * <nick@declario.com>
6: *
7: * This program is distributed under the GNU Public License
8: * <Insert GNU license blurb here>
9: */
10:
11:
12: /*
13: * Our pretty standard includes
14: */
15: #include <stdio.h>
16: #include <stdlib.h>
17: #include <unistd.h>
18: #include <time.h>
19:
20: #include <SDL.h>
21: #include <SDL_mixer.h>
22: #include <SDL_image.h>
23: #include <SDL_ttf.h>
24:
25: /*
26: * Set some basic definitions
27: */
1.3 ! nick 28: #define VER "$Id: froggix.c,v 1.2 2009-04-03 02:48:21 nick Exp $"
1.1 nick 29: #define TITLE "Froggix"
30: #define SCREEN_WIDTH 640
31: #define SCREEN_HEIGHT 480
32: #define FALSE 0
33: #define TRUE 1
34: #define LIVES 3
35: #define COLORKEY 255, 0, 255
36: #define BGCOLOR 0, 0, 0
37: #define FROGGER_START_X 290
38: #define FROGGER_START_Y 425
39: #define UP 1
40: #define DOWN 2
41: #define LEFT 3
42: #define RIGHT 4
43: #define X 0
44: #define Y 1
45: #define FRAME 24
46: #define HFRAME 12
47: #define HOP_DISTANCE 30
48: #define HOP_SPEED 3
49: #define ROW_BASE 425
50: #define LEFT_SIDE 115
51: #define RIGHT_SIDE 525
52: #define SPLASH 1 /* Death types */
53: #define SPLAT 2
54:
55: /* Point table */
56: #define SCORE_HOP 10
57: #define SCORE_GOAL 50
58: #define SCORE_LEVEL 1000
59: #define SCORE_FLY 150
60: #define SCORE_PINK 200
61: #define SCORE_SECONDS 10
62: #define HIGH_SCORE 4630
63: #define SCORE_FREE_FROG 200
64:
65: /* The green game timer */
66: #define MAX_TIMER 350
67: #define TIMER_SIZE 150
68: #define TIMER_COLOR 32, 211, 0
69: #define TIMER_LOW_COLOR 255, 0, 0
1.3 ! nick 70: #define FLY_MAX_TIME 50
! 71: #define GATOR_MAX_TIME 60
1.1 nick 72:
73: /* baddies */
74: #define VEHICLE 0
75: #define LOG 1
76: #define TURTLE 2
77: #define GATOR 3
78: #define SNAKE 4
79: #define BEAVER 5
80:
81: /* Goal areas */
82: #define MAX_GOALS 5
83:
84: /* logs */
85: #define SHORT_LOG 4
86: #define MEDIUM_LOG 6
87: #define LONG_LOG 9
88: #define MAX_WOOD 7
89:
90: /* Turtles */
91: #define DIVE_START_TIME 50
92: #define DIVE_PHASE_TIME 20
93: #define MAX_TURTLES 9
94: #define TURTLE_ANIM_TIME 5
95:
96: /* Vehicles */
97: #define MAX_VEHICLES 40
98:
99:
100: /*
101: * Froggers dstruct
102: */
103: typedef struct {
104: int placement[2];
105: int oldPlacement[2];
106: int direction;
107: int location;
108: int hopCount;
109: int currentRow;
110: int alive;
111: int riding;
112: int ridingIdx;
113: int ridingType;
114: int frogger; /* Are we frogger or bonus frog */
115: int deathType;
116: int deathCount;
117:
118: SDL_Rect src;
119: SDL_Rect dst;
120:
121: Mix_Chunk *s_hop;
122: Mix_Chunk *s_squash;
123: Mix_Chunk *s_splash;
124: Mix_Chunk *s_extra;
125: } froggerObj;
126:
127: /*
128: * Goals
129: */
130: typedef struct {
131: int x, y, w, h;
132: int occupied;
133: int fly;
134: int gator;
135: } goalObj;
136:
137: /*
138: * Vehicles
139: */
140: typedef struct {
141: int placement[2];
142: int oldPlacement[2];
143: int direction; // LEFT or RIGHT
144: int row; // row
145: int speed; // How fast are we traveling
146: int level; // Must be >= this level to display
147:
148: SDL_Rect src;
149: } vehicleObj;
150:
151: /*
152: * It's Log!
153: */
154: typedef struct {
155: int placement[2];
156: int oldPlacement[2];
157: int row; /* Current row we are in */
158: int type; /* SHORT, MEDIUM, or LONG */
159: int speed; /* What speed does the log move at */
160: int hasPink; // Is bonus frog riding
161:
162: SDL_Rect src;
163: } logObj;
164:
165: /*
166: * Turtles
167: */
168: typedef struct {
169: int placement[2];
170: int oldPlacement[2];
171: int row; /* Which row are the turtles in? */
172: int count; /* How many turtles in this group? */
173: int speed; /* How fast are they swimming */
174: int canDive; /* Can this group dive */
175: int diveStep; /* If they can dive, what diving step are then in */
176: int diveTime; /* Current dive time */
177: int animStep; /* Current animation frame */
178: int animDelay; /* The number of ticks to wait between frames */
179:
180: SDL_Rect src;
181: } turtleObj;
182:
183: int keyEvents( SDL_Event event );
184: int mySDLInit( void );
185: void beginGame( void );
186: int loadMedia( void );
187: int heartbeat( void );
188: int updateGameState( void );
1.3 ! nick 189: int checkFly( void );
1.1 nick 190: void configGameScreen( void );
191: void drawGameScreen( void );
192: void drawBackground( void );
193: int getRowPixel ( int row );
194: int collisionRow ( void );
195: int freeFrog( int score );
196: int collideFrogger ( int x, int y, int h, int w );
197: void checkFroggerBorder( void );
198: void levelUp( void );
199: int checkGoals( void );
200: void froggerReset( void );
201: logObj setWood( int type, int speed, int row, int startX );
202: turtleObj setTurtle( int dive, int diveTimer, int speed, int row, int startX, int count );
203: vehicleObj setVehicle( int row, int startX, int speed, int level );
204: goalObj setGoal( int x, int y, int w, int h );
205: void moveFrogger( void );
206: void ridingFrogger( );
207: void drawTitleScreen( void );
208: void drawPauseScreen( void );
209: void drawGameOver( void );
210: int drawDeathSequence( int deathType );
211: int checkTimer( void );
212: void drawScore( int high, int score );
213: void drawNumbers( int num, int x, int y );
214: void drawGoals( void );
215: void drawTimer( int length );
216: void drawLives( int lives );
217: void drawLevel( int level );
218: void drawWood( void );
219: void drawTurtles( void );
220: void drawVehicles( void );
221: void drawImage(SDL_Surface *srcimg, int sx, int sy, int sw, int sh, SDL_Surface *dstimg, int dx, int dy, int alpha );
222: void playSound( Mix_Chunk *sound );
223: void setFullScreenMode( void );
224:
1.3 ! nick 225: int flyTimer = 0;
1.1 nick 226: int level = 0;
227: int playing = 0;
228: int lives = 0;
229: int players = 0;
230: int score = 0;
231: int givenFreeFrog = 0;
232: int hScore = HIGH_SCORE;
233: int redraw_all = 0;
234: int fullscreen = 0;
235: int drawBG = 0;
236: int goDelay;
237: float timeLeft;
238: froggerObj frogger;
239: logObj wood[MAX_WOOD];
240: turtleObj turtle[MAX_TURTLES];
241: vehicleObj vehicle[MAX_VEHICLES];
242: goalObj goals[MAX_GOALS];
243:
244: Mix_Chunk *s_freeFrog;
245: SDL_Surface *gfx;
246: SDL_Surface *background; // This is the frogger back drop
247: SDL_Rect backgroundRect;
248: SDL_Surface *titleSurface; // Title 'Froggix' image
249: SDL_Surface *screen; //This pointer will reference the backbuffer
250: SDL_Rect leftBorderRect;
251: SDL_Rect rightBorderRect;
252: TTF_Font *font;
253:
254: int debugBorder = 0;
255:
256: /*
257: * int mySDLInit(void);
258: *
259: * This starts the basic SDL initialization for everything we'll need
260: *
261: */
262: int mySDLInit( void ) {
263: int result = 1;
264:
265: if( SDL_Init( SDL_INIT_VIDEO ) != 0 ) {
266: fprintf( stderr, "Warning: Unable to initialize video: %s\n", SDL_GetError( ) );
267: result--;
268: }
269:
270: if( TTF_Init( ) == -1 ) {
271: fprintf( stderr, "Warning: Unable to initialize font engine: %s\n", TTF_GetError( ) );
272: result--;
273: }
274:
275: if( SDL_Init( SDL_INIT_AUDIO ) != 0 ) {
276: fprintf( stderr, "Warning: Unable to initialize audio: %s\n", SDL_GetError( ) );
277: result--;
278: }
279:
280: if( Mix_OpenAudio( 11025, AUDIO_S16, 2, 512 ) < 0 ) {
281: fprintf( stderr, "Warning: Audio set failed: %s\n", SDL_GetError( ) );
282: result--;
283: }
284:
285: screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 16, SDL_HWSURFACE );
286:
287: if ( screen == NULL ) {
288: fprintf( stderr, "Error: Unable to set video mode: %s\n", SDL_GetError( ) );
289: result--;
290: }
291:
292: SDL_WM_SetCaption( TITLE, NULL );
293:
294: return result;
295: }
296:
297: /*
298: * void beginGame( void );
299: *
300: * Main game routine
301: */
302: void beginGame( void ) {
303: float next_heartbeat = 0;
304: SDL_Event event;
305: int done = 0;
306:
307: printf ( "D: Starting main game loop\n" );
308:
309: if ( loadMedia( ) <= 0 ) {
310: fprintf( stderr, "Error: Failed to load graphics and audio!\n" );
311: return;
312: }
313:
314: drawBackground( );
315:
316: while( ! done ) {
317: while( SDL_PollEvent( &event ) ) {
318: done = keyEvents( event );
319: }
320:
321: /* Check the heartbeat to see if we're ready */
322: if ( SDL_GetTicks( ) >= next_heartbeat ) {
323: next_heartbeat = SDL_GetTicks( ) + heartbeat( );
324: }
325: SDL_Delay( 30 );
326: }
327:
328: SDL_FreeSurface( gfx );
329: }
330:
331: int loadMedia( void ) {
332: int result = 1;
333:
334: /*
335: * Load frogger's textures and sounds
336: */
337: gfx = IMG_Load( "images/frogger.png" );
1.2 nick 338: frogger.riding = FALSE;
1.1 nick 339:
340: if ( gfx == NULL ) {
341: fprintf( stderr, "Error: 'images/frogger.bmp' could not be open: %s\n", SDL_GetError( ) );
342: result--;
343: }
344:
345: if ( SDL_SetColorKey( gfx, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB( gfx->format, COLORKEY ) ) == -1 )
346: fprintf( stderr, "Warning: colorkey will not be used, reason: %s\n", SDL_GetError( ) );
347:
348: background = IMG_Load( "images/gameboard.png" );
349:
350: if ( gfx == NULL ) {
351: fprintf( stderr, "Error: 'images/gameboard.png' could not be open: %s\n", SDL_GetError( ) );
352: result--;
353: }
354:
355: titleSurface = IMG_Load( "images/froggix-title.png" );
356: if ( titleSurface == NULL ) {
357: fprintf( stderr, "Error: 'images/froggix-title.png' could not be open: %s\n", SDL_GetError( ) );
358: result--;
359: }
360:
361: font = TTF_OpenFont( "fonts/CourierNew-Bold.ttf", 22 );
362: if ( font == NULL ) {
363: printf( "TTF_OpenFont: %s\n", TTF_GetError( ) );
364: result--;
365: }
366:
367: frogger.s_hop = Mix_LoadWAV( "sounds/froggix-hop.wav" );
368:
369: if ( frogger.s_hop == NULL )
370: fprintf( stderr, "Warning: dp_frogger_hop.wav could not be opened: %s\n", SDL_GetError( ) );
371:
372: frogger.s_squash = Mix_LoadWAV( "sounds/dp_frogger_squash.wav" );
373: if ( frogger.s_squash == NULL )
374: fprintf( stderr, "Warning: dp_frogger_plunk could not be opened %s\n", SDL_GetError( ));
375:
376: frogger.s_splash = Mix_LoadWAV( "sounds/dp_frogger_plunk.wav" );
377: if ( frogger.s_splash == NULL )
378: fprintf( stderr, "Warning: dp_frogger_splash could not be opened %s\n", SDL_GetError( ));
379:
380: s_freeFrog = Mix_LoadWAV( "sounds/dp_frogger_extra.wav" );
381: if ( s_freeFrog == NULL )
382: fprintf( stderr, "Warning: dp_frogger_extra could not be opened %s\n", SDL_GetError( ));
383:
384: return result;
385: }
386:
387: /*
388: * void keyEvents( void );
389: *
390: * Process the incoming keyboard and mouse events
391: *
392: */
393: int keyEvents( SDL_Event event ) {
394: int done = 0;
395:
396: /* Always check for shutdown */
397: switch( event.type ) {
398: case SDL_QUIT:
399: done = 1;
400: break;
401: case SDL_KEYDOWN:
402: /* printf( "Found key: %i\n", event.key.keysym.sym );*/
403: switch( event.key.keysym.sym ) {
404: case SDLK_ESCAPE:
405: done = 1;
406: break;
407: case 102:
408: setFullScreenMode( );
409: break;
410: default:
411: break;
412: }
413: break;
414: default:
415: break;
416: }
417: /* We are playing the game */
418: if ( level ) {
419: /* Main game playing input */
420: if ( playing ) {
421: if ( event.type == SDL_KEYDOWN && frogger.alive ) {
422: switch( event.key.keysym.sym ) {
423: case SDLK_UP:
424: if ( ! frogger.direction ) {
425: frogger.hopCount = 0;
426: frogger.direction = UP;
427: frogger.currentRow++;
428: playSound( frogger.s_hop );
429: }
430: break;
431: case SDLK_DOWN:
432: if ( ! frogger.direction ) {
433: frogger.hopCount = 0;
434: frogger.direction = DOWN;
435: frogger.currentRow--;
436: playSound( frogger.s_hop );
437: }
438: break;
439: case SDLK_LEFT:
440: if ( ! frogger.direction ) {
441: frogger.hopCount = 0;
442: frogger.direction = LEFT;
443: playSound( frogger.s_hop );
444: }
445: break;
446: case SDLK_RIGHT:
447: if ( ! frogger.direction ) {
448: frogger.hopCount = 0;
449: frogger.direction = RIGHT;
450: playSound( frogger.s_hop );
451: }
452: break;
453: case 108:
454: levelUp( );
455: fprintf( stderr, "Increase level to %i.\n", level );
456: break;
457: default:
458: break;
459: }
1.3 ! nick 460: /* Uncomment for positioning debug information
1.1 nick 461: printf( "x,y,d => %i,%i,%i,%i\n", frogger.placement[X],
462: frogger.placement[Y],
463: frogger.direction,
464: frogger.currentRow );
1.3 ! nick 465: */
1.1 nick 466: }
467: /* Game over man, game over! */
468: if ( ! lives ) {
469:
470: }
471: }
472: /* we're at the pause screen */
473: else {
474:
475: }
476: }
477: /* Main intro screen input */
478: else {
479: if ( event.type == SDL_KEYUP ) {
480: switch( event.key.keysym.sym ) {
481: case SDLK_ESCAPE:
482: done = 1;
483: break;
484: case SDLK_1:
485: printf( "D: Starting single player game\n" );
486: level = 1;
487: lives = LIVES;
488: playing = TRUE;
489: score = 0;
490: players = 1;
491: redraw_all = 1;
492: break;
493: default:
494: break;
495: }
496: }
497: }
498:
499: return done;
500: }
501:
502: int updateGameState( void ) {
1.2 nick 503: int i;
504:
1.1 nick 505: if ( ! drawBG ) configGameScreen( );
506:
507: if ( lives <= 0 ) {
508: goDelay++;
509: drawGameOver( );
510: /* Display game over screen for 50 ticks before returning
511: * to the main screen */
512: if ( goDelay > 7 ) {
513: playing = 0;
514: lives = 0;
515: level = 0;
1.2 nick 516: score = 0;
517: givenFreeFrog = 0;
518: drawBG = 0;
519: for ( i = 0; i < MAX_GOALS; i++ ) { goals[i].occupied = 0; }
520:
1.1 nick 521: }
522: return 500;
523: }
524:
525: drawGameScreen( );
526:
527: return 50;
528: }
529:
530: logObj setWood( int type, int speed, int row, int startX ) {
531: logObj tempWood;
532: int imgPixelSrc = 0;
533:
534: switch( type ) {
535: case LONG_LOG:
536: imgPixelSrc = 0;
537: break;
538: case MEDIUM_LOG:
539: imgPixelSrc = FRAME * LONG_LOG;
540: break;
541: case SHORT_LOG:
542: imgPixelSrc = FRAME * ( LONG_LOG + MEDIUM_LOG );
543: break;
544: }
545:
546: tempWood.row = row;
547: tempWood.type = type;
548: tempWood.speed = speed;
549: tempWood.hasPink = 0;
550: tempWood.placement[X] = LEFT_SIDE + startX;
551: tempWood.placement[Y] = getRowPixel( row );
552: tempWood.oldPlacement[X] = LEFT_SIDE + startX;
553: tempWood.oldPlacement[Y] = getRowPixel( row );
554: tempWood.src.y = FRAME;
555: tempWood.src.x = imgPixelSrc;
556: tempWood.src.w = FRAME * tempWood.type;
557: tempWood.src.h = FRAME;
558:
559: return tempWood;
560: }
561:
562: turtleObj setTurtle( int dive, int diveTimer, int speed, int row, int startX, int count ) {
563: turtleObj tt;
564:
565: tt.row = row;
566: tt.canDive = dive;
567: tt.diveStep = 0;
568: tt.diveTime = diveTimer;
569: tt.animStep = 0;
570: tt.animDelay = 0;
571: tt.speed = speed;
572: tt.count = count;
573: tt.placement[X] = LEFT_SIDE + startX;
574: tt.placement[Y] = getRowPixel( row );
575: tt.oldPlacement[X] = tt.placement[X];
576: tt.oldPlacement[Y] = tt.placement[Y];
577: tt.src.y = FRAME * 2;
578: tt.src.x = 0;
579: tt.src.w = FRAME;
580: tt.src.h = FRAME;
581:
582: return tt;
583: }
584:
585:
586: vehicleObj setVehicle( int row, int startX, int speed, int level ) {
587: vehicleObj v;
588:
589: v.direction = ( row % 2 ) ? LEFT : RIGHT; /* Odd rows travel left, evens go right */
590: v.row = row;
591: v.speed = speed;
592: v.level = level;
593: v.placement[X] = LEFT_SIDE + startX;
594: v.placement[Y] = getRowPixel( row );
595: v.oldPlacement[X] = v.placement[X];
596: v.oldPlacement[Y] = v.placement[Y];
597: v.src.y = FRAME * 2;
598: v.src.x = FRAME * ( 4 + row );
599: v.src.w = ( row == 5 ) ? FRAME * 2 : FRAME; /* Are we a truck? */
600: v.src.h = FRAME;
601:
602: return v;
603: }
604:
605: goalObj setGoals( int x, int y, int w, int h ) {
606: goalObj g;
607:
608: g.x = x;
609: g.y = y;
610: g.w = w;
611: g.h = h;
612: g.occupied = 0;
613: g.fly = 0;
614: g.gator = 0;
615:
616: return g;
617: }
618:
619: void configGameScreen( void ) {
620: drawBG = 1;
621:
622: /*
623: * Draw background map
624: */
625: //drawBackground( );
626: drawImage( background, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, screen, 0, 0, 255 );
627:
628: /* Cars drive on rows 1 - 5
629: * Logs are on rows 8, 9 and 11, 8 = short, 9 long, 11 medium
630: * Turtles are on rows 7, 10
631: * Frogger starts on Row 0,
632: * Sidewalk is row 6
633: * and the goal is row 12
634: */
635:
636: /* I MUST figure out a better way to handle the logs, turtles and cars */
637:
638: /* Set up the LONG logs on row 9 first */
639: wood[0] = setWood( LONG_LOG, 3, 9, 0 );
640: wood[1] = setWood( LONG_LOG, 3, 9, 305 );
641: wood[2] = setWood( SHORT_LOG, 2, 8, 25 );
642: wood[3] = setWood( SHORT_LOG, 2, 8, 160 );
643: wood[4] = setWood( SHORT_LOG, 2, 8, 380 );
644: wood[5] = setWood( MEDIUM_LOG, 4, 11, 140 );
645: wood[6] = setWood( MEDIUM_LOG, 4, 11, 440 );
646:
647: drawWood( );
648:
649: /* Configure our turtles */
650: turtle[0] = setTurtle( FALSE, 0, 1, 7, 0, 3 );
651: turtle[1] = setTurtle( TRUE, 0, 1, 7, 125, 3 );
652: turtle[2] = setTurtle( FALSE, 0, 1, 7, 250, 3 );
653: turtle[3] = setTurtle( TRUE, 30, 1, 7, 375, 3 );
654: turtle[4] = setTurtle( FALSE, 0, 2, 10, 100, 2 );
655: turtle[5] = setTurtle( TRUE, 50, 2, 10, 200, 2 );
656: turtle[6] = setTurtle( FALSE, 0, 2, 10, 300, 2 );
657: turtle[7] = setTurtle( TRUE, 10, 2, 10, 400, 2 );
658: turtle[8] = setTurtle( FALSE, 0, 2, 10, 500, 2 );
659:
660: drawTurtles( );
661:
662: /* Configure vehicles */
663: /* row, X, speed */
664: /* Row 1 -- yellow car */
665: vehicle[0] = setVehicle( 1, 0, 1, 1 );
666: vehicle[1] = setVehicle( 1, 100, 1, 3 );
667: vehicle[2] = setVehicle( 1, 200, 1, 1 );
668: vehicle[3] = setVehicle( 1, 300, 1, 1 );
669: // /* Row 2 -- tractor */
670: vehicle[4] = setVehicle( 2, 0, 3, 1 );
671: vehicle[5] = setVehicle( 2, 100, 3, 2 );
672: vehicle[6] = setVehicle( 2, 200, 3, 1 );
673: vehicle[7] = setVehicle( 2, 300, 3, 3 );
674: // /* Row 3 -- pink car */
675: vehicle[8] = setVehicle( 3, 75, 2,1 );
676: vehicle[9] = setVehicle( 3, 150, 2, 3 );
677: vehicle[10] = setVehicle( 3, 225, 2, 1 );
678: vehicle[11] = setVehicle( 3, 375, 2, 2 );
679: // /* Row 4 -- white car */
680: vehicle[12] = setVehicle( 4, 75, 5, 1 );
681: vehicle[13] = setVehicle( 4, 150, 5, 3 );
682: vehicle[14] = setVehicle( 4, 225, 5, 2 );
683: vehicle[15] = setVehicle( 4, 375, 5, 3 );
684: // /* Row 5 -- Trucks */
685: vehicle[16] = setVehicle( 5, 30, 3, 1 );
686: vehicle[17] = setVehicle( 5, 150, 3, 1 );
687: vehicle[18] = setVehicle( 5, 250, 3, 1 );
688: vehicle[19] = setVehicle( 5, 350, 3, 3 );
689:
690: drawVehicles( );
691:
692: /* Configure the goals for frogger */
693: goals[0] = setGoals( LEFT_SIDE + 3, 55, 43, 35 );
694: goals[1] = setGoals( LEFT_SIDE + 91, 55, 43, 35 );
695: goals[2] = setGoals( LEFT_SIDE + 179, 55, 43, 35 );
696: goals[3] = setGoals( LEFT_SIDE + 267, 55, 43, 35 );
697: goals[4] = setGoals( LEFT_SIDE + 355, 55, 43, 35 );
698:
699: /*
700: * Configure the left and right side black borders to conceal logs,
701: * turtles, cars, etc. that go past their boundries
702: */
703: leftBorderRect.x = 0;
704: leftBorderRect.y = 0;
705: leftBorderRect.w = LEFT_SIDE;
706: leftBorderRect.h = SCREEN_HEIGHT;
707:
708: rightBorderRect.x = RIGHT_SIDE;
709: rightBorderRect.y = 0;
710: rightBorderRect.w = SCREEN_WIDTH - RIGHT_SIDE;
711: rightBorderRect.h = SCREEN_HEIGHT;
712:
1.3 ! nick 713: /*
! 714: * We reset the flyTimer since this may not be the first game played
! 715: */
! 716: flyTimer = 0;
1.1 nick 717:
718: /*
719: * Draw frogger in starting position
720: */
721: froggerReset( );
722: }
723:
724: void drawGameScreen( void ) {
725: /*
726: * Update frogger
727: */
728: if ( frogger.direction ) moveFrogger( );
729: if ( frogger.riding ) ridingFrogger( );
730:
731: /* Check for collisions with frogger */
732: if ( frogger.alive ) {
733: if ( frogger.currentRow > 6 && frogger.currentRow < 12 ) {
734: if ( ( ! collisionRow( ) ) || ( frogger.riding == FALSE ) ) {
735: playSound( frogger.s_splash );
736: frogger.deathType = SPLASH;
737: fprintf( stderr, "D: Frog in water!!\n" );
738: frogger.alive = FALSE;
739: }
740: }
741: else if ( frogger.currentRow == 12 ) {
742: if ( collisionRow( ) ) {
743: playSound( frogger.s_squash );
744: frogger.deathType = SPLAT;
745: fprintf( stderr, "D: Frog in thorn bushes!\n" );
746: frogger.alive = FALSE;
747: }
748: }
749: else if( collisionRow( ) ) {
750: playSound( frogger.s_squash );
751: frogger.deathType = SPLAT;
752: fprintf( stderr, "D: Frog Squashed!\n" );
753: frogger.alive = FALSE;
754: }
755: }
756:
757: /*
758: * Update and draw everthing else
759: */
1.3 ! nick 760: checkFly( );
1.1 nick 761: drawImage( background, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, screen, 0, 0, 255 );
762: drawScore( 0, score );
763: drawScore( 1, hScore );
764: drawGoals( );
765: drawLives( lives );
766: drawLevel( level );
767: drawWood( );
768: drawTurtles( );
769: drawVehicles( );
770:
771: if ( frogger.alive == FALSE ) {
1.2 nick 772: frogger.riding = FALSE;
1.1 nick 773: if ( ! drawDeathSequence( frogger.deathType ) ) {
774: lives--;
775: if ( lives < 0 ) { drawGameOver( ); }
776: else { froggerReset( ); }
777: }
778: }
779:
780: if ( frogger.alive ) {
781: frogger.alive = checkTimer( );
782: drawImage( gfx, frogger.src.x, frogger.src.y, frogger.src.w,
783: frogger.src.h, screen, frogger.dst.x, frogger.dst.y, 255 );
784: }
785: if ( ! debugBorder ) {
786: SDL_FillRect( screen, &leftBorderRect, SDL_MapRGB( screen->format, BGCOLOR ) );
787: SDL_FillRect( screen, &rightBorderRect, SDL_MapRGB( screen->format, BGCOLOR ) );
788: }
789:
790: SDL_Flip( screen );
791: }
792:
793: void drawBackground( void ) {
794: /*
795: * Draw background map
796: */
797: backgroundRect.x = 0;
798: backgroundRect.y = 0;
799: SDL_BlitSurface( background, NULL, screen, &backgroundRect );
800: SDL_UpdateRect( screen, 0, 0, 0, 0 );
801: }
802:
803: /*
804: * This calculates the pixel top of the requested row
805: */
806: int getRowPixel ( int row ) {
807: return ROW_BASE - ( row * HOP_DISTANCE );
808: }
809:
810: /*
1.3 ! nick 811: * Check our fly timers to determine if we need to display or
! 812: * remove a fly from the goal area
! 813: */
! 814: int checkFly ( void ) {
! 815: int i;
! 816:
! 817: for ( i = 0; i < MAX_GOALS; i++ ) {
! 818: if ( goals[i].fly ) {
! 819: goals[i].fly++;
! 820: if ( goals[i].fly > FLY_MAX_TIME ) {
! 821: goals[i].fly = 0;
! 822: flyTimer = 0;
! 823: }
! 824:
! 825: return 0;
! 826: }
! 827: }
! 828:
! 829: flyTimer++;
! 830:
! 831: if ( flyTimer > ( FLY_MAX_TIME ) ) {
! 832: int randGoal = ( ( int ) timeLeft % 10 );
! 833: if ( ( goals[randGoal].gator == 0 ) &&
! 834: ( goals[randGoal].occupied == 0 ) ) {
! 835: printf( "Displaying fly in goal %i\n", randGoal );
! 836: goals[randGoal].fly = 1;
! 837: }
! 838: }
! 839:
! 840: return 0;
! 841: }
! 842:
! 843: /*
1.1 nick 844: * This does collision detection based on the row frogger
845: * is in to help reduce overhead
846: */
847: int collisionRow ( void ) {
848: int i;
849:
850: if ( frogger.currentRow <= 0 ) return 0;
851:
852: /* Check collision with cars */
853: if ( frogger.currentRow < 6 ) {
854: for( i = 0; i < MAX_VEHICLES; i++ ) {
855: if ( level >= vehicle[i].level ) {
856: int length = ( vehicle[i].row == 5 ) ? FRAME * 2 : FRAME; /* Trucks */
857: if ( collideFrogger( vehicle[i].placement[X],
858: vehicle[i].placement[Y], FRAME,
859: length ) ) {
860: return 1;
861: }
862: }
863: }
864: return 0;
865: }
866: /* check for collisions with turtles, logs, etc.. */
867: else if ( frogger.currentRow > 6 && frogger.currentRow < 12 ) {
868: /* here a collision is good, else death */
869: for( i = 0; i < MAX_TURTLES; i++ ) {
870: if ( collideFrogger( turtle[i].placement[X],
871: turtle[i].placement[Y], FRAME,
872: FRAME * turtle[i].count ) ) {
873: frogger.riding = ( turtle[i].diveStep == 3 ) ? FALSE : LEFT;
874: frogger.ridingIdx = i;
875: frogger.ridingType = TURTLE;
876: return 1;
877: }
878: }
879: for( i = 0; i < MAX_WOOD; i++ ) {
880: if ( collideFrogger( wood[i].placement[X],
881: wood[i].placement[Y], FRAME,
882: FRAME * wood[i].type ) ) {
883: frogger.riding = RIGHT;
884: frogger.ridingIdx = i;
885: frogger.ridingType = LOG;
886: return 1;
887: }
888: }
889: }
890: /* We're on the path, if the snake is active, check that */
891: else if ( frogger.currentRow == 6 ) {
892: frogger.riding = FALSE; /*in case we hopped off a turtle */
893: }
894: /* This leaves the goal area only */
895: else {
896: for ( i = 0; i < MAX_GOALS; i++ ) {
897: if ( collideFrogger( goals[i].x, goals[i].y, goals[i].w, goals[i].h ) ) {
898: if ( goals[i].occupied ) return 1;
899: goals[i].occupied++;
1.3 ! nick 900: if ( goals[i].fly ) {
! 901: goals[i].fly = 0;
! 902: flyTimer = 0;
! 903: score += SCORE_FLY;
! 904: }
1.1 nick 905: /* playSound( s_goal ); */
906: score += SCORE_GOAL;
907: score += ( ( int ) ( timeLeft / 10 ) ) * 10;
908: lives += freeFrog( score );
909: froggerReset( );
910: if ( checkGoals( ) ) levelUp( );
911: return 0;
912: }
913: }
914: return 1;
915: }
916:
917: return 0;
918: }
919:
920: /* If the player gets enough points, award them a free frog */
921: int freeFrog ( int score ) {
922: if ( givenFreeFrog ) return 0;
923: if ( score >= SCORE_FREE_FROG ) {
924: givenFreeFrog++;
925: playSound( s_freeFrog );
926: return 1;
927: }
928: return 0;
929: }
930:
931: /* Check what frogger is colliding with */
932: int collideFrogger ( int x, int y, int h, int w ) {
933: h++; w++;
934:
935: if ( ( frogger.placement[Y] >= ( y + h ) ) ||
936: ( frogger.placement[X] >= ( x + w ) ) ||
937: ( y >= ( frogger.placement[Y] + FRAME ) ) ||
938: ( x >= ( frogger.placement[X] + FRAME ) ) ) {
939: return( 0 );
940: }
941: return( 1 );
942: }
943:
944: /* Check left and right borders */
945: void checkFroggerBorder( void ) {
946: if ( frogger.placement[Y] - 5 >= getRowPixel( 0 ) ) {
947: frogger.placement[Y] = frogger.oldPlacement[Y];
948: frogger.currentRow = 0;
949: }
950:
951: if ( ( frogger.placement[X] <= LEFT_SIDE ) ||
952: ( frogger.placement[X] + frogger.src.w >= RIGHT_SIDE ) ) {
953: if ( ( frogger.currentRow == 0 ) ||
954: ( frogger.currentRow == 6 ) ) {
955: frogger.placement[X] = frogger.oldPlacement[X];
956: }
957: else {
958: frogger.alive = FALSE;
959: }
960: }
961: }
962:
963: void levelUp ( void ) {
964: int i;
965:
966: fprintf ( stderr, "Level %i beat! ", level );
967:
968: level++;
969: score += SCORE_LEVEL;
970: lives += freeFrog( score );
971: froggerReset( );
972: /* Play sounds */
973:
974: /* Empty goals */
975: for ( i = 0; i < MAX_GOALS; i++ ) goals[i].occupied = 0;
976:
977: /* Speed things up */
978: vehicle[0].speed = level;
979: vehicle[1].speed = level;
980: vehicle[2].speed = level;
981: vehicle[3].speed = level;
982:
983: fprintf (stderr, "Starting level %i!\n", level );
984: }
985:
986: int checkGoals ( void ) {
987: int savedFrogs = 0;
988: int i;
989:
990: for ( i = 0; i < MAX_GOALS; i++ ) {
991: if ( goals[i].occupied ) savedFrogs++;
992: }
993:
994: drawGoals( );
995:
996: return ( savedFrogs >= 5 ) ? 1 : 0;
997: }
998:
999: void froggerReset ( void ) {
1000: timeLeft = MAX_TIMER;
1001:
1002: frogger.placement[X] = FROGGER_START_X;
1003: frogger.placement[Y] = FROGGER_START_Y;
1004: frogger.oldPlacement[X] = FROGGER_START_X;
1005: frogger.oldPlacement[Y] = FROGGER_START_Y;
1006: frogger.hopCount = 0;
1007: frogger.direction = 0;
1008: frogger.currentRow = 0;
1009: frogger.alive = TRUE;
1010: frogger.riding = FALSE;
1011: frogger.deathType = 0; /* Death type SPLAT or SPLASH */
1012: frogger.deathCount = 0; /* death animation timer */
1013:
1014: frogger.src.y = 0;
1015: frogger.src.x = 0;
1016: frogger.src.w = FRAME;
1017: frogger.src.h = FRAME;
1018: frogger.dst.y = frogger.placement[Y];
1019: frogger.dst.x = frogger.placement[X];
1020:
1021: drawImage( gfx, frogger.src.x, frogger.src.y, frogger.src.w,
1022: frogger.src.h, screen, frogger.dst.x, frogger.dst.y, 255 );
1023: }
1024:
1025: /*
1026: * This actually moves frogger... I need to come up with a better
1027: * algorithm for calculating the distance and time
1028: */
1029: void moveFrogger( void ) {
1030: int currentFrame = 0;
1031: int x = 0;
1032: int y = 0;
1033: int h = FRAME;
1034: int w = FRAME;
1035: int frameLow = HOP_SPEED / 3;
1036: int frameHigh = frameLow * 2;
1037:
1038: /* Determine which frame of frogger to display */
1039: if ( ( frogger.hopCount >= frameLow ) && ( frogger.hopCount <= frameHigh ) )
1040: currentFrame = FRAME;
1041:
1042: frogger.oldPlacement[Y] = frogger.placement[Y];
1043: frogger.oldPlacement[X] = frogger.placement[X];
1044:
1045: switch( frogger.direction ) {
1046: case UP:
1047: x = currentFrame;
1048: frogger.placement[Y] -= ( HOP_DISTANCE / HOP_SPEED );
1049: break;
1050: case DOWN:
1051: x = currentFrame + ( 4 * FRAME );
1052: frogger.placement[Y] += ( HOP_DISTANCE / HOP_SPEED );
1053: break;
1054: case LEFT:
1055: x = currentFrame + ( 6 * FRAME );
1056: frogger.placement[X] -= ( HOP_DISTANCE / HOP_SPEED );
1057: break;
1058: case RIGHT:
1059: x = currentFrame + ( 2 * FRAME );
1060: frogger.placement[X] += ( HOP_DISTANCE / HOP_SPEED );
1061: break;
1062: }
1063:
1064: checkFroggerBorder( );
1065:
1066: /* select the frame to display */
1067: frogger.src.y = y;
1068: frogger.src.x = x;
1069: frogger.src.w = w;
1070: frogger.src.h = h;
1071:
1072: /* Set the old place to be erased */
1073: frogger.dst.y = frogger.oldPlacement[Y];
1074: frogger.dst.x = frogger.oldPlacement[X];
1075:
1076: SDL_FillRect( screen, NULL, SDL_MapRGB( screen->format, BGCOLOR ) );
1077:
1078: /* Place the new position */
1079: frogger.dst.y = frogger.placement[Y];
1080: frogger.dst.x = frogger.placement[X];
1081:
1082: frogger.hopCount++;
1083:
1084: if ( frogger.hopCount >= HOP_SPEED ) {
1085: frogger.hopCount = 0;
1086: frogger.direction = FALSE;
1087: score += SCORE_HOP;
1088: lives += freeFrog( score );
1089: }
1090: }
1091:
1092: void ridingFrogger( void ) {
1093: int speed = 0;
1094:
1095: if ( frogger.hopCount > 0 ) return;
1096:
1097: switch( frogger.ridingType ) {
1098: case LOG:
1099: speed = wood[frogger.ridingIdx].speed;
1100: break;
1101: case TURTLE:
1102: speed = turtle[frogger.ridingIdx].speed + 2;
1103: break;
1104: }
1105:
1106: switch( frogger.riding ) {
1107: case LEFT:
1108: frogger.oldPlacement[X] = frogger.placement[X];
1109: frogger.placement[X] -= speed;
1110: frogger.dst.x = frogger.placement[X];
1111: break;
1112: case RIGHT:
1113: frogger.oldPlacement[X] = frogger.placement[X];
1114: frogger.placement[X] += speed;
1115: frogger.dst.x = frogger.placement[X];
1116: break;
1117: }
1118:
1119: checkFroggerBorder( );
1120: }
1121:
1122: void drawTitleScreen( void ) {
1123: SDL_Surface *introText;
1124: SDL_Color fontColor = { 123, 158, 53, 255 };
1125: int center = ( SCREEN_WIDTH / 2 ) - ( titleSurface->w / 2 );
1126: int i;
1127: char *txt[] = { "Press 1 for single player game",
1128: "Press 2 for two player games",
1129: "Press F for full screen mode",
1130: "Press ESC to quit" };
1131:
1132: // drawBackground( );
1133:
1134: drawImage( titleSurface, 0, 0, titleSurface->w,
1135: titleSurface->h, screen, center, 100, 255 );
1136:
1137: for( i = 0; i <= 3; i++ ) {
1138: introText = TTF_RenderText_Solid( font, txt[i], fontColor );
1139: drawImage( introText, 0, 0, introText->w, introText->h, screen,
1140: 140, 300 + ( i * introText->h ), 255 );
1141: }
1142:
1143: SDL_Flip( screen );
1144: }
1145:
1146: void drawPauseScreen( void ) {
1147: printf( "D: Draw Pause Screen\n" );
1148:
1149: }
1150:
1151: void drawGameOver( void ) {
1152: printf( "D: Game Over\n" );
1153: }
1154:
1155: void playSound( Mix_Chunk *sound ) {
1156: Mix_PlayChannel( -1, sound, 0 );
1157: }
1158:
1159: void setFullScreenMode( void ) {
1160: /* Lets give fullscreen mode a try */
1161: if ( ! fullscreen ) {
1162: screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 16, SDL_HWSURFACE | SDL_FULLSCREEN );
1163: fullscreen = TRUE;
1164: }
1165: /* Switch back to window mode */
1166: else {
1167: screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, 16, SDL_HWSURFACE );
1168: fullscreen = FALSE;
1169: }
1170:
1171: printf( "D: Fullscreen : %i\n", fullscreen );
1172: }
1173:
1174: int drawDeathSequence( int deathType ) {
1175: int animDelay = 55;
1176: int animOffset = ( deathType == SPLAT ) ? 8 : 11;
1177: int dFrame = 0;
1178:
1179: if ( frogger.deathCount < 7 ) dFrame = 0;
1180: if ( frogger.deathCount >= 7 ) dFrame = 1;
1181: if ( frogger.deathCount >= 14) dFrame = 2;
1182: if ( frogger.deathCount > 20 ) animOffset = 12;
1183:
1184: frogger.deathCount++;
1185: if ( frogger.deathCount >= animDelay )
1186: return 0; /* we're done with death */
1187:
1188: drawImage( gfx, FRAME * ( animOffset + dFrame ), 0, FRAME, FRAME,
1189: screen, frogger.placement[X], frogger.placement[Y], 255 );
1190:
1191: return 1;
1192: }
1193:
1194: /* draw green timer and return 0 if out of time */
1195: int checkTimer( void ) {
1196: float lvl = level;
1197: int step = ( int ) ( lvl / 2 );
1198: if ( step < 1 ) step = 1;
1199: if ( step > 3 ) step = 3;
1200: timeLeft -= step;
1201:
1202: drawTimer( (int) ( ( timeLeft / MAX_TIMER ) * TIMER_SIZE ) );
1203:
1204: if ( timeLeft <= 0 ) return 0;
1205: return 1;
1206: }
1207:
1208: void drawScore( int high, int score ) {
1209: int x = 169;
1210: int y = 14;
1211:
1212: if ( score > hScore ) hScore = score;
1213: if ( high ) x = 260;
1214:
1215: drawNumbers( score, x, y );
1216: }
1217:
1218: void drawNumbers( int num, int x, int y ) {
1219: char numStr[6] = "00000";
1220: int i;
1221:
1222: /* Assume anything less than 50 pixels location is a score and
1223: * pad with '0'.
1224: */
1225: if ( y <= 15 ) sprintf( numStr, "%05i", num );
1226: else sprintf( numStr, "%i", num );
1227:
1228: for ( i = 0; i <= 4; i++ ) {
1229: char c = numStr[i];
1230: int n = atoi( &c );
1231:
1232: drawImage( gfx, n * HFRAME, FRAME * 3 , HFRAME, FRAME,
1233: screen, x + ( i * HFRAME ) + 2, y, 255 );
1234: }
1235: }
1236:
1237: /* Normally this functions manages and draws the flys, gators and saved frogs
1238: * but if drawDebugRect below is turned on it will draw the rectangle
1239: * used for collision detectiong for debuggin purposes in timer green
1240: */
1241: void drawGoals( void ) {
1242: int drawDebugRect = 0;
1243: int i;
1.3 ! nick 1244:
1.1 nick 1245: for ( i = 0; i < MAX_GOALS; i++ ) {
1246: if ( drawDebugRect ) {
1247: SDL_Rect d;
1248: d.x = goals[i].x;
1249: d.y = goals[i].y;
1250: d.w = goals[i].w;
1251: d.h = goals[i].h;
1252:
1253: SDL_FillRect( screen, &d, SDL_MapRGB( screen->format, TIMER_COLOR ) );
1254: }
1255:
1256: if ( goals[i].occupied )
1257: drawImage( gfx, FRAME * 15, 0, FRAME, FRAME,
1258: screen, goals[i].x + 13, goals[i].y + 5, 255 );
1.3 ! nick 1259: if( goals[i].fly ) {
! 1260: drawImage( gfx, FRAME * 16, 0, FRAME, FRAME,
! 1261: screen, goals[i].x + 13, goals[i].y + 5, 255 );
! 1262: }
1.1 nick 1263: }
1264: }
1265:
1266: void drawTimer( int length ) {
1267: SDL_Rect timerRect;
1268:
1269: timerRect.x = RIGHT_SIDE - 60 - length;
1270: timerRect.y = 465;
1271: timerRect.w = length;
1272: timerRect.h = 15;
1273:
1274: SDL_FillRect( screen, &timerRect, SDL_MapRGB( screen->format, TIMER_COLOR ) );
1275: }
1276:
1277: void drawLives( int lives ) {
1278: int i;
1279: int lifeFroggerSize = 16;
1280:
1281: for( i = 0; i <= lives - 2; i++ ) {
1282: drawImage( gfx, FRAME * 11, FRAME * 2, lifeFroggerSize, FRAME,
1283: screen, LEFT_SIDE + ( lifeFroggerSize * i ), 450, 255 );
1284: }
1285: }
1286:
1287: void drawLevel( int level ) {
1288: int i;
1289: int levelImageSize = 12;
1290:
1291: for( i = 0; i <= level - 1; i++ ) {
1292: drawImage( gfx, FRAME * 12, FRAME * 2, levelImageSize, FRAME,
1293: screen, RIGHT_SIDE - levelImageSize - ( levelImageSize * i ), 450, 255 );
1294: }
1295: }
1296:
1297: void drawWood ( void ) {
1298: int i;
1299:
1300: for ( i = 0; i < MAX_WOOD; i++ ) {
1301: if ( wood[i].placement[X] > ( RIGHT_SIDE + 5 ) )
1302: wood[i].placement[X] = LEFT_SIDE - wood[i].src.w - 5;
1303: wood[i].placement[X] += wood[i].speed;
1304: drawImage( gfx, wood[i].src.x, wood[i].src.y,
1305: wood[i].src.w, wood[i].src.h,
1306: screen, wood[i].placement[X],
1307: wood[i].placement[Y], 255 );
1308: }
1309: }
1310:
1311: void drawTurtles ( void ) {
1312: int i = 0;
1313: int n = 0;
1314: int animFrame = 0;
1315:
1316: for ( i = 0; i < MAX_TURTLES; i++ ) {
1317: /* This managed the turtles basic 3 frames of animation */
1318: animFrame = turtle[i].animStep;
1319: if ( turtle[i].animDelay >= TURTLE_ANIM_TIME ) {
1320: turtle[i].animDelay = 0;
1321: turtle[i].animStep++;
1322: if ( turtle[i].animStep > 2 ) turtle[i].animStep = 0;
1323: }
1324: else {
1325: turtle[i].animDelay++;
1326: }
1327:
1328: /* If a set of turtles have dive capability, this enables that */
1329: if ( turtle[i].canDive ) {
1330: turtle[i].diveTime++;
1331: /* Check if turtle is diving */
1332: if ( turtle[i].diveStep > 0 ) {
1333: switch( turtle[i].diveStep ) {
1334: case 1:
1335: animFrame = 3;
1336: break;
1337: case 2:
1338: animFrame = 4;
1339: break;
1340: case 4:
1341: animFrame = 4;
1342: break;
1343: case 5:
1344: animFrame = 3;
1345: break;
1346: case 6:
1347: turtle[i].diveStep = 0;
1348: turtle[i].diveTime = 0;
1349: break;
1350: default:
1351: animFrame = 4;
1352: break;
1353: }
1354:
1355: if ( turtle[i].diveTime > DIVE_START_TIME + ( DIVE_PHASE_TIME * turtle[i].diveStep ) )
1356: turtle[i].diveStep++;
1357:
1358: }
1359: else {
1360: if ( turtle[i].diveTime > DIVE_START_TIME )
1361: turtle[i].diveStep++;
1362: }
1363: }
1364:
1365: /* Display out turtles */
1366: for ( n = 0; n <= ( turtle[i].count - 1 ); n++ ) {
1367: turtle[i].placement[X] -= turtle[i].speed;
1368: if ( turtle[i].placement[X] <= LEFT_SIDE - ( turtle[i].count * FRAME ) + 10 )
1369: turtle[i].placement[X] = RIGHT_SIDE + 10;
1370: if ( turtle[i].diveStep != 4 )
1371: drawImage( gfx, turtle[i].src.x + ( FRAME * animFrame ),
1372: turtle[i].src.y, turtle[i].src.w, turtle[i].src.h,
1373: screen, turtle[i].placement[X] + ( ( FRAME + 3 ) * n ),
1374: turtle[i].placement[Y], 255 );
1375: }
1376: }
1377: }
1378:
1379: void drawVehicles ( void ) {
1380: int i;
1381:
1382: for ( i = 0; i < MAX_VEHICLES; i++ ) {
1383: if ( vehicle[i].direction == RIGHT ) {
1384: if ( vehicle[i].placement[X] > ( RIGHT_SIDE + 5 ) )
1385: vehicle[i].placement[X] = LEFT_SIDE - vehicle[i].src.w - 5;
1386: vehicle[i].placement[X] += vehicle[i].speed;
1387: }
1388: else {
1389: if ( vehicle[i].placement[X] < ( LEFT_SIDE - 5 ) )
1390: vehicle[i].placement[X] = RIGHT_SIDE + vehicle[i].src.w + 5;
1391: vehicle[i].placement[X] -= vehicle[i].speed;
1392: }
1393:
1394: if ( level >= vehicle[i].level )
1395: drawImage( gfx, vehicle[i].src.x, vehicle[i].src.y,
1396: vehicle[i].src.w, vehicle[i].src.h,
1397: screen, vehicle[i].placement[X],
1398: vehicle[i].placement[Y], 255 );
1399: }
1400: }
1401:
1402: void drawImage( SDL_Surface *srcimg, int sx, int sy, int sw, int sh,
1403: SDL_Surface *dstimg, int dx, int dy, int alpha ) {
1404: if ((!srcimg) || (alpha == 0)) return;
1405: SDL_Rect src, dst;
1406:
1407: src.x = sx; src.y = sy; src.w = sw; src.h = sh;
1408: dst.x = dx; dst.y = dy; dst.w = src.w; dst.h = src.h;
1409:
1410: if (alpha != 255) SDL_SetAlpha(srcimg, SDL_SRCALPHA, alpha);
1411: SDL_BlitSurface(srcimg, &src, dstimg, &dst);
1412: }
1413:
1414: int heartbeat ( void ) {
1415: int ticks;
1416: if ( level ) {
1417: if ( playing ) {
1418: ticks = updateGameState( );
1419: if ( ticks <= 0 ) ticks = 50;
1420: return ticks;
1421: }
1422: else {
1423: drawPauseScreen( );
1424: return 500;
1425: }
1426: }
1427: else {
1428: drawTitleScreen( );
1429: return 500;
1430: }
1431:
1432: return 50;
1433: }
1434:
1435: /*
1436: * Main program starts here. We'll init the video and audio
1437: * and then begin our main program loop here
1438: *
1439: */
1440: int main ( int argc, char **argv ) {
1441: if ( mySDLInit( ) <= 0 ) {
1442: fprintf( stderr, "Failure to start froggix\n" );
1443: return 255;
1444: }
1445:
1446: beginGame( );
1447:
1448: SDL_Quit( );
1449:
1450: return 0;
1451: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>