X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fscreens.c;h=b4f2e5fc8d46003189d0d2abf4c0435be3226116;hp=d1310895fb19e632ba05ebe7d4effc5ee3451ab5;hb=12677c5a393c075d0f2d8ff25604e44e310763df;hpb=c981ce2708040be6519fa2694c6ea8b4d9c51a27 diff --git a/src/screens.c b/src/screens.c index d1310895..b4f2e5fc 100644 --- a/src/screens.c +++ b/src/screens.c @@ -174,18 +174,25 @@ // screen gadget identifiers #define SCREEN_CTRL_ID_PREV_LEVEL 0 #define SCREEN_CTRL_ID_NEXT_LEVEL 1 -#define SCREEN_CTRL_ID_PREV_PLAYER 2 -#define SCREEN_CTRL_ID_NEXT_PLAYER 3 -#define SCREEN_CTRL_ID_INSERT_SOLUTION 4 -#define SCREEN_CTRL_ID_PLAY_SOLUTION 5 -#define SCREEN_CTRL_ID_SCROLL_UP 6 -#define SCREEN_CTRL_ID_SCROLL_DOWN 7 -#define SCREEN_CTRL_ID_SCROLL_VERTICAL 8 -#define SCREEN_CTRL_ID_NETWORK_SERVER 9 - -#define NUM_SCREEN_GADGETS 10 - -#define NUM_SCREEN_MENUBUTTONS 6 +#define SCREEN_CTRL_ID_FIRST_LEVEL 2 +#define SCREEN_CTRL_ID_LAST_LEVEL 3 +#define SCREEN_CTRL_ID_LEVEL_NUMBER 4 +#define SCREEN_CTRL_ID_PREV_PLAYER 5 +#define SCREEN_CTRL_ID_NEXT_PLAYER 6 +#define SCREEN_CTRL_ID_INSERT_SOLUTION 7 +#define SCREEN_CTRL_ID_PLAY_SOLUTION 8 +#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE 9 +#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE 10 +#define SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 11 +#define SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 12 +#define SCREEN_CTRL_ID_SCROLL_UP 13 +#define SCREEN_CTRL_ID_SCROLL_DOWN 14 +#define SCREEN_CTRL_ID_SCROLL_VERTICAL 15 +#define SCREEN_CTRL_ID_NETWORK_SERVER 16 + +#define NUM_SCREEN_GADGETS 17 + +#define NUM_SCREEN_MENUBUTTONS 13 #define NUM_SCREEN_SCROLLBUTTONS 2 #define NUM_SCREEN_SCROLLBARS 1 #define NUM_SCREEN_TEXTINPUT 1 @@ -193,6 +200,8 @@ #define SCREEN_MASK_MAIN (1 << 0) #define SCREEN_MASK_MAIN_HAS_SOLUTION (1 << 1) #define SCREEN_MASK_INPUT (1 << 2) +#define SCREEN_MASK_TOUCH (1 << 3) +#define SCREEN_MASK_TOUCH2 (1 << 4) // graphic position and size values for buttons and scrollbars #define SC_MENUBUTTON_XSIZE TILEX @@ -255,6 +264,7 @@ static void ModifyGameSpeedIfNeeded(void); static void DisableVsyncIfNeeded(void); static void MapScreenMenuGadgets(int); +static void UnmapScreenMenuGadgets(int); static void MapScreenGadgets(int); static void MapScreenTreeGadgets(TreeInfo *); @@ -520,6 +530,9 @@ static struct ValueTextInfo grid_sizes_list[] = { -1, NULL }, }; +static int align_xoffset = 0; +static int align_yoffset = 0; + #define DRAW_MODE(s) ((s) >= GAME_MODE_MAIN && \ (s) <= GAME_MODE_SETUP ? (s) : \ (s) == GAME_MODE_PSEUDO_TYPENAME ? \ @@ -576,6 +589,9 @@ static struct ValueTextInfo grid_sizes_list[] = #define mSX (SX + DRAW_XOFFSET(game_status)) #define mSY (SY + DRAW_YOFFSET(game_status)) +#define amSX (mSX + align_xoffset) +#define amSY (mSY + align_yoffset) + #define NUM_MENU_ENTRIES_ON_SCREEN (menu.list_size[game_status] > 2 ? \ menu.list_size[game_status] : \ MAX_MENU_ENTRIES_ON_SCREEN) @@ -724,36 +740,33 @@ static struct MainControlInfo main_controls[] = &menu.main.text.quit, &main_text_quit, NULL, NULL, }, -#if 0 - // (these two buttons are real gadgets) { MAIN_CONTROL_PREV_LEVEL, - &menu.main.button.prev_level, IMG_MENU_BUTTON_PREV_LEVEL, + NULL, -1, NULL, NULL, NULL, NULL, }, { MAIN_CONTROL_NEXT_LEVEL, - &menu.main.button.next_level, IMG_MENU_BUTTON_NEXT_LEVEL, + NULL, -1, NULL, NULL, NULL, NULL, }, -#endif { MAIN_CONTROL_FIRST_LEVEL, - &menu.main.button.first_level, IMG_MENU_BUTTON_FIRST_LEVEL, + NULL, -1, &menu.main.text.first_level, &main_text_first_level, NULL, NULL, }, { MAIN_CONTROL_LAST_LEVEL, - &menu.main.button.last_level, IMG_MENU_BUTTON_LAST_LEVEL, + NULL, -1, &menu.main.text.last_level, &main_text_last_level, NULL, NULL, }, { MAIN_CONTROL_LEVEL_NUMBER, - &menu.main.button.level_number, IMG_MENU_BUTTON_LEVEL_NUMBER, + NULL, -1, &menu.main.text.level_number, &main_text_level_number, NULL, NULL, }, @@ -982,6 +995,7 @@ static struct TitleFadingInfo getTitleFading(struct TitleControlInfo *tci) ti.fade_delay = tmi.fade_delay; ti.post_delay = tmi.post_delay; ti.auto_delay = tmi.auto_delay; + ti.auto_delay_unit = tmi.auto_delay_unit; return ti; } @@ -1364,8 +1378,8 @@ static void clearMenuListArea(void) static void drawCursorExt(int xpos, int ypos, boolean active, int graphic) { static int cursor_array[MAX_LEV_FIELDY]; - int x = mSX + TILEX * xpos; - int y = mSY + TILEY * (MENU_SCREEN_START_YPOS + ypos); + int x = amSX + TILEX * xpos; + int y = amSY + TILEY * (MENU_SCREEN_START_YPOS + ypos); if (xpos == 0) { @@ -1684,14 +1698,9 @@ static void gotoTopLevelDir(void) { int num_leveldirs = numTreeInfoInGroup(leveldir_current); int leveldir_pos = posTreeInfo(leveldir_current); - int num_page_entries; + int num_page_entries = MIN(num_leveldirs, NUM_MENU_ENTRIES_ON_SCREEN); int cl_first, cl_cursor; - if (num_leveldirs <= NUM_MENU_ENTRIES_ON_SCREEN) - num_page_entries = num_leveldirs; - else - num_page_entries = NUM_MENU_ENTRIES_ON_SCREEN; - cl_first = MAX(0, leveldir_pos - num_page_entries + 1); cl_cursor = leveldir_pos - cl_first; @@ -1703,6 +1712,25 @@ static void gotoTopLevelDir(void) } } +static unsigned int getAutoDelayCounter(struct TitleFadingInfo *fi) +{ + boolean use_frame_counter = (fi->auto_delay_unit == AUTO_DELAY_UNIT_FRAMES); + + return (use_frame_counter ? video.frame_counter : Counter()); +} + +static boolean TitleAutoDelayReached(unsigned int *counter_var, + struct TitleFadingInfo *fi) +{ + return DelayReachedExt(counter_var, fi->auto_delay, getAutoDelayCounter(fi)); +} + +static void ResetTitleAutoDelay(unsigned int *counter_var, + struct TitleFadingInfo *fi) +{ + *counter_var = getAutoDelayCounter(fi); +} + void HandleTitleScreen(int mx, int my, int dx, int dy, int button) { static unsigned int title_delay = 0; @@ -1745,10 +1773,10 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) "No title screen for this level set."); return; } - - FadeMenuSoundsAndMusic(); } + FadeMenuSoundsAndMusic(); + FadeOut(REDRAW_ALL); // title screens may have different window size @@ -1777,12 +1805,12 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) FadeIn(REDRAW_ALL); - DelayReached(&title_delay, 0); // reset delay counter + ResetTitleAutoDelay(&title_delay, &fading); return; } - if (fading.auto_delay > 0 && DelayReached(&title_delay, fading.auto_delay)) + if (fading.auto_delay > 0 && TitleAutoDelayReached(&title_delay, &fading)) button = MB_MENU_CHOICE; if (button == MB_MENU_LEAVE) @@ -1840,7 +1868,7 @@ void HandleTitleScreen(int mx, int my, int dx, int dy, int button) FadeIn(REDRAW_ALL); - DelayReached(&title_delay, 0); // reset delay counter + ResetTitleAutoDelay(&title_delay, &fading); } else { @@ -1905,7 +1933,7 @@ static void HandleMainMenu_SelectLevel(int step, int direction, if (new_level_nr != old_level_nr) { - struct MainControlInfo *mci= getMainControlInfo(MAIN_CONTROL_LEVEL_NUMBER); + struct MainControlInfo *mci = getMainControlInfo(MAIN_CONTROL_LEVEL_NUMBER); PlaySound(SND_MENU_ITEM_SELECTING); @@ -1926,9 +1954,8 @@ static void HandleMainMenu_SelectLevel(int step, int direction, UpdateScreenMenuGadgets(SCREEN_MASK_MAIN_HAS_SOLUTION, hasSolutionTape()); - // needed because DrawPreviewLevelInitial() takes some time - BackToFront(); - // SyncDisplay(); + // force redraw of playfield area (may be reset at this point) + redraw_mask |= REDRAW_FIELD; } } @@ -1938,7 +1965,7 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) static boolean button_pressed_last = FALSE; boolean button_pressed = FALSE; int pos = choice; - int i; + int i = 0; // needed to prevent compiler warning due to bad code below if (button == MB_MENU_INITIALIZE) { @@ -2035,9 +2062,23 @@ void HandleMainMenu(int mx, int my, int dx, int dy, int button) if (pos == MAIN_CONTROL_NAME) { - SetGameStatus(GAME_MODE_PSEUDO_TYPENAME); + if ((mx || my) && + insideTextPosRect(main_controls[i].pos_text, mx - mSX, my - mSY)) + { + // special case: menu text "name/team" clicked -- toggle team mode + setup.team_mode = !setup.team_mode; + + InitializeMainControls(); + DrawCursorAndText_Main(choice, TRUE, FALSE); + + DrawPreviewPlayers(); + } + else + { + SetGameStatus(GAME_MODE_PSEUDO_TYPENAME); - HandleTypeName(strlen(setup.player_name), 0); + HandleTypeName(strlen(setup.player_name), 0); + } } else if (pos == MAIN_CONTROL_LEVELS) { @@ -3976,6 +4017,51 @@ void HandleTypeName(int newxpos, Key key) // tree menu functions // ============================================================================ +static int getAlignXOffsetFromTreeInfo(TreeInfo *ti) +{ + if (game_status != GAME_MODE_SETUP || + DRAW_MODE_SETUP(setup_mode) != SETUP_MODE_CHOOSE_OTHER) + return 0; + + int max_text_size = 0; + TreeInfo *node; + + for (node = getTreeInfoFirstGroupEntry(ti); node != NULL; node = node->next) + max_text_size = MAX(max_text_size, strlen(node->name)); + + int num_entries = numTreeInfoInGroup(ti); + boolean scrollbar_needed = (num_entries > NUM_MENU_ENTRIES_ON_SCREEN); + int text_width = max_text_size * getFontWidth(FONT_TEXT_1); + int button_width = SC_MENUBUTTON_XSIZE; + int scrollbar_xpos = SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset; + int screen_width = (scrollbar_needed ? scrollbar_xpos : SXSIZE); + int align = menu.list_setup[SETUP_MODE_CHOOSE_OTHER].align; + int x = ALIGNED_XPOS(0, screen_width, align) * -1; + int align_xoffset_raw = ALIGNED_XPOS(x, button_width + text_width, align); + int align_xoffset = MAX(0, align_xoffset_raw); + + return align_xoffset; +} + +static int getAlignYOffsetFromTreeInfo(TreeInfo *ti) +{ + if (game_status != GAME_MODE_SETUP || + DRAW_MODE_SETUP(setup_mode) != SETUP_MODE_CHOOSE_OTHER) + return 0; + + int num_entries = numTreeInfoInGroup(ti); + int num_page_entries = MIN(num_entries, NUM_MENU_ENTRIES_ON_SCREEN); + int font_height = getFontHeight(FONT_TEXT_1); + int text_height = font_height * num_page_entries; + int page_height = font_height * NUM_MENU_ENTRIES_ON_SCREEN; + int align = menu.list_setup[SETUP_MODE_CHOOSE_OTHER].valign; + int y = ALIGNED_YPOS(0, page_height, align) * -1; + int align_yoffset_raw = ALIGNED_YPOS(y, text_height, align); + int align_yoffset = MAX(0, align_yoffset_raw); + + return align_yoffset; +} + static void DrawChooseTree(TreeInfo **ti_ptr) { int fade_mask = REDRAW_FIELD; @@ -4022,6 +4108,12 @@ static void DrawChooseTree(TreeInfo **ti_ptr) static void drawChooseTreeList(int first_entry, int num_page_entries, TreeInfo *ti) { + int num_entries = numTreeInfoInGroup(ti); + boolean scrollbar_needed = (num_entries > NUM_MENU_ENTRIES_ON_SCREEN); + int scrollbar_xpos = SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset; + int screen_width = (scrollbar_needed ? scrollbar_xpos : SXSIZE); + int font_nr = FONT_TEXT_1; + int font_xoffset = getFontBitmapInfo(font_nr)->draw_xoffset; int i; char *title_string = NULL; int yoffset_sets = MENU_TITLE1_YPOS; @@ -4041,14 +4133,12 @@ static void drawChooseTreeList(int first_entry, int num_page_entries, int entry_pos = first_entry + i; int xpos = MENU_SCREEN_START_XPOS; int ypos = MENU_SCREEN_START_YPOS + i; - int startx = mSX + xpos * 32; - int starty = mSY + ypos * 32; - int font_nr = FONT_TEXT_1; - int font_xoffset = getFontBitmapInfo(font_nr)->draw_xoffset; + int startx = amSX + xpos * 32; + int starty = amSY + ypos * 32; int startx_text = startx + font_xoffset; - int startx_scrollbar = mSX + SC_SCROLLBAR_XPOS + menu.scrollbar_xoffset; - int text_size = startx_scrollbar - startx_text; - int max_buffer_len = text_size / getFontWidth(font_nr); + int endx_text = amSX + screen_width; + int max_text_size = endx_text - startx_text; + int max_buffer_len = max_text_size / getFontWidth(font_nr); char buffer[max_buffer_len + 1]; node_first = getTreeInfoFirstGroupEntry(ti); @@ -4113,19 +4203,17 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, int y = ti->cl_cursor; int step = (button == 1 ? 1 : button == 2 ? 5 : 10); int num_entries = numTreeInfoInGroup(ti); - int num_page_entries; + int num_page_entries = MIN(num_entries, NUM_MENU_ENTRIES_ON_SCREEN); boolean position_set_by_scrollbar = (dx == 999); - if (num_entries <= NUM_MENU_ENTRIES_ON_SCREEN) - num_page_entries = num_entries; - else - num_page_entries = NUM_MENU_ENTRIES_ON_SCREEN; - if (button == MB_MENU_INITIALIZE) { int num_entries = numTreeInfoInGroup(ti); int entry_pos = posTreeInfo(ti); + align_xoffset = getAlignXOffsetFromTreeInfo(ti); + align_yoffset = getAlignYOffsetFromTreeInfo(ti); + if (ti->cl_first == -1) { // only on initialization @@ -4210,8 +4298,8 @@ static void HandleChooseTree(int mx, int my, int dx, int dy, int button, if (mx || my) // mouse input { - x = (mx - mSX) / 32; - y = (my - mSY) / 32 - MENU_SCREEN_START_YPOS; + x = (mx - amSX) / 32; + y = (my - amSY) / 32 - MENU_SCREEN_START_YPOS; } else if (dx || dy) // keyboard or scrollbar/scrollbutton input { @@ -4469,7 +4557,7 @@ void DrawChooseLevelNr(void) for (i = leveldir_current->first_level; i <= leveldir_current->last_level;i++) { TreeInfo *ti = newTreeInfo_setDefaults(TREE_TYPE_LEVEL_NR); - char identifier[32], name[32]; + char identifier[32], name[64]; int value = i; // temporarily load level info to get level name @@ -4644,7 +4732,8 @@ void HandleHallOfFame(int mx, int my, int dx, int dy, int button) FadeSound(SND_BACKGROUND_SCORES); - if (game_status_last_screen == GAME_MODE_PLAYING && + if (button == MB_MENU_CHOICE && + game_status_last_screen == GAME_MODE_PLAYING && setup.auto_play_next_level && setup.increment_levels && level_nr < leveldir_current->last_level && !network_playing) @@ -6103,6 +6192,17 @@ static struct { &setup.touch.grid_ysize[1], execSetupChooseGridYSize_1 }, { &setup.touch.grid_ysize[1], &grid_size_text[1][1] }, + { &setup.internal.menu_game, execSetupGame }, + { &setup.internal.menu_editor, execSetupEditor }, + { &setup.internal.menu_graphics, execSetupGraphics }, + { &setup.internal.menu_sound, execSetupSound }, + { &setup.internal.menu_artwork, execSetupArtwork }, + { &setup.internal.menu_input, execSetupInput }, + { &setup.internal.menu_touch, execSetupTouch }, + { &setup.internal.menu_shortcuts, execSetupShortcuts }, + { &setup.internal.menu_exit, execExitSetup }, + { &setup.internal.menu_save_and_exit, execSaveAndExitSetup }, + { NULL, NULL } }; @@ -7792,6 +7892,22 @@ void ConfigureJoystick(int player_nr) DrawSetupScreen_Input(); } +static void MapScreenMenuGadgets_OverlayTouchButtons(int y) +{ + if (y < video.screen_height / 3) + { + // remap touch gadgets to access upper part of the screen + UnmapScreenMenuGadgets(SCREEN_MASK_TOUCH); + MapScreenMenuGadgets(SCREEN_MASK_TOUCH2); + } + else if (y > 2 * video.screen_height / 3) + { + // remap touch gadgets to access lower part of the screen + MapScreenMenuGadgets(SCREEN_MASK_TOUCH); + UnmapScreenMenuGadgets(SCREEN_MASK_TOUCH2); + } +} + static boolean ConfigureVirtualButtonsMain(void) { static char *customize_step_text[] = @@ -7812,6 +7928,13 @@ static boolean ConfigureVirtualButtonsMain(void) CHAR_GRID_BUTTON_SNAP, CHAR_GRID_BUTTON_DROP }; + enum + { + ACTION_NONE, + ACTION_ESCAPE, + ACTION_BACK, + ACTION_NEXT + }; int font_nr = FONT_INPUT_1_ACTIVE; int font_height = getFontHeight(font_nr); int ypos1 = SYSIZE / 2 - font_height * 2; @@ -7845,80 +7968,45 @@ static boolean ConfigureVirtualButtonsMain(void) SetOverlayShowGrid(TRUE); + // map gadgets for setup touch buttons menu screen + MapScreenMenuGadgets(SCREEN_MASK_TOUCH); + while (!finished) { Event event; while (NextValidEvent(&event)) { + int action = ACTION_NONE; + + // ---------- handle events and set the resulting action ---------- + switch (event.type) { + case EVENT_USER: + { + UserEvent *user = (UserEvent *)&event; + int id = user->value1; + + action = (id == SCREEN_CTRL_ID_TOUCH_PREV_PAGE || + id == SCREEN_CTRL_ID_TOUCH_PREV_PAGE2 ? ACTION_BACK : + id == SCREEN_CTRL_ID_TOUCH_NEXT_PAGE || + id == SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2 ? ACTION_NEXT : + ACTION_NONE); + } + break; + case EVENT_KEYPRESS: { Key key = GetEventKey((KeyEvent *)&event, FALSE); - // press 'Escape' to abort and keep the old key bindings - if (key == KSYM_Escape) - { - for (x = 0; x < MAX_GRID_XSIZE; x++) - for (y = 0; y < MAX_GRID_YSIZE; y++) - overlay.grid_button[x][y] = grid_button_old[x][y]; - - FadeSkipNextFadeIn(); - - finished = TRUE; - - break; - } - - // press 'Enter' to keep the existing key binding - if (key == KSYM_Return || - key == KSYM_Menu || - key == KSYM_space) - { - step_nr++; - } - else if (key == KSYM_BackSpace || - key == KSYM_Back) - { - if (step_nr == 0) - { - FadeSkipNextFadeIn(); - - finished = TRUE; - - break; - } - - step_nr--; - } - else - { - break; - } - - // all virtual buttons configured - if (step_nr == 6) - { - finished = TRUE; - success = TRUE; - - break; - } - - for (x = 0; x < MAX_GRID_XSIZE; x++) - for (y = 0; y < MAX_GRID_YSIZE; y++) - grid_button_tmp[x][y] = overlay.grid_button[x][y]; - - overlay.grid_button_highlight = grid_button[step_nr]; - - // query next virtual button - - ClearField(); - - DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Virtual Buttons"); - DrawTextSCentered(ypos1, font_nr, "Select tiles to"); - DrawTextSCentered(ypos2, font_nr, customize_step_text[step_nr]); + action = (key == KSYM_Escape ? ACTION_ESCAPE : + key == KSYM_BackSpace || + key == KSYM_Back ? ACTION_BACK : + key == KSYM_Return || + key == KSYM_Menu || + key == KSYM_space ? ACTION_NEXT : + ACTION_NONE); } break; @@ -7931,6 +8019,19 @@ static boolean ConfigureVirtualButtonsMain(void) { ButtonEvent *button = (ButtonEvent *)&event; + motion_status = FALSE; + + if (button->type == EVENT_BUTTONPRESS) + button_status = button->button; + else + button_status = MB_RELEASED; + + if (HandleGadgets(button->x, button->y, button_status)) + { + // do not handle this button event anymore + break; + } + button->x += video.screen_xoffset; button->y += video.screen_yoffset; @@ -7939,18 +8040,14 @@ static boolean ConfigureVirtualButtonsMain(void) if (button->type == EVENT_BUTTONPRESS) { - button_status = button->button; - grid_button_draw = (overlay.grid_button[x][y] != grid_button[step_nr] ? grid_button[step_nr] : CHAR_GRID_BUTTON_NONE); set_grid_button = TRUE; } - else - { - button_status = MB_RELEASED; - } + + MapScreenMenuGadgets_OverlayTouchButtons(button->y); } break; @@ -7958,6 +8055,14 @@ static boolean ConfigureVirtualButtonsMain(void) { MotionEvent *motion = (MotionEvent *)&event; + motion_status = TRUE; + + if (HandleGadgets(motion->x, motion->y, button_status)) + { + // do not handle this button event anymore + break; + } + motion->x += video.screen_xoffset; motion->y += video.screen_yoffset; @@ -7965,6 +8070,8 @@ static boolean ConfigureVirtualButtonsMain(void) y = motion->y * overlay.grid_ysize / video.screen_height; set_grid_button = TRUE; + + MapScreenMenuGadgets_OverlayTouchButtons(motion->y); } break; @@ -7996,6 +8103,64 @@ static boolean ConfigureVirtualButtonsMain(void) break; } + // ---------- perform action set by handling events ---------- + + if (action == ACTION_ESCAPE) + { + // abort and restore the old key bindings + + for (x = 0; x < MAX_GRID_XSIZE; x++) + for (y = 0; y < MAX_GRID_YSIZE; y++) + overlay.grid_button[x][y] = grid_button_old[x][y]; + + FadeSkipNextFadeIn(); + + finished = TRUE; + } + else if (action == ACTION_BACK) + { + // keep the configured key bindings and go to previous page + + step_nr--; + + if (step_nr < 0) + { + FadeSkipNextFadeIn(); + + finished = TRUE; + } + } + else if (action == ACTION_NEXT) + { + // keep the configured key bindings and go to next page + + step_nr++; + + // all virtual buttons configured + if (step_nr == 6) + { + finished = TRUE; + success = TRUE; + } + } + + if (action != ACTION_NONE && !finished) + { + for (x = 0; x < MAX_GRID_XSIZE; x++) + for (y = 0; y < MAX_GRID_YSIZE; y++) + grid_button_tmp[x][y] = overlay.grid_button[x][y]; + + overlay.grid_button_highlight = grid_button[step_nr]; + + // configure next virtual button + + ClearField(); + + DrawTextSCentered(mSY - SY + 16, FONT_TITLE_1, "Virtual Buttons"); + DrawTextSCentered(ypos1, font_nr, "Select tiles to"); + DrawTextSCentered(ypos2, font_nr, customize_step_text[step_nr]); + } + if (set_grid_button) { overlay.grid_button[x][y] = @@ -8025,6 +8190,9 @@ void ConfigureVirtualButtons(void) { boolean success = ConfigureVirtualButtonsMain(); + UnmapScreenMenuGadgets(SCREEN_MASK_TOUCH | + SCREEN_MASK_TOUCH2); + if (success) { int font_nr = FONT_TITLE_1; @@ -8050,6 +8218,9 @@ void ConfigureVirtualButtons(void) void DrawSetupScreen(void) { + align_xoffset = 0; + align_yoffset = 0; + if (setup_mode == SETUP_MODE_INPUT) DrawSetupScreen_Input(); else if (setup_mode == SETUP_MODE_CHOOSE_GAME_SPEED) @@ -8204,95 +8375,120 @@ void HandleGameActions(void) // ---------- new screen button stuff -------------------------------------- -static void getScreenMenuButtonPos(int *x, int *y, int gadget_id) -{ - switch (gadget_id) - { - case SCREEN_CTRL_ID_PREV_LEVEL: - *x = mSX + GDI_ACTIVE_POS(menu.main.button.prev_level.x); - *y = mSY + GDI_ACTIVE_POS(menu.main.button.prev_level.y); - break; - - case SCREEN_CTRL_ID_NEXT_LEVEL: - *x = mSX + GDI_ACTIVE_POS(menu.main.button.next_level.x); - *y = mSY + GDI_ACTIVE_POS(menu.main.button.next_level.y); - break; - - case SCREEN_CTRL_ID_PREV_PLAYER: - *x = mSX + TILEX * 10; - *y = mSY + TILEY * MENU_SCREEN_START_YPOS; - break; - - case SCREEN_CTRL_ID_NEXT_PLAYER: - *x = mSX + TILEX * 12; - *y = mSY + TILEY * MENU_SCREEN_START_YPOS; - break; - - case SCREEN_CTRL_ID_INSERT_SOLUTION: - *x = mSX + GDI_ACTIVE_POS(menu.main.button.insert_solution.x); - *y = mSY + GDI_ACTIVE_POS(menu.main.button.insert_solution.y); - break; - - case SCREEN_CTRL_ID_PLAY_SOLUTION: - *x = mSX + GDI_ACTIVE_POS(menu.main.button.play_solution.x); - *y = mSY + GDI_ACTIVE_POS(menu.main.button.play_solution.y); - break; - - default: - Error(ERR_EXIT, "unknown gadget ID %d", gadget_id); - } -} - static struct { int gfx_unpressed, gfx_pressed; - void (*get_gadget_position)(int *, int *, int); + struct MenuPosInfo *pos; int gadget_id; int screen_mask; + unsigned int event_mask; + boolean is_touch_button; char *infotext; } menubutton_info[NUM_SCREEN_MENUBUTTONS] = { { IMG_MENU_BUTTON_PREV_LEVEL, IMG_MENU_BUTTON_PREV_LEVEL_ACTIVE, - getScreenMenuButtonPos, + &menu.main.button.prev_level, SCREEN_CTRL_ID_PREV_LEVEL, SCREEN_MASK_MAIN, - "last level" + GD_EVENT_PRESSED | GD_EVENT_REPEATED, + FALSE, "previous level" }, { IMG_MENU_BUTTON_NEXT_LEVEL, IMG_MENU_BUTTON_NEXT_LEVEL_ACTIVE, - getScreenMenuButtonPos, + &menu.main.button.next_level, SCREEN_CTRL_ID_NEXT_LEVEL, SCREEN_MASK_MAIN, - "next level" + GD_EVENT_PRESSED | GD_EVENT_REPEATED, + FALSE, "next level" + }, + { + IMG_MENU_BUTTON_FIRST_LEVEL, IMG_MENU_BUTTON_FIRST_LEVEL_ACTIVE, + &menu.main.button.first_level, + SCREEN_CTRL_ID_FIRST_LEVEL, + SCREEN_MASK_MAIN, + GD_EVENT_RELEASED, + FALSE, "first level" + }, + { + IMG_MENU_BUTTON_LAST_LEVEL, IMG_MENU_BUTTON_LAST_LEVEL_ACTIVE, + &menu.main.button.last_level, + SCREEN_CTRL_ID_LAST_LEVEL, + SCREEN_MASK_MAIN, + GD_EVENT_RELEASED, + FALSE, "last level" + }, + { + IMG_MENU_BUTTON_LEVEL_NUMBER, IMG_MENU_BUTTON_LEVEL_NUMBER_ACTIVE, + &menu.main.button.level_number, + SCREEN_CTRL_ID_LEVEL_NUMBER, + SCREEN_MASK_MAIN, + GD_EVENT_RELEASED, + FALSE, "level number" }, { IMG_MENU_BUTTON_LEFT, IMG_MENU_BUTTON_LEFT_ACTIVE, - getScreenMenuButtonPos, + &menu.setup.button.prev_player, SCREEN_CTRL_ID_PREV_PLAYER, SCREEN_MASK_INPUT, - "last player" + GD_EVENT_PRESSED | GD_EVENT_REPEATED, + FALSE, "previous player" }, { IMG_MENU_BUTTON_RIGHT, IMG_MENU_BUTTON_RIGHT_ACTIVE, - getScreenMenuButtonPos, + &menu.setup.button.next_player, SCREEN_CTRL_ID_NEXT_PLAYER, SCREEN_MASK_INPUT, - "next player" + GD_EVENT_PRESSED | GD_EVENT_REPEATED, + FALSE, "next player" }, { IMG_MENU_BUTTON_INSERT_SOLUTION, IMG_MENU_BUTTON_INSERT_SOLUTION_ACTIVE, - getScreenMenuButtonPos, + &menu.main.button.insert_solution, SCREEN_CTRL_ID_INSERT_SOLUTION, SCREEN_MASK_MAIN_HAS_SOLUTION, - "insert solution tape" + GD_EVENT_RELEASED, + FALSE, "insert solution tape" }, { IMG_MENU_BUTTON_PLAY_SOLUTION, IMG_MENU_BUTTON_PLAY_SOLUTION_ACTIVE, - getScreenMenuButtonPos, + &menu.main.button.play_solution, SCREEN_CTRL_ID_PLAY_SOLUTION, SCREEN_MASK_MAIN_HAS_SOLUTION, - "play solution tape" + GD_EVENT_RELEASED, + FALSE, "play solution tape" + }, + { + IMG_MENU_BUTTON_TOUCH_BACK, IMG_MENU_BUTTON_TOUCH_BACK, + &menu.setup.button.touch_back, + SCREEN_CTRL_ID_TOUCH_PREV_PAGE, + SCREEN_MASK_TOUCH, + GD_EVENT_RELEASED, + TRUE, "previous page" + }, + { + IMG_MENU_BUTTON_TOUCH_NEXT, IMG_MENU_BUTTON_TOUCH_NEXT, + &menu.setup.button.touch_next, + SCREEN_CTRL_ID_TOUCH_NEXT_PAGE, + SCREEN_MASK_TOUCH, + GD_EVENT_RELEASED, + TRUE, "next page" + }, + { + IMG_MENU_BUTTON_TOUCH_BACK2, IMG_MENU_BUTTON_TOUCH_BACK2, + &menu.setup.button.touch_back2, + SCREEN_CTRL_ID_TOUCH_PREV_PAGE2, + SCREEN_MASK_TOUCH2, + GD_EVENT_RELEASED, + TRUE, "previous page" + }, + { + IMG_MENU_BUTTON_TOUCH_NEXT2, IMG_MENU_BUTTON_TOUCH_NEXT2, + &menu.setup.button.touch_next2, + SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2, + SCREEN_MASK_TOUCH2, + GD_EVENT_RELEASED, + TRUE, "next page" }, }; @@ -8366,29 +8562,21 @@ static void CreateScreenMenubuttons(void) for (i = 0; i < NUM_SCREEN_MENUBUTTONS; i++) { + struct MenuPosInfo *pos = menubutton_info[i].pos; + boolean is_touch_button = menubutton_info[i].is_touch_button; Bitmap *gd_bitmap_unpressed, *gd_bitmap_pressed; int gfx_unpressed, gfx_pressed; int x, y, width, height; int gd_x1, gd_x2, gd_y1, gd_y2; int id = menubutton_info[i].gadget_id; - if (menubutton_info[i].screen_mask == SCREEN_MASK_MAIN_HAS_SOLUTION) - event_mask = GD_EVENT_RELEASED; - else - event_mask = GD_EVENT_PRESSED | GD_EVENT_REPEATED; + event_mask = menubutton_info[i].event_mask; - menubutton_info[i].get_gadget_position(&x, &y, id); + x = (is_touch_button ? pos->x : mSX + GDI_ACTIVE_POS(pos->x)); + y = (is_touch_button ? pos->y : mSY + GDI_ACTIVE_POS(pos->y)); - if (menubutton_info[i].screen_mask == SCREEN_MASK_MAIN_HAS_SOLUTION) - { - width = graphic_info[menubutton_info[i].gfx_pressed].width; - height = graphic_info[menubutton_info[i].gfx_pressed].height; - } - else - { - width = SC_MENUBUTTON_XSIZE; - height = SC_MENUBUTTON_YSIZE; - } + width = graphic_info[menubutton_info[i].gfx_pressed].width; + height = graphic_info[menubutton_info[i].gfx_pressed].height; gfx_unpressed = menubutton_info[i].gfx_unpressed; gfx_pressed = menubutton_info[i].gfx_pressed; @@ -8399,6 +8587,12 @@ static void CreateScreenMenubuttons(void) gd_x2 = graphic_info[gfx_pressed].src_x; gd_y2 = graphic_info[gfx_pressed].src_y; + if (is_touch_button) + { + gd_x2 += graphic_info[gfx_pressed].pressed_xoffset; + gd_y2 += graphic_info[gfx_pressed].pressed_yoffset; + } + gi = CreateGadget(GDI_CUSTOM_ID, id, GDI_CUSTOM_TYPE_ID, i, GDI_IMAGE_ID, gfx_unpressed, @@ -8412,6 +8606,7 @@ static void CreateScreenMenubuttons(void) GDI_DESIGN_UNPRESSED, gd_bitmap_unpressed, gd_x1, gd_y1, GDI_DESIGN_PRESSED, gd_bitmap_pressed, gd_x2, gd_y2, GDI_DIRECT_DRAW, FALSE, + GDI_OVERLAY_TOUCH_BUTTON, is_touch_button, GDI_EVENT_MASK, event_mask, GDI_CALLBACK_ACTION, HandleScreenGadgets, GDI_END); @@ -8636,7 +8831,7 @@ void FreeScreenGadgets(void) FreeGadget(screen_gadget[i]); } -void MapScreenMenuGadgets(int screen_mask) +static void MapScreenMenuGadgets(int screen_mask) { int i; @@ -8664,7 +8859,7 @@ static void UnmapScreenMenuGadgets(int screen_mask) } } -void UpdateScreenMenuGadgets(int screen_mask, boolean map_gadgets) +static void UpdateScreenMenuGadgets(int screen_mask, boolean map_gadgets) { if (map_gadgets) MapScreenMenuGadgets(screen_mask); @@ -8672,7 +8867,7 @@ void UpdateScreenMenuGadgets(int screen_mask, boolean map_gadgets) UnmapScreenMenuGadgets(screen_mask); } -void MapScreenGadgets(int num_entries) +static void MapScreenGadgets(int num_entries) { int i; @@ -8686,7 +8881,7 @@ void MapScreenGadgets(int num_entries) MapGadget(screen_gadget[scrollbar_info[i].gadget_id]); } -void MapScreenTreeGadgets(TreeInfo *ti) +static void MapScreenTreeGadgets(TreeInfo *ti) { MapScreenGadgets(numTreeInfoInGroup(ti)); } @@ -8709,6 +8904,20 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) HandleMainMenu_SelectLevel(step, +1, NO_DIRECT_LEVEL_SELECT); break; + case SCREEN_CTRL_ID_FIRST_LEVEL: + HandleMainMenu_SelectLevel(MAX_LEVELS, -1, NO_DIRECT_LEVEL_SELECT); + break; + + case SCREEN_CTRL_ID_LAST_LEVEL: + HandleMainMenu_SelectLevel(MAX_LEVELS, +1, NO_DIRECT_LEVEL_SELECT); + break; + + case SCREEN_CTRL_ID_LEVEL_NUMBER: + CloseDoor(DOOR_CLOSE_2); + SetGameStatus(GAME_MODE_LEVELNR); + DrawChooseLevelNr(); + break; + case SCREEN_CTRL_ID_PREV_PLAYER: HandleSetupScreen_Input_Player(step, -1); break; @@ -8725,6 +8934,13 @@ static void HandleScreenGadgets(struct GadgetInfo *gi) PlaySolutionTape(); break; + case SCREEN_CTRL_ID_TOUCH_PREV_PAGE: + case SCREEN_CTRL_ID_TOUCH_NEXT_PAGE: + case SCREEN_CTRL_ID_TOUCH_PREV_PAGE2: + case SCREEN_CTRL_ID_TOUCH_NEXT_PAGE2: + PushUserEvent(USEREVENT_GADGET_PRESSED, id, 0); + break; + case SCREEN_CTRL_ID_SCROLL_UP: if (game_status == GAME_MODE_LEVELS) HandleChooseLevelSet(0,0, 0, -1 * SCROLL_LINE, MB_MENU_MARK); @@ -8834,3 +9050,71 @@ boolean DoScreenAction(int image_id) return FALSE; } + +void DrawScreenAfterAddingSet(char *tree_subdir_new, int tree_type) +{ + // get tree info node of newly added level or artwork set + TreeInfo *tree_node_first = TREE_FIRST_NODE(tree_type); + TreeInfo *tree_node_new = getTreeInfoFromIdentifier(tree_node_first, + tree_subdir_new); + if (tree_node_new == NULL) // should not happen + return; + + // if request dialog is active, do nothing + if (game.request_active) + return; + + if (game_status == GAME_MODE_MAIN && + tree_type == TREE_TYPE_LEVEL_DIR) + { + // when adding new level set in main menu, select it as current level set + + // change current level set to newly added level set from zip file + leveldir_current = tree_node_new; + + // change current level number to first level of newly added level set + level_nr = leveldir_current->first_level; + + // redraw screen to reflect changed level set + DrawMainMenu(); + + // save this level set and level number as last selected level set + SaveLevelSetup_LastSeries(); + SaveLevelSetup_SeriesInfo(); + } + else if (game_status == GAME_MODE_LEVELS && + tree_type == TREE_TYPE_LEVEL_DIR) + { + // when adding new level set in level set menu, set cursor and update screen + + leveldir_current = tree_node_new; + + DrawChooseTree(&leveldir_current); + } + else if (game_status == GAME_MODE_SETUP) + { + // when adding new artwork set in setup menu, set cursor and update screen + + if (setup_mode == SETUP_MODE_CHOOSE_GRAPHICS && + tree_type == TREE_TYPE_GRAPHICS_DIR) + { + artwork.gfx_current = tree_node_new; + + DrawChooseTree(&artwork.gfx_current); + } + else if (setup_mode == SETUP_MODE_CHOOSE_SOUNDS && + tree_type == TREE_TYPE_SOUNDS_DIR) + { + artwork.snd_current = tree_node_new; + + DrawChooseTree(&artwork.snd_current); + } + else if (setup_mode == SETUP_MODE_CHOOSE_MUSIC && + tree_type == TREE_TYPE_MUSIC_DIR) + { + artwork.mus_current = tree_node_new; + + DrawChooseTree(&artwork.mus_current); + } + } +}