From 8e5671db64b55432158b1d43d7fd2e684544ebeb Mon Sep 17 00:00:00 2001 From: Holger Schemel Date: Fri, 5 Sep 2003 19:40:12 +0200 Subject: [PATCH] rnd-20030905-B-src --- src/conf_chr.c | 12 -- src/conf_chr.h | 12 -- src/conf_cus.c | 12 -- src/conf_cus.h | 12 -- src/conf_e2g.c | 12 -- src/conf_e2s.c | 12 -- src/conf_esg.c | 12 -- src/conf_fnt.c | 12 -- src/conf_gfx.c | 8 ++ src/conf_gfx.h | 31 ++--- src/conf_snd.h | 12 -- src/conftime.h | 2 +- src/editor.c | 13 +- src/files.c | 272 ++++++++++++++++++++++++++++++++++++++++-- src/game.c | 114 ++++++++++++++---- src/init.c | 8 ++ src/libgame/gadgets.c | 3 +- src/libgame/text.c | 7 +- src/libgame/text.h | 2 +- src/main.c | 2 +- src/main.h | 32 ++--- src/tools.c | 59 +++++++-- src/tools.h | 2 +- 23 files changed, 461 insertions(+), 202 deletions(-) diff --git a/src/conf_chr.c b/src/conf_chr.c index 506c8b27..00fe6994 100644 --- a/src/conf_chr.c +++ b/src/conf_chr.c @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_chr.c * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conf_chr.h b/src/conf_chr.h index 8cee2724..373ef0de 100644 --- a/src/conf_chr.h +++ b/src/conf_chr.h @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_chr.h * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conf_cus.c b/src/conf_cus.c index dd54ef34..fdf2c343 100644 --- a/src/conf_cus.c +++ b/src/conf_cus.c @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_cus.c * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conf_cus.h b/src/conf_cus.h index 867cd125..9078594e 100644 --- a/src/conf_cus.h +++ b/src/conf_cus.h @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_cus.h * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conf_e2g.c b/src/conf_e2g.c index 8e88f2b0..88c254b6 100644 --- a/src/conf_e2g.c +++ b/src/conf_e2g.c @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_e2g.c * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conf_e2s.c b/src/conf_e2s.c index 6e229df2..f17b1b3e 100644 --- a/src/conf_e2s.c +++ b/src/conf_e2s.c @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_e2s.c * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conf_esg.c b/src/conf_esg.c index 233ea9e9..177d0dc0 100644 --- a/src/conf_esg.c +++ b/src/conf_esg.c @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_esg.c * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conf_fnt.c b/src/conf_fnt.c index ef44d538..3ea90ce9 100644 --- a/src/conf_fnt.c +++ b/src/conf_fnt.c @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_fnt.c * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conf_gfx.c b/src/conf_gfx.c index 3bd3223f..fc55f2d6 100644 --- a/src/conf_gfx.c +++ b/src/conf_gfx.c @@ -39,12 +39,14 @@ struct ConfigInfo image_config_suffix[] = { ".global_sync", "false", TYPE_BOOLEAN }, { ".crumbled_like", ARG_UNDEFINED, TYPE_TOKEN }, { ".diggable_like", ARG_UNDEFINED, TYPE_TOKEN }, + { ".border_size", ARG_UNDEFINED, TYPE_INTEGER }, { ".step_offset", "4", TYPE_INTEGER }, { ".step_delay", "1", TYPE_INTEGER }, { ".direction", ARG_UNDEFINED, TYPE_STRING }, { ".position", ARG_UNDEFINED, TYPE_STRING }, { ".draw_xoffset", "0", TYPE_INTEGER }, { ".draw_yoffset", "0", TYPE_INTEGER }, + { ".draw_masked", "false", TYPE_BOOLEAN }, { ".name", ARG_UNDEFINED, TYPE_STRING }, { NULL, NULL, 0 } @@ -3440,6 +3442,12 @@ struct ConfigInfo image_config[] = { "editor.element_border_input.xpos", "0" }, { "editor.element_border_input.ypos", "0" }, + { "game.envelope_background", "RocksScreen.pcx" }, + { "game.envelope_background.xpos", "0" }, + { "game.envelope_background.ypos", "0" }, + { "game.envelope_background.width", "560" }, + { "game.envelope_background.height", "560" }, + { "background", UNDEFINED_FILENAME }, { "background.MAIN", UNDEFINED_FILENAME }, { "background.LEVELS", UNDEFINED_FILENAME }, diff --git a/src/conf_gfx.h b/src/conf_gfx.h index 71edd97e..59857703 100644 --- a/src/conf_gfx.h +++ b/src/conf_gfx.h @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_gfx.h * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ @@ -1284,15 +1272,16 @@ #define IMG_GLOBAL_DOOR 1263 #define IMG_EDITOR_ELEMENT_BORDER 1264 #define IMG_EDITOR_ELEMENT_BORDER_INPUT 1265 -#define IMG_BACKGROUND 1266 -#define IMG_BACKGROUND_MAIN 1267 -#define IMG_BACKGROUND_LEVELS 1268 -#define IMG_BACKGROUND_SCORES 1269 -#define IMG_BACKGROUND_EDITOR 1270 -#define IMG_BACKGROUND_INFO 1271 -#define IMG_BACKGROUND_SETUP 1272 -#define IMG_BACKGROUND_DOOR 1273 +#define IMG_GAME_ENVELOPE_BACKGROUND 1266 +#define IMG_BACKGROUND 1267 +#define IMG_BACKGROUND_MAIN 1268 +#define IMG_BACKGROUND_LEVELS 1269 +#define IMG_BACKGROUND_SCORES 1270 +#define IMG_BACKGROUND_EDITOR 1271 +#define IMG_BACKGROUND_INFO 1272 +#define IMG_BACKGROUND_SETUP 1273 +#define IMG_BACKGROUND_DOOR 1274 -#define NUM_IMAGE_FILES 1274 +#define NUM_IMAGE_FILES 1275 #endif /* CONF_GFX_H */ diff --git a/src/conf_snd.h b/src/conf_snd.h index 94366024..bfb6db88 100644 --- a/src/conf_snd.h +++ b/src/conf_snd.h @@ -1,15 +1,3 @@ -/*********************************************************** -* Rocks'n'Diamonds -- McDuffin Strikes Back! * -*----------------------------------------------------------* -* (c) 1995-2002 Artsoft Entertainment * -* Holger Schemel * -* Detmolder Strasse 189 * -* 33604 Bielefeld * -* Germany * -* e-mail: info@artsoft.org * -*----------------------------------------------------------* -* conf_snd.h * -***********************************************************/ /* ----- this file was automatically generated -- do not edit by hand ----- */ diff --git a/src/conftime.h b/src/conftime.h index 6a4286e3..b425e6a4 100644 --- a/src/conftime.h +++ b/src/conftime.h @@ -1 +1 @@ -#define COMPILE_DATE_STRING "[2003-09-04 00:41]" +#define COMPILE_DATE_STRING "[2003-09-05 19:38]" diff --git a/src/editor.c b/src/editor.c index 5e657368..bc79a606 100644 --- a/src/editor.c +++ b/src/editor.c @@ -1106,10 +1106,10 @@ static struct ValueTextInfo options_time_units[] = static struct ValueTextInfo options_change_direct_action[] = { - { CE_TOUCHED_BY_PLAYER, "player touches it" }, - { CE_PRESSED_BY_PLAYER, "player presses it" }, - { CE_PUSHED_BY_PLAYER, "player pushes it" }, - { CE_DROPPED_BY_PLAYER, "player drops it" }, + { CE_TOUCHED_BY_PLAYER, "touched by player" }, + { CE_PRESSED_BY_PLAYER, "pressed by player" }, + { CE_PUSHED_BY_PLAYER, "pushed by player" }, + { CE_DROPPED_BY_PLAYER, "dropped by player" }, { CE_COLLISION, "collision" }, { CE_IMPACT, "impact" }, { CE_SMASHED, "smashed" }, @@ -1121,9 +1121,10 @@ static struct ValueTextInfo options_change_other_action[] = { CE_OTHER_GETS_TOUCHED, "player touches" }, { CE_OTHER_GETS_PRESSED, "player presses" }, { CE_OTHER_GETS_PUSHED, "player pushes" }, + { CE_OTHER_GETS_DIGGED, "player digs" }, { CE_OTHER_GETS_COLLECTED, "player collects" }, { CE_OTHER_GETS_DROPPED, "player drops" }, - { CE_OTHER_IS_TOUCHING, "it touches" }, + { CE_OTHER_IS_TOUCHING, "touching" }, { CE_OTHER_IS_CHANGING, "change of" }, { CE_OTHER_IS_EXPLODING, "explosion of" }, { -1, NULL } @@ -4538,6 +4539,7 @@ static void CopyCustomElementPropertiesToEditor(int element) HAS_CHANGE_EVENT(element, CE_OTHER_GETS_TOUCHED) ? CE_OTHER_GETS_TOUCHED : HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PRESSED) ? CE_OTHER_GETS_PRESSED : HAS_CHANGE_EVENT(element, CE_OTHER_GETS_PUSHED) ? CE_OTHER_GETS_PUSHED : + HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DIGGED) ? CE_OTHER_GETS_DIGGED : HAS_CHANGE_EVENT(element, CE_OTHER_GETS_COLLECTED) ? CE_OTHER_GETS_COLLECTED : HAS_CHANGE_EVENT(element, CE_OTHER_GETS_DROPPED) ? CE_OTHER_GETS_DROPPED : HAS_CHANGE_EVENT(element, CE_OTHER_IS_TOUCHING) ? CE_OTHER_IS_TOUCHING : @@ -4652,6 +4654,7 @@ static void CopyCustomElementPropertiesToGame(int element) custom_element_change_events[CE_OTHER_GETS_TOUCHED] = FALSE; custom_element_change_events[CE_OTHER_GETS_PRESSED] = FALSE; custom_element_change_events[CE_OTHER_GETS_PUSHED] = FALSE; + custom_element_change_events[CE_OTHER_GETS_DIGGED] = FALSE; custom_element_change_events[CE_OTHER_GETS_COLLECTED] = FALSE; custom_element_change_events[CE_OTHER_GETS_DROPPED] = FALSE; custom_element_change_events[custom_element_change.other_action] = diff --git a/src/files.c b/src/files.c index 60d37ef2..efbe71aa 100644 --- a/src/files.c +++ b/src/files.c @@ -30,12 +30,17 @@ #define LEVEL_HEADER_UNUSED 13 /* unused level header bytes */ #define LEVEL_CHUNK_CNT2_SIZE 160 /* size of level CNT2 chunk */ #define LEVEL_CHUNK_CNT2_UNUSED 11 /* unused CNT2 chunk bytes */ +#define LEVEL_CHUNK_CNT3_HEADER 16 /* size of level CNT3 header */ +#define LEVEL_CHUNK_CNT3_UNUSED 10 /* unused CNT3 chunk bytes */ #define LEVEL_CPART_CUS3_SIZE 134 /* size of CUS3 chunk part */ #define LEVEL_CPART_CUS3_UNUSED 15 /* unused CUS3 bytes / part */ +#define LEVEL_CPART_CUS4_SIZE ??? /* size of CUS4 chunk part */ +#define LEVEL_CPART_CUS4_UNUSED ??? /* unused CUS4 bytes / part */ #define TAPE_HEADER_SIZE 20 /* size of tape file header */ #define TAPE_HEADER_UNUSED 3 /* unused tape header bytes */ -#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + x * LEVEL_CPART_CUS3_SIZE) +#define LEVEL_CHUNK_CUS3_SIZE(x) (2 + (x) * LEVEL_CPART_CUS3_SIZE) +#define LEVEL_CHUNK_CUS4_SIZE(x) (48 + 48 + (x) * 48) /* file identifier strings */ #define LEVEL_COOKIE_TMPL "ROCKSNDIAMONDS_LEVEL_FILE_VERSION_x.x" @@ -416,6 +421,7 @@ static int LoadLevel_CNT2(FILE *file, int chunk_size, struct LevelInfo *level) num_contents = getFile8Bit(file); content_xsize = getFile8Bit(file); content_ysize = getFile8Bit(file); + ReadUnusedBytesFromFile(file, LEVEL_CHUNK_CNT2_UNUSED); for(i=0; ienvelope_xsize = getFile8Bit(file); + level->envelope_ysize = getFile8Bit(file); + + ReadUnusedBytesFromFile(file, LEVEL_CHUNK_CNT3_UNUSED); + + chunk_size_expected = LEVEL_CHUNK_CNT3_HEADER + envelope_len; + + if (chunk_size_expected != chunk_size) + { + ReadUnusedBytesFromFile(file, chunk_size - LEVEL_CHUNK_CNT3_HEADER); + return chunk_size_expected; + } + + for(i=0; i < envelope_len; i++) + level->envelope[i] = getFile8Bit(file); + + return chunk_size; +} + static int LoadLevel_CUS1(FILE *file, int chunk_size, struct LevelInfo *level) { int num_changed_custom_elements = getFile16BitBE(file); @@ -590,6 +624,109 @@ static int LoadLevel_CUS3(FILE *file, int chunk_size, struct LevelInfo *level) return chunk_size; } +static int LoadLevel_CUS4(FILE *file, int chunk_size, struct LevelInfo *level) +{ + struct ElementInfo *ei; + int chunk_size_expected; + int element; + int i, x, y; + + element = getFile16BitBE(file); + + if (!IS_CUSTOM_ELEMENT(element)) + { + Error(ERR_WARN, "invalid custom element number %d", element); + + element = EL_DEFAULT; /* dummy element used for artwork config */ + } + + ei = &element_info[element]; + + for(i=0; i < MAX_ELEMENT_NAME_LEN; i++) + ei->description[i] = getFile8Bit(file); + ei->description[MAX_ELEMENT_NAME_LEN] = 0; + + Properties[element][EP_BITFIELD_BASE] = getFile32BitBE(file); + ReadUnusedBytesFromFile(file, 4); /* reserved for more base properties */ + + ei->num_change_pages = getFile8Bit(file); + + /* some free bytes for future base property values and padding */ + ReadUnusedBytesFromFile(file, 5); + + chunk_size_expected = LEVEL_CHUNK_CUS4_SIZE(ei->num_change_pages); + if (chunk_size_expected != chunk_size) + { + ReadUnusedBytesFromFile(file, chunk_size - 48); + return chunk_size_expected; + } + + /* read custom property values */ + + ei->use_gfx_element = getFile8Bit(file); + ei->gfx_element = checkLevelElement(getFile16BitBE(file)); + + ei->collect_score = getFile8Bit(file); + ei->collect_count = getFile8Bit(file); + + ei->push_delay_fixed = getFile16BitBE(file); + ei->push_delay_random = getFile16BitBE(file); + ei->move_delay_fixed = getFile16BitBE(file); + ei->move_delay_random = getFile16BitBE(file); + + ei->move_pattern = getFile16BitBE(file); + ei->move_direction_initial = getFile8Bit(file); + ei->move_stepsize = getFile8Bit(file); + + ei->slippery_type = getFile8Bit(file); + + for(y=0; y<3; y++) + for(x=0; x<3; x++) + ei->content[x][y] = checkLevelElement(getFile16BitBE(file)); + + /* some free bytes for future custom property values and padding */ + ReadUnusedBytesFromFile(file, 12); + + /* read change property values */ + + for (i=0; i < ei->num_change_pages; i++) + { + struct ElementChangeInfo *change = &ei->change_page[i]; + + change->events = getFile32BitBE(file); + + change->target_element = checkLevelElement(getFile16BitBE(file)); + + change->delay_fixed = getFile16BitBE(file); + change->delay_random = getFile16BitBE(file); + change->delay_frames = getFile16BitBE(file); + + change->trigger_element = checkLevelElement(getFile16BitBE(file)); + + change->explode = getFile8Bit(file); + change->use_content = getFile8Bit(file); + change->only_complete = getFile8Bit(file); + change->use_random_change = getFile8Bit(file); + + change->random = getFile8Bit(file); + change->power = getFile8Bit(file); + + for(y=0; y<3; y++) + for(x=0; x<3; x++) + change->content[x][y] = checkLevelElement(getFile16BitBE(file)); + + change->can_change = getFile8Bit(file); + + /* some free bytes for future change property values and padding */ + ReadUnusedBytesFromFile(file, 9); + } + + /* mark this custom element as modified */ + ei->modified_settings = TRUE; + + return chunk_size; +} + void LoadLevelFromFilename(struct LevelInfo *level, char *filename) { char cookie[MAX_LINE_LEN]; @@ -670,9 +807,11 @@ void LoadLevelFromFilename(struct LevelInfo *level, char *filename) { "BODY", -1, LoadLevel_BODY }, { "CONT", -1, LoadLevel_CONT }, { "CNT2", LEVEL_CHUNK_CNT2_SIZE, LoadLevel_CNT2 }, + { "CNT3", -1, LoadLevel_CNT3 }, { "CUS1", -1, LoadLevel_CUS1 }, { "CUS2", -1, LoadLevel_CUS2 }, { "CUS3", -1, LoadLevel_CUS3 }, + { "CUS4", -1, LoadLevel_CUS4 }, { NULL, 0, NULL } }; @@ -1214,6 +1353,22 @@ static void SaveLevel_CNT2(FILE *file, struct LevelInfo *level, int element) putFile16BitBE(file, content_array[i][x][y]); } +static void SaveLevel_CNT3(FILE *file, struct LevelInfo *level, int element) +{ + int i; + int envelope_len = strlen(level->envelope) + 1; + + putFile16BitBE(file, element); + putFile16BitBE(file, envelope_len); + putFile8Bit(file, level->envelope_xsize); + putFile8Bit(file, level->envelope_ysize); + + WriteUnusedBytesToFile(file, LEVEL_CHUNK_CNT3_UNUSED); + + for(i=0; i < envelope_len; i++) + putFile8Bit(file, level->envelope[i]); +} + #if 0 static void SaveLevel_CUS1(FILE *file, struct LevelInfo *level, int num_changed_custom_elements) @@ -1272,6 +1427,7 @@ static void SaveLevel_CUS2(FILE *file, struct LevelInfo *level, } #endif +#if 0 static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level, int num_changed_custom_elements) { @@ -1351,12 +1507,90 @@ static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level, if (check != num_changed_custom_elements) /* should not happen */ Error(ERR_WARN, "inconsistent number of custom element properties"); } +#endif + +static void SaveLevel_CUS4(FILE *file, struct LevelInfo *level, int element) +{ + struct ElementInfo *ei = &element_info[element]; + int i, x, y; + + putFile16BitBE(file, element); + + for(i=0; i < MAX_ELEMENT_NAME_LEN; i++) + putFile8Bit(file, ei->description[i]); + + putFile32BitBE(file, Properties[element][EP_BITFIELD_BASE]); + WriteUnusedBytesToFile(file, 4); /* reserved for more base properties */ + + putFile8Bit(file, ei->num_change_pages); + + /* some free bytes for future base property values and padding */ + WriteUnusedBytesToFile(file, 5); + + /* write custom property values */ + + putFile8Bit(file, ei->use_gfx_element); + putFile16BitBE(file, ei->gfx_element); + + putFile8Bit(file, ei->collect_score); + putFile8Bit(file, ei->collect_count); + + putFile16BitBE(file, ei->push_delay_fixed); + putFile16BitBE(file, ei->push_delay_random); + putFile16BitBE(file, ei->move_delay_fixed); + putFile16BitBE(file, ei->move_delay_random); + + putFile16BitBE(file, ei->move_pattern); + putFile8Bit(file, ei->move_direction_initial); + putFile8Bit(file, ei->move_stepsize); + + putFile8Bit(file, ei->slippery_type); + + for(y=0; y<3; y++) + for(x=0; x<3; x++) + putFile16BitBE(file, ei->content[x][y]); + + /* some free bytes for future custom property values and padding */ + WriteUnusedBytesToFile(file, 12); + + /* write change property values */ + + for (i=0; i < ei->num_change_pages; i++) + { + struct ElementChangeInfo *change = &ei->change_page[i]; + + putFile32BitBE(file, change->events); + + putFile16BitBE(file, change->target_element); + + putFile16BitBE(file, change->delay_fixed); + putFile16BitBE(file, change->delay_random); + putFile16BitBE(file, change->delay_frames); + + putFile16BitBE(file, change->trigger_element); + + putFile8Bit(file, change->explode); + putFile8Bit(file, change->use_content); + putFile8Bit(file, change->only_complete); + putFile8Bit(file, change->use_random_change); + + putFile8Bit(file, change->random); + putFile8Bit(file, change->power); + + for(y=0; y<3; y++) + for(x=0; x<3; x++) + putFile16BitBE(file, change->content[x][y]); + + putFile8Bit(file, change->can_change); + + /* some free bytes for future change property values and padding */ + WriteUnusedBytesToFile(file, 9); + } +} static void SaveLevelFromFilename(struct LevelInfo *level, char *filename) { int body_chunk_size; - int num_changed_custom_elements = 0; - int level_chunk_CUS3_size; int i, x, y; FILE *file; @@ -1393,12 +1627,6 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename) body_chunk_size = level->fieldx * level->fieldy * (level->encoding_16bit_field ? 2 : 1); - /* check for non-standard custom elements and calculate "CUS3" chunk size */ - for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) - if (element_info[EL_CUSTOM_START + i].modified_settings) - num_changed_custom_elements++; - level_chunk_CUS3_size = LEVEL_CHUNK_CUS3_SIZE(num_changed_custom_elements); - putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED); putFileChunkBE(file, "CAVE", CHUNK_SIZE_NONE); @@ -1427,10 +1655,30 @@ static void SaveLevelFromFilename(struct LevelInfo *level, char *filename) SaveLevel_CNT2(file, level, EL_BD_AMOEBA); } - if (num_changed_custom_elements > 0 && !level->use_custom_template) + /* check for envelope content */ + if (strlen(level->envelope) > 0) + { + int envelope_len = strlen(level->envelope) + 1; + + putFileChunkBE(file, "CNT3", LEVEL_CHUNK_CNT3_HEADER + envelope_len); + SaveLevel_CNT3(file, level, EL_ENVELOPE); + } + + /* check for non-default custom elements (unless using template level) */ + if (!level->use_custom_template) { - putFileChunkBE(file, "CUS3", level_chunk_CUS3_size); - SaveLevel_CUS3(file, level, num_changed_custom_elements); + for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + + if (element_info[element].modified_settings) + { + int num_change_pages = element_info[element].num_change_pages; + + putFileChunkBE(file, "CUS4", LEVEL_CHUNK_CUS4_SIZE(num_change_pages)); + SaveLevel_CUS4(file, level, element); + } + } } fclose(file); diff --git a/src/game.c b/src/game.c index 3e768d93..ff6d5568 100644 --- a/src/game.c +++ b/src/game.c @@ -1090,7 +1090,7 @@ void InitGame() JustStopped[x][y] = 0; Stop[x][y] = FALSE; Pushed[x][y] = FALSE; - Changing[x][y] = FALSE; + Changed[x][y] = FALSE; ExplodePhase[x][y] = 0; ExplodeField[x][y] = EX_NO_EXPLOSION; @@ -1991,13 +1991,19 @@ void CheckDynamite(int x, int y) void ShowEnvelope() { + int graphic = IMG_GAME_ENVELOPE_BACKGROUND; + boolean draw_masked = graphic_info[graphic].draw_masked; + int mask_mode = (draw_masked ? BLIT_MASKED : BLIT_ON_BACKGROUND); + int font_nr = FONT_TEXT_1; + int font_width = getFontWidth(font_nr); + int font_height = getFontHeight(font_nr); int i, x, y; /* open envelope window horizontally */ for (i = 2; i <= level.envelope_xsize + 2; i += 2) { - int startx = (SXSIZE / MINI_TILEX - i) / 2; - int starty = (SYSIZE / MINI_TILEY) / 2 - 1; + int startx = (SXSIZE / font_width - i) / 2; + int starty = (SYSIZE / font_height) / 2 - 1; SetDrawtoField(DRAW_BUFFERED); @@ -2007,24 +2013,30 @@ void ShowEnvelope() for (y=0; y < 2; y++) for (x=0; x < i; x++) { + int sx = SX + (startx + x) * font_width; + int sy = SY + (starty + y) * font_height; int ex = (x == 0 ? -1 : x == i - 1 ? +1 : 0); int ey = (y == 0 ? -1 : y == 1 ? +1 : 0); - DrawEnvelopeBorder(startx + x, starty + y, ex, ey); + DrawEnvelopeBackground(sx, sy, ex, ey, font_nr); } redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; BackToFront(); Delay(GAME_FRAME_DELAY); + + /* special case: envelope has odd width */ + if (level.envelope_xsize % 2 && i == 2) + i--; } /* open envelope window vertically */ for (i = 2; i <= level.envelope_ysize + 2; i += 2) { int xsize = level.envelope_xsize + 2; - int startx = (SXSIZE / MINI_TILEX - (xsize - 1)) / 2; - int starty = (SYSIZE / MINI_TILEY - i) / 2; + int startx = (SXSIZE / font_width - (xsize - 1)) / 2; + int starty = (SYSIZE / font_height - i) / 2; SetDrawtoField(DRAW_BUFFERED); @@ -2034,20 +2046,26 @@ void ShowEnvelope() for (y=0; y < i; y++) for (x=0; x < xsize; x++) { + int sx = SX + (startx + x) * font_width; + int sy = SY + (starty + y) * font_height; int ex = (x == 0 ? -1 : x == xsize - 1 ? +1 : 0); int ey = (y == 0 ? -1 : y == i - 1 ? +1 : 0); - DrawEnvelopeBorder(startx + x, starty + y, ex, ey); + DrawEnvelopeBackground(sx, sy, ex, ey, font_nr); } - DrawTextToTextArea(SX + (startx + 1) * MINI_TILEX, - SY + (starty + 1) * MINI_TILEY, level.envelope, - FONT_TEXT_1, level.envelope_xsize, i - 2); + DrawTextToTextArea(SX + (startx + 1) * font_width, + SY + (starty + 1) * font_height, level.envelope, + FONT_TEXT_1, level.envelope_xsize, i - 2, mask_mode); redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; BackToFront(); Delay(GAME_FRAME_DELAY); + + /* special case: envelope has odd height */ + if (level.envelope_ysize % 2 && i == 2) + i--; } if (tape.playing) @@ -2059,8 +2077,8 @@ void ShowEnvelope() for (i = level.envelope_ysize + 2; i >= 2; i -= 2) { int xsize = level.envelope_xsize + 2; - int startx = (SXSIZE / MINI_TILEX - (xsize - 1)) / 2; - int starty = (SYSIZE / MINI_TILEY - i) / 2; + int startx = (SXSIZE / font_width - (xsize - 1)) / 2; + int starty = (SYSIZE / font_height - i) / 2; SetDrawtoField(DRAW_BUFFERED); @@ -2070,27 +2088,33 @@ void ShowEnvelope() for (y=0; y < i; y++) for (x=0; x < xsize; x++) { + int sx = SX + (startx + x) * font_width; + int sy = SY + (starty + y) * font_height; int ex = (x == 0 ? -1 : x == xsize - 1 ? +1 : 0); int ey = (y == 0 ? -1 : y == i - 1 ? +1 : 0); - DrawEnvelopeBorder(startx + x, starty + y, ex, ey); + DrawEnvelopeBackground(sx, sy, ex, ey, font_nr); } - DrawTextToTextArea(SX + (startx + 1) * MINI_TILEX, - SY + (starty + 1) * MINI_TILEY, level.envelope, - FONT_TEXT_1, level.envelope_xsize, i - 2); + DrawTextToTextArea(SX + (startx + 1) * font_width, + SY + (starty + 1) * font_height, level.envelope, + FONT_TEXT_1, level.envelope_xsize, i - 2, mask_mode); redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; BackToFront(); Delay(GAME_FRAME_DELAY); + + /* special case: envelope has odd height */ + if (level.envelope_ysize % 2 && i == level.envelope_ysize + 2) + i++; } /* close envelope window horizontally */ for (i = level.envelope_xsize + 2; i >= 2; i -= 2) { - int startx = (SXSIZE / MINI_TILEX - i) / 2; - int starty = (SYSIZE / MINI_TILEY) / 2 - 1; + int startx = (SXSIZE / font_width - i) / 2; + int starty = (SYSIZE / font_height) / 2 - 1; SetDrawtoField(DRAW_BUFFERED); @@ -2100,16 +2124,22 @@ void ShowEnvelope() for (y=0; y < 2; y++) for (x=0; x < i; x++) { + int sx = SX + (startx + x) * font_width; + int sy = SY + (starty + y) * font_height; int ex = (x == 0 ? -1 : x == i - 1 ? +1 : 0); int ey = (y == 0 ? -1 : y == 1 ? +1 : 0); - DrawEnvelopeBorder(startx + x, starty + y, ex, ey); + DrawEnvelopeBackground(sx, sy, ex, ey, font_nr); } redraw_mask |= REDRAW_FIELD | REDRAW_FROM_BACKBUFFER; BackToFront(); Delay(GAME_FRAME_DELAY); + + /* special case: envelope has odd width */ + if (level.envelope_xsize % 2 && i == level.envelope_xsize + 2) + i++; } SetDrawtoField(DRAW_BUFFERED); @@ -5466,6 +5496,8 @@ static void ChangeElementNowExt(int x, int y, int target_element) RemoveField(x, y); Feld[x][y] = target_element; + Changed[x][y] = TRUE; /* no more changes in this frame */ + ResetGfxAnimation(x, y); ResetRandomAnimationValue(x, y); @@ -5490,6 +5522,8 @@ static void ChangeElementNow(int x, int y, int element, int page) { struct ElementChangeInfo *change = &element_info[element].change_page[page]; + Changed[x][y] = TRUE; /* no more changes in this frame */ + CheckTriggeredElementChange(x, y, Feld[x][y], CE_OTHER_IS_CHANGING); if (change->explode) @@ -5570,9 +5604,9 @@ static void ChangeElementNow(int x, int y, int element, int page) something_has_changed = TRUE; - /* for symmetry reasons, stop newly created border elements */ + /* for symmetry reasons, freeze newly created border elements */ if (ex != x || ey != y) - Stop[ex][ey] = TRUE; + Stop[ex][ey] = TRUE; /* no more moving in this frame */ } } @@ -5641,9 +5675,11 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, if (!(trigger_events[trigger_element] & CH_EVENT_BIT(trigger_event))) return FALSE; +#if 0 /* prevent this function from running into a loop */ if (trigger_event == CE_OTHER_IS_CHANGING) - Changing[lx][ly] = TRUE; + Changed[lx][ly] = TRUE; +#endif for (i=0; i < NUM_CUSTOM_ELEMENTS; i++) { @@ -5684,7 +5720,7 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, if (x == lx && y == ly) /* do not change trigger element itself */ continue; - if (Changing[x][y]) /* do not change just changing elements */ + if (Changed[x][y]) /* do not change already changed elements */ continue; if (Feld[x][y] == element) @@ -5692,14 +5728,18 @@ static boolean CheckTriggeredElementChange(int lx, int ly, int trigger_element, ChangeDelay[x][y] = 1; ChangeElement(x, y, page); - Changing[x][y] = TRUE; /* do not change just changed elements */ +#if 0 + Changed[x][y] = TRUE; /* prevent element from being changed again */ +#endif } } } +#if 0 /* reset change prevention array */ for (y=0; y 0) JustStopped[x][y]--; @@ -5921,7 +5963,7 @@ void GameActions() #if 1 /* reset finished pushing action (not done in ContinueMoving() to allow - continous pushing animation for elements without push delay) */ + continous pushing animation for elements with zero push delay) */ if (GfxAction[x][y] == ACTION_PUSHING && !IS_MOVING(x, y)) { ResetGfxAnimation(x, y); @@ -6777,7 +6819,9 @@ void ScrollScreen(struct PlayerInfo *player, int mode) void TestIfPlayerTouchesCustomElement(int x, int y) { +#if 0 static boolean check_changing = FALSE; +#endif static int xy[4][2] = { { 0, -1 }, @@ -6787,10 +6831,12 @@ void TestIfPlayerTouchesCustomElement(int x, int y) }; int i; +#if 0 if (check_changing) /* prevent this function from running into a loop */ return; check_changing = TRUE; +#endif for (i=0; i<4; i++) { @@ -6814,12 +6860,16 @@ void TestIfPlayerTouchesCustomElement(int x, int y) } } +#if 0 check_changing = FALSE; +#endif } void TestIfElementTouchesCustomElement(int x, int y) { +#if 0 static boolean check_changing = FALSE; +#endif static int xy[4][2] = { { 0, -1 }, @@ -6832,10 +6882,12 @@ void TestIfElementTouchesCustomElement(int x, int y) int center_element = Feld[x][y]; int i, j; +#if 0 if (check_changing) /* prevent this function from running into a loop */ return; check_changing = TRUE; +#endif for (i=0; i<4; i++) { @@ -6892,7 +6944,9 @@ void TestIfElementTouchesCustomElement(int x, int y) CheckElementChangeExt(x, y, center_element, CE_OTHER_IS_TOUCHING, center_element_change_page); +#if 0 check_changing = FALSE; +#endif } void TestIfGoodThingHitsBadThing(int good_x, int good_y, int good_move_dir) @@ -7580,6 +7634,10 @@ int DigField(struct PlayerInfo *player, PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING); + CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_DIGGED); + + TestIfElementTouchesCustomElement(x, y); + break; } else if (IS_COLLECTIBLE(element)) @@ -7671,6 +7729,8 @@ int DigField(struct PlayerInfo *player, CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_COLLECTED); + TestIfElementTouchesCustomElement(x, y); + break; } else if (IS_PUSHABLE(element)) @@ -7909,6 +7969,8 @@ boolean DropElement(struct PlayerInfo *player) CheckTriggeredElementChange(jx, jy, new_element, CE_OTHER_GETS_DROPPED); CheckElementChange(jx, jy, new_element, CE_DROPPED_BY_PLAYER); + + TestIfElementTouchesCustomElement(jx, jy); } else /* player is dropping a dyna bomb */ { diff --git a/src/init.c b/src/init.c index 05619cc4..93aceacd 100644 --- a/src/init.c +++ b/src/init.c @@ -775,6 +775,7 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) graphic_info[graphic].offset_y = 0; /* ... will be corrected later */ graphic_info[graphic].crumbled_like = -1; /* do not use clone element */ graphic_info[graphic].diggable_like = -1; /* do not use clone element */ + graphic_info[graphic].border_size = TILEX / 8; /* "CRUMBLED" border size */ /* optional x and y tile position of animation frame sequence */ if (parameter[GFX_ARG_XPOS] != ARG_UNDEFINED_VALUE) @@ -864,6 +865,10 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) if (parameter[GFX_ARG_DIGGABLE_LIKE] != ARG_UNDEFINED_VALUE) graphic_info[graphic].diggable_like = parameter[GFX_ARG_DIGGABLE_LIKE]; + /* optional border size for "crumbling" diggable graphics */ + if (parameter[GFX_ARG_BORDER_SIZE] != ARG_UNDEFINED_VALUE) + graphic_info[graphic].border_size = parameter[GFX_ARG_BORDER_SIZE]; + /* this is only used for toon animations */ graphic_info[graphic].step_offset = parameter[GFX_ARG_STEP_OFFSET]; graphic_info[graphic].step_delay = parameter[GFX_ARG_STEP_DELAY]; @@ -871,6 +876,9 @@ static void set_graphic_parameters(int graphic, char **parameter_raw) /* this is only used for drawing font characters */ graphic_info[graphic].draw_x = parameter[GFX_ARG_DRAW_XOFFSET]; graphic_info[graphic].draw_y = parameter[GFX_ARG_DRAW_YOFFSET]; + + /* this is only used for drawing envelope graphics */ + graphic_info[graphic].draw_masked = parameter[GFX_ARG_DRAW_MASKED]; } static void InitGraphicInfo() diff --git a/src/libgame/gadgets.c b/src/libgame/gadgets.c index aacadafa..dd9d2883 100644 --- a/src/libgame/gadgets.c +++ b/src/libgame/gadgets.c @@ -359,7 +359,8 @@ static void DrawGadget(struct GadgetInfo *gi, boolean pressed, boolean direct) /* gadget text value */ DrawTextToTextArea(gi->x + border_x, gi->y + border_y, gi->textarea.value, font_nr, - gi->textarea.xsize, gi->textarea.ysize); + gi->textarea.xsize, gi->textarea.ysize, + BLIT_ON_BACKGROUND); cursor_letter = gi->textarea.value[gi->textarea.cursor_position]; cursor_string[0] = (cursor_letter != '\0' ? cursor_letter : ' '); diff --git a/src/libgame/text.c b/src/libgame/text.c index 6b5f03e0..c5406657 100644 --- a/src/libgame/text.c +++ b/src/libgame/text.c @@ -327,7 +327,7 @@ void DrawTextExt(DrawBuffer *dst_bitmap, int dst_x, int dst_y, char *text, } void DrawTextToTextArea(int x, int y, char *text, int font_nr, - int area_xsize, int area_ysize) + int area_xsize, int area_ysize, int mask_mode) { int area_line = 0; int font_height = getFontHeight(font_nr); @@ -345,8 +345,11 @@ void DrawTextToTextArea(int x, int y, char *text, int font_nr, break; buffer[i] = '\0'; - DrawText(x, y + area_line * font_height, buffer, font_nr); + DrawTextExt(drawto, x, y + area_line * font_height, buffer, font_nr, + mask_mode); area_line++; } + + redraw_mask |= REDRAW_FIELD; } diff --git a/src/libgame/text.h b/src/libgame/text.h index c9c48943..bde8ba9d 100644 --- a/src/libgame/text.h +++ b/src/libgame/text.h @@ -66,6 +66,6 @@ void DrawTextF(int, int, int, char *, ...); void DrawTextFCentered(int, int, char *, ...); void DrawText(int, int, char *, int); void DrawTextExt(DrawBuffer *, int, int, char *, int, int); -void DrawTextToTextArea(int, int, char *, int, int, int); +void DrawTextToTextArea(int, int, char *, int, int, int, int); #endif /* TEXT_H */ diff --git a/src/main.c b/src/main.c index 380af747..1d85ad18 100644 --- a/src/main.c +++ b/src/main.c @@ -50,7 +50,7 @@ short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; boolean Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; -boolean Changing[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +boolean Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; short AmoebaCnt[MAX_NUM_AMOEBA]; diff --git a/src/main.h b/src/main.h index 3b109635..76be4a45 100644 --- a/src/main.h +++ b/src/main.h @@ -173,14 +173,13 @@ #define CE_OTHER_GETS_PUSHED 13 #define CE_OTHER_GETS_COLLECTED 14 #define CE_OTHER_GETS_DROPPED 15 - -/* values for activating change events (also stored in level file!) */ #define CE_BY_PLAYER 16 /* obsolete; map'd to CE_BY_DIRECT_ACTION */ #define CE_BY_COLLISION 17 /* obsolete; map'd to CE_BY_DIRECT_ACTION */ -#define CE_BY_OTHER_ACTION 18 -#define CE_BY_DIRECT_ACTION 19 +#define CE_BY_OTHER_ACTION 18 /* activates other element events */ +#define CE_BY_DIRECT_ACTION 19 /* activates direct element events */ +#define CE_OTHER_GETS_DIGGED 20 -#define NUM_CHANGE_EVENTS 20 +#define NUM_CHANGE_EVENTS 21 #define CE_BITMASK_DEFAULT 0 @@ -923,15 +922,17 @@ #define GFX_ARG_GLOBAL_SYNC 15 #define GFX_ARG_CRUMBLED_LIKE 16 #define GFX_ARG_DIGGABLE_LIKE 17 -#define GFX_ARG_STEP_OFFSET 18 -#define GFX_ARG_STEP_DELAY 19 -#define GFX_ARG_DIRECTION 20 -#define GFX_ARG_POSITION 21 -#define GFX_ARG_DRAW_XOFFSET 22 -#define GFX_ARG_DRAW_YOFFSET 23 -#define GFX_ARG_NAME 24 +#define GFX_ARG_BORDER_SIZE 18 +#define GFX_ARG_STEP_OFFSET 19 +#define GFX_ARG_STEP_DELAY 20 +#define GFX_ARG_DIRECTION 21 +#define GFX_ARG_POSITION 22 +#define GFX_ARG_DRAW_XOFFSET 23 +#define GFX_ARG_DRAW_YOFFSET 24 +#define GFX_ARG_DRAW_MASKED 25 +#define GFX_ARG_NAME 26 -#define NUM_GFX_ARGS 25 +#define NUM_GFX_ARGS 27 /* values for sound configuration suffixes */ @@ -1371,12 +1372,15 @@ struct GraphicInfo boolean anim_global_sync; int crumbled_like; /* element for cloning crumble graphics */ int diggable_like; /* element for cloning digging graphics */ + int border_size; /* border size for "crumbled" graphics */ int step_offset; /* optional step offset of toon animations */ int step_delay; /* optional step delay of toon animations */ int draw_x, draw_y; /* optional offset for drawing fonts chars */ + int draw_masked; /* optional setting for drawing envelope gfx */ + #if defined(TARGET_X11_NATIVE_PERFORMANCE_WORKAROUND) Pixmap clip_mask; /* single-graphic-only clip mask for X11 */ GC clip_gc; /* single-graphic-only clip gc for X11 */ @@ -1437,7 +1441,7 @@ extern short StorePlayer[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short Back[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern boolean Stop[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern boolean Pushed[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; -extern boolean Changing[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; +extern boolean Changed[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short JustStopped[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short AmoebaNr[MAX_LEV_FIELDX][MAX_LEV_FIELDY]; extern short AmoebaCnt[MAX_NUM_AMOEBA]; diff --git a/src/tools.c b/src/tools.c index e104066c..3da2b060 100644 --- a/src/tools.c +++ b/src/tools.c @@ -1204,7 +1204,11 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) int sx = SCREENX(x), sy = SCREENY(y); int element; int width, height, cx, cy, i; +#if 1 + int crumbled_border_size = graphic_info[graphic].border_size; +#else int snip = TILEX / 8; /* number of border pixels from "crumbled graphic" */ +#endif static int xy[4][2] = { { 0, -1 }, @@ -1247,17 +1251,17 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) if (i == 1 || i == 2) { - width = snip; + width = crumbled_border_size; height = TILEY; - cx = (i == 2 ? TILEX - snip : 0); + cx = (i == 2 ? TILEX - crumbled_border_size : 0); cy = 0; } else { width = TILEX; - height = snip; + height = crumbled_border_size; cx = 0; - cy = (i == 3 ? TILEY - snip : 0); + cy = (i == 3 ? TILEY - crumbled_border_size : 0); } BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy, @@ -1285,17 +1289,17 @@ static void DrawLevelFieldCrumbledSandExt(int x, int y, int graphic, int frame) if (i == 1 || i == 2) { - width = snip; + width = crumbled_border_size; height = TILEY; - cx = (i == 1 ? TILEX - snip : 0); + cx = (i == 1 ? TILEX - crumbled_border_size : 0); cy = 0; } else { width = TILEX; - height = snip; + height = crumbled_border_size; cx = 0; - cy = (i==0 ? TILEY-snip : 0); + cy = (i == 0 ? TILEY - crumbled_border_size : 0); } BlitBitmap(src_bitmap, drawto_field, src_x + cx, src_y + cy, @@ -1525,8 +1529,44 @@ void DrawMiniElementOrWall(int sx, int sy, int scroll_x, int scroll_y) DrawMiniGraphic(sx, sy, el2edimg(getBorderElement(x, y))); } -void DrawEnvelopeBorder(int sx, int sy, int ex, int ey) +void DrawEnvelopeBackground(int dst_x, int dst_y, int ex, int ey, int font_nr) { +#if 1 + int font_width = getFontWidth(font_nr); + int font_height = getFontHeight(font_nr); + int graphic = IMG_GAME_ENVELOPE_BACKGROUND; + Bitmap *src_bitmap; + int src_x, src_y; +#if 0 + int dst_x = SX + sx * font_width; + int dst_y = SY + sy * font_height; +#endif + int width = graphic_info[graphic].width; + int height = graphic_info[graphic].height; + boolean draw_masked = graphic_info[graphic].draw_masked; + + getGraphicSource(graphic, 0, &src_bitmap, &src_x, &src_y); + + if (src_bitmap == NULL) + { + ClearRectangle(drawto, dst_x, dst_y, font_width, font_height); + return; + } + + src_x += (ex == -1 ? 0 : ex == +1 ? width - font_width : font_width); + src_y += (ey == -1 ? 0 : ey == +1 ? height - font_height : font_height); + + if (draw_masked) + { + SetClipOrigin(src_bitmap, src_bitmap->stored_clip_gc, + dst_x - src_x, dst_y - src_y); + BlitBitmapMasked(src_bitmap, drawto, src_x, src_y, font_width, font_height, + dst_x, dst_y); + } + else + BlitBitmap(src_bitmap, drawto, src_x, src_y, font_width, font_height, + dst_x, dst_y); +#else int border[8][2] = { { EL_STEELWALL_TOPLEFT, EL_INVISIBLE_STEELWALL_TOPLEFT }, @@ -1548,6 +1588,7 @@ void DrawEnvelopeBorder(int sx, int sy, int ex, int ey) int element = border[steel_position][steel_type]; DrawMiniGraphic(sx, sy, el2edimg(element)); +#endif } void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y) diff --git a/src/tools.h b/src/tools.h index f046184a..0a5cb84b 100644 --- a/src/tools.h +++ b/src/tools.h @@ -112,7 +112,7 @@ void DrawLevelField(int, int); void DrawMiniElement(int, int, int); void DrawMiniElementOrWall(int, int, int, int); -void DrawEnvelopeBorder(int, int, int, int); +void DrawEnvelopeBackground(int, int, int, int, int); void getMicroGraphicSource(int, Bitmap **, int *, int *); void DrawMicroElement(int, int, int); -- 2.34.1