X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ftools.c;h=fb1fc5ed620303db01503aedfb186a2113a50884;hb=d6cdd73c614433eb90eede7cf5cc512b0ef0b721;hp=e99d26ce169ad18c33f601c674a684d6165ff0d6;hpb=1f295bbb8d7a54989dd60a4f3aee7b4ca5719bf1;p=rocksndiamonds.git diff --git a/src/tools.c b/src/tools.c index e99d26ce..fb1fc5ed 100644 --- a/src/tools.c +++ b/src/tools.c @@ -358,12 +358,40 @@ static int getLevelFromScreenY_SP(int sy) return ly; } +static int getLevelFromScreenX_MM(int sx) +{ + int level_xsize = level.native_mm_level->fieldx; + int full_xsize = level_xsize * TILESIZE_VAR; + + sx -= (full_xsize < SXSIZE ? (SXSIZE - full_xsize) / 2 : 0); + + int px = sx - SX; + int lx = px / TILESIZE_VAR; + + return lx; +} + +static int getLevelFromScreenY_MM(int sy) +{ + int level_ysize = level.native_mm_level->fieldy; + int full_ysize = level_ysize * TILESIZE_VAR; + + sy -= (full_ysize < SYSIZE ? (SYSIZE - full_ysize) / 2 : 0); + + int py = sy - SY; + int ly = py / TILESIZE_VAR; + + return ly; +} + int getLevelFromScreenX(int x) { if (level.game_engine_type == GAME_ENGINE_TYPE_EM) return getLevelFromScreenX_EM(x); if (level.game_engine_type == GAME_ENGINE_TYPE_SP) return getLevelFromScreenX_SP(x); + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + return getLevelFromScreenX_MM(x); else return getLevelFromScreenX_RND(x); } @@ -374,6 +402,8 @@ int getLevelFromScreenY(int y) return getLevelFromScreenY_EM(y); if (level.game_engine_type == GAME_ENGINE_TYPE_SP) return getLevelFromScreenY_SP(y); + if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + return getLevelFromScreenY_MM(y); else return getLevelFromScreenY_RND(y); } @@ -465,6 +495,8 @@ void RedrawPlayfield() RedrawPlayfield_EM(TRUE); else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) RedrawPlayfield_SP(TRUE); + else if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + RedrawPlayfield_MM(); else if (level.game_engine_type == GAME_ENGINE_TYPE_RND) RedrawPlayfield_RND(); @@ -611,6 +643,8 @@ void BlitScreenToBitmap(Bitmap *target_bitmap) BlitScreenToBitmap_EM(target_bitmap); else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) BlitScreenToBitmap_SP(target_bitmap); + else if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + BlitScreenToBitmap_MM(target_bitmap); else if (level.game_engine_type == GAME_ENGINE_TYPE_RND) BlitScreenToBitmap_RND(target_bitmap); @@ -622,11 +656,24 @@ void DrawFramesPerSecond() char text[100]; int font_nr = FONT_TEXT_2; int font_width = getFontWidth(font_nr); + int draw_deactivation_mask = GetDrawDeactivationMask(); + boolean draw_masked = (draw_deactivation_mask == REDRAW_NONE); + + /* draw FPS with leading space (needed if field buffer deactivated) */ + sprintf(text, " %04.1f fps", global.frames_per_second); - sprintf(text, "%04.1f fps", global.frames_per_second); + /* override draw deactivation mask (required for invisible warp mode) */ + SetDrawDeactivationMask(REDRAW_NONE); - DrawTextExt(backbuffer, WIN_XSIZE - font_width * strlen(text), 0, text, - font_nr, BLIT_OPAQUE); + /* draw opaque FPS if field buffer deactivated, else draw masked FPS */ + DrawTextExt(backbuffer, SX + SXSIZE - font_width * strlen(text), SY, text, + font_nr, (draw_masked ? BLIT_MASKED : BLIT_OPAQUE)); + + /* set draw deactivation mask to previous value */ + SetDrawDeactivationMask(draw_deactivation_mask); + + /* force full-screen redraw in this frame */ + redraw_mask = REDRAW_ALL; } #if DEBUG_FRAME_TIME @@ -759,6 +806,13 @@ void BackToFront() y2 = MAX(y2, EY + EYSIZE); } + // make sure that at least one pixel is blitted, and inside the screen + // (else nothing is blitted, causing the animations not to be updated) + x1 = MIN(MAX(0, x1), WIN_XSIZE - 1); + y1 = MIN(MAX(0, y1), WIN_YSIZE - 1); + x2 = MIN(MAX(1, x2), WIN_XSIZE); + y2 = MIN(MAX(1, y2), WIN_YSIZE); + BlitBitmap(backbuffer, window, x1, y1, x2 - x1, y2 - y1, x1, y1); } @@ -1424,13 +1478,6 @@ void getSizedGraphicSourceExt(int graphic, int frame, int tilesize, *y = *y * tilesize / g->tile_size; } -void getFixedGraphicSourceExt(int graphic, int frame, Bitmap **bitmap, - int *x, int *y, boolean get_backside) -{ - getSizedGraphicSourceExt(graphic, frame, TILESIZE, bitmap, x, y, - get_backside); -} - void getSizedGraphicSource(int graphic, int frame, int tilesize, Bitmap **bitmap, int *x, int *y) { @@ -2498,7 +2545,7 @@ void AnimateEnvelope(int envelope_nr, int anim_mode, int action) boolean no_delay = (tape.warp_forward); unsigned int anim_delay = 0; int frame_delay_value = (ffwd_delay ? FfwdFrameDelay : GameFrameDelay); - int anim_delay_value = (no_delay ? 0 : frame_delay_value) / 2; + int anim_delay_value = MAX(1, (no_delay ? 0 : frame_delay_value) / 2); int font_nr = FONT_ENVELOPE_1 + envelope_nr; int font_width = getFontWidth(font_nr); int font_height = getFontHeight(font_nr); @@ -2755,7 +2802,7 @@ void AnimateEnvelopeRequest(int anim_mode, int action) boolean ffwd_delay = (tape.playing && tape.fast_forward); boolean no_delay = (tape.warp_forward); int delay_value = (ffwd_delay ? delay_value_fast : delay_value_normal); - int anim_delay_value = (no_delay ? 0 : delay_value + 500 * 0) / 2; + int anim_delay_value = MAX(1, (no_delay ? 0 : delay_value + 500 * 0) / 2); unsigned int anim_delay = 0; int tile_size = MAX(request.step_offset, 1); @@ -2961,7 +3008,7 @@ void DrawMiniLevel(int size_x, int size_y, int scroll_x, int scroll_y) redraw_mask |= REDRAW_FIELD; } -static void DrawPreviewLevelPlayfieldExt(int from_x, int from_y) +static void DrawPreviewLevelPlayfield(int from_x, int from_y) { boolean show_level_border = (BorderElement != EL_EMPTY); int level_xsize = lev_fieldx + (show_level_border ? 2 : 0); @@ -3026,9 +3073,8 @@ static int getMaxTextLength(struct TextPosInfo *pos, int font_nr) return max_text_width / font_width; } -static void DrawPreviewLevelLabelExt(int mode) +static void DrawPreviewLevelLabelExt(int mode, struct TextPosInfo *pos) { - struct TextPosInfo *pos = &menu.main.text.level_info_2; char label_text[MAX_OUTPUT_LINESIZE + 1]; int max_len_label_text; int font_nr = pos->font; @@ -3071,6 +3117,19 @@ static void DrawPreviewLevelLabelExt(int mode) redraw_mask |= REDRAW_FIELD; } +static void DrawPreviewLevelLabel(int mode) +{ + DrawPreviewLevelLabelExt(mode, &menu.main.text.level_info_2); +} + +static void DrawPreviewLevelInfo(int mode) +{ + if (mode == MICROLABEL_LEVEL_NAME) + DrawPreviewLevelLabelExt(mode, &menu.main.text.level_name); + else if (mode == MICROLABEL_LEVEL_AUTHOR) + DrawPreviewLevelLabelExt(mode, &menu.main.text.level_author); +} + static void DrawPreviewLevelExt(boolean restart) { static unsigned int scroll_delay = 0; @@ -3102,8 +3161,11 @@ static void DrawPreviewLevelExt(boolean restart) label_state = 1; label_counter = 0; - DrawPreviewLevelPlayfieldExt(from_x, from_y); - DrawPreviewLevelLabelExt(label_state); + DrawPreviewLevelPlayfield(from_x, from_y); + DrawPreviewLevelLabel(label_state); + + DrawPreviewLevelInfo(MICROLABEL_LEVEL_NAME); + DrawPreviewLevelInfo(MICROLABEL_LEVEL_AUTHOR); /* initialize delay counters */ DelayReached(&scroll_delay, 0); @@ -3182,7 +3244,7 @@ static void DrawPreviewLevelExt(boolean restart) break; } - DrawPreviewLevelPlayfieldExt(from_x, from_y); + DrawPreviewLevelPlayfield(from_x, from_y); } /* !!! THIS ALL SUCKS -- SHOULD BE CLEANLY REWRITTEN !!! */ @@ -3223,7 +3285,7 @@ static void DrawPreviewLevelExt(boolean restart) label_state = (label_state == MICROLABEL_IMPORTED_FROM_HEAD ? MICROLABEL_IMPORTED_BY_HEAD : MICROLABEL_IMPORTED_BY); - DrawPreviewLevelLabelExt(label_state); + DrawPreviewLevelLabel(label_state); } } @@ -3729,6 +3791,9 @@ void WaitForEventToContinue() { boolean still_wait = TRUE; + if (program.headless) + return; + /* simulate releasing mouse button over last gadget, if still pressed */ if (button_status) HandleGadgets(-1, -1, 0); @@ -3739,16 +3804,18 @@ void WaitForEventToContinue() while (still_wait) { - if (PendingEvent()) - { - Event event; - - NextEvent(&event); + Event event; + if (NextValidEvent(&event)) + { switch (event.type) { case EVENT_BUTTONPRESS: case EVENT_KEYPRESS: +#if defined(TARGET_SDL2) + case SDL_CONTROLLERBUTTONDOWN: +#endif + case SDL_JOYBUTTONDOWN: still_wait = FALSE; break; @@ -3876,6 +3943,19 @@ static int RequestHandleEvents(unsigned int req_state) break; } +#if defined(TARGET_SDL2) + case SDL_WINDOWEVENT: + HandleWindowEvent((WindowEvent *) &event); + break; + + case SDL_APP_WILLENTERBACKGROUND: + case SDL_APP_DIDENTERBACKGROUND: + case SDL_APP_WILLENTERFOREGROUND: + case SDL_APP_DIDENTERFOREGROUND: + HandlePauseResumeEvent((PauseResumeEvent *) &event); + break; +#endif + case EVENT_KEYPRESS: { Key key = GetEventKey((KeyEvent *)&event, TRUE); @@ -3889,7 +3969,11 @@ static int RequestHandleEvents(unsigned int req_state) case KSYM_Return: #if defined(TARGET_SDL2) + case KSYM_Select: case KSYM_Menu: +#if defined(KSYM_Rewind) + case KSYM_Rewind: /* for Amazon Fire TV remote */ +#endif #endif result = 1; break; @@ -3897,6 +3981,9 @@ static int RequestHandleEvents(unsigned int req_state) case KSYM_Escape: #if defined(TARGET_SDL2) case KSYM_Back: +#if defined(KSYM_FastForward) + case KSYM_FastForward: /* for Amazon Fire TV remote */ +#endif #endif result = 0; break; @@ -3916,6 +4003,35 @@ static int RequestHandleEvents(unsigned int req_state) ClearPlayerAction(); break; +#if defined(TARGET_SDL2) + case SDL_CONTROLLERBUTTONDOWN: + switch (event.cbutton.button) + { + case SDL_CONTROLLER_BUTTON_A: + case SDL_CONTROLLER_BUTTON_X: + case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: + result = 1; + break; + + case SDL_CONTROLLER_BUTTON_B: + case SDL_CONTROLLER_BUTTON_Y: + case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: + case SDL_CONTROLLER_BUTTON_BACK: + result = 0; + break; + } + + if (req_state & REQ_PLAYER) + result = 0; + + break; + + case SDL_CONTROLLERBUTTONUP: + HandleJoystickEvent(&event); + ClearPlayerAction(); + break; +#endif + default: HandleOtherEvents(&event); break; @@ -4790,6 +4906,9 @@ unsigned int MoveDoor(unsigned int door_state) SkipUntilDelayReached(&door_delay, door_delay_value, &k, last_frame); current_move_delay += max_step_delay; + + /* prevent OS (Windows) from complaining about program not responding */ + CheckQuitEvent(); } if (door_part_done_all) @@ -7109,6 +7228,60 @@ int map_action_SP_to_RND(int action_sp) } } +int map_element_RND_to_MM(int element_rnd) +{ + return (element_rnd >= EL_CHAR_START && + element_rnd <= EL_CHAR_END ? + EL_CHAR_START_NATIVE_MM + element_rnd - EL_CHAR_START : + + element_rnd >= EL_DF_START && + element_rnd <= EL_DF_END ? + EL_DF_START_NATIVE_MM + element_rnd - EL_DF_START : + + element_rnd >= EL_MM_START && + element_rnd <= EL_MM_END ? + EL_MM_START_NATIVE_MM + element_rnd - EL_MM_START : + + element_rnd >= EL_MM_RUNTIME_START && + element_rnd <= EL_MM_RUNTIME_END ? + EL_MM_RUNTIME_START_NATIVE_MM + element_rnd - EL_MM_RUNTIME_START : + + element_rnd >= EL_MM_DUMMY_START && + element_rnd <= EL_MM_DUMMY_END ? + EL_MM_DUMMY_START_NATIVE_MM + element_rnd - EL_MM_DUMMY_START : + + EL_EMPTY_NATIVE_MM); +} + +int map_element_MM_to_RND(int element_mm) +{ + return (element_mm == EL_EMPTY_NATIVE_MM || + element_mm == EL_DF_EMPTY_NATIVE_MM ? + EL_EMPTY : + + element_mm >= EL_CHAR_START_NATIVE_MM && + element_mm <= EL_CHAR_END_NATIVE_MM ? + EL_CHAR_START + element_mm - EL_CHAR_START_NATIVE_MM : + + element_mm >= EL_DF_START_NATIVE_MM && + element_mm <= EL_DF_END_NATIVE_MM ? + EL_DF_START + element_mm - EL_DF_START_NATIVE_MM : + + element_mm >= EL_MM_START_NATIVE_MM && + element_mm <= EL_MM_END_NATIVE_MM ? + EL_MM_START + element_mm - EL_MM_START_NATIVE_MM : + + element_mm >= EL_MM_RUNTIME_START_NATIVE_MM && + element_mm <= EL_MM_RUNTIME_END_NATIVE_MM ? + EL_MM_RUNTIME_START + element_mm - EL_MM_RUNTIME_START_NATIVE_MM : + + element_mm >= EL_MM_DUMMY_START_NATIVE_MM && + element_mm <= EL_MM_DUMMY_END_NATIVE_MM ? + EL_MM_DUMMY_START + element_mm - EL_MM_DUMMY_START_NATIVE_MM : + + EL_EMPTY); +} + int get_next_element(int element) { switch (element) @@ -7353,6 +7526,8 @@ unsigned int InitRND(int seed) return InitEngineRandom_EM(seed); else if (level.game_engine_type == GAME_ENGINE_TYPE_SP) return InitEngineRandom_SP(seed); + else if (level.game_engine_type == GAME_ENGINE_TYPE_MM) + return InitEngineRandom_MM(seed); else return InitEngineRandom_RND(seed); } @@ -8307,8 +8482,15 @@ void CheckSingleStepMode_EM(byte action[MAX_PLAYERS], int frame, void CheckSingleStepMode_SP(boolean murphy_is_waiting, boolean murphy_is_dropping) { + boolean murphy_starts_dropping = FALSE; + int i; + + for (i = 0; i < MAX_PLAYERS; i++) + if (stored_player[i].force_dropping) + murphy_starts_dropping = TRUE; + if (tape.single_step && tape.recording && !tape.pausing) - if (murphy_is_waiting) + if (murphy_is_waiting && !murphy_starts_dropping) TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); CheckSaveEngineSnapshot_SP(murphy_is_waiting, murphy_is_dropping); @@ -8398,7 +8580,37 @@ void PlayMenuMusicExt(int music) void PlayMenuMusic() { - PlayMenuMusicExt(menu.music[game_status]); + char *curr_music = getCurrentlyPlayingMusicFilename(); + char *next_music = getMusicInfoEntryFilename(menu.music[game_status]); + + if (!strEqual(curr_music, next_music)) + PlayMenuMusicExt(menu.music[game_status]); +} + +void PlayMenuSoundsAndMusic() +{ + PlayMenuSound(); + PlayMenuMusic(); +} + +static void FadeMenuSounds() +{ + FadeSounds(); +} + +static void FadeMenuMusic() +{ + char *curr_music = getCurrentlyPlayingMusicFilename(); + char *next_music = getMusicInfoEntryFilename(menu.music[game_status]); + + if (!strEqual(curr_music, next_music)) + FadeMusic(); +} + +void FadeMenuSoundsAndMusic() +{ + FadeMenuSounds(); + FadeMenuMusic(); } void PlaySoundActivating() @@ -8494,6 +8706,8 @@ void SetAnimStatus(int anim_status_new) { if (anim_status_new == GAME_MODE_MAIN) anim_status_new = GAME_MODE_PSEUDO_MAINONLY; + else if (anim_status_new == GAME_MODE_SCORES) + anim_status_new = GAME_MODE_PSEUDO_SCORESOLD; global.anim_status_next = anim_status_new;