Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance mission levels select window #613

Merged
merged 5 commits into from
Oct 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
Lgt2x marked this conversation as resolved.
Show resolved Hide resolved

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
Loading