Annotation of froggix/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.1.1 2009-03-27 19:47:27 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" );
                    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++ ) {
1.2     ! nick      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:                                }
1.1       nick      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>