//renders one frame void Render(void) { LIST * cur; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); DrawStarfield(&g_starfield); for(cur = g_asteroid_list; cur; cur = cur->next) DrawAsteroid(cur->d); if(g_ships) DrawPlayer(&g_player); else { RenderText(15.2858f, 27.0f, 50.0f, 1.0f, 0.75f, 0.0f, 0.0f, "GAME OVER"); if(!g_hisct_delay) { RenderText(13.1906f, 26.0f, 50.0f, 0.5f, 0.75f, 0.5f, 0.5f, "hit F2 to start a new game"); DrawHiScoreTable(&g_hisct); } } for(cur = g_alien_list; cur; cur = cur->next) DrawAlien(cur->d); for(cur = g_shot_list; cur; cur = cur->next) DrawShot(cur->d); for(cur = g_explosion_list; cur; cur = cur->next) DrawExplosion(cur->d); for(cur = g_burst_list; cur; cur = cur->next) DrawBurst(cur->d); for(cur = g_powerup_list; cur; cur = cur->next) DrawPowerup(cur->d); if(g_paused) { RenderText(0.011792f, 6.0f, 50.0f, 6.36f, 1.0f, 0.5f, 0.5f, "paused"); RenderText(11.0954f, 4.0f, 50.0f, 1.0f, 1.0f, 0.5f, 0.5f, "(hit p to resume)"); } RenderText(29.3f, 28.7f, 50.0f, 1.0f, 0.75f, 0.75f, 0.75f, "%10d", g_score); RenderText(0.1f, 28.7f, 50.0f, 1.0f, 0.75f, 0.75f, 0.75f, "%d", (g_ships ? g_ships - 1 : 0)); if(g_level < 1000) { if(g_time_to_reset) RenderText(7.9526f, 0.5f, 50.0f, 1.0f, 0.25f, 0.25f, 0.25f, "warping to level %03d...", g_level + 1); else if(g_level) RenderText(15.2858f, 0.5f, 50.0f, 1.0f, 0.25f, 0.25f, 0.25f, "level %03d", g_level); } else RenderText(13.1906f, 0.5f, 50.0f, 1.0f, 1.0f, 1.0f, 1.0f, "you are a god"); if(g_ships && g_time_to_reset) { RenderText(15.2858f, 15.0f, 50.0f, 1.0f, 0.0f, 0.75f, 0.0f, "GOOD JOB!"); RenderText(14.5001f, 14.0f, 50.0f, 0.5f, 0.5f, 0.75f, 0.5f, "completion bonus: %3d", (g_level > 99 ? 999 : g_level * 10)); } RenderText(0.1f, 0.2f, 0.0f, 0.5f, 0.5f, 0.0f, 0.5f, "%.1ffps", g_fps); glFlush(); glutSwapBuffers(); }
//Main program loop - Run gets called until it returns false bool Run() { //Main loop - get keypresses and interpret them keystate=GetRemoteKeys(); if(keystate & KEY_HOME) { return false; } switch(mode) { case 0: { //Splash screen if (keystate & KEY_INPUT2) { //Button B //Start game InitialiseGame(); PlaySound(SOUND_BEEP); } if (keystate & KEY_INPUT1) { //Button A //show help ShowHelp(); PlaySound(SOUND_BEEP); } } break; case 2: { //Help - wait for 'OK' press if (keystate & KEY_INPUT2) { //Button B //Reset back to splash screen ResetTimer(); mode=0; Splash(); PlaySound(SOUND_BEEP); } } break; case 1: { //Game if (keystate & KEY_INPUT1) { //Button A //Reset back to splash screen ResetTimer(); mode=0; Splash(); } if (keystate & KEY_RUN) { //Go button //Fire! PlaySound(SOUND_SHOOT); refreshCount = 0; int hit; hit = LineHitsObject(cameraPos, cameraAngle); if (hit == tankObjectIndex) { //we hit the tank! score += 100; CloseGraphics(); OpenGraphics(); DrawWorld(&world, cameraPos, cameraAngle); DrawHUD(); DrawExplosion(); DrawArrow(cameraAngle.y); DrawRadarDots(true); DrawRadarArm(sweepAngle * sweepStepCount++); DrawRadarDots(false); SetTextColor(CYAN); DrawText(6,100,"Quit"); Show(); PlaySound(SOUND_EXPLOSION); PlaceTank(cameraPos, cameraAngle); } } //Have the movement sticks changed? This bit doesn't care about buttons if((keystate & (KEY_RIGHT_BACK+KEY_RIGHT_FORWARD+KEY_LEFT_BACK+KEY_LEFT_FORWARD)) != (oldKeystate & (KEY_RIGHT_BACK+KEY_RIGHT_FORWARD+KEY_LEFT_BACK+KEY_LEFT_FORWARD))) { MoveCamera(&cameraPos, &cameraAngle, baselinePos, arrowRefAngle, ReadTimer(), oldKeystate); arrowRefAngle=cameraAngle.y; baselinePos=cameraPos; ResetTimer(); oldKeystate = keystate; if (keystate==0) //we've just stopped moving refreshCount=0; } if (mode==1) { if (sweepStepCount == SWEEPSTEPS) sweepStepCount=0; if (--behaviourCount<0) ChooseBehaviour(); MoveTank(); MoveCamera(&cameraPos, &cameraAngle, baselinePos, arrowRefAngle, ReadTimer(), oldKeystate); //is it time to reset the tank model? Otherwise it gradually gets distorted if (--resetCount<0) { //Refresh the tank model which is prone to getting distorted //due to cumulative inaccuracies of sin/cos approximations Point3d angle=world.objects[tankObjectIndex].heading; Point3d tankPos=world.objects[tankObjectIndex].centre; world.objects[tankObjectIndex]=tank; MoveObject(&(world.objects[tankObjectIndex]), tankPos); RotateObjectYAxis(&(world.objects[tankObjectIndex]), angle.y); resetCount=50; } //Is it time to redraw the world? if (--refreshCount<0) { //Seems a bit brutal to have to close graphics but it's //the only way to clear the screen that'll let us draw //on it properly again - ClearScreen or ClearRectangle mess up CloseGraphics(); OpenGraphics(); DrawWorld(&world, cameraPos, cameraAngle); DrawHUD(); refreshCount=2; } DrawArrow(cameraAngle.y); DrawRadarDots(true); DrawRadarArm(sweepAngle * sweepStepCount++); DrawRadarDots(false); SetTextColor(CYAN); DrawText(6,100,"Quit"); Show(); //just in case we changed mode... if (mode==0) Splash(); } } } Sleep(50); return true; }