// Update and Draw one frame void UpdateDrawFrame(void) { // Update //---------------------------------------------------------------------------------- if (!onTransition) { switch (currentScreen) { case LOGO: { UpdateLogoScreen(); if (FinishLogoScreen()) TransitionToScreen(TITLE); } break; case TITLE: { UpdateTitleScreen(); // NOTE: FinishTitleScreen() return an int defining the screen to jump to if (FinishTitleScreen() == 1) { UnloadTitleScreen(); //currentScreen = OPTIONS; //InitOptionsScreen(); } else if (FinishTitleScreen() == 2) { UnloadTitleScreen(); InitGameplayScreen(); TransitionToScreen(GAMEPLAY); } } break; case GAMEPLAY: { UpdateGameplayScreen(); if (FinishGameplayScreen()) { UnloadGameplayScreen(); InitEndingScreen(); TransitionToScreen(ENDING); } } break; case ENDING: { UpdateEndingScreen(); if (FinishEndingScreen()) { UnloadEndingScreen(); InitGameplayScreen(); TransitionToScreen(GAMEPLAY); } } break; default: break; } } else UpdateTransition(); UpdateMusicStream(music); //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(WHITE); switch (currentScreen) { case LOGO: DrawLogoScreen(); break; case TITLE: DrawTitleScreen(); break; case GAMEPLAY: DrawGameplayScreen(); break; case ENDING: DrawEndingScreen(); break; default: break; } if (onTransition) DrawTransition(); DrawFPS(20, GetScreenHeight() - 30); DrawRectangle(GetScreenWidth() - 200, GetScreenHeight() - 50, 200, 40, Fade(WHITE, 0.6f)); DrawText("ALPHA VERSION", GetScreenWidth() - 180, GetScreenHeight() - 40, 20, DARKGRAY); EndDrawing(); //---------------------------------------------------------------------------------- }
// Update and draw game frame void UpdateDrawFrame(void) { // Update //---------------------------------------------------------------------------------- if (!onTransition) { if (player.dead) { framesCounter++; if (framesCounter > 80) { framesCounter = 0; player.dead = false; player.numLifes = 4; TransitionToScreen(TITLE); } } switch(currentScreen) { case LOGO: { UpdateLogoScreen(); if (FinishLogoScreen()) ChangeToScreen(LOGO_RL); } break; case LOGO_RL: { rlUpdateLogoScreen(); if (rlFinishLogoScreen()) TransitionToScreen(TITLE); } break; case TITLE: { UpdateTitleScreen(); if (FinishTitleScreen() == 1) TransitionToScreen(ATTIC); } break; case ATTIC: { UpdateAtticScreen(); if (FinishAtticScreen() == 1) TransitionToScreen(AISLE01); } break; case AISLE01: { UpdateAisle01Screen(); if (FinishAisle01Screen() == 1) TransitionToScreen(BATHROOM); else if(FinishAisle01Screen() == 2) TransitionToScreen(KITCHEN); else if(FinishAisle01Screen() == 3) TransitionToScreen(LIVINGROOM); } break; case BATHROOM: { UpdateBathroomScreen(); if (FinishBathroomScreen() == 1) TransitionToScreen(AISLE01); } break; case LIVINGROOM: { UpdateLivingroomScreen(); if (FinishLivingroomScreen() == 1) TransitionToScreen(AISLE01); else if(FinishLivingroomScreen() == 2)TransitionToScreen(AISLE02); } break; case AISLE02: { UpdateAisle02Screen(); if (FinishAisle02Screen() == 1) TransitionToScreen(KITCHEN); } break; case KITCHEN: { UpdateKitchenScreen(); if (FinishKitchenScreen() == 1) TransitionToScreen(ARMORY); else if(FinishKitchenScreen() == 2)TransitionToScreen(AISLE02); } break; case ARMORY: { UpdateArmoryScreen(); if(FinishArmoryScreen() == 1) TransitionToScreen(ENDING); else if(FinishArmoryScreen() == 2) TransitionToScreen(KITCHEN); } break; case ENDING: { UpdateEndingScreen(); if (FinishEndingScreen()) TransitionToScreen(TITLE); } break; default: break; } } else { // Update transition (fade-in, fade-out) UpdateTransition(); } UpdateMusicStream(music); //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); switch(currentScreen) { case LOGO: DrawLogoScreen(); break; case LOGO_RL: rlDrawLogoScreen(); break; case TITLE: DrawTitleScreen(); break; case ATTIC: DrawAtticScreen(); break; case AISLE01: DrawAisle01Screen();break; case AISLE02: DrawAisle02Screen();break; case BATHROOM: DrawBathroomScreen();break; case LIVINGROOM: DrawLivingroomScreen();break; case KITCHEN: DrawKitchenScreen();break; case ARMORY: DrawArmoryScreen();break; case ENDING: DrawEndingScreen(); break; default: break; } if (onTransition) DrawTransition(); //DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- }
// Update and draw game frame void UpdateDrawFrame(void) { // Update //---------------------------------------------------------------------------------- if (!onTransition) { switch(currentScreen) { case LOGO_RL: { rlUpdateLogoScreen(); if (rlFinishLogoScreen()) TransitionToScreen(TITLE); } break; case TITLE: { UpdateTitleScreen(); if (FinishTitleScreen() == 1) TransitionToScreen(GAMEPLAY); } break; case GAMEPLAY: { UpdateGameplayScreen(); if (FinishGameplayScreen() == 1) ChangeToScreen(LOGO_RL); else if (FinishGameplayScreen() == 2) TransitionToScreen(TITLE); } break; default: break; } } else { // Update transition (fade-in, fade-out) UpdateTransition(); } UpdateMusicStream(); //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); switch(currentScreen) { case LOGO_RL: rlDrawLogoScreen(); break; case TITLE: DrawTitleScreen(); break; case GAMEPLAY: DrawGameplayScreen(); break; default: break; } if (onTransition) DrawTransition(); //DrawFPS(10, 10); EndDrawing(); //---------------------------------------------------------------------------------- }
// Update and draw game frame static void UpdateDrawFrame(void) { // Update //---------------------------------------------------------------------------------- if (!onTransition) { switch(currentScreen) { case LOGO: { UpdateLogoScreen(); if (FinishLogoScreen()) TransitionToScreen(TITLE); } break; case TITLE: { UpdateTitleScreen(); if (FinishTitleScreen() == 1) TransitionToScreen(GAMEPLAY); } break; case GAMEPLAY: { UpdateGameplayScreen(); if (FinishGameplayScreen() == 1) TransitionToScreen(ENDING); //else if (FinishGameplayScreen() == 2) TransitionToScreen(TITLE); } break; case ENDING: { UpdateEndingScreen(); if (FinishEndingScreen() == 1) TransitionToScreen(TITLE); } break; default: break; } } else UpdateTransition(); // Update transition (fade-in, fade-out) // TODO: Review! It breaks the game... issues with audio buffering... if (currentScreen != ENDING) UpdateMusicStream(music); //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); switch(currentScreen) { case LOGO: DrawLogoScreen(); break; case TITLE: DrawTitleScreen(); break; case GAMEPLAY: DrawGameplayScreen(); break; case ENDING: DrawEndingScreen(); break; default: break; } // Draw full screen rectangle in front of everything if (onTransition) DrawTransition(); EndDrawing(); //---------------------------------------------------------------------------------- }
/* Display high scores: */ void DisplayHighScores(int level) { int i = 0; int finished = 0; Uint32 frame = 0; Uint32 timer = 0; int diff_level = level; int old_diff_level = -1; //So table gets refreshed first time through /* Surfaces, char buffers, and rects for table: */ SDL_Surface* score_surfs[HIGH_SCORES_SAVED] = {NULL}; /* 10 spaces should be enough room for place and score on each line: */ char score_strings[HIGH_SCORES_SAVED][HIGH_SCORE_NAME_LENGTH + 10] = {{'\0'}}; SDL_Rect score_rects[HIGH_SCORES_SAVED]; SDL_Rect table_bg; const int max_width = 300; int score_table_y = 100; const int title_font_size = 32; const int player_font_size = 14; char tts_temp[2000]; while (!finished) { /* Check for user events: */ while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: { cleanup(); } case SDL_MOUSEBUTTONDOWN: /* "Stop" button - go to main menu: */ { if (T4K_inRect(stop_rect, event.button.x, event.button.y )) { finished = 1; playsound(SND_TOCK); } /* "Left" button - go to previous page: */ if (T4K_inRect(prev_rect, event.button.x, event.button.y)) { if (diff_level > CADET_HIGH_SCORE) { diff_level--; if (Opts_GetGlobalOpt(MENU_SOUND)) { playsound(SND_TOCK); } } } /* "Right" button - go to next page: */ if (T4K_inRect(next_rect, event.button.x, event.button.y )) { if (diff_level < (NUM_HIGH_SCORE_LEVELS-1)) { diff_level++; if (Opts_GetGlobalOpt(MENU_SOUND)) { playsound(SND_TOCK); } } } break; } case SDL_KEYDOWN: { finished = 1; playsound(SND_TOCK); } } } /* If needed, redraw: */ if (diff_level != old_diff_level) { DrawTitleScreen(); /* Draw controls: */ if (stop_button) SDL_BlitSurface(stop_button, NULL, screen, &stop_rect); /* Draw regular or grayed-out left arrow: */ if (diff_level == CADET_HIGH_SCORE) { if (prev_gray) SDL_BlitSurface(prev_gray, NULL, screen, &prev_rect); } else { if (prev_arrow) SDL_BlitSurface(prev_arrow, NULL, screen, &prev_rect); } /* Draw regular or grayed-out right arrow: */ if (diff_level == NUM_HIGH_SCORE_LEVELS - 1) { if (next_gray) SDL_BlitSurface(next_gray, NULL, screen, &next_rect); } else { if (next_arrow) SDL_BlitSurface(next_arrow, NULL, screen, &next_rect); } /* Draw background shading for table: */ table_bg.x = (screen->w)/2 - (max_width + 20)/2 + 50; //don't draw over Tux table_bg.y = 5; table_bg.w = max_width + 20; table_bg.h = screen->h - 10 - images[IMG_RIGHT]->h; T4K_DrawButton(&table_bg, 25, SEL_RGBA); /* Draw difficulty level heading: */ { SDL_Surface* srfc = NULL; SDL_Rect text_rect, button_rect; srfc = T4K_BlackOutline(_("Hall Of Fame"), title_font_size, &yellow); strcpy(tts_temp,_("Hall Of Fame")); strcat(tts_temp," "); if (srfc) { button_rect.x = text_rect.x = (screen->w)/2 - (srfc->w)/2 + 50; button_rect.y = text_rect.y = 10; button_rect.w = text_rect.w = srfc->w; button_rect.h = text_rect.h = srfc->h; /* add margin to button and draw: */ button_rect.x -= 10; button_rect.w += 20; T4K_DrawButton(&button_rect, 15, 0, 0, 32, 192); /* Now blit text and free surface: */ SDL_BlitSurface(srfc, NULL, screen, &text_rect); SDL_FreeSurface(srfc); srfc = NULL; } switch (diff_level) { case CADET_HIGH_SCORE: srfc = T4K_BlackOutline(_("Space Cadet"), title_font_size, &white); strcat(tts_temp,_("Space Cadet")); break; case SCOUT_HIGH_SCORE: srfc = T4K_BlackOutline(_("Scout"), title_font_size, &white); strcat(tts_temp,_("Scout")); break; case RANGER_HIGH_SCORE: srfc = T4K_BlackOutline(_("Ranger"), title_font_size, &white); strcat(tts_temp,_("Ranger")); break; case ACE_HIGH_SCORE: srfc = T4K_BlackOutline(_("Ace"), title_font_size, &white); strcat(tts_temp,_("Ace")); break; case COMMANDO_HIGH_SCORE: srfc = T4K_BlackOutline(_("Commando"), title_font_size, &white); strcat(tts_temp,_("Commando")); break; case FACTORS_HIGH_SCORE: srfc = T4K_BlackOutline(_("Factors"), title_font_size, &white); strcat(tts_temp,_("Factors")); break; case FRACTIONS_HIGH_SCORE: srfc = T4K_BlackOutline(_("Fractions"), title_font_size, &white); strcat(tts_temp,_("Fractions")); break; default: srfc = T4K_BlackOutline(_("Space Cadet"), title_font_size, &white); strcat(tts_temp,_("Space Cadet")); } if (srfc) { text_rect.x = (screen->w)/2 - (srfc->w)/2 + 50; text_rect.y += text_rect.h; /* go to bottom of first line */ text_rect.w = srfc->w; text_rect.h = srfc->h; SDL_BlitSurface(srfc, NULL, screen, &text_rect); SDL_FreeSurface(srfc); srfc = NULL; /* note where score table will start: */ score_table_y = text_rect.y + text_rect.h; } } strcat(tts_temp,". Score sheet with place,score and name "); /* Generate and draw desired table: */ for (i = 0; i < HIGH_SCORES_SAVED; i++) { /* Get data for entries: */ sprintf(score_strings[i], "%d. %d %s", i + 1, /* Add one to get common-language place number */ HS_Score(diff_level, i), HS_Name(diff_level, i)); if (HS_Score(diff_level, i) != 0) { strcat(tts_temp,". On place "); strcat(tts_temp,score_strings[i]); } /* Clear out old surfaces and update: */ if (score_surfs[i]) /* this should not happen! */ SDL_FreeSurface(score_surfs[i]); if (HS_Score(diff_level, i) == Opts_LastScore() && frame % 5 < 2) score_surfs[i] = T4K_BlackOutline(N_(score_strings[i]), player_font_size, &yellow); else score_surfs[i] = T4K_BlackOutline(N_(score_strings[i]), player_font_size, &white); /* Get out if T4K_BlackOutline() fails: */ if (!score_surfs[i]) continue; /* Set up entries in vertical column: */ if (0 == i) score_rects[i].y = score_table_y; else score_rects[i].y = score_rects[i - 1].y + score_rects[i - 1].h; score_rects[i].x = (screen->w)/2 - max_width/2 + 50; score_rects[i].h = score_surfs[i]->h; score_rects[i].w = max_width; SDL_BlitSurface(score_surfs[i], NULL, screen, &score_rects[i]); SDL_FreeSurface(score_surfs[i]); score_surfs[i] = NULL; } strcat(tts_temp,". Press space or escape to return to main menu."); T4K_Tts_say(DEFAULT_VALUE,DEFAULT_VALUE,INTERRUPT,"%s",tts_temp); /* Update screen: */ SDL_UpdateRect(screen, 0, 0, 0, 0); old_diff_level = diff_level; } HandleTitleScreenAnimations(); /* Wait so we keep frame rate constant: */ T4K_Throttle(20, &timer); frame++; } // End of while (!finished) loop }
/* Get pl_name from user; other strings are text displayed by dialog: */ void NameEntry(char* pl_name, const char* s1, const char* s2, const char* s3) { char UTF8_buf[HIGH_SCORE_NAME_LENGTH * 3] = {'\0'}; SDL_Rect loc; SDL_Rect redraw_rect; int redraw = 0; int first_draw = 1; int finished = 0; Uint32 frame = 0; Uint32 start = 0; wchar_t wchar_buf[HIGH_SCORE_NAME_LENGTH + 1] = {'\0'}; const int NAME_FONT_SIZE = 32; const int BG_Y = 100; const int BG_WIDTH = 400; const int BG_HEIGHT = 200; if (!pl_name) return; /* We need to get Unicode vals from SDL keysyms */ SDL_EnableUNICODE(SDL_ENABLE); DEBUGMSG(debug_highscore, "Enter NameEntry()\n" ); DrawTitleScreen(); /* Red "Stop" circle in upper right corner to go back to main menu: */ if (stop_button) { SDL_BlitSurface(stop_button, NULL, screen, &stop_rect); } /* Draw translucent background for text: */ { SDL_Rect bg_rect; bg_rect.x = (screen->w)/2 - BG_WIDTH/2; bg_rect.y = BG_Y; bg_rect.w = BG_WIDTH; bg_rect.h = BG_HEIGHT; T4K_DrawButton(&bg_rect, 15, REG_RGBA); bg_rect.x += 10; bg_rect.y += 10; bg_rect.w -= 20; bg_rect.h = 60; T4K_DrawButton(&bg_rect, 10, SEL_RGBA); } /* Draw headings: */ { SDL_Surface* surf = T4K_BlackOutline(_(s1), DEFAULT_MENU_FONT_SIZE, &white); if (surf) { loc.x = (screen->w/2) - (surf->w/2); loc.y = 110; SDL_BlitSurface(surf, NULL, screen, &loc); SDL_FreeSurface(surf); } surf = T4K_BlackOutline(_(s2), DEFAULT_MENU_FONT_SIZE, &white); if (surf) { loc.x = (screen->w/2) - (surf->w/2); loc.y = 140; SDL_BlitSurface(surf, NULL, screen, &loc); SDL_FreeSurface(surf); } surf = T4K_BlackOutline(_(s3), DEFAULT_MENU_FONT_SIZE, &white); if (surf) { loc.x = (screen->w/2) - (surf->w/2); loc.y = 170; SDL_BlitSurface(surf, NULL, screen, &loc); SDL_FreeSurface(surf); } } if (_(s3) != NULL) T4K_Tts_say(DEFAULT_VALUE,DEFAULT_VALUE,APPEND,"%s %s %s",_(s1),_(s2),_(s3)); else if(_(s2) != NULL) T4K_Tts_say(DEFAULT_VALUE,DEFAULT_VALUE,APPEND,"%s %s",_(s1),_(s2)); else T4K_Tts_say(DEFAULT_VALUE,DEFAULT_VALUE,APPEND,"%s",_(s1)); /* and update: */ SDL_UpdateRect(screen, 0, 0, 0, 0); while (!finished) { start = SDL_GetTicks(); while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: { cleanup(); } case SDL_MOUSEBUTTONDOWN: /* "Stop" button - go to main menu: */ { if (T4K_inRect(stop_rect, event.button.x, event.button.y )) { finished = 1; playsound(SND_TOCK); break; } } case SDL_KEYDOWN: { DEBUGMSG(debug_highscore, "Before keypress, string is %S\tlength = %d\n", wchar_buf, (int)wcslen(wchar_buf)); switch (event.key.keysym.sym) { case SDLK_ESCAPE: case SDLK_RETURN: case SDLK_KP_ENTER: { finished = 1; playsound(SND_TOCK); break; } case SDLK_BACKSPACE: { if (wcslen(wchar_buf) > 0) wchar_buf[(int)wcslen(wchar_buf) - 1] = '\0'; redraw = 1; break; } /* For any other keys, if the key has a Unicode value, */ /* we add it to our string: */ default: { if ((event.key.keysym.unicode > 0) && (wcslen(wchar_buf) < HIGH_SCORE_NAME_LENGTH)) { wchar_buf[(int)wcslen(wchar_buf)] = event.key.keysym.unicode; redraw = 1; T4K_Tts_say(DEFAULT_VALUE,DEFAULT_VALUE,INTERRUPT,"%C",event.key.keysym.unicode); } } } /* end 'switch (event.key.keysym.sym)' */ DEBUGMSG(debug_highscore, "After keypress, string is %S\tlength = %d\n", wchar_buf, (int)wcslen(wchar_buf)); /* Now draw name, if needed: */ if (redraw) { SDL_Surface* s = NULL; redraw = 0; /* Convert text to UTF-8 so T4K_BlackOutline() can handle it: */ // wcstombs((char*) UTF8_buf, wchar_buf, HIGH_SCORE_NAME_LENGTH * 3); T4K_ConvertToUTF8(wchar_buf, UTF8_buf, HIGH_SCORE_NAME_LENGTH * 3); /* Redraw background and shading in area where we drew text last time: */ if (!first_draw) { SDL_BlitSurface(current_bkg(), &redraw_rect, screen, &redraw_rect); T4K_DrawButton(&redraw_rect, 0, REG_RGBA); SDL_UpdateRect(screen, redraw_rect.x, redraw_rect.y, redraw_rect.w, redraw_rect.h); } s = T4K_BlackOutline(UTF8_buf, NAME_FONT_SIZE, &yellow); if (s) { /* set up loc and blit: */ loc.x = (screen->w/2) - (s->w/2); loc.y = 230; SDL_BlitSurface(s, NULL, screen, &loc); /* Remember where we drew so we can update background next time through: */ /* (for some reason we need to update a wider area to get clean image) */ redraw_rect.x = loc.x - 20; redraw_rect.y = loc.y - 10; redraw_rect.h = s->h + 20; redraw_rect.w = s->w + 40; first_draw = 0; SDL_UpdateRect(screen, redraw_rect.x, redraw_rect.y, redraw_rect.w, redraw_rect.h); SDL_FreeSurface(s); s = NULL; } } } } } HandleTitleScreenAnimations(); /* Wait so we keep frame rate constant: */ while ((SDL_GetTicks() - start) < 33) { SDL_Delay(20); } frame++; } // End of while (!finished) loop /* Turn off SDL Unicode lookup (because has some overhead): */ SDL_EnableUNICODE(SDL_DISABLE); /* Now copy name into location pointed to by arg: */ strncpy(pl_name, UTF8_buf, HIGH_SCORE_NAME_LENGTH * 3); DEBUGMSG(debug_highscore, "Leaving NameEntry(), final string is: %s\n", pl_name); if (wcslen(wchar_buf) != 0) T4K_Tts_say(DEFAULT_VALUE,DEFAULT_VALUE,INTERRUPT,"%S.",wchar_buf); }