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

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

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