X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Ffiles.c;h=ab6a595876440efa5e72d350130cf8ced12b4b30;hb=2eb60cf4c36db6802cb11c8eadd9b2c5a0e5fd1c;hp=9bbe3bc678e19974767ddb80555dbe5e9c50217c;hpb=a4bd8800b4463c082ef66db961a81ddd75d7dbf0;p=rocksndiamonds.git diff --git a/src/files.c b/src/files.c index 9bbe3bc6..ab6a5958 100644 --- a/src/files.c +++ b/src/files.c @@ -266,6 +266,12 @@ static struct LevelFileConfigInfo chunk_config_INFO[] = &li.time_score_base, 1 }, + { + -1, -1, + TYPE_BOOLEAN, CONF_VALUE_8_BIT(13), + &li.rate_time_over_score, FALSE + }, + { -1, -1, -1, -1, @@ -3932,12 +3938,11 @@ static void CopyNativeLevel_SP_to_RND(struct LevelInfo *level) level->time_wheel = 0; level->amoeba_content = EL_EMPTY; -#if 1 - // original Supaplex does not use score values -- use default values -#else + // original Supaplex does not use score values -- rate by playing time for (i = 0; i < LEVEL_SCORE_ELEMENTS; i++) level->score[i] = 0; -#endif + + level->rate_time_over_score = TRUE; // there are no yamyams in supaplex levels for (i = 0; i < level->num_yamyam_contents; i++) @@ -6605,6 +6610,27 @@ static void LoadLevel_InitCustomElements(struct LevelInfo *level) element_info[element].ignition_delay = 8; } } + + // set mouse click change events to work for left/middle/right mouse button + if (level->game_version < VERSION_IDENT(4,2,3,0)) + { + for (i = 0; i < NUM_CUSTOM_ELEMENTS; i++) + { + int element = EL_CUSTOM_START + i; + struct ElementInfo *ei = &element_info[element]; + + for (j = 0; j < ei->num_change_pages; j++) + { + struct ElementChangeInfo *change = &ei->change_page[j]; + + if (change->has_event[CE_CLICKED_BY_MOUSE] || + change->has_event[CE_PRESSED_BY_MOUSE] || + change->has_event[CE_MOUSE_CLICKED_ON_X] || + change->has_event[CE_MOUSE_PRESSED_ON_X]) + change->trigger_side = CH_SIDE_ANY; + } + } + } } static void LoadLevel_InitElements(struct LevelInfo *level) @@ -8269,13 +8295,10 @@ void SaveTapeToFilename(char *filename) SetFilePermissions(filename, PERMS_PRIVATE); } -void SaveTape(int nr) +static void SaveTapeExt(char *filename) { - char *filename = getTapeFilename(nr); int i; - InitTapeDirectory(leveldir_current->subdir); - tape.file_version = FILE_VERSION_ACTUAL; tape.game_version = GAME_VERSION_ACTUAL; @@ -8291,6 +8314,25 @@ void SaveTape(int nr) tape.changed = FALSE; } +void SaveTape(int nr) +{ + char *filename = getTapeFilename(nr); + + InitTapeDirectory(leveldir_current->subdir); + + SaveTapeExt(filename); +} + +void SaveScoreTape(int nr) +{ + char *filename = getScoreTapeFilename(tape.score_tape_basename, nr); + + // used instead of "leveldir_current->subdir" (for network games) + InitScoreTapeDirectory(levelset.identifier, nr); + + SaveTapeExt(filename); +} + static boolean SaveTapeCheckedExt(int nr, char *msg_replace, char *msg_saved, unsigned int req_state_added) { @@ -8382,15 +8424,25 @@ void DumpTape(struct TapeInfo *tape) // score file functions // ============================================================================ -static void setScoreInfoToDefaults(void) +static void setScoreInfoToDefaultsExt(struct ScoreInfo *scores) { int i; for (i = 0; i < MAX_SCORE_ENTRIES; i++) { - strcpy(highscore[i].Name, EMPTY_PLAYER_NAME); - highscore[i].Score = 0; + strcpy(scores->entry[i].tape_basename, UNDEFINED_FILENAME); + strcpy(scores->entry[i].name, EMPTY_PLAYER_NAME); + scores->entry[i].score = 0; + scores->entry[i].time = 0; } + + scores->num_entries = 0; + scores->last_added = -1; +} + +static void setScoreInfoToDefaults(void) +{ + setScoreInfoToDefaultsExt(&scores); } static void LoadScore_OLD(int nr) @@ -8422,7 +8474,7 @@ static void LoadScore_OLD(int nr) for (i = 0; i < MAX_SCORE_ENTRIES; i++) { - if (fscanf(file, "%d", &highscore[i].Score) == EOF) + if (fscanf(file, "%d", &scores.entry[i].score) == EOF) Warn("fscanf() failed; %s", strerror(errno)); if (fgets(line, MAX_LINE_LEN, file) == NULL) @@ -8435,8 +8487,8 @@ static void LoadScore_OLD(int nr) { if (*line_ptr != ' ' && *line_ptr != '\t' && *line_ptr != '\0') { - strncpy(highscore[i].Name, line_ptr, MAX_PLAYER_NAME_LEN); - highscore[i].Name[MAX_PLAYER_NAME_LEN] = '\0'; + strncpy(scores.entry[i].name, line_ptr, MAX_PLAYER_NAME_LEN); + scores.entry[i].name[MAX_PLAYER_NAME_LEN] = '\0'; break; } } @@ -8445,6 +8497,25 @@ static void LoadScore_OLD(int nr) fclose(file); } +static void ConvertScore_OLD(void) +{ + // only convert score to time for levels that rate playing time over score + if (!level.rate_time_over_score) + return; + + // convert old score to playing time for score-less levels (like Supaplex) + int time_final_max = 999; + int i; + + for (i = 0; i < MAX_SCORE_ENTRIES; i++) + { + int score = scores.entry[i].score; + + if (score > 0 && score < time_final_max) + scores.entry[i].time = (time_final_max - score - 1) * FRAMES_PER_SECOND; + } +} + static int LoadScore_VERS(File *file, int chunk_size, struct ScoreInfo *scores) { scores->file_version = getFileVersion(file); @@ -8486,9 +8557,9 @@ static int LoadScore_NAME(File *file, int chunk_size, struct ScoreInfo *scores) for (i = 0; i < scores->num_entries; i++) { for (j = 0; j < MAX_PLAYER_NAME_LEN; j++) - highscore[i].Name[j] = getFile8Bit(file); + scores->entry[i].name[j] = getFile8Bit(file); - highscore[i].Name[MAX_PLAYER_NAME_LEN] = '\0'; + scores->entry[i].name[MAX_PLAYER_NAME_LEN] = '\0'; } chunk_size = scores->num_entries * MAX_PLAYER_NAME_LEN; @@ -8501,13 +8572,42 @@ static int LoadScore_SCOR(File *file, int chunk_size, struct ScoreInfo *scores) int i; for (i = 0; i < scores->num_entries; i++) - highscore[i].Score = getFile16BitBE(file); + scores->entry[i].score = getFile16BitBE(file); chunk_size = scores->num_entries * 2; return chunk_size; } +static int LoadScore_TIME(File *file, int chunk_size, struct ScoreInfo *scores) +{ + int i; + + for (i = 0; i < scores->num_entries; i++) + scores->entry[i].time = getFile32BitBE(file); + + chunk_size = scores->num_entries * 4; + + return chunk_size; +} + +static int LoadScore_TAPE(File *file, int chunk_size, struct ScoreInfo *scores) +{ + int i, j; + + for (i = 0; i < scores->num_entries; i++) + { + for (j = 0; j < MAX_SCORE_TAPE_BASENAME_LEN; j++) + scores->entry[i].tape_basename[j] = getFile8Bit(file); + + scores->entry[i].tape_basename[MAX_SCORE_TAPE_BASENAME_LEN] = '\0'; + } + + chunk_size = scores->num_entries * MAX_SCORE_TAPE_BASENAME_LEN; + + return chunk_size; +} + void LoadScore(int nr) { char *filename = getScoreFilename(nr); @@ -8562,6 +8662,9 @@ void LoadScore(int nr) { // score files from versions before 4.2.4.0 without chunk structure LoadScore_OLD(nr); + + // convert score to time, if possible (mainly for Supaplex levels) + ConvertScore_OLD(); } else { @@ -8577,6 +8680,8 @@ void LoadScore(int nr) { "INFO", -1, LoadScore_INFO }, { "NAME", -1, LoadScore_NAME }, { "SCOR", -1, LoadScore_SCOR }, + { "TIME", -1, LoadScore_TIME }, + { "TAPE", -1, LoadScore_TAPE }, { NULL, 0, NULL } }; @@ -8646,7 +8751,7 @@ void SaveScore_OLD(int nr) fprintf(file, "%s\n\n", SCORE_COOKIE); for (i = 0; i < MAX_SCORE_ENTRIES; i++) - fprintf(file, "%d %s\n", highscore[i].Score, highscore[i].Name); + fprintf(file, "%d %s\n", scores.entry[i].score, scores.entry[i].name); fclose(file); @@ -8680,10 +8785,10 @@ static void SaveScore_NAME(FILE *file, struct ScoreInfo *scores) for (i = 0; i < scores->num_entries; i++) { - int name_size = strlen(highscore[i].Name); + int name_size = strlen(scores->entry[i].name); for (j = 0; j < MAX_PLAYER_NAME_LEN; j++) - putFile8Bit(file, (j < name_size ? highscore[i].Name[j] : 0)); + putFile8Bit(file, (j < name_size ? scores->entry[i].name[j] : 0)); } } @@ -8692,7 +8797,28 @@ static void SaveScore_SCOR(FILE *file, struct ScoreInfo *scores) int i; for (i = 0; i < scores->num_entries; i++) - putFile16BitBE(file, highscore[i].Score); + putFile16BitBE(file, scores->entry[i].score); +} + +static void SaveScore_TIME(FILE *file, struct ScoreInfo *scores) +{ + int i; + + for (i = 0; i < scores->num_entries; i++) + putFile32BitBE(file, scores->entry[i].time); +} + +static void SaveScore_TAPE(FILE *file, struct ScoreInfo *scores) +{ + int i, j; + + for (i = 0; i < scores->num_entries; i++) + { + int size = strlen(scores->entry[i].tape_basename); + + for (j = 0; j < MAX_SCORE_TAPE_BASENAME_LEN; j++) + putFile8Bit(file, (j < size ? scores->entry[i].tape_basename[j] : 0)); + } } static void SaveScoreToFilename(char *filename) @@ -8702,6 +8828,8 @@ static void SaveScoreToFilename(char *filename) int info_chunk_size; int name_chunk_size; int scor_chunk_size; + int time_chunk_size; + int tape_chunk_size; if (!(file = fopen(filename, MODE_WRITE))) { @@ -8713,6 +8841,8 @@ static void SaveScoreToFilename(char *filename) info_chunk_size = 2 + (strlen(scores.level_identifier) + 1) + 2 + 2; name_chunk_size = scores.num_entries * MAX_PLAYER_NAME_LEN; scor_chunk_size = scores.num_entries * 2; + time_chunk_size = scores.num_entries * 4; + tape_chunk_size = scores.num_entries * MAX_SCORE_TAPE_BASENAME_LEN; putFileChunkBE(file, "RND1", CHUNK_SIZE_UNDEFINED); putFileChunkBE(file, "SCOR", CHUNK_SIZE_NONE); @@ -8729,6 +8859,12 @@ static void SaveScoreToFilename(char *filename) putFileChunkBE(file, "SCOR", scor_chunk_size); SaveScore_SCOR(file, &scores); + putFileChunkBE(file, "TIME", time_chunk_size); + SaveScore_TIME(file, &scores); + + putFileChunkBE(file, "TAPE", tape_chunk_size); + SaveScore_TAPE(file, &scores); + fclose(file); SetFilePermissions(filename, permissions); @@ -8750,8 +8886,9 @@ void SaveScore(int nr) scores.level_nr = level_nr; for (i = 0; i < MAX_SCORE_ENTRIES; i++) - if (highscore[i].Score == 0 && - strEqual(highscore[i].Name, EMPTY_PLAYER_NAME)) + if (scores.entry[i].score == 0 && + scores.entry[i].time == 0 && + strEqual(scores.entry[i].name, EMPTY_PLAYER_NAME)) break; scores.num_entries = i;