X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=795aeda2befb595fc04508083404fd91e729275f;hb=fb957ec8be35cfc2fb77827c5ae02a8e952ef82d;hp=1f07c4894bd51a5e387e5aa62eb1042b902d8814;hpb=0ab6e77cdee7930da7fc143d29c5f8658ec046cc;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 1f07c489..795aeda2 100644 --- a/src/files.c +++ b/src/files.c @@ -1319,6 +1319,8 @@ filetype_id_list[] = { LEVEL_FILE_TYPE_DX, "DX" }, { LEVEL_FILE_TYPE_SB, "SB" }, { LEVEL_FILE_TYPE_DC, "DC" }, + { LEVEL_FILE_TYPE_MM, "MM" }, + { LEVEL_FILE_TYPE_MM, "DF" }, { -1, NULL }, }; @@ -1604,6 +1606,7 @@ static void setLevelInfoToDefaults_Level(struct LevelInfo *level) level->native_em_level = &native_em_level; level->native_sp_level = &native_sp_level; + level->native_mm_level = &native_mm_level; level->file_version = FILE_VERSION_ACTUAL; level->game_version = GAME_VERSION_ACTUAL; @@ -2119,6 +2122,16 @@ static void determineLevelFileInfo_Filename(struct LevelFileInfo *lfi) if (fileExists(lfi->filename)) return; } + else if (leveldir_current->level_filetype != NULL) + { + int filetype = getFiletypeFromID(leveldir_current->level_filetype); + + /* check for specified native level file with standard file name */ + setLevelFileInfo_FormatLevelFilename(lfi, filetype, + "%03d.%s", nr, LEVELFILE_EXTENSION); + if (fileExists(lfi->filename)) + return; + } /* check for native Rocks'n'Diamonds level file */ setLevelFileInfo_FormatLevelFilename(lfi, LEVEL_FILE_TYPE_RND, @@ -3664,7 +3677,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 +3691,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; @@ -3820,8 +3853,8 @@ static void CopyNativeTape_SP_to_RND(struct LevelInfo *level) TapeSetDateFromEpochSeconds(getFileTimestampEpochSeconds(filename)); - tape.length = 0; - tape.pos[tape.length].delay = 0; + tape.counter = 0; + tape.pos[tape.counter].delay = 0; for (i = 0; i < demo->length; i++) { @@ -3829,41 +3862,91 @@ static void CopyNativeTape_SP_to_RND(struct LevelInfo *level) int demo_repeat = (demo->data[i] & 0xf0) >> 4; int tape_action = map_key_SP_to_RND(demo_action); int tape_repeat = demo_repeat + 1; - int tape_entries = 1; // one new tape entry may be added + byte action[MAX_PLAYERS] = { tape_action, 0, 0, 0 }; + boolean success = 0; + int j; - if (tape.length + tape_entries >= MAX_TAPE_LEN) + 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); break; } + } - if (tape.pos[tape.length].delay > 0) /* already stored action */ - { - if (tape.pos[tape.length].action[0] != tape_action || - tape.pos[tape.length].delay + tape_repeat >= 256) - { - tape.length++; - tape.pos[tape.length].delay = 0; - } - else - { - tape.pos[tape.length].delay += tape_repeat; - } - } + TapeHaltRecording(); +} - if (tape.pos[tape.length].delay == 0) /* store new action */ - { - tape.pos[tape.length].action[0] = tape_action; - tape.pos[tape.length].delay = tape_repeat; - } - } - tape.length++; +/* ------------------------------------------------------------------------- */ +/* functions for loading MM level */ +/* ------------------------------------------------------------------------- */ - tape.length_frames = GetTapeLengthFrames(); - tape.length_seconds = GetTapeLengthSeconds(); +void CopyNativeLevel_RND_to_MM(struct LevelInfo *level) +{ + struct LevelInfo_MM *level_mm = level->native_mm_level; + int x, y; + + level_mm->file_version = level->file_version; + level_mm->game_version = level->game_version; + level_mm->encoding_16bit_field = level->encoding_16bit_field; + + level_mm->fieldx = MIN(level->fieldx, MM_MAX_PLAYFIELD_WIDTH); + level_mm->fieldy = MIN(level->fieldy, MM_MAX_PLAYFIELD_HEIGHT); + + level_mm->time = level->time; + level_mm->kettles_needed = level->gems_needed; + level_mm->auto_count_kettles = FALSE; + level_mm->laser_red = FALSE; + level_mm->laser_green = FALSE; + level_mm->laser_blue = TRUE; + + strcpy(level_mm->name, level->name); + strcpy(level_mm->author, level->author); + + level_mm->score[SC_PACMAN] = level->score[SC_PACMAN]; + level_mm->score[SC_KEY] = level->score[SC_PACMAN]; + level_mm->score[SC_TIME_BONUS] = level->score[SC_TIME_BONUS]; + + level_mm->amoeba_speed = level->amoeba_speed; + level_mm->time_fuse = 0; + + for (x = 0; x < level->fieldx; x++) + for (y = 0; y < level->fieldy; y++) + level_mm->field[x][y] = map_element_RND_to_MM(level->field[x][y]); +} + +void CopyNativeLevel_MM_to_RND(struct LevelInfo *level) +{ + struct LevelInfo_MM *level_mm = level->native_mm_level; + int x, y; + + level->file_version = level_mm->file_version; + level->game_version = level_mm->game_version; + level->encoding_16bit_field = level_mm->encoding_16bit_field; + + level->fieldx = MIN(level_mm->fieldx, MAX_LEV_FIELDX); + level->fieldy = MIN(level_mm->fieldy, MAX_LEV_FIELDY); + + level->time = level_mm->time; + level->gems_needed = level_mm->kettles_needed; + + strcpy(level->name, level_mm->name); + strcpy(level->author, level_mm->author); + + level->score[SC_PACMAN] = level_mm->score[SC_PACMAN]; + level->score[SC_KEY] = level_mm->score[SC_PACMAN]; + level->score[SC_TIME_BONUS] = level_mm->score[SC_TIME_BONUS]; + + level->amoeba_speed = level_mm->amoeba_speed; + + for (x = 0; x < level->fieldx; x++) + for (y = 0; y < level->fieldy; y++) + level->field[x][y] = map_element_MM_to_RND(level_mm->field[x][y]); } @@ -5896,12 +5979,22 @@ static void LoadLevelFromFileInfo_SP(struct LevelInfo *level, level->no_valid_file = TRUE; } +static void LoadLevelFromFileInfo_MM(struct LevelInfo *level, + struct LevelFileInfo *level_file_info, + boolean level_info_only) +{ + if (!LoadNativeLevel_MM(level_file_info->filename, level_info_only)) + level->no_valid_file = TRUE; +} + void CopyNativeLevel_RND_to_Native(struct LevelInfo *level) { if (level->game_engine_type == GAME_ENGINE_TYPE_EM) CopyNativeLevel_RND_to_EM(level); else if (level->game_engine_type == GAME_ENGINE_TYPE_SP) CopyNativeLevel_RND_to_SP(level); + else if (level->game_engine_type == GAME_ENGINE_TYPE_MM) + CopyNativeLevel_RND_to_MM(level); } void CopyNativeLevel_Native_to_RND(struct LevelInfo *level) @@ -5910,6 +6003,8 @@ void CopyNativeLevel_Native_to_RND(struct LevelInfo *level) CopyNativeLevel_EM_to_RND(level); else if (level->game_engine_type == GAME_ENGINE_TYPE_SP) CopyNativeLevel_SP_to_RND(level); + else if (level->game_engine_type == GAME_ENGINE_TYPE_MM) + CopyNativeLevel_MM_to_RND(level); } void SaveNativeLevel(struct LevelInfo *level) @@ -5954,6 +6049,11 @@ static void LoadLevelFromFileInfo(struct LevelInfo *level, level->game_engine_type = GAME_ENGINE_TYPE_SP; break; + case LEVEL_FILE_TYPE_MM: + LoadLevelFromFileInfo_MM(level, level_file_info, level_info_only); + level->game_engine_type = GAME_ENGINE_TYPE_MM; + break; + case LEVEL_FILE_TYPE_DC: LoadLevelFromFileInfo_DC(level, level_file_info, level_info_only); break; @@ -8243,6 +8343,8 @@ static struct TokenInfo editor_cascade_setup_tokens[] = { TYPE_SWITCH, &seci.el_sp, "editor.cascade.el_sp" }, { TYPE_SWITCH, &seci.el_dc, "editor.cascade.el_dc" }, { TYPE_SWITCH, &seci.el_dx, "editor.cascade.el_dx" }, + { TYPE_SWITCH, &seci.el_mm, "editor.cascade.el_mm" }, + { TYPE_SWITCH, &seci.el_df, "editor.cascade.el_df" }, { TYPE_SWITCH, &seci.el_chars, "editor.cascade.el_chars" }, { TYPE_SWITCH, &seci.el_steel_chars, "editor.cascade.el_steel_chars" }, { TYPE_SWITCH, &seci.el_ce, "editor.cascade.el_ce" }, @@ -8436,6 +8538,10 @@ static void setSetupInfoToDefaults(struct SetupInfo *si) si->editor.el_supaplex = TRUE; si->editor.el_diamond_caves = TRUE; si->editor.el_dx_boulderdash = TRUE; + + si->editor.el_mirror_magic = TRUE; + si->editor.el_deflektor = TRUE; + si->editor.el_chars = TRUE; si->editor.el_steel_chars = TRUE; @@ -8571,6 +8677,9 @@ static void setSetupInfoToDefaults_EditorCascade(struct SetupInfo *si) si->editor_cascade.el_dc = TRUE; si->editor_cascade.el_dx = TRUE; + si->editor_cascade.el_mm = TRUE; + si->editor_cascade.el_df = TRUE; + si->editor_cascade.el_chars = FALSE; si->editor_cascade.el_steel_chars = FALSE; si->editor_cascade.el_ce = FALSE;