X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fgadgets.c;h=f84815b0effb46f94ab5bc4f399e6a84f7864b73;hb=0865ed73513e161be429a61c63913d58c9d145a3;hp=0295eec69a48d1b4cabfb4d08c44fe76bc4d1519;hpb=3bb0d9d605aafe3e832aa79fa9e8c7f088556819;p=rocksndiamonds.git diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index 0295eec6..f84815b0 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -4,7 +4,7 @@ // (c) 1995-2014 by Artsoft Entertainment // Holger Schemel // info@artsoft.org -// http://www.artsoft.org/ +// https://www.artsoft.org/ // ---------------------------------------------------------------------------- // gadgets.c // ============================================================================ @@ -78,7 +78,7 @@ static int getNewGadgetID(void) } if (next_free_gadget_id <= 0) // cannot get new gadget id - Error(ERR_EXIT, "too much gadgets -- this should not happen"); + Fail("too much gadgets -- this should not happen"); return id; } @@ -228,6 +228,9 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) if (gi == NULL || gi->deactivated) return; + if (gi->overlay_touch_button) // will be drawn later (as texture) + return; + gd = (!gi->active ? &gi->alt_design[state] : gi->checked ? &gi->alt_design[state] : &gi->design[state]); @@ -762,6 +765,100 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) } } +static void SetGadgetPosition_OverlayTouchButton(struct GadgetInfo *gi) +{ + gi->x = gi->orig_x; + gi->y = gi->orig_y; + + if (gi->x < 0) + gi->x += video.screen_width; + if (gi->y < 0) + gi->y += video.screen_height; + + gi->x -= video.screen_xoffset; + gi->y -= video.screen_yoffset; +} + +void SetGadgetsPosition_OverlayTouchButtons(void) +{ + struct GadgetInfo *gi; + + if (gadget_list_first_entry == NULL) + return; + + for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next) + if (gi->overlay_touch_button) + SetGadgetPosition_OverlayTouchButton(gi); +} + +static void DrawGadget_OverlayTouchButton(struct GadgetInfo *gi) +{ + struct GadgetDesign *gd; + int state = (gi->state ? GD_BUTTON_PRESSED : GD_BUTTON_UNPRESSED); + + if (gi == NULL || gi->deactivated) + return; + + gd = (!gi->active ? &gi->alt_design[state] : + gi->checked ? &gi->alt_design[state] : &gi->design[state]); + + int x = gi->x + video.screen_xoffset; + int y = gi->y + video.screen_yoffset; + int alpha = gi->overlay_touch_button_alpha; + int alpha_max = SDL_ALPHA_OPAQUE; + int alpha_step = ALPHA_FADING_STEPSIZE(alpha_max); + + // only show mapped overlay touch buttons if touch screen is really used + if (gi->mapped && runtime.uses_touch_device) + { + if (alpha < alpha_max) + alpha = MIN(alpha + alpha_step, alpha_max); + } + else + { + alpha = MAX(0, alpha - alpha_step); + } + + gi->overlay_touch_button_alpha = alpha; + + if (alpha == 0) + return; + + switch (gi->type) + { + case GD_TYPE_NORMAL_BUTTON: + case GD_TYPE_CHECK_BUTTON: + case GD_TYPE_RADIO_BUTTON: + SDL_SetTextureAlphaMod(gd->bitmap->texture_masked, alpha); + SDL_SetTextureBlendMode(gd->bitmap->texture_masked, SDL_BLENDMODE_BLEND); + + BlitToScreenMasked(gd->bitmap, gd->x, gd->y, gi->width, gi->height, x, y); + break; + + default: + return; + } +} + +void DrawGadgets_OverlayTouchButtons(void) +{ + struct GadgetInfo *gi; + + if (gadget_list_first_entry == NULL) + return; + + for (gi = gadget_list_first_entry; gi != NULL; gi = gi->next) + if (gi->overlay_touch_button) + DrawGadget_OverlayTouchButton(gi); +} + +boolean CheckPosition_OverlayTouchButtons(int mx, int my, int button) +{ + struct GadgetInfo *gi = getGadgetInfoFromMousePosition(mx, my, button); + + return (gi != NULL && gi->overlay_touch_button); +} + static int get_minimal_size_for_numeric_input(int minmax_value) { int min_size = 1; // value needs at least one digit @@ -787,7 +884,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) while (tag != GDI_END) { - switch(tag) + switch (tag) { case GDI_IMAGE_ID: gi->image_id = va_arg(ap, int); @@ -816,11 +913,11 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) break; case GDI_X: - gi->x = va_arg(ap, int); + gi->x = gi->orig_x = va_arg(ap, int); break; case GDI_Y: - gi->y = va_arg(ap, int); + gi->y = gi->orig_y = va_arg(ap, int); break; case GDI_WIDTH: @@ -847,6 +944,12 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) gi->direct_draw = (boolean)va_arg(ap, int); break; + case GDI_OVERLAY_TOUCH_BUTTON: + gi->overlay_touch_button = (boolean)va_arg(ap, int); + if (gi->overlay_touch_button) + SetGadgetPosition_OverlayTouchButton(gi); + break; + case GDI_CALLBACK_ACTION_ALWAYS: gi->callback_action_always = (boolean)va_arg(ap, int); break; @@ -1104,7 +1207,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) break; default: - Error(ERR_EXIT, "HandleGadgetTags(): unknown tag %d", tag); + Fail("HandleGadgetTags(): unknown tag %d", tag); } tag = va_arg(ap, int); // read next tag @@ -1118,8 +1221,8 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) gi->design[GD_BUTTON_PRESSED].bitmap == NULL)) gi->deactivated = TRUE; - // check if gadget is placed off-screen - if (gi->x < 0 || gi->y < 0) + // check if gadget is placed off-screen (and is no overlay touch button) + if ((gi->x < 0 || gi->y < 0) && !gi->overlay_touch_button) gi->deactivated = TRUE; // adjust gadget values in relation to other gadget values @@ -1165,7 +1268,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) gi->height = 2 * border_ysize + font_height; if (gi->selectbox.options == NULL) - Error(ERR_EXIT, "selectbox gadget incomplete (missing options array)"); + Fail("selectbox gadget incomplete (missing options array)"); gi->selectbox.num_values = 0; while (gi->selectbox.options[gi->selectbox.num_values].text != NULL) @@ -1227,7 +1330,7 @@ static void HandleGadgetTags(struct GadgetInfo *gi, int first_tag, va_list ap) if (gi->width == 0 || gi->height == 0 || gs->items_max == 0 || gs->items_visible == 0) - Error(ERR_EXIT, "scrollbar gadget incomplete (missing tags)"); + Fail("scrollbar gadget incomplete (missing tags)"); // calculate internal scrollbar values gs->size_min = (gi->type == GD_TYPE_SCROLLBAR_VERTICAL ? @@ -1301,6 +1404,8 @@ struct GadgetInfo *CreateGadget(int first_tag, ...) new_gadget->callback_action = default_callback_action; new_gadget->active = TRUE; new_gadget->direct_draw = TRUE; + new_gadget->overlay_touch_button = FALSE; + new_gadget->overlay_touch_button_alpha = 0; new_gadget->next = NULL; @@ -1374,6 +1479,10 @@ static void MapGadgetExt(struct GadgetInfo *gi, boolean redraw) if (gi == NULL || gi->deactivated || gi->mapped) return; + // do not map overlay touch buttons if touch screen is not used + if (gi->overlay_touch_button && !runtime.uses_touch_device) + return; + gi->mapped = TRUE; if (redraw) @@ -2121,8 +2230,12 @@ boolean HandleGadgetsKeyInput(Key key) { // restore previous text (before activating text gadget) if (gi->type & GD_TYPE_TEXT_INPUT) + { strcpy(gi->textinput.value, gi->textinput.last_value); + CheckRangeOfNumericInputGadget(gi); + } + DrawGadget(gi, DG_UNPRESSED, gi->direct_draw); last_gi = NULL;