Skip to content

Commit

Permalink
Merge pull request DescentDevelopers#613 from winterheart/mission-list
Browse files Browse the repository at this point in the history
Enhance mission levels select window
  • Loading branch information
Lgt2x authored Oct 20, 2024
2 parents 33edddd + 83886a2 commit 496b2ed
Show file tree
Hide file tree
Showing 13 changed files with 519 additions and 483 deletions.
125 changes: 98 additions & 27 deletions Descent3/LoadLevel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1459,7 +1459,7 @@ tConvertObject object_convert[] = {

int object_convert_size = sizeof(object_convert) / sizeof(tConvertObject);

int chunk_start, chunk_size, filelen;
uint32_t chunk_start, chunk_size, filelen;

int CountDataToPageIn();

Expand Down Expand Up @@ -2648,7 +2648,44 @@ void BuildXlateTable(CFILE *ifile, int (*lookup_func)(const char *), int16_t *xl
xlate_table[i] = -1;
}

#define ISCHUNK(name) (!strncmp(chunk_name, name, 4))
#define ISCHUNK(name) (strncmp(chunk_name, name, 4) == 0)

/**
* Read and check level header
* @param fp file handle of level
* @return version of level, -1 on error
*/
int ReadHeader(CFILE *fp) {
// Read & check tag
char chunk_name[4];
cf_ReadBytes((uint8_t *)chunk_name, 4, fp);
if (!ISCHUNK(LEVEL_FILE_TAG)) {
return -1;
}

// Read version number
int version = cf_ReadInt(fp);
return version;
}

void ReadInfoChunk(CFILE *fp, level_info &info) {
// Initialize info
strcpy(info.name, "Unnamed");
strcpy(info.designer, "Anonymous");
strcpy(info.copyright, "");
strcpy(info.notes, "");

cf_ReadString(info.name, sizeof(info.name), fp);

// Localize level name here...
strcpy(info.name, LocalizeLevelName(info.name));

cf_ReadString(info.designer, sizeof(info.designer), fp);
cf_ReadString(info.copyright, sizeof(info.copyright), fp);
cf_ReadString(info.notes, sizeof(info.notes), fp);
}



// Reads info about our lightmaps
void ReadNewLightmapChunk(CFILE *fp, int version) {
Expand Down Expand Up @@ -3588,6 +3625,60 @@ static inline char* GetCurrentSumString() {
return output_buf;
}

bool LoadLevelInfo(const std::filesystem::path &filename, level_info &info) {
CFILE *ifile = cfopen(filename, "rb");
bool found = false;

if (!ifile) {
LOG_ERROR.printf("Failed to open mission file %s", filename.u8string().c_str());
return false;
}

try {
// catch cfile errors

// Read and check header
int version = ReadHeader(ifile);

if (version > LEVEL_FILE_VERSION) {
LOG_ERROR.printf("Mission file too new (version %d)", version);
cfclose(ifile);
return false;
}
if (version < LEVEL_FILE_OLDEST_COMPATIBLE_VERSION) {
LOG_ERROR.printf("Mission file too old (version %d)", version);
cfclose(ifile);
return false;
}

while (!cfeof(ifile)) {
char chunk_name[4];

cf_ReadBytes((uint8_t *)chunk_name, 4, ifile);
chunk_start = cftell(ifile);
chunk_size = cf_ReadInt(ifile);

if (ISCHUNK(CHUNK_LEVEL_INFO)) {
ReadInfoChunk(ifile, info);
found = true;
break;
} else {
cfseek(ifile, chunk_start + chunk_size, SEEK_SET);
}
}

} catch (cfile_error *cfe) {
LOG_FATAL.printf("Error reading: file = <%s>, error = \"%s\"", cfe->file->name, cfe->msg);
ASSERT(cfe->read_write == CFE_READING);
cfclose(ifile);
return false;
}

cfclose(ifile);
return found;
}


extern bool Disable_editor_rendering;

#define LEVEL_LOADED_PCT_CALC (filelen) ? (float)(chunk_size + chunk_start) / (float)filelen : 0.0f
Expand Down Expand Up @@ -3620,19 +3711,11 @@ int LoadLevel(char *filename, void (*cb_fn)(const char *, int, int)) {

filelen = cfilelength(ifile);

// Read & check tag
cf_ReadBytes((uint8_t *)tag, 4, ifile);
if (strncmp(tag, LEVEL_FILE_TAG, 4)) {
cfclose(ifile);
retval = 0;
goto end_loadlevel;
}

// Read & check version number
version = cf_ReadInt(ifile);
version = ReadHeader(ifile);

// Check for too-new version
// Check for too new version
if (version > LEVEL_FILE_VERSION) {
LOG_ERROR.printf("Mission file too new (version %d)", version);
cfclose(ifile);
#if (defined(EDITOR) || defined(NEWEDITOR))
if (GetFunctionMode() == EDITOR_MODE)
Expand All @@ -3645,6 +3728,7 @@ int LoadLevel(char *filename, void (*cb_fn)(const char *, int, int)) {

// Check for too-old version
if (version < LEVEL_FILE_OLDEST_COMPATIBLE_VERSION) {
LOG_ERROR.printf("Mission file too old (version %d)", version);
cfclose(ifile);
#if (defined(EDITOR) || defined(NEWEDITOR))
if (GetFunctionMode() == EDITOR_MODE)
Expand Down Expand Up @@ -3690,12 +3774,6 @@ int LoadLevel(char *filename, void (*cb_fn)(const char *, int, int)) {
// Clear terrain sounds
ClearTerrainSound();

// Init level info
strcpy(Level_info.name, "Unnamed");
strcpy(Level_info.designer, "Anonymous");
strcpy(Level_info.copyright, "");
strcpy(Level_info.notes, "");

BOA_AABB_checksum = BOA_mine_checksum = 0;
for (i = 0; i < MAX_ROOMS; i++) {
BOA_AABB_ROOM_checksum[i] = 0;
Expand Down Expand Up @@ -3929,14 +4007,7 @@ int LoadLevel(char *filename, void (*cb_fn)(const char *, int, int)) {
} else if (ISCHUNK(CHUNK_TERRAIN)) {
ReadTerrainChunks(ifile, version);
} else if (ISCHUNK(CHUNK_LEVEL_INFO)) {
cf_ReadString(Level_info.name, sizeof(Level_info.name), ifile);

// Localize level name here...
strcpy(Level_info.name, LocalizeLevelName(Level_info.name));

cf_ReadString(Level_info.designer, sizeof(Level_info.designer), ifile);
cf_ReadString(Level_info.copyright, sizeof(Level_info.copyright), ifile);
cf_ReadString(Level_info.notes, sizeof(Level_info.notes), ifile);
ReadInfoChunk(ifile, Level_info);

if (version >= 83) {
Gravity_strength = cf_ReadFloat(ifile);
Expand Down
10 changes: 10 additions & 0 deletions Descent3/LoadLevel.h
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,7 @@
*/

#include "cfile.h"
#include "Mission.h"
#include "room.h"

// Chunk types
Expand Down Expand Up @@ -634,6 +635,15 @@
// 130->131 Added the powerups ignore gravity checkbox
// 131->132 Added another ff bounce texture for Dan (his last day wish)

/**
* Get information from level such as level name, author copyrights and notes.
* This function much lighter that LoadLevel() and gets only INFO chunk from mission.
* @param filename name of mission file
* @param info resulted info
* @return true on success
*/
bool LoadLevelInfo(const std::filesystem::path &filename, level_info &info);

// Load a level file
// Returns 1 if file read ok, else 0
// cb_fn returns current chunk, parm1 = # bytes in chunk, parm2 = number of bytes in file
Expand Down
Loading

0 comments on commit 496b2ed

Please sign in to comment.