X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Ffiles.c;h=85d171287bebb4703b146aa53aa283d27ad2ae37;hp=8b69451a5f747767416c85b8bf249008a1f2e107;hb=676fda0c5ba97e2c8b16dffddd590d5ec355c009;hpb=c3387d3deda2aeece28600228e47d67dfbc52bcb diff --git a/src/files.c b/src/files.c index 8b69451a..85d17128 100644 --- a/src/files.c +++ b/src/files.c @@ -3664,7 +3664,8 @@ void CopyNativeLevel_SP_to_RND(struct LevelInfo *level) { struct LevelInfo_SP *level_sp = level->native_sp_level; LevelInfoType *header = &level_sp->header; - int i, x, y; + boolean num_invalid_elements = 0; + int i, j, x, y; level->fieldx = level_sp->width; level->fieldy = level_sp->height; @@ -3677,20 +3678,39 @@ void CopyNativeLevel_SP_to_RND(struct LevelInfo *level) int element_new = getMappedElement(map_element_SP_to_RND(element_old)); if (element_new == EL_UNKNOWN) - Error(ERR_WARN, "invalid element %d at position %d, %d", + { + num_invalid_elements++; + + Error(ERR_DEBUG, "invalid element %d at position %d, %d", element_old, x, y); + } level->field[x][y] = element_new; } } + if (num_invalid_elements > 0) + Error(ERR_WARN, "found %d invalid elements%s", num_invalid_elements, + (!options.debug ? " (use '--debug' for more details)" : "")); + for (i = 0; i < MAX_PLAYERS; i++) level->initial_player_gravity[i] = (header->InitialGravity == 1 ? TRUE : FALSE); + /* skip leading spaces */ for (i = 0; i < SP_LEVEL_NAME_LEN; i++) - level->name[i] = header->LevelTitle[i]; - level->name[SP_LEVEL_NAME_LEN] = '\0'; + if (header->LevelTitle[i] != ' ') + break; + + /* copy level title */ + for (j = 0; i < SP_LEVEL_NAME_LEN; i++, j++) + level->name[j] = header->LevelTitle[i]; + level->name[j] = '\0'; + + /* cut trailing spaces */ + for (; j > 0; j--) + if (level->name[j - 1] == ' ' && level->name[j] == '\0') + level->name[j - 1] = '\0'; level->gems_needed = header->InfotronsNeeded; @@ -3775,6 +3795,7 @@ static void CopyNativeTape_RND_to_SP(struct LevelInfo *level) level_sp->header.DemoRandomSeed = tape.random_seed; demo->length = 0; + for (i = 0; i < tape.length; i++) { int demo_action = map_key_RND_to_SP(tape.pos[i].action[0]); @@ -3815,26 +3836,36 @@ static void CopyNativeTape_SP_to_RND(struct LevelInfo *level) return; tape.level_nr = demo->level_nr; /* (currently not used) */ - tape.length = MIN(demo->length, MAX_TAPE_LEN); tape.random_seed = level_sp->header.DemoRandomSeed; TapeSetDateFromEpochSeconds(getFileTimestampEpochSeconds(filename)); - if (tape.length < demo->length) - Error(ERR_WARN, "SP demo truncated: size %d exceeds maximum tape size %d", - demo->length, MAX_TAPE_LEN); + tape.counter = 0; + tape.pos[tape.counter].delay = 0; - for (i = 0; i < tape.length; i++) + for (i = 0; i < demo->length; i++) { int demo_action = demo->data[i] & 0x0f; int demo_repeat = (demo->data[i] & 0xf0) >> 4; + int tape_action = map_key_SP_to_RND(demo_action); + int tape_repeat = demo_repeat + 1; + byte action[MAX_PLAYERS] = { tape_action, 0, 0, 0 }; + boolean success = 0; + int j; + + for (j = 0; j < tape_repeat; j++) + success = TapeAddAction(action); + + if (!success) + { + Error(ERR_WARN, "SP demo truncated: size exceeds maximum tape size %d", + MAX_TAPE_LEN); - tape.pos[i].action[0] = map_key_SP_to_RND(demo_action); - tape.pos[i].delay = demo_repeat + 1; + break; + } } - tape.length_frames = GetTapeLengthFrames(); - tape.length_seconds = GetTapeLengthSeconds(); + TapeHaltRecording(); } @@ -7359,7 +7390,16 @@ static int LoadTape_BODY(File *file, int chunk_size, struct TapeInfo *tape) for (i = 0; i < tape->length; i++) { if (i >= MAX_TAPE_LEN) + { + Error(ERR_WARN, "tape truncated -- size exceeds maximum tape size %d", + MAX_TAPE_LEN); + + // tape too large; read and ignore remaining tape data from this chunk + for (;i < tape->length; i++) + ReadUnusedBytesFromFile(file, tape->num_participating_players + 1); + break; + } for (j = 0; j < MAX_PLAYERS; j++) {