-/***********************************************************
-* 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 ----- */
-/***********************************************************
-* 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 ----- */
-/***********************************************************
-* 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 ----- */
-/***********************************************************
-* 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 ----- */
-/***********************************************************
-* 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 ----- */
-/***********************************************************
-* 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 ----- */
-/***********************************************************
-* 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 ----- */
-/***********************************************************
-* 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 ----- */
{ ".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 }
{ "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 },
-/***********************************************************
-* 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 ----- */
#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 */
-/***********************************************************
-* 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 ----- */
-#define COMPILE_DATE_STRING "[2003-09-04 00:41]"
+#define COMPILE_DATE_STRING "[2003-09-05 19:38]"
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" },
{ 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 }
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 :
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] =
#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"
num_contents = getFile8Bit(file);
content_xsize = getFile8Bit(file);
content_ysize = getFile8Bit(file);
+
ReadUnusedBytesFromFile(file, LEVEL_CHUNK_CNT2_UNUSED);
for(i=0; i<MAX_ELEMENT_CONTENTS; i++)
return chunk_size;
}
+static int LoadLevel_CNT3(FILE *file, int chunk_size, struct LevelInfo *level)
+{
+ int i;
+ int element;
+ int envelope_len;
+ int chunk_size_expected;
+
+ element = checkLevelElement(getFile16BitBE(file));
+ envelope_len = getFile16BitBE(file);
+ level->envelope_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);
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];
{ "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 }
};
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)
}
#endif
+#if 0
static void SaveLevel_CUS3(FILE *file, struct LevelInfo *level,
int num_changed_custom_elements)
{
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;
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);
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);
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;
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);
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);
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)
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);
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);
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);
RemoveField(x, y);
Feld[x][y] = target_element;
+ Changed[x][y] = TRUE; /* no more changes in this frame */
+
ResetGfxAnimation(x, y);
ResetRandomAnimationValue(x, y);
{
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)
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 */
}
}
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++)
{
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)
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<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
- Changing[x][y] = FALSE;
+ Changed[x][y] = FALSE;
+#endif
return TRUE;
}
for (y=0; y<lev_fieldy; y++) for (x=0; x<lev_fieldx; x++)
{
+ Changed[x][y] = FALSE;
+
Stop[x][y] = FALSE;
if (JustStopped[x][y] > 0)
JustStopped[x][y]--;
#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);
void TestIfPlayerTouchesCustomElement(int x, int y)
{
+#if 0
static boolean check_changing = FALSE;
+#endif
static int xy[4][2] =
{
{ 0, -1 },
};
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++)
{
}
}
+#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 },
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++)
{
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)
PlaySoundLevelElementAction(x, y, element, ACTION_DIGGING);
+ CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_DIGGED);
+
+ TestIfElementTouchesCustomElement(x, y);
+
break;
}
else if (IS_COLLECTIBLE(element))
CheckTriggeredElementChange(x, y, element, CE_OTHER_GETS_COLLECTED);
+ TestIfElementTouchesCustomElement(x, y);
+
break;
}
else if (IS_PUSHABLE(element))
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 */
{
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)
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];
/* 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()
/* 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 : ' ');
}
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);
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;
}
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 */
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];
#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
#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 */
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 */
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];
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 },
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,
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,
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 },
int element = border[steel_position][steel_type];
DrawMiniGraphic(sx, sy, el2edimg(element));
+#endif
}
void getMicroGraphicSource(int graphic, Bitmap **bitmap, int *x, int *y)
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);