Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package rocksndiamonds for openSUSE:Factory checked in at 2021-02-02 14:25:20 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/rocksndiamonds (Old) and /work/SRC/openSUSE:Factory/.rocksndiamonds.new.28504 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "rocksndiamonds" Tue Feb 2 14:25:20 2021 rev:34 rq:868416 version:4.2.2.1 Changes: -------- --- /work/SRC/openSUSE:Factory/rocksndiamonds/rocksndiamonds.changes 2021-01-05 18:15:59.975493494 +0100 +++ /work/SRC/openSUSE:Factory/.rocksndiamonds.new.28504/rocksndiamonds.changes 2021-02-02 14:25:29.939375700 +0100 @@ -1,0 +2,19 @@ +Sat Jan 23 01:27:33 UTC 2021 - Dirk M��ller <dmueller@suse.com> + +- don't recreate games user - managed by systemd-users-game +- update to 4.2.2.1: + * fixed bug with playing team mode tapes with changed visible playfield size + * added patch mode to patch tapes to force visible playfield size of 34 x 34 + * added patch mode to automatically fix tapes for visible playfield size + * fixed single step mode for R���n���D game engine when used in team mode + * fixed triggering custom element actions by digging or collecting + * added option in level editor to use time score for 1 or 10 seconds left + * fixed time score for native Emerald Mine and Diamond Caves levels + * fixed bug with screen keyboard still being active during request dialogs + * fixed bug with screen keyboard causing overlay buttons to be disabled + * added option to disable warning about read-only levels when entering editor + * fixed bug with not updating game panel when leaving invisible warp mode + * fixed displaying new high score entry if new entry is not on the first page + * fixed graphical bug with envelope style request dialog after the game ended + +------------------------------------------------------------------- Old: ---- rocksndiamonds-4.2.2.0.tar.gz New: ---- rocksndiamonds-4.2.2.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ rocksndiamonds.spec ++++++ --- /var/tmp/diff_new_pack.RDc7H5/_old 2021-02-02 14:25:30.599376726 +0100 +++ /var/tmp/diff_new_pack.RDc7H5/_new 2021-02-02 14:25:30.603376733 +0100 @@ -17,7 +17,7 @@ Name: rocksndiamonds -Version: 4.2.2.0 +Version: 4.2.2.1 Release: 0 Summary: Colorful Boulderdash'n'Emerald Mine'n'Sokoban'n'Stuff License: GPL-2.0-or-later @@ -31,16 +31,13 @@ BuildRequires: fdupes BuildRequires: hicolor-icon-theme BuildRequires: pkgconfig -#BuildRequires: libsmpeg-devel +BuildRequires: system-user-games BuildRequires: update-desktop-files BuildRequires: pkgconfig(SDL2_image) BuildRequires: pkgconfig(SDL2_mixer) BuildRequires: pkgconfig(SDL2_net) BuildRequires: pkgconfig(zlib) Requires: %{name}-data -Requires(pre): %{_sbindir}/groupadd -Requires(pre): %{_sbindir}/useradd -Requires(pre): group(games) Requires(pre): user(games) %description @@ -90,10 +87,6 @@ %fdupes -s %{buildroot}%{_prefix} -%pre -getent group games >/dev/null || groupadd -r games -getent passwd games >/dev/null || useradd -r -g games -d %{_localstatedir}/games -s /sbin/nologin - %files %license COPYING %doc CREDITS ChangeLog ++++++ rocksndiamonds-4.2.2.0.tar.gz -> rocksndiamonds-4.2.2.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/CREDITS new/rocksndiamonds-4.2.2.1/CREDITS --- old/rocksndiamonds-4.2.2.0/CREDITS 2020-10-02 12:38:50.000000000 +0200 +++ new/rocksndiamonds-4.2.2.1/CREDITS 2021-01-15 17:16:52.000000000 +0100 @@ -51,5 +51,7 @@ Thanks to Simon Forsberg for being the moderator of the R'n'D forum. +Thanks to Rick Jansen for white X-mas. + And not to forget: Many thanks to all those who contributed levels to this game since 1995! Binary files old/rocksndiamonds-4.2.2.0/rocksndiamonds and new/rocksndiamonds-4.2.2.1/rocksndiamonds differ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/confhash.h new/rocksndiamonds-4.2.2.1/src/confhash.h --- old/rocksndiamonds-4.2.2.0/src/confhash.h 2020-12-23 13:04:59.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/confhash.h 2021-01-15 17:17:14.000000000 +0100 @@ -1 +1 @@ -#define SOURCE_HASH_STRING "ba02ca3" +#define SOURCE_HASH_STRING "b2c4f6e" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/conftime.h new/rocksndiamonds-4.2.2.1/src/conftime.h --- old/rocksndiamonds-4.2.2.0/src/conftime.h 2020-12-23 13:04:59.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/conftime.h 2021-01-15 17:17:14.000000000 +0100 @@ -1 +1 @@ -#define SOURCE_DATE_STRING "2020-12-23 12:03" +#define SOURCE_DATE_STRING "2021-01-10 00:08" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/editor.c new/rocksndiamonds-4.2.2.1/src/editor.c --- old/rocksndiamonds-4.2.2.0/src/editor.c 2020-12-14 02:15:48.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/editor.c 2021-01-15 17:16:52.000000000 +0100 @@ -559,6 +559,7 @@ // selectbox identifiers GADGET_ID_TIME_OR_STEPS, + GADGET_ID_TIME_SCORE_BASE, GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_LEVELSET_SAVE_MODE, GADGET_ID_WIND_DIRECTION, @@ -648,6 +649,7 @@ GADGET_ID_SB_OBJECTS_NEEDED, GADGET_ID_AUTO_EXIT_SOKOBAN, GADGET_ID_SOLVED_BY_ONE_PLAYER, + GADGET_ID_FINISH_DIG_COLLECT, GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_BLOCK_SNAP_FIELD, GADGET_ID_BLOCK_LAST_FIELD, @@ -839,6 +841,7 @@ enum { ED_SELECTBOX_ID_TIME_OR_STEPS, + ED_SELECTBOX_ID_TIME_SCORE_BASE, ED_SELECTBOX_ID_GAME_ENGINE_TYPE, ED_SELECTBOX_ID_LEVELSET_SAVE_MODE, ED_SELECTBOX_ID_WIND_DIRECTION, @@ -953,6 +956,7 @@ ED_CHECKBUTTON_ID_SB_OBJECTS_NEEDED, ED_CHECKBUTTON_ID_AUTO_EXIT_SOKOBAN, ED_CHECKBUTTON_ID_SOLVED_BY_ONE_PLAYER, + ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT, ED_CHECKBUTTON_ID_CONTINUOUS_SNAPPING, ED_CHECKBUTTON_ID_BLOCK_SNAP_FIELD, ED_CHECKBUTTON_ID_BLOCK_LAST_FIELD, @@ -1408,7 +1412,7 @@ GADGET_ID_LEVEL_TIMESCORE_DOWN, GADGET_ID_LEVEL_TIMESCORE_UP, GADGET_ID_LEVEL_TIMESCORE_TEXT, GADGET_ID_NONE, &level.score[SC_TIME_BONUS], - "score for each second/step left:", NULL, NULL + "score for time or steps left:", NULL, NULL }, { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(12), @@ -1731,6 +1735,14 @@ { -1, NULL } }; +static struct ValueTextInfo options_time_score_base[] = +{ + { 1, "per second/step" }, + { 10, "per 10 seconds/steps" }, + + { -1, NULL } +}; + static struct ValueTextInfo options_game_engine_type[] = { { GAME_ENGINE_TYPE_RND, "Rocks'n'Diamonds" }, @@ -2466,6 +2478,14 @@ NULL, NULL, "(0 => no limit)", "time or step limit" }, { + -1, ED_LEVEL_SETTINGS_YPOS(10), + GADGET_ID_TIME_SCORE_BASE, GADGET_ID_LEVEL_TIMESCORE_UP, + -1, + options_time_score_base, + &level.time_score_base, + NULL, NULL, NULL, "time score for 1 or 10 seconds/steps" + }, + { ED_LEVEL_SETTINGS_XPOS(0), ED_LEVEL_SETTINGS_YPOS(11), GADGET_ID_GAME_ENGINE_TYPE, GADGET_ID_NONE, -1, @@ -3111,6 +3131,13 @@ "only one player must enter exit", "level solved by first player in exit" }, { + ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(3), + GADGET_ID_FINISH_DIG_COLLECT, GADGET_ID_NONE, + &level.finish_dig_collect, + NULL, NULL, + "CE action on finished dig/collect", "only finished dig/collect triggers CE" + }, + { ED_ELEMENT_SETTINGS_XPOS(0), ED_ELEMENT_SETTINGS_YPOS(9), GADGET_ID_CONTINUOUS_SNAPPING, GADGET_ID_NONE, &level.continuous_snapping, @@ -7722,7 +7749,7 @@ return TRUE; } - if (!Request("This level is read only! " + if (!Request("This level is read-only! " "Save into personal level set?", REQ_ASK)) return FALSE; @@ -9983,6 +10010,7 @@ // draw checkbutton gadgets MapCheckbuttonGadget(ED_CHECKBUTTON_ID_USE_INITIAL_INVENTORY); + MapCheckbuttonGadget(ED_CHECKBUTTON_ID_FINISH_DIG_COLLECT); // draw counter gadgets MapCounterButtons(ED_COUNTER_ID_INVENTORY_SIZE); @@ -13382,7 +13410,7 @@ if (levelset_save_mode == LEVELSET_SAVE_MODE_UPDATE && leveldir_current->readonly) { - Request("This level set is read only!", REQ_CONFIRM); + Request("This level set is read-only!", REQ_CONFIRM); return; } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/engines.h new/rocksndiamonds-4.2.2.1/src/engines.h --- old/rocksndiamonds-4.2.2.0/src/engines.h 2020-12-14 02:15:48.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/engines.h 2021-01-15 17:16:52.000000000 +0100 @@ -31,6 +31,9 @@ boolean getTeamMode_EM(void); boolean isActivePlayer_EM(int); +int getScreenFieldSizeX(void); +int getScreenFieldSizeY(void); + void PlayLevelSound_EM(int, int, int, int); void InitGraphicInfo_EM(void); boolean CheckSingleStepMode_EM(byte action[], int, boolean, boolean, boolean); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/events.c new/rocksndiamonds-4.2.2.1/src/events.c --- old/rocksndiamonds-4.2.2.0/src/events.c 2020-12-23 13:04:38.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/events.c 2021-01-15 17:16:52.000000000 +0100 @@ -1476,7 +1476,7 @@ if (key_status == KEY_PRESSED) SetOverlayEnabled(!GetOverlayEnabled()); } - else + else if (!textinput_status) { // for any other "real" key event, disable virtual buttons SetOverlayEnabled(FALSE); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/files.c new/rocksndiamonds-4.2.2.1/src/files.c --- old/rocksndiamonds-4.2.2.0/src/files.c 2020-12-23 13:04:38.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/files.c 2021-01-15 17:16:52.000000000 +0100 @@ -59,6 +59,7 @@ #define TAPE_CHUNK_VERS_SIZE 8 // size of file version chunk #define TAPE_CHUNK_HEAD_SIZE 20 // size of tape file header #define TAPE_CHUNK_HEAD_UNUSED 1 // unused tape header bytes +#define TAPE_CHUNK_SCRN_SIZE 2 // size of screen size chunk #define LEVEL_CHUNK_CNT3_SIZE(x) (LEVEL_CHUNK_CNT3_HEADER + (x)) #define LEVEL_CHUNK_CUS3_SIZE(x) (2 + (x) * LEVEL_CPART_CUS3_SIZE) @@ -259,6 +260,12 @@ { -1, -1, + TYPE_INTEGER, CONF_VALUE_8_BIT(12), + &li.time_score_base, 1 + }, + + { + -1, -1, -1, -1, NULL, -1 } @@ -307,6 +314,11 @@ TYPE_BOOLEAN, CONF_VALUE_8_BIT(15), &li.lazy_relocation, FALSE }, + { + EL_PLAYER_1, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(16), + &li.finish_dig_collect, TRUE + }, // (these values are different for each player) { @@ -3710,6 +3722,9 @@ if (jx != -1 && jy != -1) level->field[jx][jy] = EL_PLAYER_1 + nr; } + + // time score is counted for each 10 seconds left in Emerald Mine levels + level->time_score_base = 10; } @@ -5727,6 +5742,9 @@ // Diamond Caves has the same (strange) behaviour as Emerald Mine that gems // can slip down from flat walls, like normal walls and steel walls level->em_slippery_gems = TRUE; + + // time score is counted for each 10 seconds left in Diamond Caves levels + level->time_score_base = 10; } static void LoadLevelFromFileInfo_DC(struct LevelInfo *level, @@ -6250,7 +6268,7 @@ if (level->game_version < VERSION_IDENT(3,2,0,5)) { // time bonus score was given for 10 s instead of 1 s before 3.2.0-5 - level->score[SC_TIME_BONUS] /= 10; + level->time_score_base = 10; } if (leveldir_current->latest_engine) @@ -6422,6 +6440,10 @@ // only Sokoban fields (but not objects) had to be solved before 4.1.1.1 if (level->game_version < VERSION_IDENT(4,1,1,1)) level->sb_objects_needed = FALSE; + + // CE actions were triggered by unfinished digging/collecting up to 4.2.2.0 + if (level->game_version <= VERSION_IDENT(4,2,2,0)) + level->finish_dig_collect = FALSE; } static void LoadLevel_InitStandardElements(struct LevelInfo *level) @@ -7628,6 +7650,9 @@ tape.playing = FALSE; tape.pausing = FALSE; + tape.scr_fieldx = SCR_FIELDX_DEFAULT; + tape.scr_fieldy = SCR_FIELDY_DEFAULT; + tape.no_valid_file = FALSE; } @@ -7718,6 +7743,14 @@ return chunk_size; } +static int LoadTape_SCRN(File *file, int chunk_size, struct TapeInfo *tape) +{ + tape->scr_fieldx = getFile8Bit(file); + tape->scr_fieldy = getFile8Bit(file); + + return chunk_size; +} + static int LoadTape_INFO(File *file, int chunk_size, struct TapeInfo *tape) { int level_identifier_size; @@ -8008,6 +8041,7 @@ { { "VERS", TAPE_CHUNK_VERS_SIZE, LoadTape_VERS }, { "HEAD", TAPE_CHUNK_HEAD_SIZE, LoadTape_HEAD }, + { "SCRN", TAPE_CHUNK_SCRN_SIZE, LoadTape_SCRN }, { "INFO", -1, LoadTape_INFO }, { "BODY", -1, LoadTape_BODY }, { NULL, 0, NULL } @@ -8088,6 +8122,14 @@ CopyNativeTape_SP_to_RND(&level); } +static boolean checkSaveTape_SCRN(struct TapeInfo *tape) +{ + // chunk required for team mode tapes with non-default screen size + return (tape->num_participating_players > 1 && + (tape->scr_fieldx != SCR_FIELDX_DEFAULT || + tape->scr_fieldy != SCR_FIELDY_DEFAULT)); +} + static void SaveTape_VERS(FILE *file, struct TapeInfo *tape) { putFileVersion(file, tape->file_version); @@ -8120,6 +8162,12 @@ putFileVersion(file, tape->engine_version); } +static void SaveTape_SCRN(FILE *file, struct TapeInfo *tape) +{ + putFile8Bit(file, tape->scr_fieldx); + putFile8Bit(file, tape->scr_fieldy); +} + static void SaveTape_INFO(FILE *file, struct TapeInfo *tape) { int level_identifier_size = strlen(tape->level_identifier) + 1; @@ -8185,6 +8233,12 @@ putFileChunkBE(file, "HEAD", TAPE_CHUNK_HEAD_SIZE); SaveTape_HEAD(file, &tape); + if (checkSaveTape_SCRN(&tape)) + { + putFileChunkBE(file, "SCRN", TAPE_CHUNK_SCRN_SIZE); + SaveTape_SCRN(file, &tape); + } + putFileChunkBE(file, "INFO", info_chunk_size); SaveTape_INFO(file, &tape); @@ -8693,6 +8747,10 @@ TYPE_SWITCH, &setup.editor.show_element_token, "editor.show_element_token" }, + { + TYPE_SWITCH, + &setup.editor.show_read_only_warning, "editor.show_read_only_warning" + }, }; static struct TokenInfo editor_cascade_setup_tokens[] = @@ -9324,6 +9382,8 @@ si->editor.show_element_token = FALSE; + si->editor.show_read_only_warning = TRUE; + si->editor.use_template_for_new_levels = TRUE; si->shortcut.save_game = DEFAULT_KEY_SAVE_GAME; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/game.c new/rocksndiamonds-4.2.2.1/src/game.c --- old/rocksndiamonds-4.2.2.0/src/game.c 2020-12-23 13:04:38.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/game.c 2021-01-15 17:16:52.000000000 +0100 @@ -1119,6 +1119,8 @@ static int getInvisibleActiveFromInvisibleElement(int); static int getInvisibleFromInvisibleActiveElement(int); +static void TestFieldAfterSnapping(int, int, int, int, int); + static struct GadgetInfo *game_gadget[NUM_GAME_BUTTONS]; // for detection of endless loops, caused by custom element programming @@ -2867,12 +2869,10 @@ DisplayGameControlValues(); } -#if 0 -static void UpdateGameDoorValues(void) +void UpdateGameDoorValues(void) { UpdateGameControlValues(); } -#endif void DrawGameDoorValues(void) { @@ -3576,11 +3576,15 @@ InitGameEngine(); InitGameControlValues(); - // initialize tape actions from game when recording tape if (tape.recording) { + // initialize tape actions from game when recording tape tape.use_key_actions = game.use_key_actions; tape.use_mouse_actions = game.use_mouse_actions; + + // initialize visible playfield size when recording tape (for team mode) + tape.scr_fieldx = SCR_FIELDX; + tape.scr_fieldy = SCR_FIELDY; } // don't play tapes over network @@ -3713,6 +3717,8 @@ player->shield_normal_time_left = 0; player->shield_deadly_time_left = 0; + player->last_removed_element = EL_UNDEFINED; + player->inventory_infinite_element = EL_UNDEFINED; player->inventory_size = 0; @@ -4710,7 +4716,7 @@ { static int time_count_steps; static int time, time_final; - static int score, score_final; + static float score, score_final; // needed for time score < 10 for 10 seconds static int health, health_final; static int game_over_delay_1 = 0; static int game_over_delay_2 = 0; @@ -4718,6 +4724,8 @@ int game_over_delay_value_1 = 50; int game_over_delay_value_2 = 25; int game_over_delay_value_3 = 50; + int time_score_base = MIN(MAX(1, level.time_score_base), 10); + float time_score = (float)level.score[SC_TIME_BONUS] / time_score_base; if (!game.LevelSolved_GameWon) { @@ -4751,19 +4759,23 @@ score = score_final = game.score_final; health = health_final = game.health_final; - if (level.score[SC_TIME_BONUS] > 0) + if (time_score > 0) { + int time_frames = 0; + if (TimeLeft > 0) { time_final = 0; - score_final += TimeLeft * level.score[SC_TIME_BONUS]; + time_frames = TimeLeft * FRAMES_PER_SECOND - TimeFrames; } else if (game.no_time_limit && TimePlayed < 999) { time_final = 999; - score_final += (999 - TimePlayed) * level.score[SC_TIME_BONUS]; + time_frames = (999 - TimePlayed) * FRAMES_PER_SECOND - TimeFrames; } + score_final += time_score * time_frames / FRAMES_PER_SECOND + 0.5; + time_count_steps = MAX(1, ABS(time_final - time) / 100); game_over_delay_1 = game_over_delay_value_1; @@ -4771,7 +4783,7 @@ if (level.game_engine_type == GAME_ENGINE_TYPE_MM) { health_final = 0; - score_final += health * level.score[SC_TIME_BONUS]; + score_final += health * time_score; game_over_delay_2 = game_over_delay_value_2; } @@ -4860,7 +4872,11 @@ time_count_steps = 1; time += time_count_steps * time_count_dir; - score += time_count_steps * level.score[SC_TIME_BONUS]; + score += time_count_steps * time_score; + + // set final score to correct rounding differences after counting score + if (time == time_final) + score = score_final; game.LevelSolved_CountingTime = time; game.LevelSolved_CountingScore = score; @@ -4892,7 +4908,7 @@ int health_count_dir = (health < health_final ? +1 : -1); health += health_count_dir; - score += level.score[SC_TIME_BONUS]; + score += time_score; game.LevelSolved_CountingHealth = health; game.LevelSolved_CountingScore = score; @@ -11282,13 +11298,14 @@ { if (tape.single_step && tape.recording && !tape.pausing) { - /* as it is called "single step mode", just return to pause mode when the - player stopped moving after one tile (or never starts moving at all) */ - if (!player->is_moving && - !player->is_pushing && - !player->is_dropping_pressed && - !player->effective_mouse_action.button) - TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + // as it is called "single step mode", just return to pause mode when the + // player stopped moving after one tile (or never starts moving at all) + // (reverse logic needed here in case single step mode used in team mode) + if (player->is_moving || + player->is_pushing || + player->is_dropping_pressed || + player->effective_mouse_action.button) + game.enter_single_step_mode = FALSE; } CheckSaveEngineSnapshot(player); @@ -11951,6 +11968,10 @@ DrawGameDoorValues(); } + // check single step mode (set flag and clear again if any player is active) + game.enter_single_step_mode = + (tape.single_step && tape.recording && !tape.pausing); + for (i = 0; i < MAX_PLAYERS; i++) { int actual_player_action = stored_player[i].effective_action; @@ -11975,6 +11996,10 @@ ScrollPlayer(&stored_player[i], SCROLL_GO_ON); } + // single step pause mode may already have been toggled by "ScrollPlayer()" + if (game.enter_single_step_mode && !tape.pausing) + TapeTogglePause(TAPE_TOGGLE_AUTOMATIC); + ScrollScreen(NULL, SCROLL_GO_ON); /* for backwards compatibility, the following code emulates a fixed bug that @@ -12027,10 +12052,17 @@ MovDelay[x][y]--; if (MovDelay[x][y] <= 0) { + int element = Store[x][y]; + int move_direction = MovDir[x][y]; + int player_index_bit = Store2[x][y]; + + Store[x][y] = 0; + Store2[x][y] = 0; + RemoveField(x, y); TEST_DrawLevelField(x, y); - TestIfElementTouchesCustomElement(x, y); // for empty space + TestFieldAfterSnapping(x, y, element, move_direction, player_index_bit); } } @@ -12448,6 +12480,8 @@ static boolean AllPlayersInSight(struct PlayerInfo *player, int x, int y) { int min_x = x, min_y = y, max_x = x, max_y = y; + int scr_fieldx = getScreenFieldSizeX(); + int scr_fieldy = getScreenFieldSizeY(); int i; for (i = 0; i < MAX_PLAYERS; i++) @@ -12463,7 +12497,7 @@ max_y = MAX(max_y, jy); } - return (max_x - min_x < SCR_FIELDX && max_y - min_y < SCR_FIELDY); + return (max_x - min_x < scr_fieldx && max_y - min_y < scr_fieldy); } static boolean AllPlayersInVisibleScreen(void) @@ -13029,6 +13063,21 @@ if (!player->is_pushing) TestIfElementTouchesCustomElement(jx, jy); // for empty space + if (level.finish_dig_collect && + (player->is_digging || player->is_collecting)) + { + int last_element = player->last_removed_element; + int move_direction = player->MovDir; + int enter_side = MV_DIR_OPPOSITE(move_direction); + int change_event = (player->is_digging ? CE_PLAYER_DIGS_X : + CE_PLAYER_COLLECTS_X); + + CheckTriggeredElementChangeByPlayer(jx, jy, last_element, change_event, + player->index_bit, enter_side); + + player->last_removed_element = EL_UNDEFINED; + } + if (!player->active) RemovePlayer(player); } @@ -13763,7 +13812,8 @@ game.players_still_needed--; } -static void setFieldForSnapping(int x, int y, int element, int direction) +static void SetFieldForSnapping(int x, int y, int element, int direction, + int player_index_bit) { struct ElementInfo *ei = &element_info[element]; int direction_bit = MV_DIR_TO_BIT(direction); @@ -13773,6 +13823,9 @@ Tile[x][y] = EL_ELEMENT_SNAPPING; MovDelay[x][y] = MOVE_DELAY_NORMAL_SPEED + 1 - 1; + MovDir[x][y] = direction; + Store[x][y] = element; + Store2[x][y] = player_index_bit; ResetGfxAnimation(x, y); @@ -13782,6 +13835,20 @@ GfxFrame[x][y] = -1; } +static void TestFieldAfterSnapping(int x, int y, int element, int direction, + int player_index_bit) +{ + TestIfElementTouchesCustomElement(x, y); // for empty space + + if (level.finish_dig_collect) + { + int dig_side = MV_DIR_OPPOSITE(direction); + + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player_index_bit, dig_side); + } +} + /* ============================================================================= checkDiagonalPushing() @@ -14061,22 +14128,28 @@ PlayLevelSoundElementAction(x, y, element, ACTION_DIGGING); - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_DIGS_X, - player->index_bit, dig_side); + // use old behaviour for old levels (digging) + if (!level.finish_dig_collect) + { + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_DIGS_X, + player->index_bit, dig_side); - // if digging triggered player relocation, finish digging tile - if (mode == DF_DIG && (player->jx != jx || player->jy != jy)) - setFieldForSnapping(x, y, element, move_direction); + // if digging triggered player relocation, finish digging tile + if (mode == DF_DIG && (player->jx != jx || player->jy != jy)) + SetFieldForSnapping(x, y, element, move_direction, player->index_bit); + } if (mode == DF_SNAP) { if (level.block_snap_field) - setFieldForSnapping(x, y, element, move_direction); + SetFieldForSnapping(x, y, element, move_direction, player->index_bit); else - TestIfElementTouchesCustomElement(x, y); // for empty space + TestFieldAfterSnapping(x, y, element, move_direction, player->index_bit); - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, - player->index_bit, dig_side); + // use old behaviour for old levels (snapping) + if (!level.finish_dig_collect) + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player->index_bit, dig_side); } } else if (player_can_move_or_snap && IS_COLLECTIBLE(element)) @@ -14188,25 +14261,28 @@ RaiseScoreElement(element); PlayLevelSoundElementAction(x, y, element, ACTION_COLLECTING); - if (is_player) + // use old behaviour for old levels (collecting) + if (!level.finish_dig_collect && is_player) { CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_COLLECTS_X, player->index_bit, dig_side); // if collecting triggered player relocation, finish collecting tile if (mode == DF_DIG && (player->jx != jx || player->jy != jy)) - setFieldForSnapping(x, y, element, move_direction); + SetFieldForSnapping(x, y, element, move_direction, player->index_bit); } if (mode == DF_SNAP) { if (level.block_snap_field) - setFieldForSnapping(x, y, element, move_direction); + SetFieldForSnapping(x, y, element, move_direction, player->index_bit); else - TestIfElementTouchesCustomElement(x, y); // for empty space + TestFieldAfterSnapping(x, y, element, move_direction, player->index_bit); - CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, - player->index_bit, dig_side); + // use old behaviour for old levels (snapping) + if (!level.finish_dig_collect) + CheckTriggeredElementChangeByPlayer(x, y, element, CE_PLAYER_SNAPS_X, + player->index_bit, dig_side); } } else if (player_can_move_or_snap && IS_PUSHABLE(element)) @@ -14544,6 +14620,8 @@ { player->is_collecting = !player->is_digging; player->is_active = TRUE; + + player->last_removed_element = element; } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/game.h new/rocksndiamonds-4.2.2.1/src/game.h --- old/rocksndiamonds-4.2.2.0/src/game.h 2020-12-23 13:04:38.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/game.h 2021-01-15 17:16:52.000000000 +0100 @@ -244,6 +244,9 @@ boolean set_centered_player; boolean set_centered_player_wrap; + // values for single step mode control + boolean enter_single_step_mode; + // values for random number generator initialization after snapshot unsigned int num_random_calls; @@ -378,6 +381,8 @@ int shield_normal_time_left; int shield_deadly_time_left; + int last_removed_element; + int inventory_element[MAX_INVENTORY_SIZE]; int inventory_infinite_element; int inventory_size; @@ -396,7 +401,7 @@ int getPlayerInventorySize(int); -void DrawGameValue_Time(int); +void UpdateGameDoorValues(void); void DrawGameDoorValues(void); void UpdateAndDisplayGameControlValues(void); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/game_em/graphics.c new/rocksndiamonds-4.2.2.1/src/game_em/graphics.c --- old/rocksndiamonds-4.2.2.0/src/game_em/graphics.c 2020-12-05 10:47:39.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/game_em/graphics.c 2021-01-15 17:16:52.000000000 +0100 @@ -553,11 +553,13 @@ boolean checkIfAllPlayersFitToScreen(void) { int sx1 = 0, sy1 = 0, sx2 = 0, sy2 = 0; + int scr_fieldx = getScreenFieldSizeX(); + int scr_fieldy = getScreenFieldSizeY(); setMinimalPlayerBoundaries(&sx1, &sy1, &sx2, &sy2); - return (sx2 - sx1 <= SCR_FIELDX * TILEX && - sy2 - sy1 <= SCR_FIELDY * TILEY); + return (sx2 - sx1 <= scr_fieldx * TILEX && + sy2 - sy1 <= scr_fieldy * TILEY); } static void setScreenCenteredToAllPlayers(int *sx, int *sy) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/game_em/reademc.c new/rocksndiamonds-4.2.2.1/src/game_em/reademc.c --- old/rocksndiamonds-4.2.2.0/src/game_em/reademc.c 2020-10-02 12:38:50.000000000 +0200 +++ new/rocksndiamonds-4.2.2.1/src/game_em/reademc.c 2021-01-15 17:16:52.000000000 +0100 @@ -312,7 +312,7 @@ cav.nut_score = src[2090]; cav.dynamite_score = src[2091]; cav.key_score = src[2092]; - cav.exit_score = src[2093] * 8 / 5; + cav.exit_score = src[2093]; cav.lenses_score = src[2151]; cav.magnify_score = src[2152]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/game_mm/mm_tools.c new/rocksndiamonds-4.2.2.1/src/game_mm/mm_tools.c --- old/rocksndiamonds-4.2.2.0/src/game_mm/mm_tools.c 2020-12-14 02:15:48.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/game_mm/mm_tools.c 2021-01-15 17:16:52.000000000 +0100 @@ -648,6 +648,7 @@ #define XSN_CHANGE_DELAY 30 #define XSN_CHANGE_FACTOR 3 #define XSN_ALPHA_DEFAULT XSN_ALPHA_VALUE(95) +#define XSN_ALPHA_VISIBLE XSN_ALPHA_VALUE(50) #define XSN_DEBUG_STEPS 5 static byte xsn_bits_0[] = { 0x05, 0x02, 0x05 }; @@ -707,6 +708,8 @@ struct XsnItem items[XSN_MAX_ITEMS]; Bitmap *bitmap; + + int alpha; }; static struct Xsn xsn = { 0 }; @@ -847,7 +850,7 @@ BlitBitmapMasked(xsn.bitmap, xsn.bitmap, xpos1, xsn.max_height, xsize, xsn.max_height, xpos1, 0); - SDLSetAlpha(surface_masked, TRUE, XSN_ALPHA_DEFAULT); + SDLSetAlpha(surface_masked, TRUE, xsn.alpha); for (i = xpos1; i < xpos2; i++) xsn.height[i] = MIN(xsn.height[i] + shrink, xsn.area_ysize - 1); @@ -1015,6 +1018,8 @@ xsn.change_type = 0; xsn.change_dir = 0; + xsn.alpha = XSN_ALPHA_DEFAULT; + for (i = 0; i < xsn.max_items; i++) xsn_init_item(i); } @@ -1045,8 +1050,8 @@ SDL_SetColorKey(surface_masked, SET_TRANSPARENT_PIXEL, SDL_MapRGB(surface_masked->format, 0x00, 0x00, 0x00)); - SDLSetAlpha(surface, TRUE, XSN_ALPHA_DEFAULT); - SDLSetAlpha(surface_masked, TRUE, XSN_ALPHA_DEFAULT); + SDLSetAlpha(surface, TRUE, xsn.alpha); + SDLSetAlpha(surface_masked, TRUE, xsn.alpha); SDLCreateBitmapTextures(xsn.bitmap); @@ -1103,6 +1108,20 @@ change_delay_value = xsn.change_delay * 1000; } + int xsn_alpha_dx = (gfx.mouse_y > xsn.area_ysize - xsn.max_height ? + (xsn.alpha > XSN_ALPHA_VISIBLE ? -1 : 0) : + (xsn.alpha < XSN_ALPHA_DEFAULT ? +1 : 0)); + + if (xsn_alpha_dx != 0) + { + xsn.alpha += xsn_alpha_dx; + + SDLSetAlpha(xsn.bitmap->surface_masked, TRUE, xsn.alpha); + + SDLFreeBitmapTextures(xsn.bitmap); + SDLCreateBitmapTextures(xsn.bitmap); + } + BlitToScreenMasked(xsn.bitmap, 0, 0, xsn.area_xsize, xsn.max_height, 0, xsn.area_ysize - xsn.max_height); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/libgame/system.h new/rocksndiamonds-4.2.2.1/src/libgame/system.h --- old/rocksndiamonds-4.2.2.0/src/libgame/system.h 2020-12-23 13:04:38.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/libgame/system.h 2021-01-15 17:16:52.000000000 +0100 @@ -1284,6 +1284,8 @@ boolean show_element_token; + boolean show_read_only_warning; + boolean use_template_for_new_levels; }; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/main.h new/rocksndiamonds-4.2.2.1/src/main.h --- old/rocksndiamonds-4.2.2.0/src/main.h 2020-12-23 13:04:38.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/main.h 2021-01-15 17:16:52.000000000 +0100 @@ -2571,7 +2571,7 @@ #define PROGRAM_VERSION_SUPER 4 #define PROGRAM_VERSION_MAJOR 2 #define PROGRAM_VERSION_MINOR 2 -#define PROGRAM_VERSION_PATCH 0 +#define PROGRAM_VERSION_PATCH 1 #define PROGRAM_VERSION_EXTRA "" #define PROGRAM_TITLE_STRING "Rocks'n'Diamonds" @@ -3186,6 +3186,7 @@ boolean sb_objects_needed; // all Sokoban objects must be solved boolean auto_exit_sokoban; // automatically finish solved Sokoban levels boolean solved_by_one_player; // level is solved if one player enters exit + boolean finish_dig_collect; // only finished dig/collect triggers ce action boolean continuous_snapping; // repeated snapping without releasing key boolean block_snap_field; // snapping blocks field to show animation @@ -3203,6 +3204,8 @@ // ('int' instead of 'boolean' because used as selectbox value in editor) int use_step_counter; // count steps instead of seconds for level + int time_score_base; // use time score for 1 or 10 seconds/steps + short field[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; boolean use_custom_template; // use custom properties from template file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/screens.c new/rocksndiamonds-4.2.2.1/src/screens.c --- old/rocksndiamonds-4.2.2.0/src/screens.c 2020-12-23 13:04:39.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/screens.c 2021-01-15 17:16:52.000000000 +0100 @@ -2168,10 +2168,10 @@ else if (pos == MAIN_CONTROL_EDITOR) { if (leveldir_current->readonly && - !strEqual(setup.player_name, "Artsoft")) - Request("This level is read only!", REQ_CONFIRM); + setup.editor.show_read_only_warning) + Request("This level is read-only!", REQ_CONFIRM | REQ_STAY_OPEN); - CloseDoor(DOOR_CLOSE_2); + CloseDoor(DOOR_CLOSE_ALL); SetGameStatus(GAME_MODE_EDITOR); @@ -4258,15 +4258,13 @@ name[xpos] = 0; } - else if (key == KSYM_Return) + else if (key == KSYM_Return || key == KSYM_Escape) { - setTypeNameValues(name, pos, TRUE); + boolean changed = (key == KSYM_Return); - active = FALSE; - } - else if (key == KSYM_Escape) - { - setTypeNameValues(name, pos, FALSE); + StopTextInput(); + + setTypeNameValues(name, pos, changed); active = FALSE; } @@ -4275,8 +4273,6 @@ if (!active) { - StopTextInput(); - SetGameStatus(game_status_last_screen); if (game_status == GAME_MODE_MAIN) @@ -5084,9 +5080,15 @@ if (button == MB_MENU_INITIALIZE) { level_nr = mx; - first_entry = 0; highlight_position = my; + first_entry = highlight_position - (NUM_MENU_ENTRIES_ON_SCREEN + 1) / 2 + 1; + + if (first_entry < 0) + first_entry = 0; + else if (first_entry + NUM_MENU_ENTRIES_ON_SCREEN > MAX_SCORE_ENTRIES) + first_entry = MAX(0, MAX_SCORE_ENTRIES - NUM_MENU_ENTRIES_ON_SCREEN); + drawHallOfFameList(level_nr, first_entry, highlight_position); return; @@ -6733,6 +6735,8 @@ #endif { TYPE_SWITCH, &setup.editor.show_element_token, "Show element token:" }, { TYPE_EMPTY, NULL, "" }, + { TYPE_SWITCH, &setup.editor.show_read_only_warning, "Show read-only warning:" }, + { TYPE_EMPTY, NULL, "" }, { TYPE_LEAVE_MENU, execSetupMain, "Back" }, { 0, NULL, NULL } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/tape.c new/rocksndiamonds-4.2.2.1/src/tape.c --- old/rocksndiamonds-4.2.2.0/src/tape.c 2020-12-14 02:15:48.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/tape.c 2021-01-15 17:16:52.000000000 +0100 @@ -459,6 +459,8 @@ if (redraw_display) { RedrawPlayfield(); + + UpdateGameDoorValues(); DrawGameDoorValues(); } } @@ -1237,6 +1239,7 @@ { "original tape", "em_random_bug", + "screen_34x34", NULL }; @@ -1244,6 +1247,7 @@ { VERSION_IDENT(0,0,0,0), VERSION_IDENT(3,3,1,0), + VERSION_IDENT(0,0,0,0), -1 }; @@ -1251,6 +1255,7 @@ { VERSION_IDENT(9,9,9,9), VERSION_IDENT(4,0,1,1), + VERSION_IDENT(4,2,2,0), -1 }; @@ -1258,6 +1263,7 @@ { TAPE_PROPERTY_NONE, TAPE_PROPERTY_EM_RANDOM_BUG, + TAPE_PROPERTY_NONE, -1 }; @@ -1408,6 +1414,8 @@ if (global.autoplay_mode == AUTOPLAY_MODE_FIX) { + boolean skip_patch = FALSE; + if (tape.engine_version < patch_version_first[patch_nr] || tape.engine_version > patch_version_last[patch_nr]) { @@ -1420,6 +1428,22 @@ (tape.engine_version / 100 ) % 100, (tape.engine_version ) % 100); + skip_patch = TRUE; + } + + if (strEqual(patch_name[patch_nr], "screen_34x34") && + tape.num_participating_players == 1) + { + Print("Tape %03d %s[%02d:%02d]: (%s) - skipped.\n", + level_nr, tape_patch_info, + tape.length_seconds / 60, tape.length_seconds % 60, + "not suitable for single player tapes"); + + skip_patch = TRUE; + } + + if (skip_patch) + { if (patch_name[patch_nr + 1] != NULL) { // continue with next patch @@ -1434,7 +1458,15 @@ continue; } - tape.property_bits |= patch_property_bit[patch_nr]; + if (strEqual(patch_name[patch_nr], "screen_34x34")) + { + tape.scr_fieldx = SCR_FIELDX_DEFAULT * 2; + tape.scr_fieldy = SCR_FIELDY_DEFAULT * 2; + } + else + { + tape.property_bits |= patch_property_bit[patch_nr]; + } } InitCounter(); @@ -1493,14 +1525,14 @@ return FALSE; } - byte property_bits = tape->property_bits; + boolean unpatch_tape = FALSE; + boolean use_property_bit = FALSE; byte property_bitmask = 0; - boolean set_property_bit = TRUE; if (strSuffix(mode, ":0") || strSuffix(mode, ":off") || strSuffix(mode, ":clear")) - set_property_bit = FALSE; + unpatch_tape = TRUE; if (strEqual(mode, "em_random_bug") || strPrefix(mode, "em_random_bug:")) { @@ -1514,6 +1546,41 @@ } property_bitmask = TAPE_PROPERTY_EM_RANDOM_BUG; + + use_property_bit = TRUE; + } + else if (strEqual(mode, "screen_34x34") || strPrefix(mode, "screen_34x34:")) + { + // this bug only affects team mode tapes + if (tape->num_participating_players == 1) + { + Print("Only team mode tapes can be patched against screen size bug!\n"); + + return FALSE; + } + + // this bug (that always existed before) was fixed in version 4.2.2.1 + if (tape->engine_version >= VERSION_IDENT(4,2,2,1)) + { + Print("This tape version cannot be patched against screen size bug!\n"); + + return FALSE; + } + + int factor = (unpatch_tape ? 1 : 2); + int scr_fieldx_new = SCR_FIELDX_DEFAULT * factor; + int scr_fieldy_new = SCR_FIELDY_DEFAULT * factor; + + if (scr_fieldx_new == tape->scr_fieldx && + scr_fieldy_new == tape->scr_fieldy) + { + Print("Tape already patched for '%s'!\n", mode); + + return FALSE; + } + + tape->scr_fieldx = scr_fieldx_new; + tape->scr_fieldy = scr_fieldy_new; } else { @@ -1522,22 +1589,29 @@ return FALSE; } - if (set_property_bit) - property_bits |= property_bitmask; - else - property_bits &= ~property_bitmask; - - if (property_bits == tape->property_bits) + // patching tapes using property bits may be used for several patch modes + if (use_property_bit) { - Print("Tape already patched for '%s'!\n", mode); + byte property_bits = tape->property_bits; + boolean set_property_bit = (unpatch_tape ? FALSE : TRUE); - return FALSE; + if (set_property_bit) + property_bits |= property_bitmask; + else + property_bits &= ~property_bitmask; + + if (property_bits == tape->property_bits) + { + Print("Tape already patched for '%s'!\n", mode); + + return FALSE; + } + + tape->property_bits = property_bits; } Print("Patching for '%s' ... ", mode); - tape->property_bits = property_bits; - return TRUE; } @@ -1554,6 +1628,7 @@ PrintLine("=", 79); Print("Supported patch modes:\n"); Print("- \"em_random_bug\" - use 64-bit random value bug for EM engine\n"); + Print("- \"screen_34x34\" - force visible playfield size of 34 x 34\n"); PrintLine("-", 79); Print("Supported modifiers:\n"); Print("- add \":0\", \":off\" or \":clear\" to patch mode to un-patch tape file\n"); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/tape.h new/rocksndiamonds-4.2.2.1/src/tape.h --- old/rocksndiamonds-4.2.2.0/src/tape.h 2020-11-11 21:13:14.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/tape.h 2021-01-15 17:16:52.000000000 +0100 @@ -211,6 +211,10 @@ // bits to indicate which tape properties are stored in this tape byte property_bits; + // visible playfield size when recording this tape (for team mode) + int scr_fieldx; + int scr_fieldy; + struct { byte action[MAX_TAPE_ACTIONS]; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/tools.c new/rocksndiamonds-4.2.2.1/src/tools.c --- old/rocksndiamonds-4.2.2.0/src/tools.c 2020-12-23 13:04:39.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/tools.c 2021-01-15 17:16:52.000000000 +0100 @@ -391,6 +391,16 @@ return getLevelFromScreenY_RND(y); } +int getScreenFieldSizeX(void) +{ + return (tape.playing ? tape.scr_fieldx : SCR_FIELDX); +} + +int getScreenFieldSizeY(void) +{ + return (tape.playing ? tape.scr_fieldy : SCR_FIELDY); +} + void DumpTile(int x, int y) { int sx = SCREENX(x); @@ -4264,7 +4274,7 @@ #define MAX_REQUEST_LINE_FONT1_LEN 7 #define MAX_REQUEST_LINE_FONT2_LEN 10 -static int RequestHandleEvents(unsigned int req_state) +static int RequestHandleEvents(unsigned int req_state, int draw_buffer_game) { boolean game_just_ended = (game_status == GAME_MODE_PLAYING && checkGameEnded()); @@ -4293,7 +4303,7 @@ if (game_just_ended) { - SetDrawtoField(draw_buffer_last); + SetDrawtoField(draw_buffer_game); HandleGameActions(); @@ -4594,6 +4604,7 @@ static boolean RequestDoor(char *text, unsigned int req_state) { + int draw_buffer_last = GetDrawtoField(); unsigned int old_door_state; int max_request_line_len = MAX_REQUEST_LINE_FONT1_LEN; int font_nr = FONT_TEXT_2; @@ -4735,7 +4746,7 @@ SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); // ---------- handle request buttons ---------- - result = RequestHandleEvents(req_state); + result = RequestHandleEvents(req_state, draw_buffer_last); UnmapToolButtons(); @@ -4776,6 +4787,7 @@ static boolean RequestEnvelope(char *text, unsigned int req_state) { + int draw_buffer_last = GetDrawtoField(); int result; if (game_status == GAME_MODE_PLAYING) @@ -4827,7 +4839,7 @@ SetDrawBackgroundMask(REDRAW_FIELD | REDRAW_DOOR_1); // ---------- handle request buttons ---------- - result = RequestHandleEvents(req_state); + result = RequestHandleEvents(req_state, draw_buffer_last); UnmapToolButtons(); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/rocksndiamonds-4.2.2.0/src/tools.h new/rocksndiamonds-4.2.2.1/src/tools.h --- old/rocksndiamonds-4.2.2.0/src/tools.h 2020-12-23 13:04:39.000000000 +0100 +++ new/rocksndiamonds-4.2.2.1/src/tools.h 2021-01-15 17:16:52.000000000 +0100 @@ -72,6 +72,9 @@ int getLevelFromScreenX(int); int getLevelFromScreenY(int); +int getScreenFieldSizeX(void); +int getScreenFieldSizeY(void); + void DumpTile(int, int); void DumpTileFromScreen(int, int);