X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=5a5bf6405538feceb3115a6dd39a4d9deecc1d5d;hb=7d171d862abdecced79f60535b49a686386cefe1;hp=0fd7a18ade6db1691778942d270aee3e8f15ecb7;hpb=cee436b68cda95e13abc810235a11ce94bc79c95;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 0fd7a18a..5a5bf640 100644 --- a/src/files.c +++ b/src/files.c @@ -29,7 +29,7 @@ #define CHUNK_SIZE_NONE -1 /* do not write chunk size */ #define FILE_VERS_CHUNK_SIZE 8 /* size of file version chunk */ #define LEVEL_HEADER_SIZE 80 /* size of level file header */ -#define LEVEL_HEADER_UNUSED 1 /* unused level header bytes */ +#define LEVEL_HEADER_UNUSED 0 /* 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 */ @@ -114,6 +114,10 @@ static void setLevelInfoToDefaults(struct LevelInfo *level) int i, j, x, y; + level->native_em_level = &native_em_level; + + level->game_engine_type = GAME_ENGINE_TYPE_RND; + level->file_version = FILE_VERSION_ACTUAL; level->game_version = GAME_VERSION_ACTUAL; @@ -712,6 +716,8 @@ static int LoadLevel_HEAD(FILE *file, int chunk_size, struct LevelInfo *level) level->can_pass_to_walkable = (getFile8Bit(file) == 1 ? TRUE : FALSE); level->grow_into_diggable = (getFile8Bit(file) == 1 ? TRUE : FALSE); + level->game_engine_type = getFile8Bit(file); + ReadUnusedBytesFromFile(file, LEVEL_HEADER_UNUSED); return chunk_size; @@ -1339,6 +1345,8 @@ static void LoadLevelFromFileInfo_RND(struct LevelInfo *level, /* functions for loading EM level */ /* ------------------------------------------------------------------------- */ +#if 0 + static int map_em_element_yam(int element) { switch (element) @@ -1651,16 +1659,13 @@ static int map_em_element_field(int element) #define EM_LEVEL_XSIZE 64 #define EM_LEVEL_YSIZE 32 -static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, - struct LevelFileInfo *level_file_info) +static void OLD_LoadLevelFromFileInfo_EM(struct LevelInfo *level, + struct LevelFileInfo *level_file_info) { char *filename = level_file_info->filename; FILE *file; unsigned char leveldata[EM_LEVEL_SIZE]; unsigned char *header = &leveldata[EM_LEVEL_XSIZE * EM_LEVEL_YSIZE]; - unsigned char code0 = 0x65; - unsigned char code1 = 0x11; - boolean level_is_crypted = FALSE; int nr = level_file_info->nr; int i, x, y; @@ -1673,7 +1678,7 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, return; } - for(i = 0; i < EM_LEVEL_SIZE; i++) + for (i = 0; i < EM_LEVEL_SIZE; i++) leveldata[i] = fgetc(file); fclose(file); @@ -1684,20 +1689,20 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, if ((leveldata[0] == 0xf1 || leveldata[0] == 0xf5) && leveldata[2] == 0xe7 && leveldata[3] == 0xee) { - level_is_crypted = TRUE; + unsigned char code0 = 0x65; + unsigned char code1 = 0x11; if (leveldata[0] == 0xf5) /* error in crypted Emerald Mine 2 levels */ leveldata[0] = 0xf1; - } - if (level_is_crypted) /* decode crypted level data */ - { - for(i = 0; i < EM_LEVEL_SIZE; i++) + /* decode crypted level data */ + + for (i = 0; i < EM_LEVEL_SIZE; i++) { leveldata[i] ^= code0; leveldata[i] -= code1; - code0 = (code0 + 7) & 0xff; + code0 = (code0 + 7) & 0xff; } } @@ -1730,9 +1735,9 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, level->num_yamyam_contents = 4; - for(i = 0; i < level->num_yamyam_contents; i++) - for(y = 0; y < 3; y++) - for(x = 0; x < 3; x++) + for (i = 0; i < level->num_yamyam_contents; i++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) level->yamyam_content[i][x][y] = map_em_element_yam(header[i * 9 + y * 3 + x]); @@ -1760,6 +1765,151 @@ static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, level->field[x][y] = EL_PLAYER_2; } +#else + +void CopyNativeLevel_RND_to_EM(struct LevelInfo *level) +{ + struct LevelInfo_EM *level_em = level->native_em_level; + struct LEVEL *lev = level_em->lev; + struct PLAYER *ply1 = level_em->ply1; + struct PLAYER *ply2 = level_em->ply2; + int i, x, y; + + lev->width = MIN(level->fieldx, EM_MAX_CAVE_WIDTH); + lev->height = MIN(level->fieldy, EM_MAX_CAVE_HEIGHT); + + lev->time_initial = level->time; + lev->required_initial = level->gems_needed; + + lev->emerald_score = level->score[SC_EMERALD]; + lev->diamond_score = level->score[SC_DIAMOND]; + lev->alien_score = level->score[SC_ROBOT]; + lev->tank_score = level->score[SC_SPACESHIP]; + lev->bug_score = level->score[SC_BUG]; + lev->eater_score = level->score[SC_YAMYAM]; + lev->nut_score = level->score[SC_NUT]; + lev->dynamite_score = level->score[SC_DYNAMITE]; + lev->key_score = level->score[SC_TIME_BONUS]; /* ??? CHECK THIS */ + + for (i = 0; i < MAX_ELEMENT_CONTENTS; i++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) + lev->eater_array[i][y * 3 + x] = + map_element_RND_to_EM(level->yamyam_content[i][x][y]); + + lev->ameuba_time = level->amoeba_speed; + lev->wonderwall_time_initial = level->time_magic_wall; + lev->wheel_time = level->time_wheel; + + /* first fill the complete playfield with the default border element */ + for (y = 0; y < EM_MAX_CAVE_HEIGHT; y++) + for (x = 0; x < EM_MAX_CAVE_WIDTH; x++) + level_em->cave[x][y] = ZBORDER; + + /* then copy the real level contents from level file into the playfield */ + for (y = 0; y < lev->height; y++) for (x = 0; x < lev->width; x++) + { + int new_element = map_element_RND_to_EM(level->field[x][y]); + + level_em->cave[x + 1][y + 1] = new_element; + } + + ply1->x_initial = 0; + ply1->y_initial = 0; + + ply2->x_initial = 0; + ply2->y_initial = 0; + + /* at last, set the two players at their positions in the playfield */ + for (y = 0; y < lev->height; y++) for (x = 0; x < lev->width; x++) + { + if (level->field[x][y] == EL_PLAYER_1) + { + ply1->x_initial = x + 1; + ply1->y_initial = y + 1; + } + else if (level->field[x][y] == EL_PLAYER_2) + { + ply2->x_initial = x + 1; + ply2->y_initial = y + 1; + } + } +} + +void CopyNativeLevel_EM_to_RND(struct LevelInfo *level) +{ + struct LevelInfo_EM *level_em = level->native_em_level; + struct LEVEL *lev = level_em->lev; + struct PLAYER *ply1 = level_em->ply1; + struct PLAYER *ply2 = level_em->ply2; + int i, x, y; + + level->fieldx = MIN(lev->width, MAX_LEV_FIELDX); + level->fieldy = MIN(lev->height, MAX_LEV_FIELDY); + + level->time = lev->time_initial; + level->gems_needed = lev->required_initial; + + sprintf(level->name, "Level %d", level->file_info.nr); + + level->score[SC_EMERALD] = lev->emerald_score; + level->score[SC_DIAMOND] = lev->diamond_score; + level->score[SC_ROBOT] = lev->alien_score; + level->score[SC_SPACESHIP] = lev->tank_score; + level->score[SC_BUG] = lev->bug_score; + level->score[SC_YAMYAM] = lev->eater_score; + level->score[SC_NUT] = lev->nut_score; + level->score[SC_DYNAMITE] = lev->dynamite_score; + level->score[SC_TIME_BONUS] = lev->key_score; /* ??? CHECK THIS */ + + level->num_yamyam_contents = MAX_ELEMENT_CONTENTS; + + for (i = 0; i < level->num_yamyam_contents; i++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) + level->yamyam_content[i][x][y] = + map_element_EM_to_RND(lev->eater_array[i][y * 3 + x]); + + level->amoeba_speed = lev->ameuba_time; + level->time_magic_wall = lev->wonderwall_time_initial; + level->time_wheel = lev->wheel_time; + + for (y = 0; y < level->fieldy; y++) for (x = 0; x < level->fieldx; x++) + { + int new_element = map_element_EM_to_RND(level_em->cave[x + 1][y + 1]); + + if (new_element == EL_AMOEBA_WET && level->amoeba_speed == 0) + new_element = EL_AMOEBA_DEAD; + + level->field[x][y] = new_element; + } + + level->field[ply1->x_initial - 1][ply1->y_initial - 1] = EL_PLAYER_1; + level->field[ply2->x_initial - 1][ply2->y_initial - 1] = EL_PLAYER_2; +} + +static void LoadLevelFromFileInfo_EM(struct LevelInfo *level, + struct LevelFileInfo *level_file_info) +{ + if (!LoadNativeLevel_EM(level_file_info->filename)) + level->no_valid_file = TRUE; +} + +#endif + +void CopyNativeLevel_RND_to_Native(struct LevelInfo *level) +{ + if (level->game_engine_type == GAME_ENGINE_TYPE_EM) + CopyNativeLevel_RND_to_EM(level); +} + +void CopyNativeLevel_Native_to_RND(struct LevelInfo *level) +{ + if (level->game_engine_type == GAME_ENGINE_TYPE_EM) + CopyNativeLevel_EM_to_RND(level); +} + + /* ------------------------------------------------------------------------- */ /* functions for loading SP level */ /* ------------------------------------------------------------------------- */ @@ -1911,13 +2061,13 @@ static void LoadLevelFromFileStream_SP(FILE *file, struct LevelInfo *level, level->time_wheel = 0; level->amoeba_content = EL_EMPTY; - for(i = 0; i < LEVEL_SCORE_ELEMENTS; i++) + for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++) level->score[i] = 0; /* !!! CORRECT THIS !!! */ /* there are no yamyams in supaplex levels */ - for(i = 0; i < level->num_yamyam_contents; i++) - for(y = 0; y < 3; y++) - for(x = 0; x < 3; x++) + for (i = 0; i < level->num_yamyam_contents; i++) + for (y = 0; y < 3; y++) + for (x = 0; x < 3; x++) level->yamyam_content[i][x][y] = EL_EMPTY; } @@ -2118,6 +2268,7 @@ void LoadLevelFromFileInfo(struct LevelInfo *level, case LEVEL_FILE_TYPE_EM: LoadLevelFromFileInfo_EM(level, level_file_info); + level->game_engine_type = GAME_ENGINE_TYPE_EM; break; case LEVEL_FILE_TYPE_SP: @@ -2128,6 +2279,11 @@ void LoadLevelFromFileInfo(struct LevelInfo *level, LoadLevelFromFileInfo_RND(level, level_file_info); break; } + + if (level->game_engine_type == GAME_ENGINE_TYPE_UNKNOWN) + level->game_engine_type = GAME_ENGINE_TYPE_RND; + + CopyNativeLevel_Native_to_RND(level); } void LoadLevelFromFilename(struct LevelInfo *level, char *filename) @@ -2618,6 +2774,8 @@ static void SaveLevel_HEAD(FILE *file, struct LevelInfo *level) putFile8Bit(file, (level->can_pass_to_walkable ? 1 : 0)); putFile8Bit(file, (level->grow_into_diggable ? 1 : 0)); + putFile8Bit(file, level->game_engine_type); + WriteUnusedBytesToFile(file, LEVEL_HEADER_UNUSED); }