X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ftools.c;h=ab6c4efa28f32b808b095e4955afc0966798750a;hp=6d3a0aeb00f5866603f28f4a720b0b05bd17d3b5;hb=ba20bcc8b425b7addb2bd1bfc4ef3661e56ccd43;hpb=400c25c653549b236d701d6b0d9b47a9565ec5be diff --git a/src/tools.c b/src/tools.c index 6d3a0aeb..ab6c4efa 100644 --- a/src/tools.c +++ b/src/tools.c @@ -981,6 +981,8 @@ static void FadeExt(int fade_mask, int fade_mode, int fade_type) draw_border_function); redraw_mask &= ~fade_mask; + + ClearEventQueue(); } static void SetScreenStates_BeforeFadingIn() @@ -2800,6 +2802,8 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame); } + + ClearEventQueue(); } void ShowEnvelope(int envelope_nr) @@ -3083,6 +3087,8 @@ void AnimateEnvelopeRequest(int anim_mode, int action) SkipUntilDelayReached(&anim_delay, anim_delay_value, &i, last_frame); } + + ClearEventQueue(); } void ShowEnvelopeRequest(char *text, unsigned int req_state, int action) @@ -3504,9 +3510,85 @@ static void DrawPreviewLevelExt(boolean restart) } } +void DrawPreviewPlayers() +{ + if (game_status != GAME_MODE_MAIN) + return; + + if (!network.enabled && !setup.team_mode) + return; + + boolean player_found[MAX_PLAYERS]; + int num_players = 0; + int i, x, y; + + for (i = 0; i < MAX_PLAYERS; i++) + player_found[i] = FALSE; + + /* check which players can be found in the level (simple approach) */ + for (x = 0; x < lev_fieldx; x++) + { + for (y = 0; y < lev_fieldy; y++) + { + int element = level.field[x][y]; + + if (ELEM_IS_PLAYER(element)) + { + int player_nr = GET_PLAYER_NR(element); + + player_nr = MIN(MAX(0, player_nr), MAX_PLAYERS - 1); + + if (!player_found[player_nr]) + num_players++; + + player_found[player_nr] = TRUE; + } + } + } + + struct TextPosInfo *pos = &menu.main.preview_players; + int tile_size = pos->tile_size; + int border_size = pos->border_size; + int player_xoffset_raw = (pos->vertical ? 0 : tile_size + border_size); + int player_yoffset_raw = (pos->vertical ? tile_size + border_size : 0); + int player_xoffset = (pos->xoffset != -1 ? pos->xoffset : player_xoffset_raw); + int player_yoffset = (pos->yoffset != -1 ? pos->yoffset : player_yoffset_raw); + int max_players_width = (MAX_PLAYERS - 1) * player_xoffset + tile_size; + int max_players_height = (MAX_PLAYERS - 1) * player_yoffset + tile_size; + int all_players_width = (num_players - 1) * player_xoffset + tile_size; + int all_players_height = (num_players - 1) * player_yoffset + tile_size; + int max_xpos = SX + ALIGNED_XPOS(pos->x, max_players_width, pos->align); + int max_ypos = SY + ALIGNED_YPOS(pos->y, max_players_height, pos->valign); + int xpos = SX + ALIGNED_XPOS(pos->x, all_players_width, pos->align); + int ypos = SY + ALIGNED_YPOS(pos->y, all_players_height, pos->valign); + + /* clear area in which the players will be drawn */ + ClearRectangleOnBackground(drawto, max_xpos, max_ypos, + max_players_width, max_players_height); + + /* only draw players if level is suited for team mode */ + if (num_players < 2) + return; + + /* draw all players that were found in the level */ + for (i = 0; i < MAX_PLAYERS; i++) + { + if (player_found[i]) + { + int graphic = el2img(EL_PLAYER_1 + i); + + DrawSizedGraphicThruMaskExt(drawto, xpos, ypos, graphic, 0, tile_size); + + xpos += player_xoffset; + ypos += player_yoffset; + } + } +} + void DrawPreviewLevelInitial() { DrawPreviewLevelExt(TRUE); + DrawPreviewPlayers(); } void DrawPreviewLevelAnimation() @@ -3514,6 +3596,99 @@ void DrawPreviewLevelAnimation() DrawPreviewLevelExt(FALSE); } +static void DrawNetworkPlayer(int x, int y, int player_nr, int tile_size, + int border_size, int font_nr) +{ + int graphic = el2img(EL_PLAYER_1 + player_nr); + int font_height = getFontHeight(font_nr); + int player_height = MAX(tile_size, font_height); + int xoffset_text = tile_size + border_size; + int yoffset_text = (player_height - font_height) / 2; + int yoffset_graphic = (player_height - tile_size) / 2; + char *player_name = getNetworkPlayerName(player_nr + 1); + + DrawSizedGraphicThruMaskExt(drawto, x, y + yoffset_graphic, graphic, 0, + tile_size); + DrawText(x + xoffset_text, y + yoffset_text, player_name, font_nr); +} + +void DrawNetworkPlayersExt(boolean force) +{ + if (game_status != GAME_MODE_MAIN) + return; + + if (!network.connected && !force) + return; + + int num_players = 0; + int i; + + for (i = 0; i < MAX_PLAYERS; i++) + if (stored_player[i].connected_network) + num_players++; + + struct TextPosInfo *pos = &menu.main.network_players; + int tile_size = pos->tile_size; + int border_size = pos->border_size; + int xoffset_text = tile_size + border_size; + int font_nr = pos->font; + int font_width = getFontWidth(font_nr); + int font_height = getFontHeight(font_nr); + int player_height = MAX(tile_size, font_height); + int player_yoffset = player_height + border_size; + int max_players_width = xoffset_text + MAX_PLAYER_NAME_LEN * font_width; + int max_players_height = MAX_PLAYERS * player_yoffset - border_size; + int all_players_height = num_players * player_yoffset - border_size; + int max_xpos = SX + ALIGNED_XPOS(pos->x, max_players_width, pos->align); + int max_ypos = SY + ALIGNED_YPOS(pos->y, max_players_height, pos->valign); + int ypos = SY + ALIGNED_YPOS(pos->y, all_players_height, pos->valign); + + ClearRectangleOnBackground(drawto, max_xpos, max_ypos, + max_players_width, max_players_height); + + /* first draw local network player ... */ + for (i = 0; i < MAX_PLAYERS; i++) + { + if (stored_player[i].connected_network && + stored_player[i].connected_locally) + { + char *player_name = getNetworkPlayerName(i + 1); + int player_width = xoffset_text + getTextWidth(player_name, font_nr); + int xpos = SX + ALIGNED_XPOS(pos->x, player_width, pos->align); + + DrawNetworkPlayer(xpos, ypos, i, tile_size, border_size, font_nr); + + ypos += player_yoffset; + } + } + + /* ... then draw all other network players */ + for (i = 0; i < MAX_PLAYERS; i++) + { + if (stored_player[i].connected_network && + !stored_player[i].connected_locally) + { + char *player_name = getNetworkPlayerName(i + 1); + int player_width = xoffset_text + getTextWidth(player_name, font_nr); + int xpos = SX + ALIGNED_XPOS(pos->x, player_width, pos->align); + + DrawNetworkPlayer(xpos, ypos, i, tile_size, border_size, font_nr); + + ypos += player_yoffset; + } + } +} + +void DrawNetworkPlayers() +{ + DrawNetworkPlayersExt(FALSE); +} + +void ClearNetworkPlayers() +{ + DrawNetworkPlayersExt(TRUE); +} + inline static void DrawGraphicAnimationExt(DrawBuffer *dst_bitmap, int x, int y, int graphic, int sync_frame, int mask_mode) @@ -4186,8 +4361,8 @@ static int RequestHandleEvents(unsigned int req_state) case KSYM_Return: case KSYM_y: - case KSYM_Y: #if defined(TARGET_SDL2) + case KSYM_Y: case KSYM_Select: case KSYM_Menu: #if defined(KSYM_Rewind) @@ -4199,8 +4374,8 @@ static int RequestHandleEvents(unsigned int req_state) case KSYM_Escape: case KSYM_n: - case KSYM_N: #if defined(TARGET_SDL2) + case KSYM_N: case KSYM_Back: #if defined(KSYM_FastForward) case KSYM_FastForward: /* for Amazon Fire TV remote */ @@ -4215,7 +4390,42 @@ static int RequestHandleEvents(unsigned int req_state) } if (req_state & REQ_PLAYER) - result = 0; + { + int old_player_nr = setup.network_player_nr; + + if (result != -1) + result = old_player_nr + 1; + + switch (key) + { + case KSYM_space: + result = old_player_nr + 1; + break; + + case KSYM_Up: + case KSYM_1: + result = 1; + break; + + case KSYM_Right: + case KSYM_2: + result = 2; + break; + + case KSYM_Down: + case KSYM_3: + result = 3; + break; + + case KSYM_Left: + case KSYM_4: + result = 4; + break; + + default: + break; + } + } break; } @@ -4231,19 +4441,52 @@ static int RequestHandleEvents(unsigned int req_state) case SDL_CONTROLLER_BUTTON_A: case SDL_CONTROLLER_BUTTON_X: case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + case SDL_CONTROLLER_BUTTON_LEFTSTICK: result = 1; break; case SDL_CONTROLLER_BUTTON_B: case SDL_CONTROLLER_BUTTON_Y: case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + case SDL_CONTROLLER_BUTTON_RIGHTSTICK: case SDL_CONTROLLER_BUTTON_BACK: result = 0; break; } if (req_state & REQ_PLAYER) - result = 0; + { + int old_player_nr = setup.network_player_nr; + + if (result != -1) + result = old_player_nr + 1; + + switch (event.cbutton.button) + { + case SDL_CONTROLLER_BUTTON_DPAD_UP: + case SDL_CONTROLLER_BUTTON_Y: + result = 1; + break; + + case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: + case SDL_CONTROLLER_BUTTON_B: + result = 2; + break; + + case SDL_CONTROLLER_BUTTON_DPAD_DOWN: + case SDL_CONTROLLER_BUTTON_A: + result = 3; + break; + + case SDL_CONTROLLER_BUTTON_DPAD_LEFT: + case SDL_CONTROLLER_BUTTON_X: + result = 4; + break; + + default: + break; + } + } break; @@ -4268,6 +4511,22 @@ static int RequestHandleEvents(unsigned int req_state) else if (joy & JOY_BUTTON_2) result = 0; } + else if (AnyJoystick()) + { + int joy = AnyJoystick(); + + if (req_state & REQ_PLAYER) + { + if (joy & JOY_UP) + result = 1; + else if (joy & JOY_RIGHT) + result = 2; + else if (joy & JOY_DOWN) + result = 3; + else if (joy & JOY_LEFT) + result = 4; + } + } if (level_solved) { @@ -4308,13 +4567,11 @@ static boolean RequestDoor(char *text, unsigned int req_state) SetMouseCursor(CURSOR_DEFAULT); -#if defined(NETWORK_AVALIABLE) /* pause network game while waiting for request to answer */ - if (options.network && + if (network.enabled && game_status == GAME_MODE_PLAYING && req_state & REQUEST_WAIT_FOR_INPUT) SendToServer_PausePlaying(); -#endif old_door_state = GetDoorState(); @@ -4450,13 +4707,11 @@ static boolean RequestDoor(char *text, unsigned int req_state) SetDrawBackgroundMask(REDRAW_FIELD); } -#if defined(NETWORK_AVALIABLE) /* continue network game after request */ - if (options.network && + if (network.enabled && game_status == GAME_MODE_PLAYING && req_state & REQUEST_WAIT_FOR_INPUT) SendToServer_ContinuePlaying(); -#endif /* restore deactivated drawing when quick-loading level tape recording */ if (tape.playing && tape.deactivate_display) @@ -4478,13 +4733,11 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) SetMouseCursor(CURSOR_DEFAULT); -#if defined(NETWORK_AVALIABLE) /* pause network game while waiting for request to answer */ - if (options.network && + if (network.enabled && game_status == GAME_MODE_PLAYING && req_state & REQUEST_WAIT_FOR_INPUT) SendToServer_PausePlaying(); -#endif /* simulate releasing mouse button over last gadget, if still pressed */ if (button_status) @@ -4537,13 +4790,11 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) SetDrawBackgroundMask(REDRAW_FIELD); } -#if defined(NETWORK_AVALIABLE) /* continue network game after request */ - if (options.network && + if (network.enabled && game_status == GAME_MODE_PLAYING && req_state & REQUEST_WAIT_FOR_INPUT) SendToServer_ContinuePlaying(); -#endif /* restore deactivated drawing when quick-loading level tape recording */ if (tape.playing && tape.deactivate_display) @@ -5174,6 +5425,8 @@ unsigned int MoveDoor(unsigned int door_state) DrawMaskedBorder(REDRAW_DOOR_1); DrawMaskedBorder(REDRAW_DOOR_2); + ClearEventQueue(); + return (door1 | door2); } @@ -5304,7 +5557,8 @@ void CreateToolButtons() for (i = 0; i < NUM_TOOL_BUTTONS; i++) { - struct GraphicInfo *gfx = &graphic_info[toolbutton_info[i].graphic]; + int graphic = toolbutton_info[i].graphic; + struct GraphicInfo *gfx = &graphic_info[graphic]; struct TextPosInfo *pos = toolbutton_info[i].pos; struct GadgetInfo *gi; Bitmap *deco_bitmap = None; @@ -5328,33 +5582,30 @@ void CreateToolButtons() if (x < 0 || x + gfx->width > request.width || y < 0 || y + gfx->height > request.height) { - // use left padding of "yes" button as default border padding - int padding = toolbutton_info[TOOL_CTRL_ID_YES].pos->x; - if (id == TOOL_CTRL_ID_YES) { - x = padding; - y = request.height - 2 * request.border_size - gfx->height - padding; + x = 0; + y = request.height - 2 * request.border_size - gfx->height; } else if (id == TOOL_CTRL_ID_NO) { - x = request.width - 2 * request.border_size - gfx->width - padding; - y = request.height - 2 * request.border_size - gfx->height - padding; + x = request.width - 2 * request.border_size - gfx->width; + y = request.height - 2 * request.border_size - gfx->height; } else if (id == TOOL_CTRL_ID_CONFIRM) { x = (request.width - 2 * request.border_size - gfx->width) / 2; - y = request.height - 2 * request.border_size - gfx->height - padding; + y = request.height - 2 * request.border_size - gfx->height; } else if (id >= TOOL_CTRL_ID_PLAYER_1 && id <= TOOL_CTRL_ID_PLAYER_4) { int player_nr = id - TOOL_CTRL_ID_PLAYER_1; x = (request.width - 2 * request.border_size - gfx->width) / 2; - y = request.height - 2 * request.border_size - gfx->height - padding; + y = request.height - 2 * request.border_size - gfx->height * 2; - x += (player_nr % 2 ? +1 : -1) * gfx->width / 2; - y += (player_nr / 2 ? 0 : -1) * gfx->height; + x += (player_nr == 3 ? -1 : player_nr == 1 ? +1 : 0) * gfx->width; + y += (player_nr == 0 ? -1 : player_nr == 2 ? +1 : 0) * gfx->height; } } } @@ -5370,6 +5621,7 @@ void CreateToolButtons() } gi = CreateGadget(GDI_CUSTOM_ID, id, + GDI_IMAGE_ID, graphic, GDI_INFO_TEXT, toolbutton_info[i].infotext, GDI_X, dx + x, GDI_Y, dy + y,