X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fscreens.c;h=ee5035ce0320569f35a9fb27e510a0123da9636d;hb=6ca233d4d71331460af0443bf5b307f16c6fe069;hp=3f0186216a765e9d257aeba3212b58d67933e1ce;hpb=84b4d1874b7dfed42ace079941a65baea0ac4ff6;p=rocksndiamonds.git diff --git a/src/screens.c b/src/screens.c index 3f018621..ee5035ce 100644 --- a/src/screens.c +++ b/src/screens.c @@ -312,6 +312,8 @@ static void HandleHallOfFame_SelectLevel(int, int); static char *getHallOfFameRankText(int, int); static char *getHallOfFameScoreText(int, int); +static struct TokenInfo *getSetupInfoFinal(struct TokenInfo *); + static struct GadgetInfo *screen_gadget[NUM_SCREEN_GADGETS]; static int info_mode = INFO_MODE_MAIN; @@ -1456,6 +1458,11 @@ static void clearMenuListArea(void) // clear menu list area, but not title or scrollbar DrawBackground(mSX, mSY + MENU_SCREEN_START_YPOS * 32, scrollbar_xpos - mSX, NUM_MENU_ENTRIES_ON_SCREEN * 32); + + // special compatibility handling for "Snake Bite" graphics set + if (strPrefix(leveldir_current->identifier, "snake_bite")) + ClearRectangle(drawto, mSX, mSY + MENU_SCREEN_START_YPOS * 32, + scrollbar_xpos - mSX, NUM_MENU_ENTRIES_ON_SCREEN * 32); } static void drawCursorExt(int xpos, int ypos, boolean active, int graphic) @@ -1524,6 +1531,15 @@ static int getChooseTreeEditYPos(int ypos_raw) return sy; } +static int getChooseTreeEditXPosReal(int pos) +{ + int xpos = getChooseTreeEditXPos(pos); + int font_nr = getChooseTreeEditFont(FALSE); + int font_xoffset = getFontDrawOffsetX(font_nr); + + return xpos + font_xoffset; +} + static void drawChooseTreeEdit(int ypos_raw, boolean active) { int sx = getChooseTreeEditXPos(POS_LEFT); @@ -1705,6 +1721,9 @@ void DrawMainMenu(void) return; } + // reset flag to continue playing next level from hall of fame + scores.continue_playing = FALSE; + // leveldir_current may be invalid (level group, parent link, node copy) leveldir_current = getValidLevelSeries(leveldir_current, leveldir_last_valid); @@ -2064,7 +2083,7 @@ static void HandleMainMenu_SelectLevel(int step, int direction, { // skipping levels is only allowed when trying to skip single level if (setup.skip_levels && new_level_nr == old_level_nr + 1 && - Request("Level still unsolved! Skip despite handicap?", REQ_ASK)) + Request("Level still unsolved! Skip it anyway?", REQ_ASK)) { leveldir_current->handicap_level++; SaveLevelSetup_SeriesInfo(); @@ -2557,6 +2576,9 @@ static void DrawInfoScreen_Main(void) info_info = info_info_main; + // use modified info screen info without info screen entries marked as hidden + info_info = getSetupInfoFinal(info_info); + // determine maximal number of info entries that can be displayed on screen num_info_info = 0; for (i = 0; info_info[i].type != 0 && i < NUM_MENU_ENTRIES_ON_SCREEN; i++) @@ -3988,7 +4010,7 @@ static int getPlayerNameColor(char *name) } static void drawTypeNameText(char *name, struct TextPosInfo *pos, - boolean active) + boolean active) { char text[MAX_PLAYER_NAME_LEN + 2] = { 0 }; boolean multiple_users = (game_status == GAME_MODE_PSEUDO_TYPENAMES); @@ -3996,8 +4018,12 @@ static void drawTypeNameText(char *name, struct TextPosInfo *pos, int sy = (multiple_users ? amSY + pos->y : mSY + ALIGNED_TEXT_YPOS(pos)); int font_nr = (active ? FONT_ACTIVE(pos->font) : pos->font); int font_width = getFontWidth(font_nr); + int font_xoffset = getFontDrawOffsetX(font_nr); + int font_yoffset = getFontDrawOffsetY(font_nr); + int font_sx = sx + font_xoffset; + int font_sy = sy + font_yoffset; - DrawBackgroundForFont(sx, sy, pos->width, pos->height, font_nr); + DrawBackgroundForFont(font_sx, font_sy, pos->width, pos->height, font_nr); sprintf(text, "%s%c", name, (active ? '_' : '\0')); @@ -4313,12 +4339,23 @@ static int getAlignYOffsetFromTreeInfo(TreeInfo *ti) return align_yoffset; } +static void StartPlayingFromHallOfFame(void) +{ + level_nr = scores.next_level_nr; + LoadLevel(level_nr); + + StartGameActions(network.enabled, setup.autorecord, level.random_seed); +} + static void DrawChooseTree(TreeInfo **ti_ptr) { int fade_mask = REDRAW_FIELD; boolean restart_music = (game_status != game_status_last_screen && game_status_last_screen != GAME_MODE_SCOREINFO); + scores.continue_on_return = (game_status == GAME_MODE_SCORES && + game_status_last_screen == GAME_MODE_PLAYING); + if (CheckFadeAll()) fade_mask = REDRAW_ALL; @@ -4328,7 +4365,11 @@ static void DrawChooseTree(TreeInfo **ti_ptr) { execSetupArtwork(); } - else // GAME_MODE_LEVELS + else if (game_status == GAME_MODE_SCORES && scores.continue_playing) + { + StartPlayingFromHallOfFame(); + } + else { SetGameStatus(GAME_MODE_MAIN); @@ -4628,8 +4669,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, boolean has_scrollbar = screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->mapped; int mx_scrollbar = screen_gadget[SCREEN_CTRL_ID_SCROLL_VERTICAL]->x; int mx_right_border = (has_scrollbar ? mx_scrollbar : SX + SXSIZE); - int sx1_edit_name = getChooseTreeEditXPos(POS_LEFT); - int sx2_edit_name = getChooseTreeEditXPos(POS_RIGHT); + int sx1_edit_name = getChooseTreeEditXPosReal(POS_LEFT); + int sx2_edit_name = getChooseTreeEditXPosReal(POS_RIGHT); int x = 0; int y = (ti != NULL ? ti->cl_cursor : 0); int step = (button == 1 ? 1 : button == 2 ? 5 : 10); @@ -4771,6 +4812,23 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, return; } +#if defined(PLATFORM_ANDROID) + // directly continue when touching the screen after playing + if ((mx || my) && scores.continue_on_return) + { + // ignore touch events until released + mx = my = 0; + } +#endif + + // any mouse click or cursor key stops leaving scores by "Return" key + if ((mx || my || dx || dy) && scores.continue_on_return) + { + scores.continue_on_return = FALSE; + level_nr = scores.last_level_nr; + LoadLevel(level_nr); + } + if (mx || my) // mouse input { x = (mx - amSX) / 32; @@ -4850,15 +4908,17 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, node_cursor->cl_first = ti->cl_first; node_cursor->cl_cursor = ti->cl_cursor; + *ti_ptr = node_cursor->node_group; DrawChooseTree(ti_ptr); return; } } - else if (dx == -1 && ti->node_parent) + else if ((dx == -1 || button == MB_MENU_CONTINUE) && ti->node_parent) { - FadeSetLeaveMenu(); + if (game_status != GAME_MODE_SCORES) + FadeSetLeaveMenu(); PlaySound(SND_MENU_ITEM_SELECTING); @@ -4941,6 +5001,7 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, node_cursor->cl_first = ti->cl_first; node_cursor->cl_cursor = ti->cl_cursor; + *ti_ptr = node_cursor->node_group; DrawChooseTree(ti_ptr); } @@ -4959,6 +5020,7 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, node_cursor->cl_first = ti->cl_first; node_cursor->cl_cursor = ti->cl_cursor; + *ti_ptr = node_cursor; if (ti->type == TREE_TYPE_LEVEL_DIR) @@ -5049,16 +5111,13 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, } else if (game_status == GAME_MODE_SCORES) { - if (game_status_last_screen == GAME_MODE_PLAYING && - setup.auto_play_next_level && setup.increment_levels && - scores.last_level_nr < leveldir_current->last_level && - !network_playing) + if (scores.continue_playing && scores.continue_on_return) { - StartGameActions(network.enabled, setup.autorecord, - level.random_seed); + StartPlayingFromHallOfFame(); + return; } - else + else if (!scores.continue_on_return) { SetGameStatus(GAME_MODE_SCOREINFO); @@ -5122,6 +5181,9 @@ void DrawChoosePlayerName(void) if (player_name_current == NULL) player_name_current = player_name; + // set text size for main name input (also used on name selection screen) + InitializeMainControls(); + DrawChooseTree(&player_name_current); } @@ -5252,12 +5314,15 @@ static void DrawHallOfFame_setScoreEntries(void) if (score_entry_current == NULL) score_entry_current = getFirstValidTreeInfoEntry(score_entries); + if (score_entries != NULL && scores.continue_playing) + setString(&score_entries->node_group->name, BACKLINK_TEXT_NEXT); + // ("score_entries" and "score_entry_current" may be NULL here) } -void DrawHallOfFame(int level_nr) +void DrawHallOfFame(int nr) { - scores.last_level_nr = level_nr; + scores.last_level_nr = nr; // (this is needed when called from GameEnd() after winning a game) KeyboardAutoRepeatOn(); @@ -5266,7 +5331,7 @@ void DrawHallOfFame(int level_nr) SetDrawDeactivationMask(REDRAW_NONE); SetDrawBackgroundMask(REDRAW_FIELD); - LoadLocalAndServerScore(level_nr, TRUE); + LoadLocalAndServerScore(scores.last_level_nr, TRUE); DrawHallOfFame_setScoreEntries(); @@ -5311,6 +5376,28 @@ static char *getHallOfFameScoreText(int nr, int size) return getHallOfFameTimeText(nr); // show playing time } +static char *getHallOfFameTapeDateText(struct ScoreEntry *entry) +{ + static char tape_date[MAX_ISO_DATE_LEN + 1]; + int i, j; + + if (!strEqual(entry->tape_date, UNKNOWN_NAME) || + strEqual(entry->tape_basename, UNDEFINED_FILENAME)) + return entry->tape_date; + + for (i = 0, j = 0; i < 8; i++, j++) + { + tape_date[j] = entry->tape_basename[i]; + + if (i == 3 || i == 5) + tape_date[++j] = '-'; + } + + tape_date[MAX_ISO_DATE_LEN] = '\0'; + + return tape_date; +} + static void HandleHallOfFame_SelectLevel(int step, int direction) { int old_level_nr = scores.last_level_nr; @@ -5367,6 +5454,7 @@ static void DrawScoreInfo_Content(int entry_nr) { struct ScoreEntry *entry = &scores.entry[entry_nr]; char *pos_text = getHallOfFameRankText(entry_nr, 0); + char *tape_date = getHallOfFameTapeDateText(entry); int font_title = MENU_INFO_FONT_TITLE; int font_head = MENU_INFO_FONT_HEAD; int font_text = MENU_INFO_FONT_TEXT; @@ -5378,27 +5466,28 @@ static void DrawScoreInfo_Content(int entry_nr) int ystep_title = getMenuTextStep(spacing_title, font_title); int ystep_para = getMenuTextStep(spacing_para, font_text); int ystep_line = getMenuTextStep(spacing_line, font_text); + int xstart = mSX - SX + menu.left_spacing[GAME_MODE_SCOREINFO]; int ystart = mSY - SY + menu.top_spacing[GAME_MODE_SCOREINFO]; int ybottom = mSY - SY + SYSIZE - menu.bottom_spacing[GAME_MODE_SCOREINFO]; - int xstart1 = mSX - SX + 2 * xstep; - int xstart2 = mSX - SX + 13 * xstep; + int xstart1 = xstart + xstep; + int xstart2 = xstart + xstep * 12; int select_x = SX + xstart1; int select_y1, select_y2; int play_x, play_y; int play_height = screen_gadget[SCREEN_CTRL_ID_PLAY_TAPE]->height; - boolean play_visible = (entry->id != -1); + boolean play_visible = !strEqual(tape_date, UNKNOWN_NAME); int font_width = getFontWidth(font_text); int font_height = getFontHeight(font_text); - int tape_date_width = getTextWidth(entry->tape_date, font_text); + int tape_date_width = getTextWidth(tape_date, font_text); int pad_left = xstart2; - int pad_right = MENU_SCREEN_INFO_SPACE_RIGHT; + int pad_right = menu.right_spacing[GAME_MODE_SCOREINFO]; int max_chars_per_line = (SXSIZE - pad_left - pad_right) / font_width; int max_lines_per_text = 5; int lines; ClearField(); - // redraw score selection buttons (which have just been erased) + // redraw level selection buttons (which have just been erased) RedrawScreenMenuGadgets(SCREEN_MASK_SCORES); if (score_entries == NULL) @@ -5463,7 +5552,7 @@ static void DrawScoreInfo_Content(int entry_nr) play_y = SY + ystart + (font_height - play_height) / 2; DrawTextF(xstart1, ystart, font_head, "Tape Date"); - DrawTextF(xstart2, ystart, font_text, entry->tape_date); + DrawTextF(xstart2, ystart, font_text, tape_date); ystart += ystep_line; DrawTextF(xstart1, ystart, font_head, "Platform"); @@ -5493,12 +5582,29 @@ static void DrawScoreInfo(int entry_nr) scores.last_entry_nr = entry_nr; score_info_tape_play = FALSE; - SetMainBackgroundImageIfDefined(IMG_BACKGROUND_SCOREINFO); - UnmapAllGadgets(); + FreeScreenGadgets(); + CreateScreenGadgets(); + FadeOut(REDRAW_FIELD); + // needed if different viewport properties defined after playing score tape + ChangeViewportPropertiesIfNeeded(); + + // set this after "ChangeViewportPropertiesIfNeeded()" (which may reset it) + SetDrawDeactivationMask(REDRAW_NONE); + SetDrawBackgroundMask(REDRAW_FIELD); + + // needed if different background image defined after playing score tape + SetMainBackgroundImage(IMG_BACKGROUND_SCORES); + SetMainBackgroundImageIfDefined(IMG_BACKGROUND_SCOREINFO); + + // special compatibility handling for "Snake Bite" graphics set + if (strPrefix(leveldir_current->identifier, "snake_bite")) + ClearRectangle(gfx.background_bitmap, gfx.real_sx, gfx.real_sy + 64, + gfx.full_sxsize, gfx.full_sysize - 64); + DrawScoreInfo_Content(entry_nr); // map gadgets for score info screen @@ -5561,7 +5667,7 @@ void HandleScoreInfo(int mx, int my, int dx, int dy, int button) SetGameStatus(GAME_MODE_SCORES); - DrawHallOfFame(level_nr); + DrawHallOfFame(scores.last_level_nr); } else if (dx) { @@ -7153,6 +7259,15 @@ static struct { &setup.internal.menu_exit, execExitSetup }, { &setup.internal.menu_save_and_exit, execSaveAndExitSetup }, + { &setup.internal.info_title, execInfoTitleScreen }, + { &setup.internal.info_elements, execInfoElements }, + { &setup.internal.info_music, execInfoMusic }, + { &setup.internal.info_credits, execInfoCredits }, + { &setup.internal.info_program, execInfoProgram }, + { &setup.internal.info_version, execInfoVersion }, + { &setup.internal.info_levelset, execInfoLevelSet }, + { &setup.internal.info_exit, execExitInfo }, + { NULL, NULL } }; @@ -7197,8 +7312,8 @@ static struct TokenInfo setup_info_game[] = { TYPE_SWITCH, &setup.multiple_users, "Multiple Users/Teams:" }, { TYPE_YES_NO, &setup.input_on_focus, "Only Move Focussed Player:" }, { TYPE_SWITCH, &setup.time_limit, "Time Limit:" }, - { TYPE_SWITCH, &setup.handicap, "Handicap:" }, - { TYPE_SWITCH, &setup.skip_levels, "Skip Unsolved Levels:" }, + { TYPE_SWITCH, &setup.handicap, "Force Solving Levels:" }, + { TYPE_SWITCH, &setup.skip_levels, "Allow Skipping Levels:" }, { TYPE_SWITCH, &setup.increment_levels,"Increment Solved Levels:" }, { TYPE_SWITCH, &setup.auto_play_next_level,"Auto-play Next Level:" }, { TYPE_SWITCH, &setup.count_score_after_game,"Count Score After Game:" }, @@ -9671,12 +9786,18 @@ static void CreateScreenMenubuttons(void) // if x/y set to -1, dynamically place buttons next to title text int title_width = getTextWidth(INFOTEXT_SCORE_ENTRY, FONT_TITLE_1); + // special compatibility handling for "Snake Bite" graphics set + if (strPrefix(leveldir_current->identifier, "snake_bite")) + title_width = strlen(INFOTEXT_SCORE_ENTRY) * 32; + + // use "SX" here to center buttons (ignore horizontal draw offset) if (pos->x == -1) x = (id == SCREEN_CTRL_ID_PREV_LEVEL2 ? SX + (SXSIZE - title_width) / 2 - width * 3 / 2 : id == SCREEN_CTRL_ID_NEXT_LEVEL2 ? SX + (SXSIZE + title_width) / 2 + width / 2 : 0); + // use "mSY" here to place buttons (respect vertical draw offset) if (pos->y == -1) y = (id == SCREEN_CTRL_ID_PREV_LEVEL2 || id == SCREEN_CTRL_ID_NEXT_LEVEL2 ? mSY + MENU_TITLE1_YPOS : 0); @@ -10185,6 +10306,12 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) } } +void HandleScreenGadgetKeys(Key key) +{ + if (key == setup.shortcut.tape_play) + HandleScreenGadgets(screen_gadget[SCREEN_CTRL_ID_PLAY_TAPE]); +} + void DumpScreenIdentifiers(void) { int i;