//Open a file for reading, set up a buffer PHYSFS_file *PHYSFSX_openReadBuffered(const char *filename) { PHYSFS_file *fp; PHYSFS_uint64 bufSize; char filename2[PATH_MAX]; if (filename[0] == '\x01') { //FIXME: don't look in dir, only in hogfile filename++; } snprintf(filename2, sizeof(filename2), "%s", filename); PHYSFSEXT_locateCorrectCase(filename2); fp = PHYSFS_openRead(filename2); if (!fp) return NULL; bufSize = PHYSFS_fileLength(fp); while (!PHYSFS_setBuffer(fp, bufSize) && bufSize) bufSize /= 2; // even if the error isn't memory full, for a 20MB file it'll only do this 8 times return fp; }
int PHYSFSX_removeRelFromSearchPath(const char *relname) { char relname2[PATH_MAX], pathname[PATH_MAX]; snprintf(relname2, sizeof(relname2), "%s", relname); PHYSFSEXT_locateCorrectCase(relname2); if (!PHYSFSX_getRealPath(relname2, pathname)) return 0; return PHYSFS_removeFromSearchPath(pathname); }
int PHYSFSX_exists(const char *filename, int ignorecase) { char filename2[PATH_MAX]; if (!ignorecase) return PHYSFS_exists(filename); snprintf(filename2, sizeof(filename2), "%s", filename); PHYSFSEXT_locateCorrectCase(filename2); return PHYSFS_exists(filename2); }
// Add a searchpath, but that searchpath is relative to an existing searchpath // It will add the first one it finds and return 1, if it doesn't find any it returns 0 int PHYSFSX_addRelToSearchPath(const char *relname, int add_to_end) { char relname2[PATH_MAX], pathname[PATH_MAX]; snprintf(relname2, sizeof(relname2), "%s", relname); PHYSFSEXT_locateCorrectCase(relname2); if (!PHYSFSX_getRealPath(relname2, pathname)) return 0; return PHYSFS_addToSearchPath(pathname, add_to_end); }
int PHYSFSX_fsize(const char *hogname) { PHYSFS_file *fp; char hogname2[PATH_MAX]; int size; snprintf(hogname2, sizeof(hogname2), "%s", hogname); PHYSFSEXT_locateCorrectCase(hogname2); fp = PHYSFS_openRead(hogname2); if (fp == NULL) return -1; size = PHYSFS_fileLength(fp); PHYSFS_close(fp); return size; }
//loads the specfied mission from the mission list. //build_mission_list() must have been called. //Returns true if mission loaded ok, else false. static int load_mission(mle *mission) { PHYSFS_file *mfile; char buf[PATH_MAX], *v; if (Current_mission) free_mission(); MALLOC(Current_mission, Mission, 1); if (!Current_mission) return 0; *(mle *) Current_mission = *mission; Current_mission->path = d_strdup(mission->path); Current_mission->filename = Current_mission->path + (mission->filename - mission->path); Current_mission->n_secret_levels = 0; Current_mission->enhanced = 0; //init vars Last_level = 0; Last_secret_level = 0; memset(&Briefing_text_filename, '\0', sizeof(Briefing_text_filename)); memset(&Ending_text_filename, '\0', sizeof(Ending_text_filename)); // for Descent 1 missions, load descent.hog if (EMULATING_D1) { if (!PHYSFSX_contfile_init("descent.hog", 1)) Warning("descent.hog not available, this mission may be missing some files required for briefings and exit sequence\n"); if (!stricmp(Current_mission_filename, D1_MISSION_FILENAME)) return load_mission_d1(); } if (PLAYING_BUILTIN_MISSION) { switch (Current_mission->builtin_hogsize) { case SHAREWARE_MISSION_HOGSIZE: case MAC_SHARE_MISSION_HOGSIZE: strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE_SHARE); strcpy(Ending_text_filename,BIMD2_ENDING_FILE_SHARE); return load_mission_shareware(); break; case OEM_MISSION_HOGSIZE: strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE_OEM); strcpy(Ending_text_filename,BIMD2_ENDING_FILE_OEM); return load_mission_oem(); break; default: Int3(); // fall through case FULL_MISSION_HOGSIZE: case FULL_10_MISSION_HOGSIZE: case MAC_FULL_MISSION_HOGSIZE: strcpy(Briefing_text_filename,BIMD2_BRIEFING_FILE); // continue on... (use d2.mn2 from hogfile) break; } } //read mission from file switch (mission->location) { case ML_MISSIONDIR: strcpy(buf,MISSION_DIR); break; default: Int3(); //fall through case ML_CURDIR: strcpy(buf,""); break; } strcat(buf, mission->path); if (mission->descent_version == 2) strcat(buf,".mn2"); else strcat(buf,".msn"); PHYSFSEXT_locateCorrectCase(buf); mfile = PHYSFSX_openReadBuffered(buf); if (mfile == NULL) { free_mission(); return 0; //error! } //for non-builtin missions, load HOG if (!PLAYING_BUILTIN_MISSION) { strcpy(buf+strlen(buf)-4,".hog"); //change extension PHYSFSEXT_locateCorrectCase(buf); if (PHYSFSX_exists(buf,1)) PHYSFSX_contfile_init(buf, 0); snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.tex",Current_mission_filename); if (!PHYSFSX_exists(Briefing_text_filename,1)) snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.txb",Current_mission_filename); snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.tex",Current_mission_filename); if (!PHYSFSX_exists(Ending_text_filename,1)) snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.txb",Current_mission_filename); } while (PHYSFSX_fgets(buf,sizeof(buf),mfile)) { if (istok(buf,"name") && !Current_mission->enhanced) { Current_mission->enhanced = 0; continue; //already have name, go to next line } if (istok(buf,"xname") && !Current_mission->enhanced) { Current_mission->enhanced = 1; continue; //already have name, go to next line } if (istok(buf,"zname") && !Current_mission->enhanced) { Current_mission->enhanced = 2; continue; //already have name, go to next line } else if (istok(buf,"type")) continue; //already have name, go to next line else if (istok(buf,"briefing")) { if ((v = get_value(buf)) != NULL) { add_term(v); if (strlen(v) < FILENAME_LEN && strlen(v) > 0) { char *tmp, *ptr; MALLOC(tmp, char, FILENAME_LEN); snprintf(tmp, FILENAME_LEN, "%s", v); if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one. *ptr = '\0'; strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion if (PHYSFSX_exists(tmp,1)) // check if this file exists ... snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ... else // ... otherwise ... { if ((ptr = strrchr(tmp, '.'))) *ptr = '\0'; strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension if (PHYSFSX_exists(tmp,1)) // check if this file exists ... snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ... } d_free(tmp); } } } else if (istok(buf,"ending")) { if ((v = get_value(buf)) != NULL) { add_term(v); if (strlen(v) < FILENAME_LEN && strlen(v) > 0) { char *tmp, *ptr; MALLOC(tmp, char, FILENAME_LEN); snprintf(tmp, FILENAME_LEN, "%s", v); if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one. *ptr = '\0'; strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion if (PHYSFSX_exists(tmp,1)) // check if this file exists ... snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ... else // ... otherwise ... { if ((ptr = strrchr(tmp, '.'))) *ptr = '\0'; strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension if (PHYSFSX_exists(tmp,1)) // check if this file exists ... snprintf(Ending_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ... } d_free(tmp); } } } else if (istok(buf,"num_levels")) { if ((v=get_value(buf))!=NULL) { int n_levels,i; n_levels = atoi(v); for (i=0;i<n_levels;i++) { PHYSFSX_fgets(buf,sizeof(buf),mfile); add_term(buf); if (strlen(buf) <= 12) { strcpy(Level_names[i],buf); Last_level++; } else break; } } } else if (istok(buf,"num_secrets")) { if ((v=get_value(buf))!=NULL) { int i; N_secret_levels = atoi(v); Assert(N_secret_levels <= MAX_SECRET_LEVELS_PER_MISSION); for (i=0;i<N_secret_levels;i++) { char *t; PHYSFSX_fgets(buf,sizeof(buf),mfile); if ((t=strchr(buf,','))!=NULL) *t++=0; else break; add_term(buf); if (strlen(buf) <= 12) { strcpy(Secret_level_names[i],buf); Secret_level_table[i] = atoi(t); if (Secret_level_table[i]<1 || Secret_level_table[i]>Last_level) break; Last_secret_level--; } else break; } } } } PHYSFS_close(mfile); if (Last_level <= 0) { free_mission(); //no valid mission loaded return 0; } // re-read default HAM file, in case this mission brings it's own version of it free_polygon_models(); read_hamfile(); if (Current_mission->enhanced) { char t[50]; sprintf(t,"%s.ham",Current_mission_filename); bm_read_extra_robots(t, Current_mission->enhanced); init_extra_robot_movie(Current_mission_filename); } return 1; }
int main(int argc, char **argv) { int rc; char buf[128]; PHYSFS_File *f; if (!PHYSFS_init(argv[0])) { fprintf(stderr, "PHYSFS_init(): %s\n", PHYSFS_getLastError()); return 1; } /* if */ if (!PHYSFS_addToSearchPath(".", 1)) { fprintf(stderr, "PHYSFS_addToSearchPath(): %s\n", PHYSFS_getLastError()); PHYSFS_deinit(); return 1; } /* if */ if (!PHYSFS_setWriteDir(".")) { fprintf(stderr, "PHYSFS_setWriteDir(): %s\n", PHYSFS_getLastError()); PHYSFS_deinit(); return 1; } /* if */ if (!PHYSFS_mkdir("/a/b/c")) { fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError()); PHYSFS_deinit(); return 1; } /* if */ if (!PHYSFS_mkdir("/a/b/C")) { fprintf(stderr, "PHYSFS_mkdir(): %s\n", PHYSFS_getLastError()); PHYSFS_deinit(); return 1; } /* if */ f = PHYSFS_openWrite("/a/b/c/x.txt"); PHYSFS_close(f); if (f == NULL) { fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError()); PHYSFS_deinit(); return 1; } /* if */ f = PHYSFS_openWrite("/a/b/C/X.txt"); PHYSFS_close(f); if (f == NULL) { fprintf(stderr, "PHYSFS_openWrite(): %s\n", PHYSFS_getLastError()); PHYSFS_deinit(); return 1; } /* if */ strcpy(buf, "/a/b/c/x.txt"); rc = PHYSFSEXT_locateCorrectCase(buf); if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) printf("test 1 failed\n"); strcpy(buf, "/a/B/c/x.txt"); rc = PHYSFSEXT_locateCorrectCase(buf); if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) printf("test 2 failed\n"); strcpy(buf, "/a/b/C/x.txt"); rc = PHYSFSEXT_locateCorrectCase(buf); if ((rc != 0) || (strcmp(buf, "/a/b/C/X.txt") != 0)) printf("test 3 failed\n"); strcpy(buf, "/a/b/c/X.txt"); rc = PHYSFSEXT_locateCorrectCase(buf); if ((rc != 0) || (strcmp(buf, "/a/b/c/x.txt") != 0)) printf("test 4 failed\n"); strcpy(buf, "/a/b/c/z.txt"); rc = PHYSFSEXT_locateCorrectCase(buf); if ((rc != -1) || (strcmp(buf, "/a/b/c/z.txt") != 0)) printf("test 5 failed\n"); strcpy(buf, "/A/B/Z/z.txt"); rc = PHYSFSEXT_locateCorrectCase(buf); if ((rc != -2) || (strcmp(buf, "/a/b/Z/z.txt") != 0)) printf("test 6 failed\n"); printf("Testing completed.\n"); printf(" If no errors were reported, you're good to go.\n"); PHYSFS_delete("/a/b/c/x.txt"); PHYSFS_delete("/a/b/C/X.txt"); PHYSFS_delete("/a/b/c"); PHYSFS_delete("/a/b/C"); PHYSFS_delete("/a/b"); PHYSFS_delete("/a"); PHYSFS_deinit(); return 0; } /* main */
//loads the specfied mission from the mission list. //build_mission_list() must have been called. //Returns true if mission loaded ok, else false. int load_mission(mle *mission) { PHYSFS_file *mfile; char buf[PATH_MAX], *v; if (Current_mission) free_mission(); Current_mission = d_malloc(sizeof(Mission)); if (!Current_mission) return 0; *(mle *) Current_mission = *mission; Current_mission->path = d_strdup(mission->path); Current_mission->filename = Current_mission->path + (mission->filename - mission->path); Current_mission->n_secret_levels = 0; //init vars Last_level = 0; Last_secret_level = 0; memset(&Briefing_text_filename, '\0', sizeof(Briefing_text_filename)); memset(&Ending_text_filename, '\0', sizeof(Ending_text_filename)); Secret_level_table = NULL; Level_names = NULL; Secret_level_names = NULL; // for Descent 1 missions, load descent.hog if (!PHYSFSX_contfile_init("descent.hog", 1)) Error("descent.hog not available!\n"); if (!d_stricmp(Current_mission_filename, D1_MISSION_FILENAME)) return load_mission_d1(); //read mission from file switch (mission->location) { case ML_MISSIONDIR: strcpy(buf,MISSION_DIR); break; default: Int3(); //fall through case ML_CURDIR: strcpy(buf,""); break; } strcat(buf, mission->path); strcat(buf,".msn"); PHYSFSEXT_locateCorrectCase(buf); mfile = PHYSFSX_openReadBuffered(buf); if (mfile == NULL) { free_mission(); return 0; //error! } //for non-builtin missions, load HOG strcpy(buf+strlen(buf)-4,".hog"); //change extension PHYSFSEXT_locateCorrectCase(buf); if (PHYSFSX_exists(buf,1)) PHYSFSX_contfile_init(buf, 0); snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.tex",Current_mission_filename); if (!PHYSFSX_exists(Briefing_text_filename,1)) snprintf(Briefing_text_filename, sizeof(Briefing_text_filename), "%s.txb",Current_mission_filename); snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.tex",Current_mission_filename); if (!PHYSFSX_exists(Ending_text_filename,1)) snprintf(Ending_text_filename, sizeof(Ending_text_filename), "%s.txb",Current_mission_filename); while (PHYSFSX_fgets(buf,sizeof(buf),mfile)) { if (istok(buf,"type")) continue; //already have name, go to next line else if (istok(buf,"briefing")) { if ((v = get_value(buf)) != NULL) { add_term(v); if (strlen(v) < FILENAME_LEN && strlen(v) > 0) { char *tmp, *ptr; MALLOC(tmp, char, FILENAME_LEN); snprintf(tmp, FILENAME_LEN, "%s", v); if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one. *ptr = '\0'; strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion if (PHYSFSX_exists(tmp,1)) // check if this file exists ... snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ... else // ... otherwise ... { if ((ptr = strrchr(tmp, '.'))) *ptr = '\0'; strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension if (PHYSFSX_exists(tmp,1)) // check if this file exists ... snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ... } d_free(tmp); } } } else if (istok(buf,"ending")) { if ((v = get_value(buf)) != NULL) { add_term(v); if (strlen(v) < FILENAME_LEN && strlen(v) > 0) { char *tmp, *ptr; MALLOC(tmp, char, FILENAME_LEN); snprintf(tmp, FILENAME_LEN, "%s", v); if ((ptr = strrchr(tmp, '.'))) // if there's a filename extension, kill it. No one knows it's the right one. *ptr = '\0'; strncat(tmp, ".tex", sizeof(char)*FILENAME_LEN); // apply tex-extenstion if (PHYSFSX_exists(tmp,1)) // check if this file exists ... snprintf(Briefing_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ... else // ... otherwise ... { if ((ptr = strrchr(tmp, '.'))) *ptr = '\0'; strncat(tmp, ".txb", sizeof(char)*FILENAME_LEN); // apply txb extension if (PHYSFSX_exists(tmp,1)) // check if this file exists ... snprintf(Ending_text_filename, FILENAME_LEN, "%s", tmp); // ... and apply ... } d_free(tmp); } } } else if (istok(buf,"num_levels")) { if ((v=get_value(buf))!=NULL) { int n_levels,i; n_levels = atoi(v); Assert(n_levels <= MAX_LEVELS_PER_MISSION); n_levels = min(n_levels, MAX_LEVELS_PER_MISSION); MALLOC(Level_names, d_fname, n_levels); if (!Level_names) { free_mission(); return 0; } for (i=0;i<n_levels;i++) { PHYSFSX_fgets(buf,sizeof(buf),mfile); add_term(buf); if (strlen(buf) <= 12) { strcpy(Level_names[i],buf); Last_level++; } else break; } } } else if (istok(buf,"num_secrets")) { if ((v=get_value(buf))!=NULL) { int i; N_secret_levels = atoi(v); Assert(N_secret_levels <= MAX_SECRET_LEVELS_PER_MISSION); N_secret_levels = min(N_secret_levels, MAX_SECRET_LEVELS_PER_MISSION); MALLOC(Secret_level_names, d_fname, N_secret_levels); if (!Secret_level_names) { free_mission(); return 0; } MALLOC(Secret_level_table, ubyte, N_secret_levels); if (!Secret_level_table) { free_mission(); return 0; } for (i=0;i<N_secret_levels;i++) { char *t; PHYSFSX_fgets(buf,sizeof(buf),mfile); if ((t=strchr(buf,','))!=NULL) *t++=0; else break; add_term(buf); if (strlen(buf) <= 12) { strcpy(Secret_level_names[i],buf); Secret_level_table[i] = atoi(t); if (Secret_level_table[i]<1 || Secret_level_table[i]>Last_level) break; Last_secret_level--; } else break; } } } } PHYSFS_close(mfile); if (Last_level <= 0) { free_mission(); //no valid mission loaded return 0; } return 1; }