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