Annotation of froggix/src/froggix.c, revision 1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>